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