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