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