1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
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 http://curl.haxx.se/docs/copyright.html.
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.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ***************************************************************************/
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.
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.
31 #include "curl_setup.h"
35 #include <gnutls/abstract.h>
36 #include <gnutls/gnutls.h>
37 #include <gnutls/x509.h>
39 #ifdef USE_GNUTLS_NETTLE
40 #include <gnutls/crypto.h>
41 #include <nettle/md5.h>
42 #include <nettle/sha2.h>
49 #include "inet_pton.h"
52 #include "parsedate.h"
53 #include "connect.h" /* for the connect timeout */
58 #include "curl_printf.h"
59 #include "curl_memory.h"
60 /* The last #include file should be: */
64 Some hackish cast macros based on:
65 http://library.gnome.org/devel/glib/unstable/glib-Type-Conversion-Macros.html
67 #ifndef GNUTLS_POINTER_TO_INT_CAST
68 #define GNUTLS_POINTER_TO_INT_CAST(p) ((int) (long) (p))
70 #ifndef GNUTLS_INT_TO_POINTER_CAST
71 #define GNUTLS_INT_TO_POINTER_CAST(i) ((void*) (long) (i))
74 /* Enable GnuTLS debugging by defining GTLSDEBUG */
75 /*#define GTLSDEBUG */
78 static void tls_log_func(int level, const char *str)
80 fprintf(stderr, "|<%d>| %s", level, str);
83 static bool gtls_inited = FALSE;
85 #if defined(GNUTLS_VERSION_NUMBER)
86 # if (GNUTLS_VERSION_NUMBER >= 0x020c00)
87 # undef gnutls_transport_set_lowat
88 # define gnutls_transport_set_lowat(A,B) Curl_nop_stmt
89 # define USE_GNUTLS_PRIORITY_SET_DIRECT 1
91 # if (GNUTLS_VERSION_NUMBER >= 0x020c03)
92 # define GNUTLS_MAPS_WINSOCK_ERRORS 1
95 # if (GNUTLS_VERSION_NUMBER >= 0x030200)
99 # if (GNUTLS_VERSION_NUMBER >= 0x03020d)
103 # if (GNUTLS_VERSION_NUMBER >= 0x030306)
109 # include <gnutls/ocsp.h>
113 * Custom push and pull callback functions used by GNU TLS to read and write
114 * to the socket. These functions are simple wrappers to send() and recv()
115 * (although here using the sread/swrite macros as defined by
116 * curl_setup_once.h).
117 * We use custom functions rather than the GNU TLS defaults because it allows
118 * us to get specific about the fourth "flags" argument, and to use arbitrary
119 * private data with gnutls_transport_set_ptr if we wish.
121 * When these custom push and pull callbacks fail, GNU TLS checks its own
122 * session-specific error variable, and when not set also its own global
123 * errno variable, in order to take appropriate action. GNU TLS does not
124 * require that the transport is actually a socket. This implies that for
125 * Windows builds these callbacks should ideally set the session-specific
126 * error variable using function gnutls_transport_set_errno or as a last
127 * resort global errno variable using gnutls_transport_set_global_errno,
128 * with a transport agnostic error value. This implies that some winsock
129 * error translation must take place in these callbacks.
131 * Paragraph above applies to GNU TLS versions older than 2.12.3, since
132 * this version GNU TLS does its own internal winsock error translation
133 * using system_errno() function.
136 #if defined(USE_WINSOCK) && !defined(GNUTLS_MAPS_WINSOCK_ERRORS)
137 # define gtls_EINTR 4
139 # define gtls_EAGAIN 11
140 static int gtls_mapped_sockerrno(void)
154 static ssize_t Curl_gtls_push(void *s, const void *buf, size_t len)
156 ssize_t ret = swrite(GNUTLS_POINTER_TO_INT_CAST(s), buf, len);
157 #if defined(USE_WINSOCK) && !defined(GNUTLS_MAPS_WINSOCK_ERRORS)
159 gnutls_transport_set_global_errno(gtls_mapped_sockerrno());
164 static ssize_t Curl_gtls_pull(void *s, void *buf, size_t len)
166 ssize_t ret = sread(GNUTLS_POINTER_TO_INT_CAST(s), buf, len);
167 #if defined(USE_WINSOCK) && !defined(GNUTLS_MAPS_WINSOCK_ERRORS)
169 gnutls_transport_set_global_errno(gtls_mapped_sockerrno());
176 * Global GnuTLS init, called from Curl_ssl_init(). This calls functions that
177 * are not thread-safe and thus this function itself is not thread-safe and
178 * must only be called from within curl_global_init() to keep the thread
179 * situation under control!
181 int Curl_gtls_init(void)
185 ret = gnutls_global_init()?0:1;
187 gnutls_global_set_log_function(tls_log_func);
188 gnutls_global_set_log_level(2);
195 int Curl_gtls_cleanup(void)
198 gnutls_global_deinit();
204 static void showtime(struct SessionHandle *data,
209 const struct tm *tm = &buffer;
210 CURLcode result = Curl_gmtime(stamp, &buffer);
214 snprintf(data->state.buffer,
216 "\t %s: %s, %02d %s %4d %02d:%02d:%02d GMT",
218 Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
220 Curl_month[tm->tm_mon],
225 infof(data, "%s\n", data->state.buffer);
228 static gnutls_datum_t load_file (const char *file)
231 gnutls_datum_t loaded_file = { NULL, 0 };
235 if(!(f = fopen(file, "rb")))
237 if(fseek(f, 0, SEEK_END) != 0
238 || (filelen = ftell(f)) < 0
239 || fseek(f, 0, SEEK_SET) != 0
240 || !(ptr = malloc((size_t)filelen)))
242 if(fread(ptr, 1, (size_t)filelen, f) < (size_t)filelen) {
247 loaded_file.data = ptr;
248 loaded_file.size = (unsigned int)filelen;
254 static void unload_file(gnutls_datum_t data) {
259 /* this function does a SSL/TLS (re-)handshake */
260 static CURLcode handshake(struct connectdata *conn,
265 struct SessionHandle *data = conn->data;
266 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
267 gnutls_session_t session = conn->ssl[sockindex].session;
268 curl_socket_t sockfd = conn->sock[sockindex];
274 /* check allowed time left */
275 timeout_ms = Curl_timeleft(data, NULL, duringconnect);
278 /* no need to continue if time already is up */
279 failf(data, "SSL connection timeout");
280 return CURLE_OPERATION_TIMEDOUT;
283 /* if ssl is expecting something, check if it's available. */
284 if(connssl->connecting_state == ssl_connect_2_reading
285 || connssl->connecting_state == ssl_connect_2_writing) {
287 curl_socket_t writefd = ssl_connect_2_writing==
288 connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
289 curl_socket_t readfd = ssl_connect_2_reading==
290 connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
292 what = Curl_socket_ready(readfd, writefd,
294 timeout_ms?timeout_ms:1000);
297 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
298 return CURLE_SSL_CONNECT_ERROR;
303 else if(timeout_ms) {
305 failf(data, "SSL connection timeout at %ld", timeout_ms);
306 return CURLE_OPERATION_TIMEDOUT;
309 /* socket is readable or writable */
312 rc = gnutls_handshake(session);
314 if((rc == GNUTLS_E_AGAIN) || (rc == GNUTLS_E_INTERRUPTED)) {
315 connssl->connecting_state =
316 gnutls_record_get_direction(session)?
317 ssl_connect_2_writing:ssl_connect_2_reading;
320 else if((rc < 0) && !gnutls_error_is_fatal(rc)) {
321 const char *strerr = NULL;
323 if(rc == GNUTLS_E_WARNING_ALERT_RECEIVED) {
324 int alert = gnutls_alert_get(session);
325 strerr = gnutls_alert_get_name(alert);
329 strerr = gnutls_strerror(rc);
331 infof(data, "gnutls_handshake() warning: %s\n", strerr);
335 const char *strerr = NULL;
337 if(rc == GNUTLS_E_FATAL_ALERT_RECEIVED) {
338 int alert = gnutls_alert_get(session);
339 strerr = gnutls_alert_get_name(alert);
343 strerr = gnutls_strerror(rc);
345 failf(data, "gnutls_handshake() failed: %s", strerr);
346 return CURLE_SSL_CONNECT_ERROR;
349 /* Reset our connect state machine */
350 connssl->connecting_state = ssl_connect_1;
355 static gnutls_x509_crt_fmt_t do_file_type(const char *type)
357 if(!type || !type[0])
358 return GNUTLS_X509_FMT_PEM;
359 if(Curl_raw_equal(type, "PEM"))
360 return GNUTLS_X509_FMT_PEM;
361 if(Curl_raw_equal(type, "DER"))
362 return GNUTLS_X509_FMT_DER;
367 gtls_connect_step1(struct connectdata *conn,
370 struct SessionHandle *data = conn->data;
371 gnutls_session_t session;
375 bool sni = TRUE; /* default is SNI enabled */
377 struct in6_addr addr;
381 #ifndef USE_GNUTLS_PRIORITY_SET_DIRECT
382 static const int cipher_priority[] = {
383 /* These two ciphers were added to GnuTLS as late as ver. 3.0.1,
384 but this code path is only ever used for ver. < 2.12.0.
385 GNUTLS_CIPHER_AES_128_GCM,
386 GNUTLS_CIPHER_AES_256_GCM,
388 GNUTLS_CIPHER_AES_128_CBC,
389 GNUTLS_CIPHER_AES_256_CBC,
390 GNUTLS_CIPHER_CAMELLIA_128_CBC,
391 GNUTLS_CIPHER_CAMELLIA_256_CBC,
392 GNUTLS_CIPHER_3DES_CBC,
394 static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
395 static int protocol_priority[] = { 0, 0, 0, 0 };
397 #define GNUTLS_CIPHERS "NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509"
398 /* If GnuTLS was compiled without support for SRP it will error out if SRP is
399 requested in the priority string, so treat it specially
401 #define GNUTLS_SRP "+SRP"
402 const char* prioritylist;
403 const char *err = NULL;
406 if(conn->ssl[sockindex].state == ssl_connection_complete)
407 /* to make us tolerant against being called more than once for the
414 /* GnuTLS only supports SSLv3 and TLSv1 */
415 if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) {
416 failf(data, "GnuTLS does not support SSLv2");
417 return CURLE_SSL_CONNECT_ERROR;
419 else if(data->set.ssl.version == CURL_SSLVERSION_SSLv3)
420 sni = FALSE; /* SSLv3 has no SNI */
422 /* allocate a cred struct */
423 rc = gnutls_certificate_allocate_credentials(&conn->ssl[sockindex].cred);
424 if(rc != GNUTLS_E_SUCCESS) {
425 failf(data, "gnutls_cert_all_cred() failed: %s", gnutls_strerror(rc));
426 return CURLE_SSL_CONNECT_ERROR;
430 if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
431 infof(data, "Using TLS-SRP username: %s\n", data->set.ssl.username);
433 rc = gnutls_srp_allocate_client_credentials(
434 &conn->ssl[sockindex].srp_client_cred);
435 if(rc != GNUTLS_E_SUCCESS) {
436 failf(data, "gnutls_srp_allocate_client_cred() failed: %s",
437 gnutls_strerror(rc));
438 return CURLE_OUT_OF_MEMORY;
441 rc = gnutls_srp_set_client_credentials(conn->ssl[sockindex].
443 data->set.ssl.username,
444 data->set.ssl.password);
445 if(rc != GNUTLS_E_SUCCESS) {
446 failf(data, "gnutls_srp_set_client_cred() failed: %s",
447 gnutls_strerror(rc));
448 return CURLE_BAD_FUNCTION_ARGUMENT;
453 if(data->set.ssl.CAfile) {
454 /* set the trusted CA cert bundle file */
455 gnutls_certificate_set_verify_flags(conn->ssl[sockindex].cred,
456 GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
458 rc = gnutls_certificate_set_x509_trust_file(conn->ssl[sockindex].cred,
459 data->set.ssl.CAfile,
460 GNUTLS_X509_FMT_PEM);
462 infof(data, "error reading ca cert file %s (%s)\n",
463 data->set.ssl.CAfile, gnutls_strerror(rc));
464 if(data->set.ssl.verifypeer)
465 return CURLE_SSL_CACERT_BADFILE;
468 infof(data, "found %d certificates in %s\n",
469 rc, data->set.ssl.CAfile);
473 if(data->set.ssl.CApath) {
474 /* set the trusted CA cert directory */
475 rc = gnutls_certificate_set_x509_trust_dir(conn->ssl[sockindex].cred,
476 data->set.ssl.CApath,
477 GNUTLS_X509_FMT_PEM);
479 infof(data, "error reading ca cert file %s (%s)\n",
480 data->set.ssl.CAfile, gnutls_strerror(rc));
481 if(data->set.ssl.verifypeer)
482 return CURLE_SSL_CACERT_BADFILE;
485 infof(data, "found %d certificates in %s\n",
486 rc, data->set.ssl.CApath);
490 if(data->set.ssl.CRLfile) {
491 /* set the CRL list file */
492 rc = gnutls_certificate_set_x509_crl_file(conn->ssl[sockindex].cred,
493 data->set.ssl.CRLfile,
494 GNUTLS_X509_FMT_PEM);
496 failf(data, "error reading crl file %s (%s)",
497 data->set.ssl.CRLfile, gnutls_strerror(rc));
498 return CURLE_SSL_CRL_BADFILE;
501 infof(data, "found %d CRL in %s\n",
502 rc, data->set.ssl.CRLfile);
505 /* Initialize TLS session as a client */
506 rc = gnutls_init(&conn->ssl[sockindex].session, GNUTLS_CLIENT);
507 if(rc != GNUTLS_E_SUCCESS) {
508 failf(data, "gnutls_init() failed: %d", rc);
509 return CURLE_SSL_CONNECT_ERROR;
512 /* convenient assign */
513 session = conn->ssl[sockindex].session;
515 if((0 == Curl_inet_pton(AF_INET, conn->host.name, &addr)) &&
517 (0 == Curl_inet_pton(AF_INET6, conn->host.name, &addr)) &&
520 (gnutls_server_name_set(session, GNUTLS_NAME_DNS, conn->host.name,
521 strlen(conn->host.name)) < 0))
522 infof(data, "WARNING: failed to configure server name indication (SNI) "
525 /* Use default priorities */
526 rc = gnutls_set_default_priority(session);
527 if(rc != GNUTLS_E_SUCCESS)
528 return CURLE_SSL_CONNECT_ERROR;
530 #ifndef USE_GNUTLS_PRIORITY_SET_DIRECT
531 rc = gnutls_cipher_set_priority(session, cipher_priority);
532 if(rc != GNUTLS_E_SUCCESS)
533 return CURLE_SSL_CONNECT_ERROR;
535 /* Sets the priority on the certificate types supported by gnutls. Priority
536 is higher for types specified before others. After specifying the types
537 you want, you must append a 0. */
538 rc = gnutls_certificate_type_set_priority(session, cert_type_priority);
539 if(rc != GNUTLS_E_SUCCESS)
540 return CURLE_SSL_CONNECT_ERROR;
542 if(data->set.ssl.cipher_list != NULL) {
543 failf(data, "can't pass a custom cipher list to older GnuTLS"
545 return CURLE_SSL_CONNECT_ERROR;
548 switch (data->set.ssl.version) {
549 case CURL_SSLVERSION_SSLv3:
550 protocol_priority[0] = GNUTLS_SSL3;
552 case CURL_SSLVERSION_DEFAULT:
553 case CURL_SSLVERSION_TLSv1:
554 protocol_priority[0] = GNUTLS_TLS1_0;
555 protocol_priority[1] = GNUTLS_TLS1_1;
556 protocol_priority[2] = GNUTLS_TLS1_2;
558 case CURL_SSLVERSION_TLSv1_0:
559 protocol_priority[0] = GNUTLS_TLS1_0;
561 case CURL_SSLVERSION_TLSv1_1:
562 protocol_priority[0] = GNUTLS_TLS1_1;
564 case CURL_SSLVERSION_TLSv1_2:
565 protocol_priority[0] = GNUTLS_TLS1_2;
567 case CURL_SSLVERSION_SSLv2:
569 failf(data, "GnuTLS does not support SSLv2");
570 return CURLE_SSL_CONNECT_ERROR;
573 rc = gnutls_protocol_set_priority(session, protocol_priority);
574 if(rc != GNUTLS_E_SUCCESS) {
575 failf(data, "Did you pass a valid GnuTLS cipher list?");
576 return CURLE_SSL_CONNECT_ERROR;
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
583 switch (data->set.ssl.version) {
584 case CURL_SSLVERSION_SSLv3:
585 prioritylist = GNUTLS_CIPHERS ":-VERS-TLS-ALL:+VERS-SSL3.0";
588 case CURL_SSLVERSION_DEFAULT:
589 case CURL_SSLVERSION_TLSv1:
590 prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:" GNUTLS_SRP;
592 case CURL_SSLVERSION_TLSv1_0:
593 prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
594 "+VERS-TLS1.0:" GNUTLS_SRP;
596 case CURL_SSLVERSION_TLSv1_1:
597 prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
598 "+VERS-TLS1.1:" GNUTLS_SRP;
600 case CURL_SSLVERSION_TLSv1_2:
601 prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
602 "+VERS-TLS1.2:" GNUTLS_SRP;
604 case CURL_SSLVERSION_SSLv2:
606 failf(data, "GnuTLS does not support SSLv2");
607 return CURLE_SSL_CONNECT_ERROR;
610 rc = gnutls_priority_set_direct(session, prioritylist, &err);
611 if((rc == GNUTLS_E_INVALID_REQUEST) && err) {
612 if(!strcmp(err, GNUTLS_SRP)) {
613 /* This GnuTLS was probably compiled without support for SRP.
614 * Note that fact and try again without it. */
615 int validprioritylen = curlx_uztosi(err - prioritylist);
616 char *prioritycopy = strdup(prioritylist);
618 return CURLE_OUT_OF_MEMORY;
620 infof(data, "This GnuTLS does not support SRP\n");
622 /* Remove the :+SRP */
623 prioritycopy[validprioritylen - 1] = 0;
624 rc = gnutls_priority_set_direct(session, prioritycopy, &err);
628 if(rc != GNUTLS_E_SUCCESS) {
629 failf(data, "Error %d setting GnuTLS cipher list starting with %s",
631 return CURLE_SSL_CONNECT_ERROR;
636 if(data->set.ssl_enable_alpn) {
638 gnutls_datum_t protocols[2];
641 if(data->set.httpversion == CURL_HTTP_VERSION_2_0) {
642 protocols[cur].data = (unsigned char *)NGHTTP2_PROTO_VERSION_ID;
643 protocols[cur].size = NGHTTP2_PROTO_VERSION_ID_LEN;
645 infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
649 protocols[cur].data = (unsigned char *)ALPN_HTTP_1_1;
650 protocols[cur].size = ALPN_HTTP_1_1_LENGTH;
652 infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1);
654 gnutls_alpn_set_protocols(session, protocols, cur, 0);
658 if(data->set.str[STRING_CERT]) {
659 if(gnutls_certificate_set_x509_key_file(
660 conn->ssl[sockindex].cred,
661 data->set.str[STRING_CERT],
662 data->set.str[STRING_KEY] ?
663 data->set.str[STRING_KEY] : data->set.str[STRING_CERT],
664 do_file_type(data->set.str[STRING_CERT_TYPE]) ) !=
666 failf(data, "error reading X.509 key or certificate file");
667 return CURLE_SSL_CONNECT_ERROR;
672 /* put the credentials to the current session */
673 if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
674 rc = gnutls_credentials_set(session, GNUTLS_CRD_SRP,
675 conn->ssl[sockindex].srp_client_cred);
676 if(rc != GNUTLS_E_SUCCESS) {
677 failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc));
678 return CURLE_SSL_CONNECT_ERROR;
684 rc = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
685 conn->ssl[sockindex].cred);
686 if(rc != GNUTLS_E_SUCCESS) {
687 failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc));
688 return CURLE_SSL_CONNECT_ERROR;
692 /* set the connection handle (file descriptor for the socket) */
693 gnutls_transport_set_ptr(session,
694 GNUTLS_INT_TO_POINTER_CAST(conn->sock[sockindex]));
696 /* register callback functions to send and receive data. */
697 gnutls_transport_set_push_function(session, Curl_gtls_push);
698 gnutls_transport_set_pull_function(session, Curl_gtls_pull);
700 /* lowat must be set to zero when using custom push and pull functions. */
701 gnutls_transport_set_lowat(session, 0);
704 if(data->set.ssl.verifystatus) {
705 rc = gnutls_ocsp_status_request_enable_client(session, NULL, 0, NULL);
706 if(rc != GNUTLS_E_SUCCESS) {
707 failf(data, "gnutls_ocsp_status_request_enable_client() failed: %d", rc);
708 return CURLE_SSL_CONNECT_ERROR;
713 /* This might be a reconnect, so we check for a session ID in the cache
714 to speed up things */
716 if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, &ssl_idsize)) {
717 /* we got a session id, use it! */
718 gnutls_session_set_data(session, ssl_sessionid, ssl_idsize);
720 /* Informational message */
721 infof (data, "SSL re-using session ID\n");
727 static CURLcode pkp_pin_peer_pubkey(gnutls_x509_crt_t cert,
728 const char *pinnedpubkey)
731 size_t len1 = 0, len2 = 0;
732 unsigned char *buff1 = NULL;
734 gnutls_pubkey_t key = NULL;
736 /* Result is returned to caller */
738 CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
740 /* if a path wasn't specified, don't pin */
741 if(NULL == pinnedpubkey)
748 /* Begin Gyrations to get the public key */
749 gnutls_pubkey_init(&key);
751 ret = gnutls_pubkey_import_x509(key, cert, 0);
755 ret = gnutls_pubkey_export(key, GNUTLS_X509_FMT_DER, NULL, &len1);
756 if(ret != GNUTLS_E_SHORT_MEMORY_BUFFER || len1 == 0)
759 buff1 = malloc(len1);
765 ret = gnutls_pubkey_export(key, GNUTLS_X509_FMT_DER, buff1, &len2);
766 if(ret < 0 || len1 != len2)
771 /* The one good exit point */
772 result = Curl_pin_peer_pubkey(pinnedpubkey, buff1, len1);
776 gnutls_pubkey_deinit(key);
778 Curl_safefree(buff1);
783 static Curl_recv gtls_recv;
784 static Curl_send gtls_send;
787 gtls_connect_step3(struct connectdata *conn,
790 unsigned int cert_list_size;
791 const gnutls_datum_t *chainp;
792 unsigned int verify_status = 0;
793 gnutls_x509_crt_t x509_cert, x509_issuer;
794 gnutls_datum_t issuerp;
795 char certbuf[256] = ""; /* big enough? */
801 struct SessionHandle *data = conn->data;
802 gnutls_session_t session = conn->ssl[sockindex].session;
807 gnutls_datum_t proto;
809 CURLcode result = CURLE_OK;
811 gnutls_protocol_t version = gnutls_protocol_get_version(session);
813 /* the name of the cipher suite used, e.g. ECDHE_RSA_AES_256_GCM_SHA384. */
814 ptr = gnutls_cipher_suite_get_name(gnutls_kx_get(session),
815 gnutls_cipher_get(session),
816 gnutls_mac_get(session));
818 infof(data, "SSL connection using %s / %s\n",
819 gnutls_protocol_get_name(version), ptr);
821 /* This function will return the peer's raw certificate (chain) as sent by
822 the peer. These certificates are in raw format (DER encoded for
823 X.509). In case of a X.509 then a certificate list may be present. The
824 first certificate in the list is the peer's certificate, following the
825 issuer's certificate, then the issuer's issuer etc. */
827 chainp = gnutls_certificate_get_peers(session, &cert_list_size);
829 if(data->set.ssl.verifypeer ||
830 data->set.ssl.verifyhost ||
831 data->set.ssl.issuercert) {
833 if(data->set.ssl.authtype == CURL_TLSAUTH_SRP
834 && data->set.ssl.username != NULL
835 && !data->set.ssl.verifypeer
836 && gnutls_cipher_get(session)) {
837 /* no peer cert, but auth is ok if we have SRP user and cipher and no
842 failf(data, "failed to get server cert");
843 return CURLE_PEER_FAILED_VERIFICATION;
848 infof(data, "\t common name: WARNING couldn't obtain\n");
851 if(data->set.ssl.certinfo && chainp) {
854 result = Curl_ssl_init_certinfo(data, cert_list_size);
858 for(i = 0; i < cert_list_size; i++) {
859 const char *beg = (const char *) chainp[i].data;
860 const char *end = beg + chainp[i].size;
862 result = Curl_extract_certinfo(conn, i, beg, end);
868 if(data->set.ssl.verifypeer) {
869 /* This function will try to verify the peer's certificate and return its
870 status (trusted, invalid etc.). The value of status should be one or
871 more of the gnutls_certificate_status_t enumerated elements bitwise
872 or'd. To avoid denial of service attacks some default upper limits
873 regarding the certificate key size and chain size are set. To override
874 them use gnutls_certificate_set_verify_limits(). */
876 rc = gnutls_certificate_verify_peers2(session, &verify_status);
878 failf(data, "server cert verify failed: %d", rc);
879 return CURLE_SSL_CONNECT_ERROR;
882 /* verify_status is a bitmask of gnutls_certificate_status bits */
883 if(verify_status & GNUTLS_CERT_INVALID) {
884 if(data->set.ssl.verifypeer) {
885 failf(data, "server certificate verification failed. CAfile: %s "
886 "CRLfile: %s", data->set.ssl.CAfile?data->set.ssl.CAfile:"none",
887 data->set.ssl.CRLfile?data->set.ssl.CRLfile:"none");
888 return CURLE_SSL_CACERT;
891 infof(data, "\t server certificate verification FAILED\n");
894 infof(data, "\t server certificate verification OK\n");
897 infof(data, "\t server certificate verification SKIPPED\n");
900 if(data->set.ssl.verifystatus) {
901 if(gnutls_ocsp_status_request_is_checked(session, 0) == 0) {
902 gnutls_datum_t status_request;
903 gnutls_ocsp_resp_t ocsp_resp;
905 gnutls_ocsp_cert_status_t status;
906 gnutls_x509_crl_reason_t reason;
908 rc = gnutls_ocsp_status_request_get(session, &status_request);
910 infof(data, "\t server certificate status verification FAILED\n");
912 if(rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
913 failf(data, "No OCSP response received");
914 return CURLE_SSL_INVALIDCERTSTATUS;
918 failf(data, "Invalid OCSP response received");
919 return CURLE_SSL_INVALIDCERTSTATUS;
922 gnutls_ocsp_resp_init(&ocsp_resp);
924 rc = gnutls_ocsp_resp_import(ocsp_resp, &status_request);
926 failf(data, "Invalid OCSP response received");
927 return CURLE_SSL_INVALIDCERTSTATUS;
930 rc = gnutls_ocsp_resp_get_single(ocsp_resp, 0, NULL, NULL, NULL, NULL,
931 &status, NULL, NULL, NULL, &reason);
934 case GNUTLS_OCSP_CERT_GOOD:
937 case GNUTLS_OCSP_CERT_REVOKED: {
938 const char *crl_reason;
942 case GNUTLS_X509_CRLREASON_UNSPECIFIED:
943 crl_reason = "unspecified reason";
946 case GNUTLS_X509_CRLREASON_KEYCOMPROMISE:
947 crl_reason = "private key compromised";
950 case GNUTLS_X509_CRLREASON_CACOMPROMISE:
951 crl_reason = "CA compromised";
954 case GNUTLS_X509_CRLREASON_AFFILIATIONCHANGED:
955 crl_reason = "affiliation has changed";
958 case GNUTLS_X509_CRLREASON_SUPERSEDED:
959 crl_reason = "certificate superseded";
962 case GNUTLS_X509_CRLREASON_CESSATIONOFOPERATION:
963 crl_reason = "operation has ceased";
966 case GNUTLS_X509_CRLREASON_CERTIFICATEHOLD:
967 crl_reason = "certificate is on hold";
970 case GNUTLS_X509_CRLREASON_REMOVEFROMCRL:
971 crl_reason = "will be removed from delta CRL";
974 case GNUTLS_X509_CRLREASON_PRIVILEGEWITHDRAWN:
975 crl_reason = "privilege withdrawn";
978 case GNUTLS_X509_CRLREASON_AACOMPROMISE:
979 crl_reason = "AA compromised";
983 failf(data, "Server certificate was revoked: %s", crl_reason);
988 case GNUTLS_OCSP_CERT_UNKNOWN:
989 failf(data, "Server certificate status is unknown");
993 gnutls_ocsp_resp_deinit(ocsp_resp);
995 return CURLE_SSL_INVALIDCERTSTATUS;
998 infof(data, "\t server certificate status verification OK\n");
1001 infof(data, "\t server certificate status verification SKIPPED\n");
1004 /* initialize an X.509 certificate structure. */
1005 gnutls_x509_crt_init(&x509_cert);
1008 /* convert the given DER or PEM encoded Certificate to the native
1009 gnutls_x509_crt_t format */
1010 gnutls_x509_crt_import(x509_cert, chainp, GNUTLS_X509_FMT_DER);
1012 if(data->set.ssl.issuercert) {
1013 gnutls_x509_crt_init(&x509_issuer);
1014 issuerp = load_file(data->set.ssl.issuercert);
1015 gnutls_x509_crt_import(x509_issuer, &issuerp, GNUTLS_X509_FMT_PEM);
1016 rc = gnutls_x509_crt_check_issuer(x509_cert, x509_issuer);
1017 gnutls_x509_crt_deinit(x509_issuer);
1018 unload_file(issuerp);
1020 failf(data, "server certificate issuer check failed (IssuerCert: %s)",
1021 data->set.ssl.issuercert?data->set.ssl.issuercert:"none");
1022 gnutls_x509_crt_deinit(x509_cert);
1023 return CURLE_SSL_ISSUER_ERROR;
1025 infof(data, "\t server certificate issuer check OK (Issuer Cert: %s)\n",
1026 data->set.ssl.issuercert?data->set.ssl.issuercert:"none");
1029 size=sizeof(certbuf);
1030 rc = gnutls_x509_crt_get_dn_by_oid(x509_cert, GNUTLS_OID_X520_COMMON_NAME,
1031 0, /* the first and only one */
1036 infof(data, "error fetching CN from cert:%s\n",
1037 gnutls_strerror(rc));
1040 /* This function will check if the given certificate's subject matches the
1041 given hostname. This is a basic implementation of the matching described
1042 in RFC2818 (HTTPS), which takes into account wildcards, and the subject
1043 alternative name PKIX extension. Returns non zero on success, and zero on
1045 rc = gnutls_x509_crt_check_hostname(x509_cert, conn->host.name);
1046 #if GNUTLS_VERSION_NUMBER < 0x030306
1047 /* Before 3.3.6, gnutls_x509_crt_check_hostname() didn't check IP
1051 #define use_addr in6_addr
1053 #define use_addr in_addr
1055 unsigned char addrbuf[sizeof(struct use_addr)];
1056 unsigned char certaddr[sizeof(struct use_addr)];
1057 size_t addrlen = 0, certaddrlen;
1061 if(Curl_inet_pton(AF_INET, conn->host.name, addrbuf) > 0)
1064 else if(Curl_inet_pton(AF_INET6, conn->host.name, addrbuf) > 0)
1070 certaddrlen = sizeof(certaddr);
1071 ret = gnutls_x509_crt_get_subject_alt_name(x509_cert, i, certaddr,
1072 &certaddrlen, NULL);
1073 /* If this happens, it wasn't an IP address. */
1074 if(ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
1078 if(ret != GNUTLS_SAN_IPADDRESS)
1080 if(certaddrlen == addrlen && !memcmp(addrbuf, certaddr, addrlen)) {
1089 if(data->set.ssl.verifyhost) {
1090 failf(data, "SSL: certificate subject name (%s) does not match "
1091 "target host name '%s'", certbuf, conn->host.dispname);
1092 gnutls_x509_crt_deinit(x509_cert);
1093 return CURLE_PEER_FAILED_VERIFICATION;
1096 infof(data, "\t common name: %s (does not match '%s')\n",
1097 certbuf, conn->host.dispname);
1100 infof(data, "\t common name: %s (matched)\n", certbuf);
1102 /* Check for time-based validity */
1103 certclock = gnutls_x509_crt_get_expiration_time(x509_cert);
1105 if(certclock == (time_t)-1) {
1106 if(data->set.ssl.verifypeer) {
1107 failf(data, "server cert expiration date verify failed");
1108 gnutls_x509_crt_deinit(x509_cert);
1109 return CURLE_SSL_CONNECT_ERROR;
1112 infof(data, "\t server certificate expiration date verify FAILED\n");
1115 if(certclock < time(NULL)) {
1116 if(data->set.ssl.verifypeer) {
1117 failf(data, "server certificate expiration date has passed.");
1118 gnutls_x509_crt_deinit(x509_cert);
1119 return CURLE_PEER_FAILED_VERIFICATION;
1122 infof(data, "\t server certificate expiration date FAILED\n");
1125 infof(data, "\t server certificate expiration date OK\n");
1128 certclock = gnutls_x509_crt_get_activation_time(x509_cert);
1130 if(certclock == (time_t)-1) {
1131 if(data->set.ssl.verifypeer) {
1132 failf(data, "server cert activation date verify failed");
1133 gnutls_x509_crt_deinit(x509_cert);
1134 return CURLE_SSL_CONNECT_ERROR;
1137 infof(data, "\t server certificate activation date verify FAILED\n");
1140 if(certclock > time(NULL)) {
1141 if(data->set.ssl.verifypeer) {
1142 failf(data, "server certificate not activated yet.");
1143 gnutls_x509_crt_deinit(x509_cert);
1144 return CURLE_PEER_FAILED_VERIFICATION;
1147 infof(data, "\t server certificate activation date FAILED\n");
1150 infof(data, "\t server certificate activation date OK\n");
1153 ptr = data->set.str[STRING_SSL_PINNEDPUBLICKEY];
1155 result = pkp_pin_peer_pubkey(x509_cert, ptr);
1156 if(result != CURLE_OK) {
1157 failf(data, "SSL: public key does not match pinned public key!");
1158 gnutls_x509_crt_deinit(x509_cert);
1173 /* public key algorithm's parameters */
1174 algo = gnutls_x509_crt_get_pk_algorithm(x509_cert, &bits);
1175 infof(data, "\t certificate public key: %s\n",
1176 gnutls_pk_algorithm_get_name(algo));
1178 /* version of the X.509 certificate. */
1179 infof(data, "\t certificate version: #%d\n",
1180 gnutls_x509_crt_get_version(x509_cert));
1183 size = sizeof(certbuf);
1184 gnutls_x509_crt_get_dn(x509_cert, certbuf, &size);
1185 infof(data, "\t subject: %s\n", certbuf);
1187 certclock = gnutls_x509_crt_get_activation_time(x509_cert);
1188 showtime(data, "start date", certclock);
1190 certclock = gnutls_x509_crt_get_expiration_time(x509_cert);
1191 showtime(data, "expire date", certclock);
1193 size = sizeof(certbuf);
1194 gnutls_x509_crt_get_issuer_dn(x509_cert, certbuf, &size);
1195 infof(data, "\t issuer: %s\n", certbuf);
1197 gnutls_x509_crt_deinit(x509_cert);
1199 /* compression algorithm (if any) */
1200 ptr = gnutls_compression_get_name(gnutls_compression_get(session));
1201 /* the *_get_name() says "NULL" if GNUTLS_COMP_NULL is returned */
1202 infof(data, "\t compression: %s\n", ptr);
1205 if(data->set.ssl_enable_alpn) {
1206 rc = gnutls_alpn_get_selected_protocol(session, &proto);
1208 infof(data, "ALPN, server accepted to use %.*s\n", proto.size,
1212 if(proto.size == NGHTTP2_PROTO_VERSION_ID_LEN &&
1213 !memcmp(NGHTTP2_PROTO_VERSION_ID, proto.data,
1214 NGHTTP2_PROTO_VERSION_ID_LEN)) {
1215 conn->negnpn = CURL_HTTP_VERSION_2_0;
1219 if(proto.size == ALPN_HTTP_1_1_LENGTH &&
1220 !memcmp(ALPN_HTTP_1_1, proto.data, ALPN_HTTP_1_1_LENGTH)) {
1221 conn->negnpn = CURL_HTTP_VERSION_1_1;
1225 infof(data, "ALPN, server did not agree to a protocol\n");
1229 conn->ssl[sockindex].state = ssl_connection_complete;
1230 conn->recv[sockindex] = gtls_recv;
1231 conn->send[sockindex] = gtls_send;
1234 /* we always unconditionally get the session id here, as even if we
1235 already got it from the cache and asked to use it in the connection, it
1236 might've been rejected and then a new one is in use now and we need to
1238 void *connect_sessionid;
1239 size_t connect_idsize = 0;
1241 /* get the session ID data size */
1242 gnutls_session_get_data(session, NULL, &connect_idsize);
1243 connect_sessionid = malloc(connect_idsize); /* get a buffer for it */
1245 if(connect_sessionid) {
1246 /* extract session ID to the allocated buffer */
1247 gnutls_session_get_data(session, connect_sessionid, &connect_idsize);
1249 incache = !(Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL));
1251 /* there was one before in the cache, so instead of risking that the
1252 previous one was rejected, we just kill that and store the new */
1253 Curl_ssl_delsessionid(conn, ssl_sessionid);
1256 /* store this session id */
1257 result = Curl_ssl_addsessionid(conn, connect_sessionid, connect_idsize);
1259 free(connect_sessionid);
1260 result = CURLE_OUT_OF_MEMORY;
1264 result = CURLE_OUT_OF_MEMORY;
1272 * This function is called after the TCP connect has completed. Setup the TLS
1273 * layer and do all necessary magic.
1275 /* We use connssl->connecting_state to keep track of the connection status;
1276 there are three states: 'ssl_connect_1' (not started yet or complete),
1277 'ssl_connect_2_reading' (waiting for data from server), and
1278 'ssl_connect_2_writing' (waiting to be able to write).
1281 gtls_connect_common(struct connectdata *conn,
1287 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1289 /* Initiate the connection, if not already done */
1290 if(ssl_connect_1==connssl->connecting_state) {
1291 rc = gtls_connect_step1 (conn, sockindex);
1296 rc = handshake(conn, sockindex, TRUE, nonblocking);
1298 /* handshake() sets its own error message with failf() */
1301 /* Finish connecting once the handshake is done */
1302 if(ssl_connect_1==connssl->connecting_state) {
1303 rc = gtls_connect_step3(conn, sockindex);
1308 *done = ssl_connect_1==connssl->connecting_state;
1314 Curl_gtls_connect_nonblocking(struct connectdata *conn,
1318 return gtls_connect_common(conn, sockindex, TRUE, done);
1322 Curl_gtls_connect(struct connectdata *conn,
1329 result = gtls_connect_common(conn, sockindex, FALSE, &done);
1338 static ssize_t gtls_send(struct connectdata *conn,
1344 ssize_t rc = gnutls_record_send(conn->ssl[sockindex].session, mem, len);
1347 *curlcode = (rc == GNUTLS_E_AGAIN)
1357 static void close_one(struct connectdata *conn,
1360 if(conn->ssl[idx].session) {
1361 gnutls_bye(conn->ssl[idx].session, GNUTLS_SHUT_RDWR);
1362 gnutls_deinit(conn->ssl[idx].session);
1363 conn->ssl[idx].session = NULL;
1365 if(conn->ssl[idx].cred) {
1366 gnutls_certificate_free_credentials(conn->ssl[idx].cred);
1367 conn->ssl[idx].cred = NULL;
1370 if(conn->ssl[idx].srp_client_cred) {
1371 gnutls_srp_free_client_credentials(conn->ssl[idx].srp_client_cred);
1372 conn->ssl[idx].srp_client_cred = NULL;
1377 void Curl_gtls_close(struct connectdata *conn, int sockindex)
1379 close_one(conn, sockindex);
1383 * This function is called to shut down the SSL layer but keep the
1384 * socket open (CCC - Clear Command Channel)
1386 int Curl_gtls_shutdown(struct connectdata *conn, int sockindex)
1390 struct SessionHandle *data = conn->data;
1394 /* This has only been tested on the proftpd server, and the mod_tls code
1395 sends a close notify alert without waiting for a close notify alert in
1396 response. Thus we wait for a close notify alert from the server, but
1397 we do not send one. Let's hope other servers do the same... */
1399 if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
1400 gnutls_bye(conn->ssl[sockindex].session, GNUTLS_SHUT_WR);
1402 if(conn->ssl[sockindex].session) {
1404 int what = Curl_socket_ready(conn->sock[sockindex],
1405 CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
1407 /* Something to read, let's do it and hope that it is the close
1408 notify alert from the server */
1409 result = gnutls_record_recv(conn->ssl[sockindex].session,
1413 /* This is the expected response. There was no data but only
1414 the close notify alert */
1417 case GNUTLS_E_AGAIN:
1418 case GNUTLS_E_INTERRUPTED:
1419 infof(data, "GNUTLS_E_AGAIN || GNUTLS_E_INTERRUPTED\n");
1427 else if(0 == what) {
1429 failf(data, "SSL shutdown timeout");
1434 /* anything that gets here is fatally bad */
1435 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
1440 gnutls_deinit(conn->ssl[sockindex].session);
1442 gnutls_certificate_free_credentials(conn->ssl[sockindex].cred);
1445 if(data->set.ssl.authtype == CURL_TLSAUTH_SRP
1446 && data->set.ssl.username != NULL)
1447 gnutls_srp_free_client_credentials(conn->ssl[sockindex].srp_client_cred);
1450 conn->ssl[sockindex].cred = NULL;
1451 conn->ssl[sockindex].session = NULL;
1456 static ssize_t gtls_recv(struct connectdata *conn, /* connection data */
1457 int num, /* socketindex */
1458 char *buf, /* store read data here */
1459 size_t buffersize, /* max amount to read */
1464 ret = gnutls_record_recv(conn->ssl[num].session, buf, buffersize);
1465 if((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED)) {
1466 *curlcode = CURLE_AGAIN;
1470 if(ret == GNUTLS_E_REHANDSHAKE) {
1471 /* BLOCKING call, this is bad but a work-around for now. Fixing this "the
1472 proper way" takes a whole lot of work. */
1473 CURLcode result = handshake(conn, num, FALSE, FALSE);
1475 /* handshake() writes error message on its own */
1478 *curlcode = CURLE_AGAIN; /* then return as if this was a wouldblock */
1483 failf(conn->data, "GnuTLS recv error (%d): %s",
1484 (int)ret, gnutls_strerror((int)ret));
1485 *curlcode = CURLE_RECV_ERROR;
1492 void Curl_gtls_session_free(void *ptr)
1497 size_t Curl_gtls_version(char *buffer, size_t size)
1499 return snprintf(buffer, size, "GnuTLS/%s", gnutls_check_version(NULL));
1502 #ifndef USE_GNUTLS_NETTLE
1503 static int Curl_gtls_seed(struct SessionHandle *data)
1505 /* we have the "SSL is seeded" boolean static to prevent multiple
1506 time-consuming seedings in vain */
1507 static bool ssl_seeded = FALSE;
1509 /* Quickly add a bit of entropy */
1510 gcry_fast_random_poll();
1512 if(!ssl_seeded || data->set.str[STRING_SSL_RANDOM_FILE] ||
1513 data->set.str[STRING_SSL_EGDSOCKET]) {
1515 /* TODO: to a good job seeding the RNG
1516 This may involve the gcry_control function and these options:
1517 GCRYCTL_SET_RANDOM_SEED_FILE
1518 GCRYCTL_SET_RNDEGD_SOCKET
1526 /* data might be NULL! */
1527 int Curl_gtls_random(struct SessionHandle *data,
1528 unsigned char *entropy,
1531 #if defined(USE_GNUTLS_NETTLE)
1533 gnutls_rnd(GNUTLS_RND_RANDOM, entropy, length);
1534 #elif defined(USE_GNUTLS)
1536 Curl_gtls_seed(data); /* Initiate the seed if not already done */
1537 gcry_randomize(entropy, length, GCRY_STRONG_RANDOM);
1542 void Curl_gtls_md5sum(unsigned char *tmp, /* input */
1544 unsigned char *md5sum, /* output */
1547 #if defined(USE_GNUTLS_NETTLE)
1548 struct md5_ctx MD5pw;
1550 md5_update(&MD5pw, (unsigned int)tmplen, tmp);
1551 md5_digest(&MD5pw, (unsigned int)md5len, md5sum);
1552 #elif defined(USE_GNUTLS)
1554 gcry_md_open(&MD5pw, GCRY_MD_MD5, 0);
1555 gcry_md_write(MD5pw, tmp, tmplen);
1556 memcpy(md5sum, gcry_md_read (MD5pw, 0), md5len);
1557 gcry_md_close(MD5pw);
1561 void Curl_gtls_sha256sum(const unsigned char *tmp, /* input */
1563 unsigned char *sha256sum, /* output */
1566 #if defined(USE_GNUTLS_NETTLE)
1567 struct sha256_ctx SHA256pw;
1568 sha256_init(&SHA256pw);
1569 sha256_update(&SHA256pw, (unsigned int)tmplen, tmp);
1570 sha256_digest(&SHA256pw, (unsigned int)sha256len, sha256sum);
1571 #elif defined(USE_GNUTLS)
1572 gcry_md_hd_t SHA256pw;
1573 gcry_md_open(&SHA256pw, GCRY_MD_SHA256, 0);
1574 gcry_md_write(SHA256pw, tmp, tmplen);
1575 memcpy(sha256sum, gcry_md_read (SHA256pw, 0), sha256len);
1576 gcry_md_close(SHA256pw);
1580 bool Curl_gtls_cert_status_request(void)
1589 #endif /* USE_GNUTLS */