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