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