aboutsummaryrefslogtreecommitdiffstats
path: root/src/gnutls.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gnutls.c')
-rw-r--r--src/gnutls.c691
1 files changed, 346 insertions, 345 deletions
diff --git a/src/gnutls.c b/src/gnutls.c
index 76cfa5dcc98..6b5cb47001b 100644
--- a/src/gnutls.c
+++ b/src/gnutls.c
@@ -1,5 +1,5 @@
1/* GnuTLS glue for GNU Emacs. 1/* GnuTLS glue for GNU Emacs.
2 Copyright (C) 2010-2011 Free Software Foundation, Inc. 2 Copyright (C) 2010-2012 Free Software Foundation, Inc.
3 3
4This file is part of GNU Emacs. 4This file is part of GNU Emacs.
5 5
@@ -35,7 +35,6 @@ static int
35emacs_gnutls_handle_error (gnutls_session_t, int err); 35emacs_gnutls_handle_error (gnutls_session_t, int err);
36 36
37static Lisp_Object Qgnutls_dll; 37static Lisp_Object Qgnutls_dll;
38static Lisp_Object Qgnutls_log_level;
39static Lisp_Object Qgnutls_code; 38static Lisp_Object Qgnutls_code;
40static Lisp_Object Qgnutls_anon, Qgnutls_x509pki; 39static Lisp_Object Qgnutls_anon, Qgnutls_x509pki;
41static Lisp_Object Qgnutls_e_interrupted, Qgnutls_e_again, 40static Lisp_Object Qgnutls_e_interrupted, Qgnutls_e_again,
@@ -43,18 +42,19 @@ static Lisp_Object Qgnutls_e_interrupted, Qgnutls_e_again,
43static int gnutls_global_initialized; 42static int gnutls_global_initialized;
44 43
45/* The following are for the property list of `gnutls-boot'. */ 44/* The following are for the property list of `gnutls-boot'. */
46static Lisp_Object Qgnutls_bootprop_priority; 45static Lisp_Object QCgnutls_bootprop_priority;
47static Lisp_Object Qgnutls_bootprop_trustfiles; 46static Lisp_Object QCgnutls_bootprop_trustfiles;
48static Lisp_Object Qgnutls_bootprop_keylist; 47static Lisp_Object QCgnutls_bootprop_keylist;
49static Lisp_Object Qgnutls_bootprop_crlfiles; 48static Lisp_Object QCgnutls_bootprop_crlfiles;
50static Lisp_Object Qgnutls_bootprop_callbacks; 49static Lisp_Object QCgnutls_bootprop_callbacks;
51static Lisp_Object Qgnutls_bootprop_loglevel; 50static Lisp_Object QCgnutls_bootprop_loglevel;
52static Lisp_Object Qgnutls_bootprop_hostname; 51static Lisp_Object QCgnutls_bootprop_hostname;
53static Lisp_Object Qgnutls_bootprop_verify_flags; 52static Lisp_Object QCgnutls_bootprop_min_prime_bits;
54static Lisp_Object Qgnutls_bootprop_verify_hostname_error; 53static Lisp_Object QCgnutls_bootprop_verify_flags;
54static Lisp_Object QCgnutls_bootprop_verify_hostname_error;
55 55
56/* Callback keys for `gnutls-boot'. Unused currently. */ 56/* Callback keys for `gnutls-boot'. Unused currently. */
57static Lisp_Object Qgnutls_bootprop_callbacks_verify; 57static Lisp_Object QCgnutls_bootprop_callbacks_verify;
58 58
59static void gnutls_log_function (int, const char *); 59static void gnutls_log_function (int, const char *);
60static void gnutls_log_function2 (int, const char*, const char*); 60static void gnutls_log_function2 (int, const char*, const char*);
@@ -72,39 +72,41 @@ static void gnutls_log_function2 (int, const char*, const char*);
72 } 72 }
73 73
74DEF_GNUTLS_FN (gnutls_alert_description_t, gnutls_alert_get, 74DEF_GNUTLS_FN (gnutls_alert_description_t, gnutls_alert_get,
75 (gnutls_session_t)); 75 (gnutls_session_t));
76DEF_GNUTLS_FN (const char *, gnutls_alert_get_name, 76DEF_GNUTLS_FN (const char *, gnutls_alert_get_name,
77 (gnutls_alert_description_t)); 77 (gnutls_alert_description_t));
78DEF_GNUTLS_FN (int, gnutls_alert_send_appropriate, (gnutls_session_t, int)); 78DEF_GNUTLS_FN (int, gnutls_alert_send_appropriate, (gnutls_session_t, int));
79DEF_GNUTLS_FN (int, gnutls_anon_allocate_client_credentials, 79DEF_GNUTLS_FN (int, gnutls_anon_allocate_client_credentials,
80 (gnutls_anon_client_credentials_t *)); 80 (gnutls_anon_client_credentials_t *));
81DEF_GNUTLS_FN (void, gnutls_anon_free_client_credentials, 81DEF_GNUTLS_FN (void, gnutls_anon_free_client_credentials,
82 (gnutls_anon_client_credentials_t)); 82 (gnutls_anon_client_credentials_t));
83DEF_GNUTLS_FN (int, gnutls_bye, (gnutls_session_t, gnutls_close_request_t)); 83DEF_GNUTLS_FN (int, gnutls_bye, (gnutls_session_t, gnutls_close_request_t));
84DEF_GNUTLS_FN (int, gnutls_certificate_allocate_credentials, 84DEF_GNUTLS_FN (int, gnutls_certificate_allocate_credentials,
85 (gnutls_certificate_credentials_t *)); 85 (gnutls_certificate_credentials_t *));
86DEF_GNUTLS_FN (void, gnutls_certificate_free_credentials, 86DEF_GNUTLS_FN (void, gnutls_certificate_free_credentials,
87 (gnutls_certificate_credentials_t)); 87 (gnutls_certificate_credentials_t));
88DEF_GNUTLS_FN (const gnutls_datum_t *, gnutls_certificate_get_peers, 88DEF_GNUTLS_FN (const gnutls_datum_t *, gnutls_certificate_get_peers,
89 (gnutls_session_t, unsigned int *)); 89 (gnutls_session_t, unsigned int *));
90DEF_GNUTLS_FN (void, gnutls_certificate_set_verify_flags, 90DEF_GNUTLS_FN (void, gnutls_certificate_set_verify_flags,
91 (gnutls_certificate_credentials_t, unsigned int)); 91 (gnutls_certificate_credentials_t, unsigned int));
92DEF_GNUTLS_FN (int, gnutls_certificate_set_x509_crl_file, 92DEF_GNUTLS_FN (int, gnutls_certificate_set_x509_crl_file,
93 (gnutls_certificate_credentials_t, const char *, 93 (gnutls_certificate_credentials_t, const char *,
94 gnutls_x509_crt_fmt_t)); 94 gnutls_x509_crt_fmt_t));
95DEF_GNUTLS_FN (int, gnutls_certificate_set_x509_key_file, 95DEF_GNUTLS_FN (int, gnutls_certificate_set_x509_key_file,
96 (gnutls_certificate_credentials_t, const char *, const char *, 96 (gnutls_certificate_credentials_t, const char *, const char *,
97 gnutls_x509_crt_fmt_t)); 97 gnutls_x509_crt_fmt_t));
98DEF_GNUTLS_FN (int, gnutls_certificate_set_x509_trust_file, 98DEF_GNUTLS_FN (int, gnutls_certificate_set_x509_trust_file,
99 (gnutls_certificate_credentials_t, const char *, 99 (gnutls_certificate_credentials_t, const char *,
100 gnutls_x509_crt_fmt_t)); 100 gnutls_x509_crt_fmt_t));
101DEF_GNUTLS_FN (gnutls_certificate_type_t, gnutls_certificate_type_get, 101DEF_GNUTLS_FN (gnutls_certificate_type_t, gnutls_certificate_type_get,
102 (gnutls_session_t)); 102 (gnutls_session_t));
103DEF_GNUTLS_FN (int, gnutls_certificate_verify_peers2, 103DEF_GNUTLS_FN (int, gnutls_certificate_verify_peers2,
104 (gnutls_session_t, unsigned int *)); 104 (gnutls_session_t, unsigned int *));
105DEF_GNUTLS_FN (int, gnutls_credentials_set, 105DEF_GNUTLS_FN (int, gnutls_credentials_set,
106 (gnutls_session_t, gnutls_credentials_type_t, void *)); 106 (gnutls_session_t, gnutls_credentials_type_t, void *));
107DEF_GNUTLS_FN (void, gnutls_deinit, (gnutls_session_t)); 107DEF_GNUTLS_FN (void, gnutls_deinit, (gnutls_session_t));
108DEF_GNUTLS_FN (void, gnutls_dh_set_prime_bits,
109 (gnutls_session_t, unsigned int));
108DEF_GNUTLS_FN (int, gnutls_error_is_fatal, (int)); 110DEF_GNUTLS_FN (int, gnutls_error_is_fatal, (int));
109DEF_GNUTLS_FN (int, gnutls_global_init, (void)); 111DEF_GNUTLS_FN (int, gnutls_global_init, (void));
110DEF_GNUTLS_FN (void, gnutls_global_set_log_function, (gnutls_log_func)); 112DEF_GNUTLS_FN (void, gnutls_global_set_log_function, (gnutls_log_func));
@@ -116,37 +118,39 @@ DEF_GNUTLS_FN (void, gnutls_global_set_mem_functions,
116DEF_GNUTLS_FN (int, gnutls_handshake, (gnutls_session_t)); 118DEF_GNUTLS_FN (int, gnutls_handshake, (gnutls_session_t));
117DEF_GNUTLS_FN (int, gnutls_init, (gnutls_session_t *, gnutls_connection_end_t)); 119DEF_GNUTLS_FN (int, gnutls_init, (gnutls_session_t *, gnutls_connection_end_t));
118DEF_GNUTLS_FN (int, gnutls_priority_set_direct, 120DEF_GNUTLS_FN (int, gnutls_priority_set_direct,
119 (gnutls_session_t, const char *, const char **)); 121 (gnutls_session_t, const char *, const char **));
120DEF_GNUTLS_FN (size_t, gnutls_record_check_pending, (gnutls_session_t)); 122DEF_GNUTLS_FN (size_t, gnutls_record_check_pending, (gnutls_session_t));
121DEF_GNUTLS_FN (ssize_t, gnutls_record_recv, (gnutls_session_t, void *, size_t)); 123DEF_GNUTLS_FN (ssize_t, gnutls_record_recv, (gnutls_session_t, void *, size_t));
122DEF_GNUTLS_FN (ssize_t, gnutls_record_send, 124DEF_GNUTLS_FN (ssize_t, gnutls_record_send,
123 (gnutls_session_t, const void *, size_t)); 125 (gnutls_session_t, const void *, size_t));
124DEF_GNUTLS_FN (const char *, gnutls_strerror, (int)); 126DEF_GNUTLS_FN (const char *, gnutls_strerror, (int));
125DEF_GNUTLS_FN (void, gnutls_transport_set_errno, (gnutls_session_t, int)); 127DEF_GNUTLS_FN (void, gnutls_transport_set_errno, (gnutls_session_t, int));
128DEF_GNUTLS_FN (const char *, gnutls_check_version, (const char *));
126DEF_GNUTLS_FN (void, gnutls_transport_set_lowat, (gnutls_session_t, int)); 129DEF_GNUTLS_FN (void, gnutls_transport_set_lowat, (gnutls_session_t, int));
127DEF_GNUTLS_FN (void, gnutls_transport_set_ptr2, 130DEF_GNUTLS_FN (void, gnutls_transport_set_ptr2,
128 (gnutls_session_t, gnutls_transport_ptr_t, 131 (gnutls_session_t, gnutls_transport_ptr_t,
129 gnutls_transport_ptr_t)); 132 gnutls_transport_ptr_t));
130DEF_GNUTLS_FN (void, gnutls_transport_set_pull_function, 133DEF_GNUTLS_FN (void, gnutls_transport_set_pull_function,
131 (gnutls_session_t, gnutls_pull_func)); 134 (gnutls_session_t, gnutls_pull_func));
132DEF_GNUTLS_FN (void, gnutls_transport_set_push_function, 135DEF_GNUTLS_FN (void, gnutls_transport_set_push_function,
133 (gnutls_session_t, gnutls_push_func)); 136 (gnutls_session_t, gnutls_push_func));
134DEF_GNUTLS_FN (int, gnutls_x509_crt_check_hostname, 137DEF_GNUTLS_FN (int, gnutls_x509_crt_check_hostname,
135 (gnutls_x509_crt_t, const char *)); 138 (gnutls_x509_crt_t, const char *));
136DEF_GNUTLS_FN (void, gnutls_x509_crt_deinit, (gnutls_x509_crt_t)); 139DEF_GNUTLS_FN (void, gnutls_x509_crt_deinit, (gnutls_x509_crt_t));
137DEF_GNUTLS_FN (int, gnutls_x509_crt_import, 140DEF_GNUTLS_FN (int, gnutls_x509_crt_import,
138 (gnutls_x509_crt_t, const gnutls_datum_t *, 141 (gnutls_x509_crt_t, const gnutls_datum_t *,
139 gnutls_x509_crt_fmt_t)); 142 gnutls_x509_crt_fmt_t));
140DEF_GNUTLS_FN (int, gnutls_x509_crt_init, (gnutls_x509_crt_t *)); 143DEF_GNUTLS_FN (int, gnutls_x509_crt_init, (gnutls_x509_crt_t *));
141 144
142static int 145static int
143init_gnutls_functions (Lisp_Object libraries) 146init_gnutls_functions (Lisp_Object libraries)
144{ 147{
145 HMODULE library; 148 HMODULE library;
149 int max_log_level = 1;
146 150
147 if (!(library = w32_delayed_load (libraries, Qgnutls_dll))) 151 if (!(library = w32_delayed_load (libraries, Qgnutls_dll)))
148 { 152 {
149 GNUTLS_LOG (1, 1, "GnuTLS library not found"); 153 GNUTLS_LOG (1, max_log_level, "GnuTLS library not found");
150 return 0; 154 return 0;
151 } 155 }
152 156
@@ -167,6 +171,7 @@ init_gnutls_functions (Lisp_Object libraries)
167 LOAD_GNUTLS_FN (library, gnutls_certificate_verify_peers2); 171 LOAD_GNUTLS_FN (library, gnutls_certificate_verify_peers2);
168 LOAD_GNUTLS_FN (library, gnutls_credentials_set); 172 LOAD_GNUTLS_FN (library, gnutls_credentials_set);
169 LOAD_GNUTLS_FN (library, gnutls_deinit); 173 LOAD_GNUTLS_FN (library, gnutls_deinit);
174 LOAD_GNUTLS_FN (library, gnutls_dh_set_prime_bits);
170 LOAD_GNUTLS_FN (library, gnutls_error_is_fatal); 175 LOAD_GNUTLS_FN (library, gnutls_error_is_fatal);
171 LOAD_GNUTLS_FN (library, gnutls_global_init); 176 LOAD_GNUTLS_FN (library, gnutls_global_init);
172 LOAD_GNUTLS_FN (library, gnutls_global_set_log_function); 177 LOAD_GNUTLS_FN (library, gnutls_global_set_log_function);
@@ -180,7 +185,11 @@ init_gnutls_functions (Lisp_Object libraries)
180 LOAD_GNUTLS_FN (library, gnutls_record_send); 185 LOAD_GNUTLS_FN (library, gnutls_record_send);
181 LOAD_GNUTLS_FN (library, gnutls_strerror); 186 LOAD_GNUTLS_FN (library, gnutls_strerror);
182 LOAD_GNUTLS_FN (library, gnutls_transport_set_errno); 187 LOAD_GNUTLS_FN (library, gnutls_transport_set_errno);
183 LOAD_GNUTLS_FN (library, gnutls_transport_set_lowat); 188 LOAD_GNUTLS_FN (library, gnutls_check_version);
189 /* We don't need to call gnutls_transport_set_lowat in GnuTLS 2.11.1
190 and later, and the function was removed entirely in 3.0.0. */
191 if (!fn_gnutls_check_version ("2.11.1"))
192 LOAD_GNUTLS_FN (library, gnutls_transport_set_lowat);
184 LOAD_GNUTLS_FN (library, gnutls_transport_set_ptr2); 193 LOAD_GNUTLS_FN (library, gnutls_transport_set_ptr2);
185 LOAD_GNUTLS_FN (library, gnutls_transport_set_pull_function); 194 LOAD_GNUTLS_FN (library, gnutls_transport_set_pull_function);
186 LOAD_GNUTLS_FN (library, gnutls_transport_set_push_function); 195 LOAD_GNUTLS_FN (library, gnutls_transport_set_push_function);
@@ -189,8 +198,10 @@ init_gnutls_functions (Lisp_Object libraries)
189 LOAD_GNUTLS_FN (library, gnutls_x509_crt_import); 198 LOAD_GNUTLS_FN (library, gnutls_x509_crt_import);
190 LOAD_GNUTLS_FN (library, gnutls_x509_crt_init); 199 LOAD_GNUTLS_FN (library, gnutls_x509_crt_init);
191 200
192 GNUTLS_LOG2 (1, 1, "GnuTLS library loaded:", 201 max_log_level = global_gnutls_log_level;
193 SDATA (Fget (Qgnutls_dll, QCloaded_from))); 202
203 GNUTLS_LOG2 (1, max_log_level, "GnuTLS library loaded:",
204 SDATA (Fget (Qgnutls_dll, QCloaded_from)));
194 return 1; 205 return 1;
195} 206}
196 207
@@ -213,6 +224,7 @@ init_gnutls_functions (Lisp_Object libraries)
213#define fn_gnutls_certificate_verify_peers2 gnutls_certificate_verify_peers2 224#define fn_gnutls_certificate_verify_peers2 gnutls_certificate_verify_peers2
214#define fn_gnutls_credentials_set gnutls_credentials_set 225#define fn_gnutls_credentials_set gnutls_credentials_set
215#define fn_gnutls_deinit gnutls_deinit 226#define fn_gnutls_deinit gnutls_deinit
227#define fn_gnutls_dh_set_prime_bits gnutls_dh_set_prime_bits
216#define fn_gnutls_error_is_fatal gnutls_error_is_fatal 228#define fn_gnutls_error_is_fatal gnutls_error_is_fatal
217#define fn_gnutls_global_init gnutls_global_init 229#define fn_gnutls_global_init gnutls_global_init
218#define fn_gnutls_global_set_log_function gnutls_global_set_log_function 230#define fn_gnutls_global_set_log_function gnutls_global_set_log_function
@@ -260,29 +272,34 @@ emacs_gnutls_handshake (struct Lisp_Process *proc)
260 { 272 {
261#ifdef WINDOWSNT 273#ifdef WINDOWSNT
262 /* On W32 we cannot transfer socket handles between different runtime 274 /* On W32 we cannot transfer socket handles between different runtime
263 libraries, so we tell GnuTLS to use our special push/pull 275 libraries, so we tell GnuTLS to use our special push/pull
264 functions. */ 276 functions. */
265 fn_gnutls_transport_set_ptr2 (state, 277 fn_gnutls_transport_set_ptr2 (state,
266 (gnutls_transport_ptr_t) proc, 278 (gnutls_transport_ptr_t) proc,
267 (gnutls_transport_ptr_t) proc); 279 (gnutls_transport_ptr_t) proc);
268 fn_gnutls_transport_set_push_function (state, &emacs_gnutls_push); 280 fn_gnutls_transport_set_push_function (state, &emacs_gnutls_push);
269 fn_gnutls_transport_set_pull_function (state, &emacs_gnutls_pull); 281 fn_gnutls_transport_set_pull_function (state, &emacs_gnutls_pull);
270 282
271 /* For non blocking sockets or other custom made pull/push 283 /* For non blocking sockets or other custom made pull/push
272 functions the gnutls_transport_set_lowat must be called, with 284 functions the gnutls_transport_set_lowat must be called, with
273 a zero low water mark value. (GnuTLS 2.10.4 documentation) 285 a zero low water mark value. (GnuTLS 2.10.4 documentation)
274 286
275 (Note: this is probably not strictly necessary as the lowat 287 (Note: this is probably not strictly necessary as the lowat
276 value is only used when no custom pull/push functions are 288 value is only used when no custom pull/push functions are
277 set.) */ 289 set.) */
278 fn_gnutls_transport_set_lowat (state, 0); 290 /* According to GnuTLS NEWS file, lowat level has been set to
291 zero by default in version 2.11.1, and the function
292 gnutls_transport_set_lowat was removed from the library in
293 version 2.99.0. */
294 if (!fn_gnutls_check_version ("2.11.1"))
295 fn_gnutls_transport_set_lowat (state, 0);
279#else 296#else
280 /* This is how GnuTLS takes sockets: as file descriptors passed 297 /* This is how GnuTLS takes sockets: as file descriptors passed
281 in. For an Emacs process socket, infd and outfd are the 298 in. For an Emacs process socket, infd and outfd are the
282 same but we use this two-argument version for clarity. */ 299 same but we use this two-argument version for clarity. */
283 fn_gnutls_transport_set_ptr2 (state, 300 fn_gnutls_transport_set_ptr2 (state,
284 (gnutls_transport_ptr_t) (long) proc->infd, 301 (gnutls_transport_ptr_t) (long) proc->infd,
285 (gnutls_transport_ptr_t) (long) proc->outfd); 302 (gnutls_transport_ptr_t) (long) proc->outfd);
286#endif 303#endif
287 304
288 proc->gnutls_initstage = GNUTLS_STAGE_TRANSPORT_POINTERS_SET; 305 proc->gnutls_initstage = GNUTLS_STAGE_TRANSPORT_POINTERS_SET;
@@ -328,15 +345,16 @@ emacs_gnutls_write (struct Lisp_Process *proc, const char *buf, EMACS_INT nbyte)
328 EMACS_INT bytes_written; 345 EMACS_INT bytes_written;
329 gnutls_session_t state = proc->gnutls_state; 346 gnutls_session_t state = proc->gnutls_state;
330 347
331 if (proc->gnutls_initstage != GNUTLS_STAGE_READY) { 348 if (proc->gnutls_initstage != GNUTLS_STAGE_READY)
349 {
332#ifdef EWOULDBLOCK 350#ifdef EWOULDBLOCK
333 errno = EWOULDBLOCK; 351 errno = EWOULDBLOCK;
334#endif 352#endif
335#ifdef EAGAIN 353#ifdef EAGAIN
336 errno = EAGAIN; 354 errno = EAGAIN;
337#endif 355#endif
338 return 0; 356 return 0;
339 } 357 }
340 358
341 bytes_written = 0; 359 bytes_written = 0;
342 360
@@ -345,12 +363,26 @@ emacs_gnutls_write (struct Lisp_Process *proc, const char *buf, EMACS_INT nbyte)
345 rtnval = fn_gnutls_record_send (state, buf, nbyte); 363 rtnval = fn_gnutls_record_send (state, buf, nbyte);
346 364
347 if (rtnval < 0) 365 if (rtnval < 0)
348 { 366 {
349 if (rtnval == GNUTLS_E_AGAIN || rtnval == GNUTLS_E_INTERRUPTED) 367 if (rtnval == GNUTLS_E_INTERRUPTED)
350 continue; 368 continue;
351 else 369 else
352 break; 370 {
353 } 371 /* If we get GNUTLS_E_AGAIN, then set errno
372 appropriately so that send_process retries the
373 correct way instead of erroring out. */
374 if (rtnval == GNUTLS_E_AGAIN)
375 {
376#ifdef EWOULDBLOCK
377 errno = EWOULDBLOCK;
378#endif
379#ifdef EAGAIN
380 errno = EAGAIN;
381#endif
382 }
383 break;
384 }
385 }
354 386
355 buf += rtnval; 387 buf += rtnval;
356 nbyte -= rtnval; 388 nbyte -= rtnval;
@@ -375,6 +407,9 @@ emacs_gnutls_read (struct Lisp_Process *proc, char *buf, EMACS_INT nbyte)
375 rtnval = fn_gnutls_record_recv (state, buf, nbyte); 407 rtnval = fn_gnutls_record_recv (state, buf, nbyte);
376 if (rtnval >= 0) 408 if (rtnval >= 0)
377 return rtnval; 409 return rtnval;
410 else if (rtnval == GNUTLS_E_UNEXPECTED_PACKET_LENGTH)
411 /* The peer closed the connection. */
412 return 0;
378 else if (emacs_gnutls_handle_error (state, rtnval) == 0) 413 else if (emacs_gnutls_handle_error (state, rtnval) == 0)
379 /* non-fatal error */ 414 /* non-fatal error */
380 return -1; 415 return -1;
@@ -389,7 +424,6 @@ emacs_gnutls_read (struct Lisp_Process *proc, char *buf, EMACS_INT nbyte)
389static int 424static int
390emacs_gnutls_handle_error (gnutls_session_t session, int err) 425emacs_gnutls_handle_error (gnutls_session_t session, int err)
391{ 426{
392 Lisp_Object gnutls_log_level = Fsymbol_value (Qgnutls_log_level);
393 int max_log_level = 0; 427 int max_log_level = 0;
394 428
395 int ret; 429 int ret;
@@ -399,8 +433,7 @@ emacs_gnutls_handle_error (gnutls_session_t session, int err)
399 if (err >= 0) 433 if (err >= 0)
400 return 0; 434 return 0;
401 435
402 if (NUMBERP (gnutls_log_level)) 436 max_log_level = global_gnutls_log_level;
403 max_log_level = XINT (gnutls_log_level);
404 437
405 /* TODO: use gnutls-error-fatalp and gnutls-error-string. */ 438 /* TODO: use gnutls-error-fatalp and gnutls-error-string. */
406 439
@@ -456,6 +489,44 @@ gnutls_make_error (int err)
456 return make_number (err); 489 return make_number (err);
457} 490}
458 491
492Lisp_Object
493emacs_gnutls_deinit (Lisp_Object proc)
494{
495 int log_level;
496
497 CHECK_PROCESS (proc);
498
499 if (XPROCESS (proc)->gnutls_p == 0)
500 return Qnil;
501
502 log_level = XPROCESS (proc)->gnutls_log_level;
503
504 if (XPROCESS (proc)->gnutls_x509_cred)
505 {
506 GNUTLS_LOG (2, log_level, "Deallocating x509 credentials");
507 fn_gnutls_certificate_free_credentials (XPROCESS (proc)->gnutls_x509_cred);
508 XPROCESS (proc)->gnutls_x509_cred = NULL;
509 }
510
511 if (XPROCESS (proc)->gnutls_anon_cred)
512 {
513 GNUTLS_LOG (2, log_level, "Deallocating anon credentials");
514 fn_gnutls_anon_free_client_credentials (XPROCESS (proc)->gnutls_anon_cred);
515 XPROCESS (proc)->gnutls_anon_cred = NULL;
516 }
517
518 if (XPROCESS (proc)->gnutls_state)
519 {
520 fn_gnutls_deinit (XPROCESS (proc)->gnutls_state);
521 XPROCESS (proc)->gnutls_state = NULL;
522 if (GNUTLS_INITSTAGE (proc) >= GNUTLS_STAGE_INIT)
523 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_INIT - 1;
524 }
525
526 XPROCESS (proc)->gnutls_p = 0;
527 return Qt;
528}
529
459DEFUN ("gnutls-get-initstage", Fgnutls_get_initstage, Sgnutls_get_initstage, 1, 1, 0, 530DEFUN ("gnutls-get-initstage", Fgnutls_get_initstage, Sgnutls_get_initstage, 1, 1, 0,
460 doc: /* Return the GnuTLS init stage of process PROC. 531 doc: /* Return the GnuTLS init stage of process PROC.
461See also `gnutls-boot'. */) 532See also `gnutls-boot'. */)
@@ -543,18 +614,7 @@ DEFUN ("gnutls-deinit", Fgnutls_deinit, Sgnutls_deinit, 1, 1, 0,
543See also `gnutls-init'. */) 614See also `gnutls-init'. */)
544 (Lisp_Object proc) 615 (Lisp_Object proc)
545{ 616{
546 gnutls_session_t state; 617 return emacs_gnutls_deinit (proc);
547
548 CHECK_PROCESS (proc);
549 state = XPROCESS (proc)->gnutls_state;
550
551 if (GNUTLS_INITSTAGE (proc) >= GNUTLS_STAGE_INIT)
552 {
553 fn_gnutls_deinit (state);
554 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_INIT - 1;
555 }
556
557 return Qt;
558} 618}
559 619
560DEFUN ("gnutls-available-p", Fgnutls_available_p, Sgnutls_available_p, 0, 0, 0, 620DEFUN ("gnutls-available-p", Fgnutls_available_p, Sgnutls_available_p, 0, 0, 0,
@@ -614,7 +674,7 @@ emacs_gnutls_global_deinit (void)
614 674
615DEFUN ("gnutls-boot", Fgnutls_boot, Sgnutls_boot, 3, 3, 0, 675DEFUN ("gnutls-boot", Fgnutls_boot, Sgnutls_boot, 3, 3, 0,
616 doc: /* Initialize GnuTLS client for process PROC with TYPE+PROPLIST. 676 doc: /* Initialize GnuTLS client for process PROC with TYPE+PROPLIST.
617Currently only client mode is supported. Returns a success/failure 677Currently only client mode is supported. Return a success/failure
618value you can check with `gnutls-errorp'. 678value you can check with `gnutls-errorp'.
619 679
620TYPE is a symbol, either `gnutls-anon' or `gnutls-x509pki'. 680TYPE is a symbol, either `gnutls-anon' or `gnutls-x509pki'.
@@ -641,6 +701,9 @@ gnutls_certificate_set_verify_flags.
641:verify-hostname-error, if non-nil, makes a hostname mismatch an 701:verify-hostname-error, if non-nil, makes a hostname mismatch an
642error. Otherwise it will be just a warning. 702error. Otherwise it will be just a warning.
643 703
704:min-prime-bits is the minimum accepted number of bits the client will
705accept in Diffie-Hellman key exchange.
706
644The debug level will be set for this process AND globally for GnuTLS. 707The debug level will be set for this process AND globally for GnuTLS.
645So if you set it higher or lower at any point, it affects global 708So if you set it higher or lower at any point, it affects global
646debugging. 709debugging.
@@ -662,23 +725,13 @@ one trustfile (usually a CA bundle). */)
662 (Lisp_Object proc, Lisp_Object type, Lisp_Object proplist) 725 (Lisp_Object proc, Lisp_Object type, Lisp_Object proplist)
663{ 726{
664 int ret = GNUTLS_E_SUCCESS; 727 int ret = GNUTLS_E_SUCCESS;
665
666 int max_log_level = 0; 728 int max_log_level = 0;
667 729
668 /* TODO: GNUTLS_X509_FMT_DER is also an option. */
669 int file_format = GNUTLS_X509_FMT_PEM;
670
671 unsigned int gnutls_verify_flags = GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT;
672 gnutls_x509_crt_t gnutls_verify_cert;
673 unsigned int gnutls_verify_cert_list_size;
674 const gnutls_datum_t *gnutls_verify_cert_list;
675
676 gnutls_session_t state; 730 gnutls_session_t state;
677 gnutls_certificate_credentials_t x509_cred; 731 gnutls_certificate_credentials_t x509_cred = NULL;
678 gnutls_anon_client_credentials_t anon_cred; 732 gnutls_anon_client_credentials_t anon_cred = NULL;
679 Lisp_Object global_init; 733 Lisp_Object global_init;
680 char const *priority_string_ptr = "NORMAL"; /* default priority string. */ 734 char const *priority_string_ptr = "NORMAL"; /* default priority string. */
681 Lisp_Object tail;
682 unsigned int peer_verification; 735 unsigned int peer_verification;
683 char* c_hostname; 736 char* c_hostname;
684 737
@@ -690,9 +743,9 @@ one trustfile (usually a CA bundle). */)
690 /* Lisp_Object callbacks; */ 743 /* Lisp_Object callbacks; */
691 Lisp_Object loglevel; 744 Lisp_Object loglevel;
692 Lisp_Object hostname; 745 Lisp_Object hostname;
693 Lisp_Object verify_flags;
694 /* Lisp_Object verify_error; */ 746 /* Lisp_Object verify_error; */
695 Lisp_Object verify_hostname_error; 747 Lisp_Object verify_hostname_error;
748 Lisp_Object prime_bits;
696 749
697 CHECK_PROCESS (proc); 750 CHECK_PROCESS (proc);
698 CHECK_SYMBOL (type); 751 CHECK_SYMBOL (type);
@@ -704,25 +757,25 @@ one trustfile (usually a CA bundle). */)
704 return gnutls_make_error (GNUTLS_EMACS_ERROR_NOT_LOADED); 757 return gnutls_make_error (GNUTLS_EMACS_ERROR_NOT_LOADED);
705 } 758 }
706 759
707 hostname = Fplist_get (proplist, Qgnutls_bootprop_hostname); 760 if (!EQ (type, Qgnutls_x509pki) && !EQ (type, Qgnutls_anon))
708 priority_string = Fplist_get (proplist, Qgnutls_bootprop_priority); 761 {
709 trustfiles = Fplist_get (proplist, Qgnutls_bootprop_trustfiles); 762 error ("Invalid GnuTLS credential type");
710 keylist = Fplist_get (proplist, Qgnutls_bootprop_keylist); 763 return gnutls_make_error (GNUTLS_EMACS_ERROR_INVALID_TYPE);
711 crlfiles = Fplist_get (proplist, Qgnutls_bootprop_crlfiles); 764 }
712 /* callbacks = Fplist_get (proplist, Qgnutls_bootprop_callbacks); */ 765
713 loglevel = Fplist_get (proplist, Qgnutls_bootprop_loglevel); 766 hostname = Fplist_get (proplist, QCgnutls_bootprop_hostname);
714 verify_flags = Fplist_get (proplist, Qgnutls_bootprop_verify_flags); 767 priority_string = Fplist_get (proplist, QCgnutls_bootprop_priority);
715 /* verify_error = Fplist_get (proplist, Qgnutls_bootprop_verify_error); */ 768 trustfiles = Fplist_get (proplist, QCgnutls_bootprop_trustfiles);
716 verify_hostname_error = Fplist_get (proplist, Qgnutls_bootprop_verify_hostname_error); 769 keylist = Fplist_get (proplist, QCgnutls_bootprop_keylist);
770 crlfiles = Fplist_get (proplist, QCgnutls_bootprop_crlfiles);
771 loglevel = Fplist_get (proplist, QCgnutls_bootprop_loglevel);
772 verify_hostname_error = Fplist_get (proplist, QCgnutls_bootprop_verify_hostname_error);
773 prime_bits = Fplist_get (proplist, QCgnutls_bootprop_min_prime_bits);
717 774
718 if (!STRINGP (hostname)) 775 if (!STRINGP (hostname))
719 error ("gnutls-boot: invalid :hostname parameter"); 776 error ("gnutls-boot: invalid :hostname parameter");
720
721 c_hostname = SSDATA (hostname); 777 c_hostname = SSDATA (hostname);
722 778
723 state = XPROCESS (proc)->gnutls_state;
724 XPROCESS (proc)->gnutls_p = 1;
725
726 if (NUMBERP (loglevel)) 779 if (NUMBERP (loglevel))
727 { 780 {
728 fn_gnutls_global_set_log_function (gnutls_log_function); 781 fn_gnutls_global_set_log_function (gnutls_log_function);
@@ -736,226 +789,168 @@ one trustfile (usually a CA bundle). */)
736 if (! NILP (Fgnutls_errorp (global_init))) 789 if (! NILP (Fgnutls_errorp (global_init)))
737 return global_init; 790 return global_init;
738 791
739 /* deinit and free resources. */ 792 /* Before allocating new credentials, deallocate any credentials
740 if (GNUTLS_INITSTAGE (proc) >= GNUTLS_STAGE_CRED_ALLOC) 793 that PROC might already have. */
741 { 794 emacs_gnutls_deinit (proc);
742 GNUTLS_LOG (1, max_log_level, "deallocating credentials");
743
744 if (EQ (type, Qgnutls_x509pki))
745 {
746 GNUTLS_LOG (2, max_log_level, "deallocating x509 credentials");
747 x509_cred = XPROCESS (proc)->gnutls_x509_cred;
748 fn_gnutls_certificate_free_credentials (x509_cred);
749 }
750 else if (EQ (type, Qgnutls_anon))
751 {
752 GNUTLS_LOG (2, max_log_level, "deallocating anon credentials");
753 anon_cred = XPROCESS (proc)->gnutls_anon_cred;
754 fn_gnutls_anon_free_client_credentials (anon_cred);
755 }
756 else
757 {
758 error ("unknown credential type");
759 ret = GNUTLS_EMACS_ERROR_INVALID_TYPE;
760 }
761
762 if (GNUTLS_INITSTAGE (proc) >= GNUTLS_STAGE_INIT)
763 {
764 GNUTLS_LOG (1, max_log_level, "deallocating x509 credentials");
765 Fgnutls_deinit (proc);
766 }
767 }
768 795
796 /* Mark PROC as a GnuTLS process. */
797 XPROCESS (proc)->gnutls_p = 1;
798 XPROCESS (proc)->gnutls_state = NULL;
799 XPROCESS (proc)->gnutls_x509_cred = NULL;
800 XPROCESS (proc)->gnutls_anon_cred = NULL;
801 XPROCESS (proc)->gnutls_cred_type = type;
769 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_EMPTY; 802 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_EMPTY;
770 803
771 GNUTLS_LOG (1, max_log_level, "allocating credentials"); 804 GNUTLS_LOG (1, max_log_level, "allocating credentials");
772
773 if (EQ (type, Qgnutls_x509pki)) 805 if (EQ (type, Qgnutls_x509pki))
774 { 806 {
807 Lisp_Object verify_flags;
808 unsigned int gnutls_verify_flags = GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT;
809
775 GNUTLS_LOG (2, max_log_level, "allocating x509 credentials"); 810 GNUTLS_LOG (2, max_log_level, "allocating x509 credentials");
776 x509_cred = XPROCESS (proc)->gnutls_x509_cred;
777 fn_gnutls_certificate_allocate_credentials (&x509_cred); 811 fn_gnutls_certificate_allocate_credentials (&x509_cred);
812 XPROCESS (proc)->gnutls_x509_cred = x509_cred;
778 813
814 verify_flags = Fplist_get (proplist, QCgnutls_bootprop_verify_flags);
779 if (NUMBERP (verify_flags)) 815 if (NUMBERP (verify_flags))
780 { 816 {
781 gnutls_verify_flags = XINT (verify_flags); 817 gnutls_verify_flags = XINT (verify_flags);
782 GNUTLS_LOG (2, max_log_level, "setting verification flags"); 818 GNUTLS_LOG (2, max_log_level, "setting verification flags");
783 } 819 }
784 else if (NILP (verify_flags)) 820 else if (NILP (verify_flags))
785 { 821 GNUTLS_LOG (2, max_log_level, "using default verification flags");
786 /* The default is already GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT. */
787 GNUTLS_LOG (2, max_log_level, "using default verification flags");
788 }
789 else 822 else
790 { 823 GNUTLS_LOG (2, max_log_level, "ignoring invalid verify-flags");
791 /* The default is already GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT. */ 824
792 GNUTLS_LOG (2, max_log_level, "ignoring invalid verify-flags");
793 }
794 fn_gnutls_certificate_set_verify_flags (x509_cred, gnutls_verify_flags); 825 fn_gnutls_certificate_set_verify_flags (x509_cred, gnutls_verify_flags);
795 } 826 }
796 else if (EQ (type, Qgnutls_anon)) 827 else /* Qgnutls_anon: */
797 { 828 {
798 GNUTLS_LOG (2, max_log_level, "allocating anon credentials"); 829 GNUTLS_LOG (2, max_log_level, "allocating anon credentials");
799 anon_cred = XPROCESS (proc)->gnutls_anon_cred;
800 fn_gnutls_anon_allocate_client_credentials (&anon_cred); 830 fn_gnutls_anon_allocate_client_credentials (&anon_cred);
831 XPROCESS (proc)->gnutls_anon_cred = anon_cred;
801 } 832 }
802 else
803 {
804 error ("unknown credential type");
805 ret = GNUTLS_EMACS_ERROR_INVALID_TYPE;
806 }
807
808 if (ret < GNUTLS_E_SUCCESS)
809 return gnutls_make_error (ret);
810 833
811 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_CRED_ALLOC; 834 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_CRED_ALLOC;
812 835
813 if (EQ (type, Qgnutls_x509pki)) 836 if (EQ (type, Qgnutls_x509pki))
814 { 837 {
838 /* TODO: GNUTLS_X509_FMT_DER is also an option. */
839 int file_format = GNUTLS_X509_FMT_PEM;
840 Lisp_Object tail;
841
815 for (tail = trustfiles; !NILP (tail); tail = Fcdr (tail)) 842 for (tail = trustfiles; !NILP (tail); tail = Fcdr (tail))
816 { 843 {
817 Lisp_Object trustfile = Fcar (tail); 844 Lisp_Object trustfile = Fcar (tail);
818 if (STRINGP (trustfile)) 845 if (STRINGP (trustfile))
819 { 846 {
820 GNUTLS_LOG2 (1, max_log_level, "setting the trustfile: ", 847 GNUTLS_LOG2 (1, max_log_level, "setting the trustfile: ",
821 SSDATA (trustfile)); 848 SSDATA (trustfile));
822 ret = fn_gnutls_certificate_set_x509_trust_file 849 ret = fn_gnutls_certificate_set_x509_trust_file
823 (x509_cred, 850 (x509_cred,
824 SSDATA (trustfile), 851 SSDATA (trustfile),
825 file_format); 852 file_format);
826 853
827 if (ret < GNUTLS_E_SUCCESS) 854 if (ret < GNUTLS_E_SUCCESS)
828 return gnutls_make_error (ret); 855 return gnutls_make_error (ret);
829 } 856 }
830 else 857 else
831 { 858 {
832 error ("Sorry, GnuTLS can't use non-string trustfile %s", 859 emacs_gnutls_deinit (proc);
833 SDATA (trustfile)); 860 error ("Invalid trustfile");
834 } 861 }
835 } 862 }
836 863
837 for (tail = crlfiles; !NILP (tail); tail = Fcdr (tail)) 864 for (tail = crlfiles; !NILP (tail); tail = Fcdr (tail))
838 { 865 {
839 Lisp_Object crlfile = Fcar (tail); 866 Lisp_Object crlfile = Fcar (tail);
840 if (STRINGP (crlfile)) 867 if (STRINGP (crlfile))
841 { 868 {
842 GNUTLS_LOG2 (1, max_log_level, "setting the CRL file: ", 869 GNUTLS_LOG2 (1, max_log_level, "setting the CRL file: ",
843 SSDATA (crlfile)); 870 SSDATA (crlfile));
844 ret = fn_gnutls_certificate_set_x509_crl_file 871 ret = fn_gnutls_certificate_set_x509_crl_file
845 (x509_cred, 872 (x509_cred, SSDATA (crlfile), file_format);
846 SSDATA (crlfile), 873
847 file_format); 874 if (ret < GNUTLS_E_SUCCESS)
848 875 return gnutls_make_error (ret);
849 if (ret < GNUTLS_E_SUCCESS) 876 }
850 return gnutls_make_error (ret); 877 else
851 } 878 {
852 else 879 emacs_gnutls_deinit (proc);
853 { 880 error ("Invalid CRL file");
854 error ("Sorry, GnuTLS can't use non-string CRL file %s", 881 }
855 SDATA (crlfile)); 882 }
856 }
857 }
858 883
859 for (tail = keylist; !NILP (tail); tail = Fcdr (tail)) 884 for (tail = keylist; !NILP (tail); tail = Fcdr (tail))
860 { 885 {
861 Lisp_Object keyfile = Fcar (Fcar (tail)); 886 Lisp_Object keyfile = Fcar (Fcar (tail));
862 Lisp_Object certfile = Fcar (Fcdr (tail)); 887 Lisp_Object certfile = Fcar (Fcdr (tail));
863 if (STRINGP (keyfile) && STRINGP (certfile)) 888 if (STRINGP (keyfile) && STRINGP (certfile))
864 { 889 {
865 GNUTLS_LOG2 (1, max_log_level, "setting the client key file: ", 890 GNUTLS_LOG2 (1, max_log_level, "setting the client key file: ",
866 SSDATA (keyfile)); 891 SSDATA (keyfile));
867 GNUTLS_LOG2 (1, max_log_level, "setting the client cert file: ", 892 GNUTLS_LOG2 (1, max_log_level, "setting the client cert file: ",
868 SSDATA (certfile)); 893 SSDATA (certfile));
869 ret = fn_gnutls_certificate_set_x509_key_file 894 ret = fn_gnutls_certificate_set_x509_key_file
870 (x509_cred, 895 (x509_cred, SSDATA (certfile), SSDATA (keyfile), file_format);
871 SSDATA (certfile), 896
872 SSDATA (keyfile), 897 if (ret < GNUTLS_E_SUCCESS)
873 file_format); 898 return gnutls_make_error (ret);
874 899 }
875 if (ret < GNUTLS_E_SUCCESS) 900 else
876 return gnutls_make_error (ret); 901 {
877 } 902 emacs_gnutls_deinit (proc);
878 else 903 error (STRINGP (keyfile) ? "Invalid client cert file"
879 { 904 : "Invalid client key file");
880 if (STRINGP (keyfile)) 905 }
881 error ("Sorry, GnuTLS can't use non-string client cert file %s", 906 }
882 SDATA (certfile));
883 else
884 error ("Sorry, GnuTLS can't use non-string client key file %s",
885 SDATA (keyfile));
886 }
887 }
888 } 907 }
889 908
890 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_FILES; 909 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_FILES;
891
892 GNUTLS_LOG (1, max_log_level, "gnutls callbacks"); 910 GNUTLS_LOG (1, max_log_level, "gnutls callbacks");
893
894 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_CALLBACKS; 911 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_CALLBACKS;
895 912
896#ifdef HAVE_GNUTLS_CALLBACK_CERTIFICATE_VERIFY 913 /* Call gnutls_init here: */
897#else
898#endif
899 914
900 GNUTLS_LOG (1, max_log_level, "gnutls_init"); 915 GNUTLS_LOG (1, max_log_level, "gnutls_init");
901
902 ret = fn_gnutls_init (&state, GNUTLS_CLIENT); 916 ret = fn_gnutls_init (&state, GNUTLS_CLIENT);
903 917 XPROCESS (proc)->gnutls_state = state;
904 if (ret < GNUTLS_E_SUCCESS) 918 if (ret < GNUTLS_E_SUCCESS)
905 return gnutls_make_error (ret); 919 return gnutls_make_error (ret);
906
907 XPROCESS (proc)->gnutls_state = state;
908
909 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_INIT; 920 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_INIT;
910 921
911 if (STRINGP (priority_string)) 922 if (STRINGP (priority_string))
912 { 923 {
913 priority_string_ptr = SSDATA (priority_string); 924 priority_string_ptr = SSDATA (priority_string);
914 GNUTLS_LOG2 (1, max_log_level, "got non-default priority string:", 925 GNUTLS_LOG2 (1, max_log_level, "got non-default priority string:",
915 priority_string_ptr); 926 priority_string_ptr);
916 } 927 }
917 else 928 else
918 { 929 {
919 GNUTLS_LOG2 (1, max_log_level, "using default priority string:", 930 GNUTLS_LOG2 (1, max_log_level, "using default priority string:",
920 priority_string_ptr); 931 priority_string_ptr);
921 } 932 }
922 933
923 GNUTLS_LOG (1, max_log_level, "setting the priority string"); 934 GNUTLS_LOG (1, max_log_level, "setting the priority string");
924
925 ret = fn_gnutls_priority_set_direct (state, 935 ret = fn_gnutls_priority_set_direct (state,
926 priority_string_ptr, 936 priority_string_ptr,
927 NULL); 937 NULL);
928
929 if (ret < GNUTLS_E_SUCCESS) 938 if (ret < GNUTLS_E_SUCCESS)
930 return gnutls_make_error (ret); 939 return gnutls_make_error (ret);
931 940
932 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_PRIORITY; 941 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_PRIORITY;
933 942
934 if (EQ (type, Qgnutls_x509pki)) 943 if (INTEGERP (prime_bits))
935 { 944 fn_gnutls_dh_set_prime_bits (state, XUINT (prime_bits));
936 ret = fn_gnutls_credentials_set (state, GNUTLS_CRD_CERTIFICATE, x509_cred);
937 }
938 else if (EQ (type, Qgnutls_anon))
939 {
940 ret = fn_gnutls_credentials_set (state, GNUTLS_CRD_ANON, anon_cred);
941 }
942 else
943 {
944 error ("unknown credential type");
945 ret = GNUTLS_EMACS_ERROR_INVALID_TYPE;
946 }
947 945
946 ret = EQ (type, Qgnutls_x509pki)
947 ? fn_gnutls_credentials_set (state, GNUTLS_CRD_CERTIFICATE, x509_cred)
948 : fn_gnutls_credentials_set (state, GNUTLS_CRD_ANON, anon_cred);
948 if (ret < GNUTLS_E_SUCCESS) 949 if (ret < GNUTLS_E_SUCCESS)
949 return gnutls_make_error (ret); 950 return gnutls_make_error (ret);
950 951
951 XPROCESS (proc)->gnutls_anon_cred = anon_cred;
952 XPROCESS (proc)->gnutls_x509_cred = x509_cred;
953 XPROCESS (proc)->gnutls_cred_type = type;
954
955 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_CRED_SET; 952 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_CRED_SET;
956
957 ret = emacs_gnutls_handshake (XPROCESS (proc)); 953 ret = emacs_gnutls_handshake (XPROCESS (proc));
958
959 if (ret < GNUTLS_E_SUCCESS) 954 if (ret < GNUTLS_E_SUCCESS)
960 return gnutls_make_error (ret); 955 return gnutls_make_error (ret);
961 956
@@ -966,97 +961,96 @@ one trustfile (usually a CA bundle). */)
966 gnutls_x509_crt_check_hostname() against :hostname. */ 961 gnutls_x509_crt_check_hostname() against :hostname. */
967 962
968 ret = fn_gnutls_certificate_verify_peers2 (state, &peer_verification); 963 ret = fn_gnutls_certificate_verify_peers2 (state, &peer_verification);
969
970 if (ret < GNUTLS_E_SUCCESS) 964 if (ret < GNUTLS_E_SUCCESS)
971 return gnutls_make_error (ret); 965 return gnutls_make_error (ret);
972 966
973 if (XINT (loglevel) > 0 && peer_verification & GNUTLS_CERT_INVALID) 967 if (XINT (loglevel) > 0 && peer_verification & GNUTLS_CERT_INVALID)
974 message ("%s certificate could not be verified.", 968 message ("%s certificate could not be verified.", c_hostname);
975 c_hostname); 969
976 970 if (peer_verification & GNUTLS_CERT_REVOKED)
977 if (peer_verification & GNUTLS_CERT_REVOKED) 971 GNUTLS_LOG2 (1, max_log_level, "certificate was revoked (CRL):",
978 GNUTLS_LOG2 (1, max_log_level, "certificate was revoked (CRL):", 972 c_hostname);
979 c_hostname); 973
980 974 if (peer_verification & GNUTLS_CERT_SIGNER_NOT_FOUND)
981 if (peer_verification & GNUTLS_CERT_SIGNER_NOT_FOUND) 975 GNUTLS_LOG2 (1, max_log_level, "certificate signer was not found:",
982 GNUTLS_LOG2 (1, max_log_level, "certificate signer was not found:", 976 c_hostname);
983 c_hostname); 977
984 978 if (peer_verification & GNUTLS_CERT_SIGNER_NOT_CA)
985 if (peer_verification & GNUTLS_CERT_SIGNER_NOT_CA) 979 GNUTLS_LOG2 (1, max_log_level, "certificate signer is not a CA:",
986 GNUTLS_LOG2 (1, max_log_level, "certificate signer is not a CA:", 980 c_hostname);
987 c_hostname); 981
988 982 if (peer_verification & GNUTLS_CERT_INSECURE_ALGORITHM)
989 if (peer_verification & GNUTLS_CERT_INSECURE_ALGORITHM) 983 GNUTLS_LOG2 (1, max_log_level,
990 GNUTLS_LOG2 (1, max_log_level, 984 "certificate was signed with an insecure algorithm:",
991 "certificate was signed with an insecure algorithm:", 985 c_hostname);
992 c_hostname); 986
993 987 if (peer_verification & GNUTLS_CERT_NOT_ACTIVATED)
994 if (peer_verification & GNUTLS_CERT_NOT_ACTIVATED) 988 GNUTLS_LOG2 (1, max_log_level, "certificate is not yet activated:",
995 GNUTLS_LOG2 (1, max_log_level, "certificate is not yet activated:", 989 c_hostname);
996 c_hostname); 990
997 991 if (peer_verification & GNUTLS_CERT_EXPIRED)
998 if (peer_verification & GNUTLS_CERT_EXPIRED) 992 GNUTLS_LOG2 (1, max_log_level, "certificate has expired:",
999 GNUTLS_LOG2 (1, max_log_level, "certificate has expired:", 993 c_hostname);
1000 c_hostname); 994
1001 995 if (peer_verification != 0)
1002 if (peer_verification != 0) 996 {
1003 { 997 if (NILP (verify_hostname_error))
1004 if (NILP (verify_hostname_error)) 998 GNUTLS_LOG2 (1, max_log_level, "certificate validation failed:",
1005 { 999 c_hostname);
1006 GNUTLS_LOG2 (1, max_log_level, "certificate validation failed:", 1000 else
1007 c_hostname); 1001 {
1008 } 1002 emacs_gnutls_deinit (proc);
1009 else 1003 error ("Certificate validation failed %s, verification code %d",
1010 { 1004 c_hostname, peer_verification);
1011 error ("Certificate validation failed %s, verification code %d", 1005 }
1012 c_hostname, peer_verification); 1006 }
1013 }
1014 }
1015 1007
1016 /* Up to here the process is the same for X.509 certificates and 1008 /* Up to here the process is the same for X.509 certificates and
1017 OpenPGP keys. From now on X.509 certificates are assumed. This 1009 OpenPGP keys. From now on X.509 certificates are assumed. This
1018 can be easily extended to work with openpgp keys as well. */ 1010 can be easily extended to work with openpgp keys as well. */
1019 if (fn_gnutls_certificate_type_get (state) == GNUTLS_CRT_X509) 1011 if (fn_gnutls_certificate_type_get (state) == GNUTLS_CRT_X509)
1020 { 1012 {
1021 ret = fn_gnutls_x509_crt_init (&gnutls_verify_cert); 1013 gnutls_x509_crt_t gnutls_verify_cert;
1014 const gnutls_datum_t *gnutls_verify_cert_list;
1015 unsigned int gnutls_verify_cert_list_size;
1022 1016
1017 ret = fn_gnutls_x509_crt_init (&gnutls_verify_cert);
1023 if (ret < GNUTLS_E_SUCCESS) 1018 if (ret < GNUTLS_E_SUCCESS)
1024 return gnutls_make_error (ret); 1019 return gnutls_make_error (ret);
1025 1020
1026 gnutls_verify_cert_list = 1021 gnutls_verify_cert_list =
1027 fn_gnutls_certificate_get_peers (state, &gnutls_verify_cert_list_size); 1022 fn_gnutls_certificate_get_peers (state, &gnutls_verify_cert_list_size);
1028 1023
1029 if (NULL == gnutls_verify_cert_list) 1024 if (gnutls_verify_cert_list == NULL)
1030 { 1025 {
1031 error ("No x509 certificate was found!\n"); 1026 fn_gnutls_x509_crt_deinit (gnutls_verify_cert);
1032 } 1027 emacs_gnutls_deinit (proc);
1028 error ("No x509 certificate was found\n");
1029 }
1033 1030
1034 /* We only check the first certificate in the given chain. */ 1031 /* We only check the first certificate in the given chain. */
1035 ret = fn_gnutls_x509_crt_import (gnutls_verify_cert, 1032 ret = fn_gnutls_x509_crt_import (gnutls_verify_cert,
1036 &gnutls_verify_cert_list[0], 1033 &gnutls_verify_cert_list[0],
1037 GNUTLS_X509_FMT_DER); 1034 GNUTLS_X509_FMT_DER);
1038 1035
1039 if (ret < GNUTLS_E_SUCCESS) 1036 if (ret < GNUTLS_E_SUCCESS)
1040 { 1037 {
1041 fn_gnutls_x509_crt_deinit (gnutls_verify_cert); 1038 fn_gnutls_x509_crt_deinit (gnutls_verify_cert);
1042 return gnutls_make_error (ret); 1039 return gnutls_make_error (ret);
1043 } 1040 }
1044 1041
1045 if (!fn_gnutls_x509_crt_check_hostname (gnutls_verify_cert, c_hostname)) 1042 if (!fn_gnutls_x509_crt_check_hostname (gnutls_verify_cert, c_hostname))
1046 { 1043 {
1047 if (NILP (verify_hostname_error)) 1044 if (NILP (verify_hostname_error))
1048 { 1045 GNUTLS_LOG2 (1, max_log_level, "x509 certificate does not match:",
1049 GNUTLS_LOG2 (1, max_log_level, "x509 certificate does not match:", 1046 c_hostname);
1050 c_hostname); 1047 else
1051 } 1048 {
1052 else 1049 fn_gnutls_x509_crt_deinit (gnutls_verify_cert);
1053 { 1050 emacs_gnutls_deinit (proc);
1054 fn_gnutls_x509_crt_deinit (gnutls_verify_cert); 1051 error ("The x509 certificate does not match \"%s\"", c_hostname);
1055 error ("The x509 certificate does not match \"%s\"", 1052 }
1056 c_hostname); 1053 }
1057 }
1058 }
1059
1060 fn_gnutls_x509_crt_deinit (gnutls_verify_cert); 1054 fn_gnutls_x509_crt_deinit (gnutls_verify_cert);
1061 } 1055 }
1062 1056
@@ -1087,7 +1081,7 @@ This function may also return `gnutls-e-again', or
1087 state = XPROCESS (proc)->gnutls_state; 1081 state = XPROCESS (proc)->gnutls_state;
1088 1082
1089 ret = fn_gnutls_bye (state, 1083 ret = fn_gnutls_bye (state,
1090 NILP (cont) ? GNUTLS_SHUT_RDWR : GNUTLS_SHUT_WR); 1084 NILP (cont) ? GNUTLS_SHUT_RDWR : GNUTLS_SHUT_WR);
1091 1085
1092 return gnutls_make_error (ret); 1086 return gnutls_make_error (ret);
1093} 1087}
@@ -1098,36 +1092,36 @@ syms_of_gnutls (void)
1098 gnutls_global_initialized = 0; 1092 gnutls_global_initialized = 0;
1099 1093
1100 DEFSYM (Qgnutls_dll, "gnutls"); 1094 DEFSYM (Qgnutls_dll, "gnutls");
1101 DEFSYM (Qgnutls_log_level, "gnutls-log-level");
1102 DEFSYM (Qgnutls_code, "gnutls-code"); 1095 DEFSYM (Qgnutls_code, "gnutls-code");
1103 DEFSYM (Qgnutls_anon, "gnutls-anon"); 1096 DEFSYM (Qgnutls_anon, "gnutls-anon");
1104 DEFSYM (Qgnutls_x509pki, "gnutls-x509pki"); 1097 DEFSYM (Qgnutls_x509pki, "gnutls-x509pki");
1105 DEFSYM (Qgnutls_bootprop_hostname, ":hostname"); 1098 DEFSYM (QCgnutls_bootprop_hostname, ":hostname");
1106 DEFSYM (Qgnutls_bootprop_priority, ":priority"); 1099 DEFSYM (QCgnutls_bootprop_priority, ":priority");
1107 DEFSYM (Qgnutls_bootprop_trustfiles, ":trustfiles"); 1100 DEFSYM (QCgnutls_bootprop_trustfiles, ":trustfiles");
1108 DEFSYM (Qgnutls_bootprop_keylist, ":keylist"); 1101 DEFSYM (QCgnutls_bootprop_keylist, ":keylist");
1109 DEFSYM (Qgnutls_bootprop_crlfiles, ":crlfiles"); 1102 DEFSYM (QCgnutls_bootprop_crlfiles, ":crlfiles");
1110 DEFSYM (Qgnutls_bootprop_callbacks, ":callbacks"); 1103 DEFSYM (QCgnutls_bootprop_callbacks, ":callbacks");
1111 DEFSYM (Qgnutls_bootprop_callbacks_verify, "verify"); 1104 DEFSYM (QCgnutls_bootprop_callbacks_verify, "verify");
1112 DEFSYM (Qgnutls_bootprop_loglevel, ":loglevel"); 1105 DEFSYM (QCgnutls_bootprop_min_prime_bits, ":min-prime-bits");
1113 DEFSYM (Qgnutls_bootprop_verify_flags, ":verify-flags"); 1106 DEFSYM (QCgnutls_bootprop_loglevel, ":loglevel");
1114 DEFSYM (Qgnutls_bootprop_verify_hostname_error, ":verify-hostname-error"); 1107 DEFSYM (QCgnutls_bootprop_verify_flags, ":verify-flags");
1108 DEFSYM (QCgnutls_bootprop_verify_hostname_error, ":verify-hostname-error");
1115 1109
1116 DEFSYM (Qgnutls_e_interrupted, "gnutls-e-interrupted"); 1110 DEFSYM (Qgnutls_e_interrupted, "gnutls-e-interrupted");
1117 Fput (Qgnutls_e_interrupted, Qgnutls_code, 1111 Fput (Qgnutls_e_interrupted, Qgnutls_code,
1118 make_number (GNUTLS_E_INTERRUPTED)); 1112 make_number (GNUTLS_E_INTERRUPTED));
1119 1113
1120 DEFSYM (Qgnutls_e_again, "gnutls-e-again"); 1114 DEFSYM (Qgnutls_e_again, "gnutls-e-again");
1121 Fput (Qgnutls_e_again, Qgnutls_code, 1115 Fput (Qgnutls_e_again, Qgnutls_code,
1122 make_number (GNUTLS_E_AGAIN)); 1116 make_number (GNUTLS_E_AGAIN));
1123 1117
1124 DEFSYM (Qgnutls_e_invalid_session, "gnutls-e-invalid-session"); 1118 DEFSYM (Qgnutls_e_invalid_session, "gnutls-e-invalid-session");
1125 Fput (Qgnutls_e_invalid_session, Qgnutls_code, 1119 Fput (Qgnutls_e_invalid_session, Qgnutls_code,
1126 make_number (GNUTLS_E_INVALID_SESSION)); 1120 make_number (GNUTLS_E_INVALID_SESSION));
1127 1121
1128 DEFSYM (Qgnutls_e_not_ready_for_handshake, "gnutls-e-not-ready-for-handshake"); 1122 DEFSYM (Qgnutls_e_not_ready_for_handshake, "gnutls-e-not-ready-for-handshake");
1129 Fput (Qgnutls_e_not_ready_for_handshake, Qgnutls_code, 1123 Fput (Qgnutls_e_not_ready_for_handshake, Qgnutls_code,
1130 make_number (GNUTLS_E_APPLICATION_ERROR_MIN)); 1124 make_number (GNUTLS_E_APPLICATION_ERROR_MIN));
1131 1125
1132 defsubr (&Sgnutls_get_initstage); 1126 defsubr (&Sgnutls_get_initstage);
1133 defsubr (&Sgnutls_errorp); 1127 defsubr (&Sgnutls_errorp);
@@ -1137,6 +1131,13 @@ syms_of_gnutls (void)
1137 defsubr (&Sgnutls_deinit); 1131 defsubr (&Sgnutls_deinit);
1138 defsubr (&Sgnutls_bye); 1132 defsubr (&Sgnutls_bye);
1139 defsubr (&Sgnutls_available_p); 1133 defsubr (&Sgnutls_available_p);
1134
1135 DEFVAR_INT ("gnutls-log-level", global_gnutls_log_level,
1136 doc: /* Logging level used by the GnuTLS functions.
1137Set this larger than 0 to get debug output in the *Messages* buffer.
11381 is for important messages, 2 is for debug data, and higher numbers
1139are as per the GnuTLS logging conventions. */);
1140 global_gnutls_log_level = 0;
1140} 1141}
1141 1142
1142#endif /* HAVE_GNUTLS */ 1143#endif /* HAVE_GNUTLS */