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