1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2016, 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 https://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 https://developer.gnome.org/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 Curl_easy *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 Curl_easy *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 Curl_easy *data = conn->data;
371 gnutls_session_t session;
373 bool sni = TRUE; /* default is SNI enabled */
375 struct in6_addr addr;
379 #ifndef USE_GNUTLS_PRIORITY_SET_DIRECT
380 static const int cipher_priority[] = {
381 /* These two ciphers were added to GnuTLS as late as ver. 3.0.1,
382 but this code path is only ever used for ver. < 2.12.0.
383 GNUTLS_CIPHER_AES_128_GCM,
384 GNUTLS_CIPHER_AES_256_GCM,
386 GNUTLS_CIPHER_AES_128_CBC,
387 GNUTLS_CIPHER_AES_256_CBC,
388 GNUTLS_CIPHER_CAMELLIA_128_CBC,
389 GNUTLS_CIPHER_CAMELLIA_256_CBC,
390 GNUTLS_CIPHER_3DES_CBC,
392 static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
393 static int protocol_priority[] = { 0, 0, 0, 0 };
395 #define GNUTLS_CIPHERS "NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509"
396 /* If GnuTLS was compiled without support for SRP it will error out if SRP is
397 requested in the priority string, so treat it specially
399 #define GNUTLS_SRP "+SRP"
400 const char* prioritylist;
401 const char *err = NULL;
404 if(conn->ssl[sockindex].state == ssl_connection_complete)
405 /* to make us tolerant against being called more than once for the
412 /* GnuTLS only supports SSLv3 and TLSv1 */
413 if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) {
414 failf(data, "GnuTLS does not support SSLv2");
415 return CURLE_SSL_CONNECT_ERROR;
417 else if(data->set.ssl.version == CURL_SSLVERSION_SSLv3)
418 sni = FALSE; /* SSLv3 has no SNI */
420 /* allocate a cred struct */
421 rc = gnutls_certificate_allocate_credentials(&conn->ssl[sockindex].cred);
422 if(rc != GNUTLS_E_SUCCESS) {
423 failf(data, "gnutls_cert_all_cred() failed: %s", gnutls_strerror(rc));
424 return CURLE_SSL_CONNECT_ERROR;
428 if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
429 infof(data, "Using TLS-SRP username: %s\n", data->set.ssl.username);
431 rc = gnutls_srp_allocate_client_credentials(
432 &conn->ssl[sockindex].srp_client_cred);
433 if(rc != GNUTLS_E_SUCCESS) {
434 failf(data, "gnutls_srp_allocate_client_cred() failed: %s",
435 gnutls_strerror(rc));
436 return CURLE_OUT_OF_MEMORY;
439 rc = gnutls_srp_set_client_credentials(conn->ssl[sockindex].
441 data->set.ssl.username,
442 data->set.ssl.password);
443 if(rc != GNUTLS_E_SUCCESS) {
444 failf(data, "gnutls_srp_set_client_cred() failed: %s",
445 gnutls_strerror(rc));
446 return CURLE_BAD_FUNCTION_ARGUMENT;
451 if(data->set.ssl.CAfile) {
452 /* set the trusted CA cert bundle file */
453 gnutls_certificate_set_verify_flags(conn->ssl[sockindex].cred,
454 GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
456 rc = gnutls_certificate_set_x509_trust_file(conn->ssl[sockindex].cred,
457 data->set.ssl.CAfile,
458 GNUTLS_X509_FMT_PEM);
460 infof(data, "error reading ca cert file %s (%s)\n",
461 data->set.ssl.CAfile, gnutls_strerror(rc));
462 if(data->set.ssl.verifypeer)
463 return CURLE_SSL_CACERT_BADFILE;
466 infof(data, "found %d certificates in %s\n",
467 rc, data->set.ssl.CAfile);
471 if(data->set.ssl.CApath) {
472 /* set the trusted CA cert directory */
473 rc = gnutls_certificate_set_x509_trust_dir(conn->ssl[sockindex].cred,
474 data->set.ssl.CApath,
475 GNUTLS_X509_FMT_PEM);
477 infof(data, "error reading ca cert file %s (%s)\n",
478 data->set.ssl.CAfile, gnutls_strerror(rc));
479 if(data->set.ssl.verifypeer)
480 return CURLE_SSL_CACERT_BADFILE;
483 infof(data, "found %d certificates in %s\n",
484 rc, data->set.ssl.CApath);
488 #ifdef CURL_CA_FALLBACK
489 /* use system ca certificate store as fallback */
490 if(data->set.ssl.verifypeer &&
491 !(data->set.ssl.CAfile || data->set.ssl.CApath)) {
492 gnutls_certificate_set_x509_system_trust(conn->ssl[sockindex].cred);
496 if(data->set.ssl.CRLfile) {
497 /* set the CRL list file */
498 rc = gnutls_certificate_set_x509_crl_file(conn->ssl[sockindex].cred,
499 data->set.ssl.CRLfile,
500 GNUTLS_X509_FMT_PEM);
502 failf(data, "error reading crl file %s (%s)",
503 data->set.ssl.CRLfile, gnutls_strerror(rc));
504 return CURLE_SSL_CRL_BADFILE;
507 infof(data, "found %d CRL in %s\n",
508 rc, data->set.ssl.CRLfile);
511 /* Initialize TLS session as a client */
512 rc = gnutls_init(&conn->ssl[sockindex].session, GNUTLS_CLIENT);
513 if(rc != GNUTLS_E_SUCCESS) {
514 failf(data, "gnutls_init() failed: %d", rc);
515 return CURLE_SSL_CONNECT_ERROR;
518 /* convenient assign */
519 session = conn->ssl[sockindex].session;
521 if((0 == Curl_inet_pton(AF_INET, conn->host.name, &addr)) &&
523 (0 == Curl_inet_pton(AF_INET6, conn->host.name, &addr)) &&
526 (gnutls_server_name_set(session, GNUTLS_NAME_DNS, conn->host.name,
527 strlen(conn->host.name)) < 0))
528 infof(data, "WARNING: failed to configure server name indication (SNI) "
531 /* Use default priorities */
532 rc = gnutls_set_default_priority(session);
533 if(rc != GNUTLS_E_SUCCESS)
534 return CURLE_SSL_CONNECT_ERROR;
536 #ifndef USE_GNUTLS_PRIORITY_SET_DIRECT
537 rc = gnutls_cipher_set_priority(session, cipher_priority);
538 if(rc != GNUTLS_E_SUCCESS)
539 return CURLE_SSL_CONNECT_ERROR;
541 /* Sets the priority on the certificate types supported by gnutls. Priority
542 is higher for types specified before others. After specifying the types
543 you want, you must append a 0. */
544 rc = gnutls_certificate_type_set_priority(session, cert_type_priority);
545 if(rc != GNUTLS_E_SUCCESS)
546 return CURLE_SSL_CONNECT_ERROR;
548 if(data->set.ssl.cipher_list != NULL) {
549 failf(data, "can't pass a custom cipher list to older GnuTLS"
551 return CURLE_SSL_CONNECT_ERROR;
554 switch (data->set.ssl.version) {
555 case CURL_SSLVERSION_SSLv3:
556 protocol_priority[0] = GNUTLS_SSL3;
558 case CURL_SSLVERSION_DEFAULT:
559 case CURL_SSLVERSION_TLSv1:
560 protocol_priority[0] = GNUTLS_TLS1_0;
561 protocol_priority[1] = GNUTLS_TLS1_1;
562 protocol_priority[2] = GNUTLS_TLS1_2;
564 case CURL_SSLVERSION_TLSv1_0:
565 protocol_priority[0] = GNUTLS_TLS1_0;
567 case CURL_SSLVERSION_TLSv1_1:
568 protocol_priority[0] = GNUTLS_TLS1_1;
570 case CURL_SSLVERSION_TLSv1_2:
571 protocol_priority[0] = GNUTLS_TLS1_2;
573 case CURL_SSLVERSION_SSLv2:
575 failf(data, "GnuTLS does not support SSLv2");
576 return CURLE_SSL_CONNECT_ERROR;
579 rc = gnutls_protocol_set_priority(session, protocol_priority);
580 if(rc != GNUTLS_E_SUCCESS) {
581 failf(data, "Did you pass a valid GnuTLS cipher list?");
582 return CURLE_SSL_CONNECT_ERROR;
586 /* Ensure +SRP comes at the *end* of all relevant strings so that it can be
587 * removed if a run-time error indicates that SRP is not supported by this
589 switch (data->set.ssl.version) {
590 case CURL_SSLVERSION_SSLv3:
591 prioritylist = GNUTLS_CIPHERS ":-VERS-TLS-ALL:+VERS-SSL3.0";
594 case CURL_SSLVERSION_DEFAULT:
595 case CURL_SSLVERSION_TLSv1:
596 prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:" GNUTLS_SRP;
598 case CURL_SSLVERSION_TLSv1_0:
599 prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
600 "+VERS-TLS1.0:" GNUTLS_SRP;
602 case CURL_SSLVERSION_TLSv1_1:
603 prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
604 "+VERS-TLS1.1:" GNUTLS_SRP;
606 case CURL_SSLVERSION_TLSv1_2:
607 prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
608 "+VERS-TLS1.2:" GNUTLS_SRP;
610 case CURL_SSLVERSION_SSLv2:
612 failf(data, "GnuTLS does not support SSLv2");
613 return CURLE_SSL_CONNECT_ERROR;
616 rc = gnutls_priority_set_direct(session, prioritylist, &err);
617 if((rc == GNUTLS_E_INVALID_REQUEST) && err) {
618 if(!strcmp(err, GNUTLS_SRP)) {
619 /* This GnuTLS was probably compiled without support for SRP.
620 * Note that fact and try again without it. */
621 int validprioritylen = curlx_uztosi(err - prioritylist);
622 char *prioritycopy = strdup(prioritylist);
624 return CURLE_OUT_OF_MEMORY;
626 infof(data, "This GnuTLS does not support SRP\n");
628 /* Remove the :+SRP */
629 prioritycopy[validprioritylen - 1] = 0;
630 rc = gnutls_priority_set_direct(session, prioritycopy, &err);
634 if(rc != GNUTLS_E_SUCCESS) {
635 failf(data, "Error %d setting GnuTLS cipher list starting with %s",
637 return CURLE_SSL_CONNECT_ERROR;
642 if(conn->bits.tls_enable_alpn) {
644 gnutls_datum_t protocols[2];
647 if(data->set.httpversion >= CURL_HTTP_VERSION_2) {
648 protocols[cur].data = (unsigned char *)NGHTTP2_PROTO_VERSION_ID;
649 protocols[cur].size = NGHTTP2_PROTO_VERSION_ID_LEN;
651 infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
655 protocols[cur].data = (unsigned char *)ALPN_HTTP_1_1;
656 protocols[cur].size = ALPN_HTTP_1_1_LENGTH;
658 infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1);
660 gnutls_alpn_set_protocols(session, protocols, cur, 0);
664 if(data->set.str[STRING_CERT]) {
665 if(data->set.str[STRING_KEY_PASSWD]) {
666 #if HAVE_GNUTLS_CERTIFICATE_SET_X509_KEY_FILE2
667 const unsigned int supported_key_encryption_algorithms =
668 GNUTLS_PKCS_USE_PKCS12_3DES | GNUTLS_PKCS_USE_PKCS12_ARCFOUR |
669 GNUTLS_PKCS_USE_PKCS12_RC2_40 | GNUTLS_PKCS_USE_PBES2_3DES |
670 GNUTLS_PKCS_USE_PBES2_AES_128 | GNUTLS_PKCS_USE_PBES2_AES_192 |
671 GNUTLS_PKCS_USE_PBES2_AES_256;
672 rc = gnutls_certificate_set_x509_key_file2(
673 conn->ssl[sockindex].cred,
674 data->set.str[STRING_CERT],
675 data->set.str[STRING_KEY] ?
676 data->set.str[STRING_KEY] : data->set.str[STRING_CERT],
677 do_file_type(data->set.str[STRING_CERT_TYPE]),
678 data->set.str[STRING_KEY_PASSWD],
679 supported_key_encryption_algorithms);
680 if(rc != GNUTLS_E_SUCCESS) {
682 "error reading X.509 potentially-encrypted key file: %s",
683 gnutls_strerror(rc));
684 return CURLE_SSL_CONNECT_ERROR;
687 failf(data, "gnutls lacks support for encrypted key files");
688 return CURLE_SSL_CONNECT_ERROR;
692 rc = gnutls_certificate_set_x509_key_file(
693 conn->ssl[sockindex].cred,
694 data->set.str[STRING_CERT],
695 data->set.str[STRING_KEY] ?
696 data->set.str[STRING_KEY] : data->set.str[STRING_CERT],
697 do_file_type(data->set.str[STRING_CERT_TYPE]) );
698 if(rc != GNUTLS_E_SUCCESS) {
699 failf(data, "error reading X.509 key or certificate file: %s",
700 gnutls_strerror(rc));
701 return CURLE_SSL_CONNECT_ERROR;
707 /* put the credentials to the current session */
708 if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
709 rc = gnutls_credentials_set(session, GNUTLS_CRD_SRP,
710 conn->ssl[sockindex].srp_client_cred);
711 if(rc != GNUTLS_E_SUCCESS) {
712 failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc));
713 return CURLE_SSL_CONNECT_ERROR;
719 rc = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
720 conn->ssl[sockindex].cred);
721 if(rc != GNUTLS_E_SUCCESS) {
722 failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc));
723 return CURLE_SSL_CONNECT_ERROR;
727 /* set the connection handle (file descriptor for the socket) */
728 gnutls_transport_set_ptr(session,
729 GNUTLS_INT_TO_POINTER_CAST(conn->sock[sockindex]));
731 /* register callback functions to send and receive data. */
732 gnutls_transport_set_push_function(session, Curl_gtls_push);
733 gnutls_transport_set_pull_function(session, Curl_gtls_pull);
735 /* lowat must be set to zero when using custom push and pull functions. */
736 gnutls_transport_set_lowat(session, 0);
739 if(data->set.ssl.verifystatus) {
740 rc = gnutls_ocsp_status_request_enable_client(session, NULL, 0, NULL);
741 if(rc != GNUTLS_E_SUCCESS) {
742 failf(data, "gnutls_ocsp_status_request_enable_client() failed: %d", rc);
743 return CURLE_SSL_CONNECT_ERROR;
748 /* This might be a reconnect, so we check for a session ID in the cache
749 to speed up things */
750 if(conn->ssl_config.sessionid) {
754 Curl_ssl_sessionid_lock(conn);
755 if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, &ssl_idsize)) {
756 /* we got a session id, use it! */
757 gnutls_session_set_data(session, ssl_sessionid, ssl_idsize);
759 /* Informational message */
760 infof (data, "SSL re-using session ID\n");
762 Curl_ssl_sessionid_unlock(conn);
768 static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
769 gnutls_x509_crt_t cert,
770 const char *pinnedpubkey)
773 size_t len1 = 0, len2 = 0;
774 unsigned char *buff1 = NULL;
776 gnutls_pubkey_t key = NULL;
778 /* Result is returned to caller */
780 CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
782 /* if a path wasn't specified, don't pin */
783 if(NULL == pinnedpubkey)
790 /* Begin Gyrations to get the public key */
791 gnutls_pubkey_init(&key);
793 ret = gnutls_pubkey_import_x509(key, cert, 0);
797 ret = gnutls_pubkey_export(key, GNUTLS_X509_FMT_DER, NULL, &len1);
798 if(ret != GNUTLS_E_SHORT_MEMORY_BUFFER || len1 == 0)
801 buff1 = malloc(len1);
807 ret = gnutls_pubkey_export(key, GNUTLS_X509_FMT_DER, buff1, &len2);
808 if(ret < 0 || len1 != len2)
813 /* The one good exit point */
814 result = Curl_pin_peer_pubkey(data, pinnedpubkey, buff1, len1);
818 gnutls_pubkey_deinit(key);
820 Curl_safefree(buff1);
825 static Curl_recv gtls_recv;
826 static Curl_send gtls_send;
829 gtls_connect_step3(struct connectdata *conn,
832 unsigned int cert_list_size;
833 const gnutls_datum_t *chainp;
834 unsigned int verify_status = 0;
835 gnutls_x509_crt_t x509_cert, x509_issuer;
836 gnutls_datum_t issuerp;
837 char certbuf[256] = ""; /* big enough? */
843 struct Curl_easy *data = conn->data;
844 gnutls_session_t session = conn->ssl[sockindex].session;
847 gnutls_datum_t proto;
849 CURLcode result = CURLE_OK;
851 gnutls_protocol_t version = gnutls_protocol_get_version(session);
853 /* the name of the cipher suite used, e.g. ECDHE_RSA_AES_256_GCM_SHA384. */
854 ptr = gnutls_cipher_suite_get_name(gnutls_kx_get(session),
855 gnutls_cipher_get(session),
856 gnutls_mac_get(session));
858 infof(data, "SSL connection using %s / %s\n",
859 gnutls_protocol_get_name(version), ptr);
861 /* This function will return the peer's raw certificate (chain) as sent by
862 the peer. These certificates are in raw format (DER encoded for
863 X.509). In case of a X.509 then a certificate list may be present. The
864 first certificate in the list is the peer's certificate, following the
865 issuer's certificate, then the issuer's issuer etc. */
867 chainp = gnutls_certificate_get_peers(session, &cert_list_size);
869 if(data->set.ssl.verifypeer ||
870 data->set.ssl.verifyhost ||
871 data->set.ssl.issuercert) {
873 if(data->set.ssl.authtype == CURL_TLSAUTH_SRP
874 && data->set.ssl.username != NULL
875 && !data->set.ssl.verifypeer
876 && gnutls_cipher_get(session)) {
877 /* no peer cert, but auth is ok if we have SRP user and cipher and no
882 failf(data, "failed to get server cert");
883 return CURLE_PEER_FAILED_VERIFICATION;
888 infof(data, "\t common name: WARNING couldn't obtain\n");
891 if(data->set.ssl.certinfo && chainp) {
894 result = Curl_ssl_init_certinfo(data, cert_list_size);
898 for(i = 0; i < cert_list_size; i++) {
899 const char *beg = (const char *) chainp[i].data;
900 const char *end = beg + chainp[i].size;
902 result = Curl_extract_certinfo(conn, i, beg, end);
908 if(data->set.ssl.verifypeer) {
909 /* This function will try to verify the peer's certificate and return its
910 status (trusted, invalid etc.). The value of status should be one or
911 more of the gnutls_certificate_status_t enumerated elements bitwise
912 or'd. To avoid denial of service attacks some default upper limits
913 regarding the certificate key size and chain size are set. To override
914 them use gnutls_certificate_set_verify_limits(). */
916 rc = gnutls_certificate_verify_peers2(session, &verify_status);
918 failf(data, "server cert verify failed: %d", rc);
919 return CURLE_SSL_CONNECT_ERROR;
922 /* verify_status is a bitmask of gnutls_certificate_status bits */
923 if(verify_status & GNUTLS_CERT_INVALID) {
924 if(data->set.ssl.verifypeer) {
925 failf(data, "server certificate verification failed. CAfile: %s "
926 "CRLfile: %s", data->set.ssl.CAfile?data->set.ssl.CAfile:"none",
927 data->set.ssl.CRLfile?data->set.ssl.CRLfile:"none");
928 return CURLE_SSL_CACERT;
931 infof(data, "\t server certificate verification FAILED\n");
934 infof(data, "\t server certificate verification OK\n");
937 infof(data, "\t server certificate verification SKIPPED\n");
940 if(data->set.ssl.verifystatus) {
941 if(gnutls_ocsp_status_request_is_checked(session, 0) == 0) {
942 gnutls_datum_t status_request;
943 gnutls_ocsp_resp_t ocsp_resp;
945 gnutls_ocsp_cert_status_t status;
946 gnutls_x509_crl_reason_t reason;
948 rc = gnutls_ocsp_status_request_get(session, &status_request);
950 infof(data, "\t server certificate status verification FAILED\n");
952 if(rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
953 failf(data, "No OCSP response received");
954 return CURLE_SSL_INVALIDCERTSTATUS;
958 failf(data, "Invalid OCSP response received");
959 return CURLE_SSL_INVALIDCERTSTATUS;
962 gnutls_ocsp_resp_init(&ocsp_resp);
964 rc = gnutls_ocsp_resp_import(ocsp_resp, &status_request);
966 failf(data, "Invalid OCSP response received");
967 return CURLE_SSL_INVALIDCERTSTATUS;
970 rc = gnutls_ocsp_resp_get_single(ocsp_resp, 0, NULL, NULL, NULL, NULL,
971 &status, NULL, NULL, NULL, &reason);
974 case GNUTLS_OCSP_CERT_GOOD:
977 case GNUTLS_OCSP_CERT_REVOKED: {
978 const char *crl_reason;
982 case GNUTLS_X509_CRLREASON_UNSPECIFIED:
983 crl_reason = "unspecified reason";
986 case GNUTLS_X509_CRLREASON_KEYCOMPROMISE:
987 crl_reason = "private key compromised";
990 case GNUTLS_X509_CRLREASON_CACOMPROMISE:
991 crl_reason = "CA compromised";
994 case GNUTLS_X509_CRLREASON_AFFILIATIONCHANGED:
995 crl_reason = "affiliation has changed";
998 case GNUTLS_X509_CRLREASON_SUPERSEDED:
999 crl_reason = "certificate superseded";
1002 case GNUTLS_X509_CRLREASON_CESSATIONOFOPERATION:
1003 crl_reason = "operation has ceased";
1006 case GNUTLS_X509_CRLREASON_CERTIFICATEHOLD:
1007 crl_reason = "certificate is on hold";
1010 case GNUTLS_X509_CRLREASON_REMOVEFROMCRL:
1011 crl_reason = "will be removed from delta CRL";
1014 case GNUTLS_X509_CRLREASON_PRIVILEGEWITHDRAWN:
1015 crl_reason = "privilege withdrawn";
1018 case GNUTLS_X509_CRLREASON_AACOMPROMISE:
1019 crl_reason = "AA compromised";
1023 failf(data, "Server certificate was revoked: %s", crl_reason);
1028 case GNUTLS_OCSP_CERT_UNKNOWN:
1029 failf(data, "Server certificate status is unknown");
1033 gnutls_ocsp_resp_deinit(ocsp_resp);
1035 return CURLE_SSL_INVALIDCERTSTATUS;
1038 infof(data, "\t server certificate status verification OK\n");
1041 infof(data, "\t server certificate status verification SKIPPED\n");
1044 /* initialize an X.509 certificate structure. */
1045 gnutls_x509_crt_init(&x509_cert);
1048 /* convert the given DER or PEM encoded Certificate to the native
1049 gnutls_x509_crt_t format */
1050 gnutls_x509_crt_import(x509_cert, chainp, GNUTLS_X509_FMT_DER);
1052 if(data->set.ssl.issuercert) {
1053 gnutls_x509_crt_init(&x509_issuer);
1054 issuerp = load_file(data->set.ssl.issuercert);
1055 gnutls_x509_crt_import(x509_issuer, &issuerp, GNUTLS_X509_FMT_PEM);
1056 rc = gnutls_x509_crt_check_issuer(x509_cert, x509_issuer);
1057 gnutls_x509_crt_deinit(x509_issuer);
1058 unload_file(issuerp);
1060 failf(data, "server certificate issuer check failed (IssuerCert: %s)",
1061 data->set.ssl.issuercert?data->set.ssl.issuercert:"none");
1062 gnutls_x509_crt_deinit(x509_cert);
1063 return CURLE_SSL_ISSUER_ERROR;
1065 infof(data, "\t server certificate issuer check OK (Issuer Cert: %s)\n",
1066 data->set.ssl.issuercert?data->set.ssl.issuercert:"none");
1069 size=sizeof(certbuf);
1070 rc = gnutls_x509_crt_get_dn_by_oid(x509_cert, GNUTLS_OID_X520_COMMON_NAME,
1071 0, /* the first and only one */
1076 infof(data, "error fetching CN from cert:%s\n",
1077 gnutls_strerror(rc));
1080 /* This function will check if the given certificate's subject matches the
1081 given hostname. This is a basic implementation of the matching described
1082 in RFC2818 (HTTPS), which takes into account wildcards, and the subject
1083 alternative name PKIX extension. Returns non zero on success, and zero on
1085 rc = gnutls_x509_crt_check_hostname(x509_cert, conn->host.name);
1086 #if GNUTLS_VERSION_NUMBER < 0x030306
1087 /* Before 3.3.6, gnutls_x509_crt_check_hostname() didn't check IP
1091 #define use_addr in6_addr
1093 #define use_addr in_addr
1095 unsigned char addrbuf[sizeof(struct use_addr)];
1096 unsigned char certaddr[sizeof(struct use_addr)];
1097 size_t addrlen = 0, certaddrlen;
1101 if(Curl_inet_pton(AF_INET, conn->host.name, addrbuf) > 0)
1104 else if(Curl_inet_pton(AF_INET6, conn->host.name, addrbuf) > 0)
1110 certaddrlen = sizeof(certaddr);
1111 ret = gnutls_x509_crt_get_subject_alt_name(x509_cert, i, certaddr,
1112 &certaddrlen, NULL);
1113 /* If this happens, it wasn't an IP address. */
1114 if(ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
1118 if(ret != GNUTLS_SAN_IPADDRESS)
1120 if(certaddrlen == addrlen && !memcmp(addrbuf, certaddr, addrlen)) {
1129 if(data->set.ssl.verifyhost) {
1130 failf(data, "SSL: certificate subject name (%s) does not match "
1131 "target host name '%s'", certbuf, conn->host.dispname);
1132 gnutls_x509_crt_deinit(x509_cert);
1133 return CURLE_PEER_FAILED_VERIFICATION;
1136 infof(data, "\t common name: %s (does not match '%s')\n",
1137 certbuf, conn->host.dispname);
1140 infof(data, "\t common name: %s (matched)\n", certbuf);
1142 /* Check for time-based validity */
1143 certclock = gnutls_x509_crt_get_expiration_time(x509_cert);
1145 if(certclock == (time_t)-1) {
1146 if(data->set.ssl.verifypeer) {
1147 failf(data, "server cert expiration date verify failed");
1148 gnutls_x509_crt_deinit(x509_cert);
1149 return CURLE_SSL_CONNECT_ERROR;
1152 infof(data, "\t server certificate expiration date verify FAILED\n");
1155 if(certclock < time(NULL)) {
1156 if(data->set.ssl.verifypeer) {
1157 failf(data, "server certificate expiration date has passed.");
1158 gnutls_x509_crt_deinit(x509_cert);
1159 return CURLE_PEER_FAILED_VERIFICATION;
1162 infof(data, "\t server certificate expiration date FAILED\n");
1165 infof(data, "\t server certificate expiration date OK\n");
1168 certclock = gnutls_x509_crt_get_activation_time(x509_cert);
1170 if(certclock == (time_t)-1) {
1171 if(data->set.ssl.verifypeer) {
1172 failf(data, "server cert activation date verify failed");
1173 gnutls_x509_crt_deinit(x509_cert);
1174 return CURLE_SSL_CONNECT_ERROR;
1177 infof(data, "\t server certificate activation date verify FAILED\n");
1180 if(certclock > time(NULL)) {
1181 if(data->set.ssl.verifypeer) {
1182 failf(data, "server certificate not activated yet.");
1183 gnutls_x509_crt_deinit(x509_cert);
1184 return CURLE_PEER_FAILED_VERIFICATION;
1187 infof(data, "\t server certificate activation date FAILED\n");
1190 infof(data, "\t server certificate activation date OK\n");
1193 ptr = data->set.str[STRING_SSL_PINNEDPUBLICKEY];
1195 result = pkp_pin_peer_pubkey(data, x509_cert, ptr);
1196 if(result != CURLE_OK) {
1197 failf(data, "SSL: public key does not match pinned public key!");
1198 gnutls_x509_crt_deinit(x509_cert);
1213 /* public key algorithm's parameters */
1214 algo = gnutls_x509_crt_get_pk_algorithm(x509_cert, &bits);
1215 infof(data, "\t certificate public key: %s\n",
1216 gnutls_pk_algorithm_get_name(algo));
1218 /* version of the X.509 certificate. */
1219 infof(data, "\t certificate version: #%d\n",
1220 gnutls_x509_crt_get_version(x509_cert));
1223 size = sizeof(certbuf);
1224 gnutls_x509_crt_get_dn(x509_cert, certbuf, &size);
1225 infof(data, "\t subject: %s\n", certbuf);
1227 certclock = gnutls_x509_crt_get_activation_time(x509_cert);
1228 showtime(data, "start date", certclock);
1230 certclock = gnutls_x509_crt_get_expiration_time(x509_cert);
1231 showtime(data, "expire date", certclock);
1233 size = sizeof(certbuf);
1234 gnutls_x509_crt_get_issuer_dn(x509_cert, certbuf, &size);
1235 infof(data, "\t issuer: %s\n", certbuf);
1237 gnutls_x509_crt_deinit(x509_cert);
1239 /* compression algorithm (if any) */
1240 ptr = gnutls_compression_get_name(gnutls_compression_get(session));
1241 /* the *_get_name() says "NULL" if GNUTLS_COMP_NULL is returned */
1242 infof(data, "\t compression: %s\n", ptr);
1245 if(conn->bits.tls_enable_alpn) {
1246 rc = gnutls_alpn_get_selected_protocol(session, &proto);
1248 infof(data, "ALPN, server accepted to use %.*s\n", proto.size,
1252 if(proto.size == NGHTTP2_PROTO_VERSION_ID_LEN &&
1253 !memcmp(NGHTTP2_PROTO_VERSION_ID, proto.data,
1254 NGHTTP2_PROTO_VERSION_ID_LEN)) {
1255 conn->negnpn = CURL_HTTP_VERSION_2;
1259 if(proto.size == ALPN_HTTP_1_1_LENGTH &&
1260 !memcmp(ALPN_HTTP_1_1, proto.data, ALPN_HTTP_1_1_LENGTH)) {
1261 conn->negnpn = CURL_HTTP_VERSION_1_1;
1265 infof(data, "ALPN, server did not agree to a protocol\n");
1269 conn->ssl[sockindex].state = ssl_connection_complete;
1270 conn->recv[sockindex] = gtls_recv;
1271 conn->send[sockindex] = gtls_send;
1273 if(conn->ssl_config.sessionid) {
1274 /* we always unconditionally get the session id here, as even if we
1275 already got it from the cache and asked to use it in the connection, it
1276 might've been rejected and then a new one is in use now and we need to
1279 void *ssl_sessionid;
1280 void *connect_sessionid;
1281 size_t connect_idsize = 0;
1283 /* get the session ID data size */
1284 gnutls_session_get_data(session, NULL, &connect_idsize);
1285 connect_sessionid = malloc(connect_idsize); /* get a buffer for it */
1287 if(connect_sessionid) {
1288 /* extract session ID to the allocated buffer */
1289 gnutls_session_get_data(session, connect_sessionid, &connect_idsize);
1291 Curl_ssl_sessionid_lock(conn);
1292 incache = !(Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL));
1294 /* there was one before in the cache, so instead of risking that the
1295 previous one was rejected, we just kill that and store the new */
1296 Curl_ssl_delsessionid(conn, ssl_sessionid);
1299 /* store this session id */
1300 result = Curl_ssl_addsessionid(conn, connect_sessionid, connect_idsize);
1301 Curl_ssl_sessionid_unlock(conn);
1303 free(connect_sessionid);
1304 result = CURLE_OUT_OF_MEMORY;
1308 result = CURLE_OUT_OF_MEMORY;
1316 * This function is called after the TCP connect has completed. Setup the TLS
1317 * layer and do all necessary magic.
1319 /* We use connssl->connecting_state to keep track of the connection status;
1320 there are three states: 'ssl_connect_1' (not started yet or complete),
1321 'ssl_connect_2_reading' (waiting for data from server), and
1322 'ssl_connect_2_writing' (waiting to be able to write).
1325 gtls_connect_common(struct connectdata *conn,
1331 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1333 /* Initiate the connection, if not already done */
1334 if(ssl_connect_1==connssl->connecting_state) {
1335 rc = gtls_connect_step1 (conn, sockindex);
1340 rc = handshake(conn, sockindex, TRUE, nonblocking);
1342 /* handshake() sets its own error message with failf() */
1345 /* Finish connecting once the handshake is done */
1346 if(ssl_connect_1==connssl->connecting_state) {
1347 rc = gtls_connect_step3(conn, sockindex);
1352 *done = ssl_connect_1==connssl->connecting_state;
1358 Curl_gtls_connect_nonblocking(struct connectdata *conn,
1362 return gtls_connect_common(conn, sockindex, TRUE, done);
1366 Curl_gtls_connect(struct connectdata *conn,
1373 result = gtls_connect_common(conn, sockindex, FALSE, &done);
1382 static ssize_t gtls_send(struct connectdata *conn,
1388 ssize_t rc = gnutls_record_send(conn->ssl[sockindex].session, mem, len);
1391 *curlcode = (rc == GNUTLS_E_AGAIN)
1401 static void close_one(struct connectdata *conn,
1404 if(conn->ssl[idx].session) {
1405 gnutls_bye(conn->ssl[idx].session, GNUTLS_SHUT_RDWR);
1406 gnutls_deinit(conn->ssl[idx].session);
1407 conn->ssl[idx].session = NULL;
1409 if(conn->ssl[idx].cred) {
1410 gnutls_certificate_free_credentials(conn->ssl[idx].cred);
1411 conn->ssl[idx].cred = NULL;
1414 if(conn->ssl[idx].srp_client_cred) {
1415 gnutls_srp_free_client_credentials(conn->ssl[idx].srp_client_cred);
1416 conn->ssl[idx].srp_client_cred = NULL;
1421 void Curl_gtls_close(struct connectdata *conn, int sockindex)
1423 close_one(conn, sockindex);
1427 * This function is called to shut down the SSL layer but keep the
1428 * socket open (CCC - Clear Command Channel)
1430 int Curl_gtls_shutdown(struct connectdata *conn, int sockindex)
1434 struct Curl_easy *data = conn->data;
1438 /* This has only been tested on the proftpd server, and the mod_tls code
1439 sends a close notify alert without waiting for a close notify alert in
1440 response. Thus we wait for a close notify alert from the server, but
1441 we do not send one. Let's hope other servers do the same... */
1443 if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
1444 gnutls_bye(conn->ssl[sockindex].session, GNUTLS_SHUT_WR);
1446 if(conn->ssl[sockindex].session) {
1448 int what = Curl_socket_ready(conn->sock[sockindex],
1449 CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
1451 /* Something to read, let's do it and hope that it is the close
1452 notify alert from the server */
1453 result = gnutls_record_recv(conn->ssl[sockindex].session,
1457 /* This is the expected response. There was no data but only
1458 the close notify alert */
1461 case GNUTLS_E_AGAIN:
1462 case GNUTLS_E_INTERRUPTED:
1463 infof(data, "GNUTLS_E_AGAIN || GNUTLS_E_INTERRUPTED\n");
1471 else if(0 == what) {
1473 failf(data, "SSL shutdown timeout");
1478 /* anything that gets here is fatally bad */
1479 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
1484 gnutls_deinit(conn->ssl[sockindex].session);
1486 gnutls_certificate_free_credentials(conn->ssl[sockindex].cred);
1489 if(data->set.ssl.authtype == CURL_TLSAUTH_SRP
1490 && data->set.ssl.username != NULL)
1491 gnutls_srp_free_client_credentials(conn->ssl[sockindex].srp_client_cred);
1494 conn->ssl[sockindex].cred = NULL;
1495 conn->ssl[sockindex].session = NULL;
1500 static ssize_t gtls_recv(struct connectdata *conn, /* connection data */
1501 int num, /* socketindex */
1502 char *buf, /* store read data here */
1503 size_t buffersize, /* max amount to read */
1508 ret = gnutls_record_recv(conn->ssl[num].session, buf, buffersize);
1509 if((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED)) {
1510 *curlcode = CURLE_AGAIN;
1514 if(ret == GNUTLS_E_REHANDSHAKE) {
1515 /* BLOCKING call, this is bad but a work-around for now. Fixing this "the
1516 proper way" takes a whole lot of work. */
1517 CURLcode result = handshake(conn, num, FALSE, FALSE);
1519 /* handshake() writes error message on its own */
1522 *curlcode = CURLE_AGAIN; /* then return as if this was a wouldblock */
1527 failf(conn->data, "GnuTLS recv error (%d): %s",
1528 (int)ret, gnutls_strerror((int)ret));
1529 *curlcode = CURLE_RECV_ERROR;
1536 void Curl_gtls_session_free(void *ptr)
1541 size_t Curl_gtls_version(char *buffer, size_t size)
1543 return snprintf(buffer, size, "GnuTLS/%s", gnutls_check_version(NULL));
1546 #ifndef USE_GNUTLS_NETTLE
1547 static int Curl_gtls_seed(struct Curl_easy *data)
1549 /* we have the "SSL is seeded" boolean static to prevent multiple
1550 time-consuming seedings in vain */
1551 static bool ssl_seeded = FALSE;
1553 /* Quickly add a bit of entropy */
1554 gcry_fast_random_poll();
1556 if(!ssl_seeded || data->set.str[STRING_SSL_RANDOM_FILE] ||
1557 data->set.str[STRING_SSL_EGDSOCKET]) {
1559 /* TODO: to a good job seeding the RNG
1560 This may involve the gcry_control function and these options:
1561 GCRYCTL_SET_RANDOM_SEED_FILE
1562 GCRYCTL_SET_RNDEGD_SOCKET
1570 /* data might be NULL! */
1571 int Curl_gtls_random(struct Curl_easy *data,
1572 unsigned char *entropy,
1575 #if defined(USE_GNUTLS_NETTLE)
1577 gnutls_rnd(GNUTLS_RND_RANDOM, entropy, length);
1578 #elif defined(USE_GNUTLS)
1580 Curl_gtls_seed(data); /* Initiate the seed if not already done */
1581 gcry_randomize(entropy, length, GCRY_STRONG_RANDOM);
1586 void Curl_gtls_md5sum(unsigned char *tmp, /* input */
1588 unsigned char *md5sum, /* output */
1591 #if defined(USE_GNUTLS_NETTLE)
1592 struct md5_ctx MD5pw;
1594 md5_update(&MD5pw, (unsigned int)tmplen, tmp);
1595 md5_digest(&MD5pw, (unsigned int)md5len, md5sum);
1596 #elif defined(USE_GNUTLS)
1598 gcry_md_open(&MD5pw, GCRY_MD_MD5, 0);
1599 gcry_md_write(MD5pw, tmp, tmplen);
1600 memcpy(md5sum, gcry_md_read (MD5pw, 0), md5len);
1601 gcry_md_close(MD5pw);
1605 void Curl_gtls_sha256sum(const unsigned char *tmp, /* input */
1607 unsigned char *sha256sum, /* output */
1610 #if defined(USE_GNUTLS_NETTLE)
1611 struct sha256_ctx SHA256pw;
1612 sha256_init(&SHA256pw);
1613 sha256_update(&SHA256pw, (unsigned int)tmplen, tmp);
1614 sha256_digest(&SHA256pw, (unsigned int)sha256len, sha256sum);
1615 #elif defined(USE_GNUTLS)
1616 gcry_md_hd_t SHA256pw;
1617 gcry_md_open(&SHA256pw, GCRY_MD_SHA256, 0);
1618 gcry_md_write(SHA256pw, tmp, tmplen);
1619 memcpy(sha256sum, gcry_md_read (SHA256pw, 0), sha256len);
1620 gcry_md_close(SHA256pw);
1624 bool Curl_gtls_cert_status_request(void)
1633 #endif /* USE_GNUTLS */