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