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
408 if(connssl->state == ssl_connection_complete)
409 /* to make us tolerant against being called more than once for the
410 same connection */
411 return CURLE_OK;
412
413 if(!gtls_inited)
414 gtls_init();
415
416 /* Initialize certverifyresult to OK */
417 *certverifyresult = 0;
418
419 if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) {
420 failf(data, "GnuTLS does not support SSLv2");
421 return CURLE_SSL_CONNECT_ERROR;
422 }
423 else if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv3)
424 sni = FALSE; /* SSLv3 has no SNI */
425
426 /* allocate a cred struct */
427 rc = gnutls_certificate_allocate_credentials(&backend->cred);
428 if(rc != GNUTLS_E_SUCCESS) {
429 failf(data, "gnutls_cert_all_cred() failed: %s", gnutls_strerror(rc));
430 return CURLE_SSL_CONNECT_ERROR;
431 }
432
433 #ifdef HAVE_GNUTLS_SRP
434 if(SSL_SET_OPTION(primary.authtype) == CURL_TLSAUTH_SRP) {
435 infof(data, "Using TLS-SRP username: %s",
436 SSL_SET_OPTION(primary.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(primary.username),
448 SSL_SET_OPTION(primary.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(primary.CRLfile)) {
505 /* set the CRL list file */
506 rc = gnutls_certificate_set_x509_crl_file(backend->cred,
507 SSL_SET_OPTION(primary.CRLfile),
508 GNUTLS_X509_FMT_PEM);
509 if(rc < 0) {
510 failf(data, "error reading crl file %s (%s)",
511 SSL_SET_OPTION(primary.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(primary.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 switch(SSL_CONN_CONFIG(version)) {
562 case CURL_SSLVERSION_TLSv1_3:
563 if(!tls13support) {
564 failf(data, "This GnuTLS installation does not support TLS 1.3");
565 return CURLE_SSL_CONNECT_ERROR;
566 }
567 /* FALLTHROUGH */
568 case CURL_SSLVERSION_DEFAULT:
569 case CURL_SSLVERSION_TLSv1:
570 case CURL_SSLVERSION_TLSv1_0:
571 case CURL_SSLVERSION_TLSv1_1:
572 case CURL_SSLVERSION_TLSv1_2: {
573 CURLcode result = set_ssl_version_min_max(data, &prioritylist,
574 tls13support);
575 if(result)
576 return result;
577 break;
578 }
579 case CURL_SSLVERSION_SSLv2:
580 case CURL_SSLVERSION_SSLv3:
581 default:
582 failf(data, "GnuTLS does not support SSLv2 or SSLv3");
583 return CURLE_SSL_CONNECT_ERROR;
584 }
585
586 #ifdef HAVE_GNUTLS_SRP
587 /* Only add SRP to the cipher list if SRP is requested. Otherwise
588 * GnuTLS will disable TLS 1.3 support. */
589 if(SSL_SET_OPTION(primary.authtype) == CURL_TLSAUTH_SRP) {
590 size_t len = strlen(prioritylist);
591
592 char *prioritysrp = malloc(len + sizeof(GNUTLS_SRP) + 1);
593 if(!prioritysrp)
594 return CURLE_OUT_OF_MEMORY;
595 strcpy(prioritysrp, prioritylist);
596 strcpy(prioritysrp + len, ":" GNUTLS_SRP);
597 rc = gnutls_priority_set_direct(session, prioritysrp, &err);
598 free(prioritysrp);
599
600 if((rc == GNUTLS_E_INVALID_REQUEST) && err) {
601 infof(data, "This GnuTLS does not support SRP");
602 }
603 }
604 else {
605 #endif
606 infof(data, "GnuTLS ciphers: %s", prioritylist);
607 rc = gnutls_priority_set_direct(session, prioritylist, &err);
608 #ifdef HAVE_GNUTLS_SRP
609 }
610 #endif
611
612 if(rc != GNUTLS_E_SUCCESS) {
613 failf(data, "Error %d setting GnuTLS cipher list starting with %s",
614 rc, err);
615 return CURLE_SSL_CONNECT_ERROR;
616 }
617
618 if(conn->bits.tls_enable_alpn) {
619 int cur = 0;
620 gnutls_datum_t protocols[2];
621
622 #ifdef USE_HTTP2
623 if(data->state.httpwant >= CURL_HTTP_VERSION_2
624 #ifndef CURL_DISABLE_PROXY
625 && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)
626 #endif
627 ) {
628 protocols[cur].data = (unsigned char *)ALPN_H2;
629 protocols[cur].size = ALPN_H2_LENGTH;
630 cur++;
631 infof(data, "ALPN, offering %.*s", ALPN_H2_LENGTH, ALPN_H2);
632 }
633 #endif
634
635 protocols[cur].data = (unsigned char *)ALPN_HTTP_1_1;
636 protocols[cur].size = ALPN_HTTP_1_1_LENGTH;
637 cur++;
638 infof(data, "ALPN, offering %s", ALPN_HTTP_1_1);
639
640 gnutls_alpn_set_protocols(session, protocols, cur, 0);
641 }
642
643 if(SSL_SET_OPTION(primary.clientcert)) {
644 if(SSL_SET_OPTION(key_passwd)) {
645 const unsigned int supported_key_encryption_algorithms =
646 GNUTLS_PKCS_USE_PKCS12_3DES | GNUTLS_PKCS_USE_PKCS12_ARCFOUR |
647 GNUTLS_PKCS_USE_PKCS12_RC2_40 | GNUTLS_PKCS_USE_PBES2_3DES |
648 GNUTLS_PKCS_USE_PBES2_AES_128 | GNUTLS_PKCS_USE_PBES2_AES_192 |
649 GNUTLS_PKCS_USE_PBES2_AES_256;
650 rc = gnutls_certificate_set_x509_key_file2(
651 backend->cred,
652 SSL_SET_OPTION(primary.clientcert),
653 SSL_SET_OPTION(key) ?
654 SSL_SET_OPTION(key) : SSL_SET_OPTION(primary.clientcert),
655 do_file_type(SSL_SET_OPTION(cert_type)),
656 SSL_SET_OPTION(key_passwd),
657 supported_key_encryption_algorithms);
658 if(rc != GNUTLS_E_SUCCESS) {
659 failf(data,
660 "error reading X.509 potentially-encrypted key file: %s",
661 gnutls_strerror(rc));
662 return CURLE_SSL_CONNECT_ERROR;
663 }
664 }
665 else {
666 if(gnutls_certificate_set_x509_key_file(
667 backend->cred,
668 SSL_SET_OPTION(primary.clientcert),
669 SSL_SET_OPTION(key) ?
670 SSL_SET_OPTION(key) : SSL_SET_OPTION(primary.clientcert),
671 do_file_type(SSL_SET_OPTION(cert_type)) ) !=
672 GNUTLS_E_SUCCESS) {
673 failf(data, "error reading X.509 key or certificate file");
674 return CURLE_SSL_CONNECT_ERROR;
675 }
676 }
677 }
678
679 #ifdef HAVE_GNUTLS_SRP
680 /* put the credentials to the current session */
681 if(SSL_SET_OPTION(primary.authtype) == CURL_TLSAUTH_SRP) {
682 rc = gnutls_credentials_set(session, GNUTLS_CRD_SRP,
683 backend->srp_client_cred);
684 if(rc != GNUTLS_E_SUCCESS) {
685 failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc));
686 return CURLE_SSL_CONNECT_ERROR;
687 }
688 }
689 else
690 #endif
691 {
692 rc = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
693 backend->cred);
694 if(rc != GNUTLS_E_SUCCESS) {
695 failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc));
696 return CURLE_SSL_CONNECT_ERROR;
697 }
698 }
699
700 #ifndef CURL_DISABLE_PROXY
701 if(conn->proxy_ssl[sockindex].use) {
702 transport_ptr = conn->proxy_ssl[sockindex].backend->session;
703 gnutls_transport_push = gtls_push_ssl;
704 gnutls_transport_pull = gtls_pull_ssl;
705 }
706 else
707 #endif
708 {
709 /* file descriptor for the socket */
710 transport_ptr = &conn->sock[sockindex];
711 gnutls_transport_push = gtls_push;
712 gnutls_transport_pull = gtls_pull;
713 }
714
715 /* set the connection handle */
716 gnutls_transport_set_ptr(session, transport_ptr);
717
718 /* register callback functions to send and receive data. */
719 gnutls_transport_set_push_function(session, gnutls_transport_push);
720 gnutls_transport_set_pull_function(session, gnutls_transport_pull);
721
722 if(SSL_CONN_CONFIG(verifystatus)) {
723 rc = gnutls_ocsp_status_request_enable_client(session, NULL, 0, NULL);
724 if(rc != GNUTLS_E_SUCCESS) {
725 failf(data, "gnutls_ocsp_status_request_enable_client() failed: %d", rc);
726 return CURLE_SSL_CONNECT_ERROR;
727 }
728 }
729
730 /* This might be a reconnect, so we check for a session ID in the cache
731 to speed up things */
732 if(SSL_SET_OPTION(primary.sessionid)) {
733 void *ssl_sessionid;
734 size_t ssl_idsize;
735
736 Curl_ssl_sessionid_lock(data);
737 if(!Curl_ssl_getsessionid(data, conn,
738 SSL_IS_PROXY() ? TRUE : FALSE,
739 &ssl_sessionid, &ssl_idsize, sockindex)) {
740 /* we got a session id, use it! */
741 gnutls_session_set_data(session, ssl_sessionid, ssl_idsize);
742
743 /* Informational message */
744 infof(data, "SSL re-using session ID");
745 }
746 Curl_ssl_sessionid_unlock(data);
747 }
748
749 return CURLE_OK;
750 }
751
pkp_pin_peer_pubkey(struct Curl_easy * data,gnutls_x509_crt_t cert,const char * pinnedpubkey)752 static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
753 gnutls_x509_crt_t cert,
754 const char *pinnedpubkey)
755 {
756 /* Scratch */
757 size_t len1 = 0, len2 = 0;
758 unsigned char *buff1 = NULL;
759
760 gnutls_pubkey_t key = NULL;
761
762 /* Result is returned to caller */
763 CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
764
765 /* if a path wasn't specified, don't pin */
766 if(NULL == pinnedpubkey)
767 return CURLE_OK;
768
769 if(NULL == cert)
770 return result;
771
772 do {
773 int ret;
774
775 /* Begin Gyrations to get the public key */
776 gnutls_pubkey_init(&key);
777
778 ret = gnutls_pubkey_import_x509(key, cert, 0);
779 if(ret < 0)
780 break; /* failed */
781
782 ret = gnutls_pubkey_export(key, GNUTLS_X509_FMT_DER, NULL, &len1);
783 if(ret != GNUTLS_E_SHORT_MEMORY_BUFFER || len1 == 0)
784 break; /* failed */
785
786 buff1 = malloc(len1);
787 if(NULL == buff1)
788 break; /* failed */
789
790 len2 = len1;
791
792 ret = gnutls_pubkey_export(key, GNUTLS_X509_FMT_DER, buff1, &len2);
793 if(ret < 0 || len1 != len2)
794 break; /* failed */
795
796 /* End Gyrations */
797
798 /* The one good exit point */
799 result = Curl_pin_peer_pubkey(data, pinnedpubkey, buff1, len1);
800 } while(0);
801
802 if(NULL != key)
803 gnutls_pubkey_deinit(key);
804
805 Curl_safefree(buff1);
806
807 return result;
808 }
809
810 static Curl_recv gtls_recv;
811 static Curl_send gtls_send;
812
813 static CURLcode
gtls_connect_step3(struct Curl_easy * data,struct connectdata * conn,int sockindex)814 gtls_connect_step3(struct Curl_easy *data,
815 struct connectdata *conn,
816 int sockindex)
817 {
818 unsigned int cert_list_size;
819 const gnutls_datum_t *chainp;
820 unsigned int verify_status = 0;
821 gnutls_x509_crt_t x509_cert, x509_issuer;
822 gnutls_datum_t issuerp;
823 gnutls_datum_t certfields;
824 char certname[65] = ""; /* limited to 64 chars by ASN.1 */
825 size_t size;
826 time_t certclock;
827 const char *ptr;
828 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
829 struct ssl_backend_data *backend = connssl->backend;
830 gnutls_session_t session = backend->session;
831 int rc;
832 gnutls_datum_t proto;
833 CURLcode result = CURLE_OK;
834 #ifndef CURL_DISABLE_VERBOSE_STRINGS
835 unsigned int algo;
836 unsigned int bits;
837 gnutls_protocol_t version = gnutls_protocol_get_version(session);
838 #endif
839 const char * const hostname = SSL_HOST_NAME();
840 long * const certverifyresult = &SSL_SET_OPTION_LVALUE(certverifyresult);
841
842 /* the name of the cipher suite used, e.g. ECDHE_RSA_AES_256_GCM_SHA384. */
843 ptr = gnutls_cipher_suite_get_name(gnutls_kx_get(session),
844 gnutls_cipher_get(session),
845 gnutls_mac_get(session));
846
847 infof(data, "SSL connection using %s / %s",
848 gnutls_protocol_get_name(version), ptr);
849
850 /* This function will return the peer's raw certificate (chain) as sent by
851 the peer. These certificates are in raw format (DER encoded for
852 X.509). In case of a X.509 then a certificate list may be present. The
853 first certificate in the list is the peer's certificate, following the
854 issuer's certificate, then the issuer's issuer etc. */
855
856 chainp = gnutls_certificate_get_peers(session, &cert_list_size);
857 if(!chainp) {
858 if(SSL_CONN_CONFIG(verifypeer) ||
859 SSL_CONN_CONFIG(verifyhost) ||
860 SSL_CONN_CONFIG(issuercert)) {
861 #ifdef HAVE_GNUTLS_SRP
862 if(SSL_SET_OPTION(primary.authtype) == CURL_TLSAUTH_SRP
863 && SSL_SET_OPTION(primary.username)
864 && !SSL_CONN_CONFIG(verifypeer)
865 && gnutls_cipher_get(session)) {
866 /* no peer cert, but auth is ok if we have SRP user and cipher and no
867 peer verify */
868 }
869 else {
870 #endif
871 failf(data, "failed to get server cert");
872 *certverifyresult = GNUTLS_E_NO_CERTIFICATE_FOUND;
873 return CURLE_PEER_FAILED_VERIFICATION;
874 #ifdef HAVE_GNUTLS_SRP
875 }
876 #endif
877 }
878 infof(data, " common name: WARNING couldn't obtain");
879 }
880
881 if(data->set.ssl.certinfo && chainp) {
882 unsigned int i;
883
884 result = Curl_ssl_init_certinfo(data, cert_list_size);
885 if(result)
886 return result;
887
888 for(i = 0; i < cert_list_size; i++) {
889 const char *beg = (const char *) chainp[i].data;
890 const char *end = beg + chainp[i].size;
891
892 result = Curl_extract_certinfo(data, i, beg, end);
893 if(result)
894 return result;
895 }
896 }
897
898 if(SSL_CONN_CONFIG(verifypeer)) {
899 /* This function will try to verify the peer's certificate and return its
900 status (trusted, invalid etc.). The value of status should be one or
901 more of the gnutls_certificate_status_t enumerated elements bitwise
902 or'd. To avoid denial of service attacks some default upper limits
903 regarding the certificate key size and chain size are set. To override
904 them use gnutls_certificate_set_verify_limits(). */
905
906 rc = gnutls_certificate_verify_peers2(session, &verify_status);
907 if(rc < 0) {
908 failf(data, "server cert verify failed: %d", rc);
909 *certverifyresult = rc;
910 return CURLE_SSL_CONNECT_ERROR;
911 }
912
913 *certverifyresult = verify_status;
914
915 /* verify_status is a bitmask of gnutls_certificate_status bits */
916 if(verify_status & GNUTLS_CERT_INVALID) {
917 if(SSL_CONN_CONFIG(verifypeer)) {
918 failf(data, "server certificate verification failed. CAfile: %s "
919 "CRLfile: %s", SSL_CONN_CONFIG(CAfile) ? SSL_CONN_CONFIG(CAfile):
920 "none",
921 SSL_SET_OPTION(primary.CRLfile) ?
922 SSL_SET_OPTION(primary.CRLfile) : "none");
923 return CURLE_PEER_FAILED_VERIFICATION;
924 }
925 else
926 infof(data, " server certificate verification FAILED");
927 }
928 else
929 infof(data, " server certificate verification OK");
930 }
931 else
932 infof(data, " server certificate verification SKIPPED");
933
934 if(SSL_CONN_CONFIG(verifystatus)) {
935 if(gnutls_ocsp_status_request_is_checked(session, 0) == 0) {
936 gnutls_datum_t status_request;
937 gnutls_ocsp_resp_t ocsp_resp;
938
939 gnutls_ocsp_cert_status_t status;
940 gnutls_x509_crl_reason_t reason;
941
942 rc = gnutls_ocsp_status_request_get(session, &status_request);
943
944 infof(data, " server certificate status verification FAILED");
945
946 if(rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
947 failf(data, "No OCSP response received");
948 return CURLE_SSL_INVALIDCERTSTATUS;
949 }
950
951 if(rc < 0) {
952 failf(data, "Invalid OCSP response received");
953 return CURLE_SSL_INVALIDCERTSTATUS;
954 }
955
956 gnutls_ocsp_resp_init(&ocsp_resp);
957
958 rc = gnutls_ocsp_resp_import(ocsp_resp, &status_request);
959 if(rc < 0) {
960 failf(data, "Invalid OCSP response received");
961 return CURLE_SSL_INVALIDCERTSTATUS;
962 }
963
964 (void)gnutls_ocsp_resp_get_single(ocsp_resp, 0, NULL, NULL, NULL, NULL,
965 &status, NULL, NULL, NULL, &reason);
966
967 switch(status) {
968 case GNUTLS_OCSP_CERT_GOOD:
969 break;
970
971 case GNUTLS_OCSP_CERT_REVOKED: {
972 const char *crl_reason;
973
974 switch(reason) {
975 default:
976 case GNUTLS_X509_CRLREASON_UNSPECIFIED:
977 crl_reason = "unspecified reason";
978 break;
979
980 case GNUTLS_X509_CRLREASON_KEYCOMPROMISE:
981 crl_reason = "private key compromised";
982 break;
983
984 case GNUTLS_X509_CRLREASON_CACOMPROMISE:
985 crl_reason = "CA compromised";
986 break;
987
988 case GNUTLS_X509_CRLREASON_AFFILIATIONCHANGED:
989 crl_reason = "affiliation has changed";
990 break;
991
992 case GNUTLS_X509_CRLREASON_SUPERSEDED:
993 crl_reason = "certificate superseded";
994 break;
995
996 case GNUTLS_X509_CRLREASON_CESSATIONOFOPERATION:
997 crl_reason = "operation has ceased";
998 break;
999
1000 case GNUTLS_X509_CRLREASON_CERTIFICATEHOLD:
1001 crl_reason = "certificate is on hold";
1002 break;
1003
1004 case GNUTLS_X509_CRLREASON_REMOVEFROMCRL:
1005 crl_reason = "will be removed from delta CRL";
1006 break;
1007
1008 case GNUTLS_X509_CRLREASON_PRIVILEGEWITHDRAWN:
1009 crl_reason = "privilege withdrawn";
1010 break;
1011
1012 case GNUTLS_X509_CRLREASON_AACOMPROMISE:
1013 crl_reason = "AA compromised";
1014 break;
1015 }
1016
1017 failf(data, "Server certificate was revoked: %s", crl_reason);
1018 break;
1019 }
1020
1021 default:
1022 case GNUTLS_OCSP_CERT_UNKNOWN:
1023 failf(data, "Server certificate status is unknown");
1024 break;
1025 }
1026
1027 gnutls_ocsp_resp_deinit(ocsp_resp);
1028
1029 return CURLE_SSL_INVALIDCERTSTATUS;
1030 }
1031 else
1032 infof(data, " server certificate status verification OK");
1033 }
1034 else
1035 infof(data, " server certificate status verification SKIPPED");
1036
1037 /* initialize an X.509 certificate structure. */
1038 gnutls_x509_crt_init(&x509_cert);
1039
1040 if(chainp)
1041 /* convert the given DER or PEM encoded Certificate to the native
1042 gnutls_x509_crt_t format */
1043 gnutls_x509_crt_import(x509_cert, chainp, GNUTLS_X509_FMT_DER);
1044
1045 if(SSL_CONN_CONFIG(issuercert)) {
1046 gnutls_x509_crt_init(&x509_issuer);
1047 issuerp = load_file(SSL_CONN_CONFIG(issuercert));
1048 gnutls_x509_crt_import(x509_issuer, &issuerp, GNUTLS_X509_FMT_PEM);
1049 rc = gnutls_x509_crt_check_issuer(x509_cert, x509_issuer);
1050 gnutls_x509_crt_deinit(x509_issuer);
1051 unload_file(issuerp);
1052 if(rc <= 0) {
1053 failf(data, "server certificate issuer check failed (IssuerCert: %s)",
1054 SSL_CONN_CONFIG(issuercert)?SSL_CONN_CONFIG(issuercert):"none");
1055 gnutls_x509_crt_deinit(x509_cert);
1056 return CURLE_SSL_ISSUER_ERROR;
1057 }
1058 infof(data, " server certificate issuer check OK (Issuer Cert: %s)",
1059 SSL_CONN_CONFIG(issuercert)?SSL_CONN_CONFIG(issuercert):"none");
1060 }
1061
1062 size = sizeof(certname);
1063 rc = gnutls_x509_crt_get_dn_by_oid(x509_cert, GNUTLS_OID_X520_COMMON_NAME,
1064 0, /* the first and only one */
1065 FALSE,
1066 certname,
1067 &size);
1068 if(rc) {
1069 infof(data, "error fetching CN from cert:%s",
1070 gnutls_strerror(rc));
1071 }
1072
1073 /* This function will check if the given certificate's subject matches the
1074 given hostname. This is a basic implementation of the matching described
1075 in RFC2818 (HTTPS), which takes into account wildcards, and the subject
1076 alternative name PKIX extension. Returns non zero on success, and zero on
1077 failure. */
1078 rc = gnutls_x509_crt_check_hostname(x509_cert, hostname);
1079 #if GNUTLS_VERSION_NUMBER < 0x030306
1080 /* Before 3.3.6, gnutls_x509_crt_check_hostname() didn't check IP
1081 addresses. */
1082 if(!rc) {
1083 #ifdef ENABLE_IPV6
1084 #define use_addr in6_addr
1085 #else
1086 #define use_addr in_addr
1087 #endif
1088 unsigned char addrbuf[sizeof(struct use_addr)];
1089 size_t addrlen = 0;
1090
1091 if(Curl_inet_pton(AF_INET, hostname, addrbuf) > 0)
1092 addrlen = 4;
1093 #ifdef ENABLE_IPV6
1094 else if(Curl_inet_pton(AF_INET6, hostname, addrbuf) > 0)
1095 addrlen = 16;
1096 #endif
1097
1098 if(addrlen) {
1099 unsigned char certaddr[sizeof(struct use_addr)];
1100 int i;
1101
1102 for(i = 0; ; i++) {
1103 size_t certaddrlen = sizeof(certaddr);
1104 int ret = gnutls_x509_crt_get_subject_alt_name(x509_cert, i, certaddr,
1105 &certaddrlen, NULL);
1106 /* If this happens, it wasn't an IP address. */
1107 if(ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
1108 continue;
1109 if(ret < 0)
1110 break;
1111 if(ret != GNUTLS_SAN_IPADDRESS)
1112 continue;
1113 if(certaddrlen == addrlen && !memcmp(addrbuf, certaddr, addrlen)) {
1114 rc = 1;
1115 break;
1116 }
1117 }
1118 }
1119 }
1120 #endif
1121 if(!rc) {
1122 if(SSL_CONN_CONFIG(verifyhost)) {
1123 failf(data, "SSL: certificate subject name (%s) does not match "
1124 "target host name '%s'", certname, SSL_HOST_DISPNAME());
1125 gnutls_x509_crt_deinit(x509_cert);
1126 return CURLE_PEER_FAILED_VERIFICATION;
1127 }
1128 else
1129 infof(data, " common name: %s (does not match '%s')",
1130 certname, SSL_HOST_DISPNAME());
1131 }
1132 else
1133 infof(data, " common name: %s (matched)", certname);
1134
1135 /* Check for time-based validity */
1136 certclock = gnutls_x509_crt_get_expiration_time(x509_cert);
1137
1138 if(certclock == (time_t)-1) {
1139 if(SSL_CONN_CONFIG(verifypeer)) {
1140 failf(data, "server cert expiration date verify failed");
1141 *certverifyresult = GNUTLS_CERT_EXPIRED;
1142 gnutls_x509_crt_deinit(x509_cert);
1143 return CURLE_SSL_CONNECT_ERROR;
1144 }
1145 else
1146 infof(data, " server certificate expiration date verify FAILED");
1147 }
1148 else {
1149 if(certclock < time(NULL)) {
1150 if(SSL_CONN_CONFIG(verifypeer)) {
1151 failf(data, "server certificate expiration date has passed.");
1152 *certverifyresult = GNUTLS_CERT_EXPIRED;
1153 gnutls_x509_crt_deinit(x509_cert);
1154 return CURLE_PEER_FAILED_VERIFICATION;
1155 }
1156 else
1157 infof(data, " server certificate expiration date FAILED");
1158 }
1159 else
1160 infof(data, " server certificate expiration date OK");
1161 }
1162
1163 certclock = gnutls_x509_crt_get_activation_time(x509_cert);
1164
1165 if(certclock == (time_t)-1) {
1166 if(SSL_CONN_CONFIG(verifypeer)) {
1167 failf(data, "server cert activation date verify failed");
1168 *certverifyresult = GNUTLS_CERT_NOT_ACTIVATED;
1169 gnutls_x509_crt_deinit(x509_cert);
1170 return CURLE_SSL_CONNECT_ERROR;
1171 }
1172 else
1173 infof(data, " server certificate activation date verify FAILED");
1174 }
1175 else {
1176 if(certclock > time(NULL)) {
1177 if(SSL_CONN_CONFIG(verifypeer)) {
1178 failf(data, "server certificate not activated yet.");
1179 *certverifyresult = GNUTLS_CERT_NOT_ACTIVATED;
1180 gnutls_x509_crt_deinit(x509_cert);
1181 return CURLE_PEER_FAILED_VERIFICATION;
1182 }
1183 else
1184 infof(data, " server certificate activation date FAILED");
1185 }
1186 else
1187 infof(data, " server certificate activation date OK");
1188 }
1189
1190 ptr = SSL_PINNED_PUB_KEY();
1191 if(ptr) {
1192 result = pkp_pin_peer_pubkey(data, x509_cert, ptr);
1193 if(result != CURLE_OK) {
1194 failf(data, "SSL: public key does not match pinned public key!");
1195 gnutls_x509_crt_deinit(x509_cert);
1196 return result;
1197 }
1198 }
1199
1200 /* Show:
1201
1202 - subject
1203 - start date
1204 - expire date
1205 - common name
1206 - issuer
1207
1208 */
1209
1210 #ifndef CURL_DISABLE_VERBOSE_STRINGS
1211 /* public key algorithm's parameters */
1212 algo = gnutls_x509_crt_get_pk_algorithm(x509_cert, &bits);
1213 infof(data, " certificate public key: %s",
1214 gnutls_pk_algorithm_get_name(algo));
1215
1216 /* version of the X.509 certificate. */
1217 infof(data, " certificate version: #%d",
1218 gnutls_x509_crt_get_version(x509_cert));
1219
1220
1221 rc = gnutls_x509_crt_get_dn2(x509_cert, &certfields);
1222 if(rc)
1223 infof(data, "Failed to get certificate name");
1224 else {
1225 infof(data, " subject: %s", certfields.data);
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 gnutls_free(certfields.data);
1234 }
1235
1236 rc = gnutls_x509_crt_get_issuer_dn2(x509_cert, &certfields);
1237 if(rc)
1238 infof(data, "Failed to get certificate issuer");
1239 else {
1240 infof(data, " issuer: %s", certfields.data);
1241
1242 gnutls_free(certfields.data);
1243 }
1244 #endif
1245
1246 gnutls_x509_crt_deinit(x509_cert);
1247
1248 if(conn->bits.tls_enable_alpn) {
1249 rc = gnutls_alpn_get_selected_protocol(session, &proto);
1250 if(rc == 0) {
1251 infof(data, "ALPN, server accepted to use %.*s", proto.size,
1252 proto.data);
1253
1254 #ifdef USE_HTTP2
1255 if(proto.size == ALPN_H2_LENGTH &&
1256 !memcmp(ALPN_H2, proto.data,
1257 ALPN_H2_LENGTH)) {
1258 conn->negnpn = CURL_HTTP_VERSION_2;
1259 }
1260 else
1261 #endif
1262 if(proto.size == ALPN_HTTP_1_1_LENGTH &&
1263 !memcmp(ALPN_HTTP_1_1, proto.data, ALPN_HTTP_1_1_LENGTH)) {
1264 conn->negnpn = CURL_HTTP_VERSION_1_1;
1265 }
1266 }
1267 else
1268 infof(data, "ALPN, server did not agree to a protocol");
1269
1270 Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ?
1271 BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
1272 }
1273
1274 conn->ssl[sockindex].state = ssl_connection_complete;
1275 conn->recv[sockindex] = gtls_recv;
1276 conn->send[sockindex] = gtls_send;
1277
1278 if(SSL_SET_OPTION(primary.sessionid)) {
1279 /* we always unconditionally get the session id here, as even if we
1280 already got it from the cache and asked to use it in the connection, it
1281 might've been rejected and then a new one is in use now and we need to
1282 detect that. */
1283 void *connect_sessionid;
1284 size_t connect_idsize = 0;
1285
1286 /* get the session ID data size */
1287 gnutls_session_get_data(session, NULL, &connect_idsize);
1288 connect_sessionid = malloc(connect_idsize); /* get a buffer for it */
1289
1290 if(connect_sessionid) {
1291 bool incache;
1292 void *ssl_sessionid;
1293
1294 /* extract session ID to the allocated buffer */
1295 gnutls_session_get_data(session, connect_sessionid, &connect_idsize);
1296
1297 Curl_ssl_sessionid_lock(data);
1298 incache = !(Curl_ssl_getsessionid(data, conn,
1299 SSL_IS_PROXY() ? TRUE : FALSE,
1300 &ssl_sessionid, NULL, sockindex));
1301 if(incache) {
1302 /* there was one before in the cache, so instead of risking that the
1303 previous one was rejected, we just kill that and store the new */
1304 Curl_ssl_delsessionid(data, ssl_sessionid);
1305 }
1306
1307 /* store this session id */
1308 result = Curl_ssl_addsessionid(data, conn,
1309 SSL_IS_PROXY() ? TRUE : FALSE,
1310 connect_sessionid, connect_idsize,
1311 sockindex);
1312 Curl_ssl_sessionid_unlock(data);
1313 if(result) {
1314 free(connect_sessionid);
1315 result = CURLE_OUT_OF_MEMORY;
1316 }
1317 }
1318 else
1319 result = CURLE_OUT_OF_MEMORY;
1320 }
1321
1322 return result;
1323 }
1324
1325
1326 /*
1327 * This function is called after the TCP connect has completed. Setup the TLS
1328 * layer and do all necessary magic.
1329 */
1330 /* We use connssl->connecting_state to keep track of the connection status;
1331 there are three states: 'ssl_connect_1' (not started yet or complete),
1332 'ssl_connect_2_reading' (waiting for data from server), and
1333 'ssl_connect_2_writing' (waiting to be able to write).
1334 */
1335 static CURLcode
gtls_connect_common(struct Curl_easy * data,struct connectdata * conn,int sockindex,bool nonblocking,bool * done)1336 gtls_connect_common(struct Curl_easy *data,
1337 struct connectdata *conn,
1338 int sockindex,
1339 bool nonblocking,
1340 bool *done)
1341 {
1342 int rc;
1343 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1344
1345 /* Initiate the connection, if not already done */
1346 if(ssl_connect_1 == connssl->connecting_state) {
1347 rc = gtls_connect_step1(data, conn, sockindex);
1348 if(rc)
1349 return rc;
1350 }
1351
1352 rc = handshake(data, conn, sockindex, TRUE, nonblocking);
1353 if(rc)
1354 /* handshake() sets its own error message with failf() */
1355 return rc;
1356
1357 /* Finish connecting once the handshake is done */
1358 if(ssl_connect_1 == connssl->connecting_state) {
1359 rc = gtls_connect_step3(data, conn, sockindex);
1360 if(rc)
1361 return rc;
1362 }
1363
1364 *done = ssl_connect_1 == connssl->connecting_state;
1365
1366 return CURLE_OK;
1367 }
1368
gtls_connect_nonblocking(struct Curl_easy * data,struct connectdata * conn,int sockindex,bool * done)1369 static CURLcode gtls_connect_nonblocking(struct Curl_easy *data,
1370 struct connectdata *conn,
1371 int sockindex, bool *done)
1372 {
1373 return gtls_connect_common(data, conn, sockindex, TRUE, done);
1374 }
1375
gtls_connect(struct Curl_easy * data,struct connectdata * conn,int sockindex)1376 static CURLcode gtls_connect(struct Curl_easy *data, struct connectdata *conn,
1377 int sockindex)
1378 {
1379 CURLcode result;
1380 bool done = FALSE;
1381
1382 result = gtls_connect_common(data, conn, sockindex, FALSE, &done);
1383 if(result)
1384 return result;
1385
1386 DEBUGASSERT(done);
1387
1388 return CURLE_OK;
1389 }
1390
gtls_data_pending(const struct connectdata * conn,int connindex)1391 static bool gtls_data_pending(const struct connectdata *conn,
1392 int connindex)
1393 {
1394 const struct ssl_connect_data *connssl = &conn->ssl[connindex];
1395 bool res = FALSE;
1396 struct ssl_backend_data *backend = connssl->backend;
1397 if(backend->session &&
1398 0 != gnutls_record_check_pending(backend->session))
1399 res = TRUE;
1400
1401 #ifndef CURL_DISABLE_PROXY
1402 connssl = &conn->proxy_ssl[connindex];
1403 backend = connssl->backend;
1404 if(backend->session &&
1405 0 != gnutls_record_check_pending(backend->session))
1406 res = TRUE;
1407 #endif
1408
1409 return res;
1410 }
1411
gtls_send(struct Curl_easy * data,int sockindex,const void * mem,size_t len,CURLcode * curlcode)1412 static ssize_t gtls_send(struct Curl_easy *data,
1413 int sockindex,
1414 const void *mem,
1415 size_t len,
1416 CURLcode *curlcode)
1417 {
1418 struct connectdata *conn = data->conn;
1419 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1420 struct ssl_backend_data *backend = connssl->backend;
1421 ssize_t rc = gnutls_record_send(backend->session, mem, len);
1422
1423 if(rc < 0) {
1424 *curlcode = (rc == GNUTLS_E_AGAIN)
1425 ? CURLE_AGAIN
1426 : CURLE_SEND_ERROR;
1427
1428 rc = -1;
1429 }
1430
1431 return rc;
1432 }
1433
close_one(struct ssl_connect_data * connssl)1434 static void close_one(struct ssl_connect_data *connssl)
1435 {
1436 struct ssl_backend_data *backend = connssl->backend;
1437 if(backend->session) {
1438 char buf[32];
1439 /* Maybe the server has already sent a close notify alert.
1440 Read it to avoid an RST on the TCP connection. */
1441 (void)gnutls_record_recv(backend->session, buf, sizeof(buf));
1442 gnutls_bye(backend->session, GNUTLS_SHUT_WR);
1443 gnutls_deinit(backend->session);
1444 backend->session = NULL;
1445 }
1446 if(backend->cred) {
1447 gnutls_certificate_free_credentials(backend->cred);
1448 backend->cred = NULL;
1449 }
1450 #ifdef HAVE_GNUTLS_SRP
1451 if(backend->srp_client_cred) {
1452 gnutls_srp_free_client_credentials(backend->srp_client_cred);
1453 backend->srp_client_cred = NULL;
1454 }
1455 #endif
1456 }
1457
gtls_close(struct Curl_easy * data,struct connectdata * conn,int sockindex)1458 static void gtls_close(struct Curl_easy *data, struct connectdata *conn,
1459 int sockindex)
1460 {
1461 (void) data;
1462 close_one(&conn->ssl[sockindex]);
1463 #ifndef CURL_DISABLE_PROXY
1464 close_one(&conn->proxy_ssl[sockindex]);
1465 #endif
1466 }
1467
1468 /*
1469 * This function is called to shut down the SSL layer but keep the
1470 * socket open (CCC - Clear Command Channel)
1471 */
gtls_shutdown(struct Curl_easy * data,struct connectdata * conn,int sockindex)1472 static int gtls_shutdown(struct Curl_easy *data, struct connectdata *conn,
1473 int sockindex)
1474 {
1475 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1476 struct ssl_backend_data *backend = connssl->backend;
1477 int retval = 0;
1478
1479 #ifndef CURL_DISABLE_FTP
1480 /* This has only been tested on the proftpd server, and the mod_tls code
1481 sends a close notify alert without waiting for a close notify alert in
1482 response. Thus we wait for a close notify alert from the server, but
1483 we do not send one. Let's hope other servers do the same... */
1484
1485 if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
1486 gnutls_bye(backend->session, GNUTLS_SHUT_WR);
1487 #endif
1488
1489 if(backend->session) {
1490 ssize_t result;
1491 bool done = FALSE;
1492 char buf[120];
1493
1494 while(!done) {
1495 int what = SOCKET_READABLE(conn->sock[sockindex],
1496 SSL_SHUTDOWN_TIMEOUT);
1497 if(what > 0) {
1498 /* Something to read, let's do it and hope that it is the close
1499 notify alert from the server */
1500 result = gnutls_record_recv(backend->session,
1501 buf, sizeof(buf));
1502 switch(result) {
1503 case 0:
1504 /* This is the expected response. There was no data but only
1505 the close notify alert */
1506 done = TRUE;
1507 break;
1508 case GNUTLS_E_AGAIN:
1509 case GNUTLS_E_INTERRUPTED:
1510 infof(data, "GNUTLS_E_AGAIN || GNUTLS_E_INTERRUPTED");
1511 break;
1512 default:
1513 retval = -1;
1514 done = TRUE;
1515 break;
1516 }
1517 }
1518 else if(0 == what) {
1519 /* timeout */
1520 failf(data, "SSL shutdown timeout");
1521 done = TRUE;
1522 }
1523 else {
1524 /* anything that gets here is fatally bad */
1525 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
1526 retval = -1;
1527 done = TRUE;
1528 }
1529 }
1530 gnutls_deinit(backend->session);
1531 }
1532 gnutls_certificate_free_credentials(backend->cred);
1533
1534 #ifdef HAVE_GNUTLS_SRP
1535 if(SSL_SET_OPTION(primary.authtype) == CURL_TLSAUTH_SRP
1536 && SSL_SET_OPTION(primary.username) != NULL)
1537 gnutls_srp_free_client_credentials(backend->srp_client_cred);
1538 #endif
1539
1540 backend->cred = NULL;
1541 backend->session = NULL;
1542
1543 return retval;
1544 }
1545
gtls_recv(struct Curl_easy * data,int num,char * buf,size_t buffersize,CURLcode * curlcode)1546 static ssize_t gtls_recv(struct Curl_easy *data, /* connection data */
1547 int num, /* socketindex */
1548 char *buf, /* store read data here */
1549 size_t buffersize, /* max amount to read */
1550 CURLcode *curlcode)
1551 {
1552 struct connectdata *conn = data->conn;
1553 struct ssl_connect_data *connssl = &conn->ssl[num];
1554 struct ssl_backend_data *backend = connssl->backend;
1555 ssize_t ret;
1556
1557 ret = gnutls_record_recv(backend->session, buf, buffersize);
1558 if((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED)) {
1559 *curlcode = CURLE_AGAIN;
1560 return -1;
1561 }
1562
1563 if(ret == GNUTLS_E_REHANDSHAKE) {
1564 /* BLOCKING call, this is bad but a work-around for now. Fixing this "the
1565 proper way" takes a whole lot of work. */
1566 CURLcode result = handshake(data, conn, num, FALSE, FALSE);
1567 if(result)
1568 /* handshake() writes error message on its own */
1569 *curlcode = result;
1570 else
1571 *curlcode = CURLE_AGAIN; /* then return as if this was a wouldblock */
1572 return -1;
1573 }
1574
1575 if(ret < 0) {
1576 failf(data, "GnuTLS recv error (%d): %s",
1577
1578 (int)ret, gnutls_strerror((int)ret));
1579 *curlcode = CURLE_RECV_ERROR;
1580 return -1;
1581 }
1582
1583 return ret;
1584 }
1585
gtls_session_free(void * ptr)1586 static void gtls_session_free(void *ptr)
1587 {
1588 free(ptr);
1589 }
1590
gtls_version(char * buffer,size_t size)1591 static size_t gtls_version(char *buffer, size_t size)
1592 {
1593 return msnprintf(buffer, size, "GnuTLS/%s", gnutls_check_version(NULL));
1594 }
1595
1596 /* data might be NULL! */
gtls_random(struct Curl_easy * data,unsigned char * entropy,size_t length)1597 static CURLcode gtls_random(struct Curl_easy *data,
1598 unsigned char *entropy, size_t length)
1599 {
1600 int rc;
1601 (void)data;
1602 rc = gnutls_rnd(GNUTLS_RND_RANDOM, entropy, length);
1603 return rc?CURLE_FAILED_INIT:CURLE_OK;
1604 }
1605
gtls_sha256sum(const unsigned char * tmp,size_t tmplen,unsigned char * sha256sum,size_t sha256len)1606 static CURLcode gtls_sha256sum(const unsigned char *tmp, /* input */
1607 size_t tmplen,
1608 unsigned char *sha256sum, /* output */
1609 size_t sha256len)
1610 {
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 return CURLE_OK;
1616 }
1617
gtls_cert_status_request(void)1618 static bool gtls_cert_status_request(void)
1619 {
1620 return TRUE;
1621 }
1622
gtls_get_internals(struct ssl_connect_data * connssl,CURLINFO info UNUSED_PARAM)1623 static void *gtls_get_internals(struct ssl_connect_data *connssl,
1624 CURLINFO info UNUSED_PARAM)
1625 {
1626 struct ssl_backend_data *backend = connssl->backend;
1627 (void)info;
1628 return backend->session;
1629 }
1630
1631 const struct Curl_ssl Curl_ssl_gnutls = {
1632 { CURLSSLBACKEND_GNUTLS, "gnutls" }, /* info */
1633
1634 SSLSUPP_CA_PATH |
1635 SSLSUPP_CERTINFO |
1636 SSLSUPP_PINNEDPUBKEY |
1637 SSLSUPP_HTTPS_PROXY,
1638
1639 sizeof(struct ssl_backend_data),
1640
1641 gtls_init, /* init */
1642 gtls_cleanup, /* cleanup */
1643 gtls_version, /* version */
1644 Curl_none_check_cxn, /* check_cxn */
1645 gtls_shutdown, /* shutdown */
1646 gtls_data_pending, /* data_pending */
1647 gtls_random, /* random */
1648 gtls_cert_status_request, /* cert_status_request */
1649 gtls_connect, /* connect */
1650 gtls_connect_nonblocking, /* connect_nonblocking */
1651 Curl_ssl_getsock, /* getsock */
1652 gtls_get_internals, /* get_internals */
1653 gtls_close, /* close_one */
1654 Curl_none_close_all, /* close_all */
1655 gtls_session_free, /* session_free */
1656 Curl_none_set_engine, /* set_engine */
1657 Curl_none_set_engine_default, /* set_engine_default */
1658 Curl_none_engines_list, /* engines_list */
1659 Curl_none_false_start, /* false_start */
1660 gtls_sha256sum, /* sha256sum */
1661 NULL, /* associate_connection */
1662 NULL /* disassociate_connection */
1663 };
1664
1665 #endif /* USE_GNUTLS */
1666