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