* admin/gitmerge.el (gitmerge-missing):
[emacs.git] / src / gnutls.c
blob4622011bc10c4d2b9680575af19f0cafab006693
1 /* GnuTLS glue for GNU Emacs.
2 Copyright (C) 2010-2017 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 #ifdef HAVE_GNUTLS
51 # ifdef WINDOWSNT
52 # include <windows.h>
53 # include "w32.h"
54 # endif
56 static bool emacs_gnutls_handle_error (gnutls_session_t, int);
58 static bool gnutls_global_initialized;
60 static void gnutls_log_function (int, const char *);
61 static void gnutls_log_function2 (int, const char *, const char *);
62 # ifdef HAVE_GNUTLS3
63 static void gnutls_audit_log_function (gnutls_session_t, const char *);
64 # endif
66 enum extra_peer_verification
68 CERTIFICATE_NOT_MATCHING = 2
72 # ifdef WINDOWSNT
74 DEF_DLL_FN (gnutls_alert_description_t, gnutls_alert_get,
75 (gnutls_session_t));
76 DEF_DLL_FN (const char *, gnutls_alert_get_name,
77 (gnutls_alert_description_t));
78 DEF_DLL_FN (int, gnutls_anon_allocate_client_credentials,
79 (gnutls_anon_client_credentials_t *));
80 DEF_DLL_FN (void, gnutls_anon_free_client_credentials,
81 (gnutls_anon_client_credentials_t));
82 DEF_DLL_FN (int, gnutls_bye, (gnutls_session_t, gnutls_close_request_t));
83 DEF_DLL_FN (int, gnutls_certificate_allocate_credentials,
84 (gnutls_certificate_credentials_t *));
85 DEF_DLL_FN (void, gnutls_certificate_free_credentials,
86 (gnutls_certificate_credentials_t));
87 DEF_DLL_FN (const gnutls_datum_t *, gnutls_certificate_get_peers,
88 (gnutls_session_t, unsigned int *));
89 DEF_DLL_FN (void, gnutls_certificate_set_verify_flags,
90 (gnutls_certificate_credentials_t, unsigned int));
91 DEF_DLL_FN (int, gnutls_certificate_set_x509_crl_file,
92 (gnutls_certificate_credentials_t, const char *,
93 gnutls_x509_crt_fmt_t));
94 DEF_DLL_FN (int, gnutls_certificate_set_x509_key_file,
95 (gnutls_certificate_credentials_t, const char *, const char *,
96 gnutls_x509_crt_fmt_t));
97 # ifdef HAVE_GNUTLS_X509_SYSTEM_TRUST
98 DEF_DLL_FN (int, gnutls_certificate_set_x509_system_trust,
99 (gnutls_certificate_credentials_t));
100 # endif
101 DEF_DLL_FN (int, gnutls_certificate_set_x509_trust_file,
102 (gnutls_certificate_credentials_t, const char *,
103 gnutls_x509_crt_fmt_t));
104 DEF_DLL_FN (gnutls_certificate_type_t, gnutls_certificate_type_get,
105 (gnutls_session_t));
106 DEF_DLL_FN (int, gnutls_certificate_verify_peers2,
107 (gnutls_session_t, unsigned int *));
108 DEF_DLL_FN (int, gnutls_credentials_set,
109 (gnutls_session_t, gnutls_credentials_type_t, void *));
110 DEF_DLL_FN (void, gnutls_deinit, (gnutls_session_t));
111 DEF_DLL_FN (void, gnutls_dh_set_prime_bits,
112 (gnutls_session_t, unsigned int));
113 DEF_DLL_FN (int, gnutls_dh_get_prime_bits, (gnutls_session_t));
114 DEF_DLL_FN (int, gnutls_error_is_fatal, (int));
115 DEF_DLL_FN (int, gnutls_global_init, (void));
116 DEF_DLL_FN (void, gnutls_global_set_log_function, (gnutls_log_func));
117 # ifdef HAVE_GNUTLS3
118 DEF_DLL_FN (void, gnutls_global_set_audit_log_function, (gnutls_audit_log_func));
119 # endif
120 DEF_DLL_FN (void, gnutls_global_set_log_level, (int));
121 DEF_DLL_FN (int, gnutls_handshake, (gnutls_session_t));
122 DEF_DLL_FN (int, gnutls_init, (gnutls_session_t *, unsigned int));
123 DEF_DLL_FN (int, gnutls_priority_set_direct,
124 (gnutls_session_t, const char *, const char **));
125 DEF_DLL_FN (size_t, gnutls_record_check_pending, (gnutls_session_t));
126 DEF_DLL_FN (ssize_t, gnutls_record_recv, (gnutls_session_t, void *, size_t));
127 DEF_DLL_FN (ssize_t, gnutls_record_send,
128 (gnutls_session_t, const void *, size_t));
129 DEF_DLL_FN (const char *, gnutls_strerror, (int));
130 DEF_DLL_FN (void, gnutls_transport_set_errno, (gnutls_session_t, int));
131 DEF_DLL_FN (void, gnutls_transport_set_ptr2,
132 (gnutls_session_t, gnutls_transport_ptr_t,
133 gnutls_transport_ptr_t));
134 DEF_DLL_FN (void, gnutls_transport_set_pull_function,
135 (gnutls_session_t, gnutls_pull_func));
136 DEF_DLL_FN (void, gnutls_transport_set_push_function,
137 (gnutls_session_t, gnutls_push_func));
138 DEF_DLL_FN (int, gnutls_x509_crt_check_hostname,
139 (gnutls_x509_crt_t, const char *));
140 DEF_DLL_FN (int, gnutls_x509_crt_check_issuer,
141 (gnutls_x509_crt_t, gnutls_x509_crt_t));
142 DEF_DLL_FN (void, gnutls_x509_crt_deinit, (gnutls_x509_crt_t));
143 DEF_DLL_FN (int, gnutls_x509_crt_import,
144 (gnutls_x509_crt_t, const gnutls_datum_t *,
145 gnutls_x509_crt_fmt_t));
146 DEF_DLL_FN (int, gnutls_x509_crt_init, (gnutls_x509_crt_t *));
147 DEF_DLL_FN (int, gnutls_x509_crt_get_fingerprint,
148 (gnutls_x509_crt_t,
149 gnutls_digest_algorithm_t, void *, size_t *));
150 DEF_DLL_FN (int, gnutls_x509_crt_get_version,
151 (gnutls_x509_crt_t));
152 DEF_DLL_FN (int, gnutls_x509_crt_get_serial,
153 (gnutls_x509_crt_t, void *, size_t *));
154 DEF_DLL_FN (int, gnutls_x509_crt_get_issuer_dn,
155 (gnutls_x509_crt_t, char *, size_t *));
156 DEF_DLL_FN (time_t, gnutls_x509_crt_get_activation_time,
157 (gnutls_x509_crt_t));
158 DEF_DLL_FN (time_t, gnutls_x509_crt_get_expiration_time,
159 (gnutls_x509_crt_t));
160 DEF_DLL_FN (int, gnutls_x509_crt_get_dn,
161 (gnutls_x509_crt_t, char *, size_t *));
162 DEF_DLL_FN (int, gnutls_x509_crt_get_pk_algorithm,
163 (gnutls_x509_crt_t, unsigned int *));
164 DEF_DLL_FN (const char *, gnutls_pk_algorithm_get_name,
165 (gnutls_pk_algorithm_t));
166 DEF_DLL_FN (int, gnutls_pk_bits_to_sec_param,
167 (gnutls_pk_algorithm_t, unsigned int));
168 DEF_DLL_FN (int, gnutls_x509_crt_get_issuer_unique_id,
169 (gnutls_x509_crt_t, char *, size_t *));
170 DEF_DLL_FN (int, gnutls_x509_crt_get_subject_unique_id,
171 (gnutls_x509_crt_t, char *, size_t *));
172 DEF_DLL_FN (int, gnutls_x509_crt_get_signature_algorithm,
173 (gnutls_x509_crt_t));
174 DEF_DLL_FN (int, gnutls_x509_crt_get_key_id,
175 (gnutls_x509_crt_t, unsigned int, unsigned char *, size_t *_size));
176 DEF_DLL_FN (const char *, gnutls_sec_param_get_name, (gnutls_sec_param_t));
177 DEF_DLL_FN (const char *, gnutls_sign_get_name, (gnutls_sign_algorithm_t));
178 DEF_DLL_FN (int, gnutls_server_name_set,
179 (gnutls_session_t, gnutls_server_name_type_t,
180 const void *, size_t));
181 DEF_DLL_FN (gnutls_kx_algorithm_t, gnutls_kx_get, (gnutls_session_t));
182 DEF_DLL_FN (const char *, gnutls_kx_get_name, (gnutls_kx_algorithm_t));
183 DEF_DLL_FN (gnutls_protocol_t, gnutls_protocol_get_version,
184 (gnutls_session_t));
185 DEF_DLL_FN (const char *, gnutls_protocol_get_name, (gnutls_protocol_t));
186 DEF_DLL_FN (gnutls_cipher_algorithm_t, gnutls_cipher_get,
187 (gnutls_session_t));
188 DEF_DLL_FN (const char *, gnutls_cipher_get_name,
189 (gnutls_cipher_algorithm_t));
190 DEF_DLL_FN (gnutls_mac_algorithm_t, gnutls_mac_get, (gnutls_session_t));
191 DEF_DLL_FN (const char *, gnutls_mac_get_name, (gnutls_mac_algorithm_t));
193 # ifdef HAVE_GNUTLS3
194 DEF_DLL_FN (int, gnutls_rnd, (gnutls_rnd_level_t, void *, size_t));
195 DEF_DLL_FN (const gnutls_mac_algorithm_t *, gnutls_mac_list, (void));
196 # ifdef HAVE_GNUTLS_MAC_GET_NONCE_SIZE
197 DEF_DLL_FN (size_t, gnutls_mac_get_nonce_size, (gnutls_mac_algorithm_t));
198 # endif
199 DEF_DLL_FN (size_t, gnutls_mac_get_key_size, (gnutls_mac_algorithm_t));
200 DEF_DLL_FN (const gnutls_digest_algorithm_t *, gnutls_digest_list, (void));
201 DEF_DLL_FN (const char *, gnutls_digest_get_name, (gnutls_digest_algorithm_t));
202 DEF_DLL_FN (gnutls_cipher_algorithm_t *, gnutls_cipher_list, (void));
203 DEF_DLL_FN (int, gnutls_cipher_get_iv_size, (gnutls_cipher_algorithm_t));
204 DEF_DLL_FN (size_t, gnutls_cipher_get_key_size, (gnutls_cipher_algorithm_t));
205 DEF_DLL_FN (int, gnutls_cipher_get_block_size, (gnutls_cipher_algorithm_t));
206 DEF_DLL_FN (int, gnutls_cipher_get_tag_size, (gnutls_cipher_algorithm_t));
207 DEF_DLL_FN (int, gnutls_cipher_init,
208 (gnutls_cipher_hd_t *, gnutls_cipher_algorithm_t,
209 const gnutls_datum_t *, const gnutls_datum_t *));
210 DEF_DLL_FN (void, gnutls_cipher_set_iv, (gnutls_cipher_hd_t, void *, size_t));
211 DEF_DLL_FN (int, gnutls_cipher_encrypt2,
212 (gnutls_cipher_hd_t, const void *, size_t, void *, size_t));
213 DEF_DLL_FN (void, gnutls_cipher_deinit, (gnutls_cipher_hd_t));
214 DEF_DLL_FN (int, gnutls_cipher_decrypt2,
215 (gnutls_cipher_hd_t, const void *, size_t, void *, size_t));
216 # ifdef HAVE_GNUTLS_AEAD
217 DEF_DLL_FN (int, gnutls_aead_cipher_init,
218 (gnutls_aead_cipher_hd_t *, gnutls_cipher_algorithm_t,
219 const gnutls_datum_t *));
220 DEF_DLL_FN (void, gnutls_aead_cipher_deinit, (gnutls_aead_cipher_hd_t));
221 DEF_DLL_FN (int, gnutls_aead_cipher_encrypt,
222 (gnutls_aead_cipher_hd_t, const void *, size_t, const void *,
223 size_t, size_t, const void *, size_t, void *, size_t *));
224 DEF_DLL_FN (int, gnutls_aead_cipher_decrypt,
225 (gnutls_aead_cipher_hd_t, const void *, size_t, const void *,
226 size_t, size_t, const void *, size_t, void *, size_t *));
227 # endif
228 DEF_DLL_FN (int, gnutls_hmac_init,
229 (gnutls_hmac_hd_t *, gnutls_mac_algorithm_t, const void *, size_t));
230 DEF_DLL_FN (int, gnutls_hmac_get_len, (gnutls_mac_algorithm_t));
231 DEF_DLL_FN (int, gnutls_hmac, (gnutls_hmac_hd_t, const void *, size_t));
232 DEF_DLL_FN (void, gnutls_hmac_deinit, (gnutls_hmac_hd_t, void *));
233 DEF_DLL_FN (void, gnutls_hmac_output, (gnutls_hmac_hd_t, void *));
234 DEF_DLL_FN (int, gnutls_hash_init,
235 (gnutls_hash_hd_t *, gnutls_digest_algorithm_t));
236 DEF_DLL_FN (int, gnutls_hash_get_len, (gnutls_digest_algorithm_t));
237 DEF_DLL_FN (int, gnutls_hash, (gnutls_hash_hd_t, const void *, size_t));
238 DEF_DLL_FN (void, gnutls_hash_deinit, (gnutls_hash_hd_t, void *));
239 DEF_DLL_FN (void, gnutls_hash_output, (gnutls_hash_hd_t, void *));
240 # endif /* HAVE_GNUTLS3 */
243 static bool
244 init_gnutls_functions (void)
246 HMODULE library;
247 int max_log_level = 1;
249 if (!(library = w32_delayed_load (Qgnutls)))
251 GNUTLS_LOG (1, max_log_level, "GnuTLS library not found");
252 return 0;
255 LOAD_DLL_FN (library, gnutls_alert_get);
256 LOAD_DLL_FN (library, gnutls_alert_get_name);
257 LOAD_DLL_FN (library, gnutls_anon_allocate_client_credentials);
258 LOAD_DLL_FN (library, gnutls_anon_free_client_credentials);
259 LOAD_DLL_FN (library, gnutls_bye);
260 LOAD_DLL_FN (library, gnutls_certificate_allocate_credentials);
261 LOAD_DLL_FN (library, gnutls_certificate_free_credentials);
262 LOAD_DLL_FN (library, gnutls_certificate_get_peers);
263 LOAD_DLL_FN (library, gnutls_certificate_set_verify_flags);
264 LOAD_DLL_FN (library, gnutls_certificate_set_x509_crl_file);
265 LOAD_DLL_FN (library, gnutls_certificate_set_x509_key_file);
266 # ifdef HAVE_GNUTLS_X509_SYSTEM_TRUST
267 LOAD_DLL_FN (library, gnutls_certificate_set_x509_system_trust);
268 # endif
269 LOAD_DLL_FN (library, gnutls_certificate_set_x509_trust_file);
270 LOAD_DLL_FN (library, gnutls_certificate_type_get);
271 LOAD_DLL_FN (library, gnutls_certificate_verify_peers2);
272 LOAD_DLL_FN (library, gnutls_credentials_set);
273 LOAD_DLL_FN (library, gnutls_deinit);
274 LOAD_DLL_FN (library, gnutls_dh_set_prime_bits);
275 LOAD_DLL_FN (library, gnutls_dh_get_prime_bits);
276 LOAD_DLL_FN (library, gnutls_error_is_fatal);
277 LOAD_DLL_FN (library, gnutls_global_init);
278 LOAD_DLL_FN (library, gnutls_global_set_log_function);
279 # ifdef HAVE_GNUTLS3
280 LOAD_DLL_FN (library, gnutls_global_set_audit_log_function);
281 # endif
282 LOAD_DLL_FN (library, gnutls_global_set_log_level);
283 LOAD_DLL_FN (library, gnutls_handshake);
284 LOAD_DLL_FN (library, gnutls_init);
285 LOAD_DLL_FN (library, gnutls_priority_set_direct);
286 LOAD_DLL_FN (library, gnutls_record_check_pending);
287 LOAD_DLL_FN (library, gnutls_record_recv);
288 LOAD_DLL_FN (library, gnutls_record_send);
289 LOAD_DLL_FN (library, gnutls_strerror);
290 LOAD_DLL_FN (library, gnutls_transport_set_errno);
291 LOAD_DLL_FN (library, gnutls_transport_set_ptr2);
292 LOAD_DLL_FN (library, gnutls_transport_set_pull_function);
293 LOAD_DLL_FN (library, gnutls_transport_set_push_function);
294 LOAD_DLL_FN (library, gnutls_x509_crt_check_hostname);
295 LOAD_DLL_FN (library, gnutls_x509_crt_check_issuer);
296 LOAD_DLL_FN (library, gnutls_x509_crt_deinit);
297 LOAD_DLL_FN (library, gnutls_x509_crt_import);
298 LOAD_DLL_FN (library, gnutls_x509_crt_init);
299 LOAD_DLL_FN (library, gnutls_x509_crt_get_fingerprint);
300 LOAD_DLL_FN (library, gnutls_x509_crt_get_version);
301 LOAD_DLL_FN (library, gnutls_x509_crt_get_serial);
302 LOAD_DLL_FN (library, gnutls_x509_crt_get_issuer_dn);
303 LOAD_DLL_FN (library, gnutls_x509_crt_get_activation_time);
304 LOAD_DLL_FN (library, gnutls_x509_crt_get_expiration_time);
305 LOAD_DLL_FN (library, gnutls_x509_crt_get_dn);
306 LOAD_DLL_FN (library, gnutls_x509_crt_get_pk_algorithm);
307 LOAD_DLL_FN (library, gnutls_pk_algorithm_get_name);
308 LOAD_DLL_FN (library, gnutls_pk_bits_to_sec_param);
309 LOAD_DLL_FN (library, gnutls_x509_crt_get_issuer_unique_id);
310 LOAD_DLL_FN (library, gnutls_x509_crt_get_subject_unique_id);
311 LOAD_DLL_FN (library, gnutls_x509_crt_get_signature_algorithm);
312 LOAD_DLL_FN (library, gnutls_x509_crt_get_key_id);
313 LOAD_DLL_FN (library, gnutls_sec_param_get_name);
314 LOAD_DLL_FN (library, gnutls_sign_get_name);
315 LOAD_DLL_FN (library, gnutls_server_name_set);
316 LOAD_DLL_FN (library, gnutls_kx_get);
317 LOAD_DLL_FN (library, gnutls_kx_get_name);
318 LOAD_DLL_FN (library, gnutls_protocol_get_version);
319 LOAD_DLL_FN (library, gnutls_protocol_get_name);
320 LOAD_DLL_FN (library, gnutls_cipher_get);
321 LOAD_DLL_FN (library, gnutls_cipher_get_name);
322 LOAD_DLL_FN (library, gnutls_mac_get);
323 LOAD_DLL_FN (library, gnutls_mac_get_name);
324 # ifdef HAVE_GNUTLS3
325 LOAD_DLL_FN (library, gnutls_rnd);
326 LOAD_DLL_FN (library, gnutls_mac_list);
327 # ifdef HAVE_GNUTLS_MAC_GET_NONCE_SIZE
328 LOAD_DLL_FN (library, gnutls_mac_get_nonce_size);
329 # endif
330 LOAD_DLL_FN (library, gnutls_mac_get_key_size);
331 LOAD_DLL_FN (library, gnutls_digest_list);
332 LOAD_DLL_FN (library, gnutls_digest_get_name);
333 LOAD_DLL_FN (library, gnutls_cipher_list);
334 LOAD_DLL_FN (library, gnutls_cipher_get_iv_size);
335 LOAD_DLL_FN (library, gnutls_cipher_get_key_size);
336 LOAD_DLL_FN (library, gnutls_cipher_get_block_size);
337 LOAD_DLL_FN (library, gnutls_cipher_get_tag_size);
338 LOAD_DLL_FN (library, gnutls_cipher_init);
339 LOAD_DLL_FN (library, gnutls_cipher_set_iv);
340 LOAD_DLL_FN (library, gnutls_cipher_encrypt2);
341 LOAD_DLL_FN (library, gnutls_cipher_deinit);
342 LOAD_DLL_FN (library, gnutls_cipher_decrypt2);
343 # ifdef HAVE_GNUTLS_AEAD
344 LOAD_DLL_FN (library, gnutls_aead_cipher_init);
345 LOAD_DLL_FN (library, gnutls_aead_cipher_deinit);
346 LOAD_DLL_FN (library, gnutls_aead_cipher_encrypt);
347 LOAD_DLL_FN (library, gnutls_aead_cipher_decrypt);
348 # endif
349 LOAD_DLL_FN (library, gnutls_hmac_init);
350 LOAD_DLL_FN (library, gnutls_hmac_get_len);
351 LOAD_DLL_FN (library, gnutls_hmac);
352 LOAD_DLL_FN (library, gnutls_hmac_deinit);
353 LOAD_DLL_FN (library, gnutls_hmac_output);
354 LOAD_DLL_FN (library, gnutls_hash_init);
355 LOAD_DLL_FN (library, gnutls_hash_get_len);
356 LOAD_DLL_FN (library, gnutls_hash);
357 LOAD_DLL_FN (library, gnutls_hash_deinit);
358 LOAD_DLL_FN (library, gnutls_hash_output);
359 # endif /* HAVE_GNUTLS3 */
361 max_log_level = global_gnutls_log_level;
364 Lisp_Object name = CAR_SAFE (Fget (Qgnutls, QCloaded_from));
365 GNUTLS_LOG2 (1, max_log_level, "GnuTLS library loaded:",
366 STRINGP (name) ? (const char *) SDATA (name) : "unknown");
369 return 1;
372 # define gnutls_alert_get fn_gnutls_alert_get
373 # define gnutls_alert_get_name fn_gnutls_alert_get_name
374 # define gnutls_anon_allocate_client_credentials fn_gnutls_anon_allocate_client_credentials
375 # define gnutls_anon_free_client_credentials fn_gnutls_anon_free_client_credentials
376 # define gnutls_bye fn_gnutls_bye
377 # define gnutls_certificate_allocate_credentials fn_gnutls_certificate_allocate_credentials
378 # define gnutls_certificate_free_credentials fn_gnutls_certificate_free_credentials
379 # define gnutls_certificate_get_peers fn_gnutls_certificate_get_peers
380 # define gnutls_certificate_set_verify_flags fn_gnutls_certificate_set_verify_flags
381 # define gnutls_certificate_set_x509_crl_file fn_gnutls_certificate_set_x509_crl_file
382 # define gnutls_certificate_set_x509_key_file fn_gnutls_certificate_set_x509_key_file
383 # define gnutls_certificate_set_x509_system_trust fn_gnutls_certificate_set_x509_system_trust
384 # define gnutls_certificate_set_x509_trust_file fn_gnutls_certificate_set_x509_trust_file
385 # define gnutls_certificate_type_get fn_gnutls_certificate_type_get
386 # define gnutls_certificate_verify_peers2 fn_gnutls_certificate_verify_peers2
387 # define gnutls_cipher_get fn_gnutls_cipher_get
388 # define gnutls_cipher_get_name fn_gnutls_cipher_get_name
389 # define gnutls_credentials_set fn_gnutls_credentials_set
390 # define gnutls_deinit fn_gnutls_deinit
391 # define gnutls_dh_get_prime_bits fn_gnutls_dh_get_prime_bits
392 # define gnutls_dh_set_prime_bits fn_gnutls_dh_set_prime_bits
393 # define gnutls_error_is_fatal fn_gnutls_error_is_fatal
394 # define gnutls_global_init fn_gnutls_global_init
395 # define gnutls_global_set_audit_log_function fn_gnutls_global_set_audit_log_function
396 # define gnutls_global_set_log_function fn_gnutls_global_set_log_function
397 # define gnutls_global_set_log_level fn_gnutls_global_set_log_level
398 # define gnutls_handshake fn_gnutls_handshake
399 # define gnutls_init fn_gnutls_init
400 # define gnutls_kx_get fn_gnutls_kx_get
401 # define gnutls_kx_get_name fn_gnutls_kx_get_name
402 # define gnutls_mac_get fn_gnutls_mac_get
403 # define gnutls_mac_get_name fn_gnutls_mac_get_name
404 # define gnutls_pk_algorithm_get_name fn_gnutls_pk_algorithm_get_name
405 # define gnutls_pk_bits_to_sec_param fn_gnutls_pk_bits_to_sec_param
406 # define gnutls_priority_set_direct fn_gnutls_priority_set_direct
407 # define gnutls_protocol_get_name fn_gnutls_protocol_get_name
408 # define gnutls_protocol_get_version fn_gnutls_protocol_get_version
409 # define gnutls_record_check_pending fn_gnutls_record_check_pending
410 # define gnutls_record_recv fn_gnutls_record_recv
411 # define gnutls_record_send fn_gnutls_record_send
412 # define gnutls_sec_param_get_name fn_gnutls_sec_param_get_name
413 # define gnutls_server_name_set fn_gnutls_server_name_set
414 # define gnutls_sign_get_name fn_gnutls_sign_get_name
415 # define gnutls_strerror fn_gnutls_strerror
416 # define gnutls_transport_set_errno fn_gnutls_transport_set_errno
417 # define gnutls_transport_set_ptr2 fn_gnutls_transport_set_ptr2
418 # define gnutls_transport_set_pull_function fn_gnutls_transport_set_pull_function
419 # define gnutls_transport_set_push_function fn_gnutls_transport_set_push_function
420 # define gnutls_x509_crt_check_hostname fn_gnutls_x509_crt_check_hostname
421 # define gnutls_x509_crt_check_issuer fn_gnutls_x509_crt_check_issuer
422 # define gnutls_x509_crt_deinit fn_gnutls_x509_crt_deinit
423 # define gnutls_x509_crt_get_activation_time fn_gnutls_x509_crt_get_activation_time
424 # define gnutls_x509_crt_get_dn fn_gnutls_x509_crt_get_dn
425 # define gnutls_x509_crt_get_expiration_time fn_gnutls_x509_crt_get_expiration_time
426 # define gnutls_x509_crt_get_fingerprint fn_gnutls_x509_crt_get_fingerprint
427 # define gnutls_x509_crt_get_issuer_dn fn_gnutls_x509_crt_get_issuer_dn
428 # define gnutls_x509_crt_get_issuer_unique_id fn_gnutls_x509_crt_get_issuer_unique_id
429 # define gnutls_x509_crt_get_key_id fn_gnutls_x509_crt_get_key_id
430 # define gnutls_x509_crt_get_pk_algorithm fn_gnutls_x509_crt_get_pk_algorithm
431 # define gnutls_x509_crt_get_serial fn_gnutls_x509_crt_get_serial
432 # define gnutls_x509_crt_get_signature_algorithm fn_gnutls_x509_crt_get_signature_algorithm
433 # define gnutls_x509_crt_get_subject_unique_id fn_gnutls_x509_crt_get_subject_unique_id
434 # define gnutls_x509_crt_get_version fn_gnutls_x509_crt_get_version
435 # define gnutls_x509_crt_import fn_gnutls_x509_crt_import
436 # define gnutls_x509_crt_init fn_gnutls_x509_crt_init
437 # ifdef HAVE_GNUTLS3
438 # define gnutls_rnd fn_gnutls_rnd
439 # define gnutls_mac_list fn_gnutls_mac_list
440 # ifdef HAVE_GNUTLS_MAC_GET_NONCE_SIZE
441 # define gnutls_mac_get_nonce_size fn_gnutls_mac_get_nonce_size
442 # endif
443 # define gnutls_mac_get_key_size fn_gnutls_mac_get_key_size
444 # define gnutls_digest_list fn_gnutls_digest_list
445 # define gnutls_digest_get_name fn_gnutls_digest_get_name
446 # define gnutls_cipher_list fn_gnutls_cipher_list
447 # define gnutls_cipher_get_iv_size fn_gnutls_cipher_get_iv_size
448 # define gnutls_cipher_get_key_size fn_gnutls_cipher_get_key_size
449 # define gnutls_cipher_get_block_size fn_gnutls_cipher_get_block_size
450 # define gnutls_cipher_get_tag_size fn_gnutls_cipher_get_tag_size
451 # define gnutls_cipher_init fn_gnutls_cipher_init
452 # define gnutls_cipher_set_iv fn_gnutls_cipher_set_iv
453 # define gnutls_cipher_encrypt2 fn_gnutls_cipher_encrypt2
454 # define gnutls_cipher_decrypt2 fn_gnutls_cipher_decrypt2
455 # define gnutls_cipher_deinit fn_gnutls_cipher_deinit
456 # ifdef HAVE_GNUTLS_AEAD
457 # define gnutls_aead_cipher_encrypt fn_gnutls_aead_cipher_encrypt
458 # define gnutls_aead_cipher_decrypt fn_gnutls_aead_cipher_decrypt
459 # define gnutls_aead_cipher_init fn_gnutls_aead_cipher_init
460 # define gnutls_aead_cipher_deinit fn_gnutls_aead_cipher_deinit
461 # endif
462 # define gnutls_hmac_init fn_gnutls_hmac_init
463 # define gnutls_hmac_get_len fn_gnutls_hmac_get_len
464 # define gnutls_hmac fn_gnutls_hmac
465 # define gnutls_hmac_deinit fn_gnutls_hmac_deinit
466 # define gnutls_hmac_output fn_gnutls_hmac_output
467 # define gnutls_hash_init fn_gnutls_hash_init
468 # define gnutls_hash_get_len fn_gnutls_hash_get_len
469 # define gnutls_hash fn_gnutls_hash
470 # define gnutls_hash_deinit fn_gnutls_hash_deinit
471 # define gnutls_hash_output fn_gnutls_hash_output
472 # endif /* HAVE_GNUTLS3 */
474 /* This wrapper is called from fns.c, which doesn't know about the
475 LOAD_DLL_FN stuff above. */
477 w32_gnutls_rnd (gnutls_rnd_level_t level, void *data, size_t len)
479 return gnutls_rnd (level, data, len);
482 # endif /* WINDOWSNT */
485 /* Report memory exhaustion if ERR is an out-of-memory indication. */
486 static void
487 check_memory_full (int err)
489 /* When GnuTLS exhausts memory, it doesn't say how much memory it
490 asked for, so tell the Emacs allocator that GnuTLS asked for no
491 bytes. This isn't accurate, but it's good enough. */
492 if (err == GNUTLS_E_MEMORY_ERROR)
493 memory_full (0);
496 # ifdef HAVE_GNUTLS3
497 /* Log a simple audit message. */
498 static void
499 gnutls_audit_log_function (gnutls_session_t session, const char *string)
501 if (global_gnutls_log_level >= 1)
503 message ("gnutls.c: [audit] %s", string);
506 # endif
508 /* Log a simple message. */
509 static void
510 gnutls_log_function (int level, const char *string)
512 message ("gnutls.c: [%d] %s", level, string);
515 /* Log a message and a string. */
516 static void
517 gnutls_log_function2 (int level, const char *string, const char *extra)
519 message ("gnutls.c: [%d] %s %s", level, string, extra);
523 gnutls_try_handshake (struct Lisp_Process *proc)
525 gnutls_session_t state = proc->gnutls_state;
526 int ret;
527 bool non_blocking = proc->is_non_blocking_client;
529 if (proc->gnutls_complete_negotiation_p)
530 non_blocking = false;
532 if (non_blocking)
533 proc->gnutls_p = true;
537 ret = gnutls_handshake (state);
538 emacs_gnutls_handle_error (state, ret);
539 maybe_quit ();
541 while (ret < 0
542 && gnutls_error_is_fatal (ret) == 0
543 && ! non_blocking);
545 proc->gnutls_initstage = GNUTLS_STAGE_HANDSHAKE_TRIED;
547 if (ret == GNUTLS_E_SUCCESS)
549 /* Here we're finally done. */
550 proc->gnutls_initstage = GNUTLS_STAGE_READY;
552 else
554 /* check_memory_full (gnutls_alert_send_appropriate (state, ret)); */
556 return ret;
559 # ifndef WINDOWSNT
560 static int
561 emacs_gnutls_nonblock_errno (gnutls_transport_ptr_t ptr)
563 int err = errno;
565 switch (err)
567 # ifdef _AIX
568 /* This is taken from the GnuTLS system_errno function circa 2016;
569 see <https://savannah.gnu.org/support/?107464>. */
570 case 0:
571 errno = EAGAIN;
572 /* Fall through. */
573 # endif
574 case EINPROGRESS:
575 case ENOTCONN:
576 return EAGAIN;
578 default:
579 return err;
582 # endif /* !WINDOWSNT */
584 static int
585 emacs_gnutls_handshake (struct Lisp_Process *proc)
587 gnutls_session_t state = proc->gnutls_state;
589 if (proc->gnutls_initstage < GNUTLS_STAGE_HANDSHAKE_CANDO)
590 return -1;
592 if (proc->gnutls_initstage < GNUTLS_STAGE_TRANSPORT_POINTERS_SET)
594 # ifdef WINDOWSNT
595 /* On W32 we cannot transfer socket handles between different runtime
596 libraries, so we tell GnuTLS to use our special push/pull
597 functions. */
598 gnutls_transport_set_ptr2 (state,
599 (gnutls_transport_ptr_t) proc,
600 (gnutls_transport_ptr_t) proc);
601 gnutls_transport_set_push_function (state, &emacs_gnutls_push);
602 gnutls_transport_set_pull_function (state, &emacs_gnutls_pull);
603 # else
604 /* This is how GnuTLS takes sockets: as file descriptors passed
605 in. For an Emacs process socket, infd and outfd are the
606 same but we use this two-argument version for clarity. */
607 gnutls_transport_set_ptr2 (state,
608 (void *) (intptr_t) proc->infd,
609 (void *) (intptr_t) proc->outfd);
610 if (proc->is_non_blocking_client)
611 gnutls_transport_set_errno_function (state,
612 emacs_gnutls_nonblock_errno);
613 # endif
615 proc->gnutls_initstage = GNUTLS_STAGE_TRANSPORT_POINTERS_SET;
618 return gnutls_try_handshake (proc);
621 ptrdiff_t
622 emacs_gnutls_record_check_pending (gnutls_session_t state)
624 return gnutls_record_check_pending (state);
627 # ifdef WINDOWSNT
628 void
629 emacs_gnutls_transport_set_errno (gnutls_session_t state, int err)
631 gnutls_transport_set_errno (state, err);
633 # endif
635 ptrdiff_t
636 emacs_gnutls_write (struct Lisp_Process *proc, const char *buf, ptrdiff_t nbyte)
638 ssize_t rtnval = 0;
639 ptrdiff_t bytes_written;
640 gnutls_session_t state = proc->gnutls_state;
642 if (proc->gnutls_initstage != GNUTLS_STAGE_READY)
644 errno = EAGAIN;
645 return 0;
648 bytes_written = 0;
650 while (nbyte > 0)
652 rtnval = gnutls_record_send (state, buf, nbyte);
654 if (rtnval < 0)
656 if (rtnval == GNUTLS_E_INTERRUPTED)
657 continue;
658 else
660 /* If we get GNUTLS_E_AGAIN, then set errno
661 appropriately so that send_process retries the
662 correct way instead of erroring out. */
663 if (rtnval == GNUTLS_E_AGAIN)
664 errno = EAGAIN;
665 break;
669 buf += rtnval;
670 nbyte -= rtnval;
671 bytes_written += rtnval;
674 emacs_gnutls_handle_error (state, rtnval);
675 return (bytes_written);
678 ptrdiff_t
679 emacs_gnutls_read (struct Lisp_Process *proc, char *buf, ptrdiff_t nbyte)
681 ssize_t rtnval;
682 gnutls_session_t state = proc->gnutls_state;
684 if (proc->gnutls_initstage != GNUTLS_STAGE_READY)
686 errno = EAGAIN;
687 return -1;
690 rtnval = gnutls_record_recv (state, buf, nbyte);
691 if (rtnval >= 0)
692 return rtnval;
693 else if (rtnval == GNUTLS_E_UNEXPECTED_PACKET_LENGTH)
694 /* The peer closed the connection. */
695 return 0;
696 else if (emacs_gnutls_handle_error (state, rtnval))
697 /* non-fatal error */
698 return -1;
699 else {
700 /* a fatal error occurred */
701 return 0;
705 static char const *
706 emacs_gnutls_strerror (int err)
708 char const *str = gnutls_strerror (err);
709 return str ? str : "unknown";
712 /* Report a GnuTLS error to the user.
713 Return true if the error code was successfully handled. */
714 static bool
715 emacs_gnutls_handle_error (gnutls_session_t session, int err)
717 int max_log_level = 0;
719 bool ret;
721 /* TODO: use a Lisp_Object generated by gnutls_make_error? */
722 if (err >= 0)
723 return 1;
725 check_memory_full (err);
727 max_log_level = global_gnutls_log_level;
729 /* TODO: use gnutls-error-fatalp and gnutls-error-string. */
731 char const *str = emacs_gnutls_strerror (err);
733 if (gnutls_error_is_fatal (err))
735 int level = 1;
736 /* Mostly ignore "The TLS connection was non-properly
737 terminated" message which just means that the peer closed the
738 connection. */
739 # ifdef HAVE_GNUTLS3
740 if (err == GNUTLS_E_PREMATURE_TERMINATION)
741 level = 3;
742 # endif
744 GNUTLS_LOG2 (level, max_log_level, "fatal error:", str);
745 ret = false;
747 else
749 ret = true;
751 switch (err)
753 case GNUTLS_E_AGAIN:
754 GNUTLS_LOG2 (3,
755 max_log_level,
756 "retry:",
757 str);
758 FALLTHROUGH;
759 default:
760 GNUTLS_LOG2 (1,
761 max_log_level,
762 "non-fatal error:",
763 str);
767 if (err == GNUTLS_E_WARNING_ALERT_RECEIVED
768 || err == GNUTLS_E_FATAL_ALERT_RECEIVED)
770 int alert = gnutls_alert_get (session);
771 int level = (err == GNUTLS_E_FATAL_ALERT_RECEIVED) ? 0 : 1;
772 str = gnutls_alert_get_name (alert);
773 if (!str)
774 str = "unknown";
776 GNUTLS_LOG2 (level, max_log_level, "Received alert: ", str);
778 return ret;
781 /* convert an integer error to a Lisp_Object; it will be either a
782 known symbol like `gnutls_e_interrupted' and `gnutls_e_again' or
783 simply the integer value of the error. GNUTLS_E_SUCCESS is mapped
784 to Qt. */
785 static Lisp_Object
786 gnutls_make_error (int err)
788 switch (err)
790 case GNUTLS_E_SUCCESS:
791 return Qt;
792 case GNUTLS_E_AGAIN:
793 return Qgnutls_e_again;
794 case GNUTLS_E_INTERRUPTED:
795 return Qgnutls_e_interrupted;
796 case GNUTLS_E_INVALID_SESSION:
797 return Qgnutls_e_invalid_session;
800 check_memory_full (err);
801 return make_number (err);
804 Lisp_Object
805 emacs_gnutls_deinit (Lisp_Object proc)
807 int log_level;
809 CHECK_PROCESS (proc);
811 if (! XPROCESS (proc)->gnutls_p)
812 return Qnil;
814 log_level = XPROCESS (proc)->gnutls_log_level;
816 if (XPROCESS (proc)->gnutls_x509_cred)
818 GNUTLS_LOG (2, log_level, "Deallocating x509 credentials");
819 gnutls_certificate_free_credentials (XPROCESS (proc)->gnutls_x509_cred);
820 XPROCESS (proc)->gnutls_x509_cred = NULL;
823 if (XPROCESS (proc)->gnutls_anon_cred)
825 GNUTLS_LOG (2, log_level, "Deallocating anon credentials");
826 gnutls_anon_free_client_credentials (XPROCESS (proc)->gnutls_anon_cred);
827 XPROCESS (proc)->gnutls_anon_cred = NULL;
830 if (XPROCESS (proc)->gnutls_state)
832 gnutls_deinit (XPROCESS (proc)->gnutls_state);
833 XPROCESS (proc)->gnutls_state = NULL;
834 if (GNUTLS_INITSTAGE (proc) >= GNUTLS_STAGE_INIT)
835 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_INIT - 1;
838 XPROCESS (proc)->gnutls_p = false;
839 return Qt;
842 DEFUN ("gnutls-asynchronous-parameters", Fgnutls_asynchronous_parameters,
843 Sgnutls_asynchronous_parameters, 2, 2, 0,
844 doc: /* Mark this process as being a pre-init GnuTLS process.
845 The second parameter is the list of parameters to feed to gnutls-boot
846 to finish setting up the connection. */)
847 (Lisp_Object proc, Lisp_Object params)
849 CHECK_PROCESS (proc);
851 XPROCESS (proc)->gnutls_boot_parameters = params;
852 return Qnil;
855 DEFUN ("gnutls-get-initstage", Fgnutls_get_initstage, Sgnutls_get_initstage, 1, 1, 0,
856 doc: /* Return the GnuTLS init stage of process PROC.
857 See also `gnutls-boot'. */)
858 (Lisp_Object proc)
860 CHECK_PROCESS (proc);
862 return make_number (GNUTLS_INITSTAGE (proc));
865 DEFUN ("gnutls-errorp", Fgnutls_errorp, Sgnutls_errorp, 1, 1, 0,
866 doc: /* Return t if ERROR indicates a GnuTLS problem.
867 ERROR is an integer or a symbol with an integer `gnutls-code' property.
868 usage: (gnutls-errorp ERROR) */
869 attributes: const)
870 (Lisp_Object err)
872 if (EQ (err, Qt)
873 || EQ (err, Qgnutls_e_again))
874 return Qnil;
876 return Qt;
879 DEFUN ("gnutls-error-fatalp", Fgnutls_error_fatalp, Sgnutls_error_fatalp, 1, 1, 0,
880 doc: /* Return non-nil if ERROR is fatal.
881 ERROR is an integer or a symbol with an integer `gnutls-code' property.
882 Usage: (gnutls-error-fatalp ERROR) */)
883 (Lisp_Object err)
885 Lisp_Object code;
887 if (EQ (err, Qt)) return Qnil;
889 if (SYMBOLP (err))
891 code = Fget (err, Qgnutls_code);
892 if (NUMBERP (code))
894 err = code;
896 else
898 error ("Symbol has no numeric gnutls-code property");
902 if (! TYPE_RANGED_INTEGERP (int, err))
903 error ("Not an error symbol or code");
905 if (0 == gnutls_error_is_fatal (XINT (err)))
906 return Qnil;
908 return Qt;
911 DEFUN ("gnutls-error-string", Fgnutls_error_string, Sgnutls_error_string, 1, 1, 0,
912 doc: /* Return a description of ERROR.
913 ERROR is an integer or a symbol with an integer `gnutls-code' property.
914 usage: (gnutls-error-string ERROR) */)
915 (Lisp_Object err)
917 Lisp_Object code;
919 if (EQ (err, Qt)) return build_string ("Not an error");
921 if (SYMBOLP (err))
923 code = Fget (err, Qgnutls_code);
924 if (NUMBERP (code))
926 err = code;
928 else
930 return build_string ("Symbol has no numeric gnutls-code property");
934 if (! TYPE_RANGED_INTEGERP (int, err))
935 return build_string ("Not an error symbol or code");
937 return build_string (emacs_gnutls_strerror (XINT (err)));
940 DEFUN ("gnutls-deinit", Fgnutls_deinit, Sgnutls_deinit, 1, 1, 0,
941 doc: /* Deallocate GnuTLS resources associated with process PROC.
942 See also `gnutls-init'. */)
943 (Lisp_Object proc)
945 return emacs_gnutls_deinit (proc);
948 static Lisp_Object
949 gnutls_hex_string (unsigned char *buf, ptrdiff_t buf_size, const char *prefix)
951 ptrdiff_t prefix_length = strlen (prefix);
952 ptrdiff_t retlen;
953 if (INT_MULTIPLY_WRAPV (buf_size, 3, &retlen)
954 || INT_ADD_WRAPV (prefix_length - (buf_size != 0), retlen, &retlen))
955 string_overflow ();
956 Lisp_Object ret = make_uninit_string (retlen);
957 char *string = SSDATA (ret);
958 strcpy (string, prefix);
960 for (ptrdiff_t i = 0; i < buf_size; i++)
961 sprintf (string + i * 3 + prefix_length,
962 i == buf_size - 1 ? "%02x" : "%02x:",
963 buf[i]);
965 return ret;
968 static Lisp_Object
969 gnutls_certificate_details (gnutls_x509_crt_t cert)
971 Lisp_Object res = Qnil;
972 int err;
973 size_t buf_size;
975 /* Version. */
977 int version = gnutls_x509_crt_get_version (cert);
978 check_memory_full (version);
979 if (version >= GNUTLS_E_SUCCESS)
980 res = nconc2 (res, list2 (intern (":version"),
981 make_number (version)));
984 /* Serial. */
985 buf_size = 0;
986 err = gnutls_x509_crt_get_serial (cert, NULL, &buf_size);
987 check_memory_full (err);
988 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER)
990 void *serial = xmalloc (buf_size);
991 err = gnutls_x509_crt_get_serial (cert, serial, &buf_size);
992 check_memory_full (err);
993 if (err >= GNUTLS_E_SUCCESS)
994 res = nconc2 (res, list2 (intern (":serial-number"),
995 gnutls_hex_string (serial, buf_size, "")));
996 xfree (serial);
999 /* Issuer. */
1000 buf_size = 0;
1001 err = gnutls_x509_crt_get_issuer_dn (cert, NULL, &buf_size);
1002 check_memory_full (err);
1003 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER)
1005 char *dn = xmalloc (buf_size);
1006 err = gnutls_x509_crt_get_issuer_dn (cert, dn, &buf_size);
1007 check_memory_full (err);
1008 if (err >= GNUTLS_E_SUCCESS)
1009 res = nconc2 (res, list2 (intern (":issuer"),
1010 make_string (dn, buf_size)));
1011 xfree (dn);
1014 /* Validity. */
1016 /* Add 1 to the buffer size, since 1900 is added to tm_year and
1017 that might add 1 to the year length. */
1018 char buf[INT_STRLEN_BOUND (int) + 1 + sizeof "-12-31"];
1019 struct tm t;
1020 time_t tim = gnutls_x509_crt_get_activation_time (cert);
1022 if (gmtime_r (&tim, &t) && strftime (buf, sizeof buf, "%Y-%m-%d", &t))
1023 res = nconc2 (res, list2 (intern (":valid-from"), build_string (buf)));
1025 tim = gnutls_x509_crt_get_expiration_time (cert);
1026 if (gmtime_r (&tim, &t) && strftime (buf, sizeof buf, "%Y-%m-%d", &t))
1027 res = nconc2 (res, list2 (intern (":valid-to"), build_string (buf)));
1030 /* Subject. */
1031 buf_size = 0;
1032 err = gnutls_x509_crt_get_dn (cert, NULL, &buf_size);
1033 check_memory_full (err);
1034 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER)
1036 char *dn = xmalloc (buf_size);
1037 err = gnutls_x509_crt_get_dn (cert, dn, &buf_size);
1038 check_memory_full (err);
1039 if (err >= GNUTLS_E_SUCCESS)
1040 res = nconc2 (res, list2 (intern (":subject"),
1041 make_string (dn, buf_size)));
1042 xfree (dn);
1045 /* SubjectPublicKeyInfo. */
1047 unsigned int bits;
1049 err = gnutls_x509_crt_get_pk_algorithm (cert, &bits);
1050 check_memory_full (err);
1051 if (err >= GNUTLS_E_SUCCESS)
1053 const char *name = gnutls_pk_algorithm_get_name (err);
1054 if (name)
1055 res = nconc2 (res, list2 (intern (":public-key-algorithm"),
1056 build_string (name)));
1058 name = gnutls_sec_param_get_name (gnutls_pk_bits_to_sec_param
1059 (err, bits));
1060 res = nconc2 (res, list2 (intern (":certificate-security-level"),
1061 build_string (name)));
1065 /* Unique IDs. */
1066 buf_size = 0;
1067 err = gnutls_x509_crt_get_issuer_unique_id (cert, NULL, &buf_size);
1068 check_memory_full (err);
1069 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER)
1071 char *buf = xmalloc (buf_size);
1072 err = gnutls_x509_crt_get_issuer_unique_id (cert, buf, &buf_size);
1073 check_memory_full (err);
1074 if (err >= GNUTLS_E_SUCCESS)
1075 res = nconc2 (res, list2 (intern (":issuer-unique-id"),
1076 make_string (buf, buf_size)));
1077 xfree (buf);
1080 buf_size = 0;
1081 err = gnutls_x509_crt_get_subject_unique_id (cert, NULL, &buf_size);
1082 check_memory_full (err);
1083 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER)
1085 char *buf = xmalloc (buf_size);
1086 err = gnutls_x509_crt_get_subject_unique_id (cert, buf, &buf_size);
1087 check_memory_full (err);
1088 if (err >= GNUTLS_E_SUCCESS)
1089 res = nconc2 (res, list2 (intern (":subject-unique-id"),
1090 make_string (buf, buf_size)));
1091 xfree (buf);
1094 /* Signature. */
1095 err = gnutls_x509_crt_get_signature_algorithm (cert);
1096 check_memory_full (err);
1097 if (err >= GNUTLS_E_SUCCESS)
1099 const char *name = gnutls_sign_get_name (err);
1100 if (name)
1101 res = nconc2 (res, list2 (intern (":signature-algorithm"),
1102 build_string (name)));
1105 /* Public key ID. */
1106 buf_size = 0;
1107 err = gnutls_x509_crt_get_key_id (cert, 0, NULL, &buf_size);
1108 check_memory_full (err);
1109 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER)
1111 void *buf = xmalloc (buf_size);
1112 err = gnutls_x509_crt_get_key_id (cert, 0, buf, &buf_size);
1113 check_memory_full (err);
1114 if (err >= GNUTLS_E_SUCCESS)
1115 res = nconc2 (res, list2 (intern (":public-key-id"),
1116 gnutls_hex_string (buf, buf_size, "sha1:")));
1117 xfree (buf);
1120 /* Certificate fingerprint. */
1121 buf_size = 0;
1122 err = gnutls_x509_crt_get_fingerprint (cert, GNUTLS_DIG_SHA1,
1123 NULL, &buf_size);
1124 check_memory_full (err);
1125 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER)
1127 void *buf = xmalloc (buf_size);
1128 err = gnutls_x509_crt_get_fingerprint (cert, GNUTLS_DIG_SHA1,
1129 buf, &buf_size);
1130 check_memory_full (err);
1131 if (err >= GNUTLS_E_SUCCESS)
1132 res = nconc2 (res, list2 (intern (":certificate-id"),
1133 gnutls_hex_string (buf, buf_size, "sha1:")));
1134 xfree (buf);
1137 return res;
1140 DEFUN ("gnutls-peer-status-warning-describe", Fgnutls_peer_status_warning_describe, Sgnutls_peer_status_warning_describe, 1, 1, 0,
1141 doc: /* Describe the warning of a GnuTLS peer status from `gnutls-peer-status'. */)
1142 (Lisp_Object status_symbol)
1144 CHECK_SYMBOL (status_symbol);
1146 if (EQ (status_symbol, intern (":invalid")))
1147 return build_string ("certificate could not be verified");
1149 if (EQ (status_symbol, intern (":revoked")))
1150 return build_string ("certificate was revoked (CRL)");
1152 if (EQ (status_symbol, intern (":self-signed")))
1153 return build_string ("certificate signer was not found (self-signed)");
1155 if (EQ (status_symbol, intern (":unknown-ca")))
1156 return build_string ("the certificate was signed by an unknown "
1157 "and therefore untrusted authority");
1159 if (EQ (status_symbol, intern (":not-ca")))
1160 return build_string ("certificate signer is not a CA");
1162 if (EQ (status_symbol, intern (":insecure")))
1163 return build_string ("certificate was signed with an insecure algorithm");
1165 if (EQ (status_symbol, intern (":not-activated")))
1166 return build_string ("certificate is not yet activated");
1168 if (EQ (status_symbol, intern (":expired")))
1169 return build_string ("certificate has expired");
1171 if (EQ (status_symbol, intern (":no-host-match")))
1172 return build_string ("certificate host does not match hostname");
1174 return Qnil;
1177 DEFUN ("gnutls-peer-status", Fgnutls_peer_status, Sgnutls_peer_status, 1, 1, 0,
1178 doc: /* Describe a GnuTLS PROC peer certificate and any warnings about it.
1179 The return value is a property list with top-level keys :warnings and
1180 :certificate. The :warnings entry is a list of symbols you can describe with
1181 `gnutls-peer-status-warning-describe'. */)
1182 (Lisp_Object proc)
1184 Lisp_Object warnings = Qnil, result = Qnil;
1185 unsigned int verification;
1186 gnutls_session_t state;
1188 CHECK_PROCESS (proc);
1190 if (GNUTLS_INITSTAGE (proc) != GNUTLS_STAGE_READY)
1191 return Qnil;
1193 /* Then collect any warnings already computed by the handshake. */
1194 verification = XPROCESS (proc)->gnutls_peer_verification;
1196 if (verification & GNUTLS_CERT_INVALID)
1197 warnings = Fcons (intern (":invalid"), warnings);
1199 if (verification & GNUTLS_CERT_REVOKED)
1200 warnings = Fcons (intern (":revoked"), warnings);
1202 if (verification & GNUTLS_CERT_SIGNER_NOT_FOUND)
1203 warnings = Fcons (intern (":unknown-ca"), warnings);
1205 if (verification & GNUTLS_CERT_SIGNER_NOT_CA)
1206 warnings = Fcons (intern (":not-ca"), warnings);
1208 if (verification & GNUTLS_CERT_INSECURE_ALGORITHM)
1209 warnings = Fcons (intern (":insecure"), warnings);
1211 if (verification & GNUTLS_CERT_NOT_ACTIVATED)
1212 warnings = Fcons (intern (":not-activated"), warnings);
1214 if (verification & GNUTLS_CERT_EXPIRED)
1215 warnings = Fcons (intern (":expired"), warnings);
1217 if (XPROCESS (proc)->gnutls_extra_peer_verification &
1218 CERTIFICATE_NOT_MATCHING)
1219 warnings = Fcons (intern (":no-host-match"), warnings);
1221 /* This could get called in the INIT stage, when the certificate is
1222 not yet set. */
1223 if (XPROCESS (proc)->gnutls_certificate != NULL &&
1224 gnutls_x509_crt_check_issuer(XPROCESS (proc)->gnutls_certificate,
1225 XPROCESS (proc)->gnutls_certificate))
1226 warnings = Fcons (intern (":self-signed"), warnings);
1228 if (!NILP (warnings))
1229 result = list2 (intern (":warnings"), warnings);
1231 /* This could get called in the INIT stage, when the certificate is
1232 not yet set. */
1233 if (XPROCESS (proc)->gnutls_certificate != NULL)
1234 result = nconc2 (result, list2
1235 (intern (":certificate"),
1236 gnutls_certificate_details (XPROCESS (proc)->gnutls_certificate)));
1238 state = XPROCESS (proc)->gnutls_state;
1240 /* Diffie-Hellman prime bits. */
1242 int bits = gnutls_dh_get_prime_bits (state);
1243 check_memory_full (bits);
1244 if (bits > 0)
1245 result = nconc2 (result, list2 (intern (":diffie-hellman-prime-bits"),
1246 make_number (bits)));
1249 /* Key exchange. */
1250 result = nconc2
1251 (result, list2 (intern (":key-exchange"),
1252 build_string (gnutls_kx_get_name
1253 (gnutls_kx_get (state)))));
1255 /* Protocol name. */
1256 result = nconc2
1257 (result, list2 (intern (":protocol"),
1258 build_string (gnutls_protocol_get_name
1259 (gnutls_protocol_get_version (state)))));
1261 /* Cipher name. */
1262 result = nconc2
1263 (result, list2 (intern (":cipher"),
1264 build_string (gnutls_cipher_get_name
1265 (gnutls_cipher_get (state)))));
1267 /* MAC name. */
1268 result = nconc2
1269 (result, list2 (intern (":mac"),
1270 build_string (gnutls_mac_get_name
1271 (gnutls_mac_get (state)))));
1274 return result;
1277 /* Initialize global GnuTLS state to defaults.
1278 Call `gnutls-global-deinit' when GnuTLS usage is no longer needed.
1279 Return zero on success. */
1280 Lisp_Object
1281 emacs_gnutls_global_init (void)
1283 int ret = GNUTLS_E_SUCCESS;
1285 if (!gnutls_global_initialized)
1287 ret = gnutls_global_init ();
1288 if (ret == GNUTLS_E_SUCCESS)
1289 gnutls_global_initialized = 1;
1292 return gnutls_make_error (ret);
1295 static bool
1296 gnutls_ip_address_p (char *string)
1298 char c;
1300 while ((c = *string++) != 0)
1301 if (! ((c == '.' || c == ':' || (c >= '0' && c <= '9'))))
1302 return false;
1304 return true;
1307 # if 0
1308 /* Deinitialize global GnuTLS state.
1309 See also `gnutls-global-init'. */
1310 static Lisp_Object
1311 emacs_gnutls_global_deinit (void)
1313 if (gnutls_global_initialized)
1314 gnutls_global_deinit ();
1316 gnutls_global_initialized = 0;
1318 return gnutls_make_error (GNUTLS_E_SUCCESS);
1320 # endif
1322 static void ATTRIBUTE_FORMAT_PRINTF (2, 3)
1323 boot_error (struct Lisp_Process *p, const char *m, ...)
1325 va_list ap;
1326 va_start (ap, m);
1327 if (p->is_non_blocking_client)
1328 pset_status (p, list2 (Qfailed, vformat_string (m, ap)));
1329 else
1330 verror (m, ap);
1331 va_end (ap);
1334 Lisp_Object
1335 gnutls_verify_boot (Lisp_Object proc, Lisp_Object proplist)
1337 int ret;
1338 struct Lisp_Process *p = XPROCESS (proc);
1339 gnutls_session_t state = p->gnutls_state;
1340 unsigned int peer_verification;
1341 Lisp_Object warnings;
1342 int max_log_level = p->gnutls_log_level;
1343 Lisp_Object hostname, verify_error;
1344 bool verify_error_all = false;
1345 char *c_hostname;
1347 if (NILP (proplist))
1348 proplist = Fcdr (Fplist_get (p->childp, QCtls_parameters));
1350 verify_error = Fplist_get (proplist, QCverify_error);
1351 hostname = Fplist_get (proplist, QChostname);
1353 if (EQ (verify_error, Qt))
1354 verify_error_all = true;
1355 else if (NILP (Flistp (verify_error)))
1357 boot_error (p,
1358 "gnutls-boot: invalid :verify_error parameter (not a list)");
1359 return Qnil;
1362 if (!STRINGP (hostname))
1364 boot_error (p, "gnutls-boot: invalid :hostname parameter (not a string)");
1365 return Qnil;
1367 c_hostname = SSDATA (hostname);
1369 /* Now verify the peer, following
1370 https://www.gnu.org/software/gnutls/manual/html_node/Verifying-peer_0027s-certificate.html.
1371 The peer should present at least one certificate in the chain; do a
1372 check of the certificate's hostname with
1373 gnutls_x509_crt_check_hostname against :hostname. */
1375 ret = gnutls_certificate_verify_peers2 (state, &peer_verification);
1376 if (ret < GNUTLS_E_SUCCESS)
1377 return gnutls_make_error (ret);
1379 XPROCESS (proc)->gnutls_peer_verification = peer_verification;
1381 warnings = Fplist_get (Fgnutls_peer_status (proc), intern (":warnings"));
1382 if (!NILP (warnings))
1384 for (Lisp_Object tail = warnings; CONSP (tail); tail = XCDR (tail))
1386 Lisp_Object warning = XCAR (tail);
1387 Lisp_Object message = Fgnutls_peer_status_warning_describe (warning);
1388 if (!NILP (message))
1389 GNUTLS_LOG2 (1, max_log_level, "verification:", SSDATA (message));
1393 if (peer_verification != 0)
1395 if (verify_error_all
1396 || !NILP (Fmember (QCtrustfiles, verify_error)))
1398 emacs_gnutls_deinit (proc);
1399 boot_error (p,
1400 "Certificate validation failed %s, verification code %x",
1401 c_hostname, peer_verification);
1402 return Qnil;
1404 else
1406 GNUTLS_LOG2 (1, max_log_level, "certificate validation failed:",
1407 c_hostname);
1411 /* Up to here the process is the same for X.509 certificates and
1412 OpenPGP keys. From now on X.509 certificates are assumed. This
1413 can be easily extended to work with openpgp keys as well. */
1414 if (gnutls_certificate_type_get (state) == GNUTLS_CRT_X509)
1416 gnutls_x509_crt_t gnutls_verify_cert;
1417 const gnutls_datum_t *gnutls_verify_cert_list;
1418 unsigned int gnutls_verify_cert_list_size;
1420 ret = gnutls_x509_crt_init (&gnutls_verify_cert);
1421 if (ret < GNUTLS_E_SUCCESS)
1422 return gnutls_make_error (ret);
1424 gnutls_verify_cert_list
1425 = gnutls_certificate_get_peers (state, &gnutls_verify_cert_list_size);
1427 if (gnutls_verify_cert_list == NULL)
1429 gnutls_x509_crt_deinit (gnutls_verify_cert);
1430 emacs_gnutls_deinit (proc);
1431 boot_error (p, "No x509 certificate was found\n");
1432 return Qnil;
1435 /* Check only the first certificate in the given chain. */
1436 ret = gnutls_x509_crt_import (gnutls_verify_cert,
1437 &gnutls_verify_cert_list[0],
1438 GNUTLS_X509_FMT_DER);
1440 if (ret < GNUTLS_E_SUCCESS)
1442 gnutls_x509_crt_deinit (gnutls_verify_cert);
1443 return gnutls_make_error (ret);
1446 XPROCESS (proc)->gnutls_certificate = gnutls_verify_cert;
1448 int err = gnutls_x509_crt_check_hostname (gnutls_verify_cert,
1449 c_hostname);
1450 check_memory_full (err);
1451 if (!err)
1453 XPROCESS (proc)->gnutls_extra_peer_verification
1454 |= CERTIFICATE_NOT_MATCHING;
1455 if (verify_error_all
1456 || !NILP (Fmember (QChostname, verify_error)))
1458 gnutls_x509_crt_deinit (gnutls_verify_cert);
1459 emacs_gnutls_deinit (proc);
1460 boot_error (p, "The x509 certificate does not match \"%s\"",
1461 c_hostname);
1462 return Qnil;
1464 else
1465 GNUTLS_LOG2 (1, max_log_level, "x509 certificate does not match:",
1466 c_hostname);
1470 /* Set this flag only if the whole initialization succeeded. */
1471 XPROCESS (proc)->gnutls_p = true;
1473 return gnutls_make_error (ret);
1476 DEFUN ("gnutls-boot", Fgnutls_boot, Sgnutls_boot, 3, 3, 0,
1477 doc: /* Initialize GnuTLS client for process PROC with TYPE+PROPLIST.
1478 Currently only client mode is supported. Return a success/failure
1479 value you can check with `gnutls-errorp'.
1481 TYPE is a symbol, either `gnutls-anon' or `gnutls-x509pki'.
1482 PROPLIST is a property list with the following keys:
1484 :hostname is a string naming the remote host.
1486 :priority is a GnuTLS priority string, defaults to "NORMAL".
1488 :trustfiles is a list of PEM-encoded trust files for `gnutls-x509pki'.
1490 :crlfiles is a list of PEM-encoded CRL lists for `gnutls-x509pki'.
1492 :keylist is an alist of PEM-encoded key files and PEM-encoded
1493 certificates for `gnutls-x509pki'.
1495 :callbacks is an alist of callback functions, see below.
1497 :loglevel is the debug level requested from GnuTLS, try 4.
1499 :verify-flags is a bitset as per GnuTLS'
1500 gnutls_certificate_set_verify_flags.
1502 :verify-hostname-error is ignored. Pass :hostname in :verify-error
1503 instead.
1505 :verify-error is a list of symbols to express verification checks or
1506 t to do all checks. Currently it can contain `:trustfiles' and
1507 `:hostname' to verify the certificate or the hostname respectively.
1509 :min-prime-bits is the minimum accepted number of bits the client will
1510 accept in Diffie-Hellman key exchange.
1512 :complete-negotiation, if non-nil, will make negotiation complete
1513 before returning even on non-blocking sockets.
1515 The debug level will be set for this process AND globally for GnuTLS.
1516 So if you set it higher or lower at any point, it affects global
1517 debugging.
1519 Note that the priority is set on the client. The server does not use
1520 the protocols's priority except for disabling protocols that were not
1521 specified.
1523 Processes must be initialized with this function before other GnuTLS
1524 functions are used. This function allocates resources which can only
1525 be deallocated by calling `gnutls-deinit' or by calling it again.
1527 The callbacks alist can have a `verify' key, associated with a
1528 verification function (UNUSED).
1530 Each authentication type may need additional information in order to
1531 work. For X.509 PKI (`gnutls-x509pki'), you probably need at least
1532 one trustfile (usually a CA bundle). */)
1533 (Lisp_Object proc, Lisp_Object type, Lisp_Object proplist)
1535 int ret = GNUTLS_E_SUCCESS;
1536 int max_log_level = 0;
1538 gnutls_session_t state;
1539 gnutls_certificate_credentials_t x509_cred = NULL;
1540 gnutls_anon_client_credentials_t anon_cred = NULL;
1541 Lisp_Object global_init;
1542 char const *priority_string_ptr = "NORMAL"; /* default priority string. */
1543 char *c_hostname;
1545 /* Placeholders for the property list elements. */
1546 Lisp_Object priority_string;
1547 Lisp_Object trustfiles;
1548 Lisp_Object crlfiles;
1549 Lisp_Object keylist;
1550 /* Lisp_Object callbacks; */
1551 Lisp_Object loglevel;
1552 Lisp_Object hostname;
1553 Lisp_Object prime_bits;
1554 struct Lisp_Process *p = XPROCESS (proc);
1556 CHECK_PROCESS (proc);
1557 CHECK_SYMBOL (type);
1558 CHECK_LIST (proplist);
1560 if (NILP (Fgnutls_available_p ()))
1562 boot_error (p, "GnuTLS not available");
1563 return Qnil;
1566 if (!EQ (type, Qgnutls_x509pki) && !EQ (type, Qgnutls_anon))
1568 boot_error (p, "Invalid GnuTLS credential type");
1569 return Qnil;
1572 hostname = Fplist_get (proplist, QChostname);
1573 priority_string = Fplist_get (proplist, QCpriority);
1574 trustfiles = Fplist_get (proplist, QCtrustfiles);
1575 keylist = Fplist_get (proplist, QCkeylist);
1576 crlfiles = Fplist_get (proplist, QCcrlfiles);
1577 loglevel = Fplist_get (proplist, QCloglevel);
1578 prime_bits = Fplist_get (proplist, QCmin_prime_bits);
1580 if (!STRINGP (hostname))
1582 boot_error (p, "gnutls-boot: invalid :hostname parameter (not a string)");
1583 return Qnil;
1585 c_hostname = SSDATA (hostname);
1587 state = XPROCESS (proc)->gnutls_state;
1589 if (TYPE_RANGED_INTEGERP (int, loglevel))
1591 gnutls_global_set_log_function (gnutls_log_function);
1592 # ifdef HAVE_GNUTLS3
1593 gnutls_global_set_audit_log_function (gnutls_audit_log_function);
1594 # endif
1595 gnutls_global_set_log_level (XINT (loglevel));
1596 max_log_level = XINT (loglevel);
1597 XPROCESS (proc)->gnutls_log_level = max_log_level;
1600 GNUTLS_LOG2 (1, max_log_level, "connecting to host:", c_hostname);
1602 /* Always initialize globals. */
1603 global_init = emacs_gnutls_global_init ();
1604 if (! NILP (Fgnutls_errorp (global_init)))
1605 return global_init;
1607 /* Before allocating new credentials, deallocate any credentials
1608 that PROC might already have. */
1609 emacs_gnutls_deinit (proc);
1611 /* Mark PROC as a GnuTLS process. */
1612 XPROCESS (proc)->gnutls_state = NULL;
1613 XPROCESS (proc)->gnutls_x509_cred = NULL;
1614 XPROCESS (proc)->gnutls_anon_cred = NULL;
1615 pset_gnutls_cred_type (XPROCESS (proc), type);
1616 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_EMPTY;
1618 GNUTLS_LOG (1, max_log_level, "allocating credentials");
1619 if (EQ (type, Qgnutls_x509pki))
1621 Lisp_Object verify_flags;
1622 unsigned int gnutls_verify_flags = GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT;
1624 GNUTLS_LOG (2, max_log_level, "allocating x509 credentials");
1625 check_memory_full (gnutls_certificate_allocate_credentials (&x509_cred));
1626 XPROCESS (proc)->gnutls_x509_cred = x509_cred;
1628 verify_flags = Fplist_get (proplist, QCverify_flags);
1629 if (TYPE_RANGED_INTEGERP (unsigned int, verify_flags))
1631 gnutls_verify_flags = XFASTINT (verify_flags);
1632 GNUTLS_LOG (2, max_log_level, "setting verification flags");
1634 else if (NILP (verify_flags))
1635 GNUTLS_LOG (2, max_log_level, "using default verification flags");
1636 else
1637 GNUTLS_LOG (2, max_log_level, "ignoring invalid verify-flags");
1639 gnutls_certificate_set_verify_flags (x509_cred, gnutls_verify_flags);
1641 else /* Qgnutls_anon: */
1643 GNUTLS_LOG (2, max_log_level, "allocating anon credentials");
1644 check_memory_full (gnutls_anon_allocate_client_credentials (&anon_cred));
1645 XPROCESS (proc)->gnutls_anon_cred = anon_cred;
1648 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_CRED_ALLOC;
1650 if (EQ (type, Qgnutls_x509pki))
1652 /* TODO: GNUTLS_X509_FMT_DER is also an option. */
1653 int file_format = GNUTLS_X509_FMT_PEM;
1654 Lisp_Object tail;
1656 # ifdef HAVE_GNUTLS_X509_SYSTEM_TRUST
1657 ret = gnutls_certificate_set_x509_system_trust (x509_cred);
1658 if (ret < GNUTLS_E_SUCCESS)
1660 check_memory_full (ret);
1661 GNUTLS_LOG2i (4, max_log_level,
1662 "setting system trust failed with code ", ret);
1664 # endif
1666 for (tail = trustfiles; CONSP (tail); tail = XCDR (tail))
1668 Lisp_Object trustfile = XCAR (tail);
1669 if (STRINGP (trustfile))
1671 GNUTLS_LOG2 (1, max_log_level, "setting the trustfile: ",
1672 SSDATA (trustfile));
1673 trustfile = ENCODE_FILE (trustfile);
1674 # ifdef WINDOWSNT
1675 /* Since GnuTLS doesn't support UTF-8 or UTF-16 encoded
1676 file names on Windows, we need to re-encode the file
1677 name using the current ANSI codepage. */
1678 trustfile = ansi_encode_filename (trustfile);
1679 # endif
1680 ret = gnutls_certificate_set_x509_trust_file
1681 (x509_cred,
1682 SSDATA (trustfile),
1683 file_format);
1685 if (ret < GNUTLS_E_SUCCESS)
1686 return gnutls_make_error (ret);
1688 else
1690 emacs_gnutls_deinit (proc);
1691 boot_error (p, "Invalid trustfile");
1692 return Qnil;
1696 for (tail = crlfiles; CONSP (tail); tail = XCDR (tail))
1698 Lisp_Object crlfile = XCAR (tail);
1699 if (STRINGP (crlfile))
1701 GNUTLS_LOG2 (1, max_log_level, "setting the CRL file: ",
1702 SSDATA (crlfile));
1703 crlfile = ENCODE_FILE (crlfile);
1704 # ifdef WINDOWSNT
1705 crlfile = ansi_encode_filename (crlfile);
1706 # endif
1707 ret = gnutls_certificate_set_x509_crl_file
1708 (x509_cred, SSDATA (crlfile), file_format);
1710 if (ret < GNUTLS_E_SUCCESS)
1711 return gnutls_make_error (ret);
1713 else
1715 emacs_gnutls_deinit (proc);
1716 boot_error (p, "Invalid CRL file");
1717 return Qnil;
1721 for (tail = keylist; CONSP (tail); tail = XCDR (tail))
1723 Lisp_Object keyfile = Fcar (XCAR (tail));
1724 Lisp_Object certfile = Fcar (Fcdr (XCAR (tail)));
1725 if (STRINGP (keyfile) && STRINGP (certfile))
1727 GNUTLS_LOG2 (1, max_log_level, "setting the client key file: ",
1728 SSDATA (keyfile));
1729 GNUTLS_LOG2 (1, max_log_level, "setting the client cert file: ",
1730 SSDATA (certfile));
1731 keyfile = ENCODE_FILE (keyfile);
1732 certfile = ENCODE_FILE (certfile);
1733 # ifdef WINDOWSNT
1734 keyfile = ansi_encode_filename (keyfile);
1735 certfile = ansi_encode_filename (certfile);
1736 # endif
1737 ret = gnutls_certificate_set_x509_key_file
1738 (x509_cred, SSDATA (certfile), SSDATA (keyfile), file_format);
1740 if (ret < GNUTLS_E_SUCCESS)
1741 return gnutls_make_error (ret);
1743 else
1745 emacs_gnutls_deinit (proc);
1746 boot_error (p, STRINGP (keyfile) ? "Invalid client cert file"
1747 : "Invalid client key file");
1748 return Qnil;
1753 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_FILES;
1754 GNUTLS_LOG (1, max_log_level, "gnutls callbacks");
1755 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_CALLBACKS;
1757 /* Call gnutls_init here: */
1759 GNUTLS_LOG (1, max_log_level, "gnutls_init");
1760 int gnutls_flags = GNUTLS_CLIENT;
1761 # ifdef GNUTLS_NONBLOCK
1762 if (XPROCESS (proc)->is_non_blocking_client)
1763 gnutls_flags |= GNUTLS_NONBLOCK;
1764 # endif
1765 ret = gnutls_init (&state, gnutls_flags);
1766 XPROCESS (proc)->gnutls_state = state;
1767 if (ret < GNUTLS_E_SUCCESS)
1768 return gnutls_make_error (ret);
1769 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_INIT;
1771 if (STRINGP (priority_string))
1773 priority_string_ptr = SSDATA (priority_string);
1774 GNUTLS_LOG2 (1, max_log_level, "got non-default priority string:",
1775 priority_string_ptr);
1777 else
1779 GNUTLS_LOG2 (1, max_log_level, "using default priority string:",
1780 priority_string_ptr);
1783 GNUTLS_LOG (1, max_log_level, "setting the priority string");
1784 ret = gnutls_priority_set_direct (state, priority_string_ptr, NULL);
1785 if (ret < GNUTLS_E_SUCCESS)
1786 return gnutls_make_error (ret);
1788 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_PRIORITY;
1790 if (INTEGERP (prime_bits))
1791 gnutls_dh_set_prime_bits (state, XUINT (prime_bits));
1793 ret = EQ (type, Qgnutls_x509pki)
1794 ? gnutls_credentials_set (state, GNUTLS_CRD_CERTIFICATE, x509_cred)
1795 : gnutls_credentials_set (state, GNUTLS_CRD_ANON, anon_cred);
1796 if (ret < GNUTLS_E_SUCCESS)
1797 return gnutls_make_error (ret);
1799 if (!gnutls_ip_address_p (c_hostname))
1801 ret = gnutls_server_name_set (state, GNUTLS_NAME_DNS, c_hostname,
1802 strlen (c_hostname));
1803 if (ret < GNUTLS_E_SUCCESS)
1804 return gnutls_make_error (ret);
1807 XPROCESS (proc)->gnutls_complete_negotiation_p =
1808 !NILP (Fplist_get (proplist, QCcomplete_negotiation));
1809 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_CRED_SET;
1810 ret = emacs_gnutls_handshake (XPROCESS (proc));
1811 if (ret < GNUTLS_E_SUCCESS)
1812 return gnutls_make_error (ret);
1814 return gnutls_verify_boot (proc, proplist);
1817 DEFUN ("gnutls-bye", Fgnutls_bye,
1818 Sgnutls_bye, 2, 2, 0,
1819 doc: /* Terminate current GnuTLS connection for process PROC.
1820 The connection should have been initiated using `gnutls-handshake'.
1822 If CONT is not nil the TLS connection gets terminated and further
1823 receives and sends will be disallowed. If the return value is zero you
1824 may continue using the connection. If CONT is nil, GnuTLS actually
1825 sends an alert containing a close request and waits for the peer to
1826 reply with the same message. In order to reuse the connection you
1827 should wait for an EOF from the peer.
1829 This function may also return `gnutls-e-again', or
1830 `gnutls-e-interrupted'. */)
1831 (Lisp_Object proc, Lisp_Object cont)
1833 gnutls_session_t state;
1834 int ret;
1836 CHECK_PROCESS (proc);
1838 state = XPROCESS (proc)->gnutls_state;
1840 gnutls_x509_crt_deinit (XPROCESS (proc)->gnutls_certificate);
1842 ret = gnutls_bye (state, NILP (cont) ? GNUTLS_SHUT_RDWR : GNUTLS_SHUT_WR);
1844 return gnutls_make_error (ret);
1847 #endif /* HAVE_GNUTLS */
1849 #ifdef HAVE_GNUTLS3
1851 DEFUN ("gnutls-ciphers", Fgnutls_ciphers, Sgnutls_ciphers, 0, 0, 0,
1852 doc: /* Return alist of GnuTLS symmetric cipher descriptions as plists.
1853 The alist key is the cipher name. */)
1854 (void)
1856 Lisp_Object ciphers = Qnil;
1858 const gnutls_cipher_algorithm_t *gciphers = gnutls_cipher_list ();
1859 for (ptrdiff_t pos = 0; gciphers[pos] != 0; pos++)
1861 gnutls_cipher_algorithm_t gca = gciphers[pos];
1862 if (gca == GNUTLS_CIPHER_NULL)
1863 continue;
1864 char const *cipher_name = gnutls_cipher_get_name (gca);
1865 if (!cipher_name)
1866 continue;
1868 /* A symbol representing the GnuTLS cipher. */
1869 Lisp_Object cipher_symbol = intern (cipher_name);
1871 ptrdiff_t cipher_tag_size = gnutls_cipher_get_tag_size (gca);
1873 Lisp_Object cp
1874 = listn (CONSTYPE_HEAP, 15, cipher_symbol,
1875 QCcipher_id, make_number (gca),
1876 QCtype, Qgnutls_type_cipher,
1877 QCcipher_aead_capable, cipher_tag_size == 0 ? Qnil : Qt,
1878 QCcipher_tagsize, make_number (cipher_tag_size),
1880 QCcipher_blocksize,
1881 make_number (gnutls_cipher_get_block_size (gca)),
1883 QCcipher_keysize,
1884 make_number (gnutls_cipher_get_key_size (gca)),
1886 QCcipher_ivsize,
1887 make_number (gnutls_cipher_get_iv_size (gca)));
1889 ciphers = Fcons (cp, ciphers);
1892 return ciphers;
1895 static Lisp_Object
1896 gnutls_symmetric_aead (bool encrypting, gnutls_cipher_algorithm_t gca,
1897 Lisp_Object cipher,
1898 const char *kdata, ptrdiff_t ksize,
1899 const char *vdata, ptrdiff_t vsize,
1900 const char *idata, ptrdiff_t isize,
1901 Lisp_Object aead_auth)
1903 # ifdef HAVE_GNUTLS_AEAD
1905 const char *desc = encrypting ? "encrypt" : "decrypt";
1906 Lisp_Object actual_iv = make_unibyte_string (vdata, vsize);
1908 gnutls_aead_cipher_hd_t acipher;
1909 gnutls_datum_t key_datum = { (unsigned char *) kdata, ksize };
1910 int ret = gnutls_aead_cipher_init (&acipher, gca, &key_datum);
1912 if (ret < GNUTLS_E_SUCCESS)
1913 error ("GnuTLS AEAD cipher %s/%s initialization failed: %s",
1914 gnutls_cipher_get_name (gca), desc, emacs_gnutls_strerror (ret));
1916 ptrdiff_t cipher_tag_size = gnutls_cipher_get_tag_size (gca);
1917 ptrdiff_t tagged_size;
1918 if (INT_ADD_WRAPV (isize, cipher_tag_size, &tagged_size)
1919 || SIZE_MAX < tagged_size)
1920 memory_full (SIZE_MAX);
1921 size_t storage_length = tagged_size;
1922 USE_SAFE_ALLOCA;
1923 char *storage = SAFE_ALLOCA (storage_length);
1925 const char *aead_auth_data = NULL;
1926 ptrdiff_t aead_auth_size = 0;
1928 if (!NILP (aead_auth))
1930 if (BUFFERP (aead_auth) || STRINGP (aead_auth))
1931 aead_auth = list1 (aead_auth);
1933 CHECK_CONS (aead_auth);
1935 ptrdiff_t astart_byte, aend_byte;
1936 const char *adata
1937 = extract_data_from_object (aead_auth, &astart_byte, &aend_byte);
1938 if (adata == NULL)
1939 error ("GnuTLS AEAD cipher auth extraction failed");
1941 aead_auth_data = adata;
1942 aead_auth_size = aend_byte - astart_byte;
1945 ptrdiff_t expected_remainder = encrypting ? 0 : cipher_tag_size;
1946 ptrdiff_t cipher_block_size = gnutls_cipher_get_block_size (gca);
1948 if (isize < expected_remainder
1949 || (isize - expected_remainder) % cipher_block_size != 0)
1950 error (("GnuTLS AEAD cipher %s/%s input block length %"pD"d "
1951 "is not %"pD"d greater than a multiple of the required %"pD"d"),
1952 gnutls_cipher_get_name (gca), desc,
1953 isize, expected_remainder, cipher_block_size);
1955 ret = ((encrypting ? gnutls_aead_cipher_encrypt : gnutls_aead_cipher_decrypt)
1956 (acipher, vdata, vsize, aead_auth_data, aead_auth_size,
1957 cipher_tag_size, idata, isize, storage, &storage_length));
1959 Lisp_Object output;
1960 if (GNUTLS_E_SUCCESS <= ret)
1961 output = make_unibyte_string (storage, storage_length);
1962 explicit_bzero (storage, storage_length);
1963 gnutls_aead_cipher_deinit (acipher);
1965 if (ret < GNUTLS_E_SUCCESS)
1966 error ((encrypting
1967 ? "GnuTLS AEAD cipher %s encryption failed: %s"
1968 : "GnuTLS AEAD cipher %s decryption failed: %s"),
1969 gnutls_cipher_get_name (gca), emacs_gnutls_strerror (ret));
1971 SAFE_FREE ();
1972 return list2 (output, actual_iv);
1973 # else
1974 printmax_t print_gca = gca;
1975 error ("GnuTLS AEAD cipher %"pMd" is invalid or not found", print_gca);
1976 # endif
1979 static Lisp_Object
1980 gnutls_symmetric (bool encrypting, Lisp_Object cipher,
1981 Lisp_Object key, Lisp_Object iv,
1982 Lisp_Object input, Lisp_Object aead_auth)
1984 if (BUFFERP (key) || STRINGP (key))
1985 key = list1 (key);
1987 CHECK_CONS (key);
1989 if (BUFFERP (input) || STRINGP (input))
1990 input = list1 (input);
1992 CHECK_CONS (input);
1994 if (BUFFERP (iv) || STRINGP (iv))
1995 iv = list1 (iv);
1997 CHECK_CONS (iv);
2000 const char *desc = encrypting ? "encrypt" : "decrypt";
2002 gnutls_cipher_algorithm_t gca = GNUTLS_CIPHER_UNKNOWN;
2004 Lisp_Object info = Qnil;
2005 if (STRINGP (cipher))
2006 cipher = intern (SSDATA (cipher));
2008 if (SYMBOLP (cipher))
2009 info = XCDR (Fassq (cipher, Fgnutls_ciphers ()));
2010 else if (TYPE_RANGED_INTEGERP (gnutls_cipher_algorithm_t, cipher))
2011 gca = XINT (cipher);
2012 else
2013 info = cipher;
2015 if (!NILP (info) && CONSP (info))
2017 Lisp_Object v = Fplist_get (info, QCcipher_id);
2018 if (TYPE_RANGED_INTEGERP (gnutls_cipher_algorithm_t, v))
2019 gca = XINT (v);
2022 ptrdiff_t key_size = gnutls_cipher_get_key_size (gca);
2023 if (key_size == 0)
2024 error ("GnuTLS cipher is invalid or not found");
2026 ptrdiff_t kstart_byte, kend_byte;
2027 const char *kdata = extract_data_from_object (key, &kstart_byte, &kend_byte);
2029 if (kdata == NULL)
2030 error ("GnuTLS cipher key extraction failed");
2032 if (kend_byte - kstart_byte != key_size)
2033 error (("GnuTLS cipher %s/%s key length %"pD"d is not equal to "
2034 "the required %"pD"d"),
2035 gnutls_cipher_get_name (gca), desc,
2036 kend_byte - kstart_byte, key_size);
2038 ptrdiff_t vstart_byte, vend_byte;
2039 char *vdata = extract_data_from_object (iv, &vstart_byte, &vend_byte);
2041 if (vdata == NULL)
2042 error ("GnuTLS cipher IV extraction failed");
2044 ptrdiff_t iv_size = gnutls_cipher_get_iv_size (gca);
2045 if (vend_byte - vstart_byte != iv_size)
2046 error (("GnuTLS cipher %s/%s IV length %"pD"d is not equal to "
2047 "the required %"pD"d"),
2048 gnutls_cipher_get_name (gca), desc,
2049 vend_byte - vstart_byte, iv_size);
2051 Lisp_Object actual_iv = make_unibyte_string (vdata, vend_byte - vstart_byte);
2053 ptrdiff_t istart_byte, iend_byte;
2054 const char *idata
2055 = extract_data_from_object (input, &istart_byte, &iend_byte);
2057 if (idata == NULL)
2058 error ("GnuTLS cipher input extraction failed");
2060 /* Is this an AEAD cipher? */
2061 if (gnutls_cipher_get_tag_size (gca) > 0)
2063 Lisp_Object aead_output =
2064 gnutls_symmetric_aead (encrypting, gca, cipher,
2065 kdata, kend_byte - kstart_byte,
2066 vdata, vend_byte - vstart_byte,
2067 idata, iend_byte - istart_byte,
2068 aead_auth);
2069 if (STRINGP (XCAR (key)))
2070 Fclear_string (XCAR (key));
2071 return aead_output;
2074 ptrdiff_t cipher_block_size = gnutls_cipher_get_block_size (gca);
2075 if ((iend_byte - istart_byte) % cipher_block_size != 0)
2076 error (("GnuTLS cipher %s/%s input block length %"pD"d is not a multiple "
2077 "of the required %"pD"d"),
2078 gnutls_cipher_get_name (gca), desc,
2079 iend_byte - istart_byte, cipher_block_size);
2081 gnutls_cipher_hd_t hcipher;
2082 gnutls_datum_t key_datum
2083 = { (unsigned char *) kdata, kend_byte - kstart_byte };
2085 int ret = gnutls_cipher_init (&hcipher, gca, &key_datum, NULL);
2087 if (ret < GNUTLS_E_SUCCESS)
2088 error ("GnuTLS cipher %s/%s initialization failed: %s",
2089 gnutls_cipher_get_name (gca), desc, emacs_gnutls_strerror (ret));
2091 /* Note that this will not support streaming block mode. */
2092 gnutls_cipher_set_iv (hcipher, vdata, vend_byte - vstart_byte);
2094 /* GnuTLS docs: "For the supported ciphers the encrypted data length
2095 will equal the plaintext size." */
2096 ptrdiff_t storage_length = iend_byte - istart_byte;
2097 Lisp_Object storage = make_uninit_string (storage_length);
2099 ret = ((encrypting ? gnutls_cipher_encrypt2 : gnutls_cipher_decrypt2)
2100 (hcipher, idata, iend_byte - istart_byte,
2101 SSDATA (storage), storage_length));
2103 if (STRINGP (XCAR (key)))
2104 Fclear_string (XCAR (key));
2106 if (ret < GNUTLS_E_SUCCESS)
2108 gnutls_cipher_deinit (hcipher);
2109 if (encrypting)
2110 error ("GnuTLS cipher %s encryption failed: %s",
2111 gnutls_cipher_get_name (gca), emacs_gnutls_strerror (ret));
2112 else
2113 error ("GnuTLS cipher %s decryption failed: %s",
2114 gnutls_cipher_get_name (gca), emacs_gnutls_strerror (ret));
2117 gnutls_cipher_deinit (hcipher);
2119 return list2 (storage, actual_iv);
2122 DEFUN ("gnutls-symmetric-encrypt", Fgnutls_symmetric_encrypt,
2123 Sgnutls_symmetric_encrypt, 4, 5, 0,
2124 doc: /* Encrypt INPUT with symmetric CIPHER, KEY+AEAD_AUTH, and IV to a unibyte string.
2126 Return nil on error.
2128 The KEY can be specified as a buffer or string or in other ways (see
2129 Info node `(elisp)Format of GnuTLS Cryptography Inputs'). The KEY
2130 will be wiped after use if it's a string.
2132 The IV and INPUT and the optional AEAD_AUTH can be specified as a
2133 buffer or string or in other ways (see Info node `(elisp)Format of
2134 GnuTLS Cryptography Inputs').
2136 The alist of symmetric ciphers can be obtained with `gnutls-ciphers`.
2137 The CIPHER may be a string or symbol matching a key in that alist, or
2138 a plist with the :cipher-id numeric property, or the number itself.
2140 AEAD ciphers: these ciphers will have a `gnutls-ciphers' entry with
2141 :cipher-aead-capable set to t. AEAD_AUTH can be supplied for
2142 these AEAD ciphers, but it may still be omitted (nil) as well. */)
2143 (Lisp_Object cipher, Lisp_Object key, Lisp_Object iv,
2144 Lisp_Object input, Lisp_Object aead_auth)
2146 return gnutls_symmetric (true, cipher, key, iv, input, aead_auth);
2149 DEFUN ("gnutls-symmetric-decrypt", Fgnutls_symmetric_decrypt,
2150 Sgnutls_symmetric_decrypt, 4, 5, 0,
2151 doc: /* Decrypt INPUT with symmetric CIPHER, KEY+AEAD_AUTH, and IV to a unibyte string.
2153 Return nil on error.
2155 The KEY can be specified as a buffer or string or in other ways (see
2156 Info node `(elisp)Format of GnuTLS Cryptography Inputs'). The KEY
2157 will be wiped after use if it's a string.
2159 The IV and INPUT and the optional AEAD_AUTH can be specified as a
2160 buffer or string or in other ways (see Info node `(elisp)Format of
2161 GnuTLS Cryptography Inputs').
2163 The alist of symmetric ciphers can be obtained with `gnutls-ciphers`.
2164 The CIPHER may be a string or symbol matching a key in that alist, or
2165 a plist with the `:cipher-id' numeric property, or the number itself.
2167 AEAD ciphers: these ciphers will have a `gnutls-ciphers' entry with
2168 :cipher-aead-capable set to t. AEAD_AUTH can be supplied for
2169 these AEAD ciphers, but it may still be omitted (nil) as well. */)
2170 (Lisp_Object cipher, Lisp_Object key, Lisp_Object iv,
2171 Lisp_Object input, Lisp_Object aead_auth)
2173 return gnutls_symmetric (false, cipher, key, iv, input, aead_auth);
2176 DEFUN ("gnutls-macs", Fgnutls_macs, Sgnutls_macs, 0, 0, 0,
2177 doc: /* Return alist of GnuTLS mac-algorithm method descriptions as plists.
2179 Use the value of the alist (extract it with `alist-get' for instance)
2180 with `gnutls-hash-mac'. The alist key is the mac-algorithm method
2181 name. */)
2182 (void)
2184 Lisp_Object mac_algorithms = Qnil;
2185 const gnutls_mac_algorithm_t *macs = gnutls_mac_list ();
2186 for (ptrdiff_t pos = 0; macs[pos] != 0; pos++)
2188 const gnutls_mac_algorithm_t gma = macs[pos];
2190 /* A symbol representing the GnuTLS MAC algorithm. */
2191 Lisp_Object gma_symbol = intern (gnutls_mac_get_name (gma));
2193 size_t nonce_size = 0;
2194 #ifdef HAVE_GNUTLS_MAC_GET_NONCE_SIZE
2195 nonce_size = gnutls_mac_get_nonce_size (gma);
2196 #endif
2197 Lisp_Object mp = listn (CONSTYPE_HEAP, 11, gma_symbol,
2198 QCmac_algorithm_id, make_number (gma),
2199 QCtype, Qgnutls_type_mac_algorithm,
2201 QCmac_algorithm_length,
2202 make_number (gnutls_hmac_get_len (gma)),
2204 QCmac_algorithm_keysize,
2205 make_number (gnutls_mac_get_key_size (gma)),
2207 QCmac_algorithm_noncesize,
2208 make_number (nonce_size));
2209 mac_algorithms = Fcons (mp, mac_algorithms);
2212 return mac_algorithms;
2215 DEFUN ("gnutls-digests", Fgnutls_digests, Sgnutls_digests, 0, 0, 0,
2216 doc: /* Return alist of GnuTLS digest-algorithm method descriptions as plists.
2218 Use the value of the alist (extract it with `alist-get' for instance)
2219 with `gnutls-hash-digest'. The alist key is the digest-algorithm
2220 method name. */)
2221 (void)
2223 Lisp_Object digest_algorithms = Qnil;
2224 const gnutls_digest_algorithm_t *digests = gnutls_digest_list ();
2225 for (ptrdiff_t pos = 0; digests[pos] != 0; pos++)
2227 const gnutls_digest_algorithm_t gda = digests[pos];
2229 /* A symbol representing the GnuTLS digest algorithm. */
2230 Lisp_Object gda_symbol = intern (gnutls_digest_get_name (gda));
2232 Lisp_Object mp = listn (CONSTYPE_HEAP, 7, gda_symbol,
2233 QCdigest_algorithm_id, make_number (gda),
2234 QCtype, Qgnutls_type_digest_algorithm,
2236 QCdigest_algorithm_length,
2237 make_number (gnutls_hash_get_len (gda)));
2239 digest_algorithms = Fcons (mp, digest_algorithms);
2242 return digest_algorithms;
2245 DEFUN ("gnutls-hash-mac", Fgnutls_hash_mac, Sgnutls_hash_mac, 3, 3, 0,
2246 doc: /* Hash INPUT with HASH-METHOD and KEY into a unibyte string.
2248 Return nil on error.
2250 The KEY can be specified as a buffer or string or in other ways (see
2251 Info node `(elisp)Format of GnuTLS Cryptography Inputs'). The KEY
2252 will be wiped after use if it's a string.
2254 The INPUT can be specified as a buffer or string or in other
2255 ways (see Info node `(elisp)Format of GnuTLS Cryptography Inputs').
2257 The alist of MAC algorithms can be obtained with `gnutls-macs`. The
2258 HASH-METHOD may be a string or symbol matching a key in that alist, or
2259 a plist with the `:mac-algorithm-id' numeric property, or the number
2260 itself. */)
2261 (Lisp_Object hash_method, Lisp_Object key, Lisp_Object input)
2263 if (BUFFERP (input) || STRINGP (input))
2264 input = list1 (input);
2266 CHECK_CONS (input);
2268 if (BUFFERP (key) || STRINGP (key))
2269 key = list1 (key);
2271 CHECK_CONS (key);
2273 gnutls_mac_algorithm_t gma = GNUTLS_MAC_UNKNOWN;
2275 Lisp_Object info = Qnil;
2276 if (STRINGP (hash_method))
2277 hash_method = intern (SSDATA (hash_method));
2279 if (SYMBOLP (hash_method))
2280 info = XCDR (Fassq (hash_method, Fgnutls_macs ()));
2281 else if (TYPE_RANGED_INTEGERP (gnutls_mac_algorithm_t, hash_method))
2282 gma = XINT (hash_method);
2283 else
2284 info = hash_method;
2286 if (!NILP (info) && CONSP (info))
2288 Lisp_Object v = Fplist_get (info, QCmac_algorithm_id);
2289 if (TYPE_RANGED_INTEGERP (gnutls_mac_algorithm_t, v))
2290 gma = XINT (v);
2293 ptrdiff_t digest_length = gnutls_hmac_get_len (gma);
2294 if (digest_length == 0)
2295 error ("GnuTLS MAC-method is invalid or not found");
2297 ptrdiff_t kstart_byte, kend_byte;
2298 const char *kdata = extract_data_from_object (key, &kstart_byte, &kend_byte);
2299 if (kdata == NULL)
2300 error ("GnuTLS MAC key extraction failed");
2302 gnutls_hmac_hd_t hmac;
2303 int ret = gnutls_hmac_init (&hmac, gma,
2304 kdata + kstart_byte, kend_byte - kstart_byte);
2305 if (ret < GNUTLS_E_SUCCESS)
2306 error ("GnuTLS MAC %s initialization failed: %s",
2307 gnutls_mac_get_name (gma), emacs_gnutls_strerror (ret));
2309 ptrdiff_t istart_byte, iend_byte;
2310 const char *idata
2311 = extract_data_from_object (input, &istart_byte, &iend_byte);
2312 if (idata == NULL)
2313 error ("GnuTLS MAC input extraction failed");
2315 Lisp_Object digest = make_uninit_string (digest_length);
2317 ret = gnutls_hmac (hmac, idata + istart_byte, iend_byte - istart_byte);
2319 if (STRINGP (XCAR (key)))
2320 Fclear_string (XCAR (key));
2322 if (ret < GNUTLS_E_SUCCESS)
2324 gnutls_hmac_deinit (hmac, NULL);
2325 error ("GnuTLS MAC %s application failed: %s",
2326 gnutls_mac_get_name (gma), emacs_gnutls_strerror (ret));
2329 gnutls_hmac_output (hmac, SSDATA (digest));
2330 gnutls_hmac_deinit (hmac, NULL);
2332 return digest;
2335 DEFUN ("gnutls-hash-digest", Fgnutls_hash_digest, Sgnutls_hash_digest, 2, 2, 0,
2336 doc: /* Digest INPUT with DIGEST-METHOD into a unibyte string.
2338 Return nil on error.
2340 The INPUT can be specified as a buffer or string or in other
2341 ways (see Info node `(elisp)Format of GnuTLS Cryptography Inputs').
2343 The alist of digest algorithms can be obtained with `gnutls-digests`.
2344 The DIGEST-METHOD may be a string or symbol matching a key in that
2345 alist, or a plist with the `:digest-algorithm-id' numeric property, or
2346 the number itself. */)
2347 (Lisp_Object digest_method, Lisp_Object input)
2349 if (BUFFERP (input) || STRINGP (input))
2350 input = list1 (input);
2352 CHECK_CONS (input);
2354 gnutls_digest_algorithm_t gda = GNUTLS_DIG_UNKNOWN;
2356 Lisp_Object info = Qnil;
2357 if (STRINGP (digest_method))
2358 digest_method = intern (SSDATA (digest_method));
2360 if (SYMBOLP (digest_method))
2361 info = XCDR (Fassq (digest_method, Fgnutls_digests ()));
2362 else if (TYPE_RANGED_INTEGERP (gnutls_digest_algorithm_t, digest_method))
2363 gda = XINT (digest_method);
2364 else
2365 info = digest_method;
2367 if (!NILP (info) && CONSP (info))
2369 Lisp_Object v = Fplist_get (info, QCdigest_algorithm_id);
2370 if (TYPE_RANGED_INTEGERP (gnutls_digest_algorithm_t, v))
2371 gda = XINT (v);
2374 ptrdiff_t digest_length = gnutls_hash_get_len (gda);
2375 if (digest_length == 0)
2376 error ("GnuTLS digest-method is invalid or not found");
2378 gnutls_hash_hd_t hash;
2379 int ret = gnutls_hash_init (&hash, gda);
2381 if (ret < GNUTLS_E_SUCCESS)
2382 error ("GnuTLS digest initialization failed: %s",
2383 emacs_gnutls_strerror (ret));
2385 Lisp_Object digest = make_uninit_string (digest_length);
2387 ptrdiff_t istart_byte, iend_byte;
2388 const char *idata
2389 = extract_data_from_object (input, &istart_byte, &iend_byte);
2390 if (idata == NULL)
2391 error ("GnuTLS digest input extraction failed");
2393 ret = gnutls_hash (hash, idata + istart_byte, iend_byte - istart_byte);
2395 if (ret < GNUTLS_E_SUCCESS)
2397 gnutls_hash_deinit (hash, NULL);
2398 error ("GnuTLS digest application failed: %s",
2399 emacs_gnutls_strerror (ret));
2402 gnutls_hash_output (hash, SSDATA (digest));
2403 gnutls_hash_deinit (hash, NULL);
2405 return digest;
2408 #endif /* HAVE_GNUTLS3 */
2410 DEFUN ("gnutls-available-p", Fgnutls_available_p, Sgnutls_available_p, 0, 0, 0,
2411 doc: /* Return list of capabilities if GnuTLS is available in this instance of Emacs.
2413 ...if supported : then...
2414 GnuTLS 3 or higher : the list will contain `gnutls3'.
2415 GnuTLS MACs : the list will contain `macs'.
2416 GnuTLS digests : the list will contain `digests'.
2417 GnuTLS symmetric ciphers: the list will contain `ciphers'.
2418 GnuTLS AEAD ciphers : the list will contain `AEAD-ciphers'. */)
2419 (void)
2421 Lisp_Object capabilities = Qnil;
2423 #ifdef HAVE_GNUTLS
2425 capabilities = Fcons (intern("gnutls"), capabilities);
2427 # ifdef HAVE_GNUTLS3
2428 capabilities = Fcons (intern("gnutls3"), capabilities);
2429 capabilities = Fcons (intern("digests"), capabilities);
2430 capabilities = Fcons (intern("ciphers"), capabilities);
2432 # ifdef HAVE_GNUTLS_AEAD
2433 capabilities = Fcons (intern("AEAD-ciphers"), capabilities);
2434 # endif
2436 capabilities = Fcons (intern("macs"), capabilities);
2437 # endif /* HAVE_GNUTLS3 */
2439 # ifdef WINDOWSNT
2440 Lisp_Object found = Fassq (Qgnutls, Vlibrary_cache);
2441 if (CONSP (found))
2442 return XCDR (found);
2443 else
2445 Lisp_Object status;
2446 status = init_gnutls_functions () ? capabilities : Qnil;
2447 Vlibrary_cache = Fcons (Fcons (Qgnutls, status), Vlibrary_cache);
2448 return status;
2450 # endif /* WINDOWSNT */
2451 #endif /* HAVE_GNUTLS */
2453 return capabilities;
2456 void
2457 syms_of_gnutls (void)
2459 DEFSYM (Qlibgnutls_version, "libgnutls-version");
2460 Fset (Qlibgnutls_version,
2461 #ifdef HAVE_GNUTLS
2462 make_number (GNUTLS_VERSION_MAJOR * 10000
2463 + GNUTLS_VERSION_MINOR * 100
2464 + GNUTLS_VERSION_PATCH)
2465 #else
2466 make_number (-1)
2467 #endif
2469 #ifdef HAVE_GNUTLS
2470 gnutls_global_initialized = 0;
2472 DEFSYM (Qgnutls_code, "gnutls-code");
2473 DEFSYM (Qgnutls_anon, "gnutls-anon");
2474 DEFSYM (Qgnutls_x509pki, "gnutls-x509pki");
2476 /* The following are for the property list of 'gnutls-boot'. */
2477 DEFSYM (QChostname, ":hostname");
2478 DEFSYM (QCpriority, ":priority");
2479 DEFSYM (QCtrustfiles, ":trustfiles");
2480 DEFSYM (QCkeylist, ":keylist");
2481 DEFSYM (QCcrlfiles, ":crlfiles");
2482 DEFSYM (QCmin_prime_bits, ":min-prime-bits");
2483 DEFSYM (QCloglevel, ":loglevel");
2484 DEFSYM (QCcomplete_negotiation, ":complete-negotiation");
2485 DEFSYM (QCverify_flags, ":verify-flags");
2486 DEFSYM (QCverify_error, ":verify-error");
2488 DEFSYM (QCcipher_id, ":cipher-id");
2489 DEFSYM (QCcipher_aead_capable, ":cipher-aead-capable");
2490 DEFSYM (QCcipher_blocksize, ":cipher-blocksize");
2491 DEFSYM (QCcipher_keysize, ":cipher-keysize");
2492 DEFSYM (QCcipher_tagsize, ":cipher-tagsize");
2493 DEFSYM (QCcipher_ivsize, ":cipher-ivsize");
2495 DEFSYM (QCmac_algorithm_id, ":mac-algorithm-id");
2496 DEFSYM (QCmac_algorithm_noncesize, ":mac-algorithm-noncesize");
2497 DEFSYM (QCmac_algorithm_keysize, ":mac-algorithm-keysize");
2498 DEFSYM (QCmac_algorithm_length, ":mac-algorithm-length");
2500 DEFSYM (QCdigest_algorithm_id, ":digest-algorithm-id");
2501 DEFSYM (QCdigest_algorithm_length, ":digest-algorithm-length");
2503 DEFSYM (QCtype, ":type");
2504 DEFSYM (Qgnutls_type_cipher, "gnutls-symmetric-cipher");
2505 DEFSYM (Qgnutls_type_mac_algorithm, "gnutls-mac-algorithm");
2506 DEFSYM (Qgnutls_type_digest_algorithm, "gnutls-digest-algorithm");
2508 DEFSYM (Qgnutls_e_interrupted, "gnutls-e-interrupted");
2509 Fput (Qgnutls_e_interrupted, Qgnutls_code,
2510 make_number (GNUTLS_E_INTERRUPTED));
2512 DEFSYM (Qgnutls_e_again, "gnutls-e-again");
2513 Fput (Qgnutls_e_again, Qgnutls_code,
2514 make_number (GNUTLS_E_AGAIN));
2516 DEFSYM (Qgnutls_e_invalid_session, "gnutls-e-invalid-session");
2517 Fput (Qgnutls_e_invalid_session, Qgnutls_code,
2518 make_number (GNUTLS_E_INVALID_SESSION));
2520 DEFSYM (Qgnutls_e_not_ready_for_handshake, "gnutls-e-not-ready-for-handshake");
2521 Fput (Qgnutls_e_not_ready_for_handshake, Qgnutls_code,
2522 make_number (GNUTLS_E_APPLICATION_ERROR_MIN));
2524 defsubr (&Sgnutls_get_initstage);
2525 defsubr (&Sgnutls_asynchronous_parameters);
2526 defsubr (&Sgnutls_errorp);
2527 defsubr (&Sgnutls_error_fatalp);
2528 defsubr (&Sgnutls_error_string);
2529 defsubr (&Sgnutls_boot);
2530 defsubr (&Sgnutls_deinit);
2531 defsubr (&Sgnutls_bye);
2532 defsubr (&Sgnutls_peer_status);
2533 defsubr (&Sgnutls_peer_status_warning_describe);
2535 #ifdef HAVE_GNUTLS3
2536 defsubr (&Sgnutls_ciphers);
2537 defsubr (&Sgnutls_macs);
2538 defsubr (&Sgnutls_digests);
2539 defsubr (&Sgnutls_hash_mac);
2540 defsubr (&Sgnutls_hash_digest);
2541 defsubr (&Sgnutls_symmetric_encrypt);
2542 defsubr (&Sgnutls_symmetric_decrypt);
2543 #endif
2545 DEFVAR_INT ("gnutls-log-level", global_gnutls_log_level,
2546 doc: /* Logging level used by the GnuTLS functions.
2547 Set this larger than 0 to get debug output in the *Messages* buffer.
2548 1 is for important messages, 2 is for debug data, and higher numbers
2549 are as per the GnuTLS logging conventions. */);
2550 global_gnutls_log_level = 0;
2552 #endif /* HAVE_GNUTLS */
2554 defsubr (&Sgnutls_available_p);