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