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