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