Adapt shadowfile.el for Tramp (Bug#4526, Bug#4846)
[emacs.git] / src / gnutls.c
blob461260e27f4734c17e43e4eb15f7acf3c88d214e
1 /* GnuTLS glue for GNU Emacs.
2 Copyright (C) 2010-2018 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or (at
9 your option) any later version.
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
19 #include <config.h>
20 #include <errno.h>
21 #include <stdio.h>
23 #include "lisp.h"
24 #include "process.h"
25 #include "gnutls.h"
26 #include "coding.h"
27 #include "buffer.h"
29 #if GNUTLS_VERSION_NUMBER >= 0x030014
30 # define HAVE_GNUTLS_X509_SYSTEM_TRUST
31 #endif
33 /* Although AEAD support started in GnuTLS 3.4.0 and works in 3.5.14,
34 it was broken through at least GnuTLS 3.4.10; see:
35 https://lists.gnu.org/r/emacs-devel/2017-07/msg00992.html
36 The relevant fix seems to have been made in GnuTLS 3.5.1; see:
37 https://gitlab.com/gnutls/gnutls/commit/568935848dd6b82b9315d8b6c529d00e2605e03d
38 So, require 3.5.1. */
39 #if GNUTLS_VERSION_NUMBER >= 0x030501
40 # define HAVE_GNUTLS_AEAD
41 #endif
43 /* gnutls_mac_get_nonce_size was added in GnuTLS 3.2.0, but was
44 exported only since 3.3.0. */
45 #if GNUTLS_VERSION_NUMBER >= 0x030300
46 # define HAVE_GNUTLS_MAC_GET_NONCE_SIZE
47 #endif
49 #if GNUTLS_VERSION_NUMBER >= 0x030501
50 # define HAVE_GNUTLS_EXT_GET_NAME
51 #endif
53 #if GNUTLS_VERSION_NUMBER >= 0x030205
54 # define HAVE_GNUTLS_EXT__DUMBFW
55 #endif
57 #ifdef HAVE_GNUTLS
59 # ifdef WINDOWSNT
60 # include <windows.h>
61 # include "w32.h"
62 # endif
64 static bool emacs_gnutls_handle_error (gnutls_session_t, int);
66 static bool gnutls_global_initialized;
68 static void gnutls_log_function (int, const char *);
69 static void gnutls_log_function2 (int, const char *, const char *);
70 # ifdef HAVE_GNUTLS3
71 static void gnutls_audit_log_function (gnutls_session_t, const char *);
72 # endif
74 enum extra_peer_verification
76 CERTIFICATE_NOT_MATCHING = 2
80 # ifdef WINDOWSNT
82 DEF_DLL_FN (gnutls_alert_description_t, gnutls_alert_get,
83 (gnutls_session_t));
84 DEF_DLL_FN (const char *, gnutls_alert_get_name,
85 (gnutls_alert_description_t));
86 DEF_DLL_FN (int, gnutls_anon_allocate_client_credentials,
87 (gnutls_anon_client_credentials_t *));
88 DEF_DLL_FN (void, gnutls_anon_free_client_credentials,
89 (gnutls_anon_client_credentials_t));
90 DEF_DLL_FN (int, gnutls_bye, (gnutls_session_t, gnutls_close_request_t));
91 DEF_DLL_FN (int, gnutls_certificate_allocate_credentials,
92 (gnutls_certificate_credentials_t *));
93 DEF_DLL_FN (void, gnutls_certificate_free_credentials,
94 (gnutls_certificate_credentials_t));
95 DEF_DLL_FN (const gnutls_datum_t *, gnutls_certificate_get_peers,
96 (gnutls_session_t, unsigned int *));
97 DEF_DLL_FN (void, gnutls_certificate_set_verify_flags,
98 (gnutls_certificate_credentials_t, unsigned int));
99 DEF_DLL_FN (int, gnutls_certificate_set_x509_crl_file,
100 (gnutls_certificate_credentials_t, const char *,
101 gnutls_x509_crt_fmt_t));
102 DEF_DLL_FN (int, gnutls_certificate_set_x509_key_file,
103 (gnutls_certificate_credentials_t, const char *, const char *,
104 gnutls_x509_crt_fmt_t));
105 # ifdef HAVE_GNUTLS_X509_SYSTEM_TRUST
106 DEF_DLL_FN (int, gnutls_certificate_set_x509_system_trust,
107 (gnutls_certificate_credentials_t));
108 # endif
109 DEF_DLL_FN (int, gnutls_certificate_set_x509_trust_file,
110 (gnutls_certificate_credentials_t, const char *,
111 gnutls_x509_crt_fmt_t));
112 DEF_DLL_FN (gnutls_certificate_type_t, gnutls_certificate_type_get,
113 (gnutls_session_t));
114 DEF_DLL_FN (int, gnutls_certificate_verify_peers2,
115 (gnutls_session_t, unsigned int *));
116 DEF_DLL_FN (int, gnutls_credentials_set,
117 (gnutls_session_t, gnutls_credentials_type_t, void *));
118 DEF_DLL_FN (void, gnutls_deinit, (gnutls_session_t));
119 DEF_DLL_FN (void, gnutls_dh_set_prime_bits,
120 (gnutls_session_t, unsigned int));
121 DEF_DLL_FN (int, gnutls_dh_get_prime_bits, (gnutls_session_t));
122 DEF_DLL_FN (int, gnutls_error_is_fatal, (int));
123 DEF_DLL_FN (int, gnutls_global_init, (void));
124 DEF_DLL_FN (void, gnutls_global_set_log_function, (gnutls_log_func));
125 # ifdef HAVE_GNUTLS3
126 DEF_DLL_FN (void, gnutls_global_set_audit_log_function, (gnutls_audit_log_func));
127 # endif
128 DEF_DLL_FN (void, gnutls_global_set_log_level, (int));
129 DEF_DLL_FN (int, gnutls_handshake, (gnutls_session_t));
130 DEF_DLL_FN (int, gnutls_init, (gnutls_session_t *, unsigned int));
131 DEF_DLL_FN (int, gnutls_priority_set_direct,
132 (gnutls_session_t, const char *, const char **));
133 DEF_DLL_FN (size_t, gnutls_record_check_pending, (gnutls_session_t));
134 DEF_DLL_FN (ssize_t, gnutls_record_recv, (gnutls_session_t, void *, size_t));
135 DEF_DLL_FN (ssize_t, gnutls_record_send,
136 (gnutls_session_t, const void *, size_t));
137 DEF_DLL_FN (const char *, gnutls_strerror, (int));
138 DEF_DLL_FN (void, gnutls_transport_set_errno, (gnutls_session_t, int));
139 DEF_DLL_FN (void, gnutls_transport_set_ptr2,
140 (gnutls_session_t, gnutls_transport_ptr_t,
141 gnutls_transport_ptr_t));
142 DEF_DLL_FN (void, gnutls_transport_set_pull_function,
143 (gnutls_session_t, gnutls_pull_func));
144 DEF_DLL_FN (void, gnutls_transport_set_push_function,
145 (gnutls_session_t, gnutls_push_func));
146 DEF_DLL_FN (int, gnutls_x509_crt_check_hostname,
147 (gnutls_x509_crt_t, const char *));
148 DEF_DLL_FN (int, gnutls_x509_crt_check_issuer,
149 (gnutls_x509_crt_t, gnutls_x509_crt_t));
150 DEF_DLL_FN (void, gnutls_x509_crt_deinit, (gnutls_x509_crt_t));
151 DEF_DLL_FN (int, gnutls_x509_crt_import,
152 (gnutls_x509_crt_t, const gnutls_datum_t *,
153 gnutls_x509_crt_fmt_t));
154 DEF_DLL_FN (int, gnutls_x509_crt_init, (gnutls_x509_crt_t *));
155 DEF_DLL_FN (int, gnutls_x509_crt_get_fingerprint,
156 (gnutls_x509_crt_t,
157 gnutls_digest_algorithm_t, void *, size_t *));
158 DEF_DLL_FN (int, gnutls_x509_crt_get_version,
159 (gnutls_x509_crt_t));
160 DEF_DLL_FN (int, gnutls_x509_crt_get_serial,
161 (gnutls_x509_crt_t, void *, size_t *));
162 DEF_DLL_FN (int, gnutls_x509_crt_get_issuer_dn,
163 (gnutls_x509_crt_t, char *, size_t *));
164 DEF_DLL_FN (time_t, gnutls_x509_crt_get_activation_time,
165 (gnutls_x509_crt_t));
166 DEF_DLL_FN (time_t, gnutls_x509_crt_get_expiration_time,
167 (gnutls_x509_crt_t));
168 DEF_DLL_FN (int, gnutls_x509_crt_get_dn,
169 (gnutls_x509_crt_t, char *, size_t *));
170 DEF_DLL_FN (int, gnutls_x509_crt_get_pk_algorithm,
171 (gnutls_x509_crt_t, unsigned int *));
172 DEF_DLL_FN (const char *, gnutls_pk_algorithm_get_name,
173 (gnutls_pk_algorithm_t));
174 DEF_DLL_FN (int, gnutls_pk_bits_to_sec_param,
175 (gnutls_pk_algorithm_t, unsigned int));
176 DEF_DLL_FN (int, gnutls_x509_crt_get_issuer_unique_id,
177 (gnutls_x509_crt_t, char *, size_t *));
178 DEF_DLL_FN (int, gnutls_x509_crt_get_subject_unique_id,
179 (gnutls_x509_crt_t, char *, size_t *));
180 DEF_DLL_FN (int, gnutls_x509_crt_get_signature_algorithm,
181 (gnutls_x509_crt_t));
182 DEF_DLL_FN (int, gnutls_x509_crt_get_key_id,
183 (gnutls_x509_crt_t, unsigned int, unsigned char *, size_t *_size));
184 DEF_DLL_FN (const char *, gnutls_sec_param_get_name, (gnutls_sec_param_t));
185 DEF_DLL_FN (const char *, gnutls_sign_get_name, (gnutls_sign_algorithm_t));
186 DEF_DLL_FN (int, gnutls_server_name_set,
187 (gnutls_session_t, gnutls_server_name_type_t,
188 const void *, size_t));
189 DEF_DLL_FN (gnutls_kx_algorithm_t, gnutls_kx_get, (gnutls_session_t));
190 DEF_DLL_FN (const char *, gnutls_kx_get_name, (gnutls_kx_algorithm_t));
191 DEF_DLL_FN (gnutls_protocol_t, gnutls_protocol_get_version,
192 (gnutls_session_t));
193 DEF_DLL_FN (const char *, gnutls_protocol_get_name, (gnutls_protocol_t));
194 DEF_DLL_FN (gnutls_cipher_algorithm_t, gnutls_cipher_get,
195 (gnutls_session_t));
196 DEF_DLL_FN (const char *, gnutls_cipher_get_name,
197 (gnutls_cipher_algorithm_t));
198 DEF_DLL_FN (gnutls_mac_algorithm_t, gnutls_mac_get, (gnutls_session_t));
199 DEF_DLL_FN (const char *, gnutls_mac_get_name, (gnutls_mac_algorithm_t));
201 # ifdef HAVE_GNUTLS3
202 DEF_DLL_FN (int, gnutls_rnd, (gnutls_rnd_level_t, void *, size_t));
203 DEF_DLL_FN (const gnutls_mac_algorithm_t *, gnutls_mac_list, (void));
204 # ifdef HAVE_GNUTLS_MAC_GET_NONCE_SIZE
205 DEF_DLL_FN (size_t, gnutls_mac_get_nonce_size, (gnutls_mac_algorithm_t));
206 # endif
207 DEF_DLL_FN (size_t, gnutls_mac_get_key_size, (gnutls_mac_algorithm_t));
208 DEF_DLL_FN (const gnutls_digest_algorithm_t *, gnutls_digest_list, (void));
209 DEF_DLL_FN (const char *, gnutls_digest_get_name, (gnutls_digest_algorithm_t));
210 DEF_DLL_FN (gnutls_cipher_algorithm_t *, gnutls_cipher_list, (void));
211 DEF_DLL_FN (int, gnutls_cipher_get_iv_size, (gnutls_cipher_algorithm_t));
212 DEF_DLL_FN (size_t, gnutls_cipher_get_key_size, (gnutls_cipher_algorithm_t));
213 DEF_DLL_FN (int, gnutls_cipher_get_block_size, (gnutls_cipher_algorithm_t));
214 DEF_DLL_FN (int, gnutls_cipher_get_tag_size, (gnutls_cipher_algorithm_t));
215 DEF_DLL_FN (int, gnutls_cipher_init,
216 (gnutls_cipher_hd_t *, gnutls_cipher_algorithm_t,
217 const gnutls_datum_t *, const gnutls_datum_t *));
218 DEF_DLL_FN (void, gnutls_cipher_set_iv, (gnutls_cipher_hd_t, void *, size_t));
219 DEF_DLL_FN (int, gnutls_cipher_encrypt2,
220 (gnutls_cipher_hd_t, const void *, size_t, void *, size_t));
221 DEF_DLL_FN (void, gnutls_cipher_deinit, (gnutls_cipher_hd_t));
222 DEF_DLL_FN (int, gnutls_cipher_decrypt2,
223 (gnutls_cipher_hd_t, const void *, size_t, void *, size_t));
224 # ifdef HAVE_GNUTLS_AEAD
225 DEF_DLL_FN (int, gnutls_aead_cipher_init,
226 (gnutls_aead_cipher_hd_t *, gnutls_cipher_algorithm_t,
227 const gnutls_datum_t *));
228 DEF_DLL_FN (void, gnutls_aead_cipher_deinit, (gnutls_aead_cipher_hd_t));
229 DEF_DLL_FN (int, gnutls_aead_cipher_encrypt,
230 (gnutls_aead_cipher_hd_t, const void *, size_t, const void *,
231 size_t, size_t, const void *, size_t, void *, size_t *));
232 DEF_DLL_FN (int, gnutls_aead_cipher_decrypt,
233 (gnutls_aead_cipher_hd_t, const void *, size_t, const void *,
234 size_t, size_t, const void *, size_t, void *, size_t *));
235 # endif
236 DEF_DLL_FN (int, gnutls_hmac_init,
237 (gnutls_hmac_hd_t *, gnutls_mac_algorithm_t, const void *, size_t));
238 DEF_DLL_FN (int, gnutls_hmac_get_len, (gnutls_mac_algorithm_t));
239 DEF_DLL_FN (int, gnutls_hmac, (gnutls_hmac_hd_t, const void *, size_t));
240 DEF_DLL_FN (void, gnutls_hmac_deinit, (gnutls_hmac_hd_t, void *));
241 DEF_DLL_FN (void, gnutls_hmac_output, (gnutls_hmac_hd_t, void *));
242 DEF_DLL_FN (int, gnutls_hash_init,
243 (gnutls_hash_hd_t *, gnutls_digest_algorithm_t));
244 DEF_DLL_FN (int, gnutls_hash_get_len, (gnutls_digest_algorithm_t));
245 DEF_DLL_FN (int, gnutls_hash, (gnutls_hash_hd_t, const void *, size_t));
246 DEF_DLL_FN (void, gnutls_hash_deinit, (gnutls_hash_hd_t, void *));
247 DEF_DLL_FN (void, gnutls_hash_output, (gnutls_hash_hd_t, void *));
248 # ifdef HAVE_GNUTLS_EXT_GET_NAME
249 DEF_DLL_FN (const char *, gnutls_ext_get_name, (unsigned int));
250 # endif
251 # endif /* HAVE_GNUTLS3 */
254 static bool
255 init_gnutls_functions (void)
257 HMODULE library;
258 int max_log_level = 1;
260 if (!(library = w32_delayed_load (Qgnutls)))
262 GNUTLS_LOG (1, max_log_level, "GnuTLS library not found");
263 return 0;
266 LOAD_DLL_FN (library, gnutls_alert_get);
267 LOAD_DLL_FN (library, gnutls_alert_get_name);
268 LOAD_DLL_FN (library, gnutls_anon_allocate_client_credentials);
269 LOAD_DLL_FN (library, gnutls_anon_free_client_credentials);
270 LOAD_DLL_FN (library, gnutls_bye);
271 LOAD_DLL_FN (library, gnutls_certificate_allocate_credentials);
272 LOAD_DLL_FN (library, gnutls_certificate_free_credentials);
273 LOAD_DLL_FN (library, gnutls_certificate_get_peers);
274 LOAD_DLL_FN (library, gnutls_certificate_set_verify_flags);
275 LOAD_DLL_FN (library, gnutls_certificate_set_x509_crl_file);
276 LOAD_DLL_FN (library, gnutls_certificate_set_x509_key_file);
277 # ifdef HAVE_GNUTLS_X509_SYSTEM_TRUST
278 LOAD_DLL_FN (library, gnutls_certificate_set_x509_system_trust);
279 # endif
280 LOAD_DLL_FN (library, gnutls_certificate_set_x509_trust_file);
281 LOAD_DLL_FN (library, gnutls_certificate_type_get);
282 LOAD_DLL_FN (library, gnutls_certificate_verify_peers2);
283 LOAD_DLL_FN (library, gnutls_credentials_set);
284 LOAD_DLL_FN (library, gnutls_deinit);
285 LOAD_DLL_FN (library, gnutls_dh_set_prime_bits);
286 LOAD_DLL_FN (library, gnutls_dh_get_prime_bits);
287 LOAD_DLL_FN (library, gnutls_error_is_fatal);
288 LOAD_DLL_FN (library, gnutls_global_init);
289 LOAD_DLL_FN (library, gnutls_global_set_log_function);
290 # ifdef HAVE_GNUTLS3
291 LOAD_DLL_FN (library, gnutls_global_set_audit_log_function);
292 # endif
293 LOAD_DLL_FN (library, gnutls_global_set_log_level);
294 LOAD_DLL_FN (library, gnutls_handshake);
295 LOAD_DLL_FN (library, gnutls_init);
296 LOAD_DLL_FN (library, gnutls_priority_set_direct);
297 LOAD_DLL_FN (library, gnutls_record_check_pending);
298 LOAD_DLL_FN (library, gnutls_record_recv);
299 LOAD_DLL_FN (library, gnutls_record_send);
300 LOAD_DLL_FN (library, gnutls_strerror);
301 LOAD_DLL_FN (library, gnutls_transport_set_errno);
302 LOAD_DLL_FN (library, gnutls_transport_set_ptr2);
303 LOAD_DLL_FN (library, gnutls_transport_set_pull_function);
304 LOAD_DLL_FN (library, gnutls_transport_set_push_function);
305 LOAD_DLL_FN (library, gnutls_x509_crt_check_hostname);
306 LOAD_DLL_FN (library, gnutls_x509_crt_check_issuer);
307 LOAD_DLL_FN (library, gnutls_x509_crt_deinit);
308 LOAD_DLL_FN (library, gnutls_x509_crt_import);
309 LOAD_DLL_FN (library, gnutls_x509_crt_init);
310 LOAD_DLL_FN (library, gnutls_x509_crt_get_fingerprint);
311 LOAD_DLL_FN (library, gnutls_x509_crt_get_version);
312 LOAD_DLL_FN (library, gnutls_x509_crt_get_serial);
313 LOAD_DLL_FN (library, gnutls_x509_crt_get_issuer_dn);
314 LOAD_DLL_FN (library, gnutls_x509_crt_get_activation_time);
315 LOAD_DLL_FN (library, gnutls_x509_crt_get_expiration_time);
316 LOAD_DLL_FN (library, gnutls_x509_crt_get_dn);
317 LOAD_DLL_FN (library, gnutls_x509_crt_get_pk_algorithm);
318 LOAD_DLL_FN (library, gnutls_pk_algorithm_get_name);
319 LOAD_DLL_FN (library, gnutls_pk_bits_to_sec_param);
320 LOAD_DLL_FN (library, gnutls_x509_crt_get_issuer_unique_id);
321 LOAD_DLL_FN (library, gnutls_x509_crt_get_subject_unique_id);
322 LOAD_DLL_FN (library, gnutls_x509_crt_get_signature_algorithm);
323 LOAD_DLL_FN (library, gnutls_x509_crt_get_key_id);
324 LOAD_DLL_FN (library, gnutls_sec_param_get_name);
325 LOAD_DLL_FN (library, gnutls_sign_get_name);
326 LOAD_DLL_FN (library, gnutls_server_name_set);
327 LOAD_DLL_FN (library, gnutls_kx_get);
328 LOAD_DLL_FN (library, gnutls_kx_get_name);
329 LOAD_DLL_FN (library, gnutls_protocol_get_version);
330 LOAD_DLL_FN (library, gnutls_protocol_get_name);
331 LOAD_DLL_FN (library, gnutls_cipher_get);
332 LOAD_DLL_FN (library, gnutls_cipher_get_name);
333 LOAD_DLL_FN (library, gnutls_mac_get);
334 LOAD_DLL_FN (library, gnutls_mac_get_name);
335 # ifdef HAVE_GNUTLS3
336 LOAD_DLL_FN (library, gnutls_rnd);
337 LOAD_DLL_FN (library, gnutls_mac_list);
338 # ifdef HAVE_GNUTLS_MAC_GET_NONCE_SIZE
339 LOAD_DLL_FN (library, gnutls_mac_get_nonce_size);
340 # endif
341 LOAD_DLL_FN (library, gnutls_mac_get_key_size);
342 LOAD_DLL_FN (library, gnutls_digest_list);
343 LOAD_DLL_FN (library, gnutls_digest_get_name);
344 LOAD_DLL_FN (library, gnutls_cipher_list);
345 LOAD_DLL_FN (library, gnutls_cipher_get_iv_size);
346 LOAD_DLL_FN (library, gnutls_cipher_get_key_size);
347 LOAD_DLL_FN (library, gnutls_cipher_get_block_size);
348 LOAD_DLL_FN (library, gnutls_cipher_get_tag_size);
349 LOAD_DLL_FN (library, gnutls_cipher_init);
350 LOAD_DLL_FN (library, gnutls_cipher_set_iv);
351 LOAD_DLL_FN (library, gnutls_cipher_encrypt2);
352 LOAD_DLL_FN (library, gnutls_cipher_deinit);
353 LOAD_DLL_FN (library, gnutls_cipher_decrypt2);
354 # ifdef HAVE_GNUTLS_AEAD
355 LOAD_DLL_FN (library, gnutls_aead_cipher_init);
356 LOAD_DLL_FN (library, gnutls_aead_cipher_deinit);
357 LOAD_DLL_FN (library, gnutls_aead_cipher_encrypt);
358 LOAD_DLL_FN (library, gnutls_aead_cipher_decrypt);
359 # endif
360 LOAD_DLL_FN (library, gnutls_hmac_init);
361 LOAD_DLL_FN (library, gnutls_hmac_get_len);
362 LOAD_DLL_FN (library, gnutls_hmac);
363 LOAD_DLL_FN (library, gnutls_hmac_deinit);
364 LOAD_DLL_FN (library, gnutls_hmac_output);
365 LOAD_DLL_FN (library, gnutls_hash_init);
366 LOAD_DLL_FN (library, gnutls_hash_get_len);
367 LOAD_DLL_FN (library, gnutls_hash);
368 LOAD_DLL_FN (library, gnutls_hash_deinit);
369 LOAD_DLL_FN (library, gnutls_hash_output);
370 # ifdef HAVE_GNUTLS_EXT_GET_NAME
371 LOAD_DLL_FN (library, gnutls_ext_get_name);
372 # endif
373 # endif /* HAVE_GNUTLS3 */
375 max_log_level = global_gnutls_log_level;
378 Lisp_Object name = CAR_SAFE (Fget (Qgnutls, QCloaded_from));
379 GNUTLS_LOG2 (1, max_log_level, "GnuTLS library loaded:",
380 STRINGP (name) ? (const char *) SDATA (name) : "unknown");
383 return 1;
386 # define gnutls_alert_get fn_gnutls_alert_get
387 # define gnutls_alert_get_name fn_gnutls_alert_get_name
388 # define gnutls_anon_allocate_client_credentials fn_gnutls_anon_allocate_client_credentials
389 # define gnutls_anon_free_client_credentials fn_gnutls_anon_free_client_credentials
390 # define gnutls_bye fn_gnutls_bye
391 # define gnutls_certificate_allocate_credentials fn_gnutls_certificate_allocate_credentials
392 # define gnutls_certificate_free_credentials fn_gnutls_certificate_free_credentials
393 # define gnutls_certificate_get_peers fn_gnutls_certificate_get_peers
394 # define gnutls_certificate_set_verify_flags fn_gnutls_certificate_set_verify_flags
395 # define gnutls_certificate_set_x509_crl_file fn_gnutls_certificate_set_x509_crl_file
396 # define gnutls_certificate_set_x509_key_file fn_gnutls_certificate_set_x509_key_file
397 # define gnutls_certificate_set_x509_system_trust fn_gnutls_certificate_set_x509_system_trust
398 # define gnutls_certificate_set_x509_trust_file fn_gnutls_certificate_set_x509_trust_file
399 # define gnutls_certificate_type_get fn_gnutls_certificate_type_get
400 # define gnutls_certificate_verify_peers2 fn_gnutls_certificate_verify_peers2
401 # define gnutls_cipher_get fn_gnutls_cipher_get
402 # define gnutls_cipher_get_name fn_gnutls_cipher_get_name
403 # define gnutls_credentials_set fn_gnutls_credentials_set
404 # define gnutls_deinit fn_gnutls_deinit
405 # define gnutls_dh_get_prime_bits fn_gnutls_dh_get_prime_bits
406 # define gnutls_dh_set_prime_bits fn_gnutls_dh_set_prime_bits
407 # define gnutls_error_is_fatal fn_gnutls_error_is_fatal
408 # define gnutls_global_init fn_gnutls_global_init
409 # define gnutls_global_set_audit_log_function fn_gnutls_global_set_audit_log_function
410 # define gnutls_global_set_log_function fn_gnutls_global_set_log_function
411 # define gnutls_global_set_log_level fn_gnutls_global_set_log_level
412 # define gnutls_handshake fn_gnutls_handshake
413 # define gnutls_init fn_gnutls_init
414 # define gnutls_kx_get fn_gnutls_kx_get
415 # define gnutls_kx_get_name fn_gnutls_kx_get_name
416 # define gnutls_mac_get fn_gnutls_mac_get
417 # define gnutls_mac_get_name fn_gnutls_mac_get_name
418 # define gnutls_pk_algorithm_get_name fn_gnutls_pk_algorithm_get_name
419 # define gnutls_pk_bits_to_sec_param fn_gnutls_pk_bits_to_sec_param
420 # define gnutls_priority_set_direct fn_gnutls_priority_set_direct
421 # define gnutls_protocol_get_name fn_gnutls_protocol_get_name
422 # define gnutls_protocol_get_version fn_gnutls_protocol_get_version
423 # define gnutls_record_check_pending fn_gnutls_record_check_pending
424 # define gnutls_record_recv fn_gnutls_record_recv
425 # define gnutls_record_send fn_gnutls_record_send
426 # define gnutls_sec_param_get_name fn_gnutls_sec_param_get_name
427 # define gnutls_server_name_set fn_gnutls_server_name_set
428 # define gnutls_sign_get_name fn_gnutls_sign_get_name
429 # define gnutls_strerror fn_gnutls_strerror
430 # define gnutls_transport_set_errno fn_gnutls_transport_set_errno
431 # define gnutls_transport_set_ptr2 fn_gnutls_transport_set_ptr2
432 # define gnutls_transport_set_pull_function fn_gnutls_transport_set_pull_function
433 # define gnutls_transport_set_push_function fn_gnutls_transport_set_push_function
434 # define gnutls_x509_crt_check_hostname fn_gnutls_x509_crt_check_hostname
435 # define gnutls_x509_crt_check_issuer fn_gnutls_x509_crt_check_issuer
436 # define gnutls_x509_crt_deinit fn_gnutls_x509_crt_deinit
437 # define gnutls_x509_crt_get_activation_time fn_gnutls_x509_crt_get_activation_time
438 # define gnutls_x509_crt_get_dn fn_gnutls_x509_crt_get_dn
439 # define gnutls_x509_crt_get_expiration_time fn_gnutls_x509_crt_get_expiration_time
440 # define gnutls_x509_crt_get_fingerprint fn_gnutls_x509_crt_get_fingerprint
441 # define gnutls_x509_crt_get_issuer_dn fn_gnutls_x509_crt_get_issuer_dn
442 # define gnutls_x509_crt_get_issuer_unique_id fn_gnutls_x509_crt_get_issuer_unique_id
443 # define gnutls_x509_crt_get_key_id fn_gnutls_x509_crt_get_key_id
444 # define gnutls_x509_crt_get_pk_algorithm fn_gnutls_x509_crt_get_pk_algorithm
445 # define gnutls_x509_crt_get_serial fn_gnutls_x509_crt_get_serial
446 # define gnutls_x509_crt_get_signature_algorithm fn_gnutls_x509_crt_get_signature_algorithm
447 # define gnutls_x509_crt_get_subject_unique_id fn_gnutls_x509_crt_get_subject_unique_id
448 # define gnutls_x509_crt_get_version fn_gnutls_x509_crt_get_version
449 # define gnutls_x509_crt_import fn_gnutls_x509_crt_import
450 # define gnutls_x509_crt_init fn_gnutls_x509_crt_init
451 # ifdef HAVE_GNUTLS3
452 # define gnutls_rnd fn_gnutls_rnd
453 # define gnutls_mac_list fn_gnutls_mac_list
454 # ifdef HAVE_GNUTLS_MAC_GET_NONCE_SIZE
455 # define gnutls_mac_get_nonce_size fn_gnutls_mac_get_nonce_size
456 # endif
457 # define gnutls_mac_get_key_size fn_gnutls_mac_get_key_size
458 # define gnutls_digest_list fn_gnutls_digest_list
459 # define gnutls_digest_get_name fn_gnutls_digest_get_name
460 # define gnutls_cipher_list fn_gnutls_cipher_list
461 # define gnutls_cipher_get_iv_size fn_gnutls_cipher_get_iv_size
462 # define gnutls_cipher_get_key_size fn_gnutls_cipher_get_key_size
463 # define gnutls_cipher_get_block_size fn_gnutls_cipher_get_block_size
464 # define gnutls_cipher_get_tag_size fn_gnutls_cipher_get_tag_size
465 # define gnutls_cipher_init fn_gnutls_cipher_init
466 # define gnutls_cipher_set_iv fn_gnutls_cipher_set_iv
467 # define gnutls_cipher_encrypt2 fn_gnutls_cipher_encrypt2
468 # define gnutls_cipher_decrypt2 fn_gnutls_cipher_decrypt2
469 # define gnutls_cipher_deinit fn_gnutls_cipher_deinit
470 # ifdef HAVE_GNUTLS_AEAD
471 # define gnutls_aead_cipher_encrypt fn_gnutls_aead_cipher_encrypt
472 # define gnutls_aead_cipher_decrypt fn_gnutls_aead_cipher_decrypt
473 # define gnutls_aead_cipher_init fn_gnutls_aead_cipher_init
474 # define gnutls_aead_cipher_deinit fn_gnutls_aead_cipher_deinit
475 # endif
476 # define gnutls_hmac_init fn_gnutls_hmac_init
477 # define gnutls_hmac_get_len fn_gnutls_hmac_get_len
478 # define gnutls_hmac fn_gnutls_hmac
479 # define gnutls_hmac_deinit fn_gnutls_hmac_deinit
480 # define gnutls_hmac_output fn_gnutls_hmac_output
481 # define gnutls_hash_init fn_gnutls_hash_init
482 # define gnutls_hash_get_len fn_gnutls_hash_get_len
483 # define gnutls_hash fn_gnutls_hash
484 # define gnutls_hash_deinit fn_gnutls_hash_deinit
485 # define gnutls_hash_output fn_gnutls_hash_output
486 # ifdef HAVE_GNUTLS_EXT_GET_NAME
487 # define gnutls_ext_get_name fn_gnutls_ext_get_name
488 # endif
489 # endif /* HAVE_GNUTLS3 */
492 /* This wrapper is called from fns.c, which doesn't know about the
493 LOAD_DLL_FN stuff above. */
495 w32_gnutls_rnd (gnutls_rnd_level_t level, void *data, size_t len)
497 return gnutls_rnd (level, data, len);
500 # endif /* WINDOWSNT */
503 /* Report memory exhaustion if ERR is an out-of-memory indication. */
504 static void
505 check_memory_full (int err)
507 /* When GnuTLS exhausts memory, it doesn't say how much memory it
508 asked for, so tell the Emacs allocator that GnuTLS asked for no
509 bytes. This isn't accurate, but it's good enough. */
510 if (err == GNUTLS_E_MEMORY_ERROR)
511 memory_full (0);
514 # ifdef HAVE_GNUTLS3
515 /* Log a simple audit message. */
516 static void
517 gnutls_audit_log_function (gnutls_session_t session, const char *string)
519 if (global_gnutls_log_level >= 1)
521 message ("gnutls.c: [audit] %s", string);
524 # endif
526 /* Log a simple message. */
527 static void
528 gnutls_log_function (int level, const char *string)
530 message ("gnutls.c: [%d] %s", level, string);
533 /* Log a message and a string. */
534 static void
535 gnutls_log_function2 (int level, const char *string, const char *extra)
537 message ("gnutls.c: [%d] %s %s", level, string, extra);
541 gnutls_try_handshake (struct Lisp_Process *proc)
543 gnutls_session_t state = proc->gnutls_state;
544 int ret;
545 bool non_blocking = proc->is_non_blocking_client;
547 if (proc->gnutls_complete_negotiation_p)
548 non_blocking = false;
550 if (non_blocking)
551 proc->gnutls_p = true;
555 ret = gnutls_handshake (state);
556 emacs_gnutls_handle_error (state, ret);
557 maybe_quit ();
559 while (ret < 0
560 && gnutls_error_is_fatal (ret) == 0
561 && ! non_blocking);
563 proc->gnutls_initstage = GNUTLS_STAGE_HANDSHAKE_TRIED;
565 if (ret == GNUTLS_E_SUCCESS)
567 /* Here we're finally done. */
568 proc->gnutls_initstage = GNUTLS_STAGE_READY;
570 else
572 /* check_memory_full (gnutls_alert_send_appropriate (state, ret)); */
574 return ret;
577 # ifndef WINDOWSNT
578 static int
579 emacs_gnutls_nonblock_errno (gnutls_transport_ptr_t ptr)
581 int err = errno;
583 switch (err)
585 # ifdef _AIX
586 /* This is taken from the GnuTLS system_errno function circa 2016;
587 see <https://savannah.gnu.org/support/?107464>. */
588 case 0:
589 errno = EAGAIN;
590 /* Fall through. */
591 # endif
592 case EINPROGRESS:
593 case ENOTCONN:
594 return EAGAIN;
596 default:
597 return err;
600 # endif /* !WINDOWSNT */
602 static int
603 emacs_gnutls_handshake (struct Lisp_Process *proc)
605 gnutls_session_t state = proc->gnutls_state;
607 if (proc->gnutls_initstage < GNUTLS_STAGE_HANDSHAKE_CANDO)
608 return -1;
610 if (proc->gnutls_initstage < GNUTLS_STAGE_TRANSPORT_POINTERS_SET)
612 # ifdef WINDOWSNT
613 /* On W32 we cannot transfer socket handles between different runtime
614 libraries, so we tell GnuTLS to use our special push/pull
615 functions. */
616 gnutls_transport_set_ptr2 (state,
617 (gnutls_transport_ptr_t) proc,
618 (gnutls_transport_ptr_t) proc);
619 gnutls_transport_set_push_function (state, &emacs_gnutls_push);
620 gnutls_transport_set_pull_function (state, &emacs_gnutls_pull);
621 # else
622 /* This is how GnuTLS takes sockets: as file descriptors passed
623 in. For an Emacs process socket, infd and outfd are the
624 same but we use this two-argument version for clarity. */
625 gnutls_transport_set_ptr2 (state,
626 (void *) (intptr_t) proc->infd,
627 (void *) (intptr_t) proc->outfd);
628 if (proc->is_non_blocking_client)
629 gnutls_transport_set_errno_function (state,
630 emacs_gnutls_nonblock_errno);
631 # endif
633 proc->gnutls_initstage = GNUTLS_STAGE_TRANSPORT_POINTERS_SET;
636 return gnutls_try_handshake (proc);
639 ptrdiff_t
640 emacs_gnutls_record_check_pending (gnutls_session_t state)
642 return gnutls_record_check_pending (state);
645 # ifdef WINDOWSNT
646 void
647 emacs_gnutls_transport_set_errno (gnutls_session_t state, int err)
649 gnutls_transport_set_errno (state, err);
651 # endif
653 ptrdiff_t
654 emacs_gnutls_write (struct Lisp_Process *proc, const char *buf, ptrdiff_t nbyte)
656 ssize_t rtnval = 0;
657 ptrdiff_t bytes_written;
658 gnutls_session_t state = proc->gnutls_state;
660 if (proc->gnutls_initstage != GNUTLS_STAGE_READY)
662 errno = EAGAIN;
663 return 0;
666 bytes_written = 0;
668 while (nbyte > 0)
670 rtnval = gnutls_record_send (state, buf, nbyte);
672 if (rtnval < 0)
674 if (rtnval == GNUTLS_E_INTERRUPTED)
675 continue;
676 else
678 /* If we get GNUTLS_E_AGAIN, then set errno
679 appropriately so that send_process retries the
680 correct way instead of erroring out. */
681 if (rtnval == GNUTLS_E_AGAIN)
682 errno = EAGAIN;
683 break;
687 buf += rtnval;
688 nbyte -= rtnval;
689 bytes_written += rtnval;
692 emacs_gnutls_handle_error (state, rtnval);
693 return (bytes_written);
696 ptrdiff_t
697 emacs_gnutls_read (struct Lisp_Process *proc, char *buf, ptrdiff_t nbyte)
699 ssize_t rtnval;
700 gnutls_session_t state = proc->gnutls_state;
702 if (proc->gnutls_initstage != GNUTLS_STAGE_READY)
704 errno = EAGAIN;
705 return -1;
708 rtnval = gnutls_record_recv (state, buf, nbyte);
709 if (rtnval >= 0)
710 return rtnval;
711 else if (rtnval == GNUTLS_E_UNEXPECTED_PACKET_LENGTH)
712 /* The peer closed the connection. */
713 return 0;
714 else if (emacs_gnutls_handle_error (state, rtnval))
715 /* non-fatal error */
716 return -1;
717 else {
718 /* a fatal error occurred */
719 return 0;
723 static char const *
724 emacs_gnutls_strerror (int err)
726 char const *str = gnutls_strerror (err);
727 return str ? str : "unknown";
730 /* Report a GnuTLS error to the user.
731 Return true if the error code was successfully handled. */
732 static bool
733 emacs_gnutls_handle_error (gnutls_session_t session, int err)
735 int max_log_level = 0;
737 bool ret;
739 /* TODO: use a Lisp_Object generated by gnutls_make_error? */
740 if (err >= 0)
741 return 1;
743 check_memory_full (err);
745 max_log_level = global_gnutls_log_level;
747 /* TODO: use gnutls-error-fatalp and gnutls-error-string. */
749 char const *str = emacs_gnutls_strerror (err);
751 if (gnutls_error_is_fatal (err))
753 int level = 1;
754 /* Mostly ignore "The TLS connection was non-properly
755 terminated" message which just means that the peer closed the
756 connection. */
757 # ifdef HAVE_GNUTLS3
758 if (err == GNUTLS_E_PREMATURE_TERMINATION)
759 level = 3;
760 # endif
762 GNUTLS_LOG2 (level, max_log_level, "fatal error:", str);
763 ret = false;
765 else
767 ret = true;
769 switch (err)
771 case GNUTLS_E_AGAIN:
772 GNUTLS_LOG2 (3,
773 max_log_level,
774 "retry:",
775 str);
776 FALLTHROUGH;
777 default:
778 GNUTLS_LOG2 (1,
779 max_log_level,
780 "non-fatal error:",
781 str);
785 if (err == GNUTLS_E_WARNING_ALERT_RECEIVED
786 || err == GNUTLS_E_FATAL_ALERT_RECEIVED)
788 int alert = gnutls_alert_get (session);
789 int level = (err == GNUTLS_E_FATAL_ALERT_RECEIVED) ? 0 : 1;
790 str = gnutls_alert_get_name (alert);
791 if (!str)
792 str = "unknown";
794 GNUTLS_LOG2 (level, max_log_level, "Received alert: ", str);
796 return ret;
799 /* convert an integer error to a Lisp_Object; it will be either a
800 known symbol like `gnutls_e_interrupted' and `gnutls_e_again' or
801 simply the integer value of the error. GNUTLS_E_SUCCESS is mapped
802 to Qt. */
803 static Lisp_Object
804 gnutls_make_error (int err)
806 switch (err)
808 case GNUTLS_E_SUCCESS:
809 return Qt;
810 case GNUTLS_E_AGAIN:
811 return Qgnutls_e_again;
812 case GNUTLS_E_INTERRUPTED:
813 return Qgnutls_e_interrupted;
814 case GNUTLS_E_INVALID_SESSION:
815 return Qgnutls_e_invalid_session;
818 check_memory_full (err);
819 return make_number (err);
822 Lisp_Object
823 emacs_gnutls_deinit (Lisp_Object proc)
825 int log_level;
827 CHECK_PROCESS (proc);
829 if (! XPROCESS (proc)->gnutls_p)
830 return Qnil;
832 log_level = XPROCESS (proc)->gnutls_log_level;
834 if (XPROCESS (proc)->gnutls_x509_cred)
836 GNUTLS_LOG (2, log_level, "Deallocating x509 credentials");
837 gnutls_certificate_free_credentials (XPROCESS (proc)->gnutls_x509_cred);
838 XPROCESS (proc)->gnutls_x509_cred = NULL;
841 if (XPROCESS (proc)->gnutls_anon_cred)
843 GNUTLS_LOG (2, log_level, "Deallocating anon credentials");
844 gnutls_anon_free_client_credentials (XPROCESS (proc)->gnutls_anon_cred);
845 XPROCESS (proc)->gnutls_anon_cred = NULL;
848 if (XPROCESS (proc)->gnutls_state)
850 gnutls_deinit (XPROCESS (proc)->gnutls_state);
851 XPROCESS (proc)->gnutls_state = NULL;
852 if (GNUTLS_INITSTAGE (proc) >= GNUTLS_STAGE_INIT)
853 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_INIT - 1;
856 XPROCESS (proc)->gnutls_p = false;
857 return Qt;
860 DEFUN ("gnutls-asynchronous-parameters", Fgnutls_asynchronous_parameters,
861 Sgnutls_asynchronous_parameters, 2, 2, 0,
862 doc: /* Mark this process as being a pre-init GnuTLS process.
863 The second parameter is the list of parameters to feed to gnutls-boot
864 to finish setting up the connection. */)
865 (Lisp_Object proc, Lisp_Object params)
867 CHECK_PROCESS (proc);
869 XPROCESS (proc)->gnutls_boot_parameters = params;
870 return Qnil;
873 DEFUN ("gnutls-get-initstage", Fgnutls_get_initstage, Sgnutls_get_initstage, 1, 1, 0,
874 doc: /* Return the GnuTLS init stage of process PROC.
875 See also `gnutls-boot'. */)
876 (Lisp_Object proc)
878 CHECK_PROCESS (proc);
880 return make_number (GNUTLS_INITSTAGE (proc));
883 DEFUN ("gnutls-errorp", Fgnutls_errorp, Sgnutls_errorp, 1, 1, 0,
884 doc: /* Return t if ERROR indicates a GnuTLS problem.
885 ERROR is an integer or a symbol with an integer `gnutls-code' property.
886 usage: (gnutls-errorp ERROR) */
887 attributes: const)
888 (Lisp_Object err)
890 if (EQ (err, Qt)
891 || EQ (err, Qgnutls_e_again))
892 return Qnil;
894 return Qt;
897 DEFUN ("gnutls-error-fatalp", Fgnutls_error_fatalp, Sgnutls_error_fatalp, 1, 1, 0,
898 doc: /* Return non-nil if ERROR is fatal.
899 ERROR is an integer or a symbol with an integer `gnutls-code' property.
900 Usage: (gnutls-error-fatalp ERROR) */)
901 (Lisp_Object err)
903 Lisp_Object code;
905 if (EQ (err, Qt)) return Qnil;
907 if (SYMBOLP (err))
909 code = Fget (err, Qgnutls_code);
910 if (NUMBERP (code))
912 err = code;
914 else
916 error ("Symbol has no numeric gnutls-code property");
920 if (! TYPE_RANGED_INTEGERP (int, err))
921 error ("Not an error symbol or code");
923 if (0 == gnutls_error_is_fatal (XINT (err)))
924 return Qnil;
926 return Qt;
929 DEFUN ("gnutls-error-string", Fgnutls_error_string, Sgnutls_error_string, 1, 1, 0,
930 doc: /* Return a description of ERROR.
931 ERROR is an integer or a symbol with an integer `gnutls-code' property.
932 usage: (gnutls-error-string ERROR) */)
933 (Lisp_Object err)
935 Lisp_Object code;
937 if (EQ (err, Qt)) return build_string ("Not an error");
939 if (SYMBOLP (err))
941 code = Fget (err, Qgnutls_code);
942 if (NUMBERP (code))
944 err = code;
946 else
948 return build_string ("Symbol has no numeric gnutls-code property");
952 if (! TYPE_RANGED_INTEGERP (int, err))
953 return build_string ("Not an error symbol or code");
955 return build_string (emacs_gnutls_strerror (XINT (err)));
958 DEFUN ("gnutls-deinit", Fgnutls_deinit, Sgnutls_deinit, 1, 1, 0,
959 doc: /* Deallocate GnuTLS resources associated with process PROC.
960 See also `gnutls-init'. */)
961 (Lisp_Object proc)
963 return emacs_gnutls_deinit (proc);
966 static Lisp_Object
967 gnutls_hex_string (unsigned char *buf, ptrdiff_t buf_size, const char *prefix)
969 ptrdiff_t prefix_length = strlen (prefix);
970 ptrdiff_t retlen;
971 if (INT_MULTIPLY_WRAPV (buf_size, 3, &retlen)
972 || INT_ADD_WRAPV (prefix_length - (buf_size != 0), retlen, &retlen))
973 string_overflow ();
974 Lisp_Object ret = make_uninit_string (retlen);
975 char *string = SSDATA (ret);
976 strcpy (string, prefix);
978 for (ptrdiff_t i = 0; i < buf_size; i++)
979 sprintf (string + i * 3 + prefix_length,
980 i == buf_size - 1 ? "%02x" : "%02x:",
981 buf[i]);
983 return ret;
986 static Lisp_Object
987 gnutls_certificate_details (gnutls_x509_crt_t cert)
989 Lisp_Object res = Qnil;
990 int err;
991 size_t buf_size;
993 /* Version. */
995 int version = gnutls_x509_crt_get_version (cert);
996 check_memory_full (version);
997 if (version >= GNUTLS_E_SUCCESS)
998 res = nconc2 (res, list2 (intern (":version"),
999 make_number (version)));
1002 /* Serial. */
1003 buf_size = 0;
1004 err = gnutls_x509_crt_get_serial (cert, NULL, &buf_size);
1005 check_memory_full (err);
1006 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER)
1008 void *serial = xmalloc (buf_size);
1009 err = gnutls_x509_crt_get_serial (cert, serial, &buf_size);
1010 check_memory_full (err);
1011 if (err >= GNUTLS_E_SUCCESS)
1012 res = nconc2 (res, list2 (intern (":serial-number"),
1013 gnutls_hex_string (serial, buf_size, "")));
1014 xfree (serial);
1017 /* Issuer. */
1018 buf_size = 0;
1019 err = gnutls_x509_crt_get_issuer_dn (cert, NULL, &buf_size);
1020 check_memory_full (err);
1021 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER)
1023 char *dn = xmalloc (buf_size);
1024 err = gnutls_x509_crt_get_issuer_dn (cert, dn, &buf_size);
1025 check_memory_full (err);
1026 if (err >= GNUTLS_E_SUCCESS)
1027 res = nconc2 (res, list2 (intern (":issuer"),
1028 make_string (dn, buf_size)));
1029 xfree (dn);
1032 /* Validity. */
1034 /* Add 1 to the buffer size, since 1900 is added to tm_year and
1035 that might add 1 to the year length. */
1036 char buf[INT_STRLEN_BOUND (int) + 1 + sizeof "-12-31"];
1037 struct tm t;
1038 time_t tim = gnutls_x509_crt_get_activation_time (cert);
1040 if (gmtime_r (&tim, &t) && strftime (buf, sizeof buf, "%Y-%m-%d", &t))
1041 res = nconc2 (res, list2 (intern (":valid-from"), build_string (buf)));
1043 tim = gnutls_x509_crt_get_expiration_time (cert);
1044 if (gmtime_r (&tim, &t) && strftime (buf, sizeof buf, "%Y-%m-%d", &t))
1045 res = nconc2 (res, list2 (intern (":valid-to"), build_string (buf)));
1048 /* Subject. */
1049 buf_size = 0;
1050 err = gnutls_x509_crt_get_dn (cert, NULL, &buf_size);
1051 check_memory_full (err);
1052 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER)
1054 char *dn = xmalloc (buf_size);
1055 err = gnutls_x509_crt_get_dn (cert, dn, &buf_size);
1056 check_memory_full (err);
1057 if (err >= GNUTLS_E_SUCCESS)
1058 res = nconc2 (res, list2 (intern (":subject"),
1059 make_string (dn, buf_size)));
1060 xfree (dn);
1063 /* SubjectPublicKeyInfo. */
1065 unsigned int bits;
1067 err = gnutls_x509_crt_get_pk_algorithm (cert, &bits);
1068 check_memory_full (err);
1069 if (err >= GNUTLS_E_SUCCESS)
1071 const char *name = gnutls_pk_algorithm_get_name (err);
1072 if (name)
1073 res = nconc2 (res, list2 (intern (":public-key-algorithm"),
1074 build_string (name)));
1076 name = gnutls_sec_param_get_name (gnutls_pk_bits_to_sec_param
1077 (err, bits));
1078 res = nconc2 (res, list2 (intern (":certificate-security-level"),
1079 build_string (name)));
1083 /* Unique IDs. */
1084 buf_size = 0;
1085 err = gnutls_x509_crt_get_issuer_unique_id (cert, NULL, &buf_size);
1086 check_memory_full (err);
1087 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER)
1089 char *buf = xmalloc (buf_size);
1090 err = gnutls_x509_crt_get_issuer_unique_id (cert, buf, &buf_size);
1091 check_memory_full (err);
1092 if (err >= GNUTLS_E_SUCCESS)
1093 res = nconc2 (res, list2 (intern (":issuer-unique-id"),
1094 make_string (buf, buf_size)));
1095 xfree (buf);
1098 buf_size = 0;
1099 err = gnutls_x509_crt_get_subject_unique_id (cert, NULL, &buf_size);
1100 check_memory_full (err);
1101 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER)
1103 char *buf = xmalloc (buf_size);
1104 err = gnutls_x509_crt_get_subject_unique_id (cert, buf, &buf_size);
1105 check_memory_full (err);
1106 if (err >= GNUTLS_E_SUCCESS)
1107 res = nconc2 (res, list2 (intern (":subject-unique-id"),
1108 make_string (buf, buf_size)));
1109 xfree (buf);
1112 /* Signature. */
1113 err = gnutls_x509_crt_get_signature_algorithm (cert);
1114 check_memory_full (err);
1115 if (err >= GNUTLS_E_SUCCESS)
1117 const char *name = gnutls_sign_get_name (err);
1118 if (name)
1119 res = nconc2 (res, list2 (intern (":signature-algorithm"),
1120 build_string (name)));
1123 /* Public key ID. */
1124 buf_size = 0;
1125 err = gnutls_x509_crt_get_key_id (cert, 0, NULL, &buf_size);
1126 check_memory_full (err);
1127 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER)
1129 void *buf = xmalloc (buf_size);
1130 err = gnutls_x509_crt_get_key_id (cert, 0, buf, &buf_size);
1131 check_memory_full (err);
1132 if (err >= GNUTLS_E_SUCCESS)
1133 res = nconc2 (res, list2 (intern (":public-key-id"),
1134 gnutls_hex_string (buf, buf_size, "sha1:")));
1135 xfree (buf);
1138 /* Certificate fingerprint. */
1139 buf_size = 0;
1140 err = gnutls_x509_crt_get_fingerprint (cert, GNUTLS_DIG_SHA1,
1141 NULL, &buf_size);
1142 check_memory_full (err);
1143 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER)
1145 void *buf = xmalloc (buf_size);
1146 err = gnutls_x509_crt_get_fingerprint (cert, GNUTLS_DIG_SHA1,
1147 buf, &buf_size);
1148 check_memory_full (err);
1149 if (err >= GNUTLS_E_SUCCESS)
1150 res = nconc2 (res, list2 (intern (":certificate-id"),
1151 gnutls_hex_string (buf, buf_size, "sha1:")));
1152 xfree (buf);
1155 return res;
1158 DEFUN ("gnutls-peer-status-warning-describe", Fgnutls_peer_status_warning_describe, Sgnutls_peer_status_warning_describe, 1, 1, 0,
1159 doc: /* Describe the warning of a GnuTLS peer status from `gnutls-peer-status'. */)
1160 (Lisp_Object status_symbol)
1162 CHECK_SYMBOL (status_symbol);
1164 if (EQ (status_symbol, intern (":invalid")))
1165 return build_string ("certificate could not be verified");
1167 if (EQ (status_symbol, intern (":revoked")))
1168 return build_string ("certificate was revoked (CRL)");
1170 if (EQ (status_symbol, intern (":self-signed")))
1171 return build_string ("certificate signer was not found (self-signed)");
1173 if (EQ (status_symbol, intern (":unknown-ca")))
1174 return build_string ("the certificate was signed by an unknown "
1175 "and therefore untrusted authority");
1177 if (EQ (status_symbol, intern (":not-ca")))
1178 return build_string ("certificate signer is not a CA");
1180 if (EQ (status_symbol, intern (":insecure")))
1181 return build_string ("certificate was signed with an insecure algorithm");
1183 if (EQ (status_symbol, intern (":not-activated")))
1184 return build_string ("certificate is not yet activated");
1186 if (EQ (status_symbol, intern (":expired")))
1187 return build_string ("certificate has expired");
1189 if (EQ (status_symbol, intern (":no-host-match")))
1190 return build_string ("certificate host does not match hostname");
1192 return Qnil;
1195 DEFUN ("gnutls-peer-status", Fgnutls_peer_status, Sgnutls_peer_status, 1, 1, 0,
1196 doc: /* Describe a GnuTLS PROC peer certificate and any warnings about it.
1197 The return value is a property list with top-level keys :warnings and
1198 :certificate. The :warnings entry is a list of symbols you can describe with
1199 `gnutls-peer-status-warning-describe'. */)
1200 (Lisp_Object proc)
1202 Lisp_Object warnings = Qnil, result = Qnil;
1203 unsigned int verification;
1204 gnutls_session_t state;
1206 CHECK_PROCESS (proc);
1208 if (GNUTLS_INITSTAGE (proc) != GNUTLS_STAGE_READY)
1209 return Qnil;
1211 /* Then collect any warnings already computed by the handshake. */
1212 verification = XPROCESS (proc)->gnutls_peer_verification;
1214 if (verification & GNUTLS_CERT_INVALID)
1215 warnings = Fcons (intern (":invalid"), warnings);
1217 if (verification & GNUTLS_CERT_REVOKED)
1218 warnings = Fcons (intern (":revoked"), warnings);
1220 if (verification & GNUTLS_CERT_SIGNER_NOT_FOUND)
1221 warnings = Fcons (intern (":unknown-ca"), warnings);
1223 if (verification & GNUTLS_CERT_SIGNER_NOT_CA)
1224 warnings = Fcons (intern (":not-ca"), warnings);
1226 if (verification & GNUTLS_CERT_INSECURE_ALGORITHM)
1227 warnings = Fcons (intern (":insecure"), warnings);
1229 if (verification & GNUTLS_CERT_NOT_ACTIVATED)
1230 warnings = Fcons (intern (":not-activated"), warnings);
1232 if (verification & GNUTLS_CERT_EXPIRED)
1233 warnings = Fcons (intern (":expired"), warnings);
1235 if (XPROCESS (proc)->gnutls_extra_peer_verification &
1236 CERTIFICATE_NOT_MATCHING)
1237 warnings = Fcons (intern (":no-host-match"), warnings);
1239 /* This could get called in the INIT stage, when the certificate is
1240 not yet set. */
1241 if (XPROCESS (proc)->gnutls_certificate != NULL &&
1242 gnutls_x509_crt_check_issuer(XPROCESS (proc)->gnutls_certificate,
1243 XPROCESS (proc)->gnutls_certificate))
1244 warnings = Fcons (intern (":self-signed"), warnings);
1246 if (!NILP (warnings))
1247 result = list2 (intern (":warnings"), warnings);
1249 /* This could get called in the INIT stage, when the certificate is
1250 not yet set. */
1251 if (XPROCESS (proc)->gnutls_certificate != NULL)
1252 result = nconc2 (result, list2
1253 (intern (":certificate"),
1254 gnutls_certificate_details (XPROCESS (proc)->gnutls_certificate)));
1256 state = XPROCESS (proc)->gnutls_state;
1258 /* Diffie-Hellman prime bits. */
1260 int bits = gnutls_dh_get_prime_bits (state);
1261 check_memory_full (bits);
1262 if (bits > 0)
1263 result = nconc2 (result, list2 (intern (":diffie-hellman-prime-bits"),
1264 make_number (bits)));
1267 /* Key exchange. */
1268 result = nconc2
1269 (result, list2 (intern (":key-exchange"),
1270 build_string (gnutls_kx_get_name
1271 (gnutls_kx_get (state)))));
1273 /* Protocol name. */
1274 result = nconc2
1275 (result, list2 (intern (":protocol"),
1276 build_string (gnutls_protocol_get_name
1277 (gnutls_protocol_get_version (state)))));
1279 /* Cipher name. */
1280 result = nconc2
1281 (result, list2 (intern (":cipher"),
1282 build_string (gnutls_cipher_get_name
1283 (gnutls_cipher_get (state)))));
1285 /* MAC name. */
1286 result = nconc2
1287 (result, list2 (intern (":mac"),
1288 build_string (gnutls_mac_get_name
1289 (gnutls_mac_get (state)))));
1292 return result;
1295 /* Initialize global GnuTLS state to defaults.
1296 Call `gnutls-global-deinit' when GnuTLS usage is no longer needed.
1297 Return zero on success. */
1298 Lisp_Object
1299 emacs_gnutls_global_init (void)
1301 int ret = GNUTLS_E_SUCCESS;
1303 if (!gnutls_global_initialized)
1305 ret = gnutls_global_init ();
1306 if (ret == GNUTLS_E_SUCCESS)
1307 gnutls_global_initialized = 1;
1310 return gnutls_make_error (ret);
1313 static bool
1314 gnutls_ip_address_p (char *string)
1316 char c;
1318 while ((c = *string++) != 0)
1319 if (! ((c == '.' || c == ':' || (c >= '0' && c <= '9'))))
1320 return false;
1322 return true;
1325 # if 0
1326 /* Deinitialize global GnuTLS state.
1327 See also `gnutls-global-init'. */
1328 static Lisp_Object
1329 emacs_gnutls_global_deinit (void)
1331 if (gnutls_global_initialized)
1332 gnutls_global_deinit ();
1334 gnutls_global_initialized = 0;
1336 return gnutls_make_error (GNUTLS_E_SUCCESS);
1338 # endif
1340 static void ATTRIBUTE_FORMAT_PRINTF (2, 3)
1341 boot_error (struct Lisp_Process *p, const char *m, ...)
1343 va_list ap;
1344 va_start (ap, m);
1345 if (p->is_non_blocking_client)
1346 pset_status (p, list2 (Qfailed, vformat_string (m, ap)));
1347 else
1348 verror (m, ap);
1349 va_end (ap);
1352 Lisp_Object
1353 gnutls_verify_boot (Lisp_Object proc, Lisp_Object proplist)
1355 int ret;
1356 struct Lisp_Process *p = XPROCESS (proc);
1357 gnutls_session_t state = p->gnutls_state;
1358 unsigned int peer_verification;
1359 Lisp_Object warnings;
1360 int max_log_level = p->gnutls_log_level;
1361 Lisp_Object hostname, verify_error;
1362 bool verify_error_all = false;
1363 char *c_hostname;
1365 if (NILP (proplist))
1366 proplist = Fcdr (Fplist_get (p->childp, QCtls_parameters));
1368 verify_error = Fplist_get (proplist, QCverify_error);
1369 hostname = Fplist_get (proplist, QChostname);
1371 if (EQ (verify_error, Qt))
1372 verify_error_all = true;
1373 else if (NILP (Flistp (verify_error)))
1375 boot_error (p,
1376 "gnutls-boot: invalid :verify_error parameter (not a list)");
1377 return Qnil;
1380 if (!STRINGP (hostname))
1382 boot_error (p, "gnutls-boot: invalid :hostname parameter (not a string)");
1383 return Qnil;
1385 c_hostname = SSDATA (hostname);
1387 /* Now verify the peer, following
1388 https://www.gnu.org/software/gnutls/manual/html_node/Verifying-peer_0027s-certificate.html.
1389 The peer should present at least one certificate in the chain; do a
1390 check of the certificate's hostname with
1391 gnutls_x509_crt_check_hostname against :hostname. */
1393 ret = gnutls_certificate_verify_peers2 (state, &peer_verification);
1394 if (ret < GNUTLS_E_SUCCESS)
1395 return gnutls_make_error (ret);
1397 XPROCESS (proc)->gnutls_peer_verification = peer_verification;
1399 warnings = Fplist_get (Fgnutls_peer_status (proc), intern (":warnings"));
1400 if (!NILP (warnings))
1402 for (Lisp_Object tail = warnings; CONSP (tail); tail = XCDR (tail))
1404 Lisp_Object warning = XCAR (tail);
1405 Lisp_Object message = Fgnutls_peer_status_warning_describe (warning);
1406 if (!NILP (message))
1407 GNUTLS_LOG2 (1, max_log_level, "verification:", SSDATA (message));
1411 if (peer_verification != 0)
1413 if (verify_error_all
1414 || !NILP (Fmember (QCtrustfiles, verify_error)))
1416 emacs_gnutls_deinit (proc);
1417 boot_error (p,
1418 "Certificate validation failed %s, verification code %x",
1419 c_hostname, peer_verification);
1420 return Qnil;
1422 else
1424 GNUTLS_LOG2 (1, max_log_level, "certificate validation failed:",
1425 c_hostname);
1429 /* Up to here the process is the same for X.509 certificates and
1430 OpenPGP keys. From now on X.509 certificates are assumed. This
1431 can be easily extended to work with openpgp keys as well. */
1432 if (gnutls_certificate_type_get (state) == GNUTLS_CRT_X509)
1434 gnutls_x509_crt_t gnutls_verify_cert;
1435 const gnutls_datum_t *gnutls_verify_cert_list;
1436 unsigned int gnutls_verify_cert_list_size;
1438 ret = gnutls_x509_crt_init (&gnutls_verify_cert);
1439 if (ret < GNUTLS_E_SUCCESS)
1440 return gnutls_make_error (ret);
1442 gnutls_verify_cert_list
1443 = gnutls_certificate_get_peers (state, &gnutls_verify_cert_list_size);
1445 if (gnutls_verify_cert_list == NULL)
1447 gnutls_x509_crt_deinit (gnutls_verify_cert);
1448 emacs_gnutls_deinit (proc);
1449 boot_error (p, "No x509 certificate was found\n");
1450 return Qnil;
1453 /* Check only the first certificate in the given chain. */
1454 ret = gnutls_x509_crt_import (gnutls_verify_cert,
1455 &gnutls_verify_cert_list[0],
1456 GNUTLS_X509_FMT_DER);
1458 if (ret < GNUTLS_E_SUCCESS)
1460 gnutls_x509_crt_deinit (gnutls_verify_cert);
1461 return gnutls_make_error (ret);
1464 XPROCESS (proc)->gnutls_certificate = gnutls_verify_cert;
1466 int err = gnutls_x509_crt_check_hostname (gnutls_verify_cert,
1467 c_hostname);
1468 check_memory_full (err);
1469 if (!err)
1471 XPROCESS (proc)->gnutls_extra_peer_verification
1472 |= CERTIFICATE_NOT_MATCHING;
1473 if (verify_error_all
1474 || !NILP (Fmember (QChostname, verify_error)))
1476 gnutls_x509_crt_deinit (gnutls_verify_cert);
1477 emacs_gnutls_deinit (proc);
1478 boot_error (p, "The x509 certificate does not match \"%s\"",
1479 c_hostname);
1480 return Qnil;
1482 else
1483 GNUTLS_LOG2 (1, max_log_level, "x509 certificate does not match:",
1484 c_hostname);
1488 /* Set this flag only if the whole initialization succeeded. */
1489 XPROCESS (proc)->gnutls_p = true;
1491 return gnutls_make_error (ret);
1494 DEFUN ("gnutls-boot", Fgnutls_boot, Sgnutls_boot, 3, 3, 0,
1495 doc: /* Initialize GnuTLS client for process PROC with TYPE+PROPLIST.
1496 Currently only client mode is supported. Return a success/failure
1497 value you can check with `gnutls-errorp'.
1499 TYPE is a symbol, either `gnutls-anon' or `gnutls-x509pki'.
1500 PROPLIST is a property list with the following keys:
1502 :hostname is a string naming the remote host.
1504 :priority is a GnuTLS priority string, defaults to "NORMAL".
1506 :trustfiles is a list of PEM-encoded trust files for `gnutls-x509pki'.
1508 :crlfiles is a list of PEM-encoded CRL lists for `gnutls-x509pki'.
1510 :keylist is an alist of PEM-encoded key files and PEM-encoded
1511 certificates for `gnutls-x509pki'.
1513 :callbacks is an alist of callback functions, see below.
1515 :loglevel is the debug level requested from GnuTLS, try 4.
1517 :verify-flags is a bitset as per GnuTLS'
1518 gnutls_certificate_set_verify_flags.
1520 :verify-hostname-error is ignored. Pass :hostname in :verify-error
1521 instead.
1523 :verify-error is a list of symbols to express verification checks or
1524 t to do all checks. Currently it can contain `:trustfiles' and
1525 `:hostname' to verify the certificate or the hostname respectively.
1527 :min-prime-bits is the minimum accepted number of bits the client will
1528 accept in Diffie-Hellman key exchange.
1530 :complete-negotiation, if non-nil, will make negotiation complete
1531 before returning even on non-blocking sockets.
1533 The debug level will be set for this process AND globally for GnuTLS.
1534 So if you set it higher or lower at any point, it affects global
1535 debugging.
1537 Note that the priority is set on the client. The server does not use
1538 the protocols's priority except for disabling protocols that were not
1539 specified.
1541 Processes must be initialized with this function before other GnuTLS
1542 functions are used. This function allocates resources which can only
1543 be deallocated by calling `gnutls-deinit' or by calling it again.
1545 The callbacks alist can have a `verify' key, associated with a
1546 verification function (UNUSED).
1548 Each authentication type may need additional information in order to
1549 work. For X.509 PKI (`gnutls-x509pki'), you probably need at least
1550 one trustfile (usually a CA bundle). */)
1551 (Lisp_Object proc, Lisp_Object type, Lisp_Object proplist)
1553 int ret = GNUTLS_E_SUCCESS;
1554 int max_log_level = 0;
1556 gnutls_session_t state;
1557 gnutls_certificate_credentials_t x509_cred = NULL;
1558 gnutls_anon_client_credentials_t anon_cred = NULL;
1559 Lisp_Object global_init;
1560 char const *priority_string_ptr = "NORMAL"; /* default priority string. */
1561 char *c_hostname;
1563 /* Placeholders for the property list elements. */
1564 Lisp_Object priority_string;
1565 Lisp_Object trustfiles;
1566 Lisp_Object crlfiles;
1567 Lisp_Object keylist;
1568 /* Lisp_Object callbacks; */
1569 Lisp_Object loglevel;
1570 Lisp_Object hostname;
1571 Lisp_Object prime_bits;
1572 struct Lisp_Process *p = XPROCESS (proc);
1574 CHECK_PROCESS (proc);
1575 CHECK_SYMBOL (type);
1576 CHECK_LIST (proplist);
1578 if (NILP (Fgnutls_available_p ()))
1580 boot_error (p, "GnuTLS not available");
1581 return Qnil;
1584 if (!EQ (type, Qgnutls_x509pki) && !EQ (type, Qgnutls_anon))
1586 boot_error (p, "Invalid GnuTLS credential type");
1587 return Qnil;
1590 hostname = Fplist_get (proplist, QChostname);
1591 priority_string = Fplist_get (proplist, QCpriority);
1592 trustfiles = Fplist_get (proplist, QCtrustfiles);
1593 keylist = Fplist_get (proplist, QCkeylist);
1594 crlfiles = Fplist_get (proplist, QCcrlfiles);
1595 loglevel = Fplist_get (proplist, QCloglevel);
1596 prime_bits = Fplist_get (proplist, QCmin_prime_bits);
1598 if (!STRINGP (hostname))
1600 boot_error (p, "gnutls-boot: invalid :hostname parameter (not a string)");
1601 return Qnil;
1603 c_hostname = SSDATA (hostname);
1605 state = XPROCESS (proc)->gnutls_state;
1607 if (TYPE_RANGED_INTEGERP (int, loglevel))
1609 gnutls_global_set_log_function (gnutls_log_function);
1610 # ifdef HAVE_GNUTLS3
1611 gnutls_global_set_audit_log_function (gnutls_audit_log_function);
1612 # endif
1613 gnutls_global_set_log_level (XINT (loglevel));
1614 max_log_level = XINT (loglevel);
1615 XPROCESS (proc)->gnutls_log_level = max_log_level;
1618 GNUTLS_LOG2 (1, max_log_level, "connecting to host:", c_hostname);
1620 /* Always initialize globals. */
1621 global_init = emacs_gnutls_global_init ();
1622 if (! NILP (Fgnutls_errorp (global_init)))
1623 return global_init;
1625 /* Before allocating new credentials, deallocate any credentials
1626 that PROC might already have. */
1627 emacs_gnutls_deinit (proc);
1629 /* Mark PROC as a GnuTLS process. */
1630 XPROCESS (proc)->gnutls_state = NULL;
1631 XPROCESS (proc)->gnutls_x509_cred = NULL;
1632 XPROCESS (proc)->gnutls_anon_cred = NULL;
1633 pset_gnutls_cred_type (XPROCESS (proc), type);
1634 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_EMPTY;
1636 GNUTLS_LOG (1, max_log_level, "allocating credentials");
1637 if (EQ (type, Qgnutls_x509pki))
1639 Lisp_Object verify_flags;
1640 unsigned int gnutls_verify_flags = GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT;
1642 GNUTLS_LOG (2, max_log_level, "allocating x509 credentials");
1643 check_memory_full (gnutls_certificate_allocate_credentials (&x509_cred));
1644 XPROCESS (proc)->gnutls_x509_cred = x509_cred;
1646 verify_flags = Fplist_get (proplist, QCverify_flags);
1647 if (TYPE_RANGED_INTEGERP (unsigned int, verify_flags))
1649 gnutls_verify_flags = XFASTINT (verify_flags);
1650 GNUTLS_LOG (2, max_log_level, "setting verification flags");
1652 else if (NILP (verify_flags))
1653 GNUTLS_LOG (2, max_log_level, "using default verification flags");
1654 else
1655 GNUTLS_LOG (2, max_log_level, "ignoring invalid verify-flags");
1657 gnutls_certificate_set_verify_flags (x509_cred, gnutls_verify_flags);
1659 else /* Qgnutls_anon: */
1661 GNUTLS_LOG (2, max_log_level, "allocating anon credentials");
1662 check_memory_full (gnutls_anon_allocate_client_credentials (&anon_cred));
1663 XPROCESS (proc)->gnutls_anon_cred = anon_cred;
1666 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_CRED_ALLOC;
1668 if (EQ (type, Qgnutls_x509pki))
1670 /* TODO: GNUTLS_X509_FMT_DER is also an option. */
1671 int file_format = GNUTLS_X509_FMT_PEM;
1672 Lisp_Object tail;
1674 # ifdef HAVE_GNUTLS_X509_SYSTEM_TRUST
1675 ret = gnutls_certificate_set_x509_system_trust (x509_cred);
1676 if (ret < GNUTLS_E_SUCCESS)
1678 check_memory_full (ret);
1679 GNUTLS_LOG2i (4, max_log_level,
1680 "setting system trust failed with code ", ret);
1682 # endif
1684 for (tail = trustfiles; CONSP (tail); tail = XCDR (tail))
1686 Lisp_Object trustfile = XCAR (tail);
1687 if (STRINGP (trustfile))
1689 GNUTLS_LOG2 (1, max_log_level, "setting the trustfile: ",
1690 SSDATA (trustfile));
1691 trustfile = ENCODE_FILE (trustfile);
1692 # ifdef WINDOWSNT
1693 /* Since GnuTLS doesn't support UTF-8 or UTF-16 encoded
1694 file names on Windows, we need to re-encode the file
1695 name using the current ANSI codepage. */
1696 trustfile = ansi_encode_filename (trustfile);
1697 # endif
1698 ret = gnutls_certificate_set_x509_trust_file
1699 (x509_cred,
1700 SSDATA (trustfile),
1701 file_format);
1703 if (ret < GNUTLS_E_SUCCESS)
1704 return gnutls_make_error (ret);
1706 else
1708 emacs_gnutls_deinit (proc);
1709 boot_error (p, "Invalid trustfile");
1710 return Qnil;
1714 for (tail = crlfiles; CONSP (tail); tail = XCDR (tail))
1716 Lisp_Object crlfile = XCAR (tail);
1717 if (STRINGP (crlfile))
1719 GNUTLS_LOG2 (1, max_log_level, "setting the CRL file: ",
1720 SSDATA (crlfile));
1721 crlfile = ENCODE_FILE (crlfile);
1722 # ifdef WINDOWSNT
1723 crlfile = ansi_encode_filename (crlfile);
1724 # endif
1725 ret = gnutls_certificate_set_x509_crl_file
1726 (x509_cred, SSDATA (crlfile), file_format);
1728 if (ret < GNUTLS_E_SUCCESS)
1729 return gnutls_make_error (ret);
1731 else
1733 emacs_gnutls_deinit (proc);
1734 boot_error (p, "Invalid CRL file");
1735 return Qnil;
1739 for (tail = keylist; CONSP (tail); tail = XCDR (tail))
1741 Lisp_Object keyfile = Fcar (XCAR (tail));
1742 Lisp_Object certfile = Fcar (Fcdr (XCAR (tail)));
1743 if (STRINGP (keyfile) && STRINGP (certfile))
1745 GNUTLS_LOG2 (1, max_log_level, "setting the client key file: ",
1746 SSDATA (keyfile));
1747 GNUTLS_LOG2 (1, max_log_level, "setting the client cert file: ",
1748 SSDATA (certfile));
1749 keyfile = ENCODE_FILE (keyfile);
1750 certfile = ENCODE_FILE (certfile);
1751 # ifdef WINDOWSNT
1752 keyfile = ansi_encode_filename (keyfile);
1753 certfile = ansi_encode_filename (certfile);
1754 # endif
1755 ret = gnutls_certificate_set_x509_key_file
1756 (x509_cred, SSDATA (certfile), SSDATA (keyfile), file_format);
1758 if (ret < GNUTLS_E_SUCCESS)
1759 return gnutls_make_error (ret);
1761 else
1763 emacs_gnutls_deinit (proc);
1764 boot_error (p, STRINGP (keyfile) ? "Invalid client cert file"
1765 : "Invalid client key file");
1766 return Qnil;
1771 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_FILES;
1772 GNUTLS_LOG (1, max_log_level, "gnutls callbacks");
1773 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_CALLBACKS;
1775 /* Call gnutls_init here: */
1777 GNUTLS_LOG (1, max_log_level, "gnutls_init");
1778 int gnutls_flags = GNUTLS_CLIENT;
1779 # ifdef GNUTLS_NONBLOCK
1780 if (XPROCESS (proc)->is_non_blocking_client)
1781 gnutls_flags |= GNUTLS_NONBLOCK;
1782 # endif
1783 ret = gnutls_init (&state, gnutls_flags);
1784 XPROCESS (proc)->gnutls_state = state;
1785 if (ret < GNUTLS_E_SUCCESS)
1786 return gnutls_make_error (ret);
1787 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_INIT;
1789 if (STRINGP (priority_string))
1791 priority_string_ptr = SSDATA (priority_string);
1792 GNUTLS_LOG2 (1, max_log_level, "got non-default priority string:",
1793 priority_string_ptr);
1795 else
1797 GNUTLS_LOG2 (1, max_log_level, "using default priority string:",
1798 priority_string_ptr);
1801 GNUTLS_LOG (1, max_log_level, "setting the priority string");
1802 ret = gnutls_priority_set_direct (state, priority_string_ptr, NULL);
1803 if (ret < GNUTLS_E_SUCCESS)
1804 return gnutls_make_error (ret);
1806 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_PRIORITY;
1808 if (INTEGERP (prime_bits))
1809 gnutls_dh_set_prime_bits (state, XUINT (prime_bits));
1811 ret = EQ (type, Qgnutls_x509pki)
1812 ? gnutls_credentials_set (state, GNUTLS_CRD_CERTIFICATE, x509_cred)
1813 : gnutls_credentials_set (state, GNUTLS_CRD_ANON, anon_cred);
1814 if (ret < GNUTLS_E_SUCCESS)
1815 return gnutls_make_error (ret);
1817 if (!gnutls_ip_address_p (c_hostname))
1819 ret = gnutls_server_name_set (state, GNUTLS_NAME_DNS, c_hostname,
1820 strlen (c_hostname));
1821 if (ret < GNUTLS_E_SUCCESS)
1822 return gnutls_make_error (ret);
1825 XPROCESS (proc)->gnutls_complete_negotiation_p =
1826 !NILP (Fplist_get (proplist, QCcomplete_negotiation));
1827 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_CRED_SET;
1828 ret = emacs_gnutls_handshake (XPROCESS (proc));
1829 if (ret < GNUTLS_E_SUCCESS)
1830 return gnutls_make_error (ret);
1832 return gnutls_verify_boot (proc, proplist);
1835 DEFUN ("gnutls-bye", Fgnutls_bye,
1836 Sgnutls_bye, 2, 2, 0,
1837 doc: /* Terminate current GnuTLS connection for process PROC.
1838 The connection should have been initiated using `gnutls-handshake'.
1840 If CONT is not nil the TLS connection gets terminated and further
1841 receives and sends will be disallowed. If the return value is zero you
1842 may continue using the connection. If CONT is nil, GnuTLS actually
1843 sends an alert containing a close request and waits for the peer to
1844 reply with the same message. In order to reuse the connection you
1845 should wait for an EOF from the peer.
1847 This function may also return `gnutls-e-again', or
1848 `gnutls-e-interrupted'. */)
1849 (Lisp_Object proc, Lisp_Object cont)
1851 gnutls_session_t state;
1852 int ret;
1854 CHECK_PROCESS (proc);
1856 state = XPROCESS (proc)->gnutls_state;
1858 gnutls_x509_crt_deinit (XPROCESS (proc)->gnutls_certificate);
1860 ret = gnutls_bye (state, NILP (cont) ? GNUTLS_SHUT_RDWR : GNUTLS_SHUT_WR);
1862 return gnutls_make_error (ret);
1865 #endif /* HAVE_GNUTLS */
1867 #ifdef HAVE_GNUTLS3
1869 DEFUN ("gnutls-ciphers", Fgnutls_ciphers, Sgnutls_ciphers, 0, 0, 0,
1870 doc: /* Return alist of GnuTLS symmetric cipher descriptions as plists.
1871 The alist key is the cipher name. */)
1872 (void)
1874 Lisp_Object ciphers = Qnil;
1876 const gnutls_cipher_algorithm_t *gciphers = gnutls_cipher_list ();
1877 for (ptrdiff_t pos = 0; gciphers[pos] != 0; pos++)
1879 gnutls_cipher_algorithm_t gca = gciphers[pos];
1880 if (gca == GNUTLS_CIPHER_NULL)
1881 continue;
1882 char const *cipher_name = gnutls_cipher_get_name (gca);
1883 if (!cipher_name)
1884 continue;
1886 /* A symbol representing the GnuTLS cipher. */
1887 Lisp_Object cipher_symbol = intern (cipher_name);
1889 ptrdiff_t cipher_tag_size = gnutls_cipher_get_tag_size (gca);
1891 Lisp_Object cp
1892 = listn (CONSTYPE_HEAP, 15, cipher_symbol,
1893 QCcipher_id, make_number (gca),
1894 QCtype, Qgnutls_type_cipher,
1895 QCcipher_aead_capable, cipher_tag_size == 0 ? Qnil : Qt,
1896 QCcipher_tagsize, make_number (cipher_tag_size),
1898 QCcipher_blocksize,
1899 make_number (gnutls_cipher_get_block_size (gca)),
1901 QCcipher_keysize,
1902 make_number (gnutls_cipher_get_key_size (gca)),
1904 QCcipher_ivsize,
1905 make_number (gnutls_cipher_get_iv_size (gca)));
1907 ciphers = Fcons (cp, ciphers);
1910 return ciphers;
1913 static Lisp_Object
1914 gnutls_symmetric_aead (bool encrypting, gnutls_cipher_algorithm_t gca,
1915 Lisp_Object cipher,
1916 const char *kdata, ptrdiff_t ksize,
1917 const char *vdata, ptrdiff_t vsize,
1918 const char *idata, ptrdiff_t isize,
1919 Lisp_Object aead_auth)
1921 # ifdef HAVE_GNUTLS_AEAD
1923 const char *desc = encrypting ? "encrypt" : "decrypt";
1924 Lisp_Object actual_iv = make_unibyte_string (vdata, vsize);
1926 gnutls_aead_cipher_hd_t acipher;
1927 gnutls_datum_t key_datum = { (unsigned char *) kdata, ksize };
1928 int ret = gnutls_aead_cipher_init (&acipher, gca, &key_datum);
1930 if (ret < GNUTLS_E_SUCCESS)
1931 error ("GnuTLS AEAD cipher %s/%s initialization failed: %s",
1932 gnutls_cipher_get_name (gca), desc, emacs_gnutls_strerror (ret));
1934 ptrdiff_t cipher_tag_size = gnutls_cipher_get_tag_size (gca);
1935 ptrdiff_t tagged_size;
1936 if (INT_ADD_WRAPV (isize, cipher_tag_size, &tagged_size)
1937 || SIZE_MAX < tagged_size)
1938 memory_full (SIZE_MAX);
1939 size_t storage_length = tagged_size;
1940 USE_SAFE_ALLOCA;
1941 char *storage = SAFE_ALLOCA (storage_length);
1943 const char *aead_auth_data = NULL;
1944 ptrdiff_t aead_auth_size = 0;
1946 if (!NILP (aead_auth))
1948 if (BUFFERP (aead_auth) || STRINGP (aead_auth))
1949 aead_auth = list1 (aead_auth);
1951 CHECK_CONS (aead_auth);
1953 ptrdiff_t astart_byte, aend_byte;
1954 const char *adata
1955 = extract_data_from_object (aead_auth, &astart_byte, &aend_byte);
1956 if (adata == NULL)
1957 error ("GnuTLS AEAD cipher auth extraction failed");
1959 aead_auth_data = adata;
1960 aead_auth_size = aend_byte - astart_byte;
1963 ptrdiff_t expected_remainder = encrypting ? 0 : cipher_tag_size;
1964 ptrdiff_t cipher_block_size = gnutls_cipher_get_block_size (gca);
1966 if (isize < expected_remainder
1967 || (isize - expected_remainder) % cipher_block_size != 0)
1968 error (("GnuTLS AEAD cipher %s/%s input block length %"pD"d "
1969 "is not %"pD"d greater than a multiple of the required %"pD"d"),
1970 gnutls_cipher_get_name (gca), desc,
1971 isize, expected_remainder, cipher_block_size);
1973 ret = ((encrypting ? gnutls_aead_cipher_encrypt : gnutls_aead_cipher_decrypt)
1974 (acipher, vdata, vsize, aead_auth_data, aead_auth_size,
1975 cipher_tag_size, idata, isize, storage, &storage_length));
1977 Lisp_Object output;
1978 if (GNUTLS_E_SUCCESS <= ret)
1979 output = make_unibyte_string (storage, storage_length);
1980 explicit_bzero (storage, storage_length);
1981 gnutls_aead_cipher_deinit (acipher);
1983 if (ret < GNUTLS_E_SUCCESS)
1984 error ((encrypting
1985 ? "GnuTLS AEAD cipher %s encryption failed: %s"
1986 : "GnuTLS AEAD cipher %s decryption failed: %s"),
1987 gnutls_cipher_get_name (gca), emacs_gnutls_strerror (ret));
1989 SAFE_FREE ();
1990 return list2 (output, actual_iv);
1991 # else
1992 printmax_t print_gca = gca;
1993 error ("GnuTLS AEAD cipher %"pMd" is invalid or not found", print_gca);
1994 # endif
1997 static Lisp_Object
1998 gnutls_symmetric (bool encrypting, Lisp_Object cipher,
1999 Lisp_Object key, Lisp_Object iv,
2000 Lisp_Object input, Lisp_Object aead_auth)
2002 if (BUFFERP (key) || STRINGP (key))
2003 key = list1 (key);
2005 CHECK_CONS (key);
2007 if (BUFFERP (input) || STRINGP (input))
2008 input = list1 (input);
2010 CHECK_CONS (input);
2012 if (BUFFERP (iv) || STRINGP (iv))
2013 iv = list1 (iv);
2015 CHECK_CONS (iv);
2018 const char *desc = encrypting ? "encrypt" : "decrypt";
2020 gnutls_cipher_algorithm_t gca = GNUTLS_CIPHER_UNKNOWN;
2022 Lisp_Object info = Qnil;
2023 if (STRINGP (cipher))
2024 cipher = intern (SSDATA (cipher));
2026 if (SYMBOLP (cipher))
2028 info = Fassq (cipher, Fgnutls_ciphers ());
2029 if (!CONSP (info))
2030 xsignal2 (Qerror,
2031 build_string ("GnuTLS cipher is invalid or not found"),
2032 cipher);
2033 info = XCDR (info);
2035 else if (TYPE_RANGED_INTEGERP (gnutls_cipher_algorithm_t, cipher))
2036 gca = XINT (cipher);
2037 else
2038 info = cipher;
2040 if (!NILP (info) && CONSP (info))
2042 Lisp_Object v = Fplist_get (info, QCcipher_id);
2043 if (TYPE_RANGED_INTEGERP (gnutls_cipher_algorithm_t, v))
2044 gca = XINT (v);
2047 ptrdiff_t key_size = gnutls_cipher_get_key_size (gca);
2048 if (key_size == 0)
2049 xsignal2 (Qerror,
2050 build_string ("GnuTLS cipher is invalid or not found"), cipher);
2052 ptrdiff_t kstart_byte, kend_byte;
2053 const char *kdata = extract_data_from_object (key, &kstart_byte, &kend_byte);
2055 if (kdata == NULL)
2056 error ("GnuTLS cipher key extraction failed");
2058 if (kend_byte - kstart_byte != key_size)
2059 error (("GnuTLS cipher %s/%s key length %"pD"d is not equal to "
2060 "the required %"pD"d"),
2061 gnutls_cipher_get_name (gca), desc,
2062 kend_byte - kstart_byte, key_size);
2064 ptrdiff_t vstart_byte, vend_byte;
2065 char *vdata = extract_data_from_object (iv, &vstart_byte, &vend_byte);
2067 if (vdata == NULL)
2068 error ("GnuTLS cipher IV extraction failed");
2070 ptrdiff_t iv_size = gnutls_cipher_get_iv_size (gca);
2071 if (vend_byte - vstart_byte != iv_size)
2072 error (("GnuTLS cipher %s/%s IV length %"pD"d is not equal to "
2073 "the required %"pD"d"),
2074 gnutls_cipher_get_name (gca), desc,
2075 vend_byte - vstart_byte, iv_size);
2077 Lisp_Object actual_iv = make_unibyte_string (vdata, vend_byte - vstart_byte);
2079 ptrdiff_t istart_byte, iend_byte;
2080 const char *idata
2081 = extract_data_from_object (input, &istart_byte, &iend_byte);
2083 if (idata == NULL)
2084 error ("GnuTLS cipher input extraction failed");
2086 /* Is this an AEAD cipher? */
2087 if (gnutls_cipher_get_tag_size (gca) > 0)
2089 Lisp_Object aead_output =
2090 gnutls_symmetric_aead (encrypting, gca, cipher,
2091 kdata, kend_byte - kstart_byte,
2092 vdata, vend_byte - vstart_byte,
2093 idata, iend_byte - istart_byte,
2094 aead_auth);
2095 if (STRINGP (XCAR (key)))
2096 Fclear_string (XCAR (key));
2097 return aead_output;
2100 ptrdiff_t cipher_block_size = gnutls_cipher_get_block_size (gca);
2101 if ((iend_byte - istart_byte) % cipher_block_size != 0)
2102 error (("GnuTLS cipher %s/%s input block length %"pD"d is not a multiple "
2103 "of the required %"pD"d"),
2104 gnutls_cipher_get_name (gca), desc,
2105 iend_byte - istart_byte, cipher_block_size);
2107 gnutls_cipher_hd_t hcipher;
2108 gnutls_datum_t key_datum
2109 = { (unsigned char *) kdata, kend_byte - kstart_byte };
2111 int ret = gnutls_cipher_init (&hcipher, gca, &key_datum, NULL);
2113 if (ret < GNUTLS_E_SUCCESS)
2114 error ("GnuTLS cipher %s/%s initialization failed: %s",
2115 gnutls_cipher_get_name (gca), desc, emacs_gnutls_strerror (ret));
2117 /* Note that this will not support streaming block mode. */
2118 gnutls_cipher_set_iv (hcipher, vdata, vend_byte - vstart_byte);
2120 /* GnuTLS docs: "For the supported ciphers the encrypted data length
2121 will equal the plaintext size." */
2122 ptrdiff_t storage_length = iend_byte - istart_byte;
2123 Lisp_Object storage = make_uninit_string (storage_length);
2125 ret = ((encrypting ? gnutls_cipher_encrypt2 : gnutls_cipher_decrypt2)
2126 (hcipher, idata, iend_byte - istart_byte,
2127 SSDATA (storage), storage_length));
2129 if (STRINGP (XCAR (key)))
2130 Fclear_string (XCAR (key));
2132 if (ret < GNUTLS_E_SUCCESS)
2134 gnutls_cipher_deinit (hcipher);
2135 if (encrypting)
2136 error ("GnuTLS cipher %s encryption failed: %s",
2137 gnutls_cipher_get_name (gca), emacs_gnutls_strerror (ret));
2138 else
2139 error ("GnuTLS cipher %s decryption failed: %s",
2140 gnutls_cipher_get_name (gca), emacs_gnutls_strerror (ret));
2143 gnutls_cipher_deinit (hcipher);
2145 return list2 (storage, actual_iv);
2148 DEFUN ("gnutls-symmetric-encrypt", Fgnutls_symmetric_encrypt,
2149 Sgnutls_symmetric_encrypt, 4, 5, 0,
2150 doc: /* Encrypt INPUT with symmetric CIPHER, KEY+AEAD_AUTH, and IV to a unibyte string.
2152 Return nil on error.
2154 The KEY can be specified as a buffer or string or in other ways (see
2155 Info node `(elisp)Format of GnuTLS Cryptography Inputs'). The KEY
2156 will be wiped after use if it's a string.
2158 The IV and INPUT and the optional AEAD_AUTH can be specified as a
2159 buffer or string or in other ways (see Info node `(elisp)Format of
2160 GnuTLS Cryptography Inputs').
2162 The alist of symmetric ciphers can be obtained with `gnutls-ciphers`.
2163 The CIPHER may be a string or symbol matching a key in that alist, or
2164 a plist with the :cipher-id numeric property, or the number itself.
2166 AEAD ciphers: these ciphers will have a `gnutls-ciphers' entry with
2167 :cipher-aead-capable set to t. AEAD_AUTH can be supplied for
2168 these AEAD ciphers, but it may still be omitted (nil) as well. */)
2169 (Lisp_Object cipher, Lisp_Object key, Lisp_Object iv,
2170 Lisp_Object input, Lisp_Object aead_auth)
2172 return gnutls_symmetric (true, cipher, key, iv, input, aead_auth);
2175 DEFUN ("gnutls-symmetric-decrypt", Fgnutls_symmetric_decrypt,
2176 Sgnutls_symmetric_decrypt, 4, 5, 0,
2177 doc: /* Decrypt INPUT with symmetric CIPHER, KEY+AEAD_AUTH, and IV to a unibyte string.
2179 Return nil on error.
2181 The KEY can be specified as a buffer or string or in other ways (see
2182 Info node `(elisp)Format of GnuTLS Cryptography Inputs'). The KEY
2183 will be wiped after use if it's a string.
2185 The IV and INPUT and the optional AEAD_AUTH can be specified as a
2186 buffer or string or in other ways (see Info node `(elisp)Format of
2187 GnuTLS Cryptography Inputs').
2189 The alist of symmetric ciphers can be obtained with `gnutls-ciphers`.
2190 The CIPHER may be a string or symbol matching a key in that alist, or
2191 a plist with the `:cipher-id' numeric property, or the number itself.
2193 AEAD ciphers: these ciphers will have a `gnutls-ciphers' entry with
2194 :cipher-aead-capable set to t. AEAD_AUTH can be supplied for
2195 these AEAD ciphers, but it may still be omitted (nil) as well. */)
2196 (Lisp_Object cipher, Lisp_Object key, Lisp_Object iv,
2197 Lisp_Object input, Lisp_Object aead_auth)
2199 return gnutls_symmetric (false, cipher, key, iv, input, aead_auth);
2202 DEFUN ("gnutls-macs", Fgnutls_macs, Sgnutls_macs, 0, 0, 0,
2203 doc: /* Return alist of GnuTLS mac-algorithm method descriptions as plists.
2205 Use the value of the alist (extract it with `alist-get' for instance)
2206 with `gnutls-hash-mac'. The alist key is the mac-algorithm method
2207 name. */)
2208 (void)
2210 Lisp_Object mac_algorithms = Qnil;
2211 const gnutls_mac_algorithm_t *macs = gnutls_mac_list ();
2212 for (ptrdiff_t pos = 0; macs[pos] != 0; pos++)
2214 const gnutls_mac_algorithm_t gma = macs[pos];
2216 /* A symbol representing the GnuTLS MAC algorithm. */
2217 Lisp_Object gma_symbol = intern (gnutls_mac_get_name (gma));
2219 size_t nonce_size = 0;
2220 #ifdef HAVE_GNUTLS_MAC_GET_NONCE_SIZE
2221 nonce_size = gnutls_mac_get_nonce_size (gma);
2222 #endif
2223 Lisp_Object mp = listn (CONSTYPE_HEAP, 11, gma_symbol,
2224 QCmac_algorithm_id, make_number (gma),
2225 QCtype, Qgnutls_type_mac_algorithm,
2227 QCmac_algorithm_length,
2228 make_number (gnutls_hmac_get_len (gma)),
2230 QCmac_algorithm_keysize,
2231 make_number (gnutls_mac_get_key_size (gma)),
2233 QCmac_algorithm_noncesize,
2234 make_number (nonce_size));
2235 mac_algorithms = Fcons (mp, mac_algorithms);
2238 return mac_algorithms;
2241 DEFUN ("gnutls-digests", Fgnutls_digests, Sgnutls_digests, 0, 0, 0,
2242 doc: /* Return alist of GnuTLS digest-algorithm method descriptions as plists.
2244 Use the value of the alist (extract it with `alist-get' for instance)
2245 with `gnutls-hash-digest'. The alist key is the digest-algorithm
2246 method name. */)
2247 (void)
2249 Lisp_Object digest_algorithms = Qnil;
2250 const gnutls_digest_algorithm_t *digests = gnutls_digest_list ();
2251 for (ptrdiff_t pos = 0; digests[pos] != 0; pos++)
2253 const gnutls_digest_algorithm_t gda = digests[pos];
2255 /* A symbol representing the GnuTLS digest algorithm. */
2256 Lisp_Object gda_symbol = intern (gnutls_digest_get_name (gda));
2258 Lisp_Object mp = listn (CONSTYPE_HEAP, 7, gda_symbol,
2259 QCdigest_algorithm_id, make_number (gda),
2260 QCtype, Qgnutls_type_digest_algorithm,
2262 QCdigest_algorithm_length,
2263 make_number (gnutls_hash_get_len (gda)));
2265 digest_algorithms = Fcons (mp, digest_algorithms);
2268 return digest_algorithms;
2271 DEFUN ("gnutls-hash-mac", Fgnutls_hash_mac, Sgnutls_hash_mac, 3, 3, 0,
2272 doc: /* Hash INPUT with HASH-METHOD and KEY into a unibyte string.
2274 Return nil on error.
2276 The KEY can be specified as a buffer or string or in other ways (see
2277 Info node `(elisp)Format of GnuTLS Cryptography Inputs'). The KEY
2278 will be wiped after use if it's a string.
2280 The INPUT can be specified as a buffer or string or in other
2281 ways (see Info node `(elisp)Format of GnuTLS Cryptography Inputs').
2283 The alist of MAC algorithms can be obtained with `gnutls-macs`. The
2284 HASH-METHOD may be a string or symbol matching a key in that alist, or
2285 a plist with the `:mac-algorithm-id' numeric property, or the number
2286 itself. */)
2287 (Lisp_Object hash_method, Lisp_Object key, Lisp_Object input)
2289 if (BUFFERP (input) || STRINGP (input))
2290 input = list1 (input);
2292 CHECK_CONS (input);
2294 if (BUFFERP (key) || STRINGP (key))
2295 key = list1 (key);
2297 CHECK_CONS (key);
2299 gnutls_mac_algorithm_t gma = GNUTLS_MAC_UNKNOWN;
2301 Lisp_Object info = Qnil;
2302 if (STRINGP (hash_method))
2303 hash_method = intern (SSDATA (hash_method));
2305 if (SYMBOLP (hash_method))
2307 info = Fassq (hash_method, Fgnutls_macs ());
2308 if (!CONSP (info))
2309 xsignal2 (Qerror,
2310 build_string ("GnuTLS MAC-method is invalid or not found"),
2311 hash_method);
2312 info = XCDR (info);
2314 else if (TYPE_RANGED_INTEGERP (gnutls_mac_algorithm_t, hash_method))
2315 gma = XINT (hash_method);
2316 else
2317 info = hash_method;
2319 if (!NILP (info) && CONSP (info))
2321 Lisp_Object v = Fplist_get (info, QCmac_algorithm_id);
2322 if (TYPE_RANGED_INTEGERP (gnutls_mac_algorithm_t, v))
2323 gma = XINT (v);
2326 ptrdiff_t digest_length = gnutls_hmac_get_len (gma);
2327 if (digest_length == 0)
2328 xsignal2 (Qerror,
2329 build_string ("GnuTLS MAC-method is invalid or not found"),
2330 hash_method);
2332 ptrdiff_t kstart_byte, kend_byte;
2333 const char *kdata = extract_data_from_object (key, &kstart_byte, &kend_byte);
2334 if (kdata == NULL)
2335 error ("GnuTLS MAC key extraction failed");
2337 gnutls_hmac_hd_t hmac;
2338 int ret = gnutls_hmac_init (&hmac, gma,
2339 kdata + kstart_byte, kend_byte - kstart_byte);
2340 if (ret < GNUTLS_E_SUCCESS)
2341 error ("GnuTLS MAC %s initialization failed: %s",
2342 gnutls_mac_get_name (gma), emacs_gnutls_strerror (ret));
2344 ptrdiff_t istart_byte, iend_byte;
2345 const char *idata
2346 = extract_data_from_object (input, &istart_byte, &iend_byte);
2347 if (idata == NULL)
2348 error ("GnuTLS MAC input extraction failed");
2350 Lisp_Object digest = make_uninit_string (digest_length);
2352 ret = gnutls_hmac (hmac, idata + istart_byte, iend_byte - istart_byte);
2354 if (STRINGP (XCAR (key)))
2355 Fclear_string (XCAR (key));
2357 if (ret < GNUTLS_E_SUCCESS)
2359 gnutls_hmac_deinit (hmac, NULL);
2360 error ("GnuTLS MAC %s application failed: %s",
2361 gnutls_mac_get_name (gma), emacs_gnutls_strerror (ret));
2364 gnutls_hmac_output (hmac, SSDATA (digest));
2365 gnutls_hmac_deinit (hmac, NULL);
2367 return digest;
2370 DEFUN ("gnutls-hash-digest", Fgnutls_hash_digest, Sgnutls_hash_digest, 2, 2, 0,
2371 doc: /* Digest INPUT with DIGEST-METHOD into a unibyte string.
2373 Return nil on error.
2375 The INPUT can be specified as a buffer or string or in other
2376 ways (see Info node `(elisp)Format of GnuTLS Cryptography Inputs').
2378 The alist of digest algorithms can be obtained with `gnutls-digests`.
2379 The DIGEST-METHOD may be a string or symbol matching a key in that
2380 alist, or a plist with the `:digest-algorithm-id' numeric property, or
2381 the number itself. */)
2382 (Lisp_Object digest_method, Lisp_Object input)
2384 if (BUFFERP (input) || STRINGP (input))
2385 input = list1 (input);
2387 CHECK_CONS (input);
2389 gnutls_digest_algorithm_t gda = GNUTLS_DIG_UNKNOWN;
2391 Lisp_Object info = Qnil;
2392 if (STRINGP (digest_method))
2393 digest_method = intern (SSDATA (digest_method));
2395 if (SYMBOLP (digest_method))
2397 info = Fassq (digest_method, Fgnutls_digests ());
2398 if (!CONSP (info))
2399 xsignal2 (Qerror,
2400 build_string ("GnuTLS digest-method is invalid or not found"),
2401 digest_method);
2402 info = XCDR (info);
2404 else if (TYPE_RANGED_INTEGERP (gnutls_digest_algorithm_t, digest_method))
2405 gda = XINT (digest_method);
2406 else
2407 info = digest_method;
2409 if (!NILP (info) && CONSP (info))
2411 Lisp_Object v = Fplist_get (info, QCdigest_algorithm_id);
2412 if (TYPE_RANGED_INTEGERP (gnutls_digest_algorithm_t, v))
2413 gda = XINT (v);
2416 ptrdiff_t digest_length = gnutls_hash_get_len (gda);
2417 if (digest_length == 0)
2418 xsignal2 (Qerror,
2419 build_string ("GnuTLS digest-method is invalid or not found"),
2420 digest_method);
2422 gnutls_hash_hd_t hash;
2423 int ret = gnutls_hash_init (&hash, gda);
2425 if (ret < GNUTLS_E_SUCCESS)
2426 error ("GnuTLS digest initialization failed: %s",
2427 emacs_gnutls_strerror (ret));
2429 Lisp_Object digest = make_uninit_string (digest_length);
2431 ptrdiff_t istart_byte, iend_byte;
2432 const char *idata
2433 = extract_data_from_object (input, &istart_byte, &iend_byte);
2434 if (idata == NULL)
2435 error ("GnuTLS digest input extraction failed");
2437 ret = gnutls_hash (hash, idata + istart_byte, iend_byte - istart_byte);
2439 if (ret < GNUTLS_E_SUCCESS)
2441 gnutls_hash_deinit (hash, NULL);
2442 error ("GnuTLS digest application failed: %s",
2443 emacs_gnutls_strerror (ret));
2446 gnutls_hash_output (hash, SSDATA (digest));
2447 gnutls_hash_deinit (hash, NULL);
2449 return digest;
2452 #endif /* HAVE_GNUTLS3 */
2454 DEFUN ("gnutls-available-p", Fgnutls_available_p, Sgnutls_available_p, 0, 0, 0,
2455 doc: /* Return list of capabilities if GnuTLS is available in this instance of Emacs.
2457 ...if supported : then...
2458 GnuTLS 3 or higher : the list will contain `gnutls3'.
2459 GnuTLS MACs : the list will contain `macs'.
2460 GnuTLS digests : the list will contain `digests'.
2461 GnuTLS symmetric ciphers: the list will contain `ciphers'.
2462 GnuTLS AEAD ciphers : the list will contain `AEAD-ciphers'.
2463 %DUMBFW : the list will contain `ClientHello\ Padding'.
2464 Any GnuTLS extension with ID up to 100
2465 : the list will contain its name. */)
2466 (void)
2468 Lisp_Object capabilities = Qnil;
2470 #ifdef HAVE_GNUTLS
2472 # ifdef WINDOWSNT
2473 Lisp_Object found = Fassq (Qgnutls, Vlibrary_cache);
2474 if (CONSP (found))
2475 return XCDR (found);
2477 /* Load the GnuTLS DLL and find exported functions. The external
2478 library cache is updated after the capabilities have been
2479 determined. */
2480 if (!init_gnutls_functions ())
2481 return Qnil;
2482 # endif /* WINDOWSNT */
2484 capabilities = Fcons (intern("gnutls"), capabilities);
2486 # ifdef HAVE_GNUTLS3
2487 capabilities = Fcons (intern("gnutls3"), capabilities);
2488 capabilities = Fcons (intern("digests"), capabilities);
2489 capabilities = Fcons (intern("ciphers"), capabilities);
2491 # ifdef HAVE_GNUTLS_AEAD
2492 capabilities = Fcons (intern("AEAD-ciphers"), capabilities);
2493 # endif
2495 capabilities = Fcons (intern("macs"), capabilities);
2497 # ifdef HAVE_GNUTLS_EXT_GET_NAME
2498 for (unsigned int ext=0; ext < 100; ext++)
2500 const char* name = gnutls_ext_get_name(ext);
2501 if (name != NULL)
2503 capabilities = Fcons (intern(name), capabilities);
2506 # endif
2507 # endif /* HAVE_GNUTLS3 */
2509 # ifdef HAVE_GNUTLS_EXT__DUMBFW
2510 capabilities = Fcons (intern("ClientHello Padding"), capabilities);
2511 # endif
2513 # ifdef WINDOWSNT
2514 Vlibrary_cache = Fcons (Fcons (Qgnutls, capabilities), Vlibrary_cache);
2515 # endif /* WINDOWSNT */
2516 #endif /* HAVE_GNUTLS */
2518 return capabilities;
2521 void
2522 syms_of_gnutls (void)
2524 DEFSYM (Qlibgnutls_version, "libgnutls-version");
2525 Fset (Qlibgnutls_version,
2526 #ifdef HAVE_GNUTLS
2527 make_number (GNUTLS_VERSION_MAJOR * 10000
2528 + GNUTLS_VERSION_MINOR * 100
2529 + GNUTLS_VERSION_PATCH)
2530 #else
2531 make_number (-1)
2532 #endif
2534 #ifdef HAVE_GNUTLS
2535 gnutls_global_initialized = 0;
2537 DEFSYM (Qgnutls_code, "gnutls-code");
2538 DEFSYM (Qgnutls_anon, "gnutls-anon");
2539 DEFSYM (Qgnutls_x509pki, "gnutls-x509pki");
2541 /* The following are for the property list of 'gnutls-boot'. */
2542 DEFSYM (QChostname, ":hostname");
2543 DEFSYM (QCpriority, ":priority");
2544 DEFSYM (QCtrustfiles, ":trustfiles");
2545 DEFSYM (QCkeylist, ":keylist");
2546 DEFSYM (QCcrlfiles, ":crlfiles");
2547 DEFSYM (QCmin_prime_bits, ":min-prime-bits");
2548 DEFSYM (QCloglevel, ":loglevel");
2549 DEFSYM (QCcomplete_negotiation, ":complete-negotiation");
2550 DEFSYM (QCverify_flags, ":verify-flags");
2551 DEFSYM (QCverify_error, ":verify-error");
2553 DEFSYM (QCcipher_id, ":cipher-id");
2554 DEFSYM (QCcipher_aead_capable, ":cipher-aead-capable");
2555 DEFSYM (QCcipher_blocksize, ":cipher-blocksize");
2556 DEFSYM (QCcipher_keysize, ":cipher-keysize");
2557 DEFSYM (QCcipher_tagsize, ":cipher-tagsize");
2558 DEFSYM (QCcipher_ivsize, ":cipher-ivsize");
2560 DEFSYM (QCmac_algorithm_id, ":mac-algorithm-id");
2561 DEFSYM (QCmac_algorithm_noncesize, ":mac-algorithm-noncesize");
2562 DEFSYM (QCmac_algorithm_keysize, ":mac-algorithm-keysize");
2563 DEFSYM (QCmac_algorithm_length, ":mac-algorithm-length");
2565 DEFSYM (QCdigest_algorithm_id, ":digest-algorithm-id");
2566 DEFSYM (QCdigest_algorithm_length, ":digest-algorithm-length");
2568 DEFSYM (QCtype, ":type");
2569 DEFSYM (Qgnutls_type_cipher, "gnutls-symmetric-cipher");
2570 DEFSYM (Qgnutls_type_mac_algorithm, "gnutls-mac-algorithm");
2571 DEFSYM (Qgnutls_type_digest_algorithm, "gnutls-digest-algorithm");
2573 DEFSYM (Qgnutls_e_interrupted, "gnutls-e-interrupted");
2574 Fput (Qgnutls_e_interrupted, Qgnutls_code,
2575 make_number (GNUTLS_E_INTERRUPTED));
2577 DEFSYM (Qgnutls_e_again, "gnutls-e-again");
2578 Fput (Qgnutls_e_again, Qgnutls_code,
2579 make_number (GNUTLS_E_AGAIN));
2581 DEFSYM (Qgnutls_e_invalid_session, "gnutls-e-invalid-session");
2582 Fput (Qgnutls_e_invalid_session, Qgnutls_code,
2583 make_number (GNUTLS_E_INVALID_SESSION));
2585 DEFSYM (Qgnutls_e_not_ready_for_handshake, "gnutls-e-not-ready-for-handshake");
2586 Fput (Qgnutls_e_not_ready_for_handshake, Qgnutls_code,
2587 make_number (GNUTLS_E_APPLICATION_ERROR_MIN));
2589 defsubr (&Sgnutls_get_initstage);
2590 defsubr (&Sgnutls_asynchronous_parameters);
2591 defsubr (&Sgnutls_errorp);
2592 defsubr (&Sgnutls_error_fatalp);
2593 defsubr (&Sgnutls_error_string);
2594 defsubr (&Sgnutls_boot);
2595 defsubr (&Sgnutls_deinit);
2596 defsubr (&Sgnutls_bye);
2597 defsubr (&Sgnutls_peer_status);
2598 defsubr (&Sgnutls_peer_status_warning_describe);
2600 #ifdef HAVE_GNUTLS3
2601 defsubr (&Sgnutls_ciphers);
2602 defsubr (&Sgnutls_macs);
2603 defsubr (&Sgnutls_digests);
2604 defsubr (&Sgnutls_hash_mac);
2605 defsubr (&Sgnutls_hash_digest);
2606 defsubr (&Sgnutls_symmetric_encrypt);
2607 defsubr (&Sgnutls_symmetric_decrypt);
2608 #endif
2610 DEFVAR_INT ("gnutls-log-level", global_gnutls_log_level,
2611 doc: /* Logging level used by the GnuTLS functions.
2612 Set this larger than 0 to get debug output in the *Messages* buffer.
2613 1 is for important messages, 2 is for debug data, and higher numbers
2614 are as per the GnuTLS logging conventions. */);
2615 global_gnutls_log_level = 0;
2617 #endif /* HAVE_GNUTLS */
2619 defsubr (&Sgnutls_available_p);