]> code.delx.au - gnu-emacs/blob - src/gnutls.c
Merge from origin/emacs-24
[gnu-emacs] / src / gnutls.c
1 /* GnuTLS glue for GNU Emacs.
2 Copyright (C) 2010-2014 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 <stdio.h>
22
23 #include "lisp.h"
24 #include "process.h"
25 #include "gnutls.h"
26 #include "coding.h"
27
28 #ifdef HAVE_GNUTLS
29 #include <gnutls/gnutls.h>
30
31 #ifdef WINDOWSNT
32 #include <windows.h>
33 #include "w32.h"
34 #endif
35
36 static bool emacs_gnutls_handle_error (gnutls_session_t, int);
37
38 static Lisp_Object Qgnutls_dll;
39 static Lisp_Object Qgnutls_code;
40 static Lisp_Object Qgnutls_anon, Qgnutls_x509pki;
41 static Lisp_Object Qgnutls_e_interrupted, Qgnutls_e_again,
42 Qgnutls_e_invalid_session, Qgnutls_e_not_ready_for_handshake;
43 static bool gnutls_global_initialized;
44
45 /* The following are for the property list of `gnutls-boot'. */
46 static Lisp_Object QCgnutls_bootprop_priority;
47 static Lisp_Object QCgnutls_bootprop_trustfiles;
48 static Lisp_Object QCgnutls_bootprop_keylist;
49 static Lisp_Object QCgnutls_bootprop_crlfiles;
50 static Lisp_Object QCgnutls_bootprop_callbacks;
51 static Lisp_Object QCgnutls_bootprop_loglevel;
52 static Lisp_Object QCgnutls_bootprop_hostname;
53 static Lisp_Object QCgnutls_bootprop_min_prime_bits;
54 static Lisp_Object QCgnutls_bootprop_verify_flags;
55 static Lisp_Object QCgnutls_bootprop_verify_error;
56
57 /* Callback keys for `gnutls-boot'. Unused currently. */
58 static Lisp_Object QCgnutls_bootprop_callbacks_verify;
59
60 static void gnutls_log_function (int, const char *);
61 static void gnutls_log_function2 (int, const char *, const char *);
62 #ifdef HAVE_GNUTLS3
63 static void gnutls_audit_log_function (gnutls_session_t, const char *);
64 #endif
65
66 enum extra_peer_verification
67 {
68 CERTIFICATE_NOT_MATCHING = 2
69 };
70
71 \f
72 #ifdef WINDOWSNT
73
74 /* Macro for defining functions that will be loaded from the GnuTLS DLL. */
75 #define DEF_GNUTLS_FN(rettype,func,args) static rettype (FAR CDECL *fn_##func)args
76
77 /* Macro for loading GnuTLS functions from the library. */
78 #define LOAD_GNUTLS_FN(lib,func) { \
79 fn_##func = (void *) GetProcAddress (lib, #func); \
80 if (!fn_##func) return 0; \
81 }
82
83 DEF_GNUTLS_FN (gnutls_alert_description_t, gnutls_alert_get,
84 (gnutls_session_t));
85 DEF_GNUTLS_FN (const char *, gnutls_alert_get_name,
86 (gnutls_alert_description_t));
87 DEF_GNUTLS_FN (int, gnutls_alert_send_appropriate, (gnutls_session_t, int));
88 DEF_GNUTLS_FN (int, gnutls_anon_allocate_client_credentials,
89 (gnutls_anon_client_credentials_t *));
90 DEF_GNUTLS_FN (void, gnutls_anon_free_client_credentials,
91 (gnutls_anon_client_credentials_t));
92 DEF_GNUTLS_FN (int, gnutls_bye, (gnutls_session_t, gnutls_close_request_t));
93 DEF_GNUTLS_FN (int, gnutls_certificate_allocate_credentials,
94 (gnutls_certificate_credentials_t *));
95 DEF_GNUTLS_FN (void, gnutls_certificate_free_credentials,
96 (gnutls_certificate_credentials_t));
97 DEF_GNUTLS_FN (const gnutls_datum_t *, gnutls_certificate_get_peers,
98 (gnutls_session_t, unsigned int *));
99 DEF_GNUTLS_FN (void, gnutls_certificate_set_verify_flags,
100 (gnutls_certificate_credentials_t, unsigned int));
101 DEF_GNUTLS_FN (int, gnutls_certificate_set_x509_crl_file,
102 (gnutls_certificate_credentials_t, const char *,
103 gnutls_x509_crt_fmt_t));
104 DEF_GNUTLS_FN (int, gnutls_certificate_set_x509_key_file,
105 (gnutls_certificate_credentials_t, const char *, const char *,
106 gnutls_x509_crt_fmt_t));
107 #if GNUTLS_VERSION_MAJOR + \
108 (GNUTLS_VERSION_MINOR > 0 || GNUTLS_VERSION_PATCH >= 20) > 3
109 DEF_GNUTLS_FN (int, gnutls_certificate_set_x509_system_trust,
110 (gnutls_certificate_credentials_t));
111 #endif
112 DEF_GNUTLS_FN (int, gnutls_certificate_set_x509_trust_file,
113 (gnutls_certificate_credentials_t, const char *,
114 gnutls_x509_crt_fmt_t));
115 DEF_GNUTLS_FN (gnutls_certificate_type_t, gnutls_certificate_type_get,
116 (gnutls_session_t));
117 DEF_GNUTLS_FN (int, gnutls_certificate_verify_peers2,
118 (gnutls_session_t, unsigned int *));
119 DEF_GNUTLS_FN (int, gnutls_credentials_set,
120 (gnutls_session_t, gnutls_credentials_type_t, void *));
121 DEF_GNUTLS_FN (void, gnutls_deinit, (gnutls_session_t));
122 DEF_GNUTLS_FN (void, gnutls_dh_set_prime_bits,
123 (gnutls_session_t, unsigned int));
124 DEF_GNUTLS_FN (int, gnutls_dh_get_prime_bits, (gnutls_session_t));
125 DEF_GNUTLS_FN (int, gnutls_error_is_fatal, (int));
126 DEF_GNUTLS_FN (int, gnutls_global_init, (void));
127 DEF_GNUTLS_FN (void, gnutls_global_set_log_function, (gnutls_log_func));
128 #ifdef HAVE_GNUTLS3
129 DEF_GNUTLS_FN (void, gnutls_global_set_audit_log_function, (gnutls_audit_log_func));
130 #endif
131 DEF_GNUTLS_FN (void, gnutls_global_set_log_level, (int));
132 DEF_GNUTLS_FN (int, gnutls_handshake, (gnutls_session_t));
133 DEF_GNUTLS_FN (int, gnutls_init, (gnutls_session_t *, unsigned int));
134 DEF_GNUTLS_FN (int, gnutls_priority_set_direct,
135 (gnutls_session_t, const char *, const char **));
136 DEF_GNUTLS_FN (size_t, gnutls_record_check_pending, (gnutls_session_t));
137 DEF_GNUTLS_FN (ssize_t, gnutls_record_recv, (gnutls_session_t, void *, size_t));
138 DEF_GNUTLS_FN (ssize_t, gnutls_record_send,
139 (gnutls_session_t, const void *, size_t));
140 DEF_GNUTLS_FN (const char *, gnutls_strerror, (int));
141 DEF_GNUTLS_FN (void, gnutls_transport_set_errno, (gnutls_session_t, int));
142 DEF_GNUTLS_FN (const char *, gnutls_check_version, (const char *));
143 DEF_GNUTLS_FN (void, gnutls_transport_set_lowat, (gnutls_session_t, int));
144 DEF_GNUTLS_FN (void, gnutls_transport_set_ptr2,
145 (gnutls_session_t, gnutls_transport_ptr_t,
146 gnutls_transport_ptr_t));
147 DEF_GNUTLS_FN (void, gnutls_transport_set_pull_function,
148 (gnutls_session_t, gnutls_pull_func));
149 DEF_GNUTLS_FN (void, gnutls_transport_set_push_function,
150 (gnutls_session_t, gnutls_push_func));
151 DEF_GNUTLS_FN (int, gnutls_x509_crt_check_hostname,
152 (gnutls_x509_crt_t, const char *));
153 DEF_GNUTLS_FN (void, gnutls_x509_crt_deinit, (gnutls_x509_crt_t));
154 DEF_GNUTLS_FN (int, gnutls_x509_crt_import,
155 (gnutls_x509_crt_t, const gnutls_datum_t *,
156 gnutls_x509_crt_fmt_t));
157 DEF_GNUTLS_FN (int, gnutls_x509_crt_init, (gnutls_x509_crt_t *));
158 DEF_GNUTLS_FN (int, gnutls_x509_crt_get_fingerprint,
159 (gnutls_x509_crt_t,
160 gnutls_digest_algorithm_t, void *, size_t *));
161 DEF_GNUTLS_FN (int, gnutls_x509_crt_get_version,
162 (gnutls_x509_crt_t));
163 DEF_GNUTLS_FN (int, gnutls_x509_crt_get_serial,
164 (gnutls_x509_crt_t, void *, size_t *));
165 DEF_GNUTLS_FN (int, gnutls_x509_crt_get_issuer_dn,
166 (gnutls_x509_crt_t, char *, size_t *));
167 DEF_GNUTLS_FN (time_t, gnutls_x509_crt_get_activation_time,
168 (gnutls_x509_crt_t));
169 DEF_GNUTLS_FN (time_t, gnutls_x509_crt_get_expiration_time,
170 (gnutls_x509_crt_t));
171 DEF_GNUTLS_FN (int, gnutls_x509_crt_get_dn,
172 (gnutls_x509_crt_t, char *, size_t *));
173 DEF_GNUTLS_FN (int, gnutls_x509_crt_get_pk_algorithm,
174 (gnutls_x509_crt_t, unsigned int *));
175 DEF_GNUTLS_FN (const char*, gnutls_pk_algorithm_get_name,
176 (gnutls_pk_algorithm_t));
177 DEF_GNUTLS_FN (int, gnutls_pk_bits_to_sec_param,
178 (gnutls_pk_algorithm_t, unsigned int));
179 DEF_GNUTLS_FN (int, gnutls_x509_crt_get_issuer_unique_id,
180 (gnutls_x509_crt_t, char *, size_t *));
181 DEF_GNUTLS_FN (int, gnutls_x509_crt_get_subject_unique_id,
182 (gnutls_x509_crt_t, char *, size_t *));
183 DEF_GNUTLS_FN (int, gnutls_x509_crt_get_signature_algorithm,
184 (gnutls_x509_crt_t));
185 DEF_GNUTLS_FN (int, gnutls_x509_crt_get_signature,
186 (gnutls_x509_crt_t, char *, size_t *));
187 DEF_GNUTLS_FN (int, gnutls_x509_crt_get_key_id,
188 (gnutls_x509_crt_t, unsigned int,
189 unsigned char *, size_t *_size));
190 DEF_GNUTLS_FN (const char*, gnutls_sec_param_get_name, (gnutls_sec_param_t));
191 DEF_GNUTLS_FN (const char*, gnutls_sign_get_name, (gnutls_sign_algorithm_t));
192 DEF_GNUTLS_FN (int, gnutls_server_name_set, (gnutls_session_t,
193 gnutls_server_name_type_t,
194 const void *, size_t));
195 DEF_GNUTLS_FN (gnutls_kx_algorithm_t, gnutls_kx_get, (gnutls_session_t));
196 DEF_GNUTLS_FN (const char*, gnutls_kx_get_name, (gnutls_kx_algorithm_t));
197 DEF_GNUTLS_FN (gnutls_protocol_t, gnutls_protocol_get_version,
198 (gnutls_session_t));
199 DEF_GNUTLS_FN (const char*, gnutls_protocol_get_name, (gnutls_protocol_t));
200 DEF_GNUTLS_FN (gnutls_cipher_algorithm_t, gnutls_cipher_get,
201 (gnutls_session_t));
202 DEF_GNUTLS_FN (const char*, gnutls_cipher_get_name,
203 (gnutls_cipher_algorithm_t));
204 DEF_GNUTLS_FN (gnutls_mac_algorithm_t, gnutls_mac_get, (gnutls_session_t));
205 DEF_GNUTLS_FN (const char*, gnutls_mac_get_name, (gnutls_mac_algorithm_t));
206
207
208 static bool
209 init_gnutls_functions (void)
210 {
211 HMODULE library;
212 int max_log_level = 1;
213
214 if (!(library = w32_delayed_load (Qgnutls_dll)))
215 {
216 GNUTLS_LOG (1, max_log_level, "GnuTLS library not found");
217 return 0;
218 }
219
220 LOAD_GNUTLS_FN (library, gnutls_alert_get);
221 LOAD_GNUTLS_FN (library, gnutls_alert_get_name);
222 LOAD_GNUTLS_FN (library, gnutls_alert_send_appropriate);
223 LOAD_GNUTLS_FN (library, gnutls_anon_allocate_client_credentials);
224 LOAD_GNUTLS_FN (library, gnutls_anon_free_client_credentials);
225 LOAD_GNUTLS_FN (library, gnutls_bye);
226 LOAD_GNUTLS_FN (library, gnutls_certificate_allocate_credentials);
227 LOAD_GNUTLS_FN (library, gnutls_certificate_free_credentials);
228 LOAD_GNUTLS_FN (library, gnutls_certificate_get_peers);
229 LOAD_GNUTLS_FN (library, gnutls_certificate_set_verify_flags);
230 LOAD_GNUTLS_FN (library, gnutls_certificate_set_x509_crl_file);
231 LOAD_GNUTLS_FN (library, gnutls_certificate_set_x509_key_file);
232 #if GNUTLS_VERSION_MAJOR + \
233 (GNUTLS_VERSION_MINOR > 0 || GNUTLS_VERSION_PATCH >= 20) > 3
234 LOAD_GNUTLS_FN (library, gnutls_certificate_set_x509_system_trust);
235 #endif
236 LOAD_GNUTLS_FN (library, gnutls_certificate_set_x509_trust_file);
237 LOAD_GNUTLS_FN (library, gnutls_certificate_type_get);
238 LOAD_GNUTLS_FN (library, gnutls_certificate_verify_peers2);
239 LOAD_GNUTLS_FN (library, gnutls_credentials_set);
240 LOAD_GNUTLS_FN (library, gnutls_deinit);
241 LOAD_GNUTLS_FN (library, gnutls_dh_set_prime_bits);
242 LOAD_GNUTLS_FN (library, gnutls_dh_get_prime_bits);
243 LOAD_GNUTLS_FN (library, gnutls_error_is_fatal);
244 LOAD_GNUTLS_FN (library, gnutls_global_init);
245 LOAD_GNUTLS_FN (library, gnutls_global_set_log_function);
246 #ifdef HAVE_GNUTLS3
247 LOAD_GNUTLS_FN (library, gnutls_global_set_audit_log_function);
248 #endif
249 LOAD_GNUTLS_FN (library, gnutls_global_set_log_level);
250 LOAD_GNUTLS_FN (library, gnutls_handshake);
251 LOAD_GNUTLS_FN (library, gnutls_init);
252 LOAD_GNUTLS_FN (library, gnutls_priority_set_direct);
253 LOAD_GNUTLS_FN (library, gnutls_record_check_pending);
254 LOAD_GNUTLS_FN (library, gnutls_record_recv);
255 LOAD_GNUTLS_FN (library, gnutls_record_send);
256 LOAD_GNUTLS_FN (library, gnutls_strerror);
257 LOAD_GNUTLS_FN (library, gnutls_transport_set_errno);
258 LOAD_GNUTLS_FN (library, gnutls_check_version);
259 /* We don't need to call gnutls_transport_set_lowat in GnuTLS 2.11.1
260 and later, and the function was removed entirely in 3.0.0. */
261 if (!fn_gnutls_check_version ("2.11.1"))
262 LOAD_GNUTLS_FN (library, gnutls_transport_set_lowat);
263 LOAD_GNUTLS_FN (library, gnutls_transport_set_ptr2);
264 LOAD_GNUTLS_FN (library, gnutls_transport_set_pull_function);
265 LOAD_GNUTLS_FN (library, gnutls_transport_set_push_function);
266 LOAD_GNUTLS_FN (library, gnutls_x509_crt_check_hostname);
267 LOAD_GNUTLS_FN (library, gnutls_x509_crt_deinit);
268 LOAD_GNUTLS_FN (library, gnutls_x509_crt_import);
269 LOAD_GNUTLS_FN (library, gnutls_x509_crt_init);
270 LOAD_GNUTLS_FN (library, gnutls_x509_crt_get_fingerprint);
271 LOAD_GNUTLS_FN (library, gnutls_x509_crt_get_version);
272 LOAD_GNUTLS_FN (library, gnutls_x509_crt_get_serial);
273 LOAD_GNUTLS_FN (library, gnutls_x509_crt_get_issuer_dn);
274 LOAD_GNUTLS_FN (library, gnutls_x509_crt_get_activation_time);
275 LOAD_GNUTLS_FN (library, gnutls_x509_crt_get_expiration_time);
276 LOAD_GNUTLS_FN (library, gnutls_x509_crt_get_dn);
277 LOAD_GNUTLS_FN (library, gnutls_x509_crt_get_pk_algorithm);
278 LOAD_GNUTLS_FN (library, gnutls_pk_algorithm_get_name);
279 LOAD_GNUTLS_FN (library, gnutls_pk_bits_to_sec_param);
280 LOAD_GNUTLS_FN (library, gnutls_x509_crt_get_issuer_unique_id);
281 LOAD_GNUTLS_FN (library, gnutls_x509_crt_get_subject_unique_id);
282 LOAD_GNUTLS_FN (library, gnutls_x509_crt_get_signature_algorithm);
283 LOAD_GNUTLS_FN (library, gnutls_x509_crt_get_signature);
284 LOAD_GNUTLS_FN (library, gnutls_x509_crt_get_key_id);
285 LOAD_GNUTLS_FN (library, gnutls_sec_param_get_name);
286 LOAD_GNUTLS_FN (library, gnutls_sign_get_name);
287 LOAD_GNUTLS_FN (library, gnutls_server_name_set);
288 LOAD_GNUTLS_FN (library, gnutls_kx_get);
289 LOAD_GNUTLS_FN (library, gnutls_kx_get_name);
290 LOAD_GNUTLS_FN (library, gnutls_protocol_get_version);
291 LOAD_GNUTLS_FN (library, gnutls_protocol_get_name);
292 LOAD_GNUTLS_FN (library, gnutls_cipher_get);
293 LOAD_GNUTLS_FN (library, gnutls_cipher_get_name);
294 LOAD_GNUTLS_FN (library, gnutls_mac_get);
295 LOAD_GNUTLS_FN (library, gnutls_mac_get_name);
296
297 max_log_level = global_gnutls_log_level;
298
299 {
300 Lisp_Object name = CAR_SAFE (Fget (Qgnutls_dll, QCloaded_from));
301 GNUTLS_LOG2 (1, max_log_level, "GnuTLS library loaded:",
302 STRINGP (name) ? (const char *) SDATA (name) : "unknown");
303 }
304
305 return 1;
306 }
307
308 #else /* !WINDOWSNT */
309
310 #define fn_gnutls_alert_get gnutls_alert_get
311 #define fn_gnutls_alert_get_name gnutls_alert_get_name
312 #define fn_gnutls_alert_send_appropriate gnutls_alert_send_appropriate
313 #define fn_gnutls_anon_allocate_client_credentials gnutls_anon_allocate_client_credentials
314 #define fn_gnutls_anon_free_client_credentials gnutls_anon_free_client_credentials
315 #define fn_gnutls_bye gnutls_bye
316 #define fn_gnutls_certificate_allocate_credentials gnutls_certificate_allocate_credentials
317 #define fn_gnutls_certificate_free_credentials gnutls_certificate_free_credentials
318 #define fn_gnutls_certificate_get_peers gnutls_certificate_get_peers
319 #define fn_gnutls_certificate_set_verify_flags gnutls_certificate_set_verify_flags
320 #define fn_gnutls_certificate_set_x509_crl_file gnutls_certificate_set_x509_crl_file
321 #define fn_gnutls_certificate_set_x509_key_file gnutls_certificate_set_x509_key_file
322 #if GNUTLS_VERSION_MAJOR + \
323 (GNUTLS_VERSION_MINOR > 0 || GNUTLS_VERSION_PATCH >= 20) > 3
324 #define fn_gnutls_certificate_set_x509_system_trust gnutls_certificate_set_x509_system_trust
325 #endif
326 #define fn_gnutls_certificate_set_x509_trust_file gnutls_certificate_set_x509_trust_file
327 #define fn_gnutls_certificate_type_get gnutls_certificate_type_get
328 #define fn_gnutls_certificate_verify_peers2 gnutls_certificate_verify_peers2
329 #define fn_gnutls_cipher_get gnutls_cipher_get
330 #define fn_gnutls_cipher_get_name gnutls_cipher_get_name
331 #define fn_gnutls_credentials_set gnutls_credentials_set
332 #define fn_gnutls_deinit gnutls_deinit
333 #define fn_gnutls_dh_get_prime_bits gnutls_dh_get_prime_bits
334 #define fn_gnutls_dh_set_prime_bits gnutls_dh_set_prime_bits
335 #define fn_gnutls_error_is_fatal gnutls_error_is_fatal
336 #define fn_gnutls_global_init gnutls_global_init
337 #ifdef HAVE_GNUTLS3
338 #define fn_gnutls_global_set_audit_log_function gnutls_global_set_audit_log_function
339 #endif
340 #define fn_gnutls_global_set_log_function gnutls_global_set_log_function
341 #define fn_gnutls_global_set_log_level gnutls_global_set_log_level
342 #define fn_gnutls_handshake gnutls_handshake
343 #define fn_gnutls_init gnutls_init
344 #define fn_gnutls_kx_get gnutls_kx_get
345 #define fn_gnutls_kx_get_name gnutls_kx_get_name
346 #define fn_gnutls_mac_get gnutls_mac_get
347 #define fn_gnutls_mac_get_name gnutls_mac_get_name
348 #define fn_gnutls_pk_algorithm_get_name gnutls_pk_algorithm_get_name
349 #define fn_gnutls_pk_bits_to_sec_param gnutls_pk_bits_to_sec_param
350 #define fn_gnutls_priority_set_direct gnutls_priority_set_direct
351 #define fn_gnutls_protocol_get_name gnutls_protocol_get_name
352 #define fn_gnutls_protocol_get_version gnutls_protocol_get_version
353 #define fn_gnutls_record_check_pending gnutls_record_check_pending
354 #define fn_gnutls_record_recv gnutls_record_recv
355 #define fn_gnutls_record_send gnutls_record_send
356 #define fn_gnutls_sec_param_get_name gnutls_sec_param_get_name
357 #define fn_gnutls_server_name_set gnutls_server_name_set
358 #define fn_gnutls_sign_get_name gnutls_sign_get_name
359 #define fn_gnutls_strerror gnutls_strerror
360 #define fn_gnutls_transport_set_ptr2 gnutls_transport_set_ptr2
361 #define fn_gnutls_x509_crt_check_hostname gnutls_x509_crt_check_hostname
362 #define fn_gnutls_x509_crt_deinit gnutls_x509_crt_deinit
363 #define fn_gnutls_x509_crt_get_activation_time gnutls_x509_crt_get_activation_time
364 #define fn_gnutls_x509_crt_get_dn gnutls_x509_crt_get_dn
365 #define fn_gnutls_x509_crt_get_expiration_time gnutls_x509_crt_get_expiration_time
366 #define fn_gnutls_x509_crt_get_fingerprint gnutls_x509_crt_get_fingerprint
367 #define fn_gnutls_x509_crt_get_issuer_dn gnutls_x509_crt_get_issuer_dn
368 #define fn_gnutls_x509_crt_get_issuer_unique_id gnutls_x509_crt_get_issuer_unique_id
369 #define fn_gnutls_x509_crt_get_key_id gnutls_x509_crt_get_key_id
370 #define fn_gnutls_x509_crt_get_pk_algorithm gnutls_x509_crt_get_pk_algorithm
371 #define fn_gnutls_x509_crt_get_serial gnutls_x509_crt_get_serial
372 #define fn_gnutls_x509_crt_get_signature_algorithm gnutls_x509_crt_get_signature_algorithm
373 #define fn_gnutls_x509_crt_get_subject_unique_id gnutls_x509_crt_get_subject_unique_id
374 #define fn_gnutls_x509_crt_get_version gnutls_x509_crt_get_version
375 #define fn_gnutls_x509_crt_import gnutls_x509_crt_import
376 #define fn_gnutls_x509_crt_init gnutls_x509_crt_init
377
378 #endif /* !WINDOWSNT */
379
380 \f
381 /* Report memory exhaustion if ERR is an out-of-memory indication. */
382 static void
383 check_memory_full (int err)
384 {
385 /* When GnuTLS exhausts memory, it doesn't say how much memory it
386 asked for, so tell the Emacs allocator that GnuTLS asked for no
387 bytes. This isn't accurate, but it's good enough. */
388 if (err == GNUTLS_E_MEMORY_ERROR)
389 memory_full (0);
390 }
391
392 #ifdef HAVE_GNUTLS3
393 /* Log a simple audit message. */
394 static void
395 gnutls_audit_log_function (gnutls_session_t session, const char *string)
396 {
397 if (global_gnutls_log_level >= 1)
398 {
399 message ("gnutls.c: [audit] %s", string);
400 }
401 }
402 #endif
403
404 /* Log a simple message. */
405 static void
406 gnutls_log_function (int level, const char *string)
407 {
408 message ("gnutls.c: [%d] %s", level, string);
409 }
410
411 /* Log a message and a string. */
412 static void
413 gnutls_log_function2 (int level, const char *string, const char *extra)
414 {
415 message ("gnutls.c: [%d] %s %s", level, string, extra);
416 }
417
418 /* Log a message and an integer. */
419 static void
420 gnutls_log_function2i (int level, const char *string, int extra)
421 {
422 message ("gnutls.c: [%d] %s %d", level, string, extra);
423 }
424
425 static int
426 emacs_gnutls_handshake (struct Lisp_Process *proc)
427 {
428 gnutls_session_t state = proc->gnutls_state;
429 int ret;
430
431 if (proc->gnutls_initstage < GNUTLS_STAGE_HANDSHAKE_CANDO)
432 return -1;
433
434 if (proc->gnutls_initstage < GNUTLS_STAGE_TRANSPORT_POINTERS_SET)
435 {
436 #ifdef WINDOWSNT
437 /* On W32 we cannot transfer socket handles between different runtime
438 libraries, so we tell GnuTLS to use our special push/pull
439 functions. */
440 fn_gnutls_transport_set_ptr2 (state,
441 (gnutls_transport_ptr_t) proc,
442 (gnutls_transport_ptr_t) proc);
443 fn_gnutls_transport_set_push_function (state, &emacs_gnutls_push);
444 fn_gnutls_transport_set_pull_function (state, &emacs_gnutls_pull);
445
446 /* For non blocking sockets or other custom made pull/push
447 functions the gnutls_transport_set_lowat must be called, with
448 a zero low water mark value. (GnuTLS 2.10.4 documentation)
449
450 (Note: this is probably not strictly necessary as the lowat
451 value is only used when no custom pull/push functions are
452 set.) */
453 /* According to GnuTLS NEWS file, lowat level has been set to
454 zero by default in version 2.11.1, and the function
455 gnutls_transport_set_lowat was removed from the library in
456 version 2.99.0. */
457 if (!fn_gnutls_check_version ("2.11.1"))
458 fn_gnutls_transport_set_lowat (state, 0);
459 #else
460 /* This is how GnuTLS takes sockets: as file descriptors passed
461 in. For an Emacs process socket, infd and outfd are the
462 same but we use this two-argument version for clarity. */
463 fn_gnutls_transport_set_ptr2 (state,
464 (void *) (intptr_t) proc->infd,
465 (void *) (intptr_t) proc->outfd);
466 #endif
467
468 proc->gnutls_initstage = GNUTLS_STAGE_TRANSPORT_POINTERS_SET;
469 }
470
471 do
472 {
473 ret = fn_gnutls_handshake (state);
474 emacs_gnutls_handle_error (state, ret);
475 QUIT;
476 }
477 while (ret < 0 && fn_gnutls_error_is_fatal (ret) == 0);
478
479 proc->gnutls_initstage = GNUTLS_STAGE_HANDSHAKE_TRIED;
480
481 if (ret == GNUTLS_E_SUCCESS)
482 {
483 /* Here we're finally done. */
484 proc->gnutls_initstage = GNUTLS_STAGE_READY;
485 }
486 else
487 {
488 check_memory_full (fn_gnutls_alert_send_appropriate (state, ret));
489 }
490 return ret;
491 }
492
493 ptrdiff_t
494 emacs_gnutls_record_check_pending (gnutls_session_t state)
495 {
496 return fn_gnutls_record_check_pending (state);
497 }
498
499 #ifdef WINDOWSNT
500 void
501 emacs_gnutls_transport_set_errno (gnutls_session_t state, int err)
502 {
503 fn_gnutls_transport_set_errno (state, err);
504 }
505 #endif
506
507 ptrdiff_t
508 emacs_gnutls_write (struct Lisp_Process *proc, const char *buf, ptrdiff_t nbyte)
509 {
510 ssize_t rtnval = 0;
511 ptrdiff_t bytes_written;
512 gnutls_session_t state = proc->gnutls_state;
513
514 if (proc->gnutls_initstage != GNUTLS_STAGE_READY)
515 {
516 errno = EAGAIN;
517 return 0;
518 }
519
520 bytes_written = 0;
521
522 while (nbyte > 0)
523 {
524 rtnval = fn_gnutls_record_send (state, buf, nbyte);
525
526 if (rtnval < 0)
527 {
528 if (rtnval == GNUTLS_E_INTERRUPTED)
529 continue;
530 else
531 {
532 /* If we get GNUTLS_E_AGAIN, then set errno
533 appropriately so that send_process retries the
534 correct way instead of erroring out. */
535 if (rtnval == GNUTLS_E_AGAIN)
536 errno = EAGAIN;
537 break;
538 }
539 }
540
541 buf += rtnval;
542 nbyte -= rtnval;
543 bytes_written += rtnval;
544 }
545
546 emacs_gnutls_handle_error (state, rtnval);
547 return (bytes_written);
548 }
549
550 ptrdiff_t
551 emacs_gnutls_read (struct Lisp_Process *proc, char *buf, ptrdiff_t nbyte)
552 {
553 ssize_t rtnval;
554 gnutls_session_t state = proc->gnutls_state;
555
556 int log_level = proc->gnutls_log_level;
557
558 if (proc->gnutls_initstage != GNUTLS_STAGE_READY)
559 {
560 /* If the handshake count is under the limit, try the handshake
561 again and increment the handshake count. This count is kept
562 per process (connection), not globally. */
563 if (proc->gnutls_handshakes_tried < GNUTLS_EMACS_HANDSHAKES_LIMIT)
564 {
565 proc->gnutls_handshakes_tried++;
566 emacs_gnutls_handshake (proc);
567 GNUTLS_LOG2i (5, log_level, "Retried handshake",
568 proc->gnutls_handshakes_tried);
569 return -1;
570 }
571
572 GNUTLS_LOG (2, log_level, "Giving up on handshake; resetting retries");
573 proc->gnutls_handshakes_tried = 0;
574 return 0;
575 }
576 rtnval = fn_gnutls_record_recv (state, buf, nbyte);
577 if (rtnval >= 0)
578 return rtnval;
579 else if (rtnval == GNUTLS_E_UNEXPECTED_PACKET_LENGTH)
580 /* The peer closed the connection. */
581 return 0;
582 else if (emacs_gnutls_handle_error (state, rtnval))
583 /* non-fatal error */
584 return -1;
585 else {
586 /* a fatal error occurred */
587 return 0;
588 }
589 }
590
591 /* Report a GnuTLS error to the user.
592 Return true if the error code was successfully handled. */
593 static bool
594 emacs_gnutls_handle_error (gnutls_session_t session, int err)
595 {
596 int max_log_level = 0;
597
598 bool ret;
599 const char *str;
600
601 /* TODO: use a Lisp_Object generated by gnutls_make_error? */
602 if (err >= 0)
603 return 1;
604
605 check_memory_full (err);
606
607 max_log_level = global_gnutls_log_level;
608
609 /* TODO: use gnutls-error-fatalp and gnutls-error-string. */
610
611 str = fn_gnutls_strerror (err);
612 if (!str)
613 str = "unknown";
614
615 if (fn_gnutls_error_is_fatal (err))
616 {
617 ret = 0;
618 GNUTLS_LOG2 (1, max_log_level, "fatal error:", str);
619 }
620 else
621 {
622 ret = 1;
623
624 switch (err)
625 {
626 case GNUTLS_E_AGAIN:
627 GNUTLS_LOG2 (3,
628 max_log_level,
629 "retry:",
630 str);
631 default:
632 GNUTLS_LOG2 (1,
633 max_log_level,
634 "non-fatal error:",
635 str);
636 }
637 }
638
639 if (err == GNUTLS_E_WARNING_ALERT_RECEIVED
640 || err == GNUTLS_E_FATAL_ALERT_RECEIVED)
641 {
642 int alert = fn_gnutls_alert_get (session);
643 int level = (err == GNUTLS_E_FATAL_ALERT_RECEIVED) ? 0 : 1;
644 str = fn_gnutls_alert_get_name (alert);
645 if (!str)
646 str = "unknown";
647
648 GNUTLS_LOG2 (level, max_log_level, "Received alert: ", str);
649 }
650 return ret;
651 }
652
653 /* convert an integer error to a Lisp_Object; it will be either a
654 known symbol like `gnutls_e_interrupted' and `gnutls_e_again' or
655 simply the integer value of the error. GNUTLS_E_SUCCESS is mapped
656 to Qt. */
657 static Lisp_Object
658 gnutls_make_error (int err)
659 {
660 switch (err)
661 {
662 case GNUTLS_E_SUCCESS:
663 return Qt;
664 case GNUTLS_E_AGAIN:
665 return Qgnutls_e_again;
666 case GNUTLS_E_INTERRUPTED:
667 return Qgnutls_e_interrupted;
668 case GNUTLS_E_INVALID_SESSION:
669 return Qgnutls_e_invalid_session;
670 }
671
672 check_memory_full (err);
673 return make_number (err);
674 }
675
676 Lisp_Object
677 emacs_gnutls_deinit (Lisp_Object proc)
678 {
679 int log_level;
680
681 CHECK_PROCESS (proc);
682
683 if (XPROCESS (proc)->gnutls_p == 0)
684 return Qnil;
685
686 log_level = XPROCESS (proc)->gnutls_log_level;
687
688 if (XPROCESS (proc)->gnutls_x509_cred)
689 {
690 GNUTLS_LOG (2, log_level, "Deallocating x509 credentials");
691 fn_gnutls_certificate_free_credentials (XPROCESS (proc)->gnutls_x509_cred);
692 XPROCESS (proc)->gnutls_x509_cred = NULL;
693 }
694
695 if (XPROCESS (proc)->gnutls_anon_cred)
696 {
697 GNUTLS_LOG (2, log_level, "Deallocating anon credentials");
698 fn_gnutls_anon_free_client_credentials (XPROCESS (proc)->gnutls_anon_cred);
699 XPROCESS (proc)->gnutls_anon_cred = NULL;
700 }
701
702 if (XPROCESS (proc)->gnutls_state)
703 {
704 fn_gnutls_deinit (XPROCESS (proc)->gnutls_state);
705 XPROCESS (proc)->gnutls_state = NULL;
706 if (GNUTLS_INITSTAGE (proc) >= GNUTLS_STAGE_INIT)
707 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_INIT - 1;
708 }
709
710 XPROCESS (proc)->gnutls_p = 0;
711 return Qt;
712 }
713
714 DEFUN ("gnutls-get-initstage", Fgnutls_get_initstage, Sgnutls_get_initstage, 1, 1, 0,
715 doc: /* Return the GnuTLS init stage of process PROC.
716 See also `gnutls-boot'. */)
717 (Lisp_Object proc)
718 {
719 CHECK_PROCESS (proc);
720
721 return make_number (GNUTLS_INITSTAGE (proc));
722 }
723
724 DEFUN ("gnutls-errorp", Fgnutls_errorp, Sgnutls_errorp, 1, 1, 0,
725 doc: /* Return t if ERROR indicates a GnuTLS problem.
726 ERROR is an integer or a symbol with an integer `gnutls-code' property.
727 usage: (gnutls-errorp ERROR) */)
728 (Lisp_Object err)
729 {
730 if (EQ (err, Qt)) return Qnil;
731
732 return Qt;
733 }
734
735 DEFUN ("gnutls-error-fatalp", Fgnutls_error_fatalp, Sgnutls_error_fatalp, 1, 1, 0,
736 doc: /* Return non-nil if ERROR is fatal.
737 ERROR is an integer or a symbol with an integer `gnutls-code' property.
738 Usage: (gnutls-error-fatalp ERROR) */)
739 (Lisp_Object err)
740 {
741 Lisp_Object code;
742
743 if (EQ (err, Qt)) return Qnil;
744
745 if (SYMBOLP (err))
746 {
747 code = Fget (err, Qgnutls_code);
748 if (NUMBERP (code))
749 {
750 err = code;
751 }
752 else
753 {
754 error ("Symbol has no numeric gnutls-code property");
755 }
756 }
757
758 if (! TYPE_RANGED_INTEGERP (int, err))
759 error ("Not an error symbol or code");
760
761 if (0 == fn_gnutls_error_is_fatal (XINT (err)))
762 return Qnil;
763
764 return Qt;
765 }
766
767 DEFUN ("gnutls-error-string", Fgnutls_error_string, Sgnutls_error_string, 1, 1, 0,
768 doc: /* Return a description of ERROR.
769 ERROR is an integer or a symbol with an integer `gnutls-code' property.
770 usage: (gnutls-error-string ERROR) */)
771 (Lisp_Object err)
772 {
773 Lisp_Object code;
774
775 if (EQ (err, Qt)) return build_string ("Not an error");
776
777 if (SYMBOLP (err))
778 {
779 code = Fget (err, Qgnutls_code);
780 if (NUMBERP (code))
781 {
782 err = code;
783 }
784 else
785 {
786 return build_string ("Symbol has no numeric gnutls-code property");
787 }
788 }
789
790 if (! TYPE_RANGED_INTEGERP (int, err))
791 return build_string ("Not an error symbol or code");
792
793 return build_string (fn_gnutls_strerror (XINT (err)));
794 }
795
796 DEFUN ("gnutls-deinit", Fgnutls_deinit, Sgnutls_deinit, 1, 1, 0,
797 doc: /* Deallocate GnuTLS resources associated with process PROC.
798 See also `gnutls-init'. */)
799 (Lisp_Object proc)
800 {
801 return emacs_gnutls_deinit (proc);
802 }
803
804 static Lisp_Object
805 gnutls_hex_string (unsigned char *buf, ptrdiff_t buf_size, const char *prefix)
806 {
807 ptrdiff_t prefix_length = strlen (prefix);
808 if ((STRING_BYTES_BOUND - prefix_length) / 3 < buf_size)
809 string_overflow ();
810 Lisp_Object ret = make_uninit_string (prefix_length + 3 * buf_size
811 - (buf_size != 0));
812 char *string = SSDATA (ret);
813 strcpy (string, prefix);
814
815 for (ptrdiff_t i = 0; i < buf_size; i++)
816 sprintf (string + i * 3 + prefix_length,
817 i == buf_size - 1 ? "%02x" : "%02x:",
818 buf[i]);
819
820 return ret;
821 }
822
823 static Lisp_Object
824 gnutls_certificate_details (gnutls_x509_crt_t cert)
825 {
826 Lisp_Object res = Qnil;
827 int err;
828 size_t buf_size;
829
830 /* Version. */
831 {
832 int version = fn_gnutls_x509_crt_get_version (cert);
833 check_memory_full (version);
834 if (version >= GNUTLS_E_SUCCESS)
835 res = nconc2 (res, list2 (intern (":version"),
836 make_number (version)));
837 }
838
839 /* Serial. */
840 buf_size = 0;
841 err = fn_gnutls_x509_crt_get_serial (cert, NULL, &buf_size);
842 check_memory_full (err);
843 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER)
844 {
845 void *serial = xmalloc (buf_size);
846 err = fn_gnutls_x509_crt_get_serial (cert, serial, &buf_size);
847 check_memory_full (err);
848 if (err >= GNUTLS_E_SUCCESS)
849 res = nconc2 (res, list2 (intern (":serial-number"),
850 gnutls_hex_string (serial, buf_size, "")));
851 xfree (serial);
852 }
853
854 /* Issuer. */
855 buf_size = 0;
856 err = fn_gnutls_x509_crt_get_issuer_dn (cert, NULL, &buf_size);
857 check_memory_full (err);
858 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER)
859 {
860 char *dn = xmalloc (buf_size);
861 err = fn_gnutls_x509_crt_get_issuer_dn (cert, dn, &buf_size);
862 check_memory_full (err);
863 if (err >= GNUTLS_E_SUCCESS)
864 res = nconc2 (res, list2 (intern (":issuer"),
865 make_string (dn, buf_size)));
866 xfree (dn);
867 }
868
869 /* Validity. */
870 {
871 /* Add 1 to the buffer size, since 1900 is added to tm_year and
872 that might add 1 to the year length. */
873 char buf[INT_STRLEN_BOUND (int) + 1 + sizeof "-12-31"];
874 struct tm t;
875 time_t tim = fn_gnutls_x509_crt_get_activation_time (cert);
876
877 if (gmtime_r (&tim, &t) && strftime (buf, sizeof buf, "%Y-%m-%d", &t))
878 res = nconc2 (res, list2 (intern (":valid-from"), build_string (buf)));
879
880 tim = fn_gnutls_x509_crt_get_expiration_time (cert);
881 if (gmtime_r (&tim, &t) && strftime (buf, sizeof buf, "%Y-%m-%d", &t))
882 res = nconc2 (res, list2 (intern (":valid-to"), build_string (buf)));
883 }
884
885 /* Subject. */
886 buf_size = 0;
887 err = fn_gnutls_x509_crt_get_dn (cert, NULL, &buf_size);
888 check_memory_full (err);
889 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER)
890 {
891 char *dn = xmalloc (buf_size);
892 err = fn_gnutls_x509_crt_get_dn (cert, dn, &buf_size);
893 check_memory_full (err);
894 if (err >= GNUTLS_E_SUCCESS)
895 res = nconc2 (res, list2 (intern (":subject"),
896 make_string (dn, buf_size)));
897 xfree (dn);
898 }
899
900 /* Versions older than 2.11 doesn't have these four functions. */
901 #if GNUTLS_VERSION_NUMBER >= 0x020b00
902 /* SubjectPublicKeyInfo. */
903 {
904 unsigned int bits;
905
906 err = fn_gnutls_x509_crt_get_pk_algorithm (cert, &bits);
907 check_memory_full (err);
908 if (err >= GNUTLS_E_SUCCESS)
909 {
910 const char *name = fn_gnutls_pk_algorithm_get_name (err);
911 if (name)
912 res = nconc2 (res, list2 (intern (":public-key-algorithm"),
913 build_string (name)));
914
915 name = fn_gnutls_sec_param_get_name (fn_gnutls_pk_bits_to_sec_param
916 (err, bits));
917 res = nconc2 (res, list2 (intern (":certificate-security-level"),
918 build_string (name)));
919 }
920 }
921
922 /* Unique IDs. */
923 buf_size = 0;
924 err = fn_gnutls_x509_crt_get_issuer_unique_id (cert, NULL, &buf_size);
925 check_memory_full (err);
926 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER)
927 {
928 char *buf = xmalloc (buf_size);
929 err = fn_gnutls_x509_crt_get_issuer_unique_id (cert, buf, &buf_size);
930 check_memory_full (err);
931 if (err >= GNUTLS_E_SUCCESS)
932 res = nconc2 (res, list2 (intern (":issuer-unique-id"),
933 make_string (buf, buf_size)));
934 xfree (buf);
935 }
936
937 buf_size = 0;
938 err = fn_gnutls_x509_crt_get_subject_unique_id (cert, NULL, &buf_size);
939 check_memory_full (err);
940 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER)
941 {
942 char *buf = xmalloc (buf_size);
943 err = fn_gnutls_x509_crt_get_subject_unique_id (cert, buf, &buf_size);
944 check_memory_full (err);
945 if (err >= GNUTLS_E_SUCCESS)
946 res = nconc2 (res, list2 (intern (":subject-unique-id"),
947 make_string (buf, buf_size)));
948 xfree (buf);
949 }
950 #endif
951
952 /* Signature. */
953 err = fn_gnutls_x509_crt_get_signature_algorithm (cert);
954 check_memory_full (err);
955 if (err >= GNUTLS_E_SUCCESS)
956 {
957 const char *name = fn_gnutls_sign_get_name (err);
958 if (name)
959 res = nconc2 (res, list2 (intern (":signature-algorithm"),
960 build_string (name)));
961 }
962
963 /* Public key ID. */
964 buf_size = 0;
965 err = fn_gnutls_x509_crt_get_key_id (cert, 0, NULL, &buf_size);
966 check_memory_full (err);
967 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER)
968 {
969 void *buf = xmalloc (buf_size);
970 err = fn_gnutls_x509_crt_get_key_id (cert, 0, buf, &buf_size);
971 check_memory_full (err);
972 if (err >= GNUTLS_E_SUCCESS)
973 res = nconc2 (res, list2 (intern (":public-key-id"),
974 gnutls_hex_string (buf, buf_size, "sha1:")));
975 xfree (buf);
976 }
977
978 /* Certificate fingerprint. */
979 buf_size = 0;
980 err = fn_gnutls_x509_crt_get_fingerprint (cert, GNUTLS_DIG_SHA1,
981 NULL, &buf_size);
982 check_memory_full (err);
983 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER)
984 {
985 void *buf = xmalloc (buf_size);
986 err = fn_gnutls_x509_crt_get_fingerprint (cert, GNUTLS_DIG_SHA1,
987 buf, &buf_size);
988 check_memory_full (err);
989 if (err >= GNUTLS_E_SUCCESS)
990 res = nconc2 (res, list2 (intern (":certificate-id"),
991 gnutls_hex_string (buf, buf_size, "sha1:")));
992 xfree (buf);
993 }
994
995 return res;
996 }
997
998 DEFUN ("gnutls-peer-status-warning-describe", Fgnutls_peer_status_warning_describe, Sgnutls_peer_status_warning_describe, 1, 1, 0,
999 doc: /* Describe the warning of a GnuTLS peer status from `gnutls-peer-status'. */)
1000 (Lisp_Object status_symbol)
1001 {
1002 CHECK_SYMBOL (status_symbol);
1003
1004 if (EQ (status_symbol, intern (":invalid")))
1005 return build_string ("certificate could not be verified");
1006
1007 if (EQ (status_symbol, intern (":revoked")))
1008 return build_string ("certificate was revoked (CRL)");
1009
1010 if (EQ (status_symbol, intern (":self-signed")))
1011 return build_string ("certificate signer was not found (self-signed)");
1012
1013 if (EQ (status_symbol, intern (":not-ca")))
1014 return build_string ("certificate signer is not a CA");
1015
1016 if (EQ (status_symbol, intern (":insecure")))
1017 return build_string ("certificate was signed with an insecure algorithm");
1018
1019 if (EQ (status_symbol, intern (":not-activated")))
1020 return build_string ("certificate is not yet activated");
1021
1022 if (EQ (status_symbol, intern (":expired")))
1023 return build_string ("certificate has expired");
1024
1025 if (EQ (status_symbol, intern (":no-host-match")))
1026 return build_string ("certificate host does not match hostname");
1027
1028 return Qnil;
1029 }
1030
1031 DEFUN ("gnutls-peer-status", Fgnutls_peer_status, Sgnutls_peer_status, 1, 1, 0,
1032 doc: /* Describe a GnuTLS PROC peer certificate and any warnings about it.
1033 The return value is a property list with top-level keys :warnings and
1034 :certificate. The :warnings entry is a list of symbols you can describe with
1035 `gnutls-peer-status-warning-describe'. */)
1036 (Lisp_Object proc)
1037 {
1038 Lisp_Object warnings = Qnil, result = Qnil;
1039 unsigned int verification;
1040 gnutls_session_t state;
1041
1042 CHECK_PROCESS (proc);
1043
1044 if (GNUTLS_INITSTAGE (proc) < GNUTLS_STAGE_INIT)
1045 return Qnil;
1046
1047 /* Then collect any warnings already computed by the handshake. */
1048 verification = XPROCESS (proc)->gnutls_peer_verification;
1049
1050 if (verification & GNUTLS_CERT_INVALID)
1051 warnings = Fcons (intern (":invalid"), warnings);
1052
1053 if (verification & GNUTLS_CERT_REVOKED)
1054 warnings = Fcons (intern (":revoked"), warnings);
1055
1056 if (verification & GNUTLS_CERT_SIGNER_NOT_FOUND)
1057 warnings = Fcons (intern (":self-signed"), warnings);
1058
1059 if (verification & GNUTLS_CERT_SIGNER_NOT_CA)
1060 warnings = Fcons (intern (":not-ca"), warnings);
1061
1062 if (verification & GNUTLS_CERT_INSECURE_ALGORITHM)
1063 warnings = Fcons (intern (":insecure"), warnings);
1064
1065 if (verification & GNUTLS_CERT_NOT_ACTIVATED)
1066 warnings = Fcons (intern (":not-activated"), warnings);
1067
1068 if (verification & GNUTLS_CERT_EXPIRED)
1069 warnings = Fcons (intern (":expired"), warnings);
1070
1071 if (XPROCESS (proc)->gnutls_extra_peer_verification &
1072 CERTIFICATE_NOT_MATCHING)
1073 warnings = Fcons (intern (":no-host-match"), warnings);
1074
1075 if (!NILP (warnings))
1076 result = list2 (intern (":warnings"), warnings);
1077
1078 /* This could get called in the INIT stage, when the certificate is
1079 not yet set. */
1080 if (XPROCESS (proc)->gnutls_certificate != NULL)
1081 result = nconc2 (result, list2
1082 (intern (":certificate"),
1083 gnutls_certificate_details (XPROCESS (proc)->gnutls_certificate)));
1084
1085 state = XPROCESS (proc)->gnutls_state;
1086
1087 /* Diffie-Hellman prime bits. */
1088 {
1089 int bits = fn_gnutls_dh_get_prime_bits (state);
1090 check_memory_full (bits);
1091 if (bits > 0)
1092 result = nconc2 (result, list2 (intern (":diffie-hellman-prime-bits"),
1093 make_number (bits)));
1094 }
1095
1096 /* Key exchange. */
1097 result = nconc2
1098 (result, list2 (intern (":key-exchange"),
1099 build_string (fn_gnutls_kx_get_name
1100 (fn_gnutls_kx_get (state)))));
1101
1102 /* Protocol name. */
1103 result = nconc2
1104 (result, list2 (intern (":protocol"),
1105 build_string (fn_gnutls_protocol_get_name
1106 (fn_gnutls_protocol_get_version (state)))));
1107
1108 /* Cipher name. */
1109 result = nconc2
1110 (result, list2 (intern (":cipher"),
1111 build_string (fn_gnutls_cipher_get_name
1112 (fn_gnutls_cipher_get (state)))));
1113
1114 /* MAC name. */
1115 result = nconc2
1116 (result, list2 (intern (":mac"),
1117 build_string (fn_gnutls_mac_get_name
1118 (fn_gnutls_mac_get (state)))));
1119
1120
1121 return result;
1122 }
1123
1124 /* Initialize global GnuTLS state to defaults.
1125 Call `gnutls-global-deinit' when GnuTLS usage is no longer needed.
1126 Return zero on success. */
1127 static Lisp_Object
1128 emacs_gnutls_global_init (void)
1129 {
1130 int ret = GNUTLS_E_SUCCESS;
1131
1132 if (!gnutls_global_initialized)
1133 ret = fn_gnutls_global_init ();
1134
1135 gnutls_global_initialized = 1;
1136
1137 return gnutls_make_error (ret);
1138 }
1139
1140 static bool
1141 gnutls_ip_address_p (char *string)
1142 {
1143 char c;
1144
1145 while ((c = *string++) != 0)
1146 if (! ((c == '.' || c == ':' || (c >= '0' && c <= '9'))))
1147 return false;
1148
1149 return true;
1150 }
1151
1152 #if 0
1153 /* Deinitialize global GnuTLS state.
1154 See also `gnutls-global-init'. */
1155 static Lisp_Object
1156 emacs_gnutls_global_deinit (void)
1157 {
1158 if (gnutls_global_initialized)
1159 gnutls_global_deinit ();
1160
1161 gnutls_global_initialized = 0;
1162
1163 return gnutls_make_error (GNUTLS_E_SUCCESS);
1164 }
1165 #endif
1166
1167 DEFUN ("gnutls-boot", Fgnutls_boot, Sgnutls_boot, 3, 3, 0,
1168 doc: /* Initialize GnuTLS client for process PROC with TYPE+PROPLIST.
1169 Currently only client mode is supported. Return a success/failure
1170 value you can check with `gnutls-errorp'.
1171
1172 TYPE is a symbol, either `gnutls-anon' or `gnutls-x509pki'.
1173 PROPLIST is a property list with the following keys:
1174
1175 :hostname is a string naming the remote host.
1176
1177 :priority is a GnuTLS priority string, defaults to "NORMAL".
1178
1179 :trustfiles is a list of PEM-encoded trust files for `gnutls-x509pki'.
1180
1181 :crlfiles is a list of PEM-encoded CRL lists for `gnutls-x509pki'.
1182
1183 :keylist is an alist of PEM-encoded key files and PEM-encoded
1184 certificates for `gnutls-x509pki'.
1185
1186 :callbacks is an alist of callback functions, see below.
1187
1188 :loglevel is the debug level requested from GnuTLS, try 4.
1189
1190 :verify-flags is a bitset as per GnuTLS'
1191 gnutls_certificate_set_verify_flags.
1192
1193 :verify-hostname-error is ignored. Pass :hostname in :verify-error
1194 instead.
1195
1196 :verify-error is a list of symbols to express verification checks or
1197 `t' to do all checks. Currently it can contain `:trustfiles' and
1198 `:hostname' to verify the certificate or the hostname respectively.
1199
1200 :min-prime-bits is the minimum accepted number of bits the client will
1201 accept in Diffie-Hellman key exchange.
1202
1203 The debug level will be set for this process AND globally for GnuTLS.
1204 So if you set it higher or lower at any point, it affects global
1205 debugging.
1206
1207 Note that the priority is set on the client. The server does not use
1208 the protocols's priority except for disabling protocols that were not
1209 specified.
1210
1211 Processes must be initialized with this function before other GnuTLS
1212 functions are used. This function allocates resources which can only
1213 be deallocated by calling `gnutls-deinit' or by calling it again.
1214
1215 The callbacks alist can have a `verify' key, associated with a
1216 verification function (UNUSED).
1217
1218 Each authentication type may need additional information in order to
1219 work. For X.509 PKI (`gnutls-x509pki'), you probably need at least
1220 one trustfile (usually a CA bundle). */)
1221 (Lisp_Object proc, Lisp_Object type, Lisp_Object proplist)
1222 {
1223 int ret = GNUTLS_E_SUCCESS;
1224 int max_log_level = 0;
1225 bool verify_error_all = 0;
1226
1227 gnutls_session_t state;
1228 gnutls_certificate_credentials_t x509_cred = NULL;
1229 gnutls_anon_client_credentials_t anon_cred = NULL;
1230 Lisp_Object global_init;
1231 char const *priority_string_ptr = "NORMAL"; /* default priority string. */
1232 unsigned int peer_verification;
1233 char *c_hostname;
1234
1235 /* Placeholders for the property list elements. */
1236 Lisp_Object priority_string;
1237 Lisp_Object trustfiles;
1238 Lisp_Object crlfiles;
1239 Lisp_Object keylist;
1240 /* Lisp_Object callbacks; */
1241 Lisp_Object loglevel;
1242 Lisp_Object hostname;
1243 Lisp_Object verify_error;
1244 Lisp_Object prime_bits;
1245 Lisp_Object warnings;
1246
1247 CHECK_PROCESS (proc);
1248 CHECK_SYMBOL (type);
1249 CHECK_LIST (proplist);
1250
1251 if (NILP (Fgnutls_available_p ()))
1252 error ("GnuTLS not available");
1253
1254 if (!EQ (type, Qgnutls_x509pki) && !EQ (type, Qgnutls_anon))
1255 error ("Invalid GnuTLS credential type");
1256
1257 hostname = Fplist_get (proplist, QCgnutls_bootprop_hostname);
1258 priority_string = Fplist_get (proplist, QCgnutls_bootprop_priority);
1259 trustfiles = Fplist_get (proplist, QCgnutls_bootprop_trustfiles);
1260 keylist = Fplist_get (proplist, QCgnutls_bootprop_keylist);
1261 crlfiles = Fplist_get (proplist, QCgnutls_bootprop_crlfiles);
1262 loglevel = Fplist_get (proplist, QCgnutls_bootprop_loglevel);
1263 verify_error = Fplist_get (proplist, QCgnutls_bootprop_verify_error);
1264 prime_bits = Fplist_get (proplist, QCgnutls_bootprop_min_prime_bits);
1265
1266 if (EQ (verify_error, Qt))
1267 {
1268 verify_error_all = 1;
1269 }
1270 else if (NILP (Flistp (verify_error)))
1271 {
1272 error ("gnutls-boot: invalid :verify_error parameter (not a list)");
1273 }
1274
1275 if (!STRINGP (hostname))
1276 error ("gnutls-boot: invalid :hostname parameter (not a string)");
1277 c_hostname = SSDATA (hostname);
1278
1279 state = XPROCESS (proc)->gnutls_state;
1280
1281 if (TYPE_RANGED_INTEGERP (int, loglevel))
1282 {
1283 fn_gnutls_global_set_log_function (gnutls_log_function);
1284 #ifdef HAVE_GNUTLS3
1285 fn_gnutls_global_set_audit_log_function (gnutls_audit_log_function);
1286 #endif
1287 fn_gnutls_global_set_log_level (XINT (loglevel));
1288 max_log_level = XINT (loglevel);
1289 XPROCESS (proc)->gnutls_log_level = max_log_level;
1290 }
1291
1292 GNUTLS_LOG2 (1, max_log_level, "connecting to host:", c_hostname);
1293
1294 /* Always initialize globals. */
1295 global_init = emacs_gnutls_global_init ();
1296 if (! NILP (Fgnutls_errorp (global_init)))
1297 return global_init;
1298
1299 /* Before allocating new credentials, deallocate any credentials
1300 that PROC might already have. */
1301 emacs_gnutls_deinit (proc);
1302
1303 /* Mark PROC as a GnuTLS process. */
1304 XPROCESS (proc)->gnutls_state = NULL;
1305 XPROCESS (proc)->gnutls_x509_cred = NULL;
1306 XPROCESS (proc)->gnutls_anon_cred = NULL;
1307 pset_gnutls_cred_type (XPROCESS (proc), type);
1308 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_EMPTY;
1309
1310 GNUTLS_LOG (1, max_log_level, "allocating credentials");
1311 if (EQ (type, Qgnutls_x509pki))
1312 {
1313 Lisp_Object verify_flags;
1314 unsigned int gnutls_verify_flags = GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT;
1315
1316 GNUTLS_LOG (2, max_log_level, "allocating x509 credentials");
1317 check_memory_full ((fn_gnutls_certificate_allocate_credentials
1318 (&x509_cred)));
1319 XPROCESS (proc)->gnutls_x509_cred = x509_cred;
1320
1321 verify_flags = Fplist_get (proplist, QCgnutls_bootprop_verify_flags);
1322 if (NUMBERP (verify_flags))
1323 {
1324 gnutls_verify_flags = XINT (verify_flags);
1325 GNUTLS_LOG (2, max_log_level, "setting verification flags");
1326 }
1327 else if (NILP (verify_flags))
1328 GNUTLS_LOG (2, max_log_level, "using default verification flags");
1329 else
1330 GNUTLS_LOG (2, max_log_level, "ignoring invalid verify-flags");
1331
1332 fn_gnutls_certificate_set_verify_flags (x509_cred, gnutls_verify_flags);
1333 }
1334 else /* Qgnutls_anon: */
1335 {
1336 GNUTLS_LOG (2, max_log_level, "allocating anon credentials");
1337 check_memory_full ((fn_gnutls_anon_allocate_client_credentials
1338 (&anon_cred)));
1339 XPROCESS (proc)->gnutls_anon_cred = anon_cred;
1340 }
1341
1342 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_CRED_ALLOC;
1343
1344 if (EQ (type, Qgnutls_x509pki))
1345 {
1346 /* TODO: GNUTLS_X509_FMT_DER is also an option. */
1347 int file_format = GNUTLS_X509_FMT_PEM;
1348 Lisp_Object tail;
1349
1350 #if GNUTLS_VERSION_MAJOR + \
1351 (GNUTLS_VERSION_MINOR > 0 || GNUTLS_VERSION_PATCH >= 20) > 3
1352 ret = fn_gnutls_certificate_set_x509_system_trust (x509_cred);
1353 if (ret < GNUTLS_E_SUCCESS)
1354 {
1355 check_memory_full (ret);
1356 GNUTLS_LOG2i (4, max_log_level,
1357 "setting system trust failed with code ", ret);
1358 }
1359 #endif
1360
1361 for (tail = trustfiles; CONSP (tail); tail = XCDR (tail))
1362 {
1363 Lisp_Object trustfile = XCAR (tail);
1364 if (STRINGP (trustfile))
1365 {
1366 GNUTLS_LOG2 (1, max_log_level, "setting the trustfile: ",
1367 SSDATA (trustfile));
1368 trustfile = ENCODE_FILE (trustfile);
1369 #ifdef WINDOWSNT
1370 /* Since GnuTLS doesn't support UTF-8 or UTF-16 encoded
1371 file names on Windows, we need to re-encode the file
1372 name using the current ANSI codepage. */
1373 trustfile = ansi_encode_filename (trustfile);
1374 #endif
1375 ret = fn_gnutls_certificate_set_x509_trust_file
1376 (x509_cred,
1377 SSDATA (trustfile),
1378 file_format);
1379
1380 if (ret < GNUTLS_E_SUCCESS)
1381 return gnutls_make_error (ret);
1382 }
1383 else
1384 {
1385 emacs_gnutls_deinit (proc);
1386 error ("Invalid trustfile");
1387 }
1388 }
1389
1390 for (tail = crlfiles; CONSP (tail); tail = XCDR (tail))
1391 {
1392 Lisp_Object crlfile = XCAR (tail);
1393 if (STRINGP (crlfile))
1394 {
1395 GNUTLS_LOG2 (1, max_log_level, "setting the CRL file: ",
1396 SSDATA (crlfile));
1397 crlfile = ENCODE_FILE (crlfile);
1398 #ifdef WINDOWSNT
1399 crlfile = ansi_encode_filename (crlfile);
1400 #endif
1401 ret = fn_gnutls_certificate_set_x509_crl_file
1402 (x509_cred, SSDATA (crlfile), file_format);
1403
1404 if (ret < GNUTLS_E_SUCCESS)
1405 return gnutls_make_error (ret);
1406 }
1407 else
1408 {
1409 emacs_gnutls_deinit (proc);
1410 error ("Invalid CRL file");
1411 }
1412 }
1413
1414 for (tail = keylist; CONSP (tail); tail = XCDR (tail))
1415 {
1416 Lisp_Object keyfile = Fcar (XCAR (tail));
1417 Lisp_Object certfile = Fcar (Fcdr (XCAR (tail)));
1418 if (STRINGP (keyfile) && STRINGP (certfile))
1419 {
1420 GNUTLS_LOG2 (1, max_log_level, "setting the client key file: ",
1421 SSDATA (keyfile));
1422 GNUTLS_LOG2 (1, max_log_level, "setting the client cert file: ",
1423 SSDATA (certfile));
1424 keyfile = ENCODE_FILE (keyfile);
1425 certfile = ENCODE_FILE (certfile);
1426 #ifdef WINDOWSNT
1427 keyfile = ansi_encode_filename (keyfile);
1428 certfile = ansi_encode_filename (certfile);
1429 #endif
1430 ret = fn_gnutls_certificate_set_x509_key_file
1431 (x509_cred, SSDATA (certfile), SSDATA (keyfile), file_format);
1432
1433 if (ret < GNUTLS_E_SUCCESS)
1434 return gnutls_make_error (ret);
1435 }
1436 else
1437 {
1438 emacs_gnutls_deinit (proc);
1439 error (STRINGP (keyfile) ? "Invalid client cert file"
1440 : "Invalid client key file");
1441 }
1442 }
1443 }
1444
1445 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_FILES;
1446 GNUTLS_LOG (1, max_log_level, "gnutls callbacks");
1447 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_CALLBACKS;
1448
1449 /* Call gnutls_init here: */
1450
1451 GNUTLS_LOG (1, max_log_level, "gnutls_init");
1452 ret = fn_gnutls_init (&state, GNUTLS_CLIENT);
1453 XPROCESS (proc)->gnutls_state = state;
1454 if (ret < GNUTLS_E_SUCCESS)
1455 return gnutls_make_error (ret);
1456 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_INIT;
1457
1458 if (STRINGP (priority_string))
1459 {
1460 priority_string_ptr = SSDATA (priority_string);
1461 GNUTLS_LOG2 (1, max_log_level, "got non-default priority string:",
1462 priority_string_ptr);
1463 }
1464 else
1465 {
1466 GNUTLS_LOG2 (1, max_log_level, "using default priority string:",
1467 priority_string_ptr);
1468 }
1469
1470 GNUTLS_LOG (1, max_log_level, "setting the priority string");
1471 ret = fn_gnutls_priority_set_direct (state,
1472 priority_string_ptr,
1473 NULL);
1474 if (ret < GNUTLS_E_SUCCESS)
1475 return gnutls_make_error (ret);
1476
1477 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_PRIORITY;
1478
1479 if (INTEGERP (prime_bits))
1480 fn_gnutls_dh_set_prime_bits (state, XUINT (prime_bits));
1481
1482 ret = EQ (type, Qgnutls_x509pki)
1483 ? fn_gnutls_credentials_set (state, GNUTLS_CRD_CERTIFICATE, x509_cred)
1484 : fn_gnutls_credentials_set (state, GNUTLS_CRD_ANON, anon_cred);
1485 if (ret < GNUTLS_E_SUCCESS)
1486 return gnutls_make_error (ret);
1487
1488 if (!gnutls_ip_address_p (c_hostname))
1489 {
1490 ret = fn_gnutls_server_name_set (state, GNUTLS_NAME_DNS, c_hostname,
1491 strlen (c_hostname));
1492 if (ret < GNUTLS_E_SUCCESS)
1493 return gnutls_make_error (ret);
1494 }
1495
1496 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_CRED_SET;
1497 ret = emacs_gnutls_handshake (XPROCESS (proc));
1498 if (ret < GNUTLS_E_SUCCESS)
1499 return gnutls_make_error (ret);
1500
1501 /* Now verify the peer, following
1502 http://www.gnu.org/software/gnutls/manual/html_node/Verifying-peer_0027s-certificate.html.
1503 The peer should present at least one certificate in the chain; do a
1504 check of the certificate's hostname with
1505 gnutls_x509_crt_check_hostname against :hostname. */
1506
1507 ret = fn_gnutls_certificate_verify_peers2 (state, &peer_verification);
1508 if (ret < GNUTLS_E_SUCCESS)
1509 return gnutls_make_error (ret);
1510
1511 XPROCESS (proc)->gnutls_peer_verification = peer_verification;
1512
1513 warnings = Fplist_get (Fgnutls_peer_status (proc), intern (":warnings"));
1514 if (!NILP (warnings))
1515 {
1516 Lisp_Object tail;
1517 for (tail = warnings; CONSP (tail); tail = XCDR (tail))
1518 {
1519 Lisp_Object warning = XCAR (tail);
1520 Lisp_Object message = Fgnutls_peer_status_warning_describe (warning);
1521 if (!NILP (message))
1522 GNUTLS_LOG2 (1, max_log_level, "verification:", SSDATA (message));
1523 }
1524 }
1525
1526 if (peer_verification != 0)
1527 {
1528 if (verify_error_all
1529 || !NILP (Fmember (QCgnutls_bootprop_trustfiles, verify_error)))
1530 {
1531 emacs_gnutls_deinit (proc);
1532 error ("Certificate validation failed %s, verification code %d",
1533 c_hostname, peer_verification);
1534 }
1535 else
1536 {
1537 GNUTLS_LOG2 (1, max_log_level, "certificate validation failed:",
1538 c_hostname);
1539 }
1540 }
1541
1542 /* Up to here the process is the same for X.509 certificates and
1543 OpenPGP keys. From now on X.509 certificates are assumed. This
1544 can be easily extended to work with openpgp keys as well. */
1545 if (fn_gnutls_certificate_type_get (state) == GNUTLS_CRT_X509)
1546 {
1547 gnutls_x509_crt_t gnutls_verify_cert;
1548 const gnutls_datum_t *gnutls_verify_cert_list;
1549 unsigned int gnutls_verify_cert_list_size;
1550
1551 ret = fn_gnutls_x509_crt_init (&gnutls_verify_cert);
1552 if (ret < GNUTLS_E_SUCCESS)
1553 return gnutls_make_error (ret);
1554
1555 gnutls_verify_cert_list =
1556 fn_gnutls_certificate_get_peers (state, &gnutls_verify_cert_list_size);
1557
1558 if (gnutls_verify_cert_list == NULL)
1559 {
1560 fn_gnutls_x509_crt_deinit (gnutls_verify_cert);
1561 emacs_gnutls_deinit (proc);
1562 error ("No x509 certificate was found\n");
1563 }
1564
1565 /* We only check the first certificate in the given chain. */
1566 ret = fn_gnutls_x509_crt_import (gnutls_verify_cert,
1567 &gnutls_verify_cert_list[0],
1568 GNUTLS_X509_FMT_DER);
1569
1570 if (ret < GNUTLS_E_SUCCESS)
1571 {
1572 fn_gnutls_x509_crt_deinit (gnutls_verify_cert);
1573 return gnutls_make_error (ret);
1574 }
1575
1576 XPROCESS (proc)->gnutls_certificate = gnutls_verify_cert;
1577
1578 int err
1579 = fn_gnutls_x509_crt_check_hostname (gnutls_verify_cert, c_hostname);
1580 check_memory_full (err);
1581 if (!err)
1582 {
1583 XPROCESS (proc)->gnutls_extra_peer_verification |=
1584 CERTIFICATE_NOT_MATCHING;
1585 if (verify_error_all
1586 || !NILP (Fmember (QCgnutls_bootprop_hostname, verify_error)))
1587 {
1588 fn_gnutls_x509_crt_deinit (gnutls_verify_cert);
1589 emacs_gnutls_deinit (proc);
1590 error ("The x509 certificate does not match \"%s\"", c_hostname);
1591 }
1592 else
1593 {
1594 GNUTLS_LOG2 (1, max_log_level, "x509 certificate does not match:",
1595 c_hostname);
1596 }
1597 }
1598 }
1599
1600 /* Set this flag only if the whole initialization succeeded. */
1601 XPROCESS (proc)->gnutls_p = 1;
1602
1603 return gnutls_make_error (ret);
1604 }
1605
1606 DEFUN ("gnutls-bye", Fgnutls_bye,
1607 Sgnutls_bye, 2, 2, 0,
1608 doc: /* Terminate current GnuTLS connection for process PROC.
1609 The connection should have been initiated using `gnutls-handshake'.
1610
1611 If CONT is not nil the TLS connection gets terminated and further
1612 receives and sends will be disallowed. If the return value is zero you
1613 may continue using the connection. If CONT is nil, GnuTLS actually
1614 sends an alert containing a close request and waits for the peer to
1615 reply with the same message. In order to reuse the connection you
1616 should wait for an EOF from the peer.
1617
1618 This function may also return `gnutls-e-again', or
1619 `gnutls-e-interrupted'. */)
1620 (Lisp_Object proc, Lisp_Object cont)
1621 {
1622 gnutls_session_t state;
1623 int ret;
1624
1625 CHECK_PROCESS (proc);
1626
1627 state = XPROCESS (proc)->gnutls_state;
1628
1629 fn_gnutls_x509_crt_deinit (XPROCESS (proc)->gnutls_certificate);
1630
1631 ret = fn_gnutls_bye (state,
1632 NILP (cont) ? GNUTLS_SHUT_RDWR : GNUTLS_SHUT_WR);
1633
1634 return gnutls_make_error (ret);
1635 }
1636
1637 #endif /* HAVE_GNUTLS */
1638
1639 DEFUN ("gnutls-available-p", Fgnutls_available_p, Sgnutls_available_p, 0, 0, 0,
1640 doc: /* Return t if GnuTLS is available in this instance of Emacs. */)
1641 (void)
1642 {
1643 #ifdef HAVE_GNUTLS
1644 # ifdef WINDOWSNT
1645 Lisp_Object found = Fassq (Qgnutls_dll, Vlibrary_cache);
1646 if (CONSP (found))
1647 return XCDR (found);
1648 else
1649 {
1650 Lisp_Object status;
1651 status = init_gnutls_functions () ? Qt : Qnil;
1652 Vlibrary_cache = Fcons (Fcons (Qgnutls_dll, status), Vlibrary_cache);
1653 return status;
1654 }
1655 # else /* !WINDOWSNT */
1656 return Qt;
1657 # endif /* !WINDOWSNT */
1658 #else /* !HAVE_GNUTLS */
1659 return Qnil;
1660 #endif /* !HAVE_GNUTLS */
1661 }
1662
1663 void
1664 syms_of_gnutls (void)
1665 {
1666 #ifdef HAVE_GNUTLS
1667 gnutls_global_initialized = 0;
1668
1669 DEFSYM (Qgnutls_dll, "gnutls");
1670 DEFSYM (Qgnutls_code, "gnutls-code");
1671 DEFSYM (Qgnutls_anon, "gnutls-anon");
1672 DEFSYM (Qgnutls_x509pki, "gnutls-x509pki");
1673 DEFSYM (QCgnutls_bootprop_hostname, ":hostname");
1674 DEFSYM (QCgnutls_bootprop_priority, ":priority");
1675 DEFSYM (QCgnutls_bootprop_trustfiles, ":trustfiles");
1676 DEFSYM (QCgnutls_bootprop_keylist, ":keylist");
1677 DEFSYM (QCgnutls_bootprop_crlfiles, ":crlfiles");
1678 DEFSYM (QCgnutls_bootprop_callbacks, ":callbacks");
1679 DEFSYM (QCgnutls_bootprop_callbacks_verify, "verify");
1680 DEFSYM (QCgnutls_bootprop_min_prime_bits, ":min-prime-bits");
1681 DEFSYM (QCgnutls_bootprop_loglevel, ":loglevel");
1682 DEFSYM (QCgnutls_bootprop_verify_flags, ":verify-flags");
1683 DEFSYM (QCgnutls_bootprop_verify_error, ":verify-error");
1684
1685 DEFSYM (Qgnutls_e_interrupted, "gnutls-e-interrupted");
1686 Fput (Qgnutls_e_interrupted, Qgnutls_code,
1687 make_number (GNUTLS_E_INTERRUPTED));
1688
1689 DEFSYM (Qgnutls_e_again, "gnutls-e-again");
1690 Fput (Qgnutls_e_again, Qgnutls_code,
1691 make_number (GNUTLS_E_AGAIN));
1692
1693 DEFSYM (Qgnutls_e_invalid_session, "gnutls-e-invalid-session");
1694 Fput (Qgnutls_e_invalid_session, Qgnutls_code,
1695 make_number (GNUTLS_E_INVALID_SESSION));
1696
1697 DEFSYM (Qgnutls_e_not_ready_for_handshake, "gnutls-e-not-ready-for-handshake");
1698 Fput (Qgnutls_e_not_ready_for_handshake, Qgnutls_code,
1699 make_number (GNUTLS_E_APPLICATION_ERROR_MIN));
1700
1701 defsubr (&Sgnutls_get_initstage);
1702 defsubr (&Sgnutls_errorp);
1703 defsubr (&Sgnutls_error_fatalp);
1704 defsubr (&Sgnutls_error_string);
1705 defsubr (&Sgnutls_boot);
1706 defsubr (&Sgnutls_deinit);
1707 defsubr (&Sgnutls_bye);
1708 defsubr (&Sgnutls_peer_status);
1709 defsubr (&Sgnutls_peer_status_warning_describe);
1710
1711 DEFVAR_INT ("gnutls-log-level", global_gnutls_log_level,
1712 doc: /* Logging level used by the GnuTLS functions.
1713 Set this larger than 0 to get debug output in the *Messages* buffer.
1714 1 is for important messages, 2 is for debug data, and higher numbers
1715 are as per the GnuTLS logging conventions. */);
1716 global_gnutls_log_level = 0;
1717
1718 #endif /* HAVE_GNUTLS */
1719
1720 defsubr (&Sgnutls_available_p);
1721 }