• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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   CURLcode result;
408 
409   if(connssl->state == ssl_connection_complete)
410     /* to make us tolerant against being called more than once for the
411        same connection */
412     return CURLE_OK;
413 
414   if(!gtls_inited)
415     gtls_init();
416 
417   /* Initialize certverifyresult to OK */
418   *certverifyresult = 0;
419 
420   if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) {
421     failf(data, "GnuTLS does not support SSLv2");
422     return CURLE_SSL_CONNECT_ERROR;
423   }
424   else if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv3)
425     sni = FALSE; /* SSLv3 has no SNI */
426 
427   /* allocate a cred struct */
428   rc = gnutls_certificate_allocate_credentials(&backend->cred);
429   if(rc != GNUTLS_E_SUCCESS) {
430     failf(data, "gnutls_cert_all_cred() failed: %s", gnutls_strerror(rc));
431     return CURLE_SSL_CONNECT_ERROR;
432   }
433 
434 #ifdef HAVE_GNUTLS_SRP
435   if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP) {
436     infof(data, "Using TLS-SRP username: %s", SSL_SET_OPTION(username));
437 
438     rc = gnutls_srp_allocate_client_credentials(
439            &backend->srp_client_cred);
440     if(rc != GNUTLS_E_SUCCESS) {
441       failf(data, "gnutls_srp_allocate_client_cred() failed: %s",
442             gnutls_strerror(rc));
443       return CURLE_OUT_OF_MEMORY;
444     }
445 
446     rc = gnutls_srp_set_client_credentials(backend->srp_client_cred,
447                                            SSL_SET_OPTION(username),
448                                            SSL_SET_OPTION(password));
449     if(rc != GNUTLS_E_SUCCESS) {
450       failf(data, "gnutls_srp_set_client_cred() failed: %s",
451             gnutls_strerror(rc));
452       return CURLE_BAD_FUNCTION_ARGUMENT;
453     }
454   }
455 #endif
456 
457   if(SSL_CONN_CONFIG(CAfile)) {
458     /* set the trusted CA cert bundle file */
459     gnutls_certificate_set_verify_flags(backend->cred,
460                                         GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
461 
462     rc = gnutls_certificate_set_x509_trust_file(backend->cred,
463                                                 SSL_CONN_CONFIG(CAfile),
464                                                 GNUTLS_X509_FMT_PEM);
465     if(rc < 0) {
466       infof(data, "error reading ca cert file %s (%s)",
467             SSL_CONN_CONFIG(CAfile), gnutls_strerror(rc));
468       if(SSL_CONN_CONFIG(verifypeer)) {
469         *certverifyresult = rc;
470         return CURLE_SSL_CACERT_BADFILE;
471       }
472     }
473     else
474       infof(data, "found %d certificates in %s", rc,
475             SSL_CONN_CONFIG(CAfile));
476   }
477 
478   if(SSL_CONN_CONFIG(CApath)) {
479     /* set the trusted CA cert directory */
480     rc = gnutls_certificate_set_x509_trust_dir(backend->cred,
481                                                SSL_CONN_CONFIG(CApath),
482                                                GNUTLS_X509_FMT_PEM);
483     if(rc < 0) {
484       infof(data, "error reading ca cert file %s (%s)",
485             SSL_CONN_CONFIG(CApath), gnutls_strerror(rc));
486       if(SSL_CONN_CONFIG(verifypeer)) {
487         *certverifyresult = rc;
488         return CURLE_SSL_CACERT_BADFILE;
489       }
490     }
491     else
492       infof(data, "found %d certificates in %s",
493             rc, SSL_CONN_CONFIG(CApath));
494   }
495 
496 #ifdef CURL_CA_FALLBACK
497   /* use system ca certificate store as fallback */
498   if(SSL_CONN_CONFIG(verifypeer) &&
499      !(SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(CApath))) {
500     gnutls_certificate_set_x509_system_trust(backend->cred);
501   }
502 #endif
503 
504   if(SSL_SET_OPTION(CRLfile)) {
505     /* set the CRL list file */
506     rc = gnutls_certificate_set_x509_crl_file(backend->cred,
507                                               SSL_SET_OPTION(CRLfile),
508                                               GNUTLS_X509_FMT_PEM);
509     if(rc < 0) {
510       failf(data, "error reading crl file %s (%s)",
511             SSL_SET_OPTION(CRLfile), gnutls_strerror(rc));
512       return CURLE_SSL_CRL_BADFILE;
513     }
514     else
515       infof(data, "found %d CRL in %s",
516             rc, SSL_SET_OPTION(CRLfile));
517   }
518 
519   /* Initialize TLS session as a client */
520   init_flags = GNUTLS_CLIENT;
521 
522 #if defined(GNUTLS_FORCE_CLIENT_CERT)
523   init_flags |= GNUTLS_FORCE_CLIENT_CERT;
524 #endif
525 
526 #if defined(GNUTLS_NO_TICKETS)
527   /* Disable TLS session tickets */
528   init_flags |= GNUTLS_NO_TICKETS;
529 #endif
530 
531   rc = gnutls_init(&backend->session, init_flags);
532   if(rc != GNUTLS_E_SUCCESS) {
533     failf(data, "gnutls_init() failed: %d", rc);
534     return CURLE_SSL_CONNECT_ERROR;
535   }
536 
537   /* convenient assign */
538   session = backend->session;
539 
540   if((0 == Curl_inet_pton(AF_INET, hostname, &addr)) &&
541 #ifdef ENABLE_IPV6
542      (0 == Curl_inet_pton(AF_INET6, hostname, &addr)) &&
543 #endif
544      sni &&
545      (gnutls_server_name_set(session, GNUTLS_NAME_DNS, hostname,
546                              strlen(hostname)) < 0))
547     infof(data, "WARNING: failed to configure server name indication (SNI) "
548           "TLS extension");
549 
550   /* Use default priorities */
551   rc = gnutls_set_default_priority(session);
552   if(rc != GNUTLS_E_SUCCESS)
553     return CURLE_SSL_CONNECT_ERROR;
554 
555   /* "In GnuTLS 3.6.5, TLS 1.3 is enabled by default" */
556   tls13support = gnutls_check_version("3.6.5");
557 
558   /* Ensure +SRP comes at the *end* of all relevant strings so that it can be
559    * removed if a run-time error indicates that SRP is not supported by this
560    * GnuTLS version */
561 
562   if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2 ||
563      SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv3) {
564     failf(data, "GnuTLS does not support SSLv2 or SSLv3");
565     return CURLE_SSL_CONNECT_ERROR;
566   }
567 
568   if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_TLSv1_3) {
569     if(!tls13support) {
570       failf(data, "This GnuTLS installation does not support TLS 1.3");
571       return CURLE_SSL_CONNECT_ERROR;
572     }
573   }
574 
575   /* At this point we know we have a supported TLS version, so set it */
576   result = set_ssl_version_min_max(data, &prioritylist, tls13support);
577   if(result)
578     return result;
579 
580 #ifdef HAVE_GNUTLS_SRP
581   /* Only add SRP to the cipher list if SRP is requested. Otherwise
582    * GnuTLS will disable TLS 1.3 support. */
583   if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP) {
584     size_t len = strlen(prioritylist);
585 
586     char *prioritysrp = malloc(len + sizeof(GNUTLS_SRP) + 1);
587     if(!prioritysrp)
588       return CURLE_OUT_OF_MEMORY;
589     strcpy(prioritysrp, prioritylist);
590     strcpy(prioritysrp + len, ":" GNUTLS_SRP);
591     rc = gnutls_priority_set_direct(session, prioritysrp, &err);
592     free(prioritysrp);
593 
594     if((rc == GNUTLS_E_INVALID_REQUEST) && err) {
595       infof(data, "This GnuTLS does not support SRP");
596     }
597   }
598   else {
599 #endif
600     infof(data, "GnuTLS ciphers: %s", prioritylist);
601     rc = gnutls_priority_set_direct(session, prioritylist, &err);
602 #ifdef HAVE_GNUTLS_SRP
603   }
604 #endif
605 
606   if(rc != GNUTLS_E_SUCCESS) {
607     failf(data, "Error %d setting GnuTLS cipher list starting with %s",
608           rc, err);
609     return CURLE_SSL_CONNECT_ERROR;
610   }
611 
612   if(conn->bits.tls_enable_alpn) {
613     int cur = 0;
614     gnutls_datum_t protocols[2];
615 
616 #ifdef USE_HTTP2
617     if(data->state.httpwant >= CURL_HTTP_VERSION_2
618 #ifndef CURL_DISABLE_PROXY
619        && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)
620 #endif
621        ) {
622       protocols[cur].data = (unsigned char *)ALPN_H2;
623       protocols[cur].size = ALPN_H2_LENGTH;
624       cur++;
625       infof(data, "ALPN, offering %.*s", ALPN_H2_LENGTH, ALPN_H2);
626     }
627 #endif
628 
629     protocols[cur].data = (unsigned char *)ALPN_HTTP_1_1;
630     protocols[cur].size = ALPN_HTTP_1_1_LENGTH;
631     cur++;
632     infof(data, "ALPN, offering %s", ALPN_HTTP_1_1);
633 
634     gnutls_alpn_set_protocols(session, protocols, cur, 0);
635   }
636 
637   if(SSL_SET_OPTION(primary.clientcert)) {
638     if(SSL_SET_OPTION(key_passwd)) {
639       const unsigned int supported_key_encryption_algorithms =
640         GNUTLS_PKCS_USE_PKCS12_3DES | GNUTLS_PKCS_USE_PKCS12_ARCFOUR |
641         GNUTLS_PKCS_USE_PKCS12_RC2_40 | GNUTLS_PKCS_USE_PBES2_3DES |
642         GNUTLS_PKCS_USE_PBES2_AES_128 | GNUTLS_PKCS_USE_PBES2_AES_192 |
643         GNUTLS_PKCS_USE_PBES2_AES_256;
644       rc = gnutls_certificate_set_x509_key_file2(
645            backend->cred,
646            SSL_SET_OPTION(primary.clientcert),
647            SSL_SET_OPTION(key) ?
648            SSL_SET_OPTION(key) : SSL_SET_OPTION(primary.clientcert),
649            do_file_type(SSL_SET_OPTION(cert_type)),
650            SSL_SET_OPTION(key_passwd),
651            supported_key_encryption_algorithms);
652       if(rc != GNUTLS_E_SUCCESS) {
653         failf(data,
654               "error reading X.509 potentially-encrypted key file: %s",
655               gnutls_strerror(rc));
656         return CURLE_SSL_CONNECT_ERROR;
657       }
658     }
659     else {
660       if(gnutls_certificate_set_x509_key_file(
661            backend->cred,
662            SSL_SET_OPTION(primary.clientcert),
663            SSL_SET_OPTION(key) ?
664            SSL_SET_OPTION(key) : SSL_SET_OPTION(primary.clientcert),
665            do_file_type(SSL_SET_OPTION(cert_type)) ) !=
666          GNUTLS_E_SUCCESS) {
667         failf(data, "error reading X.509 key or certificate file");
668         return CURLE_SSL_CONNECT_ERROR;
669       }
670     }
671   }
672 
673 #ifdef HAVE_GNUTLS_SRP
674   /* put the credentials to the current session */
675   if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP) {
676     rc = gnutls_credentials_set(session, GNUTLS_CRD_SRP,
677                                 backend->srp_client_cred);
678     if(rc != GNUTLS_E_SUCCESS) {
679       failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc));
680       return CURLE_SSL_CONNECT_ERROR;
681     }
682   }
683   else
684 #endif
685   {
686     rc = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
687                                 backend->cred);
688     if(rc != GNUTLS_E_SUCCESS) {
689       failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc));
690       return CURLE_SSL_CONNECT_ERROR;
691     }
692   }
693 
694 #ifndef CURL_DISABLE_PROXY
695   if(conn->proxy_ssl[sockindex].use) {
696     transport_ptr = conn->proxy_ssl[sockindex].backend->session;
697     gnutls_transport_push = gtls_push_ssl;
698     gnutls_transport_pull = gtls_pull_ssl;
699   }
700   else
701 #endif
702   {
703     /* file descriptor for the socket */
704     transport_ptr = &conn->sock[sockindex];
705     gnutls_transport_push = gtls_push;
706     gnutls_transport_pull = gtls_pull;
707   }
708 
709   /* set the connection handle */
710   gnutls_transport_set_ptr(session, transport_ptr);
711 
712   /* register callback functions to send and receive data. */
713   gnutls_transport_set_push_function(session, gnutls_transport_push);
714   gnutls_transport_set_pull_function(session, gnutls_transport_pull);
715 
716   if(SSL_CONN_CONFIG(verifystatus)) {
717     rc = gnutls_ocsp_status_request_enable_client(session, NULL, 0, NULL);
718     if(rc != GNUTLS_E_SUCCESS) {
719       failf(data, "gnutls_ocsp_status_request_enable_client() failed: %d", rc);
720       return CURLE_SSL_CONNECT_ERROR;
721     }
722   }
723 
724   /* This might be a reconnect, so we check for a session ID in the cache
725      to speed up things */
726   if(SSL_SET_OPTION(primary.sessionid)) {
727     void *ssl_sessionid;
728     size_t ssl_idsize;
729 
730     Curl_ssl_sessionid_lock(data);
731     if(!Curl_ssl_getsessionid(data, conn,
732                               SSL_IS_PROXY() ? TRUE : FALSE,
733                               &ssl_sessionid, &ssl_idsize, sockindex)) {
734       /* we got a session id, use it! */
735       gnutls_session_set_data(session, ssl_sessionid, ssl_idsize);
736 
737       /* Informational message */
738       infof(data, "SSL re-using session ID");
739     }
740     Curl_ssl_sessionid_unlock(data);
741   }
742 
743   return CURLE_OK;
744 }
745 
pkp_pin_peer_pubkey(struct Curl_easy * data,gnutls_x509_crt_t cert,const char * pinnedpubkey)746 static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
747                                     gnutls_x509_crt_t cert,
748                                     const char *pinnedpubkey)
749 {
750   /* Scratch */
751   size_t len1 = 0, len2 = 0;
752   unsigned char *buff1 = NULL;
753 
754   gnutls_pubkey_t key = NULL;
755 
756   /* Result is returned to caller */
757   CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
758 
759   /* if a path wasn't specified, don't pin */
760   if(NULL == pinnedpubkey)
761     return CURLE_OK;
762 
763   if(NULL == cert)
764     return result;
765 
766   do {
767     int ret;
768 
769     /* Begin Gyrations to get the public key     */
770     gnutls_pubkey_init(&key);
771 
772     ret = gnutls_pubkey_import_x509(key, cert, 0);
773     if(ret < 0)
774       break; /* failed */
775 
776     ret = gnutls_pubkey_export(key, GNUTLS_X509_FMT_DER, NULL, &len1);
777     if(ret != GNUTLS_E_SHORT_MEMORY_BUFFER || len1 == 0)
778       break; /* failed */
779 
780     buff1 = malloc(len1);
781     if(NULL == buff1)
782       break; /* failed */
783 
784     len2 = len1;
785 
786     ret = gnutls_pubkey_export(key, GNUTLS_X509_FMT_DER, buff1, &len2);
787     if(ret < 0 || len1 != len2)
788       break; /* failed */
789 
790     /* End Gyrations */
791 
792     /* The one good exit point */
793     result = Curl_pin_peer_pubkey(data, pinnedpubkey, buff1, len1);
794   } while(0);
795 
796   if(NULL != key)
797     gnutls_pubkey_deinit(key);
798 
799   Curl_safefree(buff1);
800 
801   return result;
802 }
803 
804 static Curl_recv gtls_recv;
805 static Curl_send gtls_send;
806 
807 static CURLcode
gtls_connect_step3(struct Curl_easy * data,struct connectdata * conn,int sockindex)808 gtls_connect_step3(struct Curl_easy *data,
809                    struct connectdata *conn,
810                    int sockindex)
811 {
812   unsigned int cert_list_size;
813   const gnutls_datum_t *chainp;
814   unsigned int verify_status = 0;
815   gnutls_x509_crt_t x509_cert, x509_issuer;
816   gnutls_datum_t issuerp;
817   gnutls_datum_t certfields;
818   char certname[65] = ""; /* limited to 64 chars by ASN.1 */
819   size_t size;
820   time_t certclock;
821   const char *ptr;
822   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
823   struct ssl_backend_data *backend = connssl->backend;
824   gnutls_session_t session = backend->session;
825   int rc;
826   gnutls_datum_t proto;
827   CURLcode result = CURLE_OK;
828 #ifndef CURL_DISABLE_VERBOSE_STRINGS
829   unsigned int algo;
830   unsigned int bits;
831   gnutls_protocol_t version = gnutls_protocol_get_version(session);
832 #endif
833   const char * const hostname = SSL_HOST_NAME();
834   long * const certverifyresult = &SSL_SET_OPTION_LVALUE(certverifyresult);
835 
836   /* the name of the cipher suite used, e.g. ECDHE_RSA_AES_256_GCM_SHA384. */
837   ptr = gnutls_cipher_suite_get_name(gnutls_kx_get(session),
838                                      gnutls_cipher_get(session),
839                                      gnutls_mac_get(session));
840 
841   infof(data, "SSL connection using %s / %s",
842         gnutls_protocol_get_name(version), ptr);
843 
844   /* This function will return the peer's raw certificate (chain) as sent by
845      the peer. These certificates are in raw format (DER encoded for
846      X.509). In case of a X.509 then a certificate list may be present. The
847      first certificate in the list is the peer's certificate, following the
848      issuer's certificate, then the issuer's issuer etc. */
849 
850   chainp = gnutls_certificate_get_peers(session, &cert_list_size);
851   if(!chainp) {
852     if(SSL_CONN_CONFIG(verifypeer) ||
853        SSL_CONN_CONFIG(verifyhost) ||
854        SSL_CONN_CONFIG(issuercert)) {
855 #ifdef HAVE_GNUTLS_SRP
856       if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP
857          && SSL_SET_OPTION(username) != NULL
858          && !SSL_CONN_CONFIG(verifypeer)
859          && gnutls_cipher_get(session)) {
860         /* no peer cert, but auth is ok if we have SRP user and cipher and no
861            peer verify */
862       }
863       else {
864 #endif
865         failf(data, "failed to get server cert");
866         *certverifyresult = GNUTLS_E_NO_CERTIFICATE_FOUND;
867         return CURLE_PEER_FAILED_VERIFICATION;
868 #ifdef HAVE_GNUTLS_SRP
869       }
870 #endif
871     }
872     infof(data, " common name: WARNING couldn't obtain");
873   }
874 
875   if(data->set.ssl.certinfo && chainp) {
876     unsigned int i;
877 
878     result = Curl_ssl_init_certinfo(data, cert_list_size);
879     if(result)
880       return result;
881 
882     for(i = 0; i < cert_list_size; i++) {
883       const char *beg = (const char *) chainp[i].data;
884       const char *end = beg + chainp[i].size;
885 
886       result = Curl_extract_certinfo(data, i, beg, end);
887       if(result)
888         return result;
889     }
890   }
891 
892   if(SSL_CONN_CONFIG(verifypeer)) {
893     /* This function will try to verify the peer's certificate and return its
894        status (trusted, invalid etc.). The value of status should be one or
895        more of the gnutls_certificate_status_t enumerated elements bitwise
896        or'd. To avoid denial of service attacks some default upper limits
897        regarding the certificate key size and chain size are set. To override
898        them use gnutls_certificate_set_verify_limits(). */
899 
900     rc = gnutls_certificate_verify_peers2(session, &verify_status);
901     if(rc < 0) {
902       failf(data, "server cert verify failed: %d", rc);
903       *certverifyresult = rc;
904       return CURLE_SSL_CONNECT_ERROR;
905     }
906 
907     *certverifyresult = verify_status;
908 
909     /* verify_status is a bitmask of gnutls_certificate_status bits */
910     if(verify_status & GNUTLS_CERT_INVALID) {
911       if(SSL_CONN_CONFIG(verifypeer)) {
912         failf(data, "server certificate verification failed. CAfile: %s "
913               "CRLfile: %s", SSL_CONN_CONFIG(CAfile) ? SSL_CONN_CONFIG(CAfile):
914               "none",
915               SSL_SET_OPTION(CRLfile)?SSL_SET_OPTION(CRLfile):"none");
916         return CURLE_PEER_FAILED_VERIFICATION;
917       }
918       else
919         infof(data, "  server certificate verification FAILED");
920     }
921     else
922       infof(data, "  server certificate verification OK");
923   }
924   else
925     infof(data, "  server certificate verification SKIPPED");
926 
927   if(SSL_CONN_CONFIG(verifystatus)) {
928     if(gnutls_ocsp_status_request_is_checked(session, 0) == 0) {
929       gnutls_datum_t status_request;
930       gnutls_ocsp_resp_t ocsp_resp;
931 
932       gnutls_ocsp_cert_status_t status;
933       gnutls_x509_crl_reason_t reason;
934 
935       rc = gnutls_ocsp_status_request_get(session, &status_request);
936 
937       infof(data, " server certificate status verification FAILED");
938 
939       if(rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
940         failf(data, "No OCSP response received");
941         return CURLE_SSL_INVALIDCERTSTATUS;
942       }
943 
944       if(rc < 0) {
945         failf(data, "Invalid OCSP response received");
946         return CURLE_SSL_INVALIDCERTSTATUS;
947       }
948 
949       gnutls_ocsp_resp_init(&ocsp_resp);
950 
951       rc = gnutls_ocsp_resp_import(ocsp_resp, &status_request);
952       if(rc < 0) {
953         failf(data, "Invalid OCSP response received");
954         return CURLE_SSL_INVALIDCERTSTATUS;
955       }
956 
957       (void)gnutls_ocsp_resp_get_single(ocsp_resp, 0, NULL, NULL, NULL, NULL,
958                                         &status, NULL, NULL, NULL, &reason);
959 
960       switch(status) {
961       case GNUTLS_OCSP_CERT_GOOD:
962         break;
963 
964       case GNUTLS_OCSP_CERT_REVOKED: {
965         const char *crl_reason;
966 
967         switch(reason) {
968           default:
969           case GNUTLS_X509_CRLREASON_UNSPECIFIED:
970             crl_reason = "unspecified reason";
971             break;
972 
973           case GNUTLS_X509_CRLREASON_KEYCOMPROMISE:
974             crl_reason = "private key compromised";
975             break;
976 
977           case GNUTLS_X509_CRLREASON_CACOMPROMISE:
978             crl_reason = "CA compromised";
979             break;
980 
981           case GNUTLS_X509_CRLREASON_AFFILIATIONCHANGED:
982             crl_reason = "affiliation has changed";
983             break;
984 
985           case GNUTLS_X509_CRLREASON_SUPERSEDED:
986             crl_reason = "certificate superseded";
987             break;
988 
989           case GNUTLS_X509_CRLREASON_CESSATIONOFOPERATION:
990             crl_reason = "operation has ceased";
991             break;
992 
993           case GNUTLS_X509_CRLREASON_CERTIFICATEHOLD:
994             crl_reason = "certificate is on hold";
995             break;
996 
997           case GNUTLS_X509_CRLREASON_REMOVEFROMCRL:
998             crl_reason = "will be removed from delta CRL";
999             break;
1000 
1001           case GNUTLS_X509_CRLREASON_PRIVILEGEWITHDRAWN:
1002             crl_reason = "privilege withdrawn";
1003             break;
1004 
1005           case GNUTLS_X509_CRLREASON_AACOMPROMISE:
1006             crl_reason = "AA compromised";
1007             break;
1008         }
1009 
1010         failf(data, "Server certificate was revoked: %s", crl_reason);
1011         break;
1012       }
1013 
1014       default:
1015       case GNUTLS_OCSP_CERT_UNKNOWN:
1016         failf(data, "Server certificate status is unknown");
1017         break;
1018       }
1019 
1020       gnutls_ocsp_resp_deinit(ocsp_resp);
1021 
1022       return CURLE_SSL_INVALIDCERTSTATUS;
1023     }
1024     else
1025       infof(data, "  server certificate status verification OK");
1026   }
1027   else
1028     infof(data, "  server certificate status verification SKIPPED");
1029 
1030   /* initialize an X.509 certificate structure. */
1031   gnutls_x509_crt_init(&x509_cert);
1032 
1033   if(chainp)
1034     /* convert the given DER or PEM encoded Certificate to the native
1035        gnutls_x509_crt_t format */
1036     gnutls_x509_crt_import(x509_cert, chainp, GNUTLS_X509_FMT_DER);
1037 
1038   if(SSL_CONN_CONFIG(issuercert)) {
1039     gnutls_x509_crt_init(&x509_issuer);
1040     issuerp = load_file(SSL_CONN_CONFIG(issuercert));
1041     gnutls_x509_crt_import(x509_issuer, &issuerp, GNUTLS_X509_FMT_PEM);
1042     rc = gnutls_x509_crt_check_issuer(x509_cert, x509_issuer);
1043     gnutls_x509_crt_deinit(x509_issuer);
1044     unload_file(issuerp);
1045     if(rc <= 0) {
1046       failf(data, "server certificate issuer check failed (IssuerCert: %s)",
1047             SSL_CONN_CONFIG(issuercert)?SSL_CONN_CONFIG(issuercert):"none");
1048       gnutls_x509_crt_deinit(x509_cert);
1049       return CURLE_SSL_ISSUER_ERROR;
1050     }
1051     infof(data, "  server certificate issuer check OK (Issuer Cert: %s)",
1052           SSL_CONN_CONFIG(issuercert)?SSL_CONN_CONFIG(issuercert):"none");
1053   }
1054 
1055   size = sizeof(certname);
1056   rc = gnutls_x509_crt_get_dn_by_oid(x509_cert, GNUTLS_OID_X520_COMMON_NAME,
1057                                      0, /* the first and only one */
1058                                      FALSE,
1059                                      certname,
1060                                      &size);
1061   if(rc) {
1062     infof(data, "error fetching CN from cert:%s",
1063           gnutls_strerror(rc));
1064   }
1065 
1066   /* This function will check if the given certificate's subject matches the
1067      given hostname. This is a basic implementation of the matching described
1068      in RFC2818 (HTTPS), which takes into account wildcards, and the subject
1069      alternative name PKIX extension. Returns non zero on success, and zero on
1070      failure. */
1071   rc = gnutls_x509_crt_check_hostname(x509_cert, hostname);
1072 #if GNUTLS_VERSION_NUMBER < 0x030306
1073   /* Before 3.3.6, gnutls_x509_crt_check_hostname() didn't check IP
1074      addresses. */
1075   if(!rc) {
1076 #ifdef ENABLE_IPV6
1077     #define use_addr in6_addr
1078 #else
1079     #define use_addr in_addr
1080 #endif
1081     unsigned char addrbuf[sizeof(struct use_addr)];
1082     size_t addrlen = 0;
1083 
1084     if(Curl_inet_pton(AF_INET, hostname, addrbuf) > 0)
1085       addrlen = 4;
1086 #ifdef ENABLE_IPV6
1087     else if(Curl_inet_pton(AF_INET6, hostname, addrbuf) > 0)
1088       addrlen = 16;
1089 #endif
1090 
1091     if(addrlen) {
1092       unsigned char certaddr[sizeof(struct use_addr)];
1093       int i;
1094 
1095       for(i = 0; ; i++) {
1096         size_t certaddrlen = sizeof(certaddr);
1097         int ret = gnutls_x509_crt_get_subject_alt_name(x509_cert, i, certaddr,
1098                                                        &certaddrlen, NULL);
1099         /* If this happens, it wasn't an IP address. */
1100         if(ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
1101           continue;
1102         if(ret < 0)
1103           break;
1104         if(ret != GNUTLS_SAN_IPADDRESS)
1105           continue;
1106         if(certaddrlen == addrlen && !memcmp(addrbuf, certaddr, addrlen)) {
1107           rc = 1;
1108           break;
1109         }
1110       }
1111     }
1112   }
1113 #endif
1114   if(!rc) {
1115     if(SSL_CONN_CONFIG(verifyhost)) {
1116       failf(data, "SSL: certificate subject name (%s) does not match "
1117             "target host name '%s'", certname, SSL_HOST_DISPNAME());
1118       gnutls_x509_crt_deinit(x509_cert);
1119       return CURLE_PEER_FAILED_VERIFICATION;
1120     }
1121     else
1122       infof(data, "  common name: %s (does not match '%s')",
1123             certname, SSL_HOST_DISPNAME());
1124   }
1125   else
1126     infof(data, "  common name: %s (matched)", certname);
1127 
1128   /* Check for time-based validity */
1129   certclock = gnutls_x509_crt_get_expiration_time(x509_cert);
1130 
1131   if(certclock == (time_t)-1) {
1132     if(SSL_CONN_CONFIG(verifypeer)) {
1133       failf(data, "server cert expiration date verify failed");
1134       *certverifyresult = GNUTLS_CERT_EXPIRED;
1135       gnutls_x509_crt_deinit(x509_cert);
1136       return CURLE_SSL_CONNECT_ERROR;
1137     }
1138     else
1139       infof(data, "  server certificate expiration date verify FAILED");
1140   }
1141   else {
1142     if(certclock < time(NULL)) {
1143       if(SSL_CONN_CONFIG(verifypeer)) {
1144         failf(data, "server certificate expiration date has passed.");
1145         *certverifyresult = GNUTLS_CERT_EXPIRED;
1146         gnutls_x509_crt_deinit(x509_cert);
1147         return CURLE_PEER_FAILED_VERIFICATION;
1148       }
1149       else
1150         infof(data, "  server certificate expiration date FAILED");
1151     }
1152     else
1153       infof(data, "  server certificate expiration date OK");
1154   }
1155 
1156   certclock = gnutls_x509_crt_get_activation_time(x509_cert);
1157 
1158   if(certclock == (time_t)-1) {
1159     if(SSL_CONN_CONFIG(verifypeer)) {
1160       failf(data, "server cert activation date verify failed");
1161       *certverifyresult = GNUTLS_CERT_NOT_ACTIVATED;
1162       gnutls_x509_crt_deinit(x509_cert);
1163       return CURLE_SSL_CONNECT_ERROR;
1164     }
1165     else
1166       infof(data, "  server certificate activation date verify FAILED");
1167   }
1168   else {
1169     if(certclock > time(NULL)) {
1170       if(SSL_CONN_CONFIG(verifypeer)) {
1171         failf(data, "server certificate not activated yet.");
1172         *certverifyresult = GNUTLS_CERT_NOT_ACTIVATED;
1173         gnutls_x509_crt_deinit(x509_cert);
1174         return CURLE_PEER_FAILED_VERIFICATION;
1175       }
1176       else
1177         infof(data, "  server certificate activation date FAILED");
1178     }
1179     else
1180       infof(data, "  server certificate activation date OK");
1181   }
1182 
1183   ptr = SSL_PINNED_PUB_KEY();
1184   if(ptr) {
1185     result = pkp_pin_peer_pubkey(data, x509_cert, ptr);
1186     if(result != CURLE_OK) {
1187       failf(data, "SSL: public key does not match pinned public key!");
1188       gnutls_x509_crt_deinit(x509_cert);
1189       return result;
1190     }
1191   }
1192 
1193   /* Show:
1194 
1195   - subject
1196   - start date
1197   - expire date
1198   - common name
1199   - issuer
1200 
1201   */
1202 
1203 #ifndef CURL_DISABLE_VERBOSE_STRINGS
1204   /* public key algorithm's parameters */
1205   algo = gnutls_x509_crt_get_pk_algorithm(x509_cert, &bits);
1206   infof(data, "  certificate public key: %s",
1207         gnutls_pk_algorithm_get_name(algo));
1208 
1209   /* version of the X.509 certificate. */
1210   infof(data, "  certificate version: #%d",
1211         gnutls_x509_crt_get_version(x509_cert));
1212 
1213 
1214   rc = gnutls_x509_crt_get_dn2(x509_cert, &certfields);
1215   if(rc)
1216     infof(data, "Failed to get certificate name");
1217   else {
1218     infof(data, "  subject: %s", certfields.data);
1219 
1220     certclock = gnutls_x509_crt_get_activation_time(x509_cert);
1221     showtime(data, "start date", certclock);
1222 
1223     certclock = gnutls_x509_crt_get_expiration_time(x509_cert);
1224     showtime(data, "expire date", certclock);
1225 
1226     gnutls_free(certfields.data);
1227   }
1228 
1229   rc = gnutls_x509_crt_get_issuer_dn2(x509_cert, &certfields);
1230   if(rc)
1231     infof(data, "Failed to get certificate issuer");
1232   else {
1233     infof(data, "  issuer: %s", certfields.data);
1234 
1235     gnutls_free(certfields.data);
1236   }
1237 #endif
1238 
1239   gnutls_x509_crt_deinit(x509_cert);
1240 
1241   if(conn->bits.tls_enable_alpn) {
1242     rc = gnutls_alpn_get_selected_protocol(session, &proto);
1243     if(rc == 0) {
1244       infof(data, "ALPN, server accepted to use %.*s", proto.size,
1245           proto.data);
1246 
1247 #ifdef USE_HTTP2
1248       if(proto.size == ALPN_H2_LENGTH &&
1249          !memcmp(ALPN_H2, proto.data,
1250                  ALPN_H2_LENGTH)) {
1251         conn->negnpn = CURL_HTTP_VERSION_2;
1252       }
1253       else
1254 #endif
1255       if(proto.size == ALPN_HTTP_1_1_LENGTH &&
1256          !memcmp(ALPN_HTTP_1_1, proto.data, ALPN_HTTP_1_1_LENGTH)) {
1257         conn->negnpn = CURL_HTTP_VERSION_1_1;
1258       }
1259     }
1260     else
1261       infof(data, "ALPN, server did not agree to a protocol");
1262 
1263     Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ?
1264                         BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
1265   }
1266 
1267   conn->ssl[sockindex].state = ssl_connection_complete;
1268   conn->recv[sockindex] = gtls_recv;
1269   conn->send[sockindex] = gtls_send;
1270 
1271   if(SSL_SET_OPTION(primary.sessionid)) {
1272     /* we always unconditionally get the session id here, as even if we
1273        already got it from the cache and asked to use it in the connection, it
1274        might've been rejected and then a new one is in use now and we need to
1275        detect that. */
1276     void *connect_sessionid;
1277     size_t connect_idsize = 0;
1278 
1279     /* get the session ID data size */
1280     gnutls_session_get_data(session, NULL, &connect_idsize);
1281     connect_sessionid = malloc(connect_idsize); /* get a buffer for it */
1282 
1283     if(connect_sessionid) {
1284       bool incache;
1285       bool added = FALSE;
1286       void *ssl_sessionid;
1287 
1288       /* extract session ID to the allocated buffer */
1289       gnutls_session_get_data(session, connect_sessionid, &connect_idsize);
1290 
1291       Curl_ssl_sessionid_lock(data);
1292       incache = !(Curl_ssl_getsessionid(data, conn,
1293                                         SSL_IS_PROXY() ? TRUE : FALSE,
1294                                         &ssl_sessionid, NULL, sockindex));
1295       if(incache) {
1296         /* there was one before in the cache, so instead of risking that the
1297            previous one was rejected, we just kill that and store the new */
1298         Curl_ssl_delsessionid(data, ssl_sessionid);
1299       }
1300 
1301       /* store this session id */
1302       result = Curl_ssl_addsessionid(data, conn,
1303                                      SSL_IS_PROXY() ? TRUE : FALSE,
1304                                      connect_sessionid, connect_idsize,
1305                                      sockindex, &added);
1306       Curl_ssl_sessionid_unlock(data);
1307       if(!added)
1308         free(connect_sessionid);
1309       if(result) {
1310         result = CURLE_OUT_OF_MEMORY;
1311       }
1312     }
1313     else
1314       result = CURLE_OUT_OF_MEMORY;
1315   }
1316 
1317   return result;
1318 }
1319 
1320 
1321 /*
1322  * This function is called after the TCP connect has completed. Setup the TLS
1323  * layer and do all necessary magic.
1324  */
1325 /* We use connssl->connecting_state to keep track of the connection status;
1326    there are three states: 'ssl_connect_1' (not started yet or complete),
1327    'ssl_connect_2_reading' (waiting for data from server), and
1328    'ssl_connect_2_writing' (waiting to be able to write).
1329  */
1330 static CURLcode
gtls_connect_common(struct Curl_easy * data,struct connectdata * conn,int sockindex,bool nonblocking,bool * done)1331 gtls_connect_common(struct Curl_easy *data,
1332                     struct connectdata *conn,
1333                     int sockindex,
1334                     bool nonblocking,
1335                     bool *done)
1336 {
1337   int rc;
1338   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1339 
1340   /* Initiate the connection, if not already done */
1341   if(ssl_connect_1 == connssl->connecting_state) {
1342     rc = gtls_connect_step1(data, conn, sockindex);
1343     if(rc)
1344       return rc;
1345   }
1346 
1347   rc = handshake(data, conn, sockindex, TRUE, nonblocking);
1348   if(rc)
1349     /* handshake() sets its own error message with failf() */
1350     return rc;
1351 
1352   /* Finish connecting once the handshake is done */
1353   if(ssl_connect_1 == connssl->connecting_state) {
1354     rc = gtls_connect_step3(data, conn, sockindex);
1355     if(rc)
1356       return rc;
1357   }
1358 
1359   *done = ssl_connect_1 == connssl->connecting_state;
1360 
1361   return CURLE_OK;
1362 }
1363 
gtls_connect_nonblocking(struct Curl_easy * data,struct connectdata * conn,int sockindex,bool * done)1364 static CURLcode gtls_connect_nonblocking(struct Curl_easy *data,
1365                                          struct connectdata *conn,
1366                                          int sockindex, bool *done)
1367 {
1368   return gtls_connect_common(data, conn, sockindex, TRUE, done);
1369 }
1370 
gtls_connect(struct Curl_easy * data,struct connectdata * conn,int sockindex)1371 static CURLcode gtls_connect(struct Curl_easy *data, struct connectdata *conn,
1372                              int sockindex)
1373 {
1374   CURLcode result;
1375   bool done = FALSE;
1376 
1377   result = gtls_connect_common(data, conn, sockindex, FALSE, &done);
1378   if(result)
1379     return result;
1380 
1381   DEBUGASSERT(done);
1382 
1383   return CURLE_OK;
1384 }
1385 
gtls_data_pending(const struct connectdata * conn,int connindex)1386 static bool gtls_data_pending(const struct connectdata *conn,
1387                               int connindex)
1388 {
1389   const struct ssl_connect_data *connssl = &conn->ssl[connindex];
1390   bool res = FALSE;
1391   struct ssl_backend_data *backend = connssl->backend;
1392   if(backend->session &&
1393      0 != gnutls_record_check_pending(backend->session))
1394     res = TRUE;
1395 
1396 #ifndef CURL_DISABLE_PROXY
1397   connssl = &conn->proxy_ssl[connindex];
1398   backend = connssl->backend;
1399   if(backend->session &&
1400      0 != gnutls_record_check_pending(backend->session))
1401     res = TRUE;
1402 #endif
1403 
1404   return res;
1405 }
1406 
gtls_send(struct Curl_easy * data,int sockindex,const void * mem,size_t len,CURLcode * curlcode)1407 static ssize_t gtls_send(struct Curl_easy *data,
1408                          int sockindex,
1409                          const void *mem,
1410                          size_t len,
1411                          CURLcode *curlcode)
1412 {
1413   struct connectdata *conn = data->conn;
1414   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1415   struct ssl_backend_data *backend = connssl->backend;
1416   ssize_t rc = gnutls_record_send(backend->session, mem, len);
1417 
1418   if(rc < 0) {
1419     *curlcode = (rc == GNUTLS_E_AGAIN)
1420       ? CURLE_AGAIN
1421       : CURLE_SEND_ERROR;
1422 
1423     rc = -1;
1424   }
1425 
1426   return rc;
1427 }
1428 
close_one(struct ssl_connect_data * connssl)1429 static void close_one(struct ssl_connect_data *connssl)
1430 {
1431   struct ssl_backend_data *backend = connssl->backend;
1432   if(backend->session) {
1433     char buf[32];
1434     /* Maybe the server has already sent a close notify alert.
1435        Read it to avoid an RST on the TCP connection. */
1436     (void)gnutls_record_recv(backend->session, buf, sizeof(buf));
1437     gnutls_bye(backend->session, GNUTLS_SHUT_WR);
1438     gnutls_deinit(backend->session);
1439     backend->session = NULL;
1440   }
1441   if(backend->cred) {
1442     gnutls_certificate_free_credentials(backend->cred);
1443     backend->cred = NULL;
1444   }
1445 #ifdef HAVE_GNUTLS_SRP
1446   if(backend->srp_client_cred) {
1447     gnutls_srp_free_client_credentials(backend->srp_client_cred);
1448     backend->srp_client_cred = NULL;
1449   }
1450 #endif
1451 }
1452 
gtls_close(struct Curl_easy * data,struct connectdata * conn,int sockindex)1453 static void gtls_close(struct Curl_easy *data, struct connectdata *conn,
1454                        int sockindex)
1455 {
1456   (void) data;
1457   close_one(&conn->ssl[sockindex]);
1458 #ifndef CURL_DISABLE_PROXY
1459   close_one(&conn->proxy_ssl[sockindex]);
1460 #endif
1461 }
1462 
1463 /*
1464  * This function is called to shut down the SSL layer but keep the
1465  * socket open (CCC - Clear Command Channel)
1466  */
gtls_shutdown(struct Curl_easy * data,struct connectdata * conn,int sockindex)1467 static int gtls_shutdown(struct Curl_easy *data, struct connectdata *conn,
1468                          int sockindex)
1469 {
1470   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1471   struct ssl_backend_data *backend = connssl->backend;
1472   int retval = 0;
1473 
1474 #ifndef CURL_DISABLE_FTP
1475   /* This has only been tested on the proftpd server, and the mod_tls code
1476      sends a close notify alert without waiting for a close notify alert in
1477      response. Thus we wait for a close notify alert from the server, but
1478      we do not send one. Let's hope other servers do the same... */
1479 
1480   if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
1481     gnutls_bye(backend->session, GNUTLS_SHUT_WR);
1482 #endif
1483 
1484   if(backend->session) {
1485     ssize_t result;
1486     bool done = FALSE;
1487     char buf[120];
1488 
1489     while(!done) {
1490       int what = SOCKET_READABLE(conn->sock[sockindex],
1491                                  SSL_SHUTDOWN_TIMEOUT);
1492       if(what > 0) {
1493         /* Something to read, let's do it and hope that it is the close
1494            notify alert from the server */
1495         result = gnutls_record_recv(backend->session,
1496                                     buf, sizeof(buf));
1497         switch(result) {
1498         case 0:
1499           /* This is the expected response. There was no data but only
1500              the close notify alert */
1501           done = TRUE;
1502           break;
1503         case GNUTLS_E_AGAIN:
1504         case GNUTLS_E_INTERRUPTED:
1505           infof(data, "GNUTLS_E_AGAIN || GNUTLS_E_INTERRUPTED");
1506           break;
1507         default:
1508           retval = -1;
1509           done = TRUE;
1510           break;
1511         }
1512       }
1513       else if(0 == what) {
1514         /* timeout */
1515         failf(data, "SSL shutdown timeout");
1516         done = TRUE;
1517       }
1518       else {
1519         /* anything that gets here is fatally bad */
1520         failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
1521         retval = -1;
1522         done = TRUE;
1523       }
1524     }
1525     gnutls_deinit(backend->session);
1526   }
1527   gnutls_certificate_free_credentials(backend->cred);
1528 
1529 #ifdef HAVE_GNUTLS_SRP
1530   if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP
1531      && SSL_SET_OPTION(username) != NULL)
1532     gnutls_srp_free_client_credentials(backend->srp_client_cred);
1533 #endif
1534 
1535   backend->cred = NULL;
1536   backend->session = NULL;
1537 
1538   return retval;
1539 }
1540 
gtls_recv(struct Curl_easy * data,int num,char * buf,size_t buffersize,CURLcode * curlcode)1541 static ssize_t gtls_recv(struct Curl_easy *data, /* connection data */
1542                          int num,                  /* socketindex */
1543                          char *buf,                /* store read data here */
1544                          size_t buffersize,        /* max amount to read */
1545                          CURLcode *curlcode)
1546 {
1547   struct connectdata *conn = data->conn;
1548   struct ssl_connect_data *connssl = &conn->ssl[num];
1549   struct ssl_backend_data *backend = connssl->backend;
1550   ssize_t ret;
1551 
1552   ret = gnutls_record_recv(backend->session, buf, buffersize);
1553   if((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED)) {
1554     *curlcode = CURLE_AGAIN;
1555     return -1;
1556   }
1557 
1558   if(ret == GNUTLS_E_REHANDSHAKE) {
1559     /* BLOCKING call, this is bad but a work-around for now. Fixing this "the
1560        proper way" takes a whole lot of work. */
1561     CURLcode result = handshake(data, conn, num, FALSE, FALSE);
1562     if(result)
1563       /* handshake() writes error message on its own */
1564       *curlcode = result;
1565     else
1566       *curlcode = CURLE_AGAIN; /* then return as if this was a wouldblock */
1567     return -1;
1568   }
1569 
1570   if(ret < 0) {
1571     failf(data, "GnuTLS recv error (%d): %s",
1572 
1573           (int)ret, gnutls_strerror((int)ret));
1574     *curlcode = CURLE_RECV_ERROR;
1575     return -1;
1576   }
1577 
1578   return ret;
1579 }
1580 
gtls_session_free(void * ptr)1581 static void gtls_session_free(void *ptr)
1582 {
1583   free(ptr);
1584 }
1585 
gtls_version(char * buffer,size_t size)1586 static size_t gtls_version(char *buffer, size_t size)
1587 {
1588   return msnprintf(buffer, size, "GnuTLS/%s", gnutls_check_version(NULL));
1589 }
1590 
1591 /* data might be NULL! */
gtls_random(struct Curl_easy * data,unsigned char * entropy,size_t length)1592 static CURLcode gtls_random(struct Curl_easy *data,
1593                             unsigned char *entropy, size_t length)
1594 {
1595   int rc;
1596   (void)data;
1597   rc = gnutls_rnd(GNUTLS_RND_RANDOM, entropy, length);
1598   return rc?CURLE_FAILED_INIT:CURLE_OK;
1599 }
1600 
gtls_sha256sum(const unsigned char * tmp,size_t tmplen,unsigned char * sha256sum,size_t sha256len)1601 static CURLcode gtls_sha256sum(const unsigned char *tmp, /* input */
1602                                size_t tmplen,
1603                                unsigned char *sha256sum, /* output */
1604                                size_t sha256len)
1605 {
1606   struct sha256_ctx SHA256pw;
1607   sha256_init(&SHA256pw);
1608   sha256_update(&SHA256pw, (unsigned int)tmplen, tmp);
1609   sha256_digest(&SHA256pw, (unsigned int)sha256len, sha256sum);
1610   return CURLE_OK;
1611 }
1612 
gtls_cert_status_request(void)1613 static bool gtls_cert_status_request(void)
1614 {
1615   return TRUE;
1616 }
1617 
gtls_get_internals(struct ssl_connect_data * connssl,CURLINFO info UNUSED_PARAM)1618 static void *gtls_get_internals(struct ssl_connect_data *connssl,
1619                                 CURLINFO info UNUSED_PARAM)
1620 {
1621   struct ssl_backend_data *backend = connssl->backend;
1622   (void)info;
1623   return backend->session;
1624 }
1625 
1626 const struct Curl_ssl Curl_ssl_gnutls = {
1627   { CURLSSLBACKEND_GNUTLS, "gnutls" }, /* info */
1628 
1629   SSLSUPP_CA_PATH  |
1630   SSLSUPP_CERTINFO |
1631   SSLSUPP_PINNEDPUBKEY |
1632   SSLSUPP_HTTPS_PROXY,
1633 
1634   sizeof(struct ssl_backend_data),
1635 
1636   gtls_init,                     /* init */
1637   gtls_cleanup,                  /* cleanup */
1638   gtls_version,                  /* version */
1639   Curl_none_check_cxn,           /* check_cxn */
1640   gtls_shutdown,                 /* shutdown */
1641   gtls_data_pending,             /* data_pending */
1642   gtls_random,                   /* random */
1643   gtls_cert_status_request,      /* cert_status_request */
1644   gtls_connect,                  /* connect */
1645   gtls_connect_nonblocking,      /* connect_nonblocking */
1646   Curl_ssl_getsock,              /* getsock */
1647   gtls_get_internals,            /* get_internals */
1648   gtls_close,                    /* close_one */
1649   Curl_none_close_all,           /* close_all */
1650   gtls_session_free,             /* session_free */
1651   Curl_none_set_engine,          /* set_engine */
1652   Curl_none_set_engine_default,  /* set_engine_default */
1653   Curl_none_engines_list,        /* engines_list */
1654   Curl_none_false_start,         /* false_start */
1655   gtls_sha256sum,                /* sha256sum */
1656   NULL,                          /* associate_connection */
1657   NULL                           /* disassociate_connection */
1658 };
1659 
1660 #endif /* USE_GNUTLS */
1661