f77ce66c67caca5ae2fa5ce2f4ffd47eb736fd3f
[platform/upstream/curl.git] / lib / vtls / gtls.c
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2014, 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 http://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/gnutls.h>
36 #include <gnutls/x509.h>
37
38 #ifdef USE_GNUTLS_NETTLE
39 #include <gnutls/crypto.h>
40 #include <nettle/md5.h>
41 #else
42 #include <gcrypt.h>
43 #endif
44
45 #include "urldata.h"
46 #include "sendf.h"
47 #include "inet_pton.h"
48 #include "gtls.h"
49 #include "vtls.h"
50 #include "parsedate.h"
51 #include "connect.h" /* for the connect timeout */
52 #include "select.h"
53 #include "rawstr.h"
54
55 #define _MPRINTF_REPLACE /* use our functions only */
56 #include <curl/mprintf.h>
57 #include "curl_memory.h"
58 /* The last #include file should be: */
59 #include "memdebug.h"
60
61 /*
62  Some hackish cast macros based on:
63  http://library.gnome.org/devel/glib/unstable/glib-Type-Conversion-Macros.html
64 */
65 #ifndef GNUTLS_POINTER_TO_INT_CAST
66 #define GNUTLS_POINTER_TO_INT_CAST(p) ((int) (long) (p))
67 #endif
68 #ifndef GNUTLS_INT_TO_POINTER_CAST
69 #define GNUTLS_INT_TO_POINTER_CAST(i) ((void*) (long) (i))
70 #endif
71
72 /* Enable GnuTLS debugging by defining GTLSDEBUG */
73 /*#define GTLSDEBUG */
74
75 #ifdef GTLSDEBUG
76 static void tls_log_func(int level, const char *str)
77 {
78     fprintf(stderr, "|<%d>| %s", level, str);
79 }
80 #endif
81 static bool gtls_inited = FALSE;
82
83 #if defined(GNUTLS_VERSION_NUMBER)
84 #  if (GNUTLS_VERSION_NUMBER >= 0x020c00)
85 #    undef gnutls_transport_set_lowat
86 #    define gnutls_transport_set_lowat(A,B) Curl_nop_stmt
87 #    define USE_GNUTLS_PRIORITY_SET_DIRECT 1
88 #  endif
89 #  if (GNUTLS_VERSION_NUMBER >= 0x020c03)
90 #    define GNUTLS_MAPS_WINSOCK_ERRORS 1
91 #  endif
92
93 #  ifdef USE_NGHTTP2
94 #    undef HAS_ALPN
95 #    if (GNUTLS_VERSION_NUMBER >= 0x030200)
96 #      define HAS_ALPN
97 #    endif
98 #  endif
99 #endif
100
101 /*
102  * Custom push and pull callback functions used by GNU TLS to read and write
103  * to the socket.  These functions are simple wrappers to send() and recv()
104  * (although here using the sread/swrite macros as defined by
105  * curl_setup_once.h).
106  * We use custom functions rather than the GNU TLS defaults because it allows
107  * us to get specific about the fourth "flags" argument, and to use arbitrary
108  * private data with gnutls_transport_set_ptr if we wish.
109  *
110  * When these custom push and pull callbacks fail, GNU TLS checks its own
111  * session-specific error variable, and when not set also its own global
112  * errno variable, in order to take appropriate action. GNU TLS does not
113  * require that the transport is actually a socket. This implies that for
114  * Windows builds these callbacks should ideally set the session-specific
115  * error variable using function gnutls_transport_set_errno or as a last
116  * resort global errno variable using gnutls_transport_set_global_errno,
117  * with a transport agnostic error value. This implies that some winsock
118  * error translation must take place in these callbacks.
119  *
120  * Paragraph above applies to GNU TLS versions older than 2.12.3, since
121  * this version GNU TLS does its own internal winsock error translation
122  * using system_errno() function.
123  */
124
125 #if defined(USE_WINSOCK) && !defined(GNUTLS_MAPS_WINSOCK_ERRORS)
126 #  define gtls_EINTR  4
127 #  define gtls_EIO    5
128 #  define gtls_EAGAIN 11
129 static int gtls_mapped_sockerrno(void)
130 {
131   switch(SOCKERRNO) {
132   case WSAEWOULDBLOCK:
133     return gtls_EAGAIN;
134   case WSAEINTR:
135     return gtls_EINTR;
136   default:
137     break;
138   }
139   return gtls_EIO;
140 }
141 #endif
142
143 static ssize_t Curl_gtls_push(void *s, const void *buf, size_t len)
144 {
145   ssize_t ret = swrite(GNUTLS_POINTER_TO_INT_CAST(s), buf, len);
146 #if defined(USE_WINSOCK) && !defined(GNUTLS_MAPS_WINSOCK_ERRORS)
147   if(ret < 0)
148     gnutls_transport_set_global_errno(gtls_mapped_sockerrno());
149 #endif
150   return ret;
151 }
152
153 static ssize_t Curl_gtls_pull(void *s, void *buf, size_t len)
154 {
155   ssize_t ret = sread(GNUTLS_POINTER_TO_INT_CAST(s), buf, len);
156 #if defined(USE_WINSOCK) && !defined(GNUTLS_MAPS_WINSOCK_ERRORS)
157   if(ret < 0)
158     gnutls_transport_set_global_errno(gtls_mapped_sockerrno());
159 #endif
160   return ret;
161 }
162
163 /* Curl_gtls_init()
164  *
165  * Global GnuTLS init, called from Curl_ssl_init(). This calls functions that
166  * are not thread-safe and thus this function itself is not thread-safe and
167  * must only be called from within curl_global_init() to keep the thread
168  * situation under control!
169  */
170 int Curl_gtls_init(void)
171 {
172   int ret = 1;
173   if(!gtls_inited) {
174     ret = gnutls_global_init()?0:1;
175 #ifdef GTLSDEBUG
176     gnutls_global_set_log_function(tls_log_func);
177     gnutls_global_set_log_level(2);
178 #endif
179     gtls_inited = TRUE;
180   }
181   return ret;
182 }
183
184 int Curl_gtls_cleanup(void)
185 {
186   if(gtls_inited) {
187     gnutls_global_deinit();
188     gtls_inited = FALSE;
189   }
190   return 1;
191 }
192
193 static void showtime(struct SessionHandle *data,
194                      const char *text,
195                      time_t stamp)
196 {
197   struct tm buffer;
198   const struct tm *tm = &buffer;
199   CURLcode result = Curl_gmtime(stamp, &buffer);
200   if(result)
201     return;
202
203   snprintf(data->state.buffer,
204            BUFSIZE,
205            "\t %s: %s, %02d %s %4d %02d:%02d:%02d GMT\n",
206            text,
207            Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
208            tm->tm_mday,
209            Curl_month[tm->tm_mon],
210            tm->tm_year + 1900,
211            tm->tm_hour,
212            tm->tm_min,
213            tm->tm_sec);
214   infof(data, "%s\n", data->state.buffer);
215 }
216
217 static gnutls_datum_t load_file (const char *file)
218 {
219   FILE *f;
220   gnutls_datum_t loaded_file = { NULL, 0 };
221   long filelen;
222   void *ptr;
223
224   if(!(f = fopen(file, "r")))
225     return loaded_file;
226   if(fseek(f, 0, SEEK_END) != 0
227      || (filelen = ftell(f)) < 0
228      || fseek(f, 0, SEEK_SET) != 0
229      || !(ptr = malloc((size_t)filelen)))
230     goto out;
231   if(fread(ptr, 1, (size_t)filelen, f) < (size_t)filelen) {
232     free(ptr);
233     goto out;
234   }
235
236   loaded_file.data = ptr;
237   loaded_file.size = (unsigned int)filelen;
238 out:
239   fclose(f);
240   return loaded_file;
241 }
242
243 static void unload_file(gnutls_datum_t data) {
244   free(data.data);
245 }
246
247
248 /* this function does a SSL/TLS (re-)handshake */
249 static CURLcode handshake(struct connectdata *conn,
250                           int sockindex,
251                           bool duringconnect,
252                           bool nonblocking)
253 {
254   struct SessionHandle *data = conn->data;
255   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
256   gnutls_session_t session = conn->ssl[sockindex].session;
257   curl_socket_t sockfd = conn->sock[sockindex];
258   long timeout_ms;
259   int rc;
260   int what;
261
262   for(;;) {
263     /* check allowed time left */
264     timeout_ms = Curl_timeleft(data, NULL, duringconnect);
265
266     if(timeout_ms < 0) {
267       /* no need to continue if time already is up */
268       failf(data, "SSL connection timeout");
269       return CURLE_OPERATION_TIMEDOUT;
270     }
271
272     /* if ssl is expecting something, check if it's available. */
273     if(connssl->connecting_state == ssl_connect_2_reading
274        || connssl->connecting_state == ssl_connect_2_writing) {
275
276       curl_socket_t writefd = ssl_connect_2_writing==
277         connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
278       curl_socket_t readfd = ssl_connect_2_reading==
279         connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
280
281       what = Curl_socket_ready(readfd, writefd,
282                                nonblocking?0:
283                                timeout_ms?timeout_ms:1000);
284       if(what < 0) {
285         /* fatal error */
286         failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
287         return CURLE_SSL_CONNECT_ERROR;
288       }
289       else if(0 == what) {
290         if(nonblocking)
291           return CURLE_OK;
292         else if(timeout_ms) {
293           /* timeout */
294           failf(data, "SSL connection timeout at %ld", timeout_ms);
295           return CURLE_OPERATION_TIMEDOUT;
296         }
297       }
298       /* socket is readable or writable */
299     }
300
301     rc = gnutls_handshake(session);
302
303     if((rc == GNUTLS_E_AGAIN) || (rc == GNUTLS_E_INTERRUPTED)) {
304       connssl->connecting_state =
305         gnutls_record_get_direction(session)?
306         ssl_connect_2_writing:ssl_connect_2_reading;
307       continue;
308       if(nonblocking)
309         return CURLE_OK;
310     }
311     else if((rc < 0) && !gnutls_error_is_fatal(rc)) {
312       const char *strerr = NULL;
313
314       if(rc == GNUTLS_E_WARNING_ALERT_RECEIVED) {
315         int alert = gnutls_alert_get(session);
316         strerr = gnutls_alert_get_name(alert);
317       }
318
319       if(strerr == NULL)
320         strerr = gnutls_strerror(rc);
321
322       failf(data, "gnutls_handshake() warning: %s", strerr);
323     }
324     else if(rc < 0) {
325       const char *strerr = NULL;
326
327       if(rc == GNUTLS_E_FATAL_ALERT_RECEIVED) {
328         int alert = gnutls_alert_get(session);
329         strerr = gnutls_alert_get_name(alert);
330       }
331
332       if(strerr == NULL)
333         strerr = gnutls_strerror(rc);
334
335       failf(data, "gnutls_handshake() failed: %s", strerr);
336       return CURLE_SSL_CONNECT_ERROR;
337     }
338
339     /* Reset our connect state machine */
340     connssl->connecting_state = ssl_connect_1;
341     return CURLE_OK;
342   }
343 }
344
345 static gnutls_x509_crt_fmt_t do_file_type(const char *type)
346 {
347   if(!type || !type[0])
348     return GNUTLS_X509_FMT_PEM;
349   if(Curl_raw_equal(type, "PEM"))
350     return GNUTLS_X509_FMT_PEM;
351   if(Curl_raw_equal(type, "DER"))
352     return GNUTLS_X509_FMT_DER;
353   return -1;
354 }
355
356 static CURLcode
357 gtls_connect_step1(struct connectdata *conn,
358                    int sockindex)
359 {
360   struct SessionHandle *data = conn->data;
361   gnutls_session_t session;
362   int rc;
363   void *ssl_sessionid;
364   size_t ssl_idsize;
365   bool sni = TRUE; /* default is SNI enabled */
366 #ifdef ENABLE_IPV6
367   struct in6_addr addr;
368 #else
369   struct in_addr addr;
370 #endif
371 #ifndef USE_GNUTLS_PRIORITY_SET_DIRECT
372   static int cipher_priority[] = { GNUTLS_CIPHER_AES_128_GCM,
373     GNUTLS_CIPHER_AES_256_GCM, GNUTLS_CIPHER_AES_128_CBC,
374     GNUTLS_CIPHER_AES_256_CBC, GNUTLS_CIPHER_CAMELLIA_128_CBC,
375     GNUTLS_CIPHER_CAMELLIA_256_CBC, GNUTLS_CIPHER_3DES_CBC,
376   };
377   static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
378   static int protocol_priority[] = { 0, 0, 0, 0 };
379 #else
380 #define GNUTLS_CIPHERS "NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509"
381   const char* prioritylist;
382   const char *err;
383 #endif
384 #ifdef HAS_ALPN
385   int protocols_size = 2;
386   gnutls_datum_t protocols[2];
387 #endif
388
389   if(conn->ssl[sockindex].state == ssl_connection_complete)
390     /* to make us tolerant against being called more than once for the
391        same connection */
392     return CURLE_OK;
393
394   if(!gtls_inited)
395     Curl_gtls_init();
396
397   /* GnuTLS only supports SSLv3 and TLSv1 */
398   if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) {
399     failf(data, "GnuTLS does not support SSLv2");
400     return CURLE_SSL_CONNECT_ERROR;
401   }
402   else if(data->set.ssl.version == CURL_SSLVERSION_SSLv3)
403     sni = FALSE; /* SSLv3 has no SNI */
404
405   /* allocate a cred struct */
406   rc = gnutls_certificate_allocate_credentials(&conn->ssl[sockindex].cred);
407   if(rc != GNUTLS_E_SUCCESS) {
408     failf(data, "gnutls_cert_all_cred() failed: %s", gnutls_strerror(rc));
409     return CURLE_SSL_CONNECT_ERROR;
410   }
411
412 #ifdef USE_TLS_SRP
413   if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
414     infof(data, "Using TLS-SRP username: %s\n", data->set.ssl.username);
415
416     rc = gnutls_srp_allocate_client_credentials(
417            &conn->ssl[sockindex].srp_client_cred);
418     if(rc != GNUTLS_E_SUCCESS) {
419       failf(data, "gnutls_srp_allocate_client_cred() failed: %s",
420             gnutls_strerror(rc));
421       return CURLE_OUT_OF_MEMORY;
422     }
423
424     rc = gnutls_srp_set_client_credentials(conn->ssl[sockindex].
425                                            srp_client_cred,
426                                            data->set.ssl.username,
427                                            data->set.ssl.password);
428     if(rc != GNUTLS_E_SUCCESS) {
429       failf(data, "gnutls_srp_set_client_cred() failed: %s",
430             gnutls_strerror(rc));
431       return CURLE_BAD_FUNCTION_ARGUMENT;
432     }
433   }
434 #endif
435
436   if(data->set.ssl.CAfile) {
437     /* set the trusted CA cert bundle file */
438     gnutls_certificate_set_verify_flags(conn->ssl[sockindex].cred,
439                                         GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
440
441     rc = gnutls_certificate_set_x509_trust_file(conn->ssl[sockindex].cred,
442                                                 data->set.ssl.CAfile,
443                                                 GNUTLS_X509_FMT_PEM);
444     if(rc < 0) {
445       infof(data, "error reading ca cert file %s (%s)\n",
446             data->set.ssl.CAfile, gnutls_strerror(rc));
447       if(data->set.ssl.verifypeer)
448         return CURLE_SSL_CACERT_BADFILE;
449     }
450     else
451       infof(data, "found %d certificates in %s\n",
452             rc, data->set.ssl.CAfile);
453   }
454
455   if(data->set.ssl.CRLfile) {
456     /* set the CRL list file */
457     rc = gnutls_certificate_set_x509_crl_file(conn->ssl[sockindex].cred,
458                                               data->set.ssl.CRLfile,
459                                               GNUTLS_X509_FMT_PEM);
460     if(rc < 0) {
461       failf(data, "error reading crl file %s (%s)",
462             data->set.ssl.CRLfile, gnutls_strerror(rc));
463       return CURLE_SSL_CRL_BADFILE;
464     }
465     else
466       infof(data, "found %d CRL in %s\n",
467             rc, data->set.ssl.CRLfile);
468   }
469
470   /* Initialize TLS session as a client */
471   rc = gnutls_init(&conn->ssl[sockindex].session, GNUTLS_CLIENT);
472   if(rc != GNUTLS_E_SUCCESS) {
473     failf(data, "gnutls_init() failed: %d", rc);
474     return CURLE_SSL_CONNECT_ERROR;
475   }
476
477   /* convenient assign */
478   session = conn->ssl[sockindex].session;
479
480   if((0 == Curl_inet_pton(AF_INET, conn->host.name, &addr)) &&
481 #ifdef ENABLE_IPV6
482      (0 == Curl_inet_pton(AF_INET6, conn->host.name, &addr)) &&
483 #endif
484      sni &&
485      (gnutls_server_name_set(session, GNUTLS_NAME_DNS, conn->host.name,
486                              strlen(conn->host.name)) < 0))
487     infof(data, "WARNING: failed to configure server name indication (SNI) "
488           "TLS extension\n");
489
490   /* Use default priorities */
491   rc = gnutls_set_default_priority(session);
492   if(rc != GNUTLS_E_SUCCESS)
493     return CURLE_SSL_CONNECT_ERROR;
494
495 #ifndef USE_GNUTLS_PRIORITY_SET_DIRECT
496   rc = gnutls_cipher_set_priority(session, cipher_priority);
497   if(rc != GNUTLS_E_SUCCESS)
498     return CURLE_SSL_CONNECT_ERROR;
499
500   /* Sets the priority on the certificate types supported by gnutls. Priority
501    is higher for types specified before others. After specifying the types
502    you want, you must append a 0. */
503   rc = gnutls_certificate_type_set_priority(session, cert_type_priority);
504   if(rc != GNUTLS_E_SUCCESS)
505     return CURLE_SSL_CONNECT_ERROR;
506
507   if(data->set.ssl.cipher_list != NULL) {
508     failf(data, "can't pass a custom cipher list to older GnuTLS"
509           " versions");
510     return CURLE_SSL_CONNECT_ERROR;
511   }
512
513   switch (data->set.ssl.version) {
514     case CURL_SSLVERSION_SSLv3:
515       protocol_priority[0] = GNUTLS_SSL3;
516       break;
517     case CURL_SSLVERSION_DEFAULT:
518     case CURL_SSLVERSION_TLSv1:
519       protocol_priority[0] = GNUTLS_TLS1_0;
520       protocol_priority[1] = GNUTLS_TLS1_1;
521       protocol_priority[2] = GNUTLS_TLS1_2;
522       break;
523     case CURL_SSLVERSION_TLSv1_0:
524       protocol_priority[0] = GNUTLS_TLS1_0;
525       break;
526     case CURL_SSLVERSION_TLSv1_1:
527       protocol_priority[0] = GNUTLS_TLS1_1;
528       break;
529     case CURL_SSLVERSION_TLSv1_2:
530       protocol_priority[0] = GNUTLS_TLS1_2;
531     break;
532       case CURL_SSLVERSION_SSLv2:
533     default:
534       failf(data, "GnuTLS does not support SSLv2");
535       return CURLE_SSL_CONNECT_ERROR;
536       break;
537   }
538   rc = gnutls_protocol_set_priority(session, protocol_priority);
539 #else
540   switch (data->set.ssl.version) {
541     case CURL_SSLVERSION_SSLv3:
542       prioritylist = GNUTLS_CIPHERS ":-VERS-TLS-ALL:+VERS-SSL3.0";
543       sni = false;
544       break;
545     case CURL_SSLVERSION_DEFAULT:
546     case CURL_SSLVERSION_TLSv1:
547       prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0";
548       break;
549     case CURL_SSLVERSION_TLSv1_0:
550       prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
551                      "+VERS-TLS1.0";
552       break;
553     case CURL_SSLVERSION_TLSv1_1:
554       prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
555                      "+VERS-TLS1.1";
556       break;
557     case CURL_SSLVERSION_TLSv1_2:
558       prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
559                      "+VERS-TLS1.2";
560       break;
561     case CURL_SSLVERSION_SSLv2:
562     default:
563       failf(data, "GnuTLS does not support SSLv2");
564       return CURLE_SSL_CONNECT_ERROR;
565       break;
566   }
567   rc = gnutls_priority_set_direct(session, prioritylist, &err);
568 #endif
569
570 #ifdef HAS_ALPN
571   if(data->set.httpversion == CURL_HTTP_VERSION_2_0) {
572     if(data->set.ssl_enable_alpn) {
573       protocols[0].data = NGHTTP2_PROTO_VERSION_ID;
574       protocols[0].size = NGHTTP2_PROTO_VERSION_ID_LEN;
575       protocols[1].data = ALPN_HTTP_1_1;
576       protocols[1].size = ALPN_HTTP_1_1_LENGTH;
577       gnutls_alpn_set_protocols(session, protocols, protocols_size, 0);
578       infof(data, "ALPN, offering %s, %s\n", NGHTTP2_PROTO_VERSION_ID,
579             ALPN_HTTP_1_1);
580     }
581     else {
582       infof(data, "SSL, can't negotiate HTTP/2.0 without ALPN\n");
583     }
584   }
585 #endif
586
587   if(rc != GNUTLS_E_SUCCESS) {
588     failf(data, "Did you pass a valid GnuTLS cipher list?");
589     return CURLE_SSL_CONNECT_ERROR;
590   }
591
592
593   if(data->set.str[STRING_CERT]) {
594     if(gnutls_certificate_set_x509_key_file(
595          conn->ssl[sockindex].cred,
596          data->set.str[STRING_CERT],
597          data->set.str[STRING_KEY] ?
598          data->set.str[STRING_KEY] : data->set.str[STRING_CERT],
599          do_file_type(data->set.str[STRING_CERT_TYPE]) ) !=
600        GNUTLS_E_SUCCESS) {
601       failf(data, "error reading X.509 key or certificate file");
602       return CURLE_SSL_CONNECT_ERROR;
603     }
604   }
605
606 #ifdef USE_TLS_SRP
607   /* put the credentials to the current session */
608   if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
609     rc = gnutls_credentials_set(session, GNUTLS_CRD_SRP,
610                                 conn->ssl[sockindex].srp_client_cred);
611     if(rc != GNUTLS_E_SUCCESS)
612       failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc));
613   }
614   else
615 #endif
616     rc = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
617                                 conn->ssl[sockindex].cred);
618
619   /* set the connection handle (file descriptor for the socket) */
620   gnutls_transport_set_ptr(session,
621                            GNUTLS_INT_TO_POINTER_CAST(conn->sock[sockindex]));
622
623   /* register callback functions to send and receive data. */
624   gnutls_transport_set_push_function(session, Curl_gtls_push);
625   gnutls_transport_set_pull_function(session, Curl_gtls_pull);
626
627   /* lowat must be set to zero when using custom push and pull functions. */
628   gnutls_transport_set_lowat(session, 0);
629
630   /* This might be a reconnect, so we check for a session ID in the cache
631      to speed up things */
632
633   if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, &ssl_idsize)) {
634     /* we got a session id, use it! */
635     gnutls_session_set_data(session, ssl_sessionid, ssl_idsize);
636
637     /* Informational message */
638     infof (data, "SSL re-using session ID\n");
639   }
640
641   return CURLE_OK;
642 }
643
644 static Curl_recv gtls_recv;
645 static Curl_send gtls_send;
646
647 static CURLcode
648 gtls_connect_step3(struct connectdata *conn,
649                    int sockindex)
650 {
651   unsigned int cert_list_size;
652   const gnutls_datum_t *chainp;
653   unsigned int verify_status;
654   gnutls_x509_crt_t x509_cert,x509_issuer;
655   gnutls_datum_t issuerp;
656   char certbuf[256]; /* big enough? */
657   size_t size;
658   unsigned int algo;
659   unsigned int bits;
660   time_t certclock;
661   const char *ptr;
662   struct SessionHandle *data = conn->data;
663   gnutls_session_t session = conn->ssl[sockindex].session;
664   int rc;
665   int incache;
666   void *ssl_sessionid;
667 #ifdef HAS_ALPN
668   gnutls_datum_t proto;
669 #endif
670   CURLcode result = CURLE_OK;
671
672   /* This function will return the peer's raw certificate (chain) as sent by
673      the peer. These certificates are in raw format (DER encoded for
674      X.509). In case of a X.509 then a certificate list may be present. The
675      first certificate in the list is the peer's certificate, following the
676      issuer's certificate, then the issuer's issuer etc. */
677
678   chainp = gnutls_certificate_get_peers(session, &cert_list_size);
679   if(!chainp) {
680     if(data->set.ssl.verifypeer ||
681        data->set.ssl.verifyhost ||
682        data->set.ssl.issuercert) {
683 #ifdef USE_TLS_SRP
684       if(data->set.ssl.authtype == CURL_TLSAUTH_SRP
685          && data->set.ssl.username != NULL
686          && !data->set.ssl.verifypeer
687          && gnutls_cipher_get(session)) {
688         /* no peer cert, but auth is ok if we have SRP user and cipher and no
689            peer verify */
690       }
691       else {
692 #endif
693         failf(data, "failed to get server cert");
694         return CURLE_PEER_FAILED_VERIFICATION;
695 #ifdef USE_TLS_SRP
696       }
697 #endif
698     }
699     infof(data, "\t common name: WARNING couldn't obtain\n");
700   }
701
702   if(data->set.ssl.verifypeer) {
703     /* This function will try to verify the peer's certificate and return its
704        status (trusted, invalid etc.). The value of status should be one or
705        more of the gnutls_certificate_status_t enumerated elements bitwise
706        or'd. To avoid denial of service attacks some default upper limits
707        regarding the certificate key size and chain size are set. To override
708        them use gnutls_certificate_set_verify_limits(). */
709
710     rc = gnutls_certificate_verify_peers2(session, &verify_status);
711     if(rc < 0) {
712       failf(data, "server cert verify failed: %d", rc);
713       return CURLE_SSL_CONNECT_ERROR;
714     }
715
716     /* verify_status is a bitmask of gnutls_certificate_status bits */
717     if(verify_status & GNUTLS_CERT_INVALID) {
718       if(data->set.ssl.verifypeer) {
719         failf(data, "server certificate verification failed. CAfile: %s "
720               "CRLfile: %s", data->set.ssl.CAfile?data->set.ssl.CAfile:"none",
721               data->set.ssl.CRLfile?data->set.ssl.CRLfile:"none");
722         return CURLE_SSL_CACERT;
723       }
724       else
725         infof(data, "\t server certificate verification FAILED\n");
726     }
727     else
728       infof(data, "\t server certificate verification OK\n");
729   }
730   else
731     infof(data, "\t server certificate verification SKIPPED\n");
732
733   /* initialize an X.509 certificate structure. */
734   gnutls_x509_crt_init(&x509_cert);
735
736   if(chainp)
737     /* convert the given DER or PEM encoded Certificate to the native
738        gnutls_x509_crt_t format */
739     gnutls_x509_crt_import(x509_cert, chainp, GNUTLS_X509_FMT_DER);
740
741   if(data->set.ssl.issuercert) {
742     gnutls_x509_crt_init(&x509_issuer);
743     issuerp = load_file(data->set.ssl.issuercert);
744     gnutls_x509_crt_import(x509_issuer, &issuerp, GNUTLS_X509_FMT_PEM);
745     rc = gnutls_x509_crt_check_issuer(x509_cert,x509_issuer);
746     unload_file(issuerp);
747     if(rc <= 0) {
748       failf(data, "server certificate issuer check failed (IssuerCert: %s)",
749             data->set.ssl.issuercert?data->set.ssl.issuercert:"none");
750       return CURLE_SSL_ISSUER_ERROR;
751     }
752     infof(data,"\t server certificate issuer check OK (Issuer Cert: %s)\n",
753           data->set.ssl.issuercert?data->set.ssl.issuercert:"none");
754   }
755
756   size=sizeof(certbuf);
757   rc = gnutls_x509_crt_get_dn_by_oid(x509_cert, GNUTLS_OID_X520_COMMON_NAME,
758                                      0, /* the first and only one */
759                                      FALSE,
760                                      certbuf,
761                                      &size);
762   if(rc) {
763     infof(data, "error fetching CN from cert:%s\n",
764           gnutls_strerror(rc));
765   }
766
767   /* This function will check if the given certificate's subject matches the
768      given hostname. This is a basic implementation of the matching described
769      in RFC2818 (HTTPS), which takes into account wildcards, and the subject
770      alternative name PKIX extension. Returns non zero on success, and zero on
771      failure. */
772   rc = gnutls_x509_crt_check_hostname(x509_cert, conn->host.name);
773
774   if(!rc) {
775     if(data->set.ssl.verifyhost) {
776       failf(data, "SSL: certificate subject name (%s) does not match "
777             "target host name '%s'", certbuf, conn->host.dispname);
778       gnutls_x509_crt_deinit(x509_cert);
779       return CURLE_PEER_FAILED_VERIFICATION;
780     }
781     else
782       infof(data, "\t common name: %s (does not match '%s')\n",
783             certbuf, conn->host.dispname);
784   }
785   else
786     infof(data, "\t common name: %s (matched)\n", certbuf);
787
788   /* Check for time-based validity */
789   certclock = gnutls_x509_crt_get_expiration_time(x509_cert);
790
791   if(certclock == (time_t)-1) {
792     failf(data, "server cert expiration date verify failed");
793     return CURLE_SSL_CONNECT_ERROR;
794   }
795
796   if(certclock < time(NULL)) {
797     if(data->set.ssl.verifypeer) {
798       failf(data, "server certificate expiration date has passed.");
799       return CURLE_PEER_FAILED_VERIFICATION;
800     }
801     else
802       infof(data, "\t server certificate expiration date FAILED\n");
803   }
804   else
805     infof(data, "\t server certificate expiration date OK\n");
806
807   certclock = gnutls_x509_crt_get_activation_time(x509_cert);
808
809   if(certclock == (time_t)-1) {
810     failf(data, "server cert activation date verify failed");
811     return CURLE_SSL_CONNECT_ERROR;
812   }
813
814   if(certclock > time(NULL)) {
815     if(data->set.ssl.verifypeer) {
816       failf(data, "server certificate not activated yet.");
817       return CURLE_PEER_FAILED_VERIFICATION;
818     }
819     else
820       infof(data, "\t server certificate activation date FAILED\n");
821   }
822   else
823     infof(data, "\t server certificate activation date OK\n");
824
825   /* Show:
826
827   - ciphers used
828   - subject
829   - start date
830   - expire date
831   - common name
832   - issuer
833
834   */
835
836   /* public key algorithm's parameters */
837   algo = gnutls_x509_crt_get_pk_algorithm(x509_cert, &bits);
838   infof(data, "\t certificate public key: %s\n",
839         gnutls_pk_algorithm_get_name(algo));
840
841   /* version of the X.509 certificate. */
842   infof(data, "\t certificate version: #%d\n",
843         gnutls_x509_crt_get_version(x509_cert));
844
845
846   size = sizeof(certbuf);
847   gnutls_x509_crt_get_dn(x509_cert, certbuf, &size);
848   infof(data, "\t subject: %s\n", certbuf);
849
850   certclock = gnutls_x509_crt_get_activation_time(x509_cert);
851   showtime(data, "start date", certclock);
852
853   certclock = gnutls_x509_crt_get_expiration_time(x509_cert);
854   showtime(data, "expire date", certclock);
855
856   size = sizeof(certbuf);
857   gnutls_x509_crt_get_issuer_dn(x509_cert, certbuf, &size);
858   infof(data, "\t issuer: %s\n", certbuf);
859
860   gnutls_x509_crt_deinit(x509_cert);
861
862   /* compression algorithm (if any) */
863   ptr = gnutls_compression_get_name(gnutls_compression_get(session));
864   /* the *_get_name() says "NULL" if GNUTLS_COMP_NULL is returned */
865   infof(data, "\t compression: %s\n", ptr);
866
867   /* the name of the cipher used. ie 3DES. */
868   ptr = gnutls_cipher_get_name(gnutls_cipher_get(session));
869   infof(data, "\t cipher: %s\n", ptr);
870
871   /* the MAC algorithms name. ie SHA1 */
872   ptr = gnutls_mac_get_name(gnutls_mac_get(session));
873   infof(data, "\t MAC: %s\n", ptr);
874
875 #ifdef HAS_ALPN
876   if(data->set.ssl_enable_alpn) {
877     rc = gnutls_alpn_get_selected_protocol(session, &proto);
878     if(rc == 0) {
879       infof(data, "ALPN, server accepted to use %.*s\n", proto.size,
880           proto.data);
881
882       if(proto.size == NGHTTP2_PROTO_VERSION_ID_LEN &&
883         memcmp(NGHTTP2_PROTO_VERSION_ID, proto.data,
884         NGHTTP2_PROTO_VERSION_ID_LEN) == 0) {
885         conn->negnpn = NPN_HTTP2;
886       }
887       else if(proto.size == ALPN_HTTP_1_1_LENGTH && memcmp(ALPN_HTTP_1_1,
888           proto.data, ALPN_HTTP_1_1_LENGTH) == 0) {
889         conn->negnpn = NPN_HTTP1_1;
890       }
891     }
892     else {
893       infof(data, "ALPN, server did not agree to a protocol\n");
894     }
895   }
896 #endif
897
898   conn->ssl[sockindex].state = ssl_connection_complete;
899   conn->recv[sockindex] = gtls_recv;
900   conn->send[sockindex] = gtls_send;
901
902   {
903     /* we always unconditionally get the session id here, as even if we
904        already got it from the cache and asked to use it in the connection, it
905        might've been rejected and then a new one is in use now and we need to
906        detect that. */
907     void *connect_sessionid;
908     size_t connect_idsize;
909
910     /* get the session ID data size */
911     gnutls_session_get_data(session, NULL, &connect_idsize);
912     connect_sessionid = malloc(connect_idsize); /* get a buffer for it */
913
914     if(connect_sessionid) {
915       /* extract session ID to the allocated buffer */
916       gnutls_session_get_data(session, connect_sessionid, &connect_idsize);
917
918       incache = !(Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL));
919       if(incache) {
920         /* there was one before in the cache, so instead of risking that the
921            previous one was rejected, we just kill that and store the new */
922         Curl_ssl_delsessionid(conn, ssl_sessionid);
923       }
924
925       /* store this session id */
926       result = Curl_ssl_addsessionid(conn, connect_sessionid, connect_idsize);
927       if(result) {
928         free(connect_sessionid);
929         result = CURLE_OUT_OF_MEMORY;
930       }
931     }
932     else
933       result = CURLE_OUT_OF_MEMORY;
934   }
935
936   return result;
937 }
938
939
940 /*
941  * This function is called after the TCP connect has completed. Setup the TLS
942  * layer and do all necessary magic.
943  */
944 /* We use connssl->connecting_state to keep track of the connection status;
945    there are three states: 'ssl_connect_1' (not started yet or complete),
946    'ssl_connect_2_reading' (waiting for data from server), and
947    'ssl_connect_2_writing' (waiting to be able to write).
948  */
949 static CURLcode
950 gtls_connect_common(struct connectdata *conn,
951                     int sockindex,
952                     bool nonblocking,
953                     bool *done)
954 {
955   int rc;
956   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
957
958   /* Initiate the connection, if not already done */
959   if(ssl_connect_1==connssl->connecting_state) {
960     rc = gtls_connect_step1 (conn, sockindex);
961     if(rc)
962       return rc;
963   }
964
965   rc = handshake(conn, sockindex, TRUE, nonblocking);
966   if(rc)
967     /* handshake() sets its own error message with failf() */
968     return rc;
969
970   /* Finish connecting once the handshake is done */
971   if(ssl_connect_1==connssl->connecting_state) {
972     rc = gtls_connect_step3(conn, sockindex);
973     if(rc)
974       return rc;
975   }
976
977   *done = ssl_connect_1==connssl->connecting_state;
978
979   return CURLE_OK;
980 }
981
982 CURLcode
983 Curl_gtls_connect_nonblocking(struct connectdata *conn,
984                               int sockindex,
985                               bool *done)
986 {
987   return gtls_connect_common(conn, sockindex, TRUE, done);
988 }
989
990 CURLcode
991 Curl_gtls_connect(struct connectdata *conn,
992                   int sockindex)
993
994 {
995   CURLcode retcode;
996   bool done = FALSE;
997
998   retcode = gtls_connect_common(conn, sockindex, FALSE, &done);
999   if(retcode)
1000     return retcode;
1001
1002   DEBUGASSERT(done);
1003
1004   return CURLE_OK;
1005 }
1006
1007 static ssize_t gtls_send(struct connectdata *conn,
1008                          int sockindex,
1009                          const void *mem,
1010                          size_t len,
1011                          CURLcode *curlcode)
1012 {
1013   ssize_t rc = gnutls_record_send(conn->ssl[sockindex].session, mem, len);
1014
1015   if(rc < 0 ) {
1016     *curlcode = (rc == GNUTLS_E_AGAIN)
1017       ? CURLE_AGAIN
1018       : CURLE_SEND_ERROR;
1019
1020     rc = -1;
1021   }
1022
1023   return rc;
1024 }
1025
1026 void Curl_gtls_close_all(struct SessionHandle *data)
1027 {
1028   /* FIX: make the OpenSSL code more generic and use parts of it here */
1029   (void)data;
1030 }
1031
1032 static void close_one(struct connectdata *conn,
1033                       int idx)
1034 {
1035   if(conn->ssl[idx].session) {
1036     gnutls_bye(conn->ssl[idx].session, GNUTLS_SHUT_RDWR);
1037     gnutls_deinit(conn->ssl[idx].session);
1038     conn->ssl[idx].session = NULL;
1039   }
1040   if(conn->ssl[idx].cred) {
1041     gnutls_certificate_free_credentials(conn->ssl[idx].cred);
1042     conn->ssl[idx].cred = NULL;
1043   }
1044 #ifdef USE_TLS_SRP
1045   if(conn->ssl[idx].srp_client_cred) {
1046     gnutls_srp_free_client_credentials(conn->ssl[idx].srp_client_cred);
1047     conn->ssl[idx].srp_client_cred = NULL;
1048   }
1049 #endif
1050 }
1051
1052 void Curl_gtls_close(struct connectdata *conn, int sockindex)
1053 {
1054   close_one(conn, sockindex);
1055 }
1056
1057 /*
1058  * This function is called to shut down the SSL layer but keep the
1059  * socket open (CCC - Clear Command Channel)
1060  */
1061 int Curl_gtls_shutdown(struct connectdata *conn, int sockindex)
1062 {
1063   ssize_t result;
1064   int retval = 0;
1065   struct SessionHandle *data = conn->data;
1066   int done = 0;
1067   char buf[120];
1068
1069   /* This has only been tested on the proftpd server, and the mod_tls code
1070      sends a close notify alert without waiting for a close notify alert in
1071      response. Thus we wait for a close notify alert from the server, but
1072      we do not send one. Let's hope other servers do the same... */
1073
1074   if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
1075       gnutls_bye(conn->ssl[sockindex].session, GNUTLS_SHUT_WR);
1076
1077   if(conn->ssl[sockindex].session) {
1078     while(!done) {
1079       int what = Curl_socket_ready(conn->sock[sockindex],
1080                                    CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
1081       if(what > 0) {
1082         /* Something to read, let's do it and hope that it is the close
1083            notify alert from the server */
1084         result = gnutls_record_recv(conn->ssl[sockindex].session,
1085                                     buf, sizeof(buf));
1086         switch(result) {
1087         case 0:
1088           /* This is the expected response. There was no data but only
1089              the close notify alert */
1090           done = 1;
1091           break;
1092         case GNUTLS_E_AGAIN:
1093         case GNUTLS_E_INTERRUPTED:
1094           infof(data, "GNUTLS_E_AGAIN || GNUTLS_E_INTERRUPTED\n");
1095           break;
1096         default:
1097           retval = -1;
1098           done = 1;
1099           break;
1100         }
1101       }
1102       else if(0 == what) {
1103         /* timeout */
1104         failf(data, "SSL shutdown timeout");
1105         done = 1;
1106         break;
1107       }
1108       else {
1109         /* anything that gets here is fatally bad */
1110         failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
1111         retval = -1;
1112         done = 1;
1113       }
1114     }
1115     gnutls_deinit(conn->ssl[sockindex].session);
1116   }
1117   gnutls_certificate_free_credentials(conn->ssl[sockindex].cred);
1118
1119 #ifdef USE_TLS_SRP
1120   if(data->set.ssl.authtype == CURL_TLSAUTH_SRP
1121      && data->set.ssl.username != NULL)
1122     gnutls_srp_free_client_credentials(conn->ssl[sockindex].srp_client_cred);
1123 #endif
1124
1125   conn->ssl[sockindex].cred = NULL;
1126   conn->ssl[sockindex].session = NULL;
1127
1128   return retval;
1129 }
1130
1131 static ssize_t gtls_recv(struct connectdata *conn, /* connection data */
1132                          int num,                  /* socketindex */
1133                          char *buf,                /* store read data here */
1134                          size_t buffersize,        /* max amount to read */
1135                          CURLcode *curlcode)
1136 {
1137   ssize_t ret;
1138
1139   ret = gnutls_record_recv(conn->ssl[num].session, buf, buffersize);
1140   if((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED)) {
1141     *curlcode = CURLE_AGAIN;
1142     return -1;
1143   }
1144
1145   if(ret == GNUTLS_E_REHANDSHAKE) {
1146     /* BLOCKING call, this is bad but a work-around for now. Fixing this "the
1147        proper way" takes a whole lot of work. */
1148     CURLcode rc = handshake(conn, num, FALSE, FALSE);
1149     if(rc)
1150       /* handshake() writes error message on its own */
1151       *curlcode = rc;
1152     else
1153       *curlcode = CURLE_AGAIN; /* then return as if this was a wouldblock */
1154     return -1;
1155   }
1156
1157   if(ret < 0) {
1158     failf(conn->data, "GnuTLS recv error (%d): %s",
1159           (int)ret, gnutls_strerror((int)ret));
1160     *curlcode = CURLE_RECV_ERROR;
1161     return -1;
1162   }
1163
1164   return ret;
1165 }
1166
1167 void Curl_gtls_session_free(void *ptr)
1168 {
1169   free(ptr);
1170 }
1171
1172 size_t Curl_gtls_version(char *buffer, size_t size)
1173 {
1174   return snprintf(buffer, size, "GnuTLS/%s", gnutls_check_version(NULL));
1175 }
1176
1177 int Curl_gtls_seed(struct SessionHandle *data)
1178 {
1179   /* we have the "SSL is seeded" boolean static to prevent multiple
1180      time-consuming seedings in vain */
1181   static bool ssl_seeded = FALSE;
1182
1183   /* Quickly add a bit of entropy */
1184 #ifndef USE_GNUTLS_NETTLE
1185   gcry_fast_random_poll();
1186 #endif
1187
1188   if(!ssl_seeded || data->set.str[STRING_SSL_RANDOM_FILE] ||
1189      data->set.str[STRING_SSL_EGDSOCKET]) {
1190
1191     /* TODO: to a good job seeding the RNG
1192        This may involve the gcry_control function and these options:
1193        GCRYCTL_SET_RANDOM_SEED_FILE
1194        GCRYCTL_SET_RNDEGD_SOCKET
1195     */
1196     ssl_seeded = TRUE;
1197   }
1198   return 0;
1199 }
1200
1201 void Curl_gtls_random(struct SessionHandle *data,
1202                       unsigned char *entropy,
1203                       size_t length)
1204 {
1205 #if defined(USE_GNUTLS_NETTLE)
1206   (void)data;
1207   gnutls_rnd(GNUTLS_RND_RANDOM, entropy, length);
1208 #elif defined(USE_GNUTLS)
1209   Curl_gtls_seed(data); /* Initiate the seed if not already done */
1210   gcry_randomize(entropy, length, GCRY_STRONG_RANDOM);
1211 #endif
1212 }
1213
1214 void Curl_gtls_md5sum(unsigned char *tmp, /* input */
1215                       size_t tmplen,
1216                       unsigned char *md5sum, /* output */
1217                       size_t md5len)
1218 {
1219 #if defined(USE_GNUTLS_NETTLE)
1220   struct md5_ctx MD5pw;
1221   md5_init(&MD5pw);
1222   md5_update(&MD5pw, (unsigned int)tmplen, tmp);
1223   md5_digest(&MD5pw, (unsigned int)md5len, md5sum);
1224 #elif defined(USE_GNUTLS)
1225   gcry_md_hd_t MD5pw;
1226   gcry_md_open(&MD5pw, GCRY_MD_MD5, 0);
1227   gcry_md_write(MD5pw, tmp, tmplen);
1228   memcpy(md5sum, gcry_md_read (MD5pw, 0), md5len);
1229   gcry_md_close(MD5pw);
1230 #endif
1231 }
1232
1233 #endif /* USE_GNUTLS */