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