1 /* GnuTLS glue for GNU Emacs.
2 Copyright (C) 2010-2014 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
9 (at 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 <http://www.gnu.org/licenses/>. */
29 #include <gnutls/gnutls.h>
36 static bool emacs_gnutls_handle_error (gnutls_session_t
, int);
38 static Lisp_Object Qgnutls_dll
;
39 static Lisp_Object Qgnutls_code
;
40 static Lisp_Object Qgnutls_anon
, Qgnutls_x509pki
;
41 static Lisp_Object Qgnutls_e_interrupted
, Qgnutls_e_again
,
42 Qgnutls_e_invalid_session
, Qgnutls_e_not_ready_for_handshake
;
43 static bool gnutls_global_initialized
;
45 /* The following are for the property list of `gnutls-boot'. */
46 static Lisp_Object QCgnutls_bootprop_priority
;
47 static Lisp_Object QCgnutls_bootprop_trustfiles
;
48 static Lisp_Object QCgnutls_bootprop_keylist
;
49 static Lisp_Object QCgnutls_bootprop_crlfiles
;
50 static Lisp_Object QCgnutls_bootprop_callbacks
;
51 static Lisp_Object QCgnutls_bootprop_loglevel
;
52 static Lisp_Object QCgnutls_bootprop_hostname
;
53 static Lisp_Object QCgnutls_bootprop_min_prime_bits
;
54 static Lisp_Object QCgnutls_bootprop_verify_flags
;
55 static Lisp_Object QCgnutls_bootprop_verify_error
;
57 /* Callback keys for `gnutls-boot'. Unused currently. */
58 static Lisp_Object QCgnutls_bootprop_callbacks_verify
;
60 static void gnutls_log_function (int, const char *);
61 static void gnutls_log_function2 (int, const char *, const char *);
63 static void gnutls_audit_log_function (gnutls_session_t
, const char *);
66 enum extra_peer_verification
68 CERTIFICATE_NOT_MATCHING
= 2
74 DEF_DLL_FN (gnutls_alert_description_t
, gnutls_alert_get
,
76 DEF_DLL_FN (const char *, gnutls_alert_get_name
,
77 (gnutls_alert_description_t
));
78 DEF_DLL_FN (int, gnutls_alert_send_appropriate
, (gnutls_session_t
, int));
79 DEF_DLL_FN (int, gnutls_anon_allocate_client_credentials
,
80 (gnutls_anon_client_credentials_t
*));
81 DEF_DLL_FN (void, gnutls_anon_free_client_credentials
,
82 (gnutls_anon_client_credentials_t
));
83 DEF_DLL_FN (int, gnutls_bye
, (gnutls_session_t
, gnutls_close_request_t
));
84 DEF_DLL_FN (int, gnutls_certificate_allocate_credentials
,
85 (gnutls_certificate_credentials_t
*));
86 DEF_DLL_FN (void, gnutls_certificate_free_credentials
,
87 (gnutls_certificate_credentials_t
));
88 DEF_DLL_FN (const gnutls_datum_t
*, gnutls_certificate_get_peers
,
89 (gnutls_session_t
, unsigned int *));
90 DEF_DLL_FN (void, gnutls_certificate_set_verify_flags
,
91 (gnutls_certificate_credentials_t
, unsigned int));
92 DEF_DLL_FN (int, gnutls_certificate_set_x509_crl_file
,
93 (gnutls_certificate_credentials_t
, const char *,
94 gnutls_x509_crt_fmt_t
));
95 DEF_DLL_FN (int, gnutls_certificate_set_x509_key_file
,
96 (gnutls_certificate_credentials_t
, const char *, const char *,
97 gnutls_x509_crt_fmt_t
));
98 # if ((GNUTLS_VERSION_MAJOR \
99 + (GNUTLS_VERSION_MINOR > 0 || GNUTLS_VERSION_PATCH >= 20)) \
101 DEF_DLL_FN (int, gnutls_certificate_set_x509_system_trust
,
102 (gnutls_certificate_credentials_t
));
104 DEF_DLL_FN (int, gnutls_certificate_set_x509_trust_file
,
105 (gnutls_certificate_credentials_t
, const char *,
106 gnutls_x509_crt_fmt_t
));
107 DEF_DLL_FN (gnutls_certificate_type_t
, gnutls_certificate_type_get
,
109 DEF_DLL_FN (int, gnutls_certificate_verify_peers2
,
110 (gnutls_session_t
, unsigned int *));
111 DEF_DLL_FN (int, gnutls_credentials_set
,
112 (gnutls_session_t
, gnutls_credentials_type_t
, void *));
113 DEF_DLL_FN (void, gnutls_deinit
, (gnutls_session_t
));
114 DEF_DLL_FN (void, gnutls_dh_set_prime_bits
,
115 (gnutls_session_t
, unsigned int));
116 DEF_DLL_FN (int, gnutls_dh_get_prime_bits
, (gnutls_session_t
));
117 DEF_DLL_FN (int, gnutls_error_is_fatal
, (int));
118 DEF_DLL_FN (int, gnutls_global_init
, (void));
119 DEF_DLL_FN (void, gnutls_global_set_log_function
, (gnutls_log_func
));
121 DEF_DLL_FN (void, gnutls_global_set_audit_log_function
, (gnutls_audit_log_func
));
123 DEF_DLL_FN (void, gnutls_global_set_log_level
, (int));
124 DEF_DLL_FN (int, gnutls_handshake
, (gnutls_session_t
));
125 DEF_DLL_FN (int, gnutls_init
, (gnutls_session_t
*, unsigned int));
126 DEF_DLL_FN (int, gnutls_priority_set_direct
,
127 (gnutls_session_t
, const char *, const char **));
128 DEF_DLL_FN (size_t, gnutls_record_check_pending
, (gnutls_session_t
));
129 DEF_DLL_FN (ssize_t
, gnutls_record_recv
, (gnutls_session_t
, void *, size_t));
130 DEF_DLL_FN (ssize_t
, gnutls_record_send
,
131 (gnutls_session_t
, const void *, size_t));
132 DEF_DLL_FN (const char *, gnutls_strerror
, (int));
133 DEF_DLL_FN (void, gnutls_transport_set_errno
, (gnutls_session_t
, int));
134 DEF_DLL_FN (const char *, gnutls_check_version
, (const char *));
135 DEF_DLL_FN (void, gnutls_transport_set_lowat
, (gnutls_session_t
, int));
136 DEF_DLL_FN (void, gnutls_transport_set_ptr2
,
137 (gnutls_session_t
, gnutls_transport_ptr_t
,
138 gnutls_transport_ptr_t
));
139 DEF_DLL_FN (void, gnutls_transport_set_pull_function
,
140 (gnutls_session_t
, gnutls_pull_func
));
141 DEF_DLL_FN (void, gnutls_transport_set_push_function
,
142 (gnutls_session_t
, gnutls_push_func
));
143 DEF_DLL_FN (int, gnutls_x509_crt_check_hostname
,
144 (gnutls_x509_crt_t
, const char *));
145 DEF_DLL_FN (void, gnutls_x509_crt_deinit
, (gnutls_x509_crt_t
));
146 DEF_DLL_FN (int, gnutls_x509_crt_import
,
147 (gnutls_x509_crt_t
, const gnutls_datum_t
*,
148 gnutls_x509_crt_fmt_t
));
149 DEF_DLL_FN (int, gnutls_x509_crt_init
, (gnutls_x509_crt_t
*));
150 DEF_DLL_FN (int, gnutls_x509_crt_get_fingerprint
,
152 gnutls_digest_algorithm_t
, void *, size_t *));
153 DEF_DLL_FN (int, gnutls_x509_crt_get_version
,
154 (gnutls_x509_crt_t
));
155 DEF_DLL_FN (int, gnutls_x509_crt_get_serial
,
156 (gnutls_x509_crt_t
, void *, size_t *));
157 DEF_DLL_FN (int, gnutls_x509_crt_get_issuer_dn
,
158 (gnutls_x509_crt_t
, char *, size_t *));
159 DEF_DLL_FN (time_t, gnutls_x509_crt_get_activation_time
,
160 (gnutls_x509_crt_t
));
161 DEF_DLL_FN (time_t, gnutls_x509_crt_get_expiration_time
,
162 (gnutls_x509_crt_t
));
163 DEF_DLL_FN (int, gnutls_x509_crt_get_dn
,
164 (gnutls_x509_crt_t
, char *, size_t *));
165 DEF_DLL_FN (int, gnutls_x509_crt_get_pk_algorithm
,
166 (gnutls_x509_crt_t
, unsigned int *));
167 DEF_DLL_FN (const char*, gnutls_pk_algorithm_get_name
,
168 (gnutls_pk_algorithm_t
));
169 DEF_DLL_FN (int, gnutls_pk_bits_to_sec_param
,
170 (gnutls_pk_algorithm_t
, unsigned int));
171 DEF_DLL_FN (int, gnutls_x509_crt_get_issuer_unique_id
,
172 (gnutls_x509_crt_t
, char *, size_t *));
173 DEF_DLL_FN (int, gnutls_x509_crt_get_subject_unique_id
,
174 (gnutls_x509_crt_t
, char *, size_t *));
175 DEF_DLL_FN (int, gnutls_x509_crt_get_signature_algorithm
,
176 (gnutls_x509_crt_t
));
177 DEF_DLL_FN (int, gnutls_x509_crt_get_signature
,
178 (gnutls_x509_crt_t
, char *, size_t *));
179 DEF_DLL_FN (int, gnutls_x509_crt_get_key_id
,
180 (gnutls_x509_crt_t
, unsigned int, unsigned char *, size_t *_size
));
181 DEF_DLL_FN (const char*, gnutls_sec_param_get_name
, (gnutls_sec_param_t
));
182 DEF_DLL_FN (const char*, gnutls_sign_get_name
, (gnutls_sign_algorithm_t
));
183 DEF_DLL_FN (int, gnutls_server_name_set
,
184 (gnutls_session_t
, gnutls_server_name_type_t
,
185 const void *, size_t));
186 DEF_DLL_FN (gnutls_kx_algorithm_t
, gnutls_kx_get
, (gnutls_session_t
));
187 DEF_DLL_FN (const char*, gnutls_kx_get_name
, (gnutls_kx_algorithm_t
));
188 DEF_DLL_FN (gnutls_protocol_t
, gnutls_protocol_get_version
,
190 DEF_DLL_FN (const char*, gnutls_protocol_get_name
, (gnutls_protocol_t
));
191 DEF_DLL_FN (gnutls_cipher_algorithm_t
, gnutls_cipher_get
,
193 DEF_DLL_FN (const char*, gnutls_cipher_get_name
,
194 (gnutls_cipher_algorithm_t
));
195 DEF_DLL_FN (gnutls_mac_algorithm_t
, gnutls_mac_get
, (gnutls_session_t
));
196 DEF_DLL_FN (const char*, gnutls_mac_get_name
, (gnutls_mac_algorithm_t
));
200 init_gnutls_functions (void)
203 int max_log_level
= 1;
205 if (!(library
= w32_delayed_load (Qgnutls_dll
)))
207 GNUTLS_LOG (1, max_log_level
, "GnuTLS library not found");
211 LOAD_DLL_FN (library
, gnutls_alert_get
);
212 LOAD_DLL_FN (library
, gnutls_alert_get_name
);
213 LOAD_DLL_FN (library
, gnutls_alert_send_appropriate
);
214 LOAD_DLL_FN (library
, gnutls_anon_allocate_client_credentials
);
215 LOAD_DLL_FN (library
, gnutls_anon_free_client_credentials
);
216 LOAD_DLL_FN (library
, gnutls_bye
);
217 LOAD_DLL_FN (library
, gnutls_certificate_allocate_credentials
);
218 LOAD_DLL_FN (library
, gnutls_certificate_free_credentials
);
219 LOAD_DLL_FN (library
, gnutls_certificate_get_peers
);
220 LOAD_DLL_FN (library
, gnutls_certificate_set_verify_flags
);
221 LOAD_DLL_FN (library
, gnutls_certificate_set_x509_crl_file
);
222 LOAD_DLL_FN (library
, gnutls_certificate_set_x509_key_file
);
223 # if ((GNUTLS_VERSION_MAJOR \
224 + (GNUTLS_VERSION_MINOR > 0 || GNUTLS_VERSION_PATCH >= 20)) \
226 LOAD_DLL_FN (library
, gnutls_certificate_set_x509_system_trust
);
228 LOAD_DLL_FN (library
, gnutls_certificate_set_x509_trust_file
);
229 LOAD_DLL_FN (library
, gnutls_certificate_type_get
);
230 LOAD_DLL_FN (library
, gnutls_certificate_verify_peers2
);
231 LOAD_DLL_FN (library
, gnutls_credentials_set
);
232 LOAD_DLL_FN (library
, gnutls_deinit
);
233 LOAD_DLL_FN (library
, gnutls_dh_set_prime_bits
);
234 LOAD_DLL_FN (library
, gnutls_dh_get_prime_bits
);
235 LOAD_DLL_FN (library
, gnutls_error_is_fatal
);
236 LOAD_DLL_FN (library
, gnutls_global_init
);
237 LOAD_DLL_FN (library
, gnutls_global_set_log_function
);
239 LOAD_DLL_FN (library
, gnutls_global_set_audit_log_function
);
241 LOAD_DLL_FN (library
, gnutls_global_set_log_level
);
242 LOAD_DLL_FN (library
, gnutls_handshake
);
243 LOAD_DLL_FN (library
, gnutls_init
);
244 LOAD_DLL_FN (library
, gnutls_priority_set_direct
);
245 LOAD_DLL_FN (library
, gnutls_record_check_pending
);
246 LOAD_DLL_FN (library
, gnutls_record_recv
);
247 LOAD_DLL_FN (library
, gnutls_record_send
);
248 LOAD_DLL_FN (library
, gnutls_strerror
);
249 LOAD_DLL_FN (library
, gnutls_transport_set_errno
);
250 LOAD_DLL_FN (library
, gnutls_check_version
);
251 /* We don't need to call gnutls_transport_set_lowat in GnuTLS 2.11.1
252 and later, and the function was removed entirely in 3.0.0. */
253 if (!fn_gnutls_check_version ("2.11.1"))
254 LOAD_DLL_FN (library
, gnutls_transport_set_lowat
);
255 LOAD_DLL_FN (library
, gnutls_transport_set_ptr2
);
256 LOAD_DLL_FN (library
, gnutls_transport_set_pull_function
);
257 LOAD_DLL_FN (library
, gnutls_transport_set_push_function
);
258 LOAD_DLL_FN (library
, gnutls_x509_crt_check_hostname
);
259 LOAD_DLL_FN (library
, gnutls_x509_crt_deinit
);
260 LOAD_DLL_FN (library
, gnutls_x509_crt_import
);
261 LOAD_DLL_FN (library
, gnutls_x509_crt_init
);
262 LOAD_DLL_FN (library
, gnutls_x509_crt_get_fingerprint
);
263 LOAD_DLL_FN (library
, gnutls_x509_crt_get_version
);
264 LOAD_DLL_FN (library
, gnutls_x509_crt_get_serial
);
265 LOAD_DLL_FN (library
, gnutls_x509_crt_get_issuer_dn
);
266 LOAD_DLL_FN (library
, gnutls_x509_crt_get_activation_time
);
267 LOAD_DLL_FN (library
, gnutls_x509_crt_get_expiration_time
);
268 LOAD_DLL_FN (library
, gnutls_x509_crt_get_dn
);
269 LOAD_DLL_FN (library
, gnutls_x509_crt_get_pk_algorithm
);
270 LOAD_DLL_FN (library
, gnutls_pk_algorithm_get_name
);
271 LOAD_DLL_FN (library
, gnutls_pk_bits_to_sec_param
);
272 LOAD_DLL_FN (library
, gnutls_x509_crt_get_issuer_unique_id
);
273 LOAD_DLL_FN (library
, gnutls_x509_crt_get_subject_unique_id
);
274 LOAD_DLL_FN (library
, gnutls_x509_crt_get_signature_algorithm
);
275 LOAD_DLL_FN (library
, gnutls_x509_crt_get_signature
);
276 LOAD_DLL_FN (library
, gnutls_x509_crt_get_key_id
);
277 LOAD_DLL_FN (library
, gnutls_sec_param_get_name
);
278 LOAD_DLL_FN (library
, gnutls_sign_get_name
);
279 LOAD_DLL_FN (library
, gnutls_server_name_set
);
280 LOAD_DLL_FN (library
, gnutls_kx_get
);
281 LOAD_DLL_FN (library
, gnutls_kx_get_name
);
282 LOAD_DLL_FN (library
, gnutls_protocol_get_version
);
283 LOAD_DLL_FN (library
, gnutls_protocol_get_name
);
284 LOAD_DLL_FN (library
, gnutls_cipher_get
);
285 LOAD_DLL_FN (library
, gnutls_cipher_get_name
);
286 LOAD_DLL_FN (library
, gnutls_mac_get
);
287 LOAD_DLL_FN (library
, gnutls_mac_get_name
);
289 max_log_level
= global_gnutls_log_level
;
292 Lisp_Object name
= CAR_SAFE (Fget (Qgnutls_dll
, QCloaded_from
));
293 GNUTLS_LOG2 (1, max_log_level
, "GnuTLS library loaded:",
294 STRINGP (name
) ? (const char *) SDATA (name
) : "unknown");
300 # define gnutls_alert_get fn_gnutls_alert_get
301 # define gnutls_alert_get_name fn_gnutls_alert_get_name
302 # define gnutls_alert_send_appropriate fn_gnutls_alert_send_appropriate
303 # define gnutls_anon_allocate_client_credentials fn_gnutls_anon_allocate_client_credentials
304 # define gnutls_anon_free_client_credentials fn_gnutls_anon_free_client_credentials
305 # define gnutls_bye fn_gnutls_bye
306 # define gnutls_certificate_allocate_credentials fn_gnutls_certificate_allocate_credentials
307 # define gnutls_certificate_free_credentials fn_gnutls_certificate_free_credentials
308 # define gnutls_certificate_get_peers fn_gnutls_certificate_get_peers
309 # define gnutls_certificate_set_verify_flags fn_gnutls_certificate_set_verify_flags
310 # define gnutls_certificate_set_x509_crl_file fn_gnutls_certificate_set_x509_crl_file
311 # define gnutls_certificate_set_x509_key_file fn_gnutls_certificate_set_x509_key_file
312 # define gnutls_certificate_set_x509_system_trust fn_gnutls_certificate_set_x509_system_trust
313 # define gnutls_certificate_set_x509_trust_file fn_gnutls_certificate_set_x509_trust_file
314 # define gnutls_certificate_type_get fn_gnutls_certificate_type_get
315 # define gnutls_certificate_verify_peers2 fn_gnutls_certificate_verify_peers2
316 # define gnutls_check_version fn_gnutls_check_version
317 # define gnutls_cipher_get fn_gnutls_cipher_get
318 # define gnutls_cipher_get_name fn_gnutls_cipher_get_name
319 # define gnutls_credentials_set fn_gnutls_credentials_set
320 # define gnutls_deinit fn_gnutls_deinit
321 # define gnutls_dh_get_prime_bits fn_gnutls_dh_get_prime_bits
322 # define gnutls_dh_set_prime_bits fn_gnutls_dh_set_prime_bits
323 # define gnutls_error_is_fatal fn_gnutls_error_is_fatal
324 # define gnutls_global_init fn_gnutls_global_init
325 # define gnutls_global_set_audit_log_function fn_gnutls_global_set_audit_log_function
326 # define gnutls_global_set_log_function fn_gnutls_global_set_log_function
327 # define gnutls_global_set_log_level fn_gnutls_global_set_log_level
328 # define gnutls_handshake fn_gnutls_handshake
329 # define gnutls_init fn_gnutls_init
330 # define gnutls_kx_get fn_gnutls_kx_get
331 # define gnutls_kx_get_name fn_gnutls_kx_get_name
332 # define gnutls_mac_get fn_gnutls_mac_get
333 # define gnutls_mac_get_name fn_gnutls_mac_get_name
334 # define gnutls_pk_algorithm_get_name fn_gnutls_pk_algorithm_get_name
335 # define gnutls_pk_bits_to_sec_param fn_gnutls_pk_bits_to_sec_param
336 # define gnutls_priority_set_direct fn_gnutls_priority_set_direct
337 # define gnutls_protocol_get_name fn_gnutls_protocol_get_name
338 # define gnutls_protocol_get_version fn_gnutls_protocol_get_version
339 # define gnutls_record_check_pending fn_gnutls_record_check_pending
340 # define gnutls_record_recv fn_gnutls_record_recv
341 # define gnutls_record_send fn_gnutls_record_send
342 # define gnutls_sec_param_get_name fn_gnutls_sec_param_get_name
343 # define gnutls_server_name_set fn_gnutls_server_name_set
344 # define gnutls_sign_get_name fn_gnutls_sign_get_name
345 # define gnutls_strerror fn_gnutls_strerror
346 # define gnutls_transport_set_errno fn_gnutls_transport_set_errno
347 # define gnutls_transport_set_lowat fn_gnutls_transport_set_lowat
348 # define gnutls_transport_set_ptr2 fn_gnutls_transport_set_ptr2
349 # define gnutls_transport_set_pull_function fn_gnutls_transport_set_pull_function
350 # define gnutls_transport_set_push_function fn_gnutls_transport_set_push_function
351 # define gnutls_x509_crt_check_hostname fn_gnutls_x509_crt_check_hostname
352 # define gnutls_x509_crt_deinit fn_gnutls_x509_crt_deinit
353 # define gnutls_x509_crt_get_activation_time fn_gnutls_x509_crt_get_activation_time
354 # define gnutls_x509_crt_get_dn fn_gnutls_x509_crt_get_dn
355 # define gnutls_x509_crt_get_expiration_time fn_gnutls_x509_crt_get_expiration_time
356 # define gnutls_x509_crt_get_fingerprint fn_gnutls_x509_crt_get_fingerprint
357 # define gnutls_x509_crt_get_issuer_dn fn_gnutls_x509_crt_get_issuer_dn
358 # define gnutls_x509_crt_get_issuer_unique_id fn_gnutls_x509_crt_get_issuer_unique_id
359 # define gnutls_x509_crt_get_key_id fn_gnutls_x509_crt_get_key_id
360 # define gnutls_x509_crt_get_pk_algorithm fn_gnutls_x509_crt_get_pk_algorithm
361 # define gnutls_x509_crt_get_serial fn_gnutls_x509_crt_get_serial
362 # define gnutls_x509_crt_get_signature fn_gnutls_x509_crt_get_signature
363 # define gnutls_x509_crt_get_signature_algorithm fn_gnutls_x509_crt_get_signature_algorithm
364 # define gnutls_x509_crt_get_subject_unique_id fn_gnutls_x509_crt_get_subject_unique_id
365 # define gnutls_x509_crt_get_version fn_gnutls_x509_crt_get_version
366 # define gnutls_x509_crt_import fn_gnutls_x509_crt_import
367 # define gnutls_x509_crt_init fn_gnutls_x509_crt_init
372 /* Report memory exhaustion if ERR is an out-of-memory indication. */
374 check_memory_full (int err
)
376 /* When GnuTLS exhausts memory, it doesn't say how much memory it
377 asked for, so tell the Emacs allocator that GnuTLS asked for no
378 bytes. This isn't accurate, but it's good enough. */
379 if (err
== GNUTLS_E_MEMORY_ERROR
)
384 /* Log a simple audit message. */
386 gnutls_audit_log_function (gnutls_session_t session
, const char *string
)
388 if (global_gnutls_log_level
>= 1)
390 message ("gnutls.c: [audit] %s", string
);
395 /* Log a simple message. */
397 gnutls_log_function (int level
, const char *string
)
399 message ("gnutls.c: [%d] %s", level
, string
);
402 /* Log a message and a string. */
404 gnutls_log_function2 (int level
, const char *string
, const char *extra
)
406 message ("gnutls.c: [%d] %s %s", level
, string
, extra
);
409 /* Log a message and an integer. */
411 gnutls_log_function2i (int level
, const char *string
, int extra
)
413 message ("gnutls.c: [%d] %s %d", level
, string
, extra
);
417 emacs_gnutls_handshake (struct Lisp_Process
*proc
)
419 gnutls_session_t state
= proc
->gnutls_state
;
422 if (proc
->gnutls_initstage
< GNUTLS_STAGE_HANDSHAKE_CANDO
)
425 if (proc
->gnutls_initstage
< GNUTLS_STAGE_TRANSPORT_POINTERS_SET
)
428 /* On W32 we cannot transfer socket handles between different runtime
429 libraries, so we tell GnuTLS to use our special push/pull
431 gnutls_transport_set_ptr2 (state
,
432 (gnutls_transport_ptr_t
) proc
,
433 (gnutls_transport_ptr_t
) proc
);
434 gnutls_transport_set_push_function (state
, &emacs_gnutls_push
);
435 gnutls_transport_set_pull_function (state
, &emacs_gnutls_pull
);
437 /* For non blocking sockets or other custom made pull/push
438 functions the gnutls_transport_set_lowat must be called, with
439 a zero low water mark value. (GnuTLS 2.10.4 documentation)
441 (Note: this is probably not strictly necessary as the lowat
442 value is only used when no custom pull/push functions are
444 /* According to GnuTLS NEWS file, lowat level has been set to
445 zero by default in version 2.11.1, and the function
446 gnutls_transport_set_lowat was removed from the library in
448 if (!gnutls_check_version ("2.11.1"))
449 gnutls_transport_set_lowat (state
, 0);
451 /* This is how GnuTLS takes sockets: as file descriptors passed
452 in. For an Emacs process socket, infd and outfd are the
453 same but we use this two-argument version for clarity. */
454 gnutls_transport_set_ptr2 (state
,
455 (void *) (intptr_t) proc
->infd
,
456 (void *) (intptr_t) proc
->outfd
);
459 proc
->gnutls_initstage
= GNUTLS_STAGE_TRANSPORT_POINTERS_SET
;
464 ret
= gnutls_handshake (state
);
465 emacs_gnutls_handle_error (state
, ret
);
468 while (ret
< 0 && gnutls_error_is_fatal (ret
) == 0);
470 proc
->gnutls_initstage
= GNUTLS_STAGE_HANDSHAKE_TRIED
;
472 if (ret
== GNUTLS_E_SUCCESS
)
474 /* Here we're finally done. */
475 proc
->gnutls_initstage
= GNUTLS_STAGE_READY
;
479 check_memory_full (gnutls_alert_send_appropriate (state
, ret
));
485 emacs_gnutls_record_check_pending (gnutls_session_t state
)
487 return gnutls_record_check_pending (state
);
492 emacs_gnutls_transport_set_errno (gnutls_session_t state
, int err
)
494 gnutls_transport_set_errno (state
, err
);
499 emacs_gnutls_write (struct Lisp_Process
*proc
, const char *buf
, ptrdiff_t nbyte
)
502 ptrdiff_t bytes_written
;
503 gnutls_session_t state
= proc
->gnutls_state
;
505 if (proc
->gnutls_initstage
!= GNUTLS_STAGE_READY
)
515 rtnval
= gnutls_record_send (state
, buf
, nbyte
);
519 if (rtnval
== GNUTLS_E_INTERRUPTED
)
523 /* If we get GNUTLS_E_AGAIN, then set errno
524 appropriately so that send_process retries the
525 correct way instead of erroring out. */
526 if (rtnval
== GNUTLS_E_AGAIN
)
534 bytes_written
+= rtnval
;
537 emacs_gnutls_handle_error (state
, rtnval
);
538 return (bytes_written
);
542 emacs_gnutls_read (struct Lisp_Process
*proc
, char *buf
, ptrdiff_t nbyte
)
545 gnutls_session_t state
= proc
->gnutls_state
;
547 int log_level
= proc
->gnutls_log_level
;
549 if (proc
->gnutls_initstage
!= GNUTLS_STAGE_READY
)
551 /* If the handshake count is under the limit, try the handshake
552 again and increment the handshake count. This count is kept
553 per process (connection), not globally. */
554 if (proc
->gnutls_handshakes_tried
< GNUTLS_EMACS_HANDSHAKES_LIMIT
)
556 proc
->gnutls_handshakes_tried
++;
557 emacs_gnutls_handshake (proc
);
558 GNUTLS_LOG2i (5, log_level
, "Retried handshake",
559 proc
->gnutls_handshakes_tried
);
563 GNUTLS_LOG (2, log_level
, "Giving up on handshake; resetting retries");
564 proc
->gnutls_handshakes_tried
= 0;
567 rtnval
= gnutls_record_recv (state
, buf
, nbyte
);
570 else if (rtnval
== GNUTLS_E_UNEXPECTED_PACKET_LENGTH
)
571 /* The peer closed the connection. */
573 else if (emacs_gnutls_handle_error (state
, rtnval
))
574 /* non-fatal error */
577 /* a fatal error occurred */
582 /* Report a GnuTLS error to the user.
583 Return true if the error code was successfully handled. */
585 emacs_gnutls_handle_error (gnutls_session_t session
, int err
)
587 int max_log_level
= 0;
592 /* TODO: use a Lisp_Object generated by gnutls_make_error? */
596 check_memory_full (err
);
598 max_log_level
= global_gnutls_log_level
;
600 /* TODO: use gnutls-error-fatalp and gnutls-error-string. */
602 str
= gnutls_strerror (err
);
606 if (gnutls_error_is_fatal (err
))
609 GNUTLS_LOG2 (1, max_log_level
, "fatal error:", str
);
630 if (err
== GNUTLS_E_WARNING_ALERT_RECEIVED
631 || err
== GNUTLS_E_FATAL_ALERT_RECEIVED
)
633 int alert
= gnutls_alert_get (session
);
634 int level
= (err
== GNUTLS_E_FATAL_ALERT_RECEIVED
) ? 0 : 1;
635 str
= gnutls_alert_get_name (alert
);
639 GNUTLS_LOG2 (level
, max_log_level
, "Received alert: ", str
);
644 /* convert an integer error to a Lisp_Object; it will be either a
645 known symbol like `gnutls_e_interrupted' and `gnutls_e_again' or
646 simply the integer value of the error. GNUTLS_E_SUCCESS is mapped
649 gnutls_make_error (int err
)
653 case GNUTLS_E_SUCCESS
:
656 return Qgnutls_e_again
;
657 case GNUTLS_E_INTERRUPTED
:
658 return Qgnutls_e_interrupted
;
659 case GNUTLS_E_INVALID_SESSION
:
660 return Qgnutls_e_invalid_session
;
663 check_memory_full (err
);
664 return make_number (err
);
668 emacs_gnutls_deinit (Lisp_Object proc
)
672 CHECK_PROCESS (proc
);
674 if (XPROCESS (proc
)->gnutls_p
== 0)
677 log_level
= XPROCESS (proc
)->gnutls_log_level
;
679 if (XPROCESS (proc
)->gnutls_x509_cred
)
681 GNUTLS_LOG (2, log_level
, "Deallocating x509 credentials");
682 gnutls_certificate_free_credentials (XPROCESS (proc
)->gnutls_x509_cred
);
683 XPROCESS (proc
)->gnutls_x509_cred
= NULL
;
686 if (XPROCESS (proc
)->gnutls_anon_cred
)
688 GNUTLS_LOG (2, log_level
, "Deallocating anon credentials");
689 gnutls_anon_free_client_credentials (XPROCESS (proc
)->gnutls_anon_cred
);
690 XPROCESS (proc
)->gnutls_anon_cred
= NULL
;
693 if (XPROCESS (proc
)->gnutls_state
)
695 gnutls_deinit (XPROCESS (proc
)->gnutls_state
);
696 XPROCESS (proc
)->gnutls_state
= NULL
;
697 if (GNUTLS_INITSTAGE (proc
) >= GNUTLS_STAGE_INIT
)
698 GNUTLS_INITSTAGE (proc
) = GNUTLS_STAGE_INIT
- 1;
701 XPROCESS (proc
)->gnutls_p
= 0;
705 DEFUN ("gnutls-get-initstage", Fgnutls_get_initstage
, Sgnutls_get_initstage
, 1, 1, 0,
706 doc
: /* Return the GnuTLS init stage of process PROC.
707 See also `gnutls-boot'. */)
710 CHECK_PROCESS (proc
);
712 return make_number (GNUTLS_INITSTAGE (proc
));
715 DEFUN ("gnutls-errorp", Fgnutls_errorp
, Sgnutls_errorp
, 1, 1, 0,
716 doc
: /* Return t if ERROR indicates a GnuTLS problem.
717 ERROR is an integer or a symbol with an integer `gnutls-code' property.
718 usage: (gnutls-errorp ERROR) */)
721 if (EQ (err
, Qt
)) return Qnil
;
726 DEFUN ("gnutls-error-fatalp", Fgnutls_error_fatalp
, Sgnutls_error_fatalp
, 1, 1, 0,
727 doc
: /* Return non-nil if ERROR is fatal.
728 ERROR is an integer or a symbol with an integer `gnutls-code' property.
729 Usage: (gnutls-error-fatalp ERROR) */)
734 if (EQ (err
, Qt
)) return Qnil
;
738 code
= Fget (err
, Qgnutls_code
);
745 error ("Symbol has no numeric gnutls-code property");
749 if (! TYPE_RANGED_INTEGERP (int, err
))
750 error ("Not an error symbol or code");
752 if (0 == gnutls_error_is_fatal (XINT (err
)))
758 DEFUN ("gnutls-error-string", Fgnutls_error_string
, Sgnutls_error_string
, 1, 1, 0,
759 doc
: /* Return a description of ERROR.
760 ERROR is an integer or a symbol with an integer `gnutls-code' property.
761 usage: (gnutls-error-string ERROR) */)
766 if (EQ (err
, Qt
)) return build_string ("Not an error");
770 code
= Fget (err
, Qgnutls_code
);
777 return build_string ("Symbol has no numeric gnutls-code property");
781 if (! TYPE_RANGED_INTEGERP (int, err
))
782 return build_string ("Not an error symbol or code");
784 return build_string (gnutls_strerror (XINT (err
)));
787 DEFUN ("gnutls-deinit", Fgnutls_deinit
, Sgnutls_deinit
, 1, 1, 0,
788 doc
: /* Deallocate GnuTLS resources associated with process PROC.
789 See also `gnutls-init'. */)
792 return emacs_gnutls_deinit (proc
);
796 gnutls_hex_string (unsigned char *buf
, ptrdiff_t buf_size
, const char *prefix
)
798 ptrdiff_t prefix_length
= strlen (prefix
);
799 if ((STRING_BYTES_BOUND
- prefix_length
) / 3 < buf_size
)
801 Lisp_Object ret
= make_uninit_string (prefix_length
+ 3 * buf_size
803 char *string
= SSDATA (ret
);
804 strcpy (string
, prefix
);
806 for (ptrdiff_t i
= 0; i
< buf_size
; i
++)
807 sprintf (string
+ i
* 3 + prefix_length
,
808 i
== buf_size
- 1 ? "%02x" : "%02x:",
815 gnutls_certificate_details (gnutls_x509_crt_t cert
)
817 Lisp_Object res
= Qnil
;
823 int version
= gnutls_x509_crt_get_version (cert
);
824 check_memory_full (version
);
825 if (version
>= GNUTLS_E_SUCCESS
)
826 res
= nconc2 (res
, list2 (intern (":version"),
827 make_number (version
)));
832 err
= gnutls_x509_crt_get_serial (cert
, NULL
, &buf_size
);
833 check_memory_full (err
);
834 if (err
== GNUTLS_E_SHORT_MEMORY_BUFFER
)
836 void *serial
= xmalloc (buf_size
);
837 err
= gnutls_x509_crt_get_serial (cert
, serial
, &buf_size
);
838 check_memory_full (err
);
839 if (err
>= GNUTLS_E_SUCCESS
)
840 res
= nconc2 (res
, list2 (intern (":serial-number"),
841 gnutls_hex_string (serial
, buf_size
, "")));
847 err
= gnutls_x509_crt_get_issuer_dn (cert
, NULL
, &buf_size
);
848 check_memory_full (err
);
849 if (err
== GNUTLS_E_SHORT_MEMORY_BUFFER
)
851 char *dn
= xmalloc (buf_size
);
852 err
= gnutls_x509_crt_get_issuer_dn (cert
, dn
, &buf_size
);
853 check_memory_full (err
);
854 if (err
>= GNUTLS_E_SUCCESS
)
855 res
= nconc2 (res
, list2 (intern (":issuer"),
856 make_string (dn
, buf_size
)));
862 /* Add 1 to the buffer size, since 1900 is added to tm_year and
863 that might add 1 to the year length. */
864 char buf
[INT_STRLEN_BOUND (int) + 1 + sizeof "-12-31"];
866 time_t tim
= gnutls_x509_crt_get_activation_time (cert
);
868 if (gmtime_r (&tim
, &t
) && strftime (buf
, sizeof buf
, "%Y-%m-%d", &t
))
869 res
= nconc2 (res
, list2 (intern (":valid-from"), build_string (buf
)));
871 tim
= gnutls_x509_crt_get_expiration_time (cert
);
872 if (gmtime_r (&tim
, &t
) && strftime (buf
, sizeof buf
, "%Y-%m-%d", &t
))
873 res
= nconc2 (res
, list2 (intern (":valid-to"), build_string (buf
)));
878 err
= gnutls_x509_crt_get_dn (cert
, NULL
, &buf_size
);
879 check_memory_full (err
);
880 if (err
== GNUTLS_E_SHORT_MEMORY_BUFFER
)
882 char *dn
= xmalloc (buf_size
);
883 err
= gnutls_x509_crt_get_dn (cert
, dn
, &buf_size
);
884 check_memory_full (err
);
885 if (err
>= GNUTLS_E_SUCCESS
)
886 res
= nconc2 (res
, list2 (intern (":subject"),
887 make_string (dn
, buf_size
)));
891 /* Versions older than 2.11 doesn't have these four functions. */
892 #if GNUTLS_VERSION_NUMBER >= 0x020b00
893 /* SubjectPublicKeyInfo. */
897 err
= gnutls_x509_crt_get_pk_algorithm (cert
, &bits
);
898 check_memory_full (err
);
899 if (err
>= GNUTLS_E_SUCCESS
)
901 const char *name
= gnutls_pk_algorithm_get_name (err
);
903 res
= nconc2 (res
, list2 (intern (":public-key-algorithm"),
904 build_string (name
)));
906 name
= gnutls_sec_param_get_name (gnutls_pk_bits_to_sec_param
908 res
= nconc2 (res
, list2 (intern (":certificate-security-level"),
909 build_string (name
)));
915 err
= gnutls_x509_crt_get_issuer_unique_id (cert
, NULL
, &buf_size
);
916 check_memory_full (err
);
917 if (err
== GNUTLS_E_SHORT_MEMORY_BUFFER
)
919 char *buf
= xmalloc (buf_size
);
920 err
= gnutls_x509_crt_get_issuer_unique_id (cert
, buf
, &buf_size
);
921 check_memory_full (err
);
922 if (err
>= GNUTLS_E_SUCCESS
)
923 res
= nconc2 (res
, list2 (intern (":issuer-unique-id"),
924 make_string (buf
, buf_size
)));
929 err
= gnutls_x509_crt_get_subject_unique_id (cert
, NULL
, &buf_size
);
930 check_memory_full (err
);
931 if (err
== GNUTLS_E_SHORT_MEMORY_BUFFER
)
933 char *buf
= xmalloc (buf_size
);
934 err
= gnutls_x509_crt_get_subject_unique_id (cert
, buf
, &buf_size
);
935 check_memory_full (err
);
936 if (err
>= GNUTLS_E_SUCCESS
)
937 res
= nconc2 (res
, list2 (intern (":subject-unique-id"),
938 make_string (buf
, buf_size
)));
944 err
= gnutls_x509_crt_get_signature_algorithm (cert
);
945 check_memory_full (err
);
946 if (err
>= GNUTLS_E_SUCCESS
)
948 const char *name
= gnutls_sign_get_name (err
);
950 res
= nconc2 (res
, list2 (intern (":signature-algorithm"),
951 build_string (name
)));
956 err
= gnutls_x509_crt_get_key_id (cert
, 0, NULL
, &buf_size
);
957 check_memory_full (err
);
958 if (err
== GNUTLS_E_SHORT_MEMORY_BUFFER
)
960 void *buf
= xmalloc (buf_size
);
961 err
= gnutls_x509_crt_get_key_id (cert
, 0, buf
, &buf_size
);
962 check_memory_full (err
);
963 if (err
>= GNUTLS_E_SUCCESS
)
964 res
= nconc2 (res
, list2 (intern (":public-key-id"),
965 gnutls_hex_string (buf
, buf_size
, "sha1:")));
969 /* Certificate fingerprint. */
971 err
= gnutls_x509_crt_get_fingerprint (cert
, GNUTLS_DIG_SHA1
,
973 check_memory_full (err
);
974 if (err
== GNUTLS_E_SHORT_MEMORY_BUFFER
)
976 void *buf
= xmalloc (buf_size
);
977 err
= gnutls_x509_crt_get_fingerprint (cert
, GNUTLS_DIG_SHA1
,
979 check_memory_full (err
);
980 if (err
>= GNUTLS_E_SUCCESS
)
981 res
= nconc2 (res
, list2 (intern (":certificate-id"),
982 gnutls_hex_string (buf
, buf_size
, "sha1:")));
989 DEFUN ("gnutls-peer-status-warning-describe", Fgnutls_peer_status_warning_describe
, Sgnutls_peer_status_warning_describe
, 1, 1, 0,
990 doc
: /* Describe the warning of a GnuTLS peer status from `gnutls-peer-status'. */)
991 (Lisp_Object status_symbol
)
993 CHECK_SYMBOL (status_symbol
);
995 if (EQ (status_symbol
, intern (":invalid")))
996 return build_string ("certificate could not be verified");
998 if (EQ (status_symbol
, intern (":revoked")))
999 return build_string ("certificate was revoked (CRL)");
1001 if (EQ (status_symbol
, intern (":self-signed")))
1002 return build_string ("certificate signer was not found (self-signed)");
1004 if (EQ (status_symbol
, intern (":not-ca")))
1005 return build_string ("certificate signer is not a CA");
1007 if (EQ (status_symbol
, intern (":insecure")))
1008 return build_string ("certificate was signed with an insecure algorithm");
1010 if (EQ (status_symbol
, intern (":not-activated")))
1011 return build_string ("certificate is not yet activated");
1013 if (EQ (status_symbol
, intern (":expired")))
1014 return build_string ("certificate has expired");
1016 if (EQ (status_symbol
, intern (":no-host-match")))
1017 return build_string ("certificate host does not match hostname");
1022 DEFUN ("gnutls-peer-status", Fgnutls_peer_status
, Sgnutls_peer_status
, 1, 1, 0,
1023 doc
: /* Describe a GnuTLS PROC peer certificate and any warnings about it.
1024 The return value is a property list with top-level keys :warnings and
1025 :certificate. The :warnings entry is a list of symbols you can describe with
1026 `gnutls-peer-status-warning-describe'. */)
1029 Lisp_Object warnings
= Qnil
, result
= Qnil
;
1030 unsigned int verification
;
1031 gnutls_session_t state
;
1033 CHECK_PROCESS (proc
);
1035 if (GNUTLS_INITSTAGE (proc
) < GNUTLS_STAGE_INIT
)
1038 /* Then collect any warnings already computed by the handshake. */
1039 verification
= XPROCESS (proc
)->gnutls_peer_verification
;
1041 if (verification
& GNUTLS_CERT_INVALID
)
1042 warnings
= Fcons (intern (":invalid"), warnings
);
1044 if (verification
& GNUTLS_CERT_REVOKED
)
1045 warnings
= Fcons (intern (":revoked"), warnings
);
1047 if (verification
& GNUTLS_CERT_SIGNER_NOT_FOUND
)
1048 warnings
= Fcons (intern (":self-signed"), warnings
);
1050 if (verification
& GNUTLS_CERT_SIGNER_NOT_CA
)
1051 warnings
= Fcons (intern (":not-ca"), warnings
);
1053 if (verification
& GNUTLS_CERT_INSECURE_ALGORITHM
)
1054 warnings
= Fcons (intern (":insecure"), warnings
);
1056 if (verification
& GNUTLS_CERT_NOT_ACTIVATED
)
1057 warnings
= Fcons (intern (":not-activated"), warnings
);
1059 if (verification
& GNUTLS_CERT_EXPIRED
)
1060 warnings
= Fcons (intern (":expired"), warnings
);
1062 if (XPROCESS (proc
)->gnutls_extra_peer_verification
&
1063 CERTIFICATE_NOT_MATCHING
)
1064 warnings
= Fcons (intern (":no-host-match"), warnings
);
1066 if (!NILP (warnings
))
1067 result
= list2 (intern (":warnings"), warnings
);
1069 /* This could get called in the INIT stage, when the certificate is
1071 if (XPROCESS (proc
)->gnutls_certificate
!= NULL
)
1072 result
= nconc2 (result
, list2
1073 (intern (":certificate"),
1074 gnutls_certificate_details (XPROCESS (proc
)->gnutls_certificate
)));
1076 state
= XPROCESS (proc
)->gnutls_state
;
1078 /* Diffie-Hellman prime bits. */
1080 int bits
= gnutls_dh_get_prime_bits (state
);
1081 check_memory_full (bits
);
1083 result
= nconc2 (result
, list2 (intern (":diffie-hellman-prime-bits"),
1084 make_number (bits
)));
1089 (result
, list2 (intern (":key-exchange"),
1090 build_string (gnutls_kx_get_name
1091 (gnutls_kx_get (state
)))));
1093 /* Protocol name. */
1095 (result
, list2 (intern (":protocol"),
1096 build_string (gnutls_protocol_get_name
1097 (gnutls_protocol_get_version (state
)))));
1101 (result
, list2 (intern (":cipher"),
1102 build_string (gnutls_cipher_get_name
1103 (gnutls_cipher_get (state
)))));
1107 (result
, list2 (intern (":mac"),
1108 build_string (gnutls_mac_get_name
1109 (gnutls_mac_get (state
)))));
1115 /* Initialize global GnuTLS state to defaults.
1116 Call `gnutls-global-deinit' when GnuTLS usage is no longer needed.
1117 Return zero on success. */
1119 emacs_gnutls_global_init (void)
1121 int ret
= GNUTLS_E_SUCCESS
;
1123 if (!gnutls_global_initialized
)
1124 ret
= gnutls_global_init ();
1126 gnutls_global_initialized
= 1;
1128 return gnutls_make_error (ret
);
1132 gnutls_ip_address_p (char *string
)
1136 while ((c
= *string
++) != 0)
1137 if (! ((c
== '.' || c
== ':' || (c
>= '0' && c
<= '9'))))
1144 /* Deinitialize global GnuTLS state.
1145 See also `gnutls-global-init'. */
1147 emacs_gnutls_global_deinit (void)
1149 if (gnutls_global_initialized
)
1150 gnutls_global_deinit ();
1152 gnutls_global_initialized
= 0;
1154 return gnutls_make_error (GNUTLS_E_SUCCESS
);
1158 DEFUN ("gnutls-boot", Fgnutls_boot
, Sgnutls_boot
, 3, 3, 0,
1159 doc
: /* Initialize GnuTLS client for process PROC with TYPE+PROPLIST.
1160 Currently only client mode is supported. Return a success/failure
1161 value you can check with `gnutls-errorp'.
1163 TYPE is a symbol, either `gnutls-anon' or `gnutls-x509pki'.
1164 PROPLIST is a property list with the following keys:
1166 :hostname is a string naming the remote host.
1168 :priority is a GnuTLS priority string, defaults to "NORMAL".
1170 :trustfiles is a list of PEM-encoded trust files for `gnutls-x509pki'.
1172 :crlfiles is a list of PEM-encoded CRL lists for `gnutls-x509pki'.
1174 :keylist is an alist of PEM-encoded key files and PEM-encoded
1175 certificates for `gnutls-x509pki'.
1177 :callbacks is an alist of callback functions, see below.
1179 :loglevel is the debug level requested from GnuTLS, try 4.
1181 :verify-flags is a bitset as per GnuTLS'
1182 gnutls_certificate_set_verify_flags.
1184 :verify-hostname-error is ignored. Pass :hostname in :verify-error
1187 :verify-error is a list of symbols to express verification checks or
1188 `t' to do all checks. Currently it can contain `:trustfiles' and
1189 `:hostname' to verify the certificate or the hostname respectively.
1191 :min-prime-bits is the minimum accepted number of bits the client will
1192 accept in Diffie-Hellman key exchange.
1194 The debug level will be set for this process AND globally for GnuTLS.
1195 So if you set it higher or lower at any point, it affects global
1198 Note that the priority is set on the client. The server does not use
1199 the protocols's priority except for disabling protocols that were not
1202 Processes must be initialized with this function before other GnuTLS
1203 functions are used. This function allocates resources which can only
1204 be deallocated by calling `gnutls-deinit' or by calling it again.
1206 The callbacks alist can have a `verify' key, associated with a
1207 verification function (UNUSED).
1209 Each authentication type may need additional information in order to
1210 work. For X.509 PKI (`gnutls-x509pki'), you probably need at least
1211 one trustfile (usually a CA bundle). */)
1212 (Lisp_Object proc
, Lisp_Object type
, Lisp_Object proplist
)
1214 int ret
= GNUTLS_E_SUCCESS
;
1215 int max_log_level
= 0;
1216 bool verify_error_all
= 0;
1218 gnutls_session_t state
;
1219 gnutls_certificate_credentials_t x509_cred
= NULL
;
1220 gnutls_anon_client_credentials_t anon_cred
= NULL
;
1221 Lisp_Object global_init
;
1222 char const *priority_string_ptr
= "NORMAL"; /* default priority string. */
1223 unsigned int peer_verification
;
1226 /* Placeholders for the property list elements. */
1227 Lisp_Object priority_string
;
1228 Lisp_Object trustfiles
;
1229 Lisp_Object crlfiles
;
1230 Lisp_Object keylist
;
1231 /* Lisp_Object callbacks; */
1232 Lisp_Object loglevel
;
1233 Lisp_Object hostname
;
1234 Lisp_Object verify_error
;
1235 Lisp_Object prime_bits
;
1236 Lisp_Object warnings
;
1238 CHECK_PROCESS (proc
);
1239 CHECK_SYMBOL (type
);
1240 CHECK_LIST (proplist
);
1242 if (NILP (Fgnutls_available_p ()))
1243 error ("GnuTLS not available");
1245 if (!EQ (type
, Qgnutls_x509pki
) && !EQ (type
, Qgnutls_anon
))
1246 error ("Invalid GnuTLS credential type");
1248 hostname
= Fplist_get (proplist
, QCgnutls_bootprop_hostname
);
1249 priority_string
= Fplist_get (proplist
, QCgnutls_bootprop_priority
);
1250 trustfiles
= Fplist_get (proplist
, QCgnutls_bootprop_trustfiles
);
1251 keylist
= Fplist_get (proplist
, QCgnutls_bootprop_keylist
);
1252 crlfiles
= Fplist_get (proplist
, QCgnutls_bootprop_crlfiles
);
1253 loglevel
= Fplist_get (proplist
, QCgnutls_bootprop_loglevel
);
1254 verify_error
= Fplist_get (proplist
, QCgnutls_bootprop_verify_error
);
1255 prime_bits
= Fplist_get (proplist
, QCgnutls_bootprop_min_prime_bits
);
1257 if (EQ (verify_error
, Qt
))
1259 verify_error_all
= 1;
1261 else if (NILP (Flistp (verify_error
)))
1263 error ("gnutls-boot: invalid :verify_error parameter (not a list)");
1266 if (!STRINGP (hostname
))
1267 error ("gnutls-boot: invalid :hostname parameter (not a string)");
1268 c_hostname
= SSDATA (hostname
);
1270 state
= XPROCESS (proc
)->gnutls_state
;
1272 if (TYPE_RANGED_INTEGERP (int, loglevel
))
1274 gnutls_global_set_log_function (gnutls_log_function
);
1276 gnutls_global_set_audit_log_function (gnutls_audit_log_function
);
1278 gnutls_global_set_log_level (XINT (loglevel
));
1279 max_log_level
= XINT (loglevel
);
1280 XPROCESS (proc
)->gnutls_log_level
= max_log_level
;
1283 GNUTLS_LOG2 (1, max_log_level
, "connecting to host:", c_hostname
);
1285 /* Always initialize globals. */
1286 global_init
= emacs_gnutls_global_init ();
1287 if (! NILP (Fgnutls_errorp (global_init
)))
1290 /* Before allocating new credentials, deallocate any credentials
1291 that PROC might already have. */
1292 emacs_gnutls_deinit (proc
);
1294 /* Mark PROC as a GnuTLS process. */
1295 XPROCESS (proc
)->gnutls_state
= NULL
;
1296 XPROCESS (proc
)->gnutls_x509_cred
= NULL
;
1297 XPROCESS (proc
)->gnutls_anon_cred
= NULL
;
1298 pset_gnutls_cred_type (XPROCESS (proc
), type
);
1299 GNUTLS_INITSTAGE (proc
) = GNUTLS_STAGE_EMPTY
;
1301 GNUTLS_LOG (1, max_log_level
, "allocating credentials");
1302 if (EQ (type
, Qgnutls_x509pki
))
1304 Lisp_Object verify_flags
;
1305 unsigned int gnutls_verify_flags
= GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT
;
1307 GNUTLS_LOG (2, max_log_level
, "allocating x509 credentials");
1308 check_memory_full (gnutls_certificate_allocate_credentials (&x509_cred
));
1309 XPROCESS (proc
)->gnutls_x509_cred
= x509_cred
;
1311 verify_flags
= Fplist_get (proplist
, QCgnutls_bootprop_verify_flags
);
1312 if (NUMBERP (verify_flags
))
1314 gnutls_verify_flags
= XINT (verify_flags
);
1315 GNUTLS_LOG (2, max_log_level
, "setting verification flags");
1317 else if (NILP (verify_flags
))
1318 GNUTLS_LOG (2, max_log_level
, "using default verification flags");
1320 GNUTLS_LOG (2, max_log_level
, "ignoring invalid verify-flags");
1322 gnutls_certificate_set_verify_flags (x509_cred
, gnutls_verify_flags
);
1324 else /* Qgnutls_anon: */
1326 GNUTLS_LOG (2, max_log_level
, "allocating anon credentials");
1327 check_memory_full (gnutls_anon_allocate_client_credentials (&anon_cred
));
1328 XPROCESS (proc
)->gnutls_anon_cred
= anon_cred
;
1331 GNUTLS_INITSTAGE (proc
) = GNUTLS_STAGE_CRED_ALLOC
;
1333 if (EQ (type
, Qgnutls_x509pki
))
1335 /* TODO: GNUTLS_X509_FMT_DER is also an option. */
1336 int file_format
= GNUTLS_X509_FMT_PEM
;
1339 #if GNUTLS_VERSION_MAJOR + \
1340 (GNUTLS_VERSION_MINOR > 0 || GNUTLS_VERSION_PATCH >= 20) > 3
1341 ret
= gnutls_certificate_set_x509_system_trust (x509_cred
);
1342 if (ret
< GNUTLS_E_SUCCESS
)
1344 check_memory_full (ret
);
1345 GNUTLS_LOG2i (4, max_log_level
,
1346 "setting system trust failed with code ", ret
);
1350 for (tail
= trustfiles
; CONSP (tail
); tail
= XCDR (tail
))
1352 Lisp_Object trustfile
= XCAR (tail
);
1353 if (STRINGP (trustfile
))
1355 GNUTLS_LOG2 (1, max_log_level
, "setting the trustfile: ",
1356 SSDATA (trustfile
));
1357 trustfile
= ENCODE_FILE (trustfile
);
1359 /* Since GnuTLS doesn't support UTF-8 or UTF-16 encoded
1360 file names on Windows, we need to re-encode the file
1361 name using the current ANSI codepage. */
1362 trustfile
= ansi_encode_filename (trustfile
);
1364 ret
= gnutls_certificate_set_x509_trust_file
1369 if (ret
< GNUTLS_E_SUCCESS
)
1370 return gnutls_make_error (ret
);
1374 emacs_gnutls_deinit (proc
);
1375 error ("Invalid trustfile");
1379 for (tail
= crlfiles
; CONSP (tail
); tail
= XCDR (tail
))
1381 Lisp_Object crlfile
= XCAR (tail
);
1382 if (STRINGP (crlfile
))
1384 GNUTLS_LOG2 (1, max_log_level
, "setting the CRL file: ",
1386 crlfile
= ENCODE_FILE (crlfile
);
1388 crlfile
= ansi_encode_filename (crlfile
);
1390 ret
= gnutls_certificate_set_x509_crl_file
1391 (x509_cred
, SSDATA (crlfile
), file_format
);
1393 if (ret
< GNUTLS_E_SUCCESS
)
1394 return gnutls_make_error (ret
);
1398 emacs_gnutls_deinit (proc
);
1399 error ("Invalid CRL file");
1403 for (tail
= keylist
; CONSP (tail
); tail
= XCDR (tail
))
1405 Lisp_Object keyfile
= Fcar (XCAR (tail
));
1406 Lisp_Object certfile
= Fcar (Fcdr (XCAR (tail
)));
1407 if (STRINGP (keyfile
) && STRINGP (certfile
))
1409 GNUTLS_LOG2 (1, max_log_level
, "setting the client key file: ",
1411 GNUTLS_LOG2 (1, max_log_level
, "setting the client cert file: ",
1413 keyfile
= ENCODE_FILE (keyfile
);
1414 certfile
= ENCODE_FILE (certfile
);
1416 keyfile
= ansi_encode_filename (keyfile
);
1417 certfile
= ansi_encode_filename (certfile
);
1419 ret
= gnutls_certificate_set_x509_key_file
1420 (x509_cred
, SSDATA (certfile
), SSDATA (keyfile
), file_format
);
1422 if (ret
< GNUTLS_E_SUCCESS
)
1423 return gnutls_make_error (ret
);
1427 emacs_gnutls_deinit (proc
);
1428 error (STRINGP (keyfile
) ? "Invalid client cert file"
1429 : "Invalid client key file");
1434 GNUTLS_INITSTAGE (proc
) = GNUTLS_STAGE_FILES
;
1435 GNUTLS_LOG (1, max_log_level
, "gnutls callbacks");
1436 GNUTLS_INITSTAGE (proc
) = GNUTLS_STAGE_CALLBACKS
;
1438 /* Call gnutls_init here: */
1440 GNUTLS_LOG (1, max_log_level
, "gnutls_init");
1441 ret
= gnutls_init (&state
, GNUTLS_CLIENT
);
1442 XPROCESS (proc
)->gnutls_state
= state
;
1443 if (ret
< GNUTLS_E_SUCCESS
)
1444 return gnutls_make_error (ret
);
1445 GNUTLS_INITSTAGE (proc
) = GNUTLS_STAGE_INIT
;
1447 if (STRINGP (priority_string
))
1449 priority_string_ptr
= SSDATA (priority_string
);
1450 GNUTLS_LOG2 (1, max_log_level
, "got non-default priority string:",
1451 priority_string_ptr
);
1455 GNUTLS_LOG2 (1, max_log_level
, "using default priority string:",
1456 priority_string_ptr
);
1459 GNUTLS_LOG (1, max_log_level
, "setting the priority string");
1460 ret
= gnutls_priority_set_direct (state
, priority_string_ptr
, NULL
);
1461 if (ret
< GNUTLS_E_SUCCESS
)
1462 return gnutls_make_error (ret
);
1464 GNUTLS_INITSTAGE (proc
) = GNUTLS_STAGE_PRIORITY
;
1466 if (INTEGERP (prime_bits
))
1467 gnutls_dh_set_prime_bits (state
, XUINT (prime_bits
));
1469 ret
= EQ (type
, Qgnutls_x509pki
)
1470 ? gnutls_credentials_set (state
, GNUTLS_CRD_CERTIFICATE
, x509_cred
)
1471 : gnutls_credentials_set (state
, GNUTLS_CRD_ANON
, anon_cred
);
1472 if (ret
< GNUTLS_E_SUCCESS
)
1473 return gnutls_make_error (ret
);
1475 if (!gnutls_ip_address_p (c_hostname
))
1477 ret
= gnutls_server_name_set (state
, GNUTLS_NAME_DNS
, c_hostname
,
1478 strlen (c_hostname
));
1479 if (ret
< GNUTLS_E_SUCCESS
)
1480 return gnutls_make_error (ret
);
1483 GNUTLS_INITSTAGE (proc
) = GNUTLS_STAGE_CRED_SET
;
1484 ret
= emacs_gnutls_handshake (XPROCESS (proc
));
1485 if (ret
< GNUTLS_E_SUCCESS
)
1486 return gnutls_make_error (ret
);
1488 /* Now verify the peer, following
1489 http://www.gnu.org/software/gnutls/manual/html_node/Verifying-peer_0027s-certificate.html.
1490 The peer should present at least one certificate in the chain; do a
1491 check of the certificate's hostname with
1492 gnutls_x509_crt_check_hostname against :hostname. */
1494 ret
= gnutls_certificate_verify_peers2 (state
, &peer_verification
);
1495 if (ret
< GNUTLS_E_SUCCESS
)
1496 return gnutls_make_error (ret
);
1498 XPROCESS (proc
)->gnutls_peer_verification
= peer_verification
;
1500 warnings
= Fplist_get (Fgnutls_peer_status (proc
), intern (":warnings"));
1501 if (!NILP (warnings
))
1504 for (tail
= warnings
; CONSP (tail
); tail
= XCDR (tail
))
1506 Lisp_Object warning
= XCAR (tail
);
1507 Lisp_Object message
= Fgnutls_peer_status_warning_describe (warning
);
1508 if (!NILP (message
))
1509 GNUTLS_LOG2 (1, max_log_level
, "verification:", SSDATA (message
));
1513 if (peer_verification
!= 0)
1515 if (verify_error_all
1516 || !NILP (Fmember (QCgnutls_bootprop_trustfiles
, verify_error
)))
1518 emacs_gnutls_deinit (proc
);
1519 error ("Certificate validation failed %s, verification code %d",
1520 c_hostname
, peer_verification
);
1524 GNUTLS_LOG2 (1, max_log_level
, "certificate validation failed:",
1529 /* Up to here the process is the same for X.509 certificates and
1530 OpenPGP keys. From now on X.509 certificates are assumed. This
1531 can be easily extended to work with openpgp keys as well. */
1532 if (gnutls_certificate_type_get (state
) == GNUTLS_CRT_X509
)
1534 gnutls_x509_crt_t gnutls_verify_cert
;
1535 const gnutls_datum_t
*gnutls_verify_cert_list
;
1536 unsigned int gnutls_verify_cert_list_size
;
1538 ret
= gnutls_x509_crt_init (&gnutls_verify_cert
);
1539 if (ret
< GNUTLS_E_SUCCESS
)
1540 return gnutls_make_error (ret
);
1542 gnutls_verify_cert_list
=
1543 gnutls_certificate_get_peers (state
, &gnutls_verify_cert_list_size
);
1545 if (gnutls_verify_cert_list
== NULL
)
1547 gnutls_x509_crt_deinit (gnutls_verify_cert
);
1548 emacs_gnutls_deinit (proc
);
1549 error ("No x509 certificate was found\n");
1552 /* We only check the first certificate in the given chain. */
1553 ret
= gnutls_x509_crt_import (gnutls_verify_cert
,
1554 &gnutls_verify_cert_list
[0],
1555 GNUTLS_X509_FMT_DER
);
1557 if (ret
< GNUTLS_E_SUCCESS
)
1559 gnutls_x509_crt_deinit (gnutls_verify_cert
);
1560 return gnutls_make_error (ret
);
1563 XPROCESS (proc
)->gnutls_certificate
= gnutls_verify_cert
;
1565 int err
= gnutls_x509_crt_check_hostname (gnutls_verify_cert
,
1567 check_memory_full (err
);
1570 XPROCESS (proc
)->gnutls_extra_peer_verification
|=
1571 CERTIFICATE_NOT_MATCHING
;
1572 if (verify_error_all
1573 || !NILP (Fmember (QCgnutls_bootprop_hostname
, verify_error
)))
1575 gnutls_x509_crt_deinit (gnutls_verify_cert
);
1576 emacs_gnutls_deinit (proc
);
1577 error ("The x509 certificate does not match \"%s\"", c_hostname
);
1581 GNUTLS_LOG2 (1, max_log_level
, "x509 certificate does not match:",
1587 /* Set this flag only if the whole initialization succeeded. */
1588 XPROCESS (proc
)->gnutls_p
= 1;
1590 return gnutls_make_error (ret
);
1593 DEFUN ("gnutls-bye", Fgnutls_bye
,
1594 Sgnutls_bye
, 2, 2, 0,
1595 doc
: /* Terminate current GnuTLS connection for process PROC.
1596 The connection should have been initiated using `gnutls-handshake'.
1598 If CONT is not nil the TLS connection gets terminated and further
1599 receives and sends will be disallowed. If the return value is zero you
1600 may continue using the connection. If CONT is nil, GnuTLS actually
1601 sends an alert containing a close request and waits for the peer to
1602 reply with the same message. In order to reuse the connection you
1603 should wait for an EOF from the peer.
1605 This function may also return `gnutls-e-again', or
1606 `gnutls-e-interrupted'. */)
1607 (Lisp_Object proc
, Lisp_Object cont
)
1609 gnutls_session_t state
;
1612 CHECK_PROCESS (proc
);
1614 state
= XPROCESS (proc
)->gnutls_state
;
1616 gnutls_x509_crt_deinit (XPROCESS (proc
)->gnutls_certificate
);
1618 ret
= gnutls_bye (state
, NILP (cont
) ? GNUTLS_SHUT_RDWR
: GNUTLS_SHUT_WR
);
1620 return gnutls_make_error (ret
);
1623 #endif /* HAVE_GNUTLS */
1625 DEFUN ("gnutls-available-p", Fgnutls_available_p
, Sgnutls_available_p
, 0, 0, 0,
1626 doc
: /* Return t if GnuTLS is available in this instance of Emacs. */)
1631 Lisp_Object found
= Fassq (Qgnutls_dll
, Vlibrary_cache
);
1633 return XCDR (found
);
1637 status
= init_gnutls_functions () ? Qt
: Qnil
;
1638 Vlibrary_cache
= Fcons (Fcons (Qgnutls_dll
, status
), Vlibrary_cache
);
1641 # else /* !WINDOWSNT */
1643 # endif /* !WINDOWSNT */
1644 #else /* !HAVE_GNUTLS */
1646 #endif /* !HAVE_GNUTLS */
1650 syms_of_gnutls (void)
1653 gnutls_global_initialized
= 0;
1655 DEFSYM (Qgnutls_dll
, "gnutls");
1656 DEFSYM (Qgnutls_code
, "gnutls-code");
1657 DEFSYM (Qgnutls_anon
, "gnutls-anon");
1658 DEFSYM (Qgnutls_x509pki
, "gnutls-x509pki");
1659 DEFSYM (QCgnutls_bootprop_hostname
, ":hostname");
1660 DEFSYM (QCgnutls_bootprop_priority
, ":priority");
1661 DEFSYM (QCgnutls_bootprop_trustfiles
, ":trustfiles");
1662 DEFSYM (QCgnutls_bootprop_keylist
, ":keylist");
1663 DEFSYM (QCgnutls_bootprop_crlfiles
, ":crlfiles");
1664 DEFSYM (QCgnutls_bootprop_callbacks
, ":callbacks");
1665 DEFSYM (QCgnutls_bootprop_callbacks_verify
, "verify");
1666 DEFSYM (QCgnutls_bootprop_min_prime_bits
, ":min-prime-bits");
1667 DEFSYM (QCgnutls_bootprop_loglevel
, ":loglevel");
1668 DEFSYM (QCgnutls_bootprop_verify_flags
, ":verify-flags");
1669 DEFSYM (QCgnutls_bootprop_verify_error
, ":verify-error");
1671 DEFSYM (Qgnutls_e_interrupted
, "gnutls-e-interrupted");
1672 Fput (Qgnutls_e_interrupted
, Qgnutls_code
,
1673 make_number (GNUTLS_E_INTERRUPTED
));
1675 DEFSYM (Qgnutls_e_again
, "gnutls-e-again");
1676 Fput (Qgnutls_e_again
, Qgnutls_code
,
1677 make_number (GNUTLS_E_AGAIN
));
1679 DEFSYM (Qgnutls_e_invalid_session
, "gnutls-e-invalid-session");
1680 Fput (Qgnutls_e_invalid_session
, Qgnutls_code
,
1681 make_number (GNUTLS_E_INVALID_SESSION
));
1683 DEFSYM (Qgnutls_e_not_ready_for_handshake
, "gnutls-e-not-ready-for-handshake");
1684 Fput (Qgnutls_e_not_ready_for_handshake
, Qgnutls_code
,
1685 make_number (GNUTLS_E_APPLICATION_ERROR_MIN
));
1687 defsubr (&Sgnutls_get_initstage
);
1688 defsubr (&Sgnutls_errorp
);
1689 defsubr (&Sgnutls_error_fatalp
);
1690 defsubr (&Sgnutls_error_string
);
1691 defsubr (&Sgnutls_boot
);
1692 defsubr (&Sgnutls_deinit
);
1693 defsubr (&Sgnutls_bye
);
1694 defsubr (&Sgnutls_peer_status
);
1695 defsubr (&Sgnutls_peer_status_warning_describe
);
1697 DEFVAR_INT ("gnutls-log-level", global_gnutls_log_level
,
1698 doc
: /* Logging level used by the GnuTLS functions.
1699 Set this larger than 0 to get debug output in the *Messages* buffer.
1700 1 is for important messages, 2 is for debug data, and higher numbers
1701 are as per the GnuTLS logging conventions. */);
1702 global_gnutls_log_level
= 0;
1704 #endif /* HAVE_GNUTLS */
1706 defsubr (&Sgnutls_available_p
);