]> code.delx.au - gnu-emacs/blob - src/gnutls.c
* gnutls.c (emacs_gnutls_handshake): Revert last change. Add QUIT
[gnu-emacs] / src / gnutls.c
1 /* GnuTLS glue for GNU Emacs.
2 Copyright (C) 2010-2012 Free Software Foundation, Inc.
3
4 This file is part of GNU Emacs.
5
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
9 (at your option) any later version.
10
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.
15
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/>. */
18
19 #include <config.h>
20 #include <errno.h>
21 #include <setjmp.h>
22
23 #include "lisp.h"
24 #include "process.h"
25
26 #ifdef HAVE_GNUTLS
27 #include <gnutls/gnutls.h>
28
29 #ifdef WINDOWSNT
30 #include <windows.h>
31 #include "w32.h"
32 #endif
33
34 static int
35 emacs_gnutls_handle_error (gnutls_session_t, int err);
36
37 static Lisp_Object Qgnutls_dll;
38 static Lisp_Object Qgnutls_code;
39 static Lisp_Object Qgnutls_anon, Qgnutls_x509pki;
40 static Lisp_Object Qgnutls_e_interrupted, Qgnutls_e_again,
41 Qgnutls_e_invalid_session, Qgnutls_e_not_ready_for_handshake;
42 static int gnutls_global_initialized;
43
44 /* The following are for the property list of `gnutls-boot'. */
45 static Lisp_Object QCgnutls_bootprop_priority;
46 static Lisp_Object QCgnutls_bootprop_trustfiles;
47 static Lisp_Object QCgnutls_bootprop_keylist;
48 static Lisp_Object QCgnutls_bootprop_crlfiles;
49 static Lisp_Object QCgnutls_bootprop_callbacks;
50 static Lisp_Object QCgnutls_bootprop_loglevel;
51 static Lisp_Object QCgnutls_bootprop_hostname;
52 static Lisp_Object QCgnutls_bootprop_min_prime_bits;
53 static Lisp_Object QCgnutls_bootprop_verify_flags;
54 static Lisp_Object QCgnutls_bootprop_verify_hostname_error;
55
56 /* Callback keys for `gnutls-boot'. Unused currently. */
57 static Lisp_Object QCgnutls_bootprop_callbacks_verify;
58
59 static void gnutls_log_function (int, const char *);
60 static void gnutls_log_function2 (int, const char*, const char*);
61
62 \f
63 #ifdef WINDOWSNT
64
65 /* Macro for defining functions that will be loaded from the GnuTLS DLL. */
66 #define DEF_GNUTLS_FN(rettype,func,args) static rettype (FAR CDECL *fn_##func)args
67
68 /* Macro for loading GnuTLS functions from the library. */
69 #define LOAD_GNUTLS_FN(lib,func) { \
70 fn_##func = (void *) GetProcAddress (lib, #func); \
71 if (!fn_##func) return 0; \
72 }
73
74 DEF_GNUTLS_FN (gnutls_alert_description_t, gnutls_alert_get,
75 (gnutls_session_t));
76 DEF_GNUTLS_FN (const char *, gnutls_alert_get_name,
77 (gnutls_alert_description_t));
78 DEF_GNUTLS_FN (int, gnutls_alert_send_appropriate, (gnutls_session_t, int));
79 DEF_GNUTLS_FN (int, gnutls_anon_allocate_client_credentials,
80 (gnutls_anon_client_credentials_t *));
81 DEF_GNUTLS_FN (void, gnutls_anon_free_client_credentials,
82 (gnutls_anon_client_credentials_t));
83 DEF_GNUTLS_FN (int, gnutls_bye, (gnutls_session_t, gnutls_close_request_t));
84 DEF_GNUTLS_FN (int, gnutls_certificate_allocate_credentials,
85 (gnutls_certificate_credentials_t *));
86 DEF_GNUTLS_FN (void, gnutls_certificate_free_credentials,
87 (gnutls_certificate_credentials_t));
88 DEF_GNUTLS_FN (const gnutls_datum_t *, gnutls_certificate_get_peers,
89 (gnutls_session_t, unsigned int *));
90 DEF_GNUTLS_FN (void, gnutls_certificate_set_verify_flags,
91 (gnutls_certificate_credentials_t, unsigned int));
92 DEF_GNUTLS_FN (int, gnutls_certificate_set_x509_crl_file,
93 (gnutls_certificate_credentials_t, const char *,
94 gnutls_x509_crt_fmt_t));
95 DEF_GNUTLS_FN (int, gnutls_certificate_set_x509_key_file,
96 (gnutls_certificate_credentials_t, const char *, const char *,
97 gnutls_x509_crt_fmt_t));
98 DEF_GNUTLS_FN (int, gnutls_certificate_set_x509_trust_file,
99 (gnutls_certificate_credentials_t, const char *,
100 gnutls_x509_crt_fmt_t));
101 DEF_GNUTLS_FN (gnutls_certificate_type_t, gnutls_certificate_type_get,
102 (gnutls_session_t));
103 DEF_GNUTLS_FN (int, gnutls_certificate_verify_peers2,
104 (gnutls_session_t, unsigned int *));
105 DEF_GNUTLS_FN (int, gnutls_credentials_set,
106 (gnutls_session_t, gnutls_credentials_type_t, void *));
107 DEF_GNUTLS_FN (void, gnutls_deinit, (gnutls_session_t));
108 DEF_GNUTLS_FN (void, gnutls_dh_set_prime_bits,
109 (gnutls_session_t, unsigned int));
110 DEF_GNUTLS_FN (int, gnutls_error_is_fatal, (int));
111 DEF_GNUTLS_FN (int, gnutls_global_init, (void));
112 DEF_GNUTLS_FN (void, gnutls_global_set_log_function, (gnutls_log_func));
113 DEF_GNUTLS_FN (void, gnutls_global_set_log_level, (int));
114 DEF_GNUTLS_FN (void, gnutls_global_set_mem_functions,
115 (gnutls_alloc_function, gnutls_alloc_function,
116 gnutls_is_secure_function, gnutls_realloc_function,
117 gnutls_free_function));
118 DEF_GNUTLS_FN (int, gnutls_handshake, (gnutls_session_t));
119 DEF_GNUTLS_FN (int, gnutls_init, (gnutls_session_t *, gnutls_connection_end_t));
120 DEF_GNUTLS_FN (int, gnutls_priority_set_direct,
121 (gnutls_session_t, const char *, const char **));
122 DEF_GNUTLS_FN (size_t, gnutls_record_check_pending, (gnutls_session_t));
123 DEF_GNUTLS_FN (ssize_t, gnutls_record_recv, (gnutls_session_t, void *, size_t));
124 DEF_GNUTLS_FN (ssize_t, gnutls_record_send,
125 (gnutls_session_t, const void *, size_t));
126 DEF_GNUTLS_FN (const char *, gnutls_strerror, (int));
127 DEF_GNUTLS_FN (void, gnutls_transport_set_errno, (gnutls_session_t, int));
128 DEF_GNUTLS_FN (const char *, gnutls_check_version, (const char *));
129 DEF_GNUTLS_FN (void, gnutls_transport_set_lowat, (gnutls_session_t, int));
130 DEF_GNUTLS_FN (void, gnutls_transport_set_ptr2,
131 (gnutls_session_t, gnutls_transport_ptr_t,
132 gnutls_transport_ptr_t));
133 DEF_GNUTLS_FN (void, gnutls_transport_set_pull_function,
134 (gnutls_session_t, gnutls_pull_func));
135 DEF_GNUTLS_FN (void, gnutls_transport_set_push_function,
136 (gnutls_session_t, gnutls_push_func));
137 DEF_GNUTLS_FN (int, gnutls_x509_crt_check_hostname,
138 (gnutls_x509_crt_t, const char *));
139 DEF_GNUTLS_FN (void, gnutls_x509_crt_deinit, (gnutls_x509_crt_t));
140 DEF_GNUTLS_FN (int, gnutls_x509_crt_import,
141 (gnutls_x509_crt_t, const gnutls_datum_t *,
142 gnutls_x509_crt_fmt_t));
143 DEF_GNUTLS_FN (int, gnutls_x509_crt_init, (gnutls_x509_crt_t *));
144
145 static int
146 init_gnutls_functions (Lisp_Object libraries)
147 {
148 HMODULE library;
149 int max_log_level = 1;
150
151 if (!(library = w32_delayed_load (libraries, Qgnutls_dll)))
152 {
153 GNUTLS_LOG (1, max_log_level, "GnuTLS library not found");
154 return 0;
155 }
156
157 LOAD_GNUTLS_FN (library, gnutls_alert_get);
158 LOAD_GNUTLS_FN (library, gnutls_alert_get_name);
159 LOAD_GNUTLS_FN (library, gnutls_alert_send_appropriate);
160 LOAD_GNUTLS_FN (library, gnutls_anon_allocate_client_credentials);
161 LOAD_GNUTLS_FN (library, gnutls_anon_free_client_credentials);
162 LOAD_GNUTLS_FN (library, gnutls_bye);
163 LOAD_GNUTLS_FN (library, gnutls_certificate_allocate_credentials);
164 LOAD_GNUTLS_FN (library, gnutls_certificate_free_credentials);
165 LOAD_GNUTLS_FN (library, gnutls_certificate_get_peers);
166 LOAD_GNUTLS_FN (library, gnutls_certificate_set_verify_flags);
167 LOAD_GNUTLS_FN (library, gnutls_certificate_set_x509_crl_file);
168 LOAD_GNUTLS_FN (library, gnutls_certificate_set_x509_key_file);
169 LOAD_GNUTLS_FN (library, gnutls_certificate_set_x509_trust_file);
170 LOAD_GNUTLS_FN (library, gnutls_certificate_type_get);
171 LOAD_GNUTLS_FN (library, gnutls_certificate_verify_peers2);
172 LOAD_GNUTLS_FN (library, gnutls_credentials_set);
173 LOAD_GNUTLS_FN (library, gnutls_deinit);
174 LOAD_GNUTLS_FN (library, gnutls_dh_set_prime_bits);
175 LOAD_GNUTLS_FN (library, gnutls_error_is_fatal);
176 LOAD_GNUTLS_FN (library, gnutls_global_init);
177 LOAD_GNUTLS_FN (library, gnutls_global_set_log_function);
178 LOAD_GNUTLS_FN (library, gnutls_global_set_log_level);
179 LOAD_GNUTLS_FN (library, gnutls_global_set_mem_functions);
180 LOAD_GNUTLS_FN (library, gnutls_handshake);
181 LOAD_GNUTLS_FN (library, gnutls_init);
182 LOAD_GNUTLS_FN (library, gnutls_priority_set_direct);
183 LOAD_GNUTLS_FN (library, gnutls_record_check_pending);
184 LOAD_GNUTLS_FN (library, gnutls_record_recv);
185 LOAD_GNUTLS_FN (library, gnutls_record_send);
186 LOAD_GNUTLS_FN (library, gnutls_strerror);
187 LOAD_GNUTLS_FN (library, gnutls_transport_set_errno);
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);
193 LOAD_GNUTLS_FN (library, gnutls_transport_set_ptr2);
194 LOAD_GNUTLS_FN (library, gnutls_transport_set_pull_function);
195 LOAD_GNUTLS_FN (library, gnutls_transport_set_push_function);
196 LOAD_GNUTLS_FN (library, gnutls_x509_crt_check_hostname);
197 LOAD_GNUTLS_FN (library, gnutls_x509_crt_deinit);
198 LOAD_GNUTLS_FN (library, gnutls_x509_crt_import);
199 LOAD_GNUTLS_FN (library, gnutls_x509_crt_init);
200
201 max_log_level = global_gnutls_log_level;
202
203 GNUTLS_LOG2 (1, max_log_level, "GnuTLS library loaded:",
204 SDATA (Fget (Qgnutls_dll, QCloaded_from)));
205 return 1;
206 }
207
208 #else /* !WINDOWSNT */
209
210 #define fn_gnutls_alert_get gnutls_alert_get
211 #define fn_gnutls_alert_get_name gnutls_alert_get_name
212 #define fn_gnutls_alert_send_appropriate gnutls_alert_send_appropriate
213 #define fn_gnutls_anon_allocate_client_credentials gnutls_anon_allocate_client_credentials
214 #define fn_gnutls_anon_free_client_credentials gnutls_anon_free_client_credentials
215 #define fn_gnutls_bye gnutls_bye
216 #define fn_gnutls_certificate_allocate_credentials gnutls_certificate_allocate_credentials
217 #define fn_gnutls_certificate_free_credentials gnutls_certificate_free_credentials
218 #define fn_gnutls_certificate_get_peers gnutls_certificate_get_peers
219 #define fn_gnutls_certificate_set_verify_flags gnutls_certificate_set_verify_flags
220 #define fn_gnutls_certificate_set_x509_crl_file gnutls_certificate_set_x509_crl_file
221 #define fn_gnutls_certificate_set_x509_key_file gnutls_certificate_set_x509_key_file
222 #define fn_gnutls_certificate_set_x509_trust_file gnutls_certificate_set_x509_trust_file
223 #define fn_gnutls_certificate_type_get gnutls_certificate_type_get
224 #define fn_gnutls_certificate_verify_peers2 gnutls_certificate_verify_peers2
225 #define fn_gnutls_credentials_set gnutls_credentials_set
226 #define fn_gnutls_deinit gnutls_deinit
227 #define fn_gnutls_dh_set_prime_bits gnutls_dh_set_prime_bits
228 #define fn_gnutls_error_is_fatal gnutls_error_is_fatal
229 #define fn_gnutls_global_init gnutls_global_init
230 #define fn_gnutls_global_set_log_function gnutls_global_set_log_function
231 #define fn_gnutls_global_set_log_level gnutls_global_set_log_level
232 #define fn_gnutls_global_set_mem_functions gnutls_global_set_mem_functions
233 #define fn_gnutls_handshake gnutls_handshake
234 #define fn_gnutls_init gnutls_init
235 #define fn_gnutls_priority_set_direct gnutls_priority_set_direct
236 #define fn_gnutls_record_check_pending gnutls_record_check_pending
237 #define fn_gnutls_record_recv gnutls_record_recv
238 #define fn_gnutls_record_send gnutls_record_send
239 #define fn_gnutls_strerror gnutls_strerror
240 #define fn_gnutls_transport_set_errno gnutls_transport_set_errno
241 #define fn_gnutls_transport_set_ptr2 gnutls_transport_set_ptr2
242 #define fn_gnutls_x509_crt_check_hostname gnutls_x509_crt_check_hostname
243 #define fn_gnutls_x509_crt_deinit gnutls_x509_crt_deinit
244 #define fn_gnutls_x509_crt_import gnutls_x509_crt_import
245 #define fn_gnutls_x509_crt_init gnutls_x509_crt_init
246
247 #endif /* !WINDOWSNT */
248
249 \f
250 /* Function to log a simple message. */
251 static void
252 gnutls_log_function (int level, const char* string)
253 {
254 message ("gnutls.c: [%d] %s", level, string);
255 }
256
257 /* Function to log a message and a string. */
258 static void
259 gnutls_log_function2 (int level, const char* string, const char* extra)
260 {
261 message ("gnutls.c: [%d] %s %s", level, string, extra);
262 }
263
264 /* Function to log a message and an integer. */
265 static void
266 gnutls_log_function2i (int level, const char* string, int extra)
267 {
268 message ("gnutls.c: [%d] %s %d", level, string, extra);
269 }
270
271 static int
272 emacs_gnutls_handshake (struct Lisp_Process *proc)
273 {
274 gnutls_session_t state = proc->gnutls_state;
275 int ret;
276
277 if (proc->gnutls_initstage < GNUTLS_STAGE_HANDSHAKE_CANDO)
278 return -1;
279
280 if (proc->gnutls_initstage < GNUTLS_STAGE_TRANSPORT_POINTERS_SET)
281 {
282 #ifdef WINDOWSNT
283 /* On W32 we cannot transfer socket handles between different runtime
284 libraries, so we tell GnuTLS to use our special push/pull
285 functions. */
286 fn_gnutls_transport_set_ptr2 (state,
287 (gnutls_transport_ptr_t) proc,
288 (gnutls_transport_ptr_t) proc);
289 fn_gnutls_transport_set_push_function (state, &emacs_gnutls_push);
290 fn_gnutls_transport_set_pull_function (state, &emacs_gnutls_pull);
291
292 /* For non blocking sockets or other custom made pull/push
293 functions the gnutls_transport_set_lowat must be called, with
294 a zero low water mark value. (GnuTLS 2.10.4 documentation)
295
296 (Note: this is probably not strictly necessary as the lowat
297 value is only used when no custom pull/push functions are
298 set.) */
299 /* According to GnuTLS NEWS file, lowat level has been set to
300 zero by default in version 2.11.1, and the function
301 gnutls_transport_set_lowat was removed from the library in
302 version 2.99.0. */
303 if (!fn_gnutls_check_version ("2.11.1"))
304 fn_gnutls_transport_set_lowat (state, 0);
305 #else
306 /* This is how GnuTLS takes sockets: as file descriptors passed
307 in. For an Emacs process socket, infd and outfd are the
308 same but we use this two-argument version for clarity. */
309 fn_gnutls_transport_set_ptr2 (state,
310 (gnutls_transport_ptr_t) (long) proc->infd,
311 (gnutls_transport_ptr_t) (long) proc->outfd);
312 #endif
313
314 proc->gnutls_initstage = GNUTLS_STAGE_TRANSPORT_POINTERS_SET;
315 }
316
317 do
318 {
319 ret = fn_gnutls_handshake (state);
320 emacs_gnutls_handle_error (state, ret);
321 QUIT;
322 }
323 while (ret < 0 && fn_gnutls_error_is_fatal (ret) == 0);
324
325 proc->gnutls_initstage = GNUTLS_STAGE_HANDSHAKE_TRIED;
326
327 if (ret == GNUTLS_E_SUCCESS)
328 {
329 /* Here we're finally done. */
330 proc->gnutls_initstage = GNUTLS_STAGE_READY;
331 }
332 else
333 {
334 fn_gnutls_alert_send_appropriate (state, ret);
335 }
336 return ret;
337 }
338
339 int
340 emacs_gnutls_record_check_pending (gnutls_session_t state)
341 {
342 return fn_gnutls_record_check_pending (state);
343 }
344
345 void
346 emacs_gnutls_transport_set_errno (gnutls_session_t state, int err)
347 {
348 fn_gnutls_transport_set_errno (state, err);
349 }
350
351 EMACS_INT
352 emacs_gnutls_write (struct Lisp_Process *proc, const char *buf, EMACS_INT nbyte)
353 {
354 ssize_t rtnval = 0;
355 EMACS_INT bytes_written;
356 gnutls_session_t state = proc->gnutls_state;
357
358 if (proc->gnutls_initstage != GNUTLS_STAGE_READY)
359 {
360 #ifdef EWOULDBLOCK
361 errno = EWOULDBLOCK;
362 #endif
363 #ifdef EAGAIN
364 errno = EAGAIN;
365 #endif
366 return 0;
367 }
368
369 bytes_written = 0;
370
371 while (nbyte > 0)
372 {
373 rtnval = fn_gnutls_record_send (state, buf, nbyte);
374
375 if (rtnval < 0)
376 {
377 if (rtnval == GNUTLS_E_INTERRUPTED)
378 continue;
379 else
380 {
381 /* If we get GNUTLS_E_AGAIN, then set errno
382 appropriately so that send_process retries the
383 correct way instead of erroring out. */
384 if (rtnval == GNUTLS_E_AGAIN)
385 {
386 #ifdef EWOULDBLOCK
387 errno = EWOULDBLOCK;
388 #endif
389 #ifdef EAGAIN
390 errno = EAGAIN;
391 #endif
392 }
393 break;
394 }
395 }
396
397 buf += rtnval;
398 nbyte -= rtnval;
399 bytes_written += rtnval;
400 }
401
402 emacs_gnutls_handle_error (state, rtnval);
403 return (bytes_written);
404 }
405
406 EMACS_INT
407 emacs_gnutls_read (struct Lisp_Process *proc, char *buf, EMACS_INT nbyte)
408 {
409 ssize_t rtnval;
410 gnutls_session_t state = proc->gnutls_state;
411
412 int log_level = proc->gnutls_log_level;
413
414 if (proc->gnutls_initstage != GNUTLS_STAGE_READY)
415 {
416 /* If the handshake count is under the limit, try the handshake
417 again and increment the handshake count. This count is kept
418 per process (connection), not globally. */
419 if (proc->gnutls_handshakes_tried < GNUTLS_EMACS_HANDSHAKES_LIMIT)
420 {
421 proc->gnutls_handshakes_tried++;
422 emacs_gnutls_handshake (proc);
423 GNUTLS_LOG2i (5, log_level, "Retried handshake",
424 proc->gnutls_handshakes_tried);
425 return -1;
426 }
427
428 GNUTLS_LOG (2, log_level, "Giving up on handshake; resetting retries");
429 proc->gnutls_handshakes_tried = 0;
430 return 0;
431 }
432 rtnval = fn_gnutls_record_recv (state, buf, nbyte);
433 if (rtnval >= 0)
434 return rtnval;
435 else if (rtnval == GNUTLS_E_UNEXPECTED_PACKET_LENGTH)
436 /* The peer closed the connection. */
437 return 0;
438 else if (emacs_gnutls_handle_error (state, rtnval) == 0)
439 /* non-fatal error */
440 return -1;
441 else {
442 /* a fatal error occurred */
443 return 0;
444 }
445 }
446
447 /* report a GnuTLS error to the user.
448 Returns zero if the error code was successfully handled. */
449 static int
450 emacs_gnutls_handle_error (gnutls_session_t session, int err)
451 {
452 int max_log_level = 0;
453
454 int ret;
455 const char *str;
456
457 /* TODO: use a Lisp_Object generated by gnutls_make_error? */
458 if (err >= 0)
459 return 0;
460
461 max_log_level = global_gnutls_log_level;
462
463 /* TODO: use gnutls-error-fatalp and gnutls-error-string. */
464
465 str = fn_gnutls_strerror (err);
466 if (!str)
467 str = "unknown";
468
469 if (fn_gnutls_error_is_fatal (err))
470 {
471 ret = err;
472 GNUTLS_LOG2 (0, max_log_level, "fatal error:", str);
473 }
474 else
475 {
476 ret = 0;
477 GNUTLS_LOG2 (1, max_log_level, "non-fatal error:", str);
478 /* TODO: EAGAIN AKA Qgnutls_e_again should be level 2. */
479 }
480
481 if (err == GNUTLS_E_WARNING_ALERT_RECEIVED
482 || err == GNUTLS_E_FATAL_ALERT_RECEIVED)
483 {
484 int alert = fn_gnutls_alert_get (session);
485 int level = (err == GNUTLS_E_FATAL_ALERT_RECEIVED) ? 0 : 1;
486 str = fn_gnutls_alert_get_name (alert);
487 if (!str)
488 str = "unknown";
489
490 GNUTLS_LOG2 (level, max_log_level, "Received alert: ", str);
491 }
492 return ret;
493 }
494
495 /* convert an integer error to a Lisp_Object; it will be either a
496 known symbol like `gnutls_e_interrupted' and `gnutls_e_again' or
497 simply the integer value of the error. GNUTLS_E_SUCCESS is mapped
498 to Qt. */
499 static Lisp_Object
500 gnutls_make_error (int err)
501 {
502 switch (err)
503 {
504 case GNUTLS_E_SUCCESS:
505 return Qt;
506 case GNUTLS_E_AGAIN:
507 return Qgnutls_e_again;
508 case GNUTLS_E_INTERRUPTED:
509 return Qgnutls_e_interrupted;
510 case GNUTLS_E_INVALID_SESSION:
511 return Qgnutls_e_invalid_session;
512 }
513
514 return make_number (err);
515 }
516
517 Lisp_Object
518 emacs_gnutls_deinit (Lisp_Object proc)
519 {
520 int log_level;
521
522 CHECK_PROCESS (proc);
523
524 if (XPROCESS (proc)->gnutls_p == 0)
525 return Qnil;
526
527 log_level = XPROCESS (proc)->gnutls_log_level;
528
529 if (XPROCESS (proc)->gnutls_x509_cred)
530 {
531 GNUTLS_LOG (2, log_level, "Deallocating x509 credentials");
532 fn_gnutls_certificate_free_credentials (XPROCESS (proc)->gnutls_x509_cred);
533 XPROCESS (proc)->gnutls_x509_cred = NULL;
534 }
535
536 if (XPROCESS (proc)->gnutls_anon_cred)
537 {
538 GNUTLS_LOG (2, log_level, "Deallocating anon credentials");
539 fn_gnutls_anon_free_client_credentials (XPROCESS (proc)->gnutls_anon_cred);
540 XPROCESS (proc)->gnutls_anon_cred = NULL;
541 }
542
543 if (XPROCESS (proc)->gnutls_state)
544 {
545 fn_gnutls_deinit (XPROCESS (proc)->gnutls_state);
546 XPROCESS (proc)->gnutls_state = NULL;
547 if (GNUTLS_INITSTAGE (proc) >= GNUTLS_STAGE_INIT)
548 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_INIT - 1;
549 }
550
551 XPROCESS (proc)->gnutls_p = 0;
552 return Qt;
553 }
554
555 DEFUN ("gnutls-get-initstage", Fgnutls_get_initstage, Sgnutls_get_initstage, 1, 1, 0,
556 doc: /* Return the GnuTLS init stage of process PROC.
557 See also `gnutls-boot'. */)
558 (Lisp_Object proc)
559 {
560 CHECK_PROCESS (proc);
561
562 return make_number (GNUTLS_INITSTAGE (proc));
563 }
564
565 DEFUN ("gnutls-errorp", Fgnutls_errorp, Sgnutls_errorp, 1, 1, 0,
566 doc: /* Return t if ERROR indicates a GnuTLS problem.
567 ERROR is an integer or a symbol with an integer `gnutls-code' property.
568 usage: (gnutls-errorp ERROR) */)
569 (Lisp_Object err)
570 {
571 if (EQ (err, Qt)) return Qnil;
572
573 return Qt;
574 }
575
576 DEFUN ("gnutls-error-fatalp", Fgnutls_error_fatalp, Sgnutls_error_fatalp, 1, 1, 0,
577 doc: /* Check if ERROR is fatal.
578 ERROR is an integer or a symbol with an integer `gnutls-code' property.
579 usage: (gnutls-error-fatalp ERROR) */)
580 (Lisp_Object err)
581 {
582 Lisp_Object code;
583
584 if (EQ (err, Qt)) return Qnil;
585
586 if (SYMBOLP (err))
587 {
588 code = Fget (err, Qgnutls_code);
589 if (NUMBERP (code))
590 {
591 err = code;
592 }
593 else
594 {
595 error ("Symbol has no numeric gnutls-code property");
596 }
597 }
598
599 if (!NUMBERP (err))
600 error ("Not an error symbol or code");
601
602 if (0 == fn_gnutls_error_is_fatal (XINT (err)))
603 return Qnil;
604
605 return Qt;
606 }
607
608 DEFUN ("gnutls-error-string", Fgnutls_error_string, Sgnutls_error_string, 1, 1, 0,
609 doc: /* Return a description of ERROR.
610 ERROR is an integer or a symbol with an integer `gnutls-code' property.
611 usage: (gnutls-error-string ERROR) */)
612 (Lisp_Object err)
613 {
614 Lisp_Object code;
615
616 if (EQ (err, Qt)) return build_string ("Not an error");
617
618 if (SYMBOLP (err))
619 {
620 code = Fget (err, Qgnutls_code);
621 if (NUMBERP (code))
622 {
623 err = code;
624 }
625 else
626 {
627 return build_string ("Symbol has no numeric gnutls-code property");
628 }
629 }
630
631 if (!NUMBERP (err))
632 return build_string ("Not an error symbol or code");
633
634 return build_string (fn_gnutls_strerror (XINT (err)));
635 }
636
637 DEFUN ("gnutls-deinit", Fgnutls_deinit, Sgnutls_deinit, 1, 1, 0,
638 doc: /* Deallocate GnuTLS resources associated with process PROC.
639 See also `gnutls-init'. */)
640 (Lisp_Object proc)
641 {
642 return emacs_gnutls_deinit (proc);
643 }
644
645 DEFUN ("gnutls-available-p", Fgnutls_available_p, Sgnutls_available_p, 0, 0, 0,
646 doc: /* Return t if GnuTLS is available in this instance of Emacs. */)
647 (void)
648 {
649 #ifdef WINDOWSNT
650 Lisp_Object found = Fassq (Qgnutls_dll, Vlibrary_cache);
651 if (CONSP (found))
652 return XCDR (found);
653 else
654 {
655 Lisp_Object status;
656 status = init_gnutls_functions (Vdynamic_library_alist) ? Qt : Qnil;
657 Vlibrary_cache = Fcons (Fcons (Qgnutls_dll, status), Vlibrary_cache);
658 return status;
659 }
660 #else
661 return Qt;
662 #endif
663 }
664
665
666 /* Initializes global GnuTLS state to defaults.
667 Call `gnutls-global-deinit' when GnuTLS usage is no longer needed.
668 Returns zero on success. */
669 static Lisp_Object
670 emacs_gnutls_global_init (void)
671 {
672 int ret = GNUTLS_E_SUCCESS;
673
674 if (!gnutls_global_initialized)
675 {
676 fn_gnutls_global_set_mem_functions (xmalloc, xmalloc, NULL,
677 xrealloc, xfree);
678 ret = fn_gnutls_global_init ();
679 }
680 gnutls_global_initialized = 1;
681
682 return gnutls_make_error (ret);
683 }
684
685 #if 0
686 /* Deinitializes global GnuTLS state.
687 See also `gnutls-global-init'. */
688 static Lisp_Object
689 emacs_gnutls_global_deinit (void)
690 {
691 if (gnutls_global_initialized)
692 gnutls_global_deinit ();
693
694 gnutls_global_initialized = 0;
695
696 return gnutls_make_error (GNUTLS_E_SUCCESS);
697 }
698 #endif
699
700 DEFUN ("gnutls-boot", Fgnutls_boot, Sgnutls_boot, 3, 3, 0,
701 doc: /* Initialize GnuTLS client for process PROC with TYPE+PROPLIST.
702 Currently only client mode is supported. Return a success/failure
703 value you can check with `gnutls-errorp'.
704
705 TYPE is a symbol, either `gnutls-anon' or `gnutls-x509pki'.
706 PROPLIST is a property list with the following keys:
707
708 :hostname is a string naming the remote host.
709
710 :priority is a GnuTLS priority string, defaults to "NORMAL".
711
712 :trustfiles is a list of PEM-encoded trust files for `gnutls-x509pki'.
713
714 :crlfiles is a list of PEM-encoded CRL lists for `gnutls-x509pki'.
715
716 :keylist is an alist of PEM-encoded key files and PEM-encoded
717 certificates for `gnutls-x509pki'.
718
719 :callbacks is an alist of callback functions, see below.
720
721 :loglevel is the debug level requested from GnuTLS, try 4.
722
723 :verify-flags is a bitset as per GnuTLS'
724 gnutls_certificate_set_verify_flags.
725
726 :verify-hostname-error, if non-nil, makes a hostname mismatch an
727 error. Otherwise it will be just a warning.
728
729 :min-prime-bits is the minimum accepted number of bits the client will
730 accept in Diffie-Hellman key exchange.
731
732 The debug level will be set for this process AND globally for GnuTLS.
733 So if you set it higher or lower at any point, it affects global
734 debugging.
735
736 Note that the priority is set on the client. The server does not use
737 the protocols's priority except for disabling protocols that were not
738 specified.
739
740 Processes must be initialized with this function before other GnuTLS
741 functions are used. This function allocates resources which can only
742 be deallocated by calling `gnutls-deinit' or by calling it again.
743
744 The callbacks alist can have a `verify' key, associated with a
745 verification function (UNUSED).
746
747 Each authentication type may need additional information in order to
748 work. For X.509 PKI (`gnutls-x509pki'), you probably need at least
749 one trustfile (usually a CA bundle). */)
750 (Lisp_Object proc, Lisp_Object type, Lisp_Object proplist)
751 {
752 int ret = GNUTLS_E_SUCCESS;
753 int max_log_level = 0;
754
755 gnutls_session_t state;
756 gnutls_certificate_credentials_t x509_cred = NULL;
757 gnutls_anon_client_credentials_t anon_cred = NULL;
758 Lisp_Object global_init;
759 char const *priority_string_ptr = "NORMAL"; /* default priority string. */
760 unsigned int peer_verification;
761 char* c_hostname;
762
763 /* Placeholders for the property list elements. */
764 Lisp_Object priority_string;
765 Lisp_Object trustfiles;
766 Lisp_Object crlfiles;
767 Lisp_Object keylist;
768 /* Lisp_Object callbacks; */
769 Lisp_Object loglevel;
770 Lisp_Object hostname;
771 /* Lisp_Object verify_error; */
772 Lisp_Object verify_hostname_error;
773 Lisp_Object prime_bits;
774
775 CHECK_PROCESS (proc);
776 CHECK_SYMBOL (type);
777 CHECK_LIST (proplist);
778
779 if (NILP (Fgnutls_available_p ()))
780 {
781 error ("GnuTLS not available");
782 return gnutls_make_error (GNUTLS_EMACS_ERROR_NOT_LOADED);
783 }
784
785 if (!EQ (type, Qgnutls_x509pki) && !EQ (type, Qgnutls_anon))
786 {
787 error ("Invalid GnuTLS credential type");
788 return gnutls_make_error (GNUTLS_EMACS_ERROR_INVALID_TYPE);
789 }
790
791 hostname = Fplist_get (proplist, QCgnutls_bootprop_hostname);
792 priority_string = Fplist_get (proplist, QCgnutls_bootprop_priority);
793 trustfiles = Fplist_get (proplist, QCgnutls_bootprop_trustfiles);
794 keylist = Fplist_get (proplist, QCgnutls_bootprop_keylist);
795 crlfiles = Fplist_get (proplist, QCgnutls_bootprop_crlfiles);
796 loglevel = Fplist_get (proplist, QCgnutls_bootprop_loglevel);
797 verify_hostname_error = Fplist_get (proplist, QCgnutls_bootprop_verify_hostname_error);
798 prime_bits = Fplist_get (proplist, QCgnutls_bootprop_min_prime_bits);
799
800 if (!STRINGP (hostname))
801 error ("gnutls-boot: invalid :hostname parameter");
802 c_hostname = SSDATA (hostname);
803
804 if (NUMBERP (loglevel))
805 {
806 fn_gnutls_global_set_log_function (gnutls_log_function);
807 fn_gnutls_global_set_log_level (XINT (loglevel));
808 max_log_level = XINT (loglevel);
809 XPROCESS (proc)->gnutls_log_level = max_log_level;
810 }
811
812 /* always initialize globals. */
813 global_init = emacs_gnutls_global_init ();
814 if (! NILP (Fgnutls_errorp (global_init)))
815 return global_init;
816
817 /* Before allocating new credentials, deallocate any credentials
818 that PROC might already have. */
819 emacs_gnutls_deinit (proc);
820
821 /* Mark PROC as a GnuTLS process. */
822 XPROCESS (proc)->gnutls_p = 1;
823 XPROCESS (proc)->gnutls_state = NULL;
824 XPROCESS (proc)->gnutls_x509_cred = NULL;
825 XPROCESS (proc)->gnutls_anon_cred = NULL;
826 XPROCESS (proc)->gnutls_cred_type = type;
827 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_EMPTY;
828
829 GNUTLS_LOG (1, max_log_level, "allocating credentials");
830 if (EQ (type, Qgnutls_x509pki))
831 {
832 Lisp_Object verify_flags;
833 unsigned int gnutls_verify_flags = GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT;
834
835 GNUTLS_LOG (2, max_log_level, "allocating x509 credentials");
836 fn_gnutls_certificate_allocate_credentials (&x509_cred);
837 XPROCESS (proc)->gnutls_x509_cred = x509_cred;
838
839 verify_flags = Fplist_get (proplist, QCgnutls_bootprop_verify_flags);
840 if (NUMBERP (verify_flags))
841 {
842 gnutls_verify_flags = XINT (verify_flags);
843 GNUTLS_LOG (2, max_log_level, "setting verification flags");
844 }
845 else if (NILP (verify_flags))
846 GNUTLS_LOG (2, max_log_level, "using default verification flags");
847 else
848 GNUTLS_LOG (2, max_log_level, "ignoring invalid verify-flags");
849
850 fn_gnutls_certificate_set_verify_flags (x509_cred, gnutls_verify_flags);
851 }
852 else /* Qgnutls_anon: */
853 {
854 GNUTLS_LOG (2, max_log_level, "allocating anon credentials");
855 fn_gnutls_anon_allocate_client_credentials (&anon_cred);
856 XPROCESS (proc)->gnutls_anon_cred = anon_cred;
857 }
858
859 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_CRED_ALLOC;
860
861 if (EQ (type, Qgnutls_x509pki))
862 {
863 /* TODO: GNUTLS_X509_FMT_DER is also an option. */
864 int file_format = GNUTLS_X509_FMT_PEM;
865 Lisp_Object tail;
866
867 for (tail = trustfiles; !NILP (tail); tail = Fcdr (tail))
868 {
869 Lisp_Object trustfile = Fcar (tail);
870 if (STRINGP (trustfile))
871 {
872 GNUTLS_LOG2 (1, max_log_level, "setting the trustfile: ",
873 SSDATA (trustfile));
874 ret = fn_gnutls_certificate_set_x509_trust_file
875 (x509_cred,
876 SSDATA (trustfile),
877 file_format);
878
879 if (ret < GNUTLS_E_SUCCESS)
880 return gnutls_make_error (ret);
881 }
882 else
883 {
884 emacs_gnutls_deinit (proc);
885 error ("Invalid trustfile");
886 }
887 }
888
889 for (tail = crlfiles; !NILP (tail); tail = Fcdr (tail))
890 {
891 Lisp_Object crlfile = Fcar (tail);
892 if (STRINGP (crlfile))
893 {
894 GNUTLS_LOG2 (1, max_log_level, "setting the CRL file: ",
895 SSDATA (crlfile));
896 ret = fn_gnutls_certificate_set_x509_crl_file
897 (x509_cred, SSDATA (crlfile), file_format);
898
899 if (ret < GNUTLS_E_SUCCESS)
900 return gnutls_make_error (ret);
901 }
902 else
903 {
904 emacs_gnutls_deinit (proc);
905 error ("Invalid CRL file");
906 }
907 }
908
909 for (tail = keylist; !NILP (tail); tail = Fcdr (tail))
910 {
911 Lisp_Object keyfile = Fcar (Fcar (tail));
912 Lisp_Object certfile = Fcar (Fcdr (tail));
913 if (STRINGP (keyfile) && STRINGP (certfile))
914 {
915 GNUTLS_LOG2 (1, max_log_level, "setting the client key file: ",
916 SSDATA (keyfile));
917 GNUTLS_LOG2 (1, max_log_level, "setting the client cert file: ",
918 SSDATA (certfile));
919 ret = fn_gnutls_certificate_set_x509_key_file
920 (x509_cred, SSDATA (certfile), SSDATA (keyfile), file_format);
921
922 if (ret < GNUTLS_E_SUCCESS)
923 return gnutls_make_error (ret);
924 }
925 else
926 {
927 emacs_gnutls_deinit (proc);
928 error (STRINGP (keyfile) ? "Invalid client cert file"
929 : "Invalid client key file");
930 }
931 }
932 }
933
934 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_FILES;
935 GNUTLS_LOG (1, max_log_level, "gnutls callbacks");
936 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_CALLBACKS;
937
938 /* Call gnutls_init here: */
939
940 GNUTLS_LOG (1, max_log_level, "gnutls_init");
941 ret = fn_gnutls_init (&state, GNUTLS_CLIENT);
942 XPROCESS (proc)->gnutls_state = state;
943 if (ret < GNUTLS_E_SUCCESS)
944 return gnutls_make_error (ret);
945 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_INIT;
946
947 if (STRINGP (priority_string))
948 {
949 priority_string_ptr = SSDATA (priority_string);
950 GNUTLS_LOG2 (1, max_log_level, "got non-default priority string:",
951 priority_string_ptr);
952 }
953 else
954 {
955 GNUTLS_LOG2 (1, max_log_level, "using default priority string:",
956 priority_string_ptr);
957 }
958
959 GNUTLS_LOG (1, max_log_level, "setting the priority string");
960 ret = fn_gnutls_priority_set_direct (state,
961 priority_string_ptr,
962 NULL);
963 if (ret < GNUTLS_E_SUCCESS)
964 return gnutls_make_error (ret);
965
966 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_PRIORITY;
967
968 if (INTEGERP (prime_bits))
969 fn_gnutls_dh_set_prime_bits (state, XUINT (prime_bits));
970
971 ret = EQ (type, Qgnutls_x509pki)
972 ? fn_gnutls_credentials_set (state, GNUTLS_CRD_CERTIFICATE, x509_cred)
973 : fn_gnutls_credentials_set (state, GNUTLS_CRD_ANON, anon_cred);
974 if (ret < GNUTLS_E_SUCCESS)
975 return gnutls_make_error (ret);
976
977 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_CRED_SET;
978 ret = emacs_gnutls_handshake (XPROCESS (proc));
979 if (ret < GNUTLS_E_SUCCESS)
980 return gnutls_make_error (ret);
981
982 /* Now verify the peer, following
983 http://www.gnu.org/software/gnutls/manual/html_node/Verifying-peer_0027s-certificate.html.
984 The peer should present at least one certificate in the chain; do a
985 check of the certificate's hostname with
986 gnutls_x509_crt_check_hostname() against :hostname. */
987
988 ret = fn_gnutls_certificate_verify_peers2 (state, &peer_verification);
989 if (ret < GNUTLS_E_SUCCESS)
990 return gnutls_make_error (ret);
991
992 if (XINT (loglevel) > 0 && peer_verification & GNUTLS_CERT_INVALID)
993 message ("%s certificate could not be verified.", c_hostname);
994
995 if (peer_verification & GNUTLS_CERT_REVOKED)
996 GNUTLS_LOG2 (1, max_log_level, "certificate was revoked (CRL):",
997 c_hostname);
998
999 if (peer_verification & GNUTLS_CERT_SIGNER_NOT_FOUND)
1000 GNUTLS_LOG2 (1, max_log_level, "certificate signer was not found:",
1001 c_hostname);
1002
1003 if (peer_verification & GNUTLS_CERT_SIGNER_NOT_CA)
1004 GNUTLS_LOG2 (1, max_log_level, "certificate signer is not a CA:",
1005 c_hostname);
1006
1007 if (peer_verification & GNUTLS_CERT_INSECURE_ALGORITHM)
1008 GNUTLS_LOG2 (1, max_log_level,
1009 "certificate was signed with an insecure algorithm:",
1010 c_hostname);
1011
1012 if (peer_verification & GNUTLS_CERT_NOT_ACTIVATED)
1013 GNUTLS_LOG2 (1, max_log_level, "certificate is not yet activated:",
1014 c_hostname);
1015
1016 if (peer_verification & GNUTLS_CERT_EXPIRED)
1017 GNUTLS_LOG2 (1, max_log_level, "certificate has expired:",
1018 c_hostname);
1019
1020 if (peer_verification != 0)
1021 {
1022 if (NILP (verify_hostname_error))
1023 GNUTLS_LOG2 (1, max_log_level, "certificate validation failed:",
1024 c_hostname);
1025 else
1026 {
1027 emacs_gnutls_deinit (proc);
1028 error ("Certificate validation failed %s, verification code %d",
1029 c_hostname, peer_verification);
1030 }
1031 }
1032
1033 /* Up to here the process is the same for X.509 certificates and
1034 OpenPGP keys. From now on X.509 certificates are assumed. This
1035 can be easily extended to work with openpgp keys as well. */
1036 if (fn_gnutls_certificate_type_get (state) == GNUTLS_CRT_X509)
1037 {
1038 gnutls_x509_crt_t gnutls_verify_cert;
1039 const gnutls_datum_t *gnutls_verify_cert_list;
1040 unsigned int gnutls_verify_cert_list_size;
1041
1042 ret = fn_gnutls_x509_crt_init (&gnutls_verify_cert);
1043 if (ret < GNUTLS_E_SUCCESS)
1044 return gnutls_make_error (ret);
1045
1046 gnutls_verify_cert_list =
1047 fn_gnutls_certificate_get_peers (state, &gnutls_verify_cert_list_size);
1048
1049 if (gnutls_verify_cert_list == NULL)
1050 {
1051 fn_gnutls_x509_crt_deinit (gnutls_verify_cert);
1052 emacs_gnutls_deinit (proc);
1053 error ("No x509 certificate was found\n");
1054 }
1055
1056 /* We only check the first certificate in the given chain. */
1057 ret = fn_gnutls_x509_crt_import (gnutls_verify_cert,
1058 &gnutls_verify_cert_list[0],
1059 GNUTLS_X509_FMT_DER);
1060
1061 if (ret < GNUTLS_E_SUCCESS)
1062 {
1063 fn_gnutls_x509_crt_deinit (gnutls_verify_cert);
1064 return gnutls_make_error (ret);
1065 }
1066
1067 if (!fn_gnutls_x509_crt_check_hostname (gnutls_verify_cert, c_hostname))
1068 {
1069 if (NILP (verify_hostname_error))
1070 GNUTLS_LOG2 (1, max_log_level, "x509 certificate does not match:",
1071 c_hostname);
1072 else
1073 {
1074 fn_gnutls_x509_crt_deinit (gnutls_verify_cert);
1075 emacs_gnutls_deinit (proc);
1076 error ("The x509 certificate does not match \"%s\"", c_hostname);
1077 }
1078 }
1079 fn_gnutls_x509_crt_deinit (gnutls_verify_cert);
1080 }
1081
1082 return gnutls_make_error (ret);
1083 }
1084
1085 DEFUN ("gnutls-bye", Fgnutls_bye,
1086 Sgnutls_bye, 2, 2, 0,
1087 doc: /* Terminate current GnuTLS connection for process PROC.
1088 The connection should have been initiated using `gnutls-handshake'.
1089
1090 If CONT is not nil the TLS connection gets terminated and further
1091 receives and sends will be disallowed. If the return value is zero you
1092 may continue using the connection. If CONT is nil, GnuTLS actually
1093 sends an alert containing a close request and waits for the peer to
1094 reply with the same message. In order to reuse the connection you
1095 should wait for an EOF from the peer.
1096
1097 This function may also return `gnutls-e-again', or
1098 `gnutls-e-interrupted'. */)
1099 (Lisp_Object proc, Lisp_Object cont)
1100 {
1101 gnutls_session_t state;
1102 int ret;
1103
1104 CHECK_PROCESS (proc);
1105
1106 state = XPROCESS (proc)->gnutls_state;
1107
1108 ret = fn_gnutls_bye (state,
1109 NILP (cont) ? GNUTLS_SHUT_RDWR : GNUTLS_SHUT_WR);
1110
1111 return gnutls_make_error (ret);
1112 }
1113
1114 void
1115 syms_of_gnutls (void)
1116 {
1117 gnutls_global_initialized = 0;
1118
1119 DEFSYM (Qgnutls_dll, "gnutls");
1120 DEFSYM (Qgnutls_code, "gnutls-code");
1121 DEFSYM (Qgnutls_anon, "gnutls-anon");
1122 DEFSYM (Qgnutls_x509pki, "gnutls-x509pki");
1123 DEFSYM (QCgnutls_bootprop_hostname, ":hostname");
1124 DEFSYM (QCgnutls_bootprop_priority, ":priority");
1125 DEFSYM (QCgnutls_bootprop_trustfiles, ":trustfiles");
1126 DEFSYM (QCgnutls_bootprop_keylist, ":keylist");
1127 DEFSYM (QCgnutls_bootprop_crlfiles, ":crlfiles");
1128 DEFSYM (QCgnutls_bootprop_callbacks, ":callbacks");
1129 DEFSYM (QCgnutls_bootprop_callbacks_verify, "verify");
1130 DEFSYM (QCgnutls_bootprop_min_prime_bits, ":min-prime-bits");
1131 DEFSYM (QCgnutls_bootprop_loglevel, ":loglevel");
1132 DEFSYM (QCgnutls_bootprop_verify_flags, ":verify-flags");
1133 DEFSYM (QCgnutls_bootprop_verify_hostname_error, ":verify-hostname-error");
1134
1135 DEFSYM (Qgnutls_e_interrupted, "gnutls-e-interrupted");
1136 Fput (Qgnutls_e_interrupted, Qgnutls_code,
1137 make_number (GNUTLS_E_INTERRUPTED));
1138
1139 DEFSYM (Qgnutls_e_again, "gnutls-e-again");
1140 Fput (Qgnutls_e_again, Qgnutls_code,
1141 make_number (GNUTLS_E_AGAIN));
1142
1143 DEFSYM (Qgnutls_e_invalid_session, "gnutls-e-invalid-session");
1144 Fput (Qgnutls_e_invalid_session, Qgnutls_code,
1145 make_number (GNUTLS_E_INVALID_SESSION));
1146
1147 DEFSYM (Qgnutls_e_not_ready_for_handshake, "gnutls-e-not-ready-for-handshake");
1148 Fput (Qgnutls_e_not_ready_for_handshake, Qgnutls_code,
1149 make_number (GNUTLS_E_APPLICATION_ERROR_MIN));
1150
1151 defsubr (&Sgnutls_get_initstage);
1152 defsubr (&Sgnutls_errorp);
1153 defsubr (&Sgnutls_error_fatalp);
1154 defsubr (&Sgnutls_error_string);
1155 defsubr (&Sgnutls_boot);
1156 defsubr (&Sgnutls_deinit);
1157 defsubr (&Sgnutls_bye);
1158 defsubr (&Sgnutls_available_p);
1159
1160 DEFVAR_INT ("gnutls-log-level", global_gnutls_log_level,
1161 doc: /* Logging level used by the GnuTLS functions.
1162 Set this larger than 0 to get debug output in the *Messages* buffer.
1163 1 is for important messages, 2 is for debug data, and higher numbers
1164 are as per the GnuTLS logging conventions. */);
1165 global_gnutls_log_level = 0;
1166 }
1167
1168 #endif /* HAVE_GNUTLS */