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