gnutls: improved error message if setting cipher list fails
[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 const int cipher_priority[] = {
373   /* These two ciphers were added to GnuTLS as late as ver. 3.0.1,
374      but this code path is only ever used for ver. < 2.12.0.
375      GNUTLS_CIPHER_AES_128_GCM,
376      GNUTLS_CIPHER_AES_256_GCM,
377   */
378     GNUTLS_CIPHER_AES_128_CBC,
379     GNUTLS_CIPHER_AES_256_CBC,
380     GNUTLS_CIPHER_CAMELLIA_128_CBC,
381     GNUTLS_CIPHER_CAMELLIA_256_CBC,
382     GNUTLS_CIPHER_3DES_CBC,
383   };
384   static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
385   static int protocol_priority[] = { 0, 0, 0, 0 };
386 #else
387 #define GNUTLS_CIPHERS "NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509"
388   const char* prioritylist;
389   const char *err = NULL;
390 #endif
391 #ifdef HAS_ALPN
392   int protocols_size = 2;
393   gnutls_datum_t protocols[2];
394 #endif
395
396   if(conn->ssl[sockindex].state == ssl_connection_complete)
397     /* to make us tolerant against being called more than once for the
398        same connection */
399     return CURLE_OK;
400
401   if(!gtls_inited)
402     Curl_gtls_init();
403
404   /* GnuTLS only supports SSLv3 and TLSv1 */
405   if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) {
406     failf(data, "GnuTLS does not support SSLv2");
407     return CURLE_SSL_CONNECT_ERROR;
408   }
409   else if(data->set.ssl.version == CURL_SSLVERSION_SSLv3)
410     sni = FALSE; /* SSLv3 has no SNI */
411
412   /* allocate a cred struct */
413   rc = gnutls_certificate_allocate_credentials(&conn->ssl[sockindex].cred);
414   if(rc != GNUTLS_E_SUCCESS) {
415     failf(data, "gnutls_cert_all_cred() failed: %s", gnutls_strerror(rc));
416     return CURLE_SSL_CONNECT_ERROR;
417   }
418
419 #ifdef USE_TLS_SRP
420   if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
421     infof(data, "Using TLS-SRP username: %s\n", data->set.ssl.username);
422
423     rc = gnutls_srp_allocate_client_credentials(
424            &conn->ssl[sockindex].srp_client_cred);
425     if(rc != GNUTLS_E_SUCCESS) {
426       failf(data, "gnutls_srp_allocate_client_cred() failed: %s",
427             gnutls_strerror(rc));
428       return CURLE_OUT_OF_MEMORY;
429     }
430
431     rc = gnutls_srp_set_client_credentials(conn->ssl[sockindex].
432                                            srp_client_cred,
433                                            data->set.ssl.username,
434                                            data->set.ssl.password);
435     if(rc != GNUTLS_E_SUCCESS) {
436       failf(data, "gnutls_srp_set_client_cred() failed: %s",
437             gnutls_strerror(rc));
438       return CURLE_BAD_FUNCTION_ARGUMENT;
439     }
440   }
441 #endif
442
443   if(data->set.ssl.CAfile) {
444     /* set the trusted CA cert bundle file */
445     gnutls_certificate_set_verify_flags(conn->ssl[sockindex].cred,
446                                         GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
447
448     rc = gnutls_certificate_set_x509_trust_file(conn->ssl[sockindex].cred,
449                                                 data->set.ssl.CAfile,
450                                                 GNUTLS_X509_FMT_PEM);
451     if(rc < 0) {
452       infof(data, "error reading ca cert file %s (%s)\n",
453             data->set.ssl.CAfile, gnutls_strerror(rc));
454       if(data->set.ssl.verifypeer)
455         return CURLE_SSL_CACERT_BADFILE;
456     }
457     else
458       infof(data, "found %d certificates in %s\n",
459             rc, data->set.ssl.CAfile);
460   }
461
462   if(data->set.ssl.CRLfile) {
463     /* set the CRL list file */
464     rc = gnutls_certificate_set_x509_crl_file(conn->ssl[sockindex].cred,
465                                               data->set.ssl.CRLfile,
466                                               GNUTLS_X509_FMT_PEM);
467     if(rc < 0) {
468       failf(data, "error reading crl file %s (%s)",
469             data->set.ssl.CRLfile, gnutls_strerror(rc));
470       return CURLE_SSL_CRL_BADFILE;
471     }
472     else
473       infof(data, "found %d CRL in %s\n",
474             rc, data->set.ssl.CRLfile);
475   }
476
477   /* Initialize TLS session as a client */
478   rc = gnutls_init(&conn->ssl[sockindex].session, GNUTLS_CLIENT);
479   if(rc != GNUTLS_E_SUCCESS) {
480     failf(data, "gnutls_init() failed: %d", rc);
481     return CURLE_SSL_CONNECT_ERROR;
482   }
483
484   /* convenient assign */
485   session = conn->ssl[sockindex].session;
486
487   if((0 == Curl_inet_pton(AF_INET, conn->host.name, &addr)) &&
488 #ifdef ENABLE_IPV6
489      (0 == Curl_inet_pton(AF_INET6, conn->host.name, &addr)) &&
490 #endif
491      sni &&
492      (gnutls_server_name_set(session, GNUTLS_NAME_DNS, conn->host.name,
493                              strlen(conn->host.name)) < 0))
494     infof(data, "WARNING: failed to configure server name indication (SNI) "
495           "TLS extension\n");
496
497   /* Use default priorities */
498   rc = gnutls_set_default_priority(session);
499   if(rc != GNUTLS_E_SUCCESS)
500     return CURLE_SSL_CONNECT_ERROR;
501
502 #ifndef USE_GNUTLS_PRIORITY_SET_DIRECT
503   rc = gnutls_cipher_set_priority(session, cipher_priority);
504   if(rc != GNUTLS_E_SUCCESS)
505     return CURLE_SSL_CONNECT_ERROR;
506
507   /* Sets the priority on the certificate types supported by gnutls. Priority
508    is higher for types specified before others. After specifying the types
509    you want, you must append a 0. */
510   rc = gnutls_certificate_type_set_priority(session, cert_type_priority);
511   if(rc != GNUTLS_E_SUCCESS)
512     return CURLE_SSL_CONNECT_ERROR;
513
514   if(data->set.ssl.cipher_list != NULL) {
515     failf(data, "can't pass a custom cipher list to older GnuTLS"
516           " versions");
517     return CURLE_SSL_CONNECT_ERROR;
518   }
519
520   switch (data->set.ssl.version) {
521     case CURL_SSLVERSION_SSLv3:
522       protocol_priority[0] = GNUTLS_SSL3;
523       break;
524     case CURL_SSLVERSION_DEFAULT:
525     case CURL_SSLVERSION_TLSv1:
526       protocol_priority[0] = GNUTLS_TLS1_0;
527       protocol_priority[1] = GNUTLS_TLS1_1;
528       protocol_priority[2] = GNUTLS_TLS1_2;
529       break;
530     case CURL_SSLVERSION_TLSv1_0:
531       protocol_priority[0] = GNUTLS_TLS1_0;
532       break;
533     case CURL_SSLVERSION_TLSv1_1:
534       protocol_priority[0] = GNUTLS_TLS1_1;
535       break;
536     case CURL_SSLVERSION_TLSv1_2:
537       protocol_priority[0] = GNUTLS_TLS1_2;
538     break;
539       case CURL_SSLVERSION_SSLv2:
540     default:
541       failf(data, "GnuTLS does not support SSLv2");
542       return CURLE_SSL_CONNECT_ERROR;
543       break;
544   }
545   rc = gnutls_protocol_set_priority(session, protocol_priority);
546   if(rc != GNUTLS_E_SUCCESS) {
547     failf(data, "Did you pass a valid GnuTLS cipher list?");
548     return CURLE_SSL_CONNECT_ERROR;
549   }
550
551 #else
552   switch (data->set.ssl.version) {
553     case CURL_SSLVERSION_SSLv3:
554       prioritylist = GNUTLS_CIPHERS ":-VERS-TLS-ALL:+VERS-SSL3.0";
555       sni = false;
556       break;
557     case CURL_SSLVERSION_DEFAULT:
558     case CURL_SSLVERSION_TLSv1:
559       prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:+SRP";
560       break;
561     case CURL_SSLVERSION_TLSv1_0:
562       prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
563                      "+VERS-TLS1.0:+SRP";
564       break;
565     case CURL_SSLVERSION_TLSv1_1:
566       prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
567                      "+VERS-TLS1.1:+SRP";
568       break;
569     case CURL_SSLVERSION_TLSv1_2:
570       prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
571                      "+VERS-TLS1.2:+SRP";
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_priority_set_direct(session, prioritylist, &err);
580   if(rc != GNUTLS_E_SUCCESS) {
581     failf(data, "Error %d setting GnuTLS cipher list starting with %s",
582           rc, err);
583     return CURLE_SSL_CONNECT_ERROR;
584   }
585 #endif
586
587 #ifdef HAS_ALPN
588   if(data->set.httpversion == CURL_HTTP_VERSION_2_0) {
589     if(data->set.ssl_enable_alpn) {
590       protocols[0].data = NGHTTP2_PROTO_VERSION_ID;
591       protocols[0].size = NGHTTP2_PROTO_VERSION_ID_LEN;
592       protocols[1].data = ALPN_HTTP_1_1;
593       protocols[1].size = ALPN_HTTP_1_1_LENGTH;
594       gnutls_alpn_set_protocols(session, protocols, protocols_size, 0);
595       infof(data, "ALPN, offering %s, %s\n", NGHTTP2_PROTO_VERSION_ID,
596             ALPN_HTTP_1_1);
597     }
598     else {
599       infof(data, "SSL, can't negotiate HTTP/2.0 without ALPN\n");
600     }
601   }
602 #endif
603
604   if(data->set.str[STRING_CERT]) {
605     if(gnutls_certificate_set_x509_key_file(
606          conn->ssl[sockindex].cred,
607          data->set.str[STRING_CERT],
608          data->set.str[STRING_KEY] ?
609          data->set.str[STRING_KEY] : data->set.str[STRING_CERT],
610          do_file_type(data->set.str[STRING_CERT_TYPE]) ) !=
611        GNUTLS_E_SUCCESS) {
612       failf(data, "error reading X.509 key or certificate file");
613       return CURLE_SSL_CONNECT_ERROR;
614     }
615   }
616
617 #ifdef USE_TLS_SRP
618   /* put the credentials to the current session */
619   if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
620     rc = gnutls_credentials_set(session, GNUTLS_CRD_SRP,
621                                 conn->ssl[sockindex].srp_client_cred);
622     if(rc != GNUTLS_E_SUCCESS)
623       failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc));
624   }
625   else
626 #endif
627     rc = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
628                                 conn->ssl[sockindex].cred);
629
630   /* set the connection handle (file descriptor for the socket) */
631   gnutls_transport_set_ptr(session,
632                            GNUTLS_INT_TO_POINTER_CAST(conn->sock[sockindex]));
633
634   /* register callback functions to send and receive data. */
635   gnutls_transport_set_push_function(session, Curl_gtls_push);
636   gnutls_transport_set_pull_function(session, Curl_gtls_pull);
637
638   /* lowat must be set to zero when using custom push and pull functions. */
639   gnutls_transport_set_lowat(session, 0);
640
641   /* This might be a reconnect, so we check for a session ID in the cache
642      to speed up things */
643
644   if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, &ssl_idsize)) {
645     /* we got a session id, use it! */
646     gnutls_session_set_data(session, ssl_sessionid, ssl_idsize);
647
648     /* Informational message */
649     infof (data, "SSL re-using session ID\n");
650   }
651
652   return CURLE_OK;
653 }
654
655 static Curl_recv gtls_recv;
656 static Curl_send gtls_send;
657
658 static CURLcode
659 gtls_connect_step3(struct connectdata *conn,
660                    int sockindex)
661 {
662   unsigned int cert_list_size;
663   const gnutls_datum_t *chainp;
664   unsigned int verify_status;
665   gnutls_x509_crt_t x509_cert,x509_issuer;
666   gnutls_datum_t issuerp;
667   char certbuf[256] = ""; /* big enough? */
668   size_t size;
669   unsigned int algo;
670   unsigned int bits;
671   time_t certclock;
672   const char *ptr;
673   struct SessionHandle *data = conn->data;
674   gnutls_session_t session = conn->ssl[sockindex].session;
675   int rc;
676   int incache;
677   void *ssl_sessionid;
678 #ifdef HAS_ALPN
679   gnutls_datum_t proto;
680 #endif
681   CURLcode result = CURLE_OK;
682
683   /* This function will return the peer's raw certificate (chain) as sent by
684      the peer. These certificates are in raw format (DER encoded for
685      X.509). In case of a X.509 then a certificate list may be present. The
686      first certificate in the list is the peer's certificate, following the
687      issuer's certificate, then the issuer's issuer etc. */
688
689   chainp = gnutls_certificate_get_peers(session, &cert_list_size);
690   if(!chainp) {
691     if(data->set.ssl.verifypeer ||
692        data->set.ssl.verifyhost ||
693        data->set.ssl.issuercert) {
694 #ifdef USE_TLS_SRP
695       if(data->set.ssl.authtype == CURL_TLSAUTH_SRP
696          && data->set.ssl.username != NULL
697          && !data->set.ssl.verifypeer
698          && gnutls_cipher_get(session)) {
699         /* no peer cert, but auth is ok if we have SRP user and cipher and no
700            peer verify */
701       }
702       else {
703 #endif
704         failf(data, "failed to get server cert");
705         return CURLE_PEER_FAILED_VERIFICATION;
706 #ifdef USE_TLS_SRP
707       }
708 #endif
709     }
710     infof(data, "\t common name: WARNING couldn't obtain\n");
711   }
712
713   if(data->set.ssl.verifypeer) {
714     /* This function will try to verify the peer's certificate and return its
715        status (trusted, invalid etc.). The value of status should be one or
716        more of the gnutls_certificate_status_t enumerated elements bitwise
717        or'd. To avoid denial of service attacks some default upper limits
718        regarding the certificate key size and chain size are set. To override
719        them use gnutls_certificate_set_verify_limits(). */
720
721     rc = gnutls_certificate_verify_peers2(session, &verify_status);
722     if(rc < 0) {
723       failf(data, "server cert verify failed: %d", rc);
724       return CURLE_SSL_CONNECT_ERROR;
725     }
726
727     /* verify_status is a bitmask of gnutls_certificate_status bits */
728     if(verify_status & GNUTLS_CERT_INVALID) {
729       if(data->set.ssl.verifypeer) {
730         failf(data, "server certificate verification failed. CAfile: %s "
731               "CRLfile: %s", data->set.ssl.CAfile?data->set.ssl.CAfile:"none",
732               data->set.ssl.CRLfile?data->set.ssl.CRLfile:"none");
733         return CURLE_SSL_CACERT;
734       }
735       else
736         infof(data, "\t server certificate verification FAILED\n");
737     }
738     else
739       infof(data, "\t server certificate verification OK\n");
740   }
741   else
742     infof(data, "\t server certificate verification SKIPPED\n");
743
744   /* initialize an X.509 certificate structure. */
745   gnutls_x509_crt_init(&x509_cert);
746
747   if(chainp)
748     /* convert the given DER or PEM encoded Certificate to the native
749        gnutls_x509_crt_t format */
750     gnutls_x509_crt_import(x509_cert, chainp, GNUTLS_X509_FMT_DER);
751
752   if(data->set.ssl.issuercert) {
753     gnutls_x509_crt_init(&x509_issuer);
754     issuerp = load_file(data->set.ssl.issuercert);
755     gnutls_x509_crt_import(x509_issuer, &issuerp, GNUTLS_X509_FMT_PEM);
756     rc = gnutls_x509_crt_check_issuer(x509_cert,x509_issuer);
757     unload_file(issuerp);
758     if(rc <= 0) {
759       failf(data, "server certificate issuer check failed (IssuerCert: %s)",
760             data->set.ssl.issuercert?data->set.ssl.issuercert:"none");
761       return CURLE_SSL_ISSUER_ERROR;
762     }
763     infof(data,"\t server certificate issuer check OK (Issuer Cert: %s)\n",
764           data->set.ssl.issuercert?data->set.ssl.issuercert:"none");
765   }
766
767   size=sizeof(certbuf);
768   rc = gnutls_x509_crt_get_dn_by_oid(x509_cert, GNUTLS_OID_X520_COMMON_NAME,
769                                      0, /* the first and only one */
770                                      FALSE,
771                                      certbuf,
772                                      &size);
773   if(rc) {
774     infof(data, "error fetching CN from cert:%s\n",
775           gnutls_strerror(rc));
776   }
777
778   /* This function will check if the given certificate's subject matches the
779      given hostname. This is a basic implementation of the matching described
780      in RFC2818 (HTTPS), which takes into account wildcards, and the subject
781      alternative name PKIX extension. Returns non zero on success, and zero on
782      failure. */
783   rc = gnutls_x509_crt_check_hostname(x509_cert, conn->host.name);
784
785   if(!rc) {
786     if(data->set.ssl.verifyhost) {
787       failf(data, "SSL: certificate subject name (%s) does not match "
788             "target host name '%s'", certbuf, conn->host.dispname);
789       gnutls_x509_crt_deinit(x509_cert);
790       return CURLE_PEER_FAILED_VERIFICATION;
791     }
792     else
793       infof(data, "\t common name: %s (does not match '%s')\n",
794             certbuf, conn->host.dispname);
795   }
796   else
797     infof(data, "\t common name: %s (matched)\n", certbuf);
798
799   /* Check for time-based validity */
800   certclock = gnutls_x509_crt_get_expiration_time(x509_cert);
801
802   if(certclock == (time_t)-1) {
803     if(data->set.ssl.verifypeer) {
804       failf(data, "server cert expiration date verify failed");
805       return CURLE_SSL_CONNECT_ERROR;
806     }
807     else
808       infof(data, "\t server certificate expiration date verify FAILED\n");
809   }
810   else {
811     if(certclock < time(NULL)) {
812       if(data->set.ssl.verifypeer) {
813         failf(data, "server certificate expiration date has passed.");
814         return CURLE_PEER_FAILED_VERIFICATION;
815       }
816       else
817         infof(data, "\t server certificate expiration date FAILED\n");
818     }
819     else
820       infof(data, "\t server certificate expiration date OK\n");
821   }
822
823   certclock = gnutls_x509_crt_get_activation_time(x509_cert);
824
825   if(certclock == (time_t)-1) {
826     if(data->set.ssl.verifypeer) {
827       failf(data, "server cert activation date verify failed");
828       return CURLE_SSL_CONNECT_ERROR;
829     }
830     else
831       infof(data, "\t server certificate activation date verify FAILED\n");
832   }
833   else {
834     if(certclock > time(NULL)) {
835       if(data->set.ssl.verifypeer) {
836         failf(data, "server certificate not activated yet.");
837         return CURLE_PEER_FAILED_VERIFICATION;
838       }
839       else
840         infof(data, "\t server certificate activation date FAILED\n");
841     }
842     else
843       infof(data, "\t server certificate activation date OK\n");
844   }
845
846   /* Show:
847
848   - ciphers used
849   - subject
850   - start date
851   - expire date
852   - common name
853   - issuer
854
855   */
856
857   /* public key algorithm's parameters */
858   algo = gnutls_x509_crt_get_pk_algorithm(x509_cert, &bits);
859   infof(data, "\t certificate public key: %s\n",
860         gnutls_pk_algorithm_get_name(algo));
861
862   /* version of the X.509 certificate. */
863   infof(data, "\t certificate version: #%d\n",
864         gnutls_x509_crt_get_version(x509_cert));
865
866
867   size = sizeof(certbuf);
868   gnutls_x509_crt_get_dn(x509_cert, certbuf, &size);
869   infof(data, "\t subject: %s\n", certbuf);
870
871   certclock = gnutls_x509_crt_get_activation_time(x509_cert);
872   showtime(data, "start date", certclock);
873
874   certclock = gnutls_x509_crt_get_expiration_time(x509_cert);
875   showtime(data, "expire date", certclock);
876
877   size = sizeof(certbuf);
878   gnutls_x509_crt_get_issuer_dn(x509_cert, certbuf, &size);
879   infof(data, "\t issuer: %s\n", certbuf);
880
881   gnutls_x509_crt_deinit(x509_cert);
882
883   /* compression algorithm (if any) */
884   ptr = gnutls_compression_get_name(gnutls_compression_get(session));
885   /* the *_get_name() says "NULL" if GNUTLS_COMP_NULL is returned */
886   infof(data, "\t compression: %s\n", ptr);
887
888   /* the name of the cipher used. ie 3DES. */
889   ptr = gnutls_cipher_get_name(gnutls_cipher_get(session));
890   infof(data, "\t cipher: %s\n", ptr);
891
892   /* the MAC algorithms name. ie SHA1 */
893   ptr = gnutls_mac_get_name(gnutls_mac_get(session));
894   infof(data, "\t MAC: %s\n", ptr);
895
896 #ifdef HAS_ALPN
897   if(data->set.ssl_enable_alpn) {
898     rc = gnutls_alpn_get_selected_protocol(session, &proto);
899     if(rc == 0) {
900       infof(data, "ALPN, server accepted to use %.*s\n", proto.size,
901           proto.data);
902
903       if(proto.size == NGHTTP2_PROTO_VERSION_ID_LEN &&
904         memcmp(NGHTTP2_PROTO_VERSION_ID, proto.data,
905         NGHTTP2_PROTO_VERSION_ID_LEN) == 0) {
906         conn->negnpn = NPN_HTTP2;
907       }
908       else if(proto.size == ALPN_HTTP_1_1_LENGTH && memcmp(ALPN_HTTP_1_1,
909           proto.data, ALPN_HTTP_1_1_LENGTH) == 0) {
910         conn->negnpn = NPN_HTTP1_1;
911       }
912     }
913     else {
914       infof(data, "ALPN, server did not agree to a protocol\n");
915     }
916   }
917 #endif
918
919   conn->ssl[sockindex].state = ssl_connection_complete;
920   conn->recv[sockindex] = gtls_recv;
921   conn->send[sockindex] = gtls_send;
922
923   {
924     /* we always unconditionally get the session id here, as even if we
925        already got it from the cache and asked to use it in the connection, it
926        might've been rejected and then a new one is in use now and we need to
927        detect that. */
928     void *connect_sessionid;
929     size_t connect_idsize = 0;
930
931     /* get the session ID data size */
932     gnutls_session_get_data(session, NULL, &connect_idsize);
933     connect_sessionid = malloc(connect_idsize); /* get a buffer for it */
934
935     if(connect_sessionid) {
936       /* extract session ID to the allocated buffer */
937       gnutls_session_get_data(session, connect_sessionid, &connect_idsize);
938
939       incache = !(Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL));
940       if(incache) {
941         /* there was one before in the cache, so instead of risking that the
942            previous one was rejected, we just kill that and store the new */
943         Curl_ssl_delsessionid(conn, ssl_sessionid);
944       }
945
946       /* store this session id */
947       result = Curl_ssl_addsessionid(conn, connect_sessionid, connect_idsize);
948       if(result) {
949         free(connect_sessionid);
950         result = CURLE_OUT_OF_MEMORY;
951       }
952     }
953     else
954       result = CURLE_OUT_OF_MEMORY;
955   }
956
957   return result;
958 }
959
960
961 /*
962  * This function is called after the TCP connect has completed. Setup the TLS
963  * layer and do all necessary magic.
964  */
965 /* We use connssl->connecting_state to keep track of the connection status;
966    there are three states: 'ssl_connect_1' (not started yet or complete),
967    'ssl_connect_2_reading' (waiting for data from server), and
968    'ssl_connect_2_writing' (waiting to be able to write).
969  */
970 static CURLcode
971 gtls_connect_common(struct connectdata *conn,
972                     int sockindex,
973                     bool nonblocking,
974                     bool *done)
975 {
976   int rc;
977   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
978
979   /* Initiate the connection, if not already done */
980   if(ssl_connect_1==connssl->connecting_state) {
981     rc = gtls_connect_step1 (conn, sockindex);
982     if(rc)
983       return rc;
984   }
985
986   rc = handshake(conn, sockindex, TRUE, nonblocking);
987   if(rc)
988     /* handshake() sets its own error message with failf() */
989     return rc;
990
991   /* Finish connecting once the handshake is done */
992   if(ssl_connect_1==connssl->connecting_state) {
993     rc = gtls_connect_step3(conn, sockindex);
994     if(rc)
995       return rc;
996   }
997
998   *done = ssl_connect_1==connssl->connecting_state;
999
1000   return CURLE_OK;
1001 }
1002
1003 CURLcode
1004 Curl_gtls_connect_nonblocking(struct connectdata *conn,
1005                               int sockindex,
1006                               bool *done)
1007 {
1008   return gtls_connect_common(conn, sockindex, TRUE, done);
1009 }
1010
1011 CURLcode
1012 Curl_gtls_connect(struct connectdata *conn,
1013                   int sockindex)
1014
1015 {
1016   CURLcode retcode;
1017   bool done = FALSE;
1018
1019   retcode = gtls_connect_common(conn, sockindex, FALSE, &done);
1020   if(retcode)
1021     return retcode;
1022
1023   DEBUGASSERT(done);
1024
1025   return CURLE_OK;
1026 }
1027
1028 static ssize_t gtls_send(struct connectdata *conn,
1029                          int sockindex,
1030                          const void *mem,
1031                          size_t len,
1032                          CURLcode *curlcode)
1033 {
1034   ssize_t rc = gnutls_record_send(conn->ssl[sockindex].session, mem, len);
1035
1036   if(rc < 0 ) {
1037     *curlcode = (rc == GNUTLS_E_AGAIN)
1038       ? CURLE_AGAIN
1039       : CURLE_SEND_ERROR;
1040
1041     rc = -1;
1042   }
1043
1044   return rc;
1045 }
1046
1047 void Curl_gtls_close_all(struct SessionHandle *data)
1048 {
1049   /* FIX: make the OpenSSL code more generic and use parts of it here */
1050   (void)data;
1051 }
1052
1053 static void close_one(struct connectdata *conn,
1054                       int idx)
1055 {
1056   if(conn->ssl[idx].session) {
1057     gnutls_bye(conn->ssl[idx].session, GNUTLS_SHUT_RDWR);
1058     gnutls_deinit(conn->ssl[idx].session);
1059     conn->ssl[idx].session = NULL;
1060   }
1061   if(conn->ssl[idx].cred) {
1062     gnutls_certificate_free_credentials(conn->ssl[idx].cred);
1063     conn->ssl[idx].cred = NULL;
1064   }
1065 #ifdef USE_TLS_SRP
1066   if(conn->ssl[idx].srp_client_cred) {
1067     gnutls_srp_free_client_credentials(conn->ssl[idx].srp_client_cred);
1068     conn->ssl[idx].srp_client_cred = NULL;
1069   }
1070 #endif
1071 }
1072
1073 void Curl_gtls_close(struct connectdata *conn, int sockindex)
1074 {
1075   close_one(conn, sockindex);
1076 }
1077
1078 /*
1079  * This function is called to shut down the SSL layer but keep the
1080  * socket open (CCC - Clear Command Channel)
1081  */
1082 int Curl_gtls_shutdown(struct connectdata *conn, int sockindex)
1083 {
1084   ssize_t result;
1085   int retval = 0;
1086   struct SessionHandle *data = conn->data;
1087   int done = 0;
1088   char buf[120];
1089
1090   /* This has only been tested on the proftpd server, and the mod_tls code
1091      sends a close notify alert without waiting for a close notify alert in
1092      response. Thus we wait for a close notify alert from the server, but
1093      we do not send one. Let's hope other servers do the same... */
1094
1095   if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
1096       gnutls_bye(conn->ssl[sockindex].session, GNUTLS_SHUT_WR);
1097
1098   if(conn->ssl[sockindex].session) {
1099     while(!done) {
1100       int what = Curl_socket_ready(conn->sock[sockindex],
1101                                    CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
1102       if(what > 0) {
1103         /* Something to read, let's do it and hope that it is the close
1104            notify alert from the server */
1105         result = gnutls_record_recv(conn->ssl[sockindex].session,
1106                                     buf, sizeof(buf));
1107         switch(result) {
1108         case 0:
1109           /* This is the expected response. There was no data but only
1110              the close notify alert */
1111           done = 1;
1112           break;
1113         case GNUTLS_E_AGAIN:
1114         case GNUTLS_E_INTERRUPTED:
1115           infof(data, "GNUTLS_E_AGAIN || GNUTLS_E_INTERRUPTED\n");
1116           break;
1117         default:
1118           retval = -1;
1119           done = 1;
1120           break;
1121         }
1122       }
1123       else if(0 == what) {
1124         /* timeout */
1125         failf(data, "SSL shutdown timeout");
1126         done = 1;
1127         break;
1128       }
1129       else {
1130         /* anything that gets here is fatally bad */
1131         failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
1132         retval = -1;
1133         done = 1;
1134       }
1135     }
1136     gnutls_deinit(conn->ssl[sockindex].session);
1137   }
1138   gnutls_certificate_free_credentials(conn->ssl[sockindex].cred);
1139
1140 #ifdef USE_TLS_SRP
1141   if(data->set.ssl.authtype == CURL_TLSAUTH_SRP
1142      && data->set.ssl.username != NULL)
1143     gnutls_srp_free_client_credentials(conn->ssl[sockindex].srp_client_cred);
1144 #endif
1145
1146   conn->ssl[sockindex].cred = NULL;
1147   conn->ssl[sockindex].session = NULL;
1148
1149   return retval;
1150 }
1151
1152 static ssize_t gtls_recv(struct connectdata *conn, /* connection data */
1153                          int num,                  /* socketindex */
1154                          char *buf,                /* store read data here */
1155                          size_t buffersize,        /* max amount to read */
1156                          CURLcode *curlcode)
1157 {
1158   ssize_t ret;
1159
1160   ret = gnutls_record_recv(conn->ssl[num].session, buf, buffersize);
1161   if((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED)) {
1162     *curlcode = CURLE_AGAIN;
1163     return -1;
1164   }
1165
1166   if(ret == GNUTLS_E_REHANDSHAKE) {
1167     /* BLOCKING call, this is bad but a work-around for now. Fixing this "the
1168        proper way" takes a whole lot of work. */
1169     CURLcode rc = handshake(conn, num, FALSE, FALSE);
1170     if(rc)
1171       /* handshake() writes error message on its own */
1172       *curlcode = rc;
1173     else
1174       *curlcode = CURLE_AGAIN; /* then return as if this was a wouldblock */
1175     return -1;
1176   }
1177
1178   if(ret < 0) {
1179     failf(conn->data, "GnuTLS recv error (%d): %s",
1180           (int)ret, gnutls_strerror((int)ret));
1181     *curlcode = CURLE_RECV_ERROR;
1182     return -1;
1183   }
1184
1185   return ret;
1186 }
1187
1188 void Curl_gtls_session_free(void *ptr)
1189 {
1190   free(ptr);
1191 }
1192
1193 size_t Curl_gtls_version(char *buffer, size_t size)
1194 {
1195   return snprintf(buffer, size, "GnuTLS/%s", gnutls_check_version(NULL));
1196 }
1197
1198 int Curl_gtls_seed(struct SessionHandle *data)
1199 {
1200   /* we have the "SSL is seeded" boolean static to prevent multiple
1201      time-consuming seedings in vain */
1202   static bool ssl_seeded = FALSE;
1203
1204   /* Quickly add a bit of entropy */
1205 #ifndef USE_GNUTLS_NETTLE
1206   gcry_fast_random_poll();
1207 #endif
1208
1209   if(!ssl_seeded || data->set.str[STRING_SSL_RANDOM_FILE] ||
1210      data->set.str[STRING_SSL_EGDSOCKET]) {
1211
1212     /* TODO: to a good job seeding the RNG
1213        This may involve the gcry_control function and these options:
1214        GCRYCTL_SET_RANDOM_SEED_FILE
1215        GCRYCTL_SET_RNDEGD_SOCKET
1216     */
1217     ssl_seeded = TRUE;
1218   }
1219   return 0;
1220 }
1221
1222 void Curl_gtls_random(struct SessionHandle *data,
1223                       unsigned char *entropy,
1224                       size_t length)
1225 {
1226 #if defined(USE_GNUTLS_NETTLE)
1227   (void)data;
1228   gnutls_rnd(GNUTLS_RND_RANDOM, entropy, length);
1229 #elif defined(USE_GNUTLS)
1230   Curl_gtls_seed(data); /* Initiate the seed if not already done */
1231   gcry_randomize(entropy, length, GCRY_STRONG_RANDOM);
1232 #endif
1233 }
1234
1235 void Curl_gtls_md5sum(unsigned char *tmp, /* input */
1236                       size_t tmplen,
1237                       unsigned char *md5sum, /* output */
1238                       size_t md5len)
1239 {
1240 #if defined(USE_GNUTLS_NETTLE)
1241   struct md5_ctx MD5pw;
1242   md5_init(&MD5pw);
1243   md5_update(&MD5pw, (unsigned int)tmplen, tmp);
1244   md5_digest(&MD5pw, (unsigned int)md5len, md5sum);
1245 #elif defined(USE_GNUTLS)
1246   gcry_md_hd_t MD5pw;
1247   gcry_md_open(&MD5pw, GCRY_MD_MD5, 0);
1248   gcry_md_write(MD5pw, tmp, tmplen);
1249   memcpy(md5sum, gcry_md_read (MD5pw, 0), md5len);
1250   gcry_md_close(MD5pw);
1251 #endif
1252 }
1253
1254 #endif /* USE_GNUTLS */