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