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 rc = gnutls_init(>ls->session, init_flags);
686 if(rc != GNUTLS_E_SUCCESS) {
687 failf(data, "gnutls_init() failed: %d", rc);
688 return CURLE_SSL_CONNECT_ERROR;
689 }
690
691 if(sni && peer->sni) {
692 if(gnutls_server_name_set(gtls->session, GNUTLS_NAME_DNS,
693 peer->sni, strlen(peer->sni)) < 0) {
694 failf(data, "Failed to set SNI");
695 return CURLE_SSL_CONNECT_ERROR;
696 }
697 }
698
699 /* Use default priorities */
700 rc = gnutls_set_default_priority(gtls->session);
701 if(rc != GNUTLS_E_SUCCESS)
702 return CURLE_SSL_CONNECT_ERROR;
703
704 /* "In GnuTLS 3.6.5, TLS 1.3 is enabled by default" */
705 tls13support = gnutls_check_version("3.6.5");
706
707 /* Ensure +SRP comes at the *end* of all relevant strings so that it can be
708 * removed if a run-time error indicates that SRP is not supported by this
709 * GnuTLS version */
710
711 if(config->version == CURL_SSLVERSION_SSLv2 ||
712 config->version == CURL_SSLVERSION_SSLv3) {
713 failf(data, "GnuTLS does not support SSLv2 or SSLv3");
714 return CURLE_SSL_CONNECT_ERROR;
715 }
716
717 if(config->version == CURL_SSLVERSION_TLSv1_3) {
718 if(!tls13support) {
719 failf(data, "This GnuTLS installation does not support TLS 1.3");
720 return CURLE_SSL_CONNECT_ERROR;
721 }
722 }
723
724 /* At this point we know we have a supported TLS version, so set it */
725 result = set_ssl_version_min_max(data, peer,
726 config, &prioritylist, tls13support);
727 if(result)
728 return result;
729
730 #ifdef USE_GNUTLS_SRP
731 /* Only add SRP to the cipher list if SRP is requested. Otherwise
732 * GnuTLS will disable TLS 1.3 support. */
733 if(config->username) {
734 char *prioritysrp = aprintf("%s:" GNUTLS_SRP, prioritylist);
735 if(!prioritysrp)
736 return CURLE_OUT_OF_MEMORY;
737 rc = gnutls_priority_set_direct(gtls->session, prioritysrp, &err);
738 free(prioritysrp);
739
740 if((rc == GNUTLS_E_INVALID_REQUEST) && err) {
741 infof(data, "This GnuTLS does not support SRP");
742 }
743 }
744 else {
745 #endif
746 infof(data, "GnuTLS ciphers: %s", prioritylist);
747 rc = gnutls_priority_set_direct(gtls->session, prioritylist, &err);
748 #ifdef USE_GNUTLS_SRP
749 }
750 #endif
751
752 if(rc != GNUTLS_E_SUCCESS) {
753 failf(data, "Error %d setting GnuTLS cipher list starting with %s",
754 rc, err);
755 return CURLE_SSL_CONNECT_ERROR;
756 }
757
758 if(config->clientcert) {
759 if(!gtls->trust_setup) {
760 result = Curl_gtls_client_trust_setup(cf, data, gtls);
761 if(result)
762 return result;
763 }
764 if(ssl_config->key_passwd) {
765 const unsigned int supported_key_encryption_algorithms =
766 GNUTLS_PKCS_USE_PKCS12_3DES | GNUTLS_PKCS_USE_PKCS12_ARCFOUR |
767 GNUTLS_PKCS_USE_PKCS12_RC2_40 | GNUTLS_PKCS_USE_PBES2_3DES |
768 GNUTLS_PKCS_USE_PBES2_AES_128 | GNUTLS_PKCS_USE_PBES2_AES_192 |
769 GNUTLS_PKCS_USE_PBES2_AES_256;
770 rc = gnutls_certificate_set_x509_key_file2(
771 gtls->cred,
772 config->clientcert,
773 ssl_config->key ? ssl_config->key : config->clientcert,
774 do_file_type(ssl_config->cert_type),
775 ssl_config->key_passwd,
776 supported_key_encryption_algorithms);
777 if(rc != GNUTLS_E_SUCCESS) {
778 failf(data,
779 "error reading X.509 potentially-encrypted key file: %s",
780 gnutls_strerror(rc));
781 return CURLE_SSL_CONNECT_ERROR;
782 }
783 }
784 else {
785 if(gnutls_certificate_set_x509_key_file(
786 gtls->cred,
787 config->clientcert,
788 ssl_config->key ? ssl_config->key : config->clientcert,
789 do_file_type(ssl_config->cert_type) ) !=
790 GNUTLS_E_SUCCESS) {
791 failf(data, "error reading X.509 key or certificate file");
792 return CURLE_SSL_CONNECT_ERROR;
793 }
794 }
795 }
796
797 #ifdef USE_GNUTLS_SRP
798 /* put the credentials to the current session */
799 if(config->username) {
800 rc = gnutls_credentials_set(gtls->session, GNUTLS_CRD_SRP,
801 gtls->srp_client_cred);
802 if(rc != GNUTLS_E_SUCCESS) {
803 failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc));
804 return CURLE_SSL_CONNECT_ERROR;
805 }
806 }
807 else
808 #endif
809 {
810 rc = gnutls_credentials_set(gtls->session, GNUTLS_CRD_CERTIFICATE,
811 gtls->cred);
812 if(rc != GNUTLS_E_SUCCESS) {
813 failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc));
814 return CURLE_SSL_CONNECT_ERROR;
815 }
816 }
817
818 if(config->verifystatus) {
819 rc = gnutls_ocsp_status_request_enable_client(gtls->session,
820 NULL, 0, NULL);
821 if(rc != GNUTLS_E_SUCCESS) {
822 failf(data, "gnutls_ocsp_status_request_enable_client() failed: %d", rc);
823 return CURLE_SSL_CONNECT_ERROR;
824 }
825 }
826
827 return CURLE_OK;
828 }
829
keylog_callback(gnutls_session_t session,const char * label,const gnutls_datum_t * secret)830 static int keylog_callback(gnutls_session_t session, const char *label,
831 const gnutls_datum_t *secret)
832 {
833 gnutls_datum_t crandom;
834 gnutls_datum_t srandom;
835
836 gnutls_session_get_random(session, &crandom, &srandom);
837 if(crandom.size != 32) {
838 return -1;
839 }
840
841 Curl_tls_keylog_write(label, crandom.data, secret->data, secret->size);
842 return 0;
843 }
844
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)845 CURLcode Curl_gtls_ctx_init(struct gtls_ctx *gctx,
846 struct Curl_cfilter *cf,
847 struct Curl_easy *data,
848 struct ssl_peer *peer,
849 const unsigned char *alpn, size_t alpn_len,
850 Curl_gtls_ctx_setup_cb *cb_setup,
851 void *cb_user_data,
852 void *ssl_user_data)
853 {
854 struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
855 CURLcode result;
856
857 DEBUGASSERT(gctx);
858
859 result = gtls_client_init(cf, data, peer, gctx);
860 if(result)
861 return result;
862
863 gnutls_session_set_ptr(gctx->session, ssl_user_data);
864
865 if(cb_setup) {
866 result = cb_setup(cf, data, cb_user_data);
867 if(result)
868 return result;
869 }
870
871 /* Open the file if a TLS or QUIC backend has not done this before. */
872 Curl_tls_keylog_open();
873 if(Curl_tls_keylog_enabled()) {
874 gnutls_session_set_keylog_function(gctx->session, keylog_callback);
875 }
876
877 /* convert the ALPN string from our arguments to a list of strings
878 * that gnutls wants and will convert internally back to this very
879 * string for sending to the server. nice. */
880 if(alpn && alpn_len) {
881 gnutls_datum_t alpns[5];
882 size_t i, alen = alpn_len;
883 unsigned char *s = (unsigned char *)alpn;
884 unsigned char slen;
885 for(i = 0; (i < ARRAYSIZE(alpns)) && alen; ++i) {
886 slen = s[0];
887 if(slen >= alen)
888 return CURLE_FAILED_INIT;
889 alpns[i].data = s + 1;
890 alpns[i].size = slen;
891 s += slen + 1;
892 alen -= (size_t)slen + 1;
893 }
894 if(alen) /* not all alpn chars used, wrong format or too many */
895 return CURLE_FAILED_INIT;
896 if(i && gnutls_alpn_set_protocols(gctx->session,
897 alpns, (unsigned int)i,
898 GNUTLS_ALPN_MANDATORY)) {
899 failf(data, "failed setting ALPN");
900 return CURLE_SSL_CONNECT_ERROR;
901 }
902 }
903
904 /* This might be a reconnect, so we check for a session ID in the cache
905 to speed up things */
906 if(conn_config->sessionid) {
907 void *ssl_sessionid;
908 size_t ssl_idsize;
909
910 Curl_ssl_sessionid_lock(data);
911 if(!Curl_ssl_getsessionid(cf, data, peer, &ssl_sessionid, &ssl_idsize)) {
912 /* we got a session id, use it! */
913 int rc;
914
915 rc = gnutls_session_set_data(gctx->session, ssl_sessionid, ssl_idsize);
916 if(rc < 0)
917 infof(data, "SSL failed to set session ID");
918 else
919 infof(data, "SSL reusing session ID (size=%zu)", ssl_idsize);
920 }
921 Curl_ssl_sessionid_unlock(data);
922 }
923 return CURLE_OK;
924 }
925
926 static CURLcode
gtls_connect_step1(struct Curl_cfilter * cf,struct Curl_easy * data)927 gtls_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
928 {
929 struct ssl_connect_data *connssl = cf->ctx;
930 struct gtls_ssl_backend_data *backend =
931 (struct gtls_ssl_backend_data *)connssl->backend;
932 struct alpn_proto_buf proto;
933 CURLcode result;
934
935 DEBUGASSERT(backend);
936 DEBUGASSERT(ssl_connect_1 == connssl->connecting_state);
937
938 if(connssl->state == ssl_connection_complete)
939 /* to make us tolerant against being called more than once for the
940 same connection */
941 return CURLE_OK;
942
943 memset(&proto, 0, sizeof(proto));
944 if(connssl->alpn) {
945 result = Curl_alpn_to_proto_buf(&proto, connssl->alpn);
946 if(result) {
947 failf(data, "Error determining ALPN");
948 return CURLE_SSL_CONNECT_ERROR;
949 }
950 }
951
952 result = Curl_gtls_ctx_init(&backend->gtls, cf, data, &connssl->peer,
953 proto.data, proto.len, NULL, NULL, cf);
954 if(result)
955 return result;
956
957 gnutls_handshake_set_hook_function(backend->gtls.session,
958 GNUTLS_HANDSHAKE_ANY, GNUTLS_HOOK_POST,
959 gtls_handshake_cb);
960
961 /* register callback functions and handle to send and receive data. */
962 gnutls_transport_set_ptr(backend->gtls.session, cf);
963 gnutls_transport_set_push_function(backend->gtls.session, gtls_push);
964 gnutls_transport_set_pull_function(backend->gtls.session, gtls_pull);
965
966 return CURLE_OK;
967 }
968
pkp_pin_peer_pubkey(struct Curl_easy * data,gnutls_x509_crt_t cert,const char * pinnedpubkey)969 static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
970 gnutls_x509_crt_t cert,
971 const char *pinnedpubkey)
972 {
973 /* Scratch */
974 size_t len1 = 0, len2 = 0;
975 unsigned char *buff1 = NULL;
976
977 gnutls_pubkey_t key = NULL;
978
979 /* Result is returned to caller */
980 CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
981
982 /* if a path wasn't specified, don't pin */
983 if(!pinnedpubkey)
984 return CURLE_OK;
985
986 if(!cert)
987 return result;
988
989 do {
990 int ret;
991
992 /* Begin Gyrations to get the public key */
993 gnutls_pubkey_init(&key);
994
995 ret = gnutls_pubkey_import_x509(key, cert, 0);
996 if(ret < 0)
997 break; /* failed */
998
999 ret = gnutls_pubkey_export(key, GNUTLS_X509_FMT_DER, NULL, &len1);
1000 if(ret != GNUTLS_E_SHORT_MEMORY_BUFFER || len1 == 0)
1001 break; /* failed */
1002
1003 buff1 = malloc(len1);
1004 if(!buff1)
1005 break; /* failed */
1006
1007 len2 = len1;
1008
1009 ret = gnutls_pubkey_export(key, GNUTLS_X509_FMT_DER, buff1, &len2);
1010 if(ret < 0 || len1 != len2)
1011 break; /* failed */
1012
1013 /* End Gyrations */
1014
1015 /* The one good exit point */
1016 result = Curl_pin_peer_pubkey(data, pinnedpubkey, buff1, len1);
1017 } while(0);
1018
1019 if(key)
1020 gnutls_pubkey_deinit(key);
1021
1022 Curl_safefree(buff1);
1023
1024 return result;
1025 }
1026
1027 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)1028 Curl_gtls_verifyserver(struct Curl_easy *data,
1029 gnutls_session_t session,
1030 struct ssl_primary_config *config,
1031 struct ssl_config_data *ssl_config,
1032 struct ssl_peer *peer,
1033 const char *pinned_key)
1034 {
1035 unsigned int cert_list_size;
1036 const gnutls_datum_t *chainp;
1037 unsigned int verify_status = 0;
1038 gnutls_x509_crt_t x509_cert, x509_issuer;
1039 gnutls_datum_t issuerp;
1040 gnutls_datum_t certfields;
1041 char certname[65] = ""; /* limited to 64 chars by ASN.1 */
1042 size_t size;
1043 time_t certclock;
1044 int rc;
1045 CURLcode result = CURLE_OK;
1046 #ifndef CURL_DISABLE_VERBOSE_STRINGS
1047 const char *ptr;
1048 unsigned int algo;
1049 unsigned int bits;
1050 gnutls_protocol_t version = gnutls_protocol_get_version(session);
1051 #endif
1052 long * const certverifyresult = &ssl_config->certverifyresult;
1053
1054 #ifndef CURL_DISABLE_VERBOSE_STRINGS
1055 /* the name of the cipher suite used, e.g. ECDHE_RSA_AES_256_GCM_SHA384. */
1056 ptr = gnutls_cipher_suite_get_name(gnutls_kx_get(session),
1057 gnutls_cipher_get(session),
1058 gnutls_mac_get(session));
1059
1060 infof(data, "SSL connection using %s / %s",
1061 gnutls_protocol_get_name(version), ptr);
1062 #endif
1063
1064 /* This function will return the peer's raw certificate (chain) as sent by
1065 the peer. These certificates are in raw format (DER encoded for
1066 X.509). In case of a X.509 then a certificate list may be present. The
1067 first certificate in the list is the peer's certificate, following the
1068 issuer's certificate, then the issuer's issuer etc. */
1069
1070 chainp = gnutls_certificate_get_peers(session, &cert_list_size);
1071 if(!chainp) {
1072 if(config->verifypeer ||
1073 config->verifyhost ||
1074 config->issuercert) {
1075 #ifdef USE_GNUTLS_SRP
1076 if(ssl_config->primary.username && !config->verifypeer &&
1077 gnutls_cipher_get(session)) {
1078 /* no peer cert, but auth is ok if we have SRP user and cipher and no
1079 peer verify */
1080 }
1081 else {
1082 #endif
1083 failf(data, "failed to get server cert");
1084 *certverifyresult = GNUTLS_E_NO_CERTIFICATE_FOUND;
1085 return CURLE_PEER_FAILED_VERIFICATION;
1086 #ifdef USE_GNUTLS_SRP
1087 }
1088 #endif
1089 }
1090 infof(data, " common name: WARNING couldn't obtain");
1091 }
1092
1093 if(data->set.ssl.certinfo && chainp) {
1094 unsigned int i;
1095
1096 result = Curl_ssl_init_certinfo(data, cert_list_size);
1097 if(result)
1098 return result;
1099
1100 for(i = 0; i < cert_list_size; i++) {
1101 const char *beg = (const char *) chainp[i].data;
1102 const char *end = beg + chainp[i].size;
1103
1104 result = Curl_extract_certinfo(data, i, beg, end);
1105 if(result)
1106 return result;
1107 }
1108 }
1109
1110 if(config->verifypeer) {
1111 /* This function will try to verify the peer's certificate and return its
1112 status (trusted, invalid etc.). The value of status should be one or
1113 more of the gnutls_certificate_status_t enumerated elements bitwise
1114 or'd. To avoid denial of service attacks some default upper limits
1115 regarding the certificate key size and chain size are set. To override
1116 them use gnutls_certificate_set_verify_limits(). */
1117
1118 rc = gnutls_certificate_verify_peers2(session, &verify_status);
1119 if(rc < 0) {
1120 failf(data, "server cert verify failed: %d", rc);
1121 *certverifyresult = rc;
1122 return CURLE_SSL_CONNECT_ERROR;
1123 }
1124
1125 *certverifyresult = verify_status;
1126
1127 /* verify_status is a bitmask of gnutls_certificate_status bits */
1128 if(verify_status & GNUTLS_CERT_INVALID) {
1129 if(config->verifypeer) {
1130 failf(data, "server certificate verification failed. CAfile: %s "
1131 "CRLfile: %s", config->CAfile ? config->CAfile:
1132 "none",
1133 ssl_config->primary.CRLfile ?
1134 ssl_config->primary.CRLfile : "none");
1135 return CURLE_PEER_FAILED_VERIFICATION;
1136 }
1137 else
1138 infof(data, " server certificate verification FAILED");
1139 }
1140 else
1141 infof(data, " server certificate verification OK");
1142 }
1143 else
1144 infof(data, " server certificate verification SKIPPED");
1145
1146 if(config->verifystatus) {
1147 if(gnutls_ocsp_status_request_is_checked(session, 0) == 0) {
1148 gnutls_datum_t status_request;
1149 gnutls_ocsp_resp_t ocsp_resp;
1150
1151 gnutls_ocsp_cert_status_t status;
1152 gnutls_x509_crl_reason_t reason;
1153
1154 rc = gnutls_ocsp_status_request_get(session, &status_request);
1155
1156 infof(data, " server certificate status verification FAILED");
1157
1158 if(rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
1159 failf(data, "No OCSP response received");
1160 return CURLE_SSL_INVALIDCERTSTATUS;
1161 }
1162
1163 if(rc < 0) {
1164 failf(data, "Invalid OCSP response received");
1165 return CURLE_SSL_INVALIDCERTSTATUS;
1166 }
1167
1168 gnutls_ocsp_resp_init(&ocsp_resp);
1169
1170 rc = gnutls_ocsp_resp_import(ocsp_resp, &status_request);
1171 if(rc < 0) {
1172 failf(data, "Invalid OCSP response received");
1173 return CURLE_SSL_INVALIDCERTSTATUS;
1174 }
1175
1176 (void)gnutls_ocsp_resp_get_single(ocsp_resp, 0, NULL, NULL, NULL, NULL,
1177 &status, NULL, NULL, NULL, &reason);
1178
1179 switch(status) {
1180 case GNUTLS_OCSP_CERT_GOOD:
1181 break;
1182
1183 case GNUTLS_OCSP_CERT_REVOKED: {
1184 const char *crl_reason;
1185
1186 switch(reason) {
1187 default:
1188 case GNUTLS_X509_CRLREASON_UNSPECIFIED:
1189 crl_reason = "unspecified reason";
1190 break;
1191
1192 case GNUTLS_X509_CRLREASON_KEYCOMPROMISE:
1193 crl_reason = "private key compromised";
1194 break;
1195
1196 case GNUTLS_X509_CRLREASON_CACOMPROMISE:
1197 crl_reason = "CA compromised";
1198 break;
1199
1200 case GNUTLS_X509_CRLREASON_AFFILIATIONCHANGED:
1201 crl_reason = "affiliation has changed";
1202 break;
1203
1204 case GNUTLS_X509_CRLREASON_SUPERSEDED:
1205 crl_reason = "certificate superseded";
1206 break;
1207
1208 case GNUTLS_X509_CRLREASON_CESSATIONOFOPERATION:
1209 crl_reason = "operation has ceased";
1210 break;
1211
1212 case GNUTLS_X509_CRLREASON_CERTIFICATEHOLD:
1213 crl_reason = "certificate is on hold";
1214 break;
1215
1216 case GNUTLS_X509_CRLREASON_REMOVEFROMCRL:
1217 crl_reason = "will be removed from delta CRL";
1218 break;
1219
1220 case GNUTLS_X509_CRLREASON_PRIVILEGEWITHDRAWN:
1221 crl_reason = "privilege withdrawn";
1222 break;
1223
1224 case GNUTLS_X509_CRLREASON_AACOMPROMISE:
1225 crl_reason = "AA compromised";
1226 break;
1227 }
1228
1229 failf(data, "Server certificate was revoked: %s", crl_reason);
1230 break;
1231 }
1232
1233 default:
1234 case GNUTLS_OCSP_CERT_UNKNOWN:
1235 failf(data, "Server certificate status is unknown");
1236 break;
1237 }
1238
1239 gnutls_ocsp_resp_deinit(ocsp_resp);
1240
1241 return CURLE_SSL_INVALIDCERTSTATUS;
1242 }
1243 else
1244 infof(data, " server certificate status verification OK");
1245 }
1246 else
1247 infof(data, " server certificate status verification SKIPPED");
1248
1249 /* initialize an X.509 certificate structure. */
1250 gnutls_x509_crt_init(&x509_cert);
1251
1252 if(chainp)
1253 /* convert the given DER or PEM encoded Certificate to the native
1254 gnutls_x509_crt_t format */
1255 gnutls_x509_crt_import(x509_cert, chainp, GNUTLS_X509_FMT_DER);
1256
1257 if(config->issuercert) {
1258 gnutls_x509_crt_init(&x509_issuer);
1259 issuerp = load_file(config->issuercert);
1260 gnutls_x509_crt_import(x509_issuer, &issuerp, GNUTLS_X509_FMT_PEM);
1261 rc = gnutls_x509_crt_check_issuer(x509_cert, x509_issuer);
1262 gnutls_x509_crt_deinit(x509_issuer);
1263 unload_file(issuerp);
1264 if(rc <= 0) {
1265 failf(data, "server certificate issuer check failed (IssuerCert: %s)",
1266 config->issuercert?config->issuercert:"none");
1267 gnutls_x509_crt_deinit(x509_cert);
1268 return CURLE_SSL_ISSUER_ERROR;
1269 }
1270 infof(data, " server certificate issuer check OK (Issuer Cert: %s)",
1271 config->issuercert?config->issuercert:"none");
1272 }
1273
1274 size = sizeof(certname);
1275 rc = gnutls_x509_crt_get_dn_by_oid(x509_cert, GNUTLS_OID_X520_COMMON_NAME,
1276 0, /* the first and only one */
1277 FALSE,
1278 certname,
1279 &size);
1280 if(rc) {
1281 infof(data, "error fetching CN from cert:%s",
1282 gnutls_strerror(rc));
1283 }
1284
1285 /* This function will check if the given certificate's subject matches the
1286 given hostname. This is a basic implementation of the matching described
1287 in RFC2818 (HTTPS), which takes into account wildcards, and the subject
1288 alternative name PKIX extension. Returns non zero on success, and zero on
1289 failure. */
1290 rc = gnutls_x509_crt_check_hostname(x509_cert, peer->hostname);
1291 #if GNUTLS_VERSION_NUMBER < 0x030306
1292 /* Before 3.3.6, gnutls_x509_crt_check_hostname() didn't check IP
1293 addresses. */
1294 if(!rc) {
1295 #ifdef USE_IPV6
1296 #define use_addr in6_addr
1297 #else
1298 #define use_addr in_addr
1299 #endif
1300 unsigned char addrbuf[sizeof(struct use_addr)];
1301 size_t addrlen = 0;
1302
1303 if(Curl_inet_pton(AF_INET, peer->hostname, addrbuf) > 0)
1304 addrlen = 4;
1305 #ifdef USE_IPV6
1306 else if(Curl_inet_pton(AF_INET6, peer->hostname, addrbuf) > 0)
1307 addrlen = 16;
1308 #endif
1309
1310 if(addrlen) {
1311 unsigned char certaddr[sizeof(struct use_addr)];
1312 int i;
1313
1314 for(i = 0; ; i++) {
1315 size_t certaddrlen = sizeof(certaddr);
1316 int ret = gnutls_x509_crt_get_subject_alt_name(x509_cert, i, certaddr,
1317 &certaddrlen, NULL);
1318 /* If this happens, it wasn't an IP address. */
1319 if(ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
1320 continue;
1321 if(ret < 0)
1322 break;
1323 if(ret != GNUTLS_SAN_IPADDRESS)
1324 continue;
1325 if(certaddrlen == addrlen && !memcmp(addrbuf, certaddr, addrlen)) {
1326 rc = 1;
1327 break;
1328 }
1329 }
1330 }
1331 }
1332 #endif
1333 if(!rc) {
1334 if(config->verifyhost) {
1335 failf(data, "SSL: certificate subject name (%s) does not match "
1336 "target host name '%s'", certname, peer->dispname);
1337 gnutls_x509_crt_deinit(x509_cert);
1338 return CURLE_PEER_FAILED_VERIFICATION;
1339 }
1340 else
1341 infof(data, " common name: %s (does not match '%s')",
1342 certname, peer->dispname);
1343 }
1344 else
1345 infof(data, " common name: %s (matched)", certname);
1346
1347 /* Check for time-based validity */
1348 certclock = gnutls_x509_crt_get_expiration_time(x509_cert);
1349
1350 if(certclock == (time_t)-1) {
1351 if(config->verifypeer) {
1352 failf(data, "server cert expiration date verify failed");
1353 *certverifyresult = GNUTLS_CERT_EXPIRED;
1354 gnutls_x509_crt_deinit(x509_cert);
1355 return CURLE_SSL_CONNECT_ERROR;
1356 }
1357 else
1358 infof(data, " server certificate expiration date verify FAILED");
1359 }
1360 else {
1361 if(certclock < time(NULL)) {
1362 if(config->verifypeer) {
1363 failf(data, "server certificate expiration date has passed.");
1364 *certverifyresult = GNUTLS_CERT_EXPIRED;
1365 gnutls_x509_crt_deinit(x509_cert);
1366 return CURLE_PEER_FAILED_VERIFICATION;
1367 }
1368 else
1369 infof(data, " server certificate expiration date FAILED");
1370 }
1371 else
1372 infof(data, " server certificate expiration date OK");
1373 }
1374
1375 certclock = gnutls_x509_crt_get_activation_time(x509_cert);
1376
1377 if(certclock == (time_t)-1) {
1378 if(config->verifypeer) {
1379 failf(data, "server cert activation date verify failed");
1380 *certverifyresult = GNUTLS_CERT_NOT_ACTIVATED;
1381 gnutls_x509_crt_deinit(x509_cert);
1382 return CURLE_SSL_CONNECT_ERROR;
1383 }
1384 else
1385 infof(data, " server certificate activation date verify FAILED");
1386 }
1387 else {
1388 if(certclock > time(NULL)) {
1389 if(config->verifypeer) {
1390 failf(data, "server certificate not activated yet.");
1391 *certverifyresult = GNUTLS_CERT_NOT_ACTIVATED;
1392 gnutls_x509_crt_deinit(x509_cert);
1393 return CURLE_PEER_FAILED_VERIFICATION;
1394 }
1395 else
1396 infof(data, " server certificate activation date FAILED");
1397 }
1398 else
1399 infof(data, " server certificate activation date OK");
1400 }
1401
1402 if(pinned_key) {
1403 result = pkp_pin_peer_pubkey(data, x509_cert, pinned_key);
1404 if(result != CURLE_OK) {
1405 failf(data, "SSL: public key does not match pinned public key");
1406 gnutls_x509_crt_deinit(x509_cert);
1407 return result;
1408 }
1409 }
1410
1411 /* Show:
1412
1413 - subject
1414 - start date
1415 - expire date
1416 - common name
1417 - issuer
1418
1419 */
1420
1421 #ifndef CURL_DISABLE_VERBOSE_STRINGS
1422 /* public key algorithm's parameters */
1423 algo = gnutls_x509_crt_get_pk_algorithm(x509_cert, &bits);
1424 infof(data, " certificate public key: %s",
1425 gnutls_pk_algorithm_get_name(algo));
1426
1427 /* version of the X.509 certificate. */
1428 infof(data, " certificate version: #%d",
1429 gnutls_x509_crt_get_version(x509_cert));
1430
1431
1432 rc = gnutls_x509_crt_get_dn2(x509_cert, &certfields);
1433 if(rc)
1434 infof(data, "Failed to get certificate name");
1435 else {
1436 infof(data, " subject: %s", certfields.data);
1437
1438 certclock = gnutls_x509_crt_get_activation_time(x509_cert);
1439 showtime(data, "start date", certclock);
1440
1441 certclock = gnutls_x509_crt_get_expiration_time(x509_cert);
1442 showtime(data, "expire date", certclock);
1443
1444 gnutls_free(certfields.data);
1445 }
1446
1447 rc = gnutls_x509_crt_get_issuer_dn2(x509_cert, &certfields);
1448 if(rc)
1449 infof(data, "Failed to get certificate issuer");
1450 else {
1451 infof(data, " issuer: %s", certfields.data);
1452
1453 gnutls_free(certfields.data);
1454 }
1455 #endif
1456
1457 gnutls_x509_crt_deinit(x509_cert);
1458
1459 return result;
1460 }
1461
gtls_verifyserver(struct Curl_cfilter * cf,struct Curl_easy * data,gnutls_session_t session)1462 static CURLcode gtls_verifyserver(struct Curl_cfilter *cf,
1463 struct Curl_easy *data,
1464 gnutls_session_t session)
1465 {
1466 struct ssl_connect_data *connssl = cf->ctx;
1467 struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
1468 struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
1469 #ifndef CURL_DISABLE_PROXY
1470 const char *pinned_key = Curl_ssl_cf_is_proxy(cf)?
1471 data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY]:
1472 data->set.str[STRING_SSL_PINNEDPUBLICKEY];
1473 #else
1474 const char *pinned_key = data->set.str[STRING_SSL_PINNEDPUBLICKEY];
1475 #endif
1476 CURLcode result;
1477
1478 result = Curl_gtls_verifyserver(data, session, conn_config, ssl_config,
1479 &connssl->peer, pinned_key);
1480 if(result)
1481 goto out;
1482
1483 if(connssl->alpn) {
1484 gnutls_datum_t proto;
1485 int rc;
1486
1487 rc = gnutls_alpn_get_selected_protocol(session, &proto);
1488 if(rc == 0)
1489 Curl_alpn_set_negotiated(cf, data, proto.data, proto.size);
1490 else
1491 Curl_alpn_set_negotiated(cf, data, NULL, 0);
1492 }
1493
1494 /* Only on TLSv1.2 or lower do we have the session id now. For
1495 * TLSv1.3 we get it via a SESSION_TICKET message that arrives later. */
1496 if(gnutls_protocol_get_version(session) < GNUTLS_TLS1_3)
1497 result = gtls_update_session_id(cf, data, session);
1498
1499 out:
1500 return result;
1501 }
1502
1503 /*
1504 * This function is called after the TCP connect has completed. Setup the TLS
1505 * layer and do all necessary magic.
1506 */
1507 /* We use connssl->connecting_state to keep track of the connection status;
1508 there are three states: 'ssl_connect_1' (not started yet or complete),
1509 'ssl_connect_2_reading' (waiting for data from server), and
1510 'ssl_connect_2_writing' (waiting to be able to write).
1511 */
1512 static CURLcode
gtls_connect_common(struct Curl_cfilter * cf,struct Curl_easy * data,bool nonblocking,bool * done)1513 gtls_connect_common(struct Curl_cfilter *cf,
1514 struct Curl_easy *data,
1515 bool nonblocking,
1516 bool *done)
1517 {
1518 struct ssl_connect_data *connssl = cf->ctx;
1519 int rc;
1520 CURLcode result = CURLE_OK;
1521
1522 /* Initiate the connection, if not already done */
1523 if(ssl_connect_1 == connssl->connecting_state) {
1524 rc = gtls_connect_step1(cf, data);
1525 if(rc) {
1526 result = rc;
1527 goto out;
1528 }
1529 }
1530
1531 rc = handshake(cf, data, TRUE, nonblocking);
1532 if(rc) {
1533 /* handshake() sets its own error message with failf() */
1534 result = rc;
1535 goto out;
1536 }
1537
1538 /* Finish connecting once the handshake is done */
1539 if(ssl_connect_1 == connssl->connecting_state) {
1540 struct gtls_ssl_backend_data *backend =
1541 (struct gtls_ssl_backend_data *)connssl->backend;
1542 gnutls_session_t session;
1543 DEBUGASSERT(backend);
1544 session = backend->gtls.session;
1545 rc = gtls_verifyserver(cf, data, session);
1546 if(rc) {
1547 result = rc;
1548 goto out;
1549 }
1550 connssl->state = ssl_connection_complete;
1551 }
1552
1553 out:
1554 *done = ssl_connect_1 == connssl->connecting_state;
1555
1556 return result;
1557 }
1558
gtls_connect_nonblocking(struct Curl_cfilter * cf,struct Curl_easy * data,bool * done)1559 static CURLcode gtls_connect_nonblocking(struct Curl_cfilter *cf,
1560 struct Curl_easy *data,
1561 bool *done)
1562 {
1563 return gtls_connect_common(cf, data, TRUE, done);
1564 }
1565
gtls_connect(struct Curl_cfilter * cf,struct Curl_easy * data)1566 static CURLcode gtls_connect(struct Curl_cfilter *cf,
1567 struct Curl_easy *data)
1568 {
1569 CURLcode result;
1570 bool done = FALSE;
1571
1572 result = gtls_connect_common(cf, data, FALSE, &done);
1573 if(result)
1574 return result;
1575
1576 DEBUGASSERT(done);
1577
1578 return CURLE_OK;
1579 }
1580
gtls_data_pending(struct Curl_cfilter * cf,const struct Curl_easy * data)1581 static bool gtls_data_pending(struct Curl_cfilter *cf,
1582 const struct Curl_easy *data)
1583 {
1584 struct ssl_connect_data *ctx = cf->ctx;
1585 struct gtls_ssl_backend_data *backend;
1586
1587 (void)data;
1588 DEBUGASSERT(ctx && ctx->backend);
1589 backend = (struct gtls_ssl_backend_data *)ctx->backend;
1590 if(backend->gtls.session &&
1591 0 != gnutls_record_check_pending(backend->gtls.session))
1592 return TRUE;
1593 return FALSE;
1594 }
1595
gtls_send(struct Curl_cfilter * cf,struct Curl_easy * data,const void * mem,size_t len,CURLcode * curlcode)1596 static ssize_t gtls_send(struct Curl_cfilter *cf,
1597 struct Curl_easy *data,
1598 const void *mem,
1599 size_t len,
1600 CURLcode *curlcode)
1601 {
1602 struct ssl_connect_data *connssl = cf->ctx;
1603 struct gtls_ssl_backend_data *backend =
1604 (struct gtls_ssl_backend_data *)connssl->backend;
1605 ssize_t rc;
1606
1607 (void)data;
1608 DEBUGASSERT(backend);
1609 backend->gtls.io_result = CURLE_OK;
1610 rc = gnutls_record_send(backend->gtls.session, mem, len);
1611
1612 if(rc < 0) {
1613 *curlcode = (rc == GNUTLS_E_AGAIN)?
1614 CURLE_AGAIN :
1615 (backend->gtls.io_result? backend->gtls.io_result : CURLE_SEND_ERROR);
1616
1617 rc = -1;
1618 }
1619
1620 return rc;
1621 }
1622
gtls_close(struct Curl_cfilter * cf,struct Curl_easy * data)1623 static void gtls_close(struct Curl_cfilter *cf,
1624 struct Curl_easy *data)
1625 {
1626 struct ssl_connect_data *connssl = cf->ctx;
1627 struct gtls_ssl_backend_data *backend =
1628 (struct gtls_ssl_backend_data *)connssl->backend;
1629
1630 (void) data;
1631 DEBUGASSERT(backend);
1632
1633 if(backend->gtls.session) {
1634 char buf[32];
1635 /* Maybe the server has already sent a close notify alert.
1636 Read it to avoid an RST on the TCP connection. */
1637 (void)gnutls_record_recv(backend->gtls.session, buf, sizeof(buf));
1638 gnutls_bye(backend->gtls.session, GNUTLS_SHUT_WR);
1639 gnutls_deinit(backend->gtls.session);
1640 backend->gtls.session = NULL;
1641 }
1642 if(backend->gtls.cred) {
1643 gnutls_certificate_free_credentials(backend->gtls.cred);
1644 backend->gtls.cred = NULL;
1645 }
1646 #ifdef USE_GNUTLS_SRP
1647 if(backend->gtls.srp_client_cred) {
1648 gnutls_srp_free_client_credentials(backend->gtls.srp_client_cred);
1649 backend->gtls.srp_client_cred = NULL;
1650 }
1651 #endif
1652 }
1653
1654 /*
1655 * This function is called to shut down the SSL layer but keep the
1656 * socket open (CCC - Clear Command Channel)
1657 */
gtls_shutdown(struct Curl_cfilter * cf,struct Curl_easy * data)1658 static int gtls_shutdown(struct Curl_cfilter *cf,
1659 struct Curl_easy *data)
1660 {
1661 struct ssl_connect_data *connssl = cf->ctx;
1662 struct gtls_ssl_backend_data *backend =
1663 (struct gtls_ssl_backend_data *)connssl->backend;
1664 int retval = 0;
1665
1666 DEBUGASSERT(backend);
1667
1668 #ifndef CURL_DISABLE_FTP
1669 /* This has only been tested on the proftpd server, and the mod_tls code
1670 sends a close notify alert without waiting for a close notify alert in
1671 response. Thus we wait for a close notify alert from the server, but
1672 we do not send one. Let's hope other servers do the same... */
1673
1674 if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
1675 gnutls_bye(backend->gtls.session, GNUTLS_SHUT_WR);
1676 #endif
1677
1678 if(backend->gtls.session) {
1679 ssize_t result;
1680 bool done = FALSE;
1681 char buf[120];
1682
1683 while(!done && !connssl->peer_closed) {
1684 int what = SOCKET_READABLE(Curl_conn_cf_get_socket(cf, data),
1685 SSL_SHUTDOWN_TIMEOUT);
1686 if(what > 0) {
1687 /* Something to read, let's do it and hope that it is the close
1688 notify alert from the server */
1689 result = gnutls_record_recv(backend->gtls.session,
1690 buf, sizeof(buf));
1691 switch(result) {
1692 case 0:
1693 /* This is the expected response. There was no data but only
1694 the close notify alert */
1695 done = TRUE;
1696 break;
1697 case GNUTLS_E_AGAIN:
1698 case GNUTLS_E_INTERRUPTED:
1699 infof(data, "GNUTLS_E_AGAIN || GNUTLS_E_INTERRUPTED");
1700 break;
1701 default:
1702 retval = -1;
1703 done = TRUE;
1704 break;
1705 }
1706 }
1707 else if(0 == what) {
1708 /* timeout */
1709 failf(data, "SSL shutdown timeout");
1710 done = TRUE;
1711 }
1712 else {
1713 /* anything that gets here is fatally bad */
1714 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
1715 retval = -1;
1716 done = TRUE;
1717 }
1718 }
1719 gnutls_deinit(backend->gtls.session);
1720 }
1721 gnutls_certificate_free_credentials(backend->gtls.cred);
1722
1723 #ifdef USE_GNUTLS_SRP
1724 {
1725 struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
1726 if(ssl_config->primary.username)
1727 gnutls_srp_free_client_credentials(backend->gtls.srp_client_cred);
1728 }
1729 #endif
1730
1731 backend->gtls.cred = NULL;
1732 backend->gtls.session = NULL;
1733
1734 return retval;
1735 }
1736
gtls_recv(struct Curl_cfilter * cf,struct Curl_easy * data,char * buf,size_t buffersize,CURLcode * curlcode)1737 static ssize_t gtls_recv(struct Curl_cfilter *cf,
1738 struct Curl_easy *data,
1739 char *buf,
1740 size_t buffersize,
1741 CURLcode *curlcode)
1742 {
1743 struct ssl_connect_data *connssl = cf->ctx;
1744 struct gtls_ssl_backend_data *backend =
1745 (struct gtls_ssl_backend_data *)connssl->backend;
1746 ssize_t ret;
1747
1748 (void)data;
1749 DEBUGASSERT(backend);
1750
1751 backend->gtls.io_result = CURLE_OK;
1752 ret = gnutls_record_recv(backend->gtls.session, buf, buffersize);
1753 if((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED)) {
1754 *curlcode = CURLE_AGAIN;
1755 ret = -1;
1756 goto out;
1757 }
1758
1759 if(ret == GNUTLS_E_REHANDSHAKE) {
1760 /* BLOCKING call, this is bad but a work-around for now. Fixing this "the
1761 proper way" takes a whole lot of work. */
1762 CURLcode result = handshake(cf, data, FALSE, FALSE);
1763 if(result)
1764 /* handshake() writes error message on its own */
1765 *curlcode = result;
1766 else
1767 *curlcode = CURLE_AGAIN; /* then return as if this was a wouldblock */
1768 ret = -1;
1769 goto out;
1770 }
1771
1772 if(ret < 0) {
1773 failf(data, "GnuTLS recv error (%d): %s",
1774
1775 (int)ret, gnutls_strerror((int)ret));
1776 *curlcode = backend->gtls.io_result?
1777 backend->gtls.io_result : CURLE_RECV_ERROR;
1778 ret = -1;
1779 goto out;
1780 }
1781
1782 out:
1783 return ret;
1784 }
1785
gtls_version(char * buffer,size_t size)1786 static size_t gtls_version(char *buffer, size_t size)
1787 {
1788 return msnprintf(buffer, size, "GnuTLS/%s", gnutls_check_version(NULL));
1789 }
1790
1791 /* data might be NULL! */
gtls_random(struct Curl_easy * data,unsigned char * entropy,size_t length)1792 static CURLcode gtls_random(struct Curl_easy *data,
1793 unsigned char *entropy, size_t length)
1794 {
1795 int rc;
1796 (void)data;
1797 rc = gnutls_rnd(GNUTLS_RND_RANDOM, entropy, length);
1798 return rc?CURLE_FAILED_INIT:CURLE_OK;
1799 }
1800
gtls_sha256sum(const unsigned char * tmp,size_t tmplen,unsigned char * sha256sum,size_t sha256len)1801 static CURLcode gtls_sha256sum(const unsigned char *tmp, /* input */
1802 size_t tmplen,
1803 unsigned char *sha256sum, /* output */
1804 size_t sha256len)
1805 {
1806 struct sha256_ctx SHA256pw;
1807 sha256_init(&SHA256pw);
1808 sha256_update(&SHA256pw, (unsigned int)tmplen, tmp);
1809 sha256_digest(&SHA256pw, (unsigned int)sha256len, sha256sum);
1810 return CURLE_OK;
1811 }
1812
gtls_cert_status_request(void)1813 static bool gtls_cert_status_request(void)
1814 {
1815 return TRUE;
1816 }
1817
gtls_get_internals(struct ssl_connect_data * connssl,CURLINFO info UNUSED_PARAM)1818 static void *gtls_get_internals(struct ssl_connect_data *connssl,
1819 CURLINFO info UNUSED_PARAM)
1820 {
1821 struct gtls_ssl_backend_data *backend =
1822 (struct gtls_ssl_backend_data *)connssl->backend;
1823 (void)info;
1824 DEBUGASSERT(backend);
1825 return backend->gtls.session;
1826 }
1827
1828 const struct Curl_ssl Curl_ssl_gnutls = {
1829 { CURLSSLBACKEND_GNUTLS, "gnutls" }, /* info */
1830
1831 SSLSUPP_CA_PATH |
1832 SSLSUPP_CERTINFO |
1833 SSLSUPP_PINNEDPUBKEY |
1834 SSLSUPP_HTTPS_PROXY,
1835
1836 sizeof(struct gtls_ssl_backend_data),
1837
1838 gtls_init, /* init */
1839 gtls_cleanup, /* cleanup */
1840 gtls_version, /* version */
1841 Curl_none_check_cxn, /* check_cxn */
1842 gtls_shutdown, /* shutdown */
1843 gtls_data_pending, /* data_pending */
1844 gtls_random, /* random */
1845 gtls_cert_status_request, /* cert_status_request */
1846 gtls_connect, /* connect */
1847 gtls_connect_nonblocking, /* connect_nonblocking */
1848 Curl_ssl_adjust_pollset, /* adjust_pollset */
1849 gtls_get_internals, /* get_internals */
1850 gtls_close, /* close_one */
1851 Curl_none_close_all, /* close_all */
1852 Curl_none_set_engine, /* set_engine */
1853 Curl_none_set_engine_default, /* set_engine_default */
1854 Curl_none_engines_list, /* engines_list */
1855 Curl_none_false_start, /* false_start */
1856 gtls_sha256sum, /* sha256sum */
1857 NULL, /* associate_connection */
1858 NULL, /* disassociate_connection */
1859 NULL, /* free_multi_ssl_backend_data */
1860 gtls_recv, /* recv decrypted data */
1861 gtls_send, /* send data to encrypt */
1862 };
1863
1864 #endif /* USE_GNUTLS */
1865