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