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