Merge from origin/emacs-25
[emacs.git] / src / gnutls.c
blobaf2ba52870cb71629376144346e0095f8820e9e6
1 /* GnuTLS glue for GNU Emacs.
2 Copyright (C) 2010-2016 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or (at
9 your option) any later version.
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
19 #include <config.h>
20 #include <errno.h>
21 #include <stdio.h>
23 #include "lisp.h"
24 #include "process.h"
25 #include "gnutls.h"
26 #include "coding.h"
28 #ifdef HAVE_GNUTLS
30 #ifdef WINDOWSNT
31 #include <windows.h>
32 #include "w32.h"
33 #endif
35 static bool emacs_gnutls_handle_error (gnutls_session_t, int);
37 static bool gnutls_global_initialized;
39 static void gnutls_log_function (int, const char *);
40 static void gnutls_log_function2 (int, const char *, const char *);
41 #ifdef HAVE_GNUTLS3
42 static void gnutls_audit_log_function (gnutls_session_t, const char *);
43 #endif
45 enum extra_peer_verification
47 CERTIFICATE_NOT_MATCHING = 2
51 #ifdef WINDOWSNT
53 DEF_DLL_FN (gnutls_alert_description_t, gnutls_alert_get,
54 (gnutls_session_t));
55 DEF_DLL_FN (const char *, gnutls_alert_get_name,
56 (gnutls_alert_description_t));
57 DEF_DLL_FN (int, gnutls_anon_allocate_client_credentials,
58 (gnutls_anon_client_credentials_t *));
59 DEF_DLL_FN (void, gnutls_anon_free_client_credentials,
60 (gnutls_anon_client_credentials_t));
61 DEF_DLL_FN (int, gnutls_bye, (gnutls_session_t, gnutls_close_request_t));
62 DEF_DLL_FN (int, gnutls_certificate_allocate_credentials,
63 (gnutls_certificate_credentials_t *));
64 DEF_DLL_FN (void, gnutls_certificate_free_credentials,
65 (gnutls_certificate_credentials_t));
66 DEF_DLL_FN (const gnutls_datum_t *, gnutls_certificate_get_peers,
67 (gnutls_session_t, unsigned int *));
68 DEF_DLL_FN (void, gnutls_certificate_set_verify_flags,
69 (gnutls_certificate_credentials_t, unsigned int));
70 DEF_DLL_FN (int, gnutls_certificate_set_x509_crl_file,
71 (gnutls_certificate_credentials_t, const char *,
72 gnutls_x509_crt_fmt_t));
73 DEF_DLL_FN (int, gnutls_certificate_set_x509_key_file,
74 (gnutls_certificate_credentials_t, const char *, const char *,
75 gnutls_x509_crt_fmt_t));
76 # if ((GNUTLS_VERSION_MAJOR \
77 + (GNUTLS_VERSION_MINOR > 0 || GNUTLS_VERSION_PATCH >= 20)) \
78 > 3)
79 DEF_DLL_FN (int, gnutls_certificate_set_x509_system_trust,
80 (gnutls_certificate_credentials_t));
81 # endif
82 DEF_DLL_FN (int, gnutls_certificate_set_x509_trust_file,
83 (gnutls_certificate_credentials_t, const char *,
84 gnutls_x509_crt_fmt_t));
85 DEF_DLL_FN (gnutls_certificate_type_t, gnutls_certificate_type_get,
86 (gnutls_session_t));
87 DEF_DLL_FN (int, gnutls_certificate_verify_peers2,
88 (gnutls_session_t, unsigned int *));
89 DEF_DLL_FN (int, gnutls_credentials_set,
90 (gnutls_session_t, gnutls_credentials_type_t, void *));
91 DEF_DLL_FN (void, gnutls_deinit, (gnutls_session_t));
92 DEF_DLL_FN (void, gnutls_dh_set_prime_bits,
93 (gnutls_session_t, unsigned int));
94 DEF_DLL_FN (int, gnutls_dh_get_prime_bits, (gnutls_session_t));
95 DEF_DLL_FN (int, gnutls_error_is_fatal, (int));
96 DEF_DLL_FN (int, gnutls_global_init, (void));
97 DEF_DLL_FN (void, gnutls_global_set_log_function, (gnutls_log_func));
98 # ifdef HAVE_GNUTLS3
99 DEF_DLL_FN (void, gnutls_global_set_audit_log_function, (gnutls_audit_log_func));
100 # endif
101 DEF_DLL_FN (void, gnutls_global_set_log_level, (int));
102 DEF_DLL_FN (int, gnutls_handshake, (gnutls_session_t));
103 DEF_DLL_FN (int, gnutls_init, (gnutls_session_t *, unsigned int));
104 DEF_DLL_FN (int, gnutls_priority_set_direct,
105 (gnutls_session_t, const char *, const char **));
106 DEF_DLL_FN (size_t, gnutls_record_check_pending, (gnutls_session_t));
107 DEF_DLL_FN (ssize_t, gnutls_record_recv, (gnutls_session_t, void *, size_t));
108 DEF_DLL_FN (ssize_t, gnutls_record_send,
109 (gnutls_session_t, const void *, size_t));
110 DEF_DLL_FN (const char *, gnutls_strerror, (int));
111 DEF_DLL_FN (void, gnutls_transport_set_errno, (gnutls_session_t, int));
112 DEF_DLL_FN (void, gnutls_transport_set_ptr2,
113 (gnutls_session_t, gnutls_transport_ptr_t,
114 gnutls_transport_ptr_t));
115 DEF_DLL_FN (void, gnutls_transport_set_pull_function,
116 (gnutls_session_t, gnutls_pull_func));
117 DEF_DLL_FN (void, gnutls_transport_set_push_function,
118 (gnutls_session_t, gnutls_push_func));
119 DEF_DLL_FN (int, gnutls_x509_crt_check_hostname,
120 (gnutls_x509_crt_t, const char *));
121 DEF_DLL_FN (int, gnutls_x509_crt_check_issuer,
122 (gnutls_x509_crt_t, gnutls_x509_crt_t));
123 DEF_DLL_FN (void, gnutls_x509_crt_deinit, (gnutls_x509_crt_t));
124 DEF_DLL_FN (int, gnutls_x509_crt_import,
125 (gnutls_x509_crt_t, const gnutls_datum_t *,
126 gnutls_x509_crt_fmt_t));
127 DEF_DLL_FN (int, gnutls_x509_crt_init, (gnutls_x509_crt_t *));
128 DEF_DLL_FN (int, gnutls_x509_crt_get_fingerprint,
129 (gnutls_x509_crt_t,
130 gnutls_digest_algorithm_t, void *, size_t *));
131 DEF_DLL_FN (int, gnutls_x509_crt_get_version,
132 (gnutls_x509_crt_t));
133 DEF_DLL_FN (int, gnutls_x509_crt_get_serial,
134 (gnutls_x509_crt_t, void *, size_t *));
135 DEF_DLL_FN (int, gnutls_x509_crt_get_issuer_dn,
136 (gnutls_x509_crt_t, char *, size_t *));
137 DEF_DLL_FN (time_t, gnutls_x509_crt_get_activation_time,
138 (gnutls_x509_crt_t));
139 DEF_DLL_FN (time_t, gnutls_x509_crt_get_expiration_time,
140 (gnutls_x509_crt_t));
141 DEF_DLL_FN (int, gnutls_x509_crt_get_dn,
142 (gnutls_x509_crt_t, char *, size_t *));
143 DEF_DLL_FN (int, gnutls_x509_crt_get_pk_algorithm,
144 (gnutls_x509_crt_t, unsigned int *));
145 DEF_DLL_FN (const char*, gnutls_pk_algorithm_get_name,
146 (gnutls_pk_algorithm_t));
147 DEF_DLL_FN (int, gnutls_pk_bits_to_sec_param,
148 (gnutls_pk_algorithm_t, unsigned int));
149 DEF_DLL_FN (int, gnutls_x509_crt_get_issuer_unique_id,
150 (gnutls_x509_crt_t, char *, size_t *));
151 DEF_DLL_FN (int, gnutls_x509_crt_get_subject_unique_id,
152 (gnutls_x509_crt_t, char *, size_t *));
153 DEF_DLL_FN (int, gnutls_x509_crt_get_signature_algorithm,
154 (gnutls_x509_crt_t));
155 DEF_DLL_FN (int, gnutls_x509_crt_get_key_id,
156 (gnutls_x509_crt_t, unsigned int, unsigned char *, size_t *_size));
157 DEF_DLL_FN (const char*, gnutls_sec_param_get_name, (gnutls_sec_param_t));
158 DEF_DLL_FN (const char*, gnutls_sign_get_name, (gnutls_sign_algorithm_t));
159 DEF_DLL_FN (int, gnutls_server_name_set,
160 (gnutls_session_t, gnutls_server_name_type_t,
161 const void *, size_t));
162 DEF_DLL_FN (gnutls_kx_algorithm_t, gnutls_kx_get, (gnutls_session_t));
163 DEF_DLL_FN (const char*, gnutls_kx_get_name, (gnutls_kx_algorithm_t));
164 DEF_DLL_FN (gnutls_protocol_t, gnutls_protocol_get_version,
165 (gnutls_session_t));
166 DEF_DLL_FN (const char*, gnutls_protocol_get_name, (gnutls_protocol_t));
167 DEF_DLL_FN (gnutls_cipher_algorithm_t, gnutls_cipher_get,
168 (gnutls_session_t));
169 DEF_DLL_FN (const char*, gnutls_cipher_get_name,
170 (gnutls_cipher_algorithm_t));
171 DEF_DLL_FN (gnutls_mac_algorithm_t, gnutls_mac_get, (gnutls_session_t));
172 DEF_DLL_FN (const char*, gnutls_mac_get_name, (gnutls_mac_algorithm_t));
175 static bool
176 init_gnutls_functions (void)
178 HMODULE library;
179 int max_log_level = 1;
181 if (!(library = w32_delayed_load (Qgnutls)))
183 GNUTLS_LOG (1, max_log_level, "GnuTLS library not found");
184 return 0;
187 LOAD_DLL_FN (library, gnutls_alert_get);
188 LOAD_DLL_FN (library, gnutls_alert_get_name);
189 LOAD_DLL_FN (library, gnutls_anon_allocate_client_credentials);
190 LOAD_DLL_FN (library, gnutls_anon_free_client_credentials);
191 LOAD_DLL_FN (library, gnutls_bye);
192 LOAD_DLL_FN (library, gnutls_certificate_allocate_credentials);
193 LOAD_DLL_FN (library, gnutls_certificate_free_credentials);
194 LOAD_DLL_FN (library, gnutls_certificate_get_peers);
195 LOAD_DLL_FN (library, gnutls_certificate_set_verify_flags);
196 LOAD_DLL_FN (library, gnutls_certificate_set_x509_crl_file);
197 LOAD_DLL_FN (library, gnutls_certificate_set_x509_key_file);
198 # if ((GNUTLS_VERSION_MAJOR \
199 + (GNUTLS_VERSION_MINOR > 0 || GNUTLS_VERSION_PATCH >= 20)) \
200 > 3)
201 LOAD_DLL_FN (library, gnutls_certificate_set_x509_system_trust);
202 # endif
203 LOAD_DLL_FN (library, gnutls_certificate_set_x509_trust_file);
204 LOAD_DLL_FN (library, gnutls_certificate_type_get);
205 LOAD_DLL_FN (library, gnutls_certificate_verify_peers2);
206 LOAD_DLL_FN (library, gnutls_credentials_set);
207 LOAD_DLL_FN (library, gnutls_deinit);
208 LOAD_DLL_FN (library, gnutls_dh_set_prime_bits);
209 LOAD_DLL_FN (library, gnutls_dh_get_prime_bits);
210 LOAD_DLL_FN (library, gnutls_error_is_fatal);
211 LOAD_DLL_FN (library, gnutls_global_init);
212 LOAD_DLL_FN (library, gnutls_global_set_log_function);
213 # ifdef HAVE_GNUTLS3
214 LOAD_DLL_FN (library, gnutls_global_set_audit_log_function);
215 # endif
216 LOAD_DLL_FN (library, gnutls_global_set_log_level);
217 LOAD_DLL_FN (library, gnutls_handshake);
218 LOAD_DLL_FN (library, gnutls_init);
219 LOAD_DLL_FN (library, gnutls_priority_set_direct);
220 LOAD_DLL_FN (library, gnutls_record_check_pending);
221 LOAD_DLL_FN (library, gnutls_record_recv);
222 LOAD_DLL_FN (library, gnutls_record_send);
223 LOAD_DLL_FN (library, gnutls_strerror);
224 LOAD_DLL_FN (library, gnutls_transport_set_errno);
225 LOAD_DLL_FN (library, gnutls_transport_set_ptr2);
226 LOAD_DLL_FN (library, gnutls_transport_set_pull_function);
227 LOAD_DLL_FN (library, gnutls_transport_set_push_function);
228 LOAD_DLL_FN (library, gnutls_x509_crt_check_hostname);
229 LOAD_DLL_FN (library, gnutls_x509_crt_check_issuer);
230 LOAD_DLL_FN (library, gnutls_x509_crt_deinit);
231 LOAD_DLL_FN (library, gnutls_x509_crt_import);
232 LOAD_DLL_FN (library, gnutls_x509_crt_init);
233 LOAD_DLL_FN (library, gnutls_x509_crt_get_fingerprint);
234 LOAD_DLL_FN (library, gnutls_x509_crt_get_version);
235 LOAD_DLL_FN (library, gnutls_x509_crt_get_serial);
236 LOAD_DLL_FN (library, gnutls_x509_crt_get_issuer_dn);
237 LOAD_DLL_FN (library, gnutls_x509_crt_get_activation_time);
238 LOAD_DLL_FN (library, gnutls_x509_crt_get_expiration_time);
239 LOAD_DLL_FN (library, gnutls_x509_crt_get_dn);
240 LOAD_DLL_FN (library, gnutls_x509_crt_get_pk_algorithm);
241 LOAD_DLL_FN (library, gnutls_pk_algorithm_get_name);
242 LOAD_DLL_FN (library, gnutls_pk_bits_to_sec_param);
243 LOAD_DLL_FN (library, gnutls_x509_crt_get_issuer_unique_id);
244 LOAD_DLL_FN (library, gnutls_x509_crt_get_subject_unique_id);
245 LOAD_DLL_FN (library, gnutls_x509_crt_get_signature_algorithm);
246 LOAD_DLL_FN (library, gnutls_x509_crt_get_key_id);
247 LOAD_DLL_FN (library, gnutls_sec_param_get_name);
248 LOAD_DLL_FN (library, gnutls_sign_get_name);
249 LOAD_DLL_FN (library, gnutls_server_name_set);
250 LOAD_DLL_FN (library, gnutls_kx_get);
251 LOAD_DLL_FN (library, gnutls_kx_get_name);
252 LOAD_DLL_FN (library, gnutls_protocol_get_version);
253 LOAD_DLL_FN (library, gnutls_protocol_get_name);
254 LOAD_DLL_FN (library, gnutls_cipher_get);
255 LOAD_DLL_FN (library, gnutls_cipher_get_name);
256 LOAD_DLL_FN (library, gnutls_mac_get);
257 LOAD_DLL_FN (library, gnutls_mac_get_name);
259 max_log_level = global_gnutls_log_level;
262 Lisp_Object name = CAR_SAFE (Fget (Qgnutls, QCloaded_from));
263 GNUTLS_LOG2 (1, max_log_level, "GnuTLS library loaded:",
264 STRINGP (name) ? (const char *) SDATA (name) : "unknown");
267 return 1;
270 # define gnutls_alert_get fn_gnutls_alert_get
271 # define gnutls_alert_get_name fn_gnutls_alert_get_name
272 # define gnutls_anon_allocate_client_credentials fn_gnutls_anon_allocate_client_credentials
273 # define gnutls_anon_free_client_credentials fn_gnutls_anon_free_client_credentials
274 # define gnutls_bye fn_gnutls_bye
275 # define gnutls_certificate_allocate_credentials fn_gnutls_certificate_allocate_credentials
276 # define gnutls_certificate_free_credentials fn_gnutls_certificate_free_credentials
277 # define gnutls_certificate_get_peers fn_gnutls_certificate_get_peers
278 # define gnutls_certificate_set_verify_flags fn_gnutls_certificate_set_verify_flags
279 # define gnutls_certificate_set_x509_crl_file fn_gnutls_certificate_set_x509_crl_file
280 # define gnutls_certificate_set_x509_key_file fn_gnutls_certificate_set_x509_key_file
281 # define gnutls_certificate_set_x509_system_trust fn_gnutls_certificate_set_x509_system_trust
282 # define gnutls_certificate_set_x509_trust_file fn_gnutls_certificate_set_x509_trust_file
283 # define gnutls_certificate_type_get fn_gnutls_certificate_type_get
284 # define gnutls_certificate_verify_peers2 fn_gnutls_certificate_verify_peers2
285 # define gnutls_cipher_get fn_gnutls_cipher_get
286 # define gnutls_cipher_get_name fn_gnutls_cipher_get_name
287 # define gnutls_credentials_set fn_gnutls_credentials_set
288 # define gnutls_deinit fn_gnutls_deinit
289 # define gnutls_dh_get_prime_bits fn_gnutls_dh_get_prime_bits
290 # define gnutls_dh_set_prime_bits fn_gnutls_dh_set_prime_bits
291 # define gnutls_error_is_fatal fn_gnutls_error_is_fatal
292 # define gnutls_global_init fn_gnutls_global_init
293 # define gnutls_global_set_audit_log_function fn_gnutls_global_set_audit_log_function
294 # define gnutls_global_set_log_function fn_gnutls_global_set_log_function
295 # define gnutls_global_set_log_level fn_gnutls_global_set_log_level
296 # define gnutls_handshake fn_gnutls_handshake
297 # define gnutls_init fn_gnutls_init
298 # define gnutls_kx_get fn_gnutls_kx_get
299 # define gnutls_kx_get_name fn_gnutls_kx_get_name
300 # define gnutls_mac_get fn_gnutls_mac_get
301 # define gnutls_mac_get_name fn_gnutls_mac_get_name
302 # define gnutls_pk_algorithm_get_name fn_gnutls_pk_algorithm_get_name
303 # define gnutls_pk_bits_to_sec_param fn_gnutls_pk_bits_to_sec_param
304 # define gnutls_priority_set_direct fn_gnutls_priority_set_direct
305 # define gnutls_protocol_get_name fn_gnutls_protocol_get_name
306 # define gnutls_protocol_get_version fn_gnutls_protocol_get_version
307 # define gnutls_record_check_pending fn_gnutls_record_check_pending
308 # define gnutls_record_recv fn_gnutls_record_recv
309 # define gnutls_record_send fn_gnutls_record_send
310 # define gnutls_sec_param_get_name fn_gnutls_sec_param_get_name
311 # define gnutls_server_name_set fn_gnutls_server_name_set
312 # define gnutls_sign_get_name fn_gnutls_sign_get_name
313 # define gnutls_strerror fn_gnutls_strerror
314 # define gnutls_transport_set_errno fn_gnutls_transport_set_errno
315 # define gnutls_transport_set_ptr2 fn_gnutls_transport_set_ptr2
316 # define gnutls_transport_set_pull_function fn_gnutls_transport_set_pull_function
317 # define gnutls_transport_set_push_function fn_gnutls_transport_set_push_function
318 # define gnutls_x509_crt_check_hostname fn_gnutls_x509_crt_check_hostname
319 # define gnutls_x509_crt_check_issuer fn_gnutls_x509_crt_check_issuer
320 # define gnutls_x509_crt_deinit fn_gnutls_x509_crt_deinit
321 # define gnutls_x509_crt_get_activation_time fn_gnutls_x509_crt_get_activation_time
322 # define gnutls_x509_crt_get_dn fn_gnutls_x509_crt_get_dn
323 # define gnutls_x509_crt_get_expiration_time fn_gnutls_x509_crt_get_expiration_time
324 # define gnutls_x509_crt_get_fingerprint fn_gnutls_x509_crt_get_fingerprint
325 # define gnutls_x509_crt_get_issuer_dn fn_gnutls_x509_crt_get_issuer_dn
326 # define gnutls_x509_crt_get_issuer_unique_id fn_gnutls_x509_crt_get_issuer_unique_id
327 # define gnutls_x509_crt_get_key_id fn_gnutls_x509_crt_get_key_id
328 # define gnutls_x509_crt_get_pk_algorithm fn_gnutls_x509_crt_get_pk_algorithm
329 # define gnutls_x509_crt_get_serial fn_gnutls_x509_crt_get_serial
330 # define gnutls_x509_crt_get_signature_algorithm fn_gnutls_x509_crt_get_signature_algorithm
331 # define gnutls_x509_crt_get_subject_unique_id fn_gnutls_x509_crt_get_subject_unique_id
332 # define gnutls_x509_crt_get_version fn_gnutls_x509_crt_get_version
333 # define gnutls_x509_crt_import fn_gnutls_x509_crt_import
334 # define gnutls_x509_crt_init fn_gnutls_x509_crt_init
336 #endif
339 /* Report memory exhaustion if ERR is an out-of-memory indication. */
340 static void
341 check_memory_full (int err)
343 /* When GnuTLS exhausts memory, it doesn't say how much memory it
344 asked for, so tell the Emacs allocator that GnuTLS asked for no
345 bytes. This isn't accurate, but it's good enough. */
346 if (err == GNUTLS_E_MEMORY_ERROR)
347 memory_full (0);
350 #ifdef HAVE_GNUTLS3
351 /* Log a simple audit message. */
352 static void
353 gnutls_audit_log_function (gnutls_session_t session, const char *string)
355 if (global_gnutls_log_level >= 1)
357 message ("gnutls.c: [audit] %s", string);
360 #endif
362 /* Log a simple message. */
363 static void
364 gnutls_log_function (int level, const char *string)
366 message ("gnutls.c: [%d] %s", level, string);
369 /* Log a message and a string. */
370 static void
371 gnutls_log_function2 (int level, const char *string, const char *extra)
373 message ("gnutls.c: [%d] %s %s", level, string, extra);
377 gnutls_try_handshake (struct Lisp_Process *proc)
379 gnutls_session_t state = proc->gnutls_state;
380 int ret;
381 bool non_blocking = proc->is_non_blocking_client;
383 if (proc->gnutls_complete_negotiation_p)
384 non_blocking = false;
386 if (non_blocking)
387 proc->gnutls_p = true;
391 ret = gnutls_handshake (state);
392 emacs_gnutls_handle_error (state, ret);
393 QUIT;
395 while (ret < 0
396 && gnutls_error_is_fatal (ret) == 0
397 && ! non_blocking);
399 proc->gnutls_initstage = GNUTLS_STAGE_HANDSHAKE_TRIED;
401 if (ret == GNUTLS_E_SUCCESS)
403 /* Here we're finally done. */
404 proc->gnutls_initstage = GNUTLS_STAGE_READY;
406 else
408 /* check_memory_full (gnutls_alert_send_appropriate (state, ret)); */
410 return ret;
413 #ifndef WINDOWSNT
414 static int
415 emacs_gnutls_nonblock_errno (gnutls_transport_ptr_t ptr)
417 int err = errno;
419 switch (err)
421 # ifdef _AIX
422 /* This is taken from the GnuTLS system_errno function circa 2016;
423 see <http://savannah.gnu.org/support/?107464>. */
424 case 0:
425 errno = EAGAIN;
426 /* Fall through. */
427 # endif
428 case EINPROGRESS:
429 case ENOTCONN:
430 return EAGAIN;
432 default:
433 return err;
436 #endif
438 static int
439 emacs_gnutls_handshake (struct Lisp_Process *proc)
441 gnutls_session_t state = proc->gnutls_state;
443 if (proc->gnutls_initstage < GNUTLS_STAGE_HANDSHAKE_CANDO)
444 return -1;
446 if (proc->gnutls_initstage < GNUTLS_STAGE_TRANSPORT_POINTERS_SET)
448 #ifdef WINDOWSNT
449 /* On W32 we cannot transfer socket handles between different runtime
450 libraries, so we tell GnuTLS to use our special push/pull
451 functions. */
452 gnutls_transport_set_ptr2 (state,
453 (gnutls_transport_ptr_t) proc,
454 (gnutls_transport_ptr_t) proc);
455 gnutls_transport_set_push_function (state, &emacs_gnutls_push);
456 gnutls_transport_set_pull_function (state, &emacs_gnutls_pull);
457 #else
458 /* This is how GnuTLS takes sockets: as file descriptors passed
459 in. For an Emacs process socket, infd and outfd are the
460 same but we use this two-argument version for clarity. */
461 gnutls_transport_set_ptr2 (state,
462 (void *) (intptr_t) proc->infd,
463 (void *) (intptr_t) proc->outfd);
464 if (proc->is_non_blocking_client)
465 gnutls_transport_set_errno_function (state,
466 emacs_gnutls_nonblock_errno);
467 #endif
469 proc->gnutls_initstage = GNUTLS_STAGE_TRANSPORT_POINTERS_SET;
472 return gnutls_try_handshake (proc);
475 ptrdiff_t
476 emacs_gnutls_record_check_pending (gnutls_session_t state)
478 return gnutls_record_check_pending (state);
481 #ifdef WINDOWSNT
482 void
483 emacs_gnutls_transport_set_errno (gnutls_session_t state, int err)
485 gnutls_transport_set_errno (state, err);
487 #endif
489 ptrdiff_t
490 emacs_gnutls_write (struct Lisp_Process *proc, const char *buf, ptrdiff_t nbyte)
492 ssize_t rtnval = 0;
493 ptrdiff_t bytes_written;
494 gnutls_session_t state = proc->gnutls_state;
496 if (proc->gnutls_initstage != GNUTLS_STAGE_READY)
498 errno = EAGAIN;
499 return 0;
502 bytes_written = 0;
504 while (nbyte > 0)
506 rtnval = gnutls_record_send (state, buf, nbyte);
508 if (rtnval < 0)
510 if (rtnval == GNUTLS_E_INTERRUPTED)
511 continue;
512 else
514 /* If we get GNUTLS_E_AGAIN, then set errno
515 appropriately so that send_process retries the
516 correct way instead of erroring out. */
517 if (rtnval == GNUTLS_E_AGAIN)
518 errno = EAGAIN;
519 break;
523 buf += rtnval;
524 nbyte -= rtnval;
525 bytes_written += rtnval;
528 emacs_gnutls_handle_error (state, rtnval);
529 return (bytes_written);
532 ptrdiff_t
533 emacs_gnutls_read (struct Lisp_Process *proc, char *buf, ptrdiff_t nbyte)
535 ssize_t rtnval;
536 gnutls_session_t state = proc->gnutls_state;
538 if (proc->gnutls_initstage != GNUTLS_STAGE_READY)
540 errno = EAGAIN;
541 return -1;
544 rtnval = gnutls_record_recv (state, buf, nbyte);
545 if (rtnval >= 0)
546 return rtnval;
547 else if (rtnval == GNUTLS_E_UNEXPECTED_PACKET_LENGTH)
548 /* The peer closed the connection. */
549 return 0;
550 else if (emacs_gnutls_handle_error (state, rtnval))
551 /* non-fatal error */
552 return -1;
553 else {
554 /* a fatal error occurred */
555 return 0;
559 /* Report a GnuTLS error to the user.
560 Return true if the error code was successfully handled. */
561 static bool
562 emacs_gnutls_handle_error (gnutls_session_t session, int err)
564 int max_log_level = 0;
566 bool ret;
567 const char *str;
569 /* TODO: use a Lisp_Object generated by gnutls_make_error? */
570 if (err >= 0)
571 return 1;
573 check_memory_full (err);
575 max_log_level = global_gnutls_log_level;
577 /* TODO: use gnutls-error-fatalp and gnutls-error-string. */
579 str = gnutls_strerror (err);
580 if (!str)
581 str = "unknown";
583 if (gnutls_error_is_fatal (err))
585 ret = 0;
586 GNUTLS_LOG2 (1, max_log_level, "fatal error:", str);
588 else
590 ret = 1;
592 switch (err)
594 case GNUTLS_E_AGAIN:
595 GNUTLS_LOG2 (3,
596 max_log_level,
597 "retry:",
598 str);
599 default:
600 GNUTLS_LOG2 (1,
601 max_log_level,
602 "non-fatal error:",
603 str);
607 if (err == GNUTLS_E_WARNING_ALERT_RECEIVED
608 || err == GNUTLS_E_FATAL_ALERT_RECEIVED)
610 int alert = gnutls_alert_get (session);
611 int level = (err == GNUTLS_E_FATAL_ALERT_RECEIVED) ? 0 : 1;
612 str = gnutls_alert_get_name (alert);
613 if (!str)
614 str = "unknown";
616 GNUTLS_LOG2 (level, max_log_level, "Received alert: ", str);
618 return ret;
621 /* convert an integer error to a Lisp_Object; it will be either a
622 known symbol like `gnutls_e_interrupted' and `gnutls_e_again' or
623 simply the integer value of the error. GNUTLS_E_SUCCESS is mapped
624 to Qt. */
625 static Lisp_Object
626 gnutls_make_error (int err)
628 switch (err)
630 case GNUTLS_E_SUCCESS:
631 return Qt;
632 case GNUTLS_E_AGAIN:
633 return Qgnutls_e_again;
634 case GNUTLS_E_INTERRUPTED:
635 return Qgnutls_e_interrupted;
636 case GNUTLS_E_INVALID_SESSION:
637 return Qgnutls_e_invalid_session;
640 check_memory_full (err);
641 return make_number (err);
644 Lisp_Object
645 emacs_gnutls_deinit (Lisp_Object proc)
647 int log_level;
649 CHECK_PROCESS (proc);
651 if (! XPROCESS (proc)->gnutls_p)
652 return Qnil;
654 log_level = XPROCESS (proc)->gnutls_log_level;
656 if (XPROCESS (proc)->gnutls_x509_cred)
658 GNUTLS_LOG (2, log_level, "Deallocating x509 credentials");
659 gnutls_certificate_free_credentials (XPROCESS (proc)->gnutls_x509_cred);
660 XPROCESS (proc)->gnutls_x509_cred = NULL;
663 if (XPROCESS (proc)->gnutls_anon_cred)
665 GNUTLS_LOG (2, log_level, "Deallocating anon credentials");
666 gnutls_anon_free_client_credentials (XPROCESS (proc)->gnutls_anon_cred);
667 XPROCESS (proc)->gnutls_anon_cred = NULL;
670 if (XPROCESS (proc)->gnutls_state)
672 gnutls_deinit (XPROCESS (proc)->gnutls_state);
673 XPROCESS (proc)->gnutls_state = NULL;
674 if (GNUTLS_INITSTAGE (proc) >= GNUTLS_STAGE_INIT)
675 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_INIT - 1;
678 XPROCESS (proc)->gnutls_p = false;
679 return Qt;
682 DEFUN ("gnutls-asynchronous-parameters", Fgnutls_asynchronous_parameters,
683 Sgnutls_asynchronous_parameters, 2, 2, 0,
684 doc: /* Mark this process as being a pre-init GnuTLS process.
685 The second parameter is the list of parameters to feed to gnutls-boot
686 to finish setting up the connection. */)
687 (Lisp_Object proc, Lisp_Object params)
689 CHECK_PROCESS (proc);
691 XPROCESS (proc)->gnutls_boot_parameters = params;
692 return Qnil;
695 DEFUN ("gnutls-get-initstage", Fgnutls_get_initstage, Sgnutls_get_initstage, 1, 1, 0,
696 doc: /* Return the GnuTLS init stage of process PROC.
697 See also `gnutls-boot'. */)
698 (Lisp_Object proc)
700 CHECK_PROCESS (proc);
702 return make_number (GNUTLS_INITSTAGE (proc));
705 DEFUN ("gnutls-errorp", Fgnutls_errorp, Sgnutls_errorp, 1, 1, 0,
706 doc: /* Return t if ERROR indicates a GnuTLS problem.
707 ERROR is an integer or a symbol with an integer `gnutls-code' property.
708 usage: (gnutls-errorp ERROR) */
709 attributes: const)
710 (Lisp_Object err)
712 if (EQ (err, Qt)
713 || EQ (err, Qgnutls_e_again))
714 return Qnil;
716 return Qt;
719 DEFUN ("gnutls-error-fatalp", Fgnutls_error_fatalp, Sgnutls_error_fatalp, 1, 1, 0,
720 doc: /* Return non-nil if ERROR is fatal.
721 ERROR is an integer or a symbol with an integer `gnutls-code' property.
722 Usage: (gnutls-error-fatalp ERROR) */)
723 (Lisp_Object err)
725 Lisp_Object code;
727 if (EQ (err, Qt)) return Qnil;
729 if (SYMBOLP (err))
731 code = Fget (err, Qgnutls_code);
732 if (NUMBERP (code))
734 err = code;
736 else
738 error ("Symbol has no numeric gnutls-code property");
742 if (! TYPE_RANGED_INTEGERP (int, err))
743 error ("Not an error symbol or code");
745 if (0 == gnutls_error_is_fatal (XINT (err)))
746 return Qnil;
748 return Qt;
751 DEFUN ("gnutls-error-string", Fgnutls_error_string, Sgnutls_error_string, 1, 1, 0,
752 doc: /* Return a description of ERROR.
753 ERROR is an integer or a symbol with an integer `gnutls-code' property.
754 usage: (gnutls-error-string ERROR) */)
755 (Lisp_Object err)
757 Lisp_Object code;
759 if (EQ (err, Qt)) return build_string ("Not an error");
761 if (SYMBOLP (err))
763 code = Fget (err, Qgnutls_code);
764 if (NUMBERP (code))
766 err = code;
768 else
770 return build_string ("Symbol has no numeric gnutls-code property");
774 if (! TYPE_RANGED_INTEGERP (int, err))
775 return build_string ("Not an error symbol or code");
777 return build_string (gnutls_strerror (XINT (err)));
780 DEFUN ("gnutls-deinit", Fgnutls_deinit, Sgnutls_deinit, 1, 1, 0,
781 doc: /* Deallocate GnuTLS resources associated with process PROC.
782 See also `gnutls-init'. */)
783 (Lisp_Object proc)
785 return emacs_gnutls_deinit (proc);
788 static Lisp_Object
789 gnutls_hex_string (unsigned char *buf, ptrdiff_t buf_size, const char *prefix)
791 ptrdiff_t prefix_length = strlen (prefix);
792 ptrdiff_t retlen;
793 if (INT_MULTIPLY_WRAPV (buf_size, 3, &retlen)
794 || INT_ADD_WRAPV (prefix_length - (buf_size != 0), retlen, &retlen))
795 string_overflow ();
796 Lisp_Object ret = make_uninit_string (retlen);
797 char *string = SSDATA (ret);
798 strcpy (string, prefix);
800 for (ptrdiff_t i = 0; i < buf_size; i++)
801 sprintf (string + i * 3 + prefix_length,
802 i == buf_size - 1 ? "%02x" : "%02x:",
803 buf[i]);
805 return ret;
808 static Lisp_Object
809 gnutls_certificate_details (gnutls_x509_crt_t cert)
811 Lisp_Object res = Qnil;
812 int err;
813 size_t buf_size;
815 /* Version. */
817 int version = gnutls_x509_crt_get_version (cert);
818 check_memory_full (version);
819 if (version >= GNUTLS_E_SUCCESS)
820 res = nconc2 (res, list2 (intern (":version"),
821 make_number (version)));
824 /* Serial. */
825 buf_size = 0;
826 err = gnutls_x509_crt_get_serial (cert, NULL, &buf_size);
827 check_memory_full (err);
828 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER)
830 void *serial = xmalloc (buf_size);
831 err = gnutls_x509_crt_get_serial (cert, serial, &buf_size);
832 check_memory_full (err);
833 if (err >= GNUTLS_E_SUCCESS)
834 res = nconc2 (res, list2 (intern (":serial-number"),
835 gnutls_hex_string (serial, buf_size, "")));
836 xfree (serial);
839 /* Issuer. */
840 buf_size = 0;
841 err = gnutls_x509_crt_get_issuer_dn (cert, NULL, &buf_size);
842 check_memory_full (err);
843 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER)
845 char *dn = xmalloc (buf_size);
846 err = gnutls_x509_crt_get_issuer_dn (cert, dn, &buf_size);
847 check_memory_full (err);
848 if (err >= GNUTLS_E_SUCCESS)
849 res = nconc2 (res, list2 (intern (":issuer"),
850 make_string (dn, buf_size)));
851 xfree (dn);
854 /* Validity. */
856 /* Add 1 to the buffer size, since 1900 is added to tm_year and
857 that might add 1 to the year length. */
858 char buf[INT_STRLEN_BOUND (int) + 1 + sizeof "-12-31"];
859 struct tm t;
860 time_t tim = gnutls_x509_crt_get_activation_time (cert);
862 if (gmtime_r (&tim, &t) && strftime (buf, sizeof buf, "%Y-%m-%d", &t))
863 res = nconc2 (res, list2 (intern (":valid-from"), build_string (buf)));
865 tim = gnutls_x509_crt_get_expiration_time (cert);
866 if (gmtime_r (&tim, &t) && strftime (buf, sizeof buf, "%Y-%m-%d", &t))
867 res = nconc2 (res, list2 (intern (":valid-to"), build_string (buf)));
870 /* Subject. */
871 buf_size = 0;
872 err = gnutls_x509_crt_get_dn (cert, NULL, &buf_size);
873 check_memory_full (err);
874 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER)
876 char *dn = xmalloc (buf_size);
877 err = gnutls_x509_crt_get_dn (cert, dn, &buf_size);
878 check_memory_full (err);
879 if (err >= GNUTLS_E_SUCCESS)
880 res = nconc2 (res, list2 (intern (":subject"),
881 make_string (dn, buf_size)));
882 xfree (dn);
885 /* SubjectPublicKeyInfo. */
887 unsigned int bits;
889 err = gnutls_x509_crt_get_pk_algorithm (cert, &bits);
890 check_memory_full (err);
891 if (err >= GNUTLS_E_SUCCESS)
893 const char *name = gnutls_pk_algorithm_get_name (err);
894 if (name)
895 res = nconc2 (res, list2 (intern (":public-key-algorithm"),
896 build_string (name)));
898 name = gnutls_sec_param_get_name (gnutls_pk_bits_to_sec_param
899 (err, bits));
900 res = nconc2 (res, list2 (intern (":certificate-security-level"),
901 build_string (name)));
905 /* Unique IDs. */
906 buf_size = 0;
907 err = gnutls_x509_crt_get_issuer_unique_id (cert, NULL, &buf_size);
908 check_memory_full (err);
909 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER)
911 char *buf = xmalloc (buf_size);
912 err = gnutls_x509_crt_get_issuer_unique_id (cert, buf, &buf_size);
913 check_memory_full (err);
914 if (err >= GNUTLS_E_SUCCESS)
915 res = nconc2 (res, list2 (intern (":issuer-unique-id"),
916 make_string (buf, buf_size)));
917 xfree (buf);
920 buf_size = 0;
921 err = gnutls_x509_crt_get_subject_unique_id (cert, NULL, &buf_size);
922 check_memory_full (err);
923 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER)
925 char *buf = xmalloc (buf_size);
926 err = gnutls_x509_crt_get_subject_unique_id (cert, buf, &buf_size);
927 check_memory_full (err);
928 if (err >= GNUTLS_E_SUCCESS)
929 res = nconc2 (res, list2 (intern (":subject-unique-id"),
930 make_string (buf, buf_size)));
931 xfree (buf);
934 /* Signature. */
935 err = gnutls_x509_crt_get_signature_algorithm (cert);
936 check_memory_full (err);
937 if (err >= GNUTLS_E_SUCCESS)
939 const char *name = gnutls_sign_get_name (err);
940 if (name)
941 res = nconc2 (res, list2 (intern (":signature-algorithm"),
942 build_string (name)));
945 /* Public key ID. */
946 buf_size = 0;
947 err = gnutls_x509_crt_get_key_id (cert, 0, NULL, &buf_size);
948 check_memory_full (err);
949 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER)
951 void *buf = xmalloc (buf_size);
952 err = gnutls_x509_crt_get_key_id (cert, 0, buf, &buf_size);
953 check_memory_full (err);
954 if (err >= GNUTLS_E_SUCCESS)
955 res = nconc2 (res, list2 (intern (":public-key-id"),
956 gnutls_hex_string (buf, buf_size, "sha1:")));
957 xfree (buf);
960 /* Certificate fingerprint. */
961 buf_size = 0;
962 err = gnutls_x509_crt_get_fingerprint (cert, GNUTLS_DIG_SHA1,
963 NULL, &buf_size);
964 check_memory_full (err);
965 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER)
967 void *buf = xmalloc (buf_size);
968 err = gnutls_x509_crt_get_fingerprint (cert, GNUTLS_DIG_SHA1,
969 buf, &buf_size);
970 check_memory_full (err);
971 if (err >= GNUTLS_E_SUCCESS)
972 res = nconc2 (res, list2 (intern (":certificate-id"),
973 gnutls_hex_string (buf, buf_size, "sha1:")));
974 xfree (buf);
977 return res;
980 DEFUN ("gnutls-peer-status-warning-describe", Fgnutls_peer_status_warning_describe, Sgnutls_peer_status_warning_describe, 1, 1, 0,
981 doc: /* Describe the warning of a GnuTLS peer status from `gnutls-peer-status'. */)
982 (Lisp_Object status_symbol)
984 CHECK_SYMBOL (status_symbol);
986 if (EQ (status_symbol, intern (":invalid")))
987 return build_string ("certificate could not be verified");
989 if (EQ (status_symbol, intern (":revoked")))
990 return build_string ("certificate was revoked (CRL)");
992 if (EQ (status_symbol, intern (":self-signed")))
993 return build_string ("certificate signer was not found (self-signed)");
995 if (EQ (status_symbol, intern (":unknown-ca")))
996 return build_string ("the certificate was signed by an unknown "
997 "and therefore untrusted authority");
999 if (EQ (status_symbol, intern (":not-ca")))
1000 return build_string ("certificate signer is not a CA");
1002 if (EQ (status_symbol, intern (":insecure")))
1003 return build_string ("certificate was signed with an insecure algorithm");
1005 if (EQ (status_symbol, intern (":not-activated")))
1006 return build_string ("certificate is not yet activated");
1008 if (EQ (status_symbol, intern (":expired")))
1009 return build_string ("certificate has expired");
1011 if (EQ (status_symbol, intern (":no-host-match")))
1012 return build_string ("certificate host does not match hostname");
1014 return Qnil;
1017 DEFUN ("gnutls-peer-status", Fgnutls_peer_status, Sgnutls_peer_status, 1, 1, 0,
1018 doc: /* Describe a GnuTLS PROC peer certificate and any warnings about it.
1019 The return value is a property list with top-level keys :warnings and
1020 :certificate. The :warnings entry is a list of symbols you can describe with
1021 `gnutls-peer-status-warning-describe'. */)
1022 (Lisp_Object proc)
1024 Lisp_Object warnings = Qnil, result = Qnil;
1025 unsigned int verification;
1026 gnutls_session_t state;
1028 CHECK_PROCESS (proc);
1030 if (GNUTLS_INITSTAGE (proc) != GNUTLS_STAGE_READY)
1031 return Qnil;
1033 /* Then collect any warnings already computed by the handshake. */
1034 verification = XPROCESS (proc)->gnutls_peer_verification;
1036 if (verification & GNUTLS_CERT_INVALID)
1037 warnings = Fcons (intern (":invalid"), warnings);
1039 if (verification & GNUTLS_CERT_REVOKED)
1040 warnings = Fcons (intern (":revoked"), warnings);
1042 if (verification & GNUTLS_CERT_SIGNER_NOT_FOUND)
1043 warnings = Fcons (intern (":unknown-ca"), warnings);
1045 if (verification & GNUTLS_CERT_SIGNER_NOT_CA)
1046 warnings = Fcons (intern (":not-ca"), warnings);
1048 if (verification & GNUTLS_CERT_INSECURE_ALGORITHM)
1049 warnings = Fcons (intern (":insecure"), warnings);
1051 if (verification & GNUTLS_CERT_NOT_ACTIVATED)
1052 warnings = Fcons (intern (":not-activated"), warnings);
1054 if (verification & GNUTLS_CERT_EXPIRED)
1055 warnings = Fcons (intern (":expired"), warnings);
1057 if (XPROCESS (proc)->gnutls_extra_peer_verification &
1058 CERTIFICATE_NOT_MATCHING)
1059 warnings = Fcons (intern (":no-host-match"), warnings);
1061 /* This could get called in the INIT stage, when the certificate is
1062 not yet set. */
1063 if (XPROCESS (proc)->gnutls_certificate != NULL &&
1064 gnutls_x509_crt_check_issuer(XPROCESS (proc)->gnutls_certificate,
1065 XPROCESS (proc)->gnutls_certificate))
1066 warnings = Fcons (intern (":self-signed"), warnings);
1068 if (!NILP (warnings))
1069 result = list2 (intern (":warnings"), warnings);
1071 /* This could get called in the INIT stage, when the certificate is
1072 not yet set. */
1073 if (XPROCESS (proc)->gnutls_certificate != NULL)
1074 result = nconc2 (result, list2
1075 (intern (":certificate"),
1076 gnutls_certificate_details (XPROCESS (proc)->gnutls_certificate)));
1078 state = XPROCESS (proc)->gnutls_state;
1080 /* Diffie-Hellman prime bits. */
1082 int bits = gnutls_dh_get_prime_bits (state);
1083 check_memory_full (bits);
1084 if (bits > 0)
1085 result = nconc2 (result, list2 (intern (":diffie-hellman-prime-bits"),
1086 make_number (bits)));
1089 /* Key exchange. */
1090 result = nconc2
1091 (result, list2 (intern (":key-exchange"),
1092 build_string (gnutls_kx_get_name
1093 (gnutls_kx_get (state)))));
1095 /* Protocol name. */
1096 result = nconc2
1097 (result, list2 (intern (":protocol"),
1098 build_string (gnutls_protocol_get_name
1099 (gnutls_protocol_get_version (state)))));
1101 /* Cipher name. */
1102 result = nconc2
1103 (result, list2 (intern (":cipher"),
1104 build_string (gnutls_cipher_get_name
1105 (gnutls_cipher_get (state)))));
1107 /* MAC name. */
1108 result = nconc2
1109 (result, list2 (intern (":mac"),
1110 build_string (gnutls_mac_get_name
1111 (gnutls_mac_get (state)))));
1114 return result;
1117 /* Initialize global GnuTLS state to defaults.
1118 Call `gnutls-global-deinit' when GnuTLS usage is no longer needed.
1119 Return zero on success. */
1120 Lisp_Object
1121 emacs_gnutls_global_init (void)
1123 int ret = GNUTLS_E_SUCCESS;
1125 if (!gnutls_global_initialized)
1127 ret = gnutls_global_init ();
1128 if (ret == GNUTLS_E_SUCCESS)
1129 gnutls_global_initialized = 1;
1132 return gnutls_make_error (ret);
1135 static bool
1136 gnutls_ip_address_p (char *string)
1138 char c;
1140 while ((c = *string++) != 0)
1141 if (! ((c == '.' || c == ':' || (c >= '0' && c <= '9'))))
1142 return false;
1144 return true;
1147 #if 0
1148 /* Deinitialize global GnuTLS state.
1149 See also `gnutls-global-init'. */
1150 static Lisp_Object
1151 emacs_gnutls_global_deinit (void)
1153 if (gnutls_global_initialized)
1154 gnutls_global_deinit ();
1156 gnutls_global_initialized = 0;
1158 return gnutls_make_error (GNUTLS_E_SUCCESS);
1160 #endif
1162 static void ATTRIBUTE_FORMAT_PRINTF (2, 3)
1163 boot_error (struct Lisp_Process *p, const char *m, ...)
1165 va_list ap;
1166 va_start (ap, m);
1167 if (p->is_non_blocking_client)
1168 pset_status (p, list2 (Qfailed, vformat_string (m, ap)));
1169 else
1170 verror (m, ap);
1171 va_end (ap);
1174 Lisp_Object
1175 gnutls_verify_boot (Lisp_Object proc, Lisp_Object proplist)
1177 int ret;
1178 struct Lisp_Process *p = XPROCESS (proc);
1179 gnutls_session_t state = p->gnutls_state;
1180 unsigned int peer_verification;
1181 Lisp_Object warnings;
1182 int max_log_level = p->gnutls_log_level;
1183 Lisp_Object hostname, verify_error;
1184 bool verify_error_all = false;
1185 char *c_hostname;
1187 if (NILP (proplist))
1188 proplist = Fcdr (Fplist_get (p->childp, QCtls_parameters));
1190 verify_error = Fplist_get (proplist, QCverify_error);
1191 hostname = Fplist_get (proplist, QChostname);
1193 if (EQ (verify_error, Qt))
1194 verify_error_all = true;
1195 else if (NILP (Flistp (verify_error)))
1197 boot_error (p,
1198 "gnutls-boot: invalid :verify_error parameter (not a list)");
1199 return Qnil;
1202 if (!STRINGP (hostname))
1204 boot_error (p, "gnutls-boot: invalid :hostname parameter (not a string)");
1205 return Qnil;
1207 c_hostname = SSDATA (hostname);
1209 /* Now verify the peer, following
1210 http://www.gnu.org/software/gnutls/manual/html_node/Verifying-peer_0027s-certificate.html.
1211 The peer should present at least one certificate in the chain; do a
1212 check of the certificate's hostname with
1213 gnutls_x509_crt_check_hostname against :hostname. */
1215 ret = gnutls_certificate_verify_peers2 (state, &peer_verification);
1216 if (ret < GNUTLS_E_SUCCESS)
1217 return gnutls_make_error (ret);
1219 XPROCESS (proc)->gnutls_peer_verification = peer_verification;
1221 warnings = Fplist_get (Fgnutls_peer_status (proc), intern (":warnings"));
1222 if (!NILP (warnings))
1224 for (Lisp_Object tail = warnings; CONSP (tail); tail = XCDR (tail))
1226 Lisp_Object warning = XCAR (tail);
1227 Lisp_Object message = Fgnutls_peer_status_warning_describe (warning);
1228 if (!NILP (message))
1229 GNUTLS_LOG2 (1, max_log_level, "verification:", SSDATA (message));
1233 if (peer_verification != 0)
1235 if (verify_error_all
1236 || !NILP (Fmember (QCtrustfiles, verify_error)))
1238 emacs_gnutls_deinit (proc);
1239 boot_error (p,
1240 "Certificate validation failed %s, verification code %x",
1241 c_hostname, peer_verification);
1242 return Qnil;
1244 else
1246 GNUTLS_LOG2 (1, max_log_level, "certificate validation failed:",
1247 c_hostname);
1251 /* Up to here the process is the same for X.509 certificates and
1252 OpenPGP keys. From now on X.509 certificates are assumed. This
1253 can be easily extended to work with openpgp keys as well. */
1254 if (gnutls_certificate_type_get (state) == GNUTLS_CRT_X509)
1256 gnutls_x509_crt_t gnutls_verify_cert;
1257 const gnutls_datum_t *gnutls_verify_cert_list;
1258 unsigned int gnutls_verify_cert_list_size;
1260 ret = gnutls_x509_crt_init (&gnutls_verify_cert);
1261 if (ret < GNUTLS_E_SUCCESS)
1262 return gnutls_make_error (ret);
1264 gnutls_verify_cert_list
1265 = gnutls_certificate_get_peers (state, &gnutls_verify_cert_list_size);
1267 if (gnutls_verify_cert_list == NULL)
1269 gnutls_x509_crt_deinit (gnutls_verify_cert);
1270 emacs_gnutls_deinit (proc);
1271 boot_error (p, "No x509 certificate was found\n");
1272 return Qnil;
1275 /* Check only the first certificate in the given chain. */
1276 ret = gnutls_x509_crt_import (gnutls_verify_cert,
1277 &gnutls_verify_cert_list[0],
1278 GNUTLS_X509_FMT_DER);
1280 if (ret < GNUTLS_E_SUCCESS)
1282 gnutls_x509_crt_deinit (gnutls_verify_cert);
1283 return gnutls_make_error (ret);
1286 XPROCESS (proc)->gnutls_certificate = gnutls_verify_cert;
1288 int err = gnutls_x509_crt_check_hostname (gnutls_verify_cert,
1289 c_hostname);
1290 check_memory_full (err);
1291 if (!err)
1293 XPROCESS (proc)->gnutls_extra_peer_verification
1294 |= CERTIFICATE_NOT_MATCHING;
1295 if (verify_error_all
1296 || !NILP (Fmember (QChostname, verify_error)))
1298 gnutls_x509_crt_deinit (gnutls_verify_cert);
1299 emacs_gnutls_deinit (proc);
1300 boot_error (p, "The x509 certificate does not match \"%s\"",
1301 c_hostname);
1302 return Qnil;
1304 else
1305 GNUTLS_LOG2 (1, max_log_level, "x509 certificate does not match:",
1306 c_hostname);
1310 /* Set this flag only if the whole initialization succeeded. */
1311 XPROCESS (proc)->gnutls_p = true;
1313 return gnutls_make_error (ret);
1316 DEFUN ("gnutls-boot", Fgnutls_boot, Sgnutls_boot, 3, 3, 0,
1317 doc: /* Initialize GnuTLS client for process PROC with TYPE+PROPLIST.
1318 Currently only client mode is supported. Return a success/failure
1319 value you can check with `gnutls-errorp'.
1321 TYPE is a symbol, either `gnutls-anon' or `gnutls-x509pki'.
1322 PROPLIST is a property list with the following keys:
1324 :hostname is a string naming the remote host.
1326 :priority is a GnuTLS priority string, defaults to "NORMAL".
1328 :trustfiles is a list of PEM-encoded trust files for `gnutls-x509pki'.
1330 :crlfiles is a list of PEM-encoded CRL lists for `gnutls-x509pki'.
1332 :keylist is an alist of PEM-encoded key files and PEM-encoded
1333 certificates for `gnutls-x509pki'.
1335 :callbacks is an alist of callback functions, see below.
1337 :loglevel is the debug level requested from GnuTLS, try 4.
1339 :verify-flags is a bitset as per GnuTLS'
1340 gnutls_certificate_set_verify_flags.
1342 :verify-hostname-error is ignored. Pass :hostname in :verify-error
1343 instead.
1345 :verify-error is a list of symbols to express verification checks or
1346 t to do all checks. Currently it can contain `:trustfiles' and
1347 `:hostname' to verify the certificate or the hostname respectively.
1349 :min-prime-bits is the minimum accepted number of bits the client will
1350 accept in Diffie-Hellman key exchange.
1352 :complete-negotiation, if non-nil, will make negotiation complete
1353 before returning even on non-blocking sockets.
1355 The debug level will be set for this process AND globally for GnuTLS.
1356 So if you set it higher or lower at any point, it affects global
1357 debugging.
1359 Note that the priority is set on the client. The server does not use
1360 the protocols's priority except for disabling protocols that were not
1361 specified.
1363 Processes must be initialized with this function before other GnuTLS
1364 functions are used. This function allocates resources which can only
1365 be deallocated by calling `gnutls-deinit' or by calling it again.
1367 The callbacks alist can have a `verify' key, associated with a
1368 verification function (UNUSED).
1370 Each authentication type may need additional information in order to
1371 work. For X.509 PKI (`gnutls-x509pki'), you probably need at least
1372 one trustfile (usually a CA bundle). */)
1373 (Lisp_Object proc, Lisp_Object type, Lisp_Object proplist)
1375 int ret = GNUTLS_E_SUCCESS;
1376 int max_log_level = 0;
1378 gnutls_session_t state;
1379 gnutls_certificate_credentials_t x509_cred = NULL;
1380 gnutls_anon_client_credentials_t anon_cred = NULL;
1381 Lisp_Object global_init;
1382 char const *priority_string_ptr = "NORMAL"; /* default priority string. */
1383 char *c_hostname;
1385 /* Placeholders for the property list elements. */
1386 Lisp_Object priority_string;
1387 Lisp_Object trustfiles;
1388 Lisp_Object crlfiles;
1389 Lisp_Object keylist;
1390 /* Lisp_Object callbacks; */
1391 Lisp_Object loglevel;
1392 Lisp_Object hostname;
1393 Lisp_Object prime_bits;
1394 struct Lisp_Process *p = XPROCESS (proc);
1396 CHECK_PROCESS (proc);
1397 CHECK_SYMBOL (type);
1398 CHECK_LIST (proplist);
1400 if (NILP (Fgnutls_available_p ()))
1402 boot_error (p, "GnuTLS not available");
1403 return Qnil;
1406 if (!EQ (type, Qgnutls_x509pki) && !EQ (type, Qgnutls_anon))
1408 boot_error (p, "Invalid GnuTLS credential type");
1409 return Qnil;
1412 hostname = Fplist_get (proplist, QChostname);
1413 priority_string = Fplist_get (proplist, QCpriority);
1414 trustfiles = Fplist_get (proplist, QCtrustfiles);
1415 keylist = Fplist_get (proplist, QCkeylist);
1416 crlfiles = Fplist_get (proplist, QCcrlfiles);
1417 loglevel = Fplist_get (proplist, QCloglevel);
1418 prime_bits = Fplist_get (proplist, QCmin_prime_bits);
1420 if (!STRINGP (hostname))
1422 boot_error (p, "gnutls-boot: invalid :hostname parameter (not a string)");
1423 return Qnil;
1425 c_hostname = SSDATA (hostname);
1427 state = XPROCESS (proc)->gnutls_state;
1429 if (TYPE_RANGED_INTEGERP (int, loglevel))
1431 gnutls_global_set_log_function (gnutls_log_function);
1432 #ifdef HAVE_GNUTLS3
1433 gnutls_global_set_audit_log_function (gnutls_audit_log_function);
1434 #endif
1435 gnutls_global_set_log_level (XINT (loglevel));
1436 max_log_level = XINT (loglevel);
1437 XPROCESS (proc)->gnutls_log_level = max_log_level;
1440 GNUTLS_LOG2 (1, max_log_level, "connecting to host:", c_hostname);
1442 /* Always initialize globals. */
1443 global_init = emacs_gnutls_global_init ();
1444 if (! NILP (Fgnutls_errorp (global_init)))
1445 return global_init;
1447 /* Before allocating new credentials, deallocate any credentials
1448 that PROC might already have. */
1449 emacs_gnutls_deinit (proc);
1451 /* Mark PROC as a GnuTLS process. */
1452 XPROCESS (proc)->gnutls_state = NULL;
1453 XPROCESS (proc)->gnutls_x509_cred = NULL;
1454 XPROCESS (proc)->gnutls_anon_cred = NULL;
1455 pset_gnutls_cred_type (XPROCESS (proc), type);
1456 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_EMPTY;
1458 GNUTLS_LOG (1, max_log_level, "allocating credentials");
1459 if (EQ (type, Qgnutls_x509pki))
1461 Lisp_Object verify_flags;
1462 unsigned int gnutls_verify_flags = GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT;
1464 GNUTLS_LOG (2, max_log_level, "allocating x509 credentials");
1465 check_memory_full (gnutls_certificate_allocate_credentials (&x509_cred));
1466 XPROCESS (proc)->gnutls_x509_cred = x509_cred;
1468 verify_flags = Fplist_get (proplist, QCverify_flags);
1469 if (NUMBERP (verify_flags))
1471 gnutls_verify_flags = XINT (verify_flags);
1472 GNUTLS_LOG (2, max_log_level, "setting verification flags");
1474 else if (NILP (verify_flags))
1475 GNUTLS_LOG (2, max_log_level, "using default verification flags");
1476 else
1477 GNUTLS_LOG (2, max_log_level, "ignoring invalid verify-flags");
1479 gnutls_certificate_set_verify_flags (x509_cred, gnutls_verify_flags);
1481 else /* Qgnutls_anon: */
1483 GNUTLS_LOG (2, max_log_level, "allocating anon credentials");
1484 check_memory_full (gnutls_anon_allocate_client_credentials (&anon_cred));
1485 XPROCESS (proc)->gnutls_anon_cred = anon_cred;
1488 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_CRED_ALLOC;
1490 if (EQ (type, Qgnutls_x509pki))
1492 /* TODO: GNUTLS_X509_FMT_DER is also an option. */
1493 int file_format = GNUTLS_X509_FMT_PEM;
1494 Lisp_Object tail;
1496 #if GNUTLS_VERSION_MAJOR + \
1497 (GNUTLS_VERSION_MINOR > 0 || GNUTLS_VERSION_PATCH >= 20) > 3
1498 ret = gnutls_certificate_set_x509_system_trust (x509_cred);
1499 if (ret < GNUTLS_E_SUCCESS)
1501 check_memory_full (ret);
1502 GNUTLS_LOG2i (4, max_log_level,
1503 "setting system trust failed with code ", ret);
1505 #endif
1507 for (tail = trustfiles; CONSP (tail); tail = XCDR (tail))
1509 Lisp_Object trustfile = XCAR (tail);
1510 if (STRINGP (trustfile))
1512 GNUTLS_LOG2 (1, max_log_level, "setting the trustfile: ",
1513 SSDATA (trustfile));
1514 trustfile = ENCODE_FILE (trustfile);
1515 #ifdef WINDOWSNT
1516 /* Since GnuTLS doesn't support UTF-8 or UTF-16 encoded
1517 file names on Windows, we need to re-encode the file
1518 name using the current ANSI codepage. */
1519 trustfile = ansi_encode_filename (trustfile);
1520 #endif
1521 ret = gnutls_certificate_set_x509_trust_file
1522 (x509_cred,
1523 SSDATA (trustfile),
1524 file_format);
1526 if (ret < GNUTLS_E_SUCCESS)
1527 return gnutls_make_error (ret);
1529 else
1531 emacs_gnutls_deinit (proc);
1532 boot_error (p, "Invalid trustfile");
1533 return Qnil;
1537 for (tail = crlfiles; CONSP (tail); tail = XCDR (tail))
1539 Lisp_Object crlfile = XCAR (tail);
1540 if (STRINGP (crlfile))
1542 GNUTLS_LOG2 (1, max_log_level, "setting the CRL file: ",
1543 SSDATA (crlfile));
1544 crlfile = ENCODE_FILE (crlfile);
1545 #ifdef WINDOWSNT
1546 crlfile = ansi_encode_filename (crlfile);
1547 #endif
1548 ret = gnutls_certificate_set_x509_crl_file
1549 (x509_cred, SSDATA (crlfile), file_format);
1551 if (ret < GNUTLS_E_SUCCESS)
1552 return gnutls_make_error (ret);
1554 else
1556 emacs_gnutls_deinit (proc);
1557 boot_error (p, "Invalid CRL file");
1558 return Qnil;
1562 for (tail = keylist; CONSP (tail); tail = XCDR (tail))
1564 Lisp_Object keyfile = Fcar (XCAR (tail));
1565 Lisp_Object certfile = Fcar (Fcdr (XCAR (tail)));
1566 if (STRINGP (keyfile) && STRINGP (certfile))
1568 GNUTLS_LOG2 (1, max_log_level, "setting the client key file: ",
1569 SSDATA (keyfile));
1570 GNUTLS_LOG2 (1, max_log_level, "setting the client cert file: ",
1571 SSDATA (certfile));
1572 keyfile = ENCODE_FILE (keyfile);
1573 certfile = ENCODE_FILE (certfile);
1574 #ifdef WINDOWSNT
1575 keyfile = ansi_encode_filename (keyfile);
1576 certfile = ansi_encode_filename (certfile);
1577 #endif
1578 ret = gnutls_certificate_set_x509_key_file
1579 (x509_cred, SSDATA (certfile), SSDATA (keyfile), file_format);
1581 if (ret < GNUTLS_E_SUCCESS)
1582 return gnutls_make_error (ret);
1584 else
1586 emacs_gnutls_deinit (proc);
1587 boot_error (p, STRINGP (keyfile) ? "Invalid client cert file"
1588 : "Invalid client key file");
1589 return Qnil;
1594 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_FILES;
1595 GNUTLS_LOG (1, max_log_level, "gnutls callbacks");
1596 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_CALLBACKS;
1598 /* Call gnutls_init here: */
1600 GNUTLS_LOG (1, max_log_level, "gnutls_init");
1601 int gnutls_flags = GNUTLS_CLIENT;
1602 #ifdef GNUTLS_NONBLOCK
1603 if (XPROCESS (proc)->is_non_blocking_client)
1604 gnutls_flags |= GNUTLS_NONBLOCK;
1605 #endif
1606 ret = gnutls_init (&state, gnutls_flags);
1607 XPROCESS (proc)->gnutls_state = state;
1608 if (ret < GNUTLS_E_SUCCESS)
1609 return gnutls_make_error (ret);
1610 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_INIT;
1612 if (STRINGP (priority_string))
1614 priority_string_ptr = SSDATA (priority_string);
1615 GNUTLS_LOG2 (1, max_log_level, "got non-default priority string:",
1616 priority_string_ptr);
1618 else
1620 GNUTLS_LOG2 (1, max_log_level, "using default priority string:",
1621 priority_string_ptr);
1624 GNUTLS_LOG (1, max_log_level, "setting the priority string");
1625 ret = gnutls_priority_set_direct (state, priority_string_ptr, NULL);
1626 if (ret < GNUTLS_E_SUCCESS)
1627 return gnutls_make_error (ret);
1629 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_PRIORITY;
1631 if (INTEGERP (prime_bits))
1632 gnutls_dh_set_prime_bits (state, XUINT (prime_bits));
1634 ret = EQ (type, Qgnutls_x509pki)
1635 ? gnutls_credentials_set (state, GNUTLS_CRD_CERTIFICATE, x509_cred)
1636 : gnutls_credentials_set (state, GNUTLS_CRD_ANON, anon_cred);
1637 if (ret < GNUTLS_E_SUCCESS)
1638 return gnutls_make_error (ret);
1640 if (!gnutls_ip_address_p (c_hostname))
1642 ret = gnutls_server_name_set (state, GNUTLS_NAME_DNS, c_hostname,
1643 strlen (c_hostname));
1644 if (ret < GNUTLS_E_SUCCESS)
1645 return gnutls_make_error (ret);
1648 XPROCESS (proc)->gnutls_complete_negotiation_p =
1649 !NILP (Fplist_get (proplist, QCcomplete_negotiation));
1650 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_CRED_SET;
1651 ret = emacs_gnutls_handshake (XPROCESS (proc));
1652 if (ret < GNUTLS_E_SUCCESS)
1653 return gnutls_make_error (ret);
1655 return gnutls_verify_boot (proc, proplist);
1658 DEFUN ("gnutls-bye", Fgnutls_bye,
1659 Sgnutls_bye, 2, 2, 0,
1660 doc: /* Terminate current GnuTLS connection for process PROC.
1661 The connection should have been initiated using `gnutls-handshake'.
1663 If CONT is not nil the TLS connection gets terminated and further
1664 receives and sends will be disallowed. If the return value is zero you
1665 may continue using the connection. If CONT is nil, GnuTLS actually
1666 sends an alert containing a close request and waits for the peer to
1667 reply with the same message. In order to reuse the connection you
1668 should wait for an EOF from the peer.
1670 This function may also return `gnutls-e-again', or
1671 `gnutls-e-interrupted'. */)
1672 (Lisp_Object proc, Lisp_Object cont)
1674 gnutls_session_t state;
1675 int ret;
1677 CHECK_PROCESS (proc);
1679 state = XPROCESS (proc)->gnutls_state;
1681 gnutls_x509_crt_deinit (XPROCESS (proc)->gnutls_certificate);
1683 ret = gnutls_bye (state, NILP (cont) ? GNUTLS_SHUT_RDWR : GNUTLS_SHUT_WR);
1685 return gnutls_make_error (ret);
1688 #endif /* HAVE_GNUTLS */
1690 DEFUN ("gnutls-available-p", Fgnutls_available_p, Sgnutls_available_p, 0, 0, 0,
1691 doc: /* Return t if GnuTLS is available in this instance of Emacs. */)
1692 (void)
1694 #ifdef HAVE_GNUTLS
1695 # ifdef WINDOWSNT
1696 Lisp_Object found = Fassq (Qgnutls, Vlibrary_cache);
1697 if (CONSP (found))
1698 return XCDR (found);
1699 else
1701 Lisp_Object status;
1702 status = init_gnutls_functions () ? Qt : Qnil;
1703 Vlibrary_cache = Fcons (Fcons (Qgnutls, status), Vlibrary_cache);
1704 return status;
1706 # else /* !WINDOWSNT */
1707 return Qt;
1708 # endif /* !WINDOWSNT */
1709 #else /* !HAVE_GNUTLS */
1710 return Qnil;
1711 #endif /* !HAVE_GNUTLS */
1714 void
1715 syms_of_gnutls (void)
1717 DEFSYM (Qlibgnutls_version, "libgnutls-version");
1718 Fset (Qlibgnutls_version,
1719 #ifdef HAVE_GNUTLS
1720 make_number (GNUTLS_VERSION_MAJOR * 10000
1721 + GNUTLS_VERSION_MINOR * 100
1722 + GNUTLS_VERSION_PATCH)
1723 #else
1724 make_number (-1)
1725 #endif
1727 #ifdef HAVE_GNUTLS
1728 gnutls_global_initialized = 0;
1730 DEFSYM (Qgnutls_code, "gnutls-code");
1731 DEFSYM (Qgnutls_anon, "gnutls-anon");
1732 DEFSYM (Qgnutls_x509pki, "gnutls-x509pki");
1734 /* The following are for the property list of 'gnutls-boot'. */
1735 DEFSYM (QChostname, ":hostname");
1736 DEFSYM (QCpriority, ":priority");
1737 DEFSYM (QCtrustfiles, ":trustfiles");
1738 DEFSYM (QCkeylist, ":keylist");
1739 DEFSYM (QCcrlfiles, ":crlfiles");
1740 DEFSYM (QCmin_prime_bits, ":min-prime-bits");
1741 DEFSYM (QCloglevel, ":loglevel");
1742 DEFSYM (QCcomplete_negotiation, ":complete-negotiation");
1743 DEFSYM (QCverify_flags, ":verify-flags");
1744 DEFSYM (QCverify_error, ":verify-error");
1746 DEFSYM (Qgnutls_e_interrupted, "gnutls-e-interrupted");
1747 Fput (Qgnutls_e_interrupted, Qgnutls_code,
1748 make_number (GNUTLS_E_INTERRUPTED));
1750 DEFSYM (Qgnutls_e_again, "gnutls-e-again");
1751 Fput (Qgnutls_e_again, Qgnutls_code,
1752 make_number (GNUTLS_E_AGAIN));
1754 DEFSYM (Qgnutls_e_invalid_session, "gnutls-e-invalid-session");
1755 Fput (Qgnutls_e_invalid_session, Qgnutls_code,
1756 make_number (GNUTLS_E_INVALID_SESSION));
1758 DEFSYM (Qgnutls_e_not_ready_for_handshake, "gnutls-e-not-ready-for-handshake");
1759 Fput (Qgnutls_e_not_ready_for_handshake, Qgnutls_code,
1760 make_number (GNUTLS_E_APPLICATION_ERROR_MIN));
1762 defsubr (&Sgnutls_get_initstage);
1763 defsubr (&Sgnutls_asynchronous_parameters);
1764 defsubr (&Sgnutls_errorp);
1765 defsubr (&Sgnutls_error_fatalp);
1766 defsubr (&Sgnutls_error_string);
1767 defsubr (&Sgnutls_boot);
1768 defsubr (&Sgnutls_deinit);
1769 defsubr (&Sgnutls_bye);
1770 defsubr (&Sgnutls_peer_status);
1771 defsubr (&Sgnutls_peer_status_warning_describe);
1773 DEFVAR_INT ("gnutls-log-level", global_gnutls_log_level,
1774 doc: /* Logging level used by the GnuTLS functions.
1775 Set this larger than 0 to get debug output in the *Messages* buffer.
1776 1 is for important messages, 2 is for debug data, and higher numbers
1777 are as per the GnuTLS logging conventions. */);
1778 global_gnutls_log_level = 0;
1780 #endif /* HAVE_GNUTLS */
1782 defsubr (&Sgnutls_available_p);