1 /***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
9 *
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at https://curl.se/docs/copyright.html.
13 *
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 * SPDX-License-Identifier: curl
22 *
23 ***************************************************************************/
24
25 /*
26 * Source file for all GnuTLS-specific code for the TLS/SSL layer. No code
27 * but vtls.c should ever call or use these functions.
28 *
29 * Note: don't use the GnuTLS' *_t variable type names in this source code,
30 * since they were not present in 1.0.X.
31 */
32
33 #include "curl_setup.h"
34
35 #ifdef USE_GNUTLS
36
37 #include <gnutls/abstract.h>
38 #include <gnutls/gnutls.h>
39 #include <gnutls/x509.h>
40 #include <gnutls/crypto.h>
41 #include <nettle/sha2.h>
42
43 #include "urldata.h"
44 #include "sendf.h"
45 #include "inet_pton.h"
46 #include "keylog.h"
47 #include "gtls.h"
48 #include "vtls.h"
49 #include "vtls_int.h"
50 #include "vauth/vauth.h"
51 #include "parsedate.h"
52 #include "connect.h" /* for the connect timeout */
53 #include "select.h"
54 #include "strcase.h"
55 #include "warnless.h"
56 #include "x509asn1.h"
57 #include "multiif.h"
58 #include "curl_printf.h"
59 #include "curl_memory.h"
60 /* The last #include file should be: */
61 #include "memdebug.h"
62
63 #ifndef ARRAYSIZE
64 #define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
65 #endif
66
67 #define QUIC_PRIORITY \
68 "NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-128-GCM:+AES-256-GCM:" \
69 "+CHACHA20-POLY1305:+AES-128-CCM:-GROUP-ALL:+GROUP-SECP256R1:" \
70 "+GROUP-X25519:+GROUP-SECP384R1:+GROUP-SECP521R1:" \
71 "%DISABLE_TLS13_COMPAT_MODE"
72
73 /* Enable GnuTLS debugging by defining GTLSDEBUG */
74 /*#define GTLSDEBUG */
75
76 #ifdef GTLSDEBUG
tls_log_func(int level,const char * str)77 static void tls_log_func(int level, const char *str)
78 {
79 fprintf(stderr, "|<%d>| %s", level, str);
80 }
81 #endif
82 static bool gtls_inited = FALSE;
83
84 #if !defined(GNUTLS_VERSION_NUMBER) || (GNUTLS_VERSION_NUMBER < 0x03010a)
85 #error "too old GnuTLS version"
86 #endif
87
88 # include <gnutls/ocsp.h>
89
90 struct gtls_ssl_backend_data {
91 struct gtls_ctx gtls;
92 };
93
gtls_push(void * s,const void * buf,size_t blen)94 static ssize_t gtls_push(void *s, const void *buf, size_t blen)
95 {
96 struct Curl_cfilter *cf = s;
97 struct ssl_connect_data *connssl = cf->ctx;
98 struct gtls_ssl_backend_data *backend =
99 (struct gtls_ssl_backend_data *)connssl->backend;
100 struct Curl_easy *data = CF_DATA_CURRENT(cf);
101 ssize_t nwritten;
102 CURLcode result;
103
104 DEBUGASSERT(data);
105 nwritten = Curl_conn_cf_send(cf->next, data, buf, blen, &result);
106 CURL_TRC_CF(data, cf, "gtls_push(len=%zu) -> %zd, err=%d",
107 blen, nwritten, result);
108 backend->gtls.io_result = result;
109 if(nwritten < 0) {
110 gnutls_transport_set_errno(backend->gtls.session,
111 (CURLE_AGAIN == result)? EAGAIN : EINVAL);
112 nwritten = -1;
113 }
114 return nwritten;
115 }
116
gtls_pull(void * s,void * buf,size_t blen)117 static ssize_t gtls_pull(void *s, void *buf, size_t blen)
118 {
119 struct Curl_cfilter *cf = s;
120 struct ssl_connect_data *connssl = cf->ctx;
121 struct gtls_ssl_backend_data *backend =
122 (struct gtls_ssl_backend_data *)connssl->backend;
123 struct Curl_easy *data = CF_DATA_CURRENT(cf);
124 ssize_t nread;
125 CURLcode result;
126
127 DEBUGASSERT(data);
128 if(!backend->gtls.trust_setup) {
129 result = Curl_gtls_client_trust_setup(cf, data, &backend->gtls);
130 if(result) {
131 gnutls_transport_set_errno(backend->gtls.session, EINVAL);
132 backend->gtls.io_result = result;
133 return -1;
134 }
135 }
136
137 nread = Curl_conn_cf_recv(cf->next, data, buf, blen, &result);
138 CURL_TRC_CF(data, cf, "glts_pull(len=%zu) -> %zd, err=%d",
139 blen, nread, result);
140 backend->gtls.io_result = result;
141 if(nread < 0) {
142 gnutls_transport_set_errno(backend->gtls.session,
143 (CURLE_AGAIN == result)? EAGAIN : EINVAL);
144 nread = -1;
145 }
146 else if(nread == 0)
147 connssl->peer_closed = TRUE;
148 return nread;
149 }
150
151 /* gtls_init()
152 *
153 * Global GnuTLS init, called from Curl_ssl_init(). This calls functions that
154 * are not thread-safe and thus this function itself is not thread-safe and
155 * must only be called from within curl_global_init() to keep the thread
156 * situation under control!
157 */
gtls_init(void)158 static int gtls_init(void)
159 {
160 int ret = 1;
161 if(!gtls_inited) {
162 ret = gnutls_global_init()?0:1;
163 #ifdef GTLSDEBUG
164 gnutls_global_set_log_function(tls_log_func);
165 gnutls_global_set_log_level(2);
166 #endif
167 gtls_inited = TRUE;
168 }
169 return ret;
170 }
171
gtls_cleanup(void)172 static void gtls_cleanup(void)
173 {
174 if(gtls_inited) {
175 gnutls_global_deinit();
176 gtls_inited = FALSE;
177 }
178 }
179
180 #ifndef CURL_DISABLE_VERBOSE_STRINGS
showtime(struct Curl_easy * data,const char * text,time_t stamp)181 static void showtime(struct Curl_easy *data,
182 const char *text,
183 time_t stamp)
184 {
185 struct tm buffer;
186 const struct tm *tm = &buffer;
187 char str[96];
188 CURLcode result = Curl_gmtime(stamp, &buffer);
189 if(result)
190 return;
191
192 msnprintf(str,
193 sizeof(str),
194 " %s: %s, %02d %s %4d %02d:%02d:%02d GMT",
195 text,
196 Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
197 tm->tm_mday,
198 Curl_month[tm->tm_mon],
199 tm->tm_year + 1900,
200 tm->tm_hour,
201 tm->tm_min,
202 tm->tm_sec);
203 infof(data, "%s", str);
204 }
205 #endif
206
load_file(const char * file)207 static gnutls_datum_t load_file(const char *file)
208 {
209 FILE *f;
210 gnutls_datum_t loaded_file = { NULL, 0 };
211 long filelen;
212 void *ptr;
213
214 f = fopen(file, "rb");
215 if(!f)
216 return loaded_file;
217 if(fseek(f, 0, SEEK_END) != 0
218 || (filelen = ftell(f)) < 0
219 || fseek(f, 0, SEEK_SET) != 0
220 || !(ptr = malloc((size_t)filelen)))
221 goto out;
222 if(fread(ptr, 1, (size_t)filelen, f) < (size_t)filelen) {
223 free(ptr);
224 goto out;
225 }
226
227 loaded_file.data = ptr;
228 loaded_file.size = (unsigned int)filelen;
229 out:
230 fclose(f);
231 return loaded_file;
232 }
233
unload_file(gnutls_datum_t data)234 static void unload_file(gnutls_datum_t data)
235 {
236 free(data.data);
237 }
238
239
240 /* this function does a SSL/TLS (re-)handshake */
handshake(struct Curl_cfilter * cf,struct Curl_easy * data,bool duringconnect,bool nonblocking)241 static CURLcode handshake(struct Curl_cfilter *cf,
242 struct Curl_easy *data,
243 bool duringconnect,
244 bool nonblocking)
245 {
246 struct ssl_connect_data *connssl = cf->ctx;
247 struct gtls_ssl_backend_data *backend =
248 (struct gtls_ssl_backend_data *)connssl->backend;
249 gnutls_session_t session;
250 curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data);
251
252 DEBUGASSERT(backend);
253 session = backend->gtls.session;
254
255 for(;;) {
256 timediff_t timeout_ms;
257 int rc;
258
259 /* check allowed time left */
260 timeout_ms = Curl_timeleft(data, NULL, duringconnect);
261
262 if(timeout_ms < 0) {
263 /* no need to continue if time already is up */
264 failf(data, "SSL connection timeout");
265 return CURLE_OPERATION_TIMEDOUT;
266 }
267
268 /* if ssl is expecting something, check if it's available. */
269 if(connssl->connecting_state == ssl_connect_2_reading
270 || connssl->connecting_state == ssl_connect_2_writing) {
271 int what;
272 curl_socket_t writefd = ssl_connect_2_writing ==
273 connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
274 curl_socket_t readfd = ssl_connect_2_reading ==
275 connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
276
277 what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
278 nonblocking?0:
279 timeout_ms?timeout_ms:1000);
280 if(what < 0) {
281 /* fatal error */
282 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
283 return CURLE_SSL_CONNECT_ERROR;
284 }
285 else if(0 == what) {
286 if(nonblocking)
287 return CURLE_OK;
288 else if(timeout_ms) {
289 /* timeout */
290 failf(data, "SSL connection timeout at %ld", (long)timeout_ms);
291 return CURLE_OPERATION_TIMEDOUT;
292 }
293 }
294 /* socket is readable or writable */
295 }
296
297 backend->gtls.io_result = CURLE_OK;
298 rc = gnutls_handshake(session);
299
300 if(!backend->gtls.trust_setup) {
301 /* After having send off the ClientHello, we prepare the trust
302 * store to verify the coming certificate from the server */
303 CURLcode result = Curl_gtls_client_trust_setup(cf, data, &backend->gtls);
304 if(result)
305 return result;
306 }
307
308 if((rc == GNUTLS_E_AGAIN) || (rc == GNUTLS_E_INTERRUPTED)) {
309 connssl->connecting_state =
310 gnutls_record_get_direction(session)?
311 ssl_connect_2_writing:ssl_connect_2_reading;
312 continue;
313 }
314 else if((rc < 0) && !gnutls_error_is_fatal(rc)) {
315 const char *strerr = NULL;
316
317 if(rc == GNUTLS_E_WARNING_ALERT_RECEIVED) {
318 int alert = gnutls_alert_get(session);
319 strerr = gnutls_alert_get_name(alert);
320 }
321
322 if(!strerr)
323 strerr = gnutls_strerror(rc);
324
325 infof(data, "gnutls_handshake() warning: %s", strerr);
326 continue;
327 }
328 else if((rc < 0) && backend->gtls.io_result) {
329 return backend->gtls.io_result;
330 }
331 else if(rc < 0) {
332 const char *strerr = NULL;
333
334 if(rc == GNUTLS_E_FATAL_ALERT_RECEIVED) {
335 int alert = gnutls_alert_get(session);
336 strerr = gnutls_alert_get_name(alert);
337 }
338
339 if(!strerr)
340 strerr = gnutls_strerror(rc);
341
342 failf(data, "gnutls_handshake() failed: %s", strerr);
343 return CURLE_SSL_CONNECT_ERROR;
344 }
345
346 /* Reset our connect state machine */
347 connssl->connecting_state = ssl_connect_1;
348 return CURLE_OK;
349 }
350 }
351
do_file_type(const char * type)352 static gnutls_x509_crt_fmt_t do_file_type(const char *type)
353 {
354 if(!type || !type[0])
355 return GNUTLS_X509_FMT_PEM;
356 if(strcasecompare(type, "PEM"))
357 return GNUTLS_X509_FMT_PEM;
358 if(strcasecompare(type, "DER"))
359 return GNUTLS_X509_FMT_DER;
360 return GNUTLS_X509_FMT_PEM; /* default to PEM */
361 }
362
363 #define GNUTLS_CIPHERS "NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509"
364 /* If GnuTLS was compiled without support for SRP it will error out if SRP is
365 requested in the priority string, so treat it specially
366 */
367 #define GNUTLS_SRP "+SRP"
368
369 static CURLcode
set_ssl_version_min_max(struct Curl_easy * data,struct ssl_peer * peer,struct ssl_primary_config * conn_config,const char ** prioritylist,const char * tls13support)370 set_ssl_version_min_max(struct Curl_easy *data,
371 struct ssl_peer *peer,
372 struct ssl_primary_config *conn_config,
373 const char **prioritylist,
374 const char *tls13support)
375 {
376 long ssl_version = conn_config->version;
377 long ssl_version_max = conn_config->version_max;
378
379 if(peer->transport == TRNSPRT_QUIC) {
380 if((ssl_version != CURL_SSLVERSION_DEFAULT) &&
381 (ssl_version < CURL_SSLVERSION_TLSv1_3)) {
382 failf(data, "QUIC needs at least TLS version 1.3");
383 return CURLE_SSL_CONNECT_ERROR;
384 }
385 *prioritylist = QUIC_PRIORITY;
386 return CURLE_OK;
387 }
388
389 if((ssl_version == CURL_SSLVERSION_DEFAULT) ||
390 (ssl_version == CURL_SSLVERSION_TLSv1))
391 ssl_version = CURL_SSLVERSION_TLSv1_0;
392 if(ssl_version_max == CURL_SSLVERSION_MAX_NONE)
393 ssl_version_max = CURL_SSLVERSION_MAX_DEFAULT;
394 if(!tls13support) {
395 /* If the running GnuTLS doesn't support TLS 1.3, we must not specify a
396 prioritylist involving that since it will make GnuTLS return an en
397 error back at us */
398 if((ssl_version_max == CURL_SSLVERSION_MAX_TLSv1_3) ||
399 (ssl_version_max == CURL_SSLVERSION_MAX_DEFAULT)) {
400 ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
401 }
402 }
403 else if(ssl_version_max == CURL_SSLVERSION_MAX_DEFAULT) {
404 ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_3;
405 }
406
407 switch(ssl_version | ssl_version_max) {
408 case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_0:
409 *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
410 "+VERS-TLS1.0";
411 return CURLE_OK;
412 case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_1:
413 *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
414 "+VERS-TLS1.1:+VERS-TLS1.0";
415 return CURLE_OK;
416 case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_2:
417 *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
418 "+VERS-TLS1.2:+VERS-TLS1.1:+VERS-TLS1.0";
419 return CURLE_OK;
420 case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_TLSv1_1:
421 *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
422 "+VERS-TLS1.1";
423 return CURLE_OK;
424 case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_TLSv1_2:
425 *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
426 "+VERS-TLS1.2:+VERS-TLS1.1";
427 return CURLE_OK;
428 case CURL_SSLVERSION_TLSv1_2 | CURL_SSLVERSION_MAX_TLSv1_2:
429 *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
430 "+VERS-TLS1.2";
431 return CURLE_OK;
432 case CURL_SSLVERSION_TLSv1_3 | CURL_SSLVERSION_MAX_TLSv1_3:
433 *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
434 "+VERS-TLS1.3";
435 return CURLE_OK;
436 case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_3:
437 *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0";
438 return CURLE_OK;
439 case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_TLSv1_3:
440 *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
441 "+VERS-TLS1.3:+VERS-TLS1.2:+VERS-TLS1.1";
442 return CURLE_OK;
443 case CURL_SSLVERSION_TLSv1_2 | CURL_SSLVERSION_MAX_TLSv1_3:
444 *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
445 "+VERS-TLS1.3:+VERS-TLS1.2";
446 return CURLE_OK;
447 }
448
449 failf(data, "GnuTLS: cannot set ssl protocol");
450 return CURLE_SSL_CONNECT_ERROR;
451 }
452
Curl_gtls_client_trust_setup(struct Curl_cfilter * cf,struct Curl_easy * data,struct gtls_ctx * gtls)453 CURLcode Curl_gtls_client_trust_setup(struct Curl_cfilter *cf,
454 struct Curl_easy *data,
455 struct gtls_ctx *gtls)
456 {
457 struct ssl_primary_config *config = Curl_ssl_cf_get_primary_config(cf);
458 struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
459 int rc;
460
461 CURL_TRC_CF(data, cf, "setup trust anchors and CRLs");
462 if(config->verifypeer) {
463 bool imported_native_ca = false;
464
465 if(ssl_config->native_ca_store) {
466 rc = gnutls_certificate_set_x509_system_trust(gtls->cred);
467 if(rc < 0)
468 infof(data, "error reading native ca store (%s), continuing anyway",
469 gnutls_strerror(rc));
470 else {
471 infof(data, "found %d certificates in native ca store", rc);
472 if(rc > 0)
473 imported_native_ca = true;
474 }
475 }
476
477 if(config->CAfile) {
478 /* set the trusted CA cert bundle file */
479 gnutls_certificate_set_verify_flags(gtls->cred,
480 GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
481
482 rc = gnutls_certificate_set_x509_trust_file(gtls->cred,
483 config->CAfile,
484 GNUTLS_X509_FMT_PEM);
485 if(rc < 0) {
486 infof(data, "error reading ca cert file %s (%s)%s",
487 config->CAfile, gnutls_strerror(rc),
488 (imported_native_ca ? ", continuing anyway" : ""));
489 if(!imported_native_ca) {
490 ssl_config->certverifyresult = rc;
491 return CURLE_SSL_CACERT_BADFILE;
492 }
493 }
494 else
495 infof(data, "found %d certificates in %s", rc, config->CAfile);
496 }
497
498 if(config->CApath) {
499 /* set the trusted CA cert directory */
500 rc = gnutls_certificate_set_x509_trust_dir(gtls->cred,
501 config->CApath,
502 GNUTLS_X509_FMT_PEM);
503 if(rc < 0) {
504 infof(data, "error reading ca cert file %s (%s)%s",
505 config->CApath, gnutls_strerror(rc),
506 (imported_native_ca ? ", continuing anyway" : ""));
507 if(!imported_native_ca) {
508 ssl_config->certverifyresult = rc;
509 return CURLE_SSL_CACERT_BADFILE;
510 }
511 }
512 else
513 infof(data, "found %d certificates in %s", rc, config->CApath);
514 }
515 }
516
517 if(config->CRLfile) {
518 /* set the CRL list file */
519 rc = gnutls_certificate_set_x509_crl_file(gtls->cred,
520 config->CRLfile,
521 GNUTLS_X509_FMT_PEM);
522 if(rc < 0) {
523 failf(data, "error reading crl file %s (%s)",
524 config->CRLfile, gnutls_strerror(rc));
525 return CURLE_SSL_CRL_BADFILE;
526 }
527 else
528 infof(data, "found %d CRL in %s", rc, config->CRLfile);
529 }
530
531 gtls->trust_setup = TRUE;
532 return CURLE_OK;
533 }
534
gtls_sessionid_free(void * sessionid,size_t idsize)535 static void gtls_sessionid_free(void *sessionid, size_t idsize)
536 {
537 (void)idsize;
538 free(sessionid);
539 }
540
gtls_update_session_id(struct Curl_cfilter * cf,struct Curl_easy * data,gnutls_session_t session)541 static CURLcode gtls_update_session_id(struct Curl_cfilter *cf,
542 struct Curl_easy *data,
543 gnutls_session_t session)
544 {
545 struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
546 struct ssl_connect_data *connssl = cf->ctx;
547 CURLcode result = CURLE_OK;
548
549 if(ssl_config->primary.sessionid) {
550 /* we always unconditionally get the session id here, as even if we
551 already got it from the cache and asked to use it in the connection, it
552 might've been rejected and then a new one is in use now and we need to
553 detect that. */
554 void *connect_sessionid;
555 size_t connect_idsize = 0;
556
557 /* get the session ID data size */
558 gnutls_session_get_data(session, NULL, &connect_idsize);
559 connect_sessionid = malloc(connect_idsize); /* get a buffer for it */
560 if(!connect_sessionid) {
561 return CURLE_OUT_OF_MEMORY;
562 }
563 else {
564 bool incache;
565 void *ssl_sessionid;
566
567 /* extract session ID to the allocated buffer */
568 gnutls_session_get_data(session, connect_sessionid, &connect_idsize);
569
570 DEBUGF(infof(data, "get session id (len=%zu) and store in cache",
571 connect_idsize));
572 Curl_ssl_sessionid_lock(data);
573 incache = !(Curl_ssl_getsessionid(cf, data, &connssl->peer,
574 &ssl_sessionid, NULL));
575 if(incache) {
576 /* there was one before in the cache, so instead of risking that the
577 previous one was rejected, we just kill that and store the new */
578 Curl_ssl_delsessionid(data, ssl_sessionid);
579 }
580
581 /* store this session id, takes ownership */
582 result = Curl_ssl_addsessionid(cf, data, &connssl->peer,
583 connect_sessionid, connect_idsize,
584 gtls_sessionid_free);
585 Curl_ssl_sessionid_unlock(data);
586 }
587 }
588 return result;
589 }
590
gtls_handshake_cb(gnutls_session_t session,unsigned int htype,unsigned when,unsigned int incoming,const gnutls_datum_t * msg)591 static int gtls_handshake_cb(gnutls_session_t session, unsigned int htype,
592 unsigned when, unsigned int incoming,
593 const gnutls_datum_t *msg)
594 {
595 struct Curl_cfilter *cf = gnutls_session_get_ptr(session);
596
597 (void)msg;
598 (void)incoming;
599 if(when) { /* after message has been processed */
600 struct Curl_easy *data = CF_DATA_CURRENT(cf);
601 if(data) {
602 DEBUGF(infof(data, "handshake: %s message type %d",
603 incoming? "incoming" : "outgoing", htype));
604 switch(htype) {
605 case GNUTLS_HANDSHAKE_NEW_SESSION_TICKET: {
606 gtls_update_session_id(cf, data, session);
607 break;
608 }
609 default:
610 break;
611 }
612 }
613 }
614 return 0;
615 }
616
gtls_client_init(struct Curl_cfilter * cf,struct Curl_easy * data,struct ssl_peer * peer,struct gtls_ctx * gtls)617 static CURLcode gtls_client_init(struct Curl_cfilter *cf,
618 struct Curl_easy *data,
619 struct ssl_peer *peer,
620 struct gtls_ctx *gtls)
621 {
622 struct ssl_primary_config *config = Curl_ssl_cf_get_primary_config(cf);
623 struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
624 unsigned int init_flags;
625 int rc;
626 bool sni = TRUE; /* default is SNI enabled */
627 const char *prioritylist;
628 const char *err = NULL;
629 const char *tls13support;
630 CURLcode result;
631
632 if(!gtls_inited)
633 gtls_init();
634
635 if(config->version == CURL_SSLVERSION_SSLv2) {
636 failf(data, "GnuTLS does not support SSLv2");
637 return CURLE_SSL_CONNECT_ERROR;
638 }
639 else if(config->version == CURL_SSLVERSION_SSLv3)
640 sni = FALSE; /* SSLv3 has no SNI */
641
642 /* allocate a cred struct */
643 rc = gnutls_certificate_allocate_credentials(>ls->cred);
644 if(rc != GNUTLS_E_SUCCESS) {
645 failf(data, "gnutls_cert_all_cred() failed: %s", gnutls_strerror(rc));
646 return CURLE_SSL_CONNECT_ERROR;
647 }
648
649 #ifdef USE_GNUTLS_SRP
650 if(config->username && Curl_auth_allowed_to_host(data)) {
651 infof(data, "Using TLS-SRP username: %s", config->username);
652
653 rc = gnutls_srp_allocate_client_credentials(>ls->srp_client_cred);
654 if(rc != GNUTLS_E_SUCCESS) {
655 failf(data, "gnutls_srp_allocate_client_cred() failed: %s",
656 gnutls_strerror(rc));
657 return CURLE_OUT_OF_MEMORY;
658 }
659
660 rc = gnutls_srp_set_client_credentials(gtls->srp_client_cred,
661 config->username,
662 config->password);
663 if(rc != GNUTLS_E_SUCCESS) {
664 failf(data, "gnutls_srp_set_client_cred() failed: %s",
665 gnutls_strerror(rc));
666 return CURLE_BAD_FUNCTION_ARGUMENT;
667 }
668 }
669 #endif
670
671 ssl_config->certverifyresult = 0;
672
673 /* Initialize TLS session as a client */
674 init_flags = GNUTLS_CLIENT;
675
676 #if defined(GNUTLS_FORCE_CLIENT_CERT)
677 init_flags |= GNUTLS_FORCE_CLIENT_CERT;
678 #endif
679
680 #if defined(GNUTLS_NO_TICKETS)
681 /* Disable TLS session tickets */
682 init_flags |= GNUTLS_NO_TICKETS;
683 #endif
684
685 #if defined(GNUTLS_NO_STATUS_REQUEST)
686 if(!config->verifystatus)
687 /* Disable the "status_request" TLS extension, enabled by default since
688 GnuTLS 3.8.0. */
689 init_flags |= GNUTLS_NO_STATUS_REQUEST;
690 #endif
691
692 rc = gnutls_init(>ls->session, init_flags);
693 if(rc != GNUTLS_E_SUCCESS) {
694 failf(data, "gnutls_init() failed: %d", rc);
695 return CURLE_SSL_CONNECT_ERROR;
696 }
697
698 if(sni && peer->sni) {
699 if(gnutls_server_name_set(gtls->session, GNUTLS_NAME_DNS,
700 peer->sni, strlen(peer->sni)) < 0) {
701 failf(data, "Failed to set SNI");
702 return CURLE_SSL_CONNECT_ERROR;
703 }
704 }
705
706 /* Use default priorities */
707 rc = gnutls_set_default_priority(gtls->session);
708 if(rc != GNUTLS_E_SUCCESS)
709 return CURLE_SSL_CONNECT_ERROR;
710
711 /* "In GnuTLS 3.6.5, TLS 1.3 is enabled by default" */
712 tls13support = gnutls_check_version("3.6.5");
713
714 /* Ensure +SRP comes at the *end* of all relevant strings so that it can be
715 * removed if a run-time error indicates that SRP is not supported by this
716 * GnuTLS version */
717
718 if(config->version == CURL_SSLVERSION_SSLv2 ||
719 config->version == CURL_SSLVERSION_SSLv3) {
720 failf(data, "GnuTLS does not support SSLv2 or SSLv3");
721 return CURLE_SSL_CONNECT_ERROR;
722 }
723
724 if(config->version == CURL_SSLVERSION_TLSv1_3) {
725 if(!tls13support) {
726 failf(data, "This GnuTLS installation does not support TLS 1.3");
727 return CURLE_SSL_CONNECT_ERROR;
728 }
729 }
730
731 /* At this point we know we have a supported TLS version, so set it */
732 result = set_ssl_version_min_max(data, peer,
733 config, &prioritylist, tls13support);
734 if(result)
735 return result;
736
737 #ifdef USE_GNUTLS_SRP
738 /* Only add SRP to the cipher list if SRP is requested. Otherwise
739 * GnuTLS will disable TLS 1.3 support. */
740 if(config->username) {
741 char *prioritysrp = aprintf("%s:" GNUTLS_SRP, prioritylist);
742 if(!prioritysrp)
743 return CURLE_OUT_OF_MEMORY;
744 rc = gnutls_priority_set_direct(gtls->session, prioritysrp, &err);
745 free(prioritysrp);
746
747 if((rc == GNUTLS_E_INVALID_REQUEST) && err) {
748 infof(data, "This GnuTLS does not support SRP");
749 }
750 }
751 else {
752 #endif
753 infof(data, "GnuTLS ciphers: %s", prioritylist);
754 rc = gnutls_priority_set_direct(gtls->session, prioritylist, &err);
755 #ifdef USE_GNUTLS_SRP
756 }
757 #endif
758
759 if(rc != GNUTLS_E_SUCCESS) {
760 failf(data, "Error %d setting GnuTLS cipher list starting with %s",
761 rc, err);
762 return CURLE_SSL_CONNECT_ERROR;
763 }
764
765 if(config->clientcert) {
766 if(!gtls->trust_setup) {
767 result = Curl_gtls_client_trust_setup(cf, data, gtls);
768 if(result)
769 return result;
770 }
771 if(ssl_config->key_passwd) {
772 const unsigned int supported_key_encryption_algorithms =
773 GNUTLS_PKCS_USE_PKCS12_3DES | GNUTLS_PKCS_USE_PKCS12_ARCFOUR |
774 GNUTLS_PKCS_USE_PKCS12_RC2_40 | GNUTLS_PKCS_USE_PBES2_3DES |
775 GNUTLS_PKCS_USE_PBES2_AES_128 | GNUTLS_PKCS_USE_PBES2_AES_192 |
776 GNUTLS_PKCS_USE_PBES2_AES_256;
777 rc = gnutls_certificate_set_x509_key_file2(
778 gtls->cred,
779 config->clientcert,
780 ssl_config->key ? ssl_config->key : config->clientcert,
781 do_file_type(ssl_config->cert_type),
782 ssl_config->key_passwd,
783 supported_key_encryption_algorithms);
784 if(rc != GNUTLS_E_SUCCESS) {
785 failf(data,
786 "error reading X.509 potentially-encrypted key file: %s",
787 gnutls_strerror(rc));
788 return CURLE_SSL_CONNECT_ERROR;
789 }
790 }
791 else {
792 if(gnutls_certificate_set_x509_key_file(
793 gtls->cred,
794 config->clientcert,
795 ssl_config->key ? ssl_config->key : config->clientcert,
796 do_file_type(ssl_config->cert_type) ) !=
797 GNUTLS_E_SUCCESS) {
798 failf(data, "error reading X.509 key or certificate file");
799 return CURLE_SSL_CONNECT_ERROR;
800 }
801 }
802 }
803
804 #ifdef USE_GNUTLS_SRP
805 /* put the credentials to the current session */
806 if(config->username) {
807 rc = gnutls_credentials_set(gtls->session, GNUTLS_CRD_SRP,
808 gtls->srp_client_cred);
809 if(rc != GNUTLS_E_SUCCESS) {
810 failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc));
811 return CURLE_SSL_CONNECT_ERROR;
812 }
813 }
814 else
815 #endif
816 {
817 rc = gnutls_credentials_set(gtls->session, GNUTLS_CRD_CERTIFICATE,
818 gtls->cred);
819 if(rc != GNUTLS_E_SUCCESS) {
820 failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc));
821 return CURLE_SSL_CONNECT_ERROR;
822 }
823 }
824
825 if(config->verifystatus) {
826 rc = gnutls_ocsp_status_request_enable_client(gtls->session,
827 NULL, 0, NULL);
828 if(rc != GNUTLS_E_SUCCESS) {
829 failf(data, "gnutls_ocsp_status_request_enable_client() failed: %d", rc);
830 return CURLE_SSL_CONNECT_ERROR;
831 }
832 }
833
834 return CURLE_OK;
835 }
836
keylog_callback(gnutls_session_t session,const char * label,const gnutls_datum_t * secret)837 static int keylog_callback(gnutls_session_t session, const char *label,
838 const gnutls_datum_t *secret)
839 {
840 gnutls_datum_t crandom;
841 gnutls_datum_t srandom;
842
843 gnutls_session_get_random(session, &crandom, &srandom);
844 if(crandom.size != 32) {
845 return -1;
846 }
847
848 Curl_tls_keylog_write(label, crandom.data, secret->data, secret->size);
849 return 0;
850 }
851
Curl_gtls_ctx_init(struct gtls_ctx * gctx,struct Curl_cfilter * cf,struct Curl_easy * data,struct ssl_peer * peer,const unsigned char * alpn,size_t alpn_len,Curl_gtls_ctx_setup_cb * cb_setup,void * cb_user_data,void * ssl_user_data)852 CURLcode Curl_gtls_ctx_init(struct gtls_ctx *gctx,
853 struct Curl_cfilter *cf,
854 struct Curl_easy *data,
855 struct ssl_peer *peer,
856 const unsigned char *alpn, size_t alpn_len,
857 Curl_gtls_ctx_setup_cb *cb_setup,
858 void *cb_user_data,
859 void *ssl_user_data)
860 {
861 struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
862 CURLcode result;
863
864 DEBUGASSERT(gctx);
865
866 result = gtls_client_init(cf, data, peer, gctx);
867 if(result)
868 return result;
869
870 gnutls_session_set_ptr(gctx->session, ssl_user_data);
871
872 if(cb_setup) {
873 result = cb_setup(cf, data, cb_user_data);
874 if(result)
875 return result;
876 }
877
878 /* Open the file if a TLS or QUIC backend has not done this before. */
879 Curl_tls_keylog_open();
880 if(Curl_tls_keylog_enabled()) {
881 gnutls_session_set_keylog_function(gctx->session, keylog_callback);
882 }
883
884 /* convert the ALPN string from our arguments to a list of strings
885 * that gnutls wants and will convert internally back to this very
886 * string for sending to the server. nice. */
887 if(alpn && alpn_len) {
888 gnutls_datum_t alpns[5];
889 size_t i, alen = alpn_len;
890 unsigned char *s = (unsigned char *)alpn;
891 unsigned char slen;
892 for(i = 0; (i < ARRAYSIZE(alpns)) && alen; ++i) {
893 slen = s[0];
894 if(slen >= alen)
895 return CURLE_FAILED_INIT;
896 alpns[i].data = s + 1;
897 alpns[i].size = slen;
898 s += slen + 1;
899 alen -= (size_t)slen + 1;
900 }
901 if(alen) /* not all alpn chars used, wrong format or too many */
902 return CURLE_FAILED_INIT;
903 if(i && gnutls_alpn_set_protocols(gctx->session,
904 alpns, (unsigned int)i,
905 GNUTLS_ALPN_MANDATORY)) {
906 failf(data, "failed setting ALPN");
907 return CURLE_SSL_CONNECT_ERROR;
908 }
909 }
910
911 /* This might be a reconnect, so we check for a session ID in the cache
912 to speed up things */
913 if(conn_config->sessionid) {
914 void *ssl_sessionid;
915 size_t ssl_idsize;
916
917 Curl_ssl_sessionid_lock(data);
918 if(!Curl_ssl_getsessionid(cf, data, peer, &ssl_sessionid, &ssl_idsize)) {
919 /* we got a session id, use it! */
920 int rc;
921
922 rc = gnutls_session_set_data(gctx->session, ssl_sessionid, ssl_idsize);
923 if(rc < 0)
924 infof(data, "SSL failed to set session ID");
925 else
926 infof(data, "SSL reusing session ID (size=%zu)", ssl_idsize);
927 }
928 Curl_ssl_sessionid_unlock(data);
929 }
930 return CURLE_OK;
931 }
932
933 static CURLcode
gtls_connect_step1(struct Curl_cfilter * cf,struct Curl_easy * data)934 gtls_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
935 {
936 struct ssl_connect_data *connssl = cf->ctx;
937 struct gtls_ssl_backend_data *backend =
938 (struct gtls_ssl_backend_data *)connssl->backend;
939 struct alpn_proto_buf proto;
940 CURLcode result;
941
942 DEBUGASSERT(backend);
943 DEBUGASSERT(ssl_connect_1 == connssl->connecting_state);
944
945 if(connssl->state == ssl_connection_complete)
946 /* to make us tolerant against being called more than once for the
947 same connection */
948 return CURLE_OK;
949
950 memset(&proto, 0, sizeof(proto));
951 if(connssl->alpn) {
952 result = Curl_alpn_to_proto_buf(&proto, connssl->alpn);
953 if(result) {
954 failf(data, "Error determining ALPN");
955 return CURLE_SSL_CONNECT_ERROR;
956 }
957 }
958
959 result = Curl_gtls_ctx_init(&backend->gtls, cf, data, &connssl->peer,
960 proto.data, proto.len, NULL, NULL, cf);
961 if(result)
962 return result;
963
964 gnutls_handshake_set_hook_function(backend->gtls.session,
965 GNUTLS_HANDSHAKE_ANY, GNUTLS_HOOK_POST,
966 gtls_handshake_cb);
967
968 /* register callback functions and handle to send and receive data. */
969 gnutls_transport_set_ptr(backend->gtls.session, cf);
970 gnutls_transport_set_push_function(backend->gtls.session, gtls_push);
971 gnutls_transport_set_pull_function(backend->gtls.session, gtls_pull);
972
973 return CURLE_OK;
974 }
975
pkp_pin_peer_pubkey(struct Curl_easy * data,gnutls_x509_crt_t cert,const char * pinnedpubkey)976 static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
977 gnutls_x509_crt_t cert,
978 const char *pinnedpubkey)
979 {
980 /* Scratch */
981 size_t len1 = 0, len2 = 0;
982 unsigned char *buff1 = NULL;
983
984 gnutls_pubkey_t key = NULL;
985
986 /* Result is returned to caller */
987 CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
988
989 /* if a path wasn't specified, don't pin */
990 if(!pinnedpubkey)
991 return CURLE_OK;
992
993 if(!cert)
994 return result;
995
996 do {
997 int ret;
998
999 /* Begin Gyrations to get the public key */
1000 gnutls_pubkey_init(&key);
1001
1002 ret = gnutls_pubkey_import_x509(key, cert, 0);
1003 if(ret < 0)
1004 break; /* failed */
1005
1006 ret = gnutls_pubkey_export(key, GNUTLS_X509_FMT_DER, NULL, &len1);
1007 if(ret != GNUTLS_E_SHORT_MEMORY_BUFFER || len1 == 0)
1008 break; /* failed */
1009
1010 buff1 = malloc(len1);
1011 if(!buff1)
1012 break; /* failed */
1013
1014 len2 = len1;
1015
1016 ret = gnutls_pubkey_export(key, GNUTLS_X509_FMT_DER, buff1, &len2);
1017 if(ret < 0 || len1 != len2)
1018 break; /* failed */
1019
1020 /* End Gyrations */
1021
1022 /* The one good exit point */
1023 result = Curl_pin_peer_pubkey(data, pinnedpubkey, buff1, len1);
1024 } while(0);
1025
1026 if(key)
1027 gnutls_pubkey_deinit(key);
1028
1029 Curl_safefree(buff1);
1030
1031 return result;
1032 }
1033
1034 CURLcode
Curl_gtls_verifyserver(struct Curl_easy * data,gnutls_session_t session,struct ssl_primary_config * config,struct ssl_config_data * ssl_config,struct ssl_peer * peer,const char * pinned_key)1035 Curl_gtls_verifyserver(struct Curl_easy *data,
1036 gnutls_session_t session,
1037 struct ssl_primary_config *config,
1038 struct ssl_config_data *ssl_config,
1039 struct ssl_peer *peer,
1040 const char *pinned_key)
1041 {
1042 unsigned int cert_list_size;
1043 const gnutls_datum_t *chainp;
1044 unsigned int verify_status = 0;
1045 gnutls_x509_crt_t x509_cert, x509_issuer;
1046 gnutls_datum_t issuerp;
1047 gnutls_datum_t certfields;
1048 char certname[65] = ""; /* limited to 64 chars by ASN.1 */
1049 size_t size;
1050 time_t certclock;
1051 int rc;
1052 CURLcode result = CURLE_OK;
1053 #ifndef CURL_DISABLE_VERBOSE_STRINGS
1054 const char *ptr;
1055 unsigned int algo;
1056 unsigned int bits;
1057 gnutls_protocol_t version = gnutls_protocol_get_version(session);
1058 #endif
1059 long * const certverifyresult = &ssl_config->certverifyresult;
1060
1061 #ifndef CURL_DISABLE_VERBOSE_STRINGS
1062 /* the name of the cipher suite used, e.g. ECDHE_RSA_AES_256_GCM_SHA384. */
1063 ptr = gnutls_cipher_suite_get_name(gnutls_kx_get(session),
1064 gnutls_cipher_get(session),
1065 gnutls_mac_get(session));
1066
1067 infof(data, "SSL connection using %s / %s",
1068 gnutls_protocol_get_name(version), ptr);
1069 #endif
1070
1071 /* This function will return the peer's raw certificate (chain) as sent by
1072 the peer. These certificates are in raw format (DER encoded for
1073 X.509). In case of a X.509 then a certificate list may be present. The
1074 first certificate in the list is the peer's certificate, following the
1075 issuer's certificate, then the issuer's issuer etc. */
1076
1077 chainp = gnutls_certificate_get_peers(session, &cert_list_size);
1078 if(!chainp) {
1079 if(config->verifypeer ||
1080 config->verifyhost ||
1081 config->issuercert) {
1082 #ifdef USE_GNUTLS_SRP
1083 if(ssl_config->primary.username && !config->verifypeer &&
1084 gnutls_cipher_get(session)) {
1085 /* no peer cert, but auth is ok if we have SRP user and cipher and no
1086 peer verify */
1087 }
1088 else {
1089 #endif
1090 failf(data, "failed to get server cert");
1091 *certverifyresult = GNUTLS_E_NO_CERTIFICATE_FOUND;
1092 return CURLE_PEER_FAILED_VERIFICATION;
1093 #ifdef USE_GNUTLS_SRP
1094 }
1095 #endif
1096 }
1097 infof(data, " common name: WARNING couldn't obtain");
1098 }
1099
1100 if(data->set.ssl.certinfo && chainp) {
1101 unsigned int i;
1102
1103 result = Curl_ssl_init_certinfo(data, cert_list_size);
1104 if(result)
1105 return result;
1106
1107 for(i = 0; i < cert_list_size; i++) {
1108 const char *beg = (const char *) chainp[i].data;
1109 const char *end = beg + chainp[i].size;
1110
1111 result = Curl_extract_certinfo(data, i, beg, end);
1112 if(result)
1113 return result;
1114 }
1115 }
1116
1117 if(config->verifypeer) {
1118 /* This function will try to verify the peer's certificate and return its
1119 status (trusted, invalid etc.). The value of status should be one or
1120 more of the gnutls_certificate_status_t enumerated elements bitwise
1121 or'd. To avoid denial of service attacks some default upper limits
1122 regarding the certificate key size and chain size are set. To override
1123 them use gnutls_certificate_set_verify_limits(). */
1124
1125 rc = gnutls_certificate_verify_peers2(session, &verify_status);
1126 if(rc < 0) {
1127 failf(data, "server cert verify failed: %d", rc);
1128 *certverifyresult = rc;
1129 return CURLE_SSL_CONNECT_ERROR;
1130 }
1131
1132 *certverifyresult = verify_status;
1133
1134 /* verify_status is a bitmask of gnutls_certificate_status bits */
1135 if(verify_status & GNUTLS_CERT_INVALID) {
1136 if(config->verifypeer) {
1137 failf(data, "server certificate verification failed. CAfile: %s "
1138 "CRLfile: %s", config->CAfile ? config->CAfile:
1139 "none",
1140 ssl_config->primary.CRLfile ?
1141 ssl_config->primary.CRLfile : "none");
1142 return CURLE_PEER_FAILED_VERIFICATION;
1143 }
1144 else
1145 infof(data, " server certificate verification FAILED");
1146 }
1147 else
1148 infof(data, " server certificate verification OK");
1149 }
1150 else
1151 infof(data, " server certificate verification SKIPPED");
1152
1153 if(config->verifystatus) {
1154 gnutls_datum_t status_request;
1155 gnutls_ocsp_resp_t ocsp_resp;
1156
1157 gnutls_ocsp_cert_status_t status;
1158 gnutls_x509_crl_reason_t reason;
1159
1160 rc = gnutls_ocsp_status_request_get(session, &status_request);
1161
1162 infof(data, " server certificate status verification FAILED");
1163
1164 if(rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
1165 failf(data, "No OCSP response received");
1166 return CURLE_SSL_INVALIDCERTSTATUS;
1167 }
1168
1169 if(rc < 0) {
1170 failf(data, "Invalid OCSP response received");
1171 return CURLE_SSL_INVALIDCERTSTATUS;
1172 }
1173
1174 gnutls_ocsp_resp_init(&ocsp_resp);
1175
1176 rc = gnutls_ocsp_resp_import(ocsp_resp, &status_request);
1177 if(rc < 0) {
1178 failf(data, "Invalid OCSP response received");
1179 return CURLE_SSL_INVALIDCERTSTATUS;
1180 }
1181
1182 (void)gnutls_ocsp_resp_get_single(ocsp_resp, 0, NULL, NULL, NULL, NULL,
1183 &status, NULL, NULL, NULL, &reason);
1184
1185 switch(status) {
1186 case GNUTLS_OCSP_CERT_GOOD:
1187 break;
1188
1189 case GNUTLS_OCSP_CERT_REVOKED: {
1190 const char *crl_reason;
1191
1192 switch(reason) {
1193 default:
1194 case GNUTLS_X509_CRLREASON_UNSPECIFIED:
1195 crl_reason = "unspecified reason";
1196 break;
1197
1198 case GNUTLS_X509_CRLREASON_KEYCOMPROMISE:
1199 crl_reason = "private key compromised";
1200 break;
1201
1202 case GNUTLS_X509_CRLREASON_CACOMPROMISE:
1203 crl_reason = "CA compromised";
1204 break;
1205
1206 case GNUTLS_X509_CRLREASON_AFFILIATIONCHANGED:
1207 crl_reason = "affiliation has changed";
1208 break;
1209
1210 case GNUTLS_X509_CRLREASON_SUPERSEDED:
1211 crl_reason = "certificate superseded";
1212 break;
1213
1214 case GNUTLS_X509_CRLREASON_CESSATIONOFOPERATION:
1215 crl_reason = "operation has ceased";
1216 break;
1217
1218 case GNUTLS_X509_CRLREASON_CERTIFICATEHOLD:
1219 crl_reason = "certificate is on hold";
1220 break;
1221
1222 case GNUTLS_X509_CRLREASON_REMOVEFROMCRL:
1223 crl_reason = "will be removed from delta CRL";
1224 break;
1225
1226 case GNUTLS_X509_CRLREASON_PRIVILEGEWITHDRAWN:
1227 crl_reason = "privilege withdrawn";
1228 break;
1229
1230 case GNUTLS_X509_CRLREASON_AACOMPROMISE:
1231 crl_reason = "AA compromised";
1232 break;
1233 }
1234
1235 failf(data, "Server certificate was revoked: %s", crl_reason);
1236 break;
1237 }
1238
1239 default:
1240 case GNUTLS_OCSP_CERT_UNKNOWN:
1241 failf(data, "Server certificate status is unknown");
1242 break;
1243 }
1244
1245 gnutls_ocsp_resp_deinit(ocsp_resp);
1246 if(status != GNUTLS_OCSP_CERT_GOOD)
1247 return CURLE_SSL_INVALIDCERTSTATUS;
1248 }
1249 else
1250 infof(data, " server certificate status verification SKIPPED");
1251
1252 /* initialize an X.509 certificate structure. */
1253 gnutls_x509_crt_init(&x509_cert);
1254
1255 if(chainp)
1256 /* convert the given DER or PEM encoded Certificate to the native
1257 gnutls_x509_crt_t format */
1258 gnutls_x509_crt_import(x509_cert, chainp, GNUTLS_X509_FMT_DER);
1259
1260 if(config->issuercert) {
1261 gnutls_x509_crt_init(&x509_issuer);
1262 issuerp = load_file(config->issuercert);
1263 gnutls_x509_crt_import(x509_issuer, &issuerp, GNUTLS_X509_FMT_PEM);
1264 rc = gnutls_x509_crt_check_issuer(x509_cert, x509_issuer);
1265 gnutls_x509_crt_deinit(x509_issuer);
1266 unload_file(issuerp);
1267 if(rc <= 0) {
1268 failf(data, "server certificate issuer check failed (IssuerCert: %s)",
1269 config->issuercert?config->issuercert:"none");
1270 gnutls_x509_crt_deinit(x509_cert);
1271 return CURLE_SSL_ISSUER_ERROR;
1272 }
1273 infof(data, " server certificate issuer check OK (Issuer Cert: %s)",
1274 config->issuercert?config->issuercert:"none");
1275 }
1276
1277 size = sizeof(certname);
1278 rc = gnutls_x509_crt_get_dn_by_oid(x509_cert, GNUTLS_OID_X520_COMMON_NAME,
1279 0, /* the first and only one */
1280 FALSE,
1281 certname,
1282 &size);
1283 if(rc) {
1284 infof(data, "error fetching CN from cert:%s",
1285 gnutls_strerror(rc));
1286 }
1287
1288 /* This function will check if the given certificate's subject matches the
1289 given hostname. This is a basic implementation of the matching described
1290 in RFC2818 (HTTPS), which takes into account wildcards, and the subject
1291 alternative name PKIX extension. Returns non zero on success, and zero on
1292 failure. */
1293 rc = gnutls_x509_crt_check_hostname(x509_cert, peer->hostname);
1294 #if GNUTLS_VERSION_NUMBER < 0x030306
1295 /* Before 3.3.6, gnutls_x509_crt_check_hostname() didn't check IP
1296 addresses. */
1297 if(!rc) {
1298 #ifdef USE_IPV6
1299 #define use_addr in6_addr
1300 #else
1301 #define use_addr in_addr
1302 #endif
1303 unsigned char addrbuf[sizeof(struct use_addr)];
1304 size_t addrlen = 0;
1305
1306 if(Curl_inet_pton(AF_INET, peer->hostname, addrbuf) > 0)
1307 addrlen = 4;
1308 #ifdef USE_IPV6
1309 else if(Curl_inet_pton(AF_INET6, peer->hostname, addrbuf) > 0)
1310 addrlen = 16;
1311 #endif
1312
1313 if(addrlen) {
1314 unsigned char certaddr[sizeof(struct use_addr)];
1315 int i;
1316
1317 for(i = 0; ; i++) {
1318 size_t certaddrlen = sizeof(certaddr);
1319 int ret = gnutls_x509_crt_get_subject_alt_name(x509_cert, i, certaddr,
1320 &certaddrlen, NULL);
1321 /* If this happens, it wasn't an IP address. */
1322 if(ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
1323 continue;
1324 if(ret < 0)
1325 break;
1326 if(ret != GNUTLS_SAN_IPADDRESS)
1327 continue;
1328 if(certaddrlen == addrlen && !memcmp(addrbuf, certaddr, addrlen)) {
1329 rc = 1;
1330 break;
1331 }
1332 }
1333 }
1334 }
1335 #endif
1336 if(!rc) {
1337 if(config->verifyhost) {
1338 failf(data, "SSL: certificate subject name (%s) does not match "
1339 "target host name '%s'", certname, peer->dispname);
1340 gnutls_x509_crt_deinit(x509_cert);
1341 return CURLE_PEER_FAILED_VERIFICATION;
1342 }
1343 else
1344 infof(data, " common name: %s (does not match '%s')",
1345 certname, peer->dispname);
1346 }
1347 else
1348 infof(data, " common name: %s (matched)", certname);
1349
1350 /* Check for time-based validity */
1351 certclock = gnutls_x509_crt_get_expiration_time(x509_cert);
1352
1353 if(certclock == (time_t)-1) {
1354 if(config->verifypeer) {
1355 failf(data, "server cert expiration date verify failed");
1356 *certverifyresult = GNUTLS_CERT_EXPIRED;
1357 gnutls_x509_crt_deinit(x509_cert);
1358 return CURLE_SSL_CONNECT_ERROR;
1359 }
1360 else
1361 infof(data, " server certificate expiration date verify FAILED");
1362 }
1363 else {
1364 if(certclock < time(NULL)) {
1365 if(config->verifypeer) {
1366 failf(data, "server certificate expiration date has passed.");
1367 *certverifyresult = GNUTLS_CERT_EXPIRED;
1368 gnutls_x509_crt_deinit(x509_cert);
1369 return CURLE_PEER_FAILED_VERIFICATION;
1370 }
1371 else
1372 infof(data, " server certificate expiration date FAILED");
1373 }
1374 else
1375 infof(data, " server certificate expiration date OK");
1376 }
1377
1378 certclock = gnutls_x509_crt_get_activation_time(x509_cert);
1379
1380 if(certclock == (time_t)-1) {
1381 if(config->verifypeer) {
1382 failf(data, "server cert activation date verify failed");
1383 *certverifyresult = GNUTLS_CERT_NOT_ACTIVATED;
1384 gnutls_x509_crt_deinit(x509_cert);
1385 return CURLE_SSL_CONNECT_ERROR;
1386 }
1387 else
1388 infof(data, " server certificate activation date verify FAILED");
1389 }
1390 else {
1391 if(certclock > time(NULL)) {
1392 if(config->verifypeer) {
1393 failf(data, "server certificate not activated yet.");
1394 *certverifyresult = GNUTLS_CERT_NOT_ACTIVATED;
1395 gnutls_x509_crt_deinit(x509_cert);
1396 return CURLE_PEER_FAILED_VERIFICATION;
1397 }
1398 else
1399 infof(data, " server certificate activation date FAILED");
1400 }
1401 else
1402 infof(data, " server certificate activation date OK");
1403 }
1404
1405 if(pinned_key) {
1406 result = pkp_pin_peer_pubkey(data, x509_cert, pinned_key);
1407 if(result != CURLE_OK) {
1408 failf(data, "SSL: public key does not match pinned public key");
1409 gnutls_x509_crt_deinit(x509_cert);
1410 return result;
1411 }
1412 }
1413
1414 /* Show:
1415
1416 - subject
1417 - start date
1418 - expire date
1419 - common name
1420 - issuer
1421
1422 */
1423
1424 #ifndef CURL_DISABLE_VERBOSE_STRINGS
1425 /* public key algorithm's parameters */
1426 algo = gnutls_x509_crt_get_pk_algorithm(x509_cert, &bits);
1427 infof(data, " certificate public key: %s",
1428 gnutls_pk_algorithm_get_name(algo));
1429
1430 /* version of the X.509 certificate. */
1431 infof(data, " certificate version: #%d",
1432 gnutls_x509_crt_get_version(x509_cert));
1433
1434
1435 rc = gnutls_x509_crt_get_dn2(x509_cert, &certfields);
1436 if(rc)
1437 infof(data, "Failed to get certificate name");
1438 else {
1439 infof(data, " subject: %s", certfields.data);
1440
1441 certclock = gnutls_x509_crt_get_activation_time(x509_cert);
1442 showtime(data, "start date", certclock);
1443
1444 certclock = gnutls_x509_crt_get_expiration_time(x509_cert);
1445 showtime(data, "expire date", certclock);
1446
1447 gnutls_free(certfields.data);
1448 }
1449
1450 rc = gnutls_x509_crt_get_issuer_dn2(x509_cert, &certfields);
1451 if(rc)
1452 infof(data, "Failed to get certificate issuer");
1453 else {
1454 infof(data, " issuer: %s", certfields.data);
1455
1456 gnutls_free(certfields.data);
1457 }
1458 #endif
1459
1460 gnutls_x509_crt_deinit(x509_cert);
1461
1462 return result;
1463 }
1464
gtls_verifyserver(struct Curl_cfilter * cf,struct Curl_easy * data,gnutls_session_t session)1465 static CURLcode gtls_verifyserver(struct Curl_cfilter *cf,
1466 struct Curl_easy *data,
1467 gnutls_session_t session)
1468 {
1469 struct ssl_connect_data *connssl = cf->ctx;
1470 struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
1471 struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
1472 #ifndef CURL_DISABLE_PROXY
1473 const char *pinned_key = Curl_ssl_cf_is_proxy(cf)?
1474 data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY]:
1475 data->set.str[STRING_SSL_PINNEDPUBLICKEY];
1476 #else
1477 const char *pinned_key = data->set.str[STRING_SSL_PINNEDPUBLICKEY];
1478 #endif
1479 CURLcode result;
1480
1481 result = Curl_gtls_verifyserver(data, session, conn_config, ssl_config,
1482 &connssl->peer, pinned_key);
1483 if(result)
1484 goto out;
1485
1486 if(connssl->alpn) {
1487 gnutls_datum_t proto;
1488 int rc;
1489
1490 rc = gnutls_alpn_get_selected_protocol(session, &proto);
1491 if(rc == 0)
1492 Curl_alpn_set_negotiated(cf, data, proto.data, proto.size);
1493 else
1494 Curl_alpn_set_negotiated(cf, data, NULL, 0);
1495 }
1496
1497 /* Only on TLSv1.2 or lower do we have the session id now. For
1498 * TLSv1.3 we get it via a SESSION_TICKET message that arrives later. */
1499 if(gnutls_protocol_get_version(session) < GNUTLS_TLS1_3)
1500 result = gtls_update_session_id(cf, data, session);
1501
1502 out:
1503 return result;
1504 }
1505
1506 /*
1507 * This function is called after the TCP connect has completed. Setup the TLS
1508 * layer and do all necessary magic.
1509 */
1510 /* We use connssl->connecting_state to keep track of the connection status;
1511 there are three states: 'ssl_connect_1' (not started yet or complete),
1512 'ssl_connect_2_reading' (waiting for data from server), and
1513 'ssl_connect_2_writing' (waiting to be able to write).
1514 */
1515 static CURLcode
gtls_connect_common(struct Curl_cfilter * cf,struct Curl_easy * data,bool nonblocking,bool * done)1516 gtls_connect_common(struct Curl_cfilter *cf,
1517 struct Curl_easy *data,
1518 bool nonblocking,
1519 bool *done)
1520 {
1521 struct ssl_connect_data *connssl = cf->ctx;
1522 int rc;
1523 CURLcode result = CURLE_OK;
1524
1525 /* Initiate the connection, if not already done */
1526 if(ssl_connect_1 == connssl->connecting_state) {
1527 rc = gtls_connect_step1(cf, data);
1528 if(rc) {
1529 result = rc;
1530 goto out;
1531 }
1532 }
1533
1534 rc = handshake(cf, data, TRUE, nonblocking);
1535 if(rc) {
1536 /* handshake() sets its own error message with failf() */
1537 result = rc;
1538 goto out;
1539 }
1540
1541 /* Finish connecting once the handshake is done */
1542 if(ssl_connect_1 == connssl->connecting_state) {
1543 struct gtls_ssl_backend_data *backend =
1544 (struct gtls_ssl_backend_data *)connssl->backend;
1545 gnutls_session_t session;
1546 DEBUGASSERT(backend);
1547 session = backend->gtls.session;
1548 rc = gtls_verifyserver(cf, data, session);
1549 if(rc) {
1550 result = rc;
1551 goto out;
1552 }
1553 connssl->state = ssl_connection_complete;
1554 }
1555
1556 out:
1557 *done = ssl_connect_1 == connssl->connecting_state;
1558
1559 return result;
1560 }
1561
gtls_connect_nonblocking(struct Curl_cfilter * cf,struct Curl_easy * data,bool * done)1562 static CURLcode gtls_connect_nonblocking(struct Curl_cfilter *cf,
1563 struct Curl_easy *data,
1564 bool *done)
1565 {
1566 return gtls_connect_common(cf, data, TRUE, done);
1567 }
1568
gtls_connect(struct Curl_cfilter * cf,struct Curl_easy * data)1569 static CURLcode gtls_connect(struct Curl_cfilter *cf,
1570 struct Curl_easy *data)
1571 {
1572 CURLcode result;
1573 bool done = FALSE;
1574
1575 result = gtls_connect_common(cf, data, FALSE, &done);
1576 if(result)
1577 return result;
1578
1579 DEBUGASSERT(done);
1580
1581 return CURLE_OK;
1582 }
1583
gtls_data_pending(struct Curl_cfilter * cf,const struct Curl_easy * data)1584 static bool gtls_data_pending(struct Curl_cfilter *cf,
1585 const struct Curl_easy *data)
1586 {
1587 struct ssl_connect_data *ctx = cf->ctx;
1588 struct gtls_ssl_backend_data *backend;
1589
1590 (void)data;
1591 DEBUGASSERT(ctx && ctx->backend);
1592 backend = (struct gtls_ssl_backend_data *)ctx->backend;
1593 if(backend->gtls.session &&
1594 0 != gnutls_record_check_pending(backend->gtls.session))
1595 return TRUE;
1596 return FALSE;
1597 }
1598
gtls_send(struct Curl_cfilter * cf,struct Curl_easy * data,const void * mem,size_t len,CURLcode * curlcode)1599 static ssize_t gtls_send(struct Curl_cfilter *cf,
1600 struct Curl_easy *data,
1601 const void *mem,
1602 size_t len,
1603 CURLcode *curlcode)
1604 {
1605 struct ssl_connect_data *connssl = cf->ctx;
1606 struct gtls_ssl_backend_data *backend =
1607 (struct gtls_ssl_backend_data *)connssl->backend;
1608 ssize_t rc;
1609
1610 (void)data;
1611 DEBUGASSERT(backend);
1612 backend->gtls.io_result = CURLE_OK;
1613 rc = gnutls_record_send(backend->gtls.session, mem, len);
1614
1615 if(rc < 0) {
1616 *curlcode = (rc == GNUTLS_E_AGAIN)?
1617 CURLE_AGAIN :
1618 (backend->gtls.io_result? backend->gtls.io_result : CURLE_SEND_ERROR);
1619
1620 rc = -1;
1621 }
1622
1623 return rc;
1624 }
1625
gtls_close(struct Curl_cfilter * cf,struct Curl_easy * data)1626 static void gtls_close(struct Curl_cfilter *cf,
1627 struct Curl_easy *data)
1628 {
1629 struct ssl_connect_data *connssl = cf->ctx;
1630 struct gtls_ssl_backend_data *backend =
1631 (struct gtls_ssl_backend_data *)connssl->backend;
1632
1633 (void) data;
1634 DEBUGASSERT(backend);
1635
1636 if(backend->gtls.session) {
1637 char buf[32];
1638 /* Maybe the server has already sent a close notify alert.
1639 Read it to avoid an RST on the TCP connection. */
1640 (void)gnutls_record_recv(backend->gtls.session, buf, sizeof(buf));
1641 gnutls_bye(backend->gtls.session, GNUTLS_SHUT_WR);
1642 gnutls_deinit(backend->gtls.session);
1643 backend->gtls.session = NULL;
1644 }
1645 if(backend->gtls.cred) {
1646 gnutls_certificate_free_credentials(backend->gtls.cred);
1647 backend->gtls.cred = NULL;
1648 }
1649 #ifdef USE_GNUTLS_SRP
1650 if(backend->gtls.srp_client_cred) {
1651 gnutls_srp_free_client_credentials(backend->gtls.srp_client_cred);
1652 backend->gtls.srp_client_cred = NULL;
1653 }
1654 #endif
1655 }
1656
1657 /*
1658 * This function is called to shut down the SSL layer but keep the
1659 * socket open (CCC - Clear Command Channel)
1660 */
gtls_shutdown(struct Curl_cfilter * cf,struct Curl_easy * data)1661 static int gtls_shutdown(struct Curl_cfilter *cf,
1662 struct Curl_easy *data)
1663 {
1664 struct ssl_connect_data *connssl = cf->ctx;
1665 struct gtls_ssl_backend_data *backend =
1666 (struct gtls_ssl_backend_data *)connssl->backend;
1667 int retval = 0;
1668
1669 DEBUGASSERT(backend);
1670
1671 #ifndef CURL_DISABLE_FTP
1672 /* This has only been tested on the proftpd server, and the mod_tls code
1673 sends a close notify alert without waiting for a close notify alert in
1674 response. Thus we wait for a close notify alert from the server, but
1675 we do not send one. Let's hope other servers do the same... */
1676
1677 if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
1678 gnutls_bye(backend->gtls.session, GNUTLS_SHUT_WR);
1679 #endif
1680
1681 if(backend->gtls.session) {
1682 ssize_t result;
1683 bool done = FALSE;
1684 char buf[120];
1685
1686 while(!done && !connssl->peer_closed) {
1687 int what = SOCKET_READABLE(Curl_conn_cf_get_socket(cf, data),
1688 SSL_SHUTDOWN_TIMEOUT);
1689 if(what > 0) {
1690 /* Something to read, let's do it and hope that it is the close
1691 notify alert from the server */
1692 result = gnutls_record_recv(backend->gtls.session,
1693 buf, sizeof(buf));
1694 switch(result) {
1695 case 0:
1696 /* This is the expected response. There was no data but only
1697 the close notify alert */
1698 done = TRUE;
1699 break;
1700 case GNUTLS_E_AGAIN:
1701 case GNUTLS_E_INTERRUPTED:
1702 infof(data, "GNUTLS_E_AGAIN || GNUTLS_E_INTERRUPTED");
1703 break;
1704 default:
1705 retval = -1;
1706 done = TRUE;
1707 break;
1708 }
1709 }
1710 else if(0 == what) {
1711 /* timeout */
1712 failf(data, "SSL shutdown timeout");
1713 done = TRUE;
1714 }
1715 else {
1716 /* anything that gets here is fatally bad */
1717 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
1718 retval = -1;
1719 done = TRUE;
1720 }
1721 }
1722 gnutls_deinit(backend->gtls.session);
1723 }
1724 gnutls_certificate_free_credentials(backend->gtls.cred);
1725
1726 #ifdef USE_GNUTLS_SRP
1727 {
1728 struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
1729 if(ssl_config->primary.username)
1730 gnutls_srp_free_client_credentials(backend->gtls.srp_client_cred);
1731 }
1732 #endif
1733
1734 backend->gtls.cred = NULL;
1735 backend->gtls.session = NULL;
1736
1737 return retval;
1738 }
1739
gtls_recv(struct Curl_cfilter * cf,struct Curl_easy * data,char * buf,size_t buffersize,CURLcode * curlcode)1740 static ssize_t gtls_recv(struct Curl_cfilter *cf,
1741 struct Curl_easy *data,
1742 char *buf,
1743 size_t buffersize,
1744 CURLcode *curlcode)
1745 {
1746 struct ssl_connect_data *connssl = cf->ctx;
1747 struct gtls_ssl_backend_data *backend =
1748 (struct gtls_ssl_backend_data *)connssl->backend;
1749 ssize_t ret;
1750
1751 (void)data;
1752 DEBUGASSERT(backend);
1753
1754 backend->gtls.io_result = CURLE_OK;
1755 ret = gnutls_record_recv(backend->gtls.session, buf, buffersize);
1756 if((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED)) {
1757 *curlcode = CURLE_AGAIN;
1758 ret = -1;
1759 goto out;
1760 }
1761
1762 if(ret == GNUTLS_E_REHANDSHAKE) {
1763 /* BLOCKING call, this is bad but a work-around for now. Fixing this "the
1764 proper way" takes a whole lot of work. */
1765 CURLcode result = handshake(cf, data, FALSE, FALSE);
1766 if(result)
1767 /* handshake() writes error message on its own */
1768 *curlcode = result;
1769 else
1770 *curlcode = CURLE_AGAIN; /* then return as if this was a wouldblock */
1771 ret = -1;
1772 goto out;
1773 }
1774
1775 if(ret < 0) {
1776 failf(data, "GnuTLS recv error (%d): %s",
1777
1778 (int)ret, gnutls_strerror((int)ret));
1779 *curlcode = backend->gtls.io_result?
1780 backend->gtls.io_result : CURLE_RECV_ERROR;
1781 ret = -1;
1782 goto out;
1783 }
1784
1785 out:
1786 return ret;
1787 }
1788
gtls_version(char * buffer,size_t size)1789 static size_t gtls_version(char *buffer, size_t size)
1790 {
1791 return msnprintf(buffer, size, "GnuTLS/%s", gnutls_check_version(NULL));
1792 }
1793
1794 /* data might be NULL! */
gtls_random(struct Curl_easy * data,unsigned char * entropy,size_t length)1795 static CURLcode gtls_random(struct Curl_easy *data,
1796 unsigned char *entropy, size_t length)
1797 {
1798 int rc;
1799 (void)data;
1800 rc = gnutls_rnd(GNUTLS_RND_RANDOM, entropy, length);
1801 return rc?CURLE_FAILED_INIT:CURLE_OK;
1802 }
1803
gtls_sha256sum(const unsigned char * tmp,size_t tmplen,unsigned char * sha256sum,size_t sha256len)1804 static CURLcode gtls_sha256sum(const unsigned char *tmp, /* input */
1805 size_t tmplen,
1806 unsigned char *sha256sum, /* output */
1807 size_t sha256len)
1808 {
1809 struct sha256_ctx SHA256pw;
1810 sha256_init(&SHA256pw);
1811 sha256_update(&SHA256pw, (unsigned int)tmplen, tmp);
1812 sha256_digest(&SHA256pw, (unsigned int)sha256len, sha256sum);
1813 return CURLE_OK;
1814 }
1815
gtls_cert_status_request(void)1816 static bool gtls_cert_status_request(void)
1817 {
1818 return TRUE;
1819 }
1820
gtls_get_internals(struct ssl_connect_data * connssl,CURLINFO info UNUSED_PARAM)1821 static void *gtls_get_internals(struct ssl_connect_data *connssl,
1822 CURLINFO info UNUSED_PARAM)
1823 {
1824 struct gtls_ssl_backend_data *backend =
1825 (struct gtls_ssl_backend_data *)connssl->backend;
1826 (void)info;
1827 DEBUGASSERT(backend);
1828 return backend->gtls.session;
1829 }
1830
1831 const struct Curl_ssl Curl_ssl_gnutls = {
1832 { CURLSSLBACKEND_GNUTLS, "gnutls" }, /* info */
1833
1834 SSLSUPP_CA_PATH |
1835 SSLSUPP_CERTINFO |
1836 SSLSUPP_PINNEDPUBKEY |
1837 SSLSUPP_HTTPS_PROXY,
1838
1839 sizeof(struct gtls_ssl_backend_data),
1840
1841 gtls_init, /* init */
1842 gtls_cleanup, /* cleanup */
1843 gtls_version, /* version */
1844 Curl_none_check_cxn, /* check_cxn */
1845 gtls_shutdown, /* shutdown */
1846 gtls_data_pending, /* data_pending */
1847 gtls_random, /* random */
1848 gtls_cert_status_request, /* cert_status_request */
1849 gtls_connect, /* connect */
1850 gtls_connect_nonblocking, /* connect_nonblocking */
1851 Curl_ssl_adjust_pollset, /* adjust_pollset */
1852 gtls_get_internals, /* get_internals */
1853 gtls_close, /* close_one */
1854 Curl_none_close_all, /* close_all */
1855 Curl_none_set_engine, /* set_engine */
1856 Curl_none_set_engine_default, /* set_engine_default */
1857 Curl_none_engines_list, /* engines_list */
1858 Curl_none_false_start, /* false_start */
1859 gtls_sha256sum, /* sha256sum */
1860 NULL, /* associate_connection */
1861 NULL, /* disassociate_connection */
1862 NULL, /* free_multi_ssl_backend_data */
1863 gtls_recv, /* recv decrypted data */
1864 gtls_send, /* send data to encrypt */
1865 };
1866
1867 #endif /* USE_GNUTLS */
1868