blob: 181e64d8d9f411fa543f0881193b90949b5dabfb [file] [log] [blame]
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001/*
2 * SSL/TLS interface functions for OpenSSL
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003 * Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi>
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004 *
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08005 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07007 */
8
9#include "includes.h"
10
11#ifndef CONFIG_SMARTCARD
12#ifndef OPENSSL_NO_ENGINE
Kenny Rootdb3c5a42012-03-20 17:00:47 -070013#ifndef ANDROID
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070014#define OPENSSL_NO_ENGINE
15#endif
16#endif
Kenny Rootdb3c5a42012-03-20 17:00:47 -070017#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070018
19#include <openssl/ssl.h>
20#include <openssl/err.h>
Dmitry Shmidt849734c2016-05-27 09:59:01 -070021#include <openssl/opensslv.h>
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070022#include <openssl/pkcs12.h>
23#include <openssl/x509v3.h>
24#ifndef OPENSSL_NO_ENGINE
25#include <openssl/engine.h>
26#endif /* OPENSSL_NO_ENGINE */
Dmitry Shmidtd80a4012015-11-05 16:35:40 -080027#ifndef OPENSSL_NO_DSA
28#include <openssl/dsa.h>
29#endif
30#ifndef OPENSSL_NO_DH
31#include <openssl/dh.h>
32#endif
33
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070034#include "common.h"
35#include "crypto.h"
Dmitry Shmidtaf9da312015-04-03 10:03:11 -070036#include "sha1.h"
Dmitry Shmidtd80a4012015-11-05 16:35:40 -080037#include "sha256.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070038#include "tls.h"
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -080039#include "tls_openssl.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070040
Dmitry Shmidt849734c2016-05-27 09:59:01 -070041#if !defined(CONFIG_FIPS) && \
42 (defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || \
43 defined(EAP_SERVER_FAST))
44#define OPENSSL_NEED_EAP_FAST_PRF
45#endif
46
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -070047#if defined(OPENSSL_IS_BORINGSSL)
48/* stack_index_t is the return type of OpenSSL's sk_XXX_num() functions. */
49typedef size_t stack_index_t;
50#else
51typedef int stack_index_t;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070052#endif
53
Dmitry Shmidt34af3062013-07-11 10:46:32 -070054#ifdef SSL_set_tlsext_status_type
55#ifndef OPENSSL_NO_TLSEXT
56#define HAVE_OCSP
57#include <openssl/ocsp.h>
58#endif /* OPENSSL_NO_TLSEXT */
59#endif /* SSL_set_tlsext_status_type */
60
Dmitry Shmidt849734c2016-05-27 09:59:01 -070061#if (OPENSSL_VERSION_NUMBER < 0x10100000L || \
Roshan Pius3a1667e2018-07-03 15:17:14 -070062 (defined(LIBRESSL_VERSION_NUMBER) && \
63 LIBRESSL_VERSION_NUMBER < 0x20700000L)) && \
Dmitry Shmidt849734c2016-05-27 09:59:01 -070064 !defined(BORINGSSL_API_VERSION)
Dmitry Shmidtde47be72016-01-07 12:52:55 -080065/*
66 * SSL_get_client_random() and SSL_get_server_random() were added in OpenSSL
Dmitry Shmidt849734c2016-05-27 09:59:01 -070067 * 1.1.0 and newer BoringSSL revisions. Provide compatibility wrappers for
68 * older versions.
Dmitry Shmidtde47be72016-01-07 12:52:55 -080069 */
70
71static size_t SSL_get_client_random(const SSL *ssl, unsigned char *out,
72 size_t outlen)
73{
74 if (!ssl->s3 || outlen < SSL3_RANDOM_SIZE)
75 return 0;
76 os_memcpy(out, ssl->s3->client_random, SSL3_RANDOM_SIZE);
77 return SSL3_RANDOM_SIZE;
78}
79
80
81static size_t SSL_get_server_random(const SSL *ssl, unsigned char *out,
82 size_t outlen)
83{
84 if (!ssl->s3 || outlen < SSL3_RANDOM_SIZE)
85 return 0;
86 os_memcpy(out, ssl->s3->server_random, SSL3_RANDOM_SIZE);
87 return SSL3_RANDOM_SIZE;
88}
89
90
Dmitry Shmidt849734c2016-05-27 09:59:01 -070091#ifdef OPENSSL_NEED_EAP_FAST_PRF
Dmitry Shmidtde47be72016-01-07 12:52:55 -080092static size_t SSL_SESSION_get_master_key(const SSL_SESSION *session,
93 unsigned char *out, size_t outlen)
94{
95 if (!session || session->master_key_length < 0 ||
96 (size_t) session->master_key_length > outlen)
97 return 0;
98 if ((size_t) session->master_key_length < outlen)
99 outlen = session->master_key_length;
100 os_memcpy(out, session->master_key, outlen);
101 return outlen;
102}
Dmitry Shmidt849734c2016-05-27 09:59:01 -0700103#endif /* OPENSSL_NEED_EAP_FAST_PRF */
Dmitry Shmidtde47be72016-01-07 12:52:55 -0800104
105#endif
106
Hai Shalom39bc25d2019-02-06 16:32:13 -0800107#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
108 (defined(LIBRESSL_VERSION_NUMBER) && \
109 LIBRESSL_VERSION_NUMBER < 0x20700000L)
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700110#ifdef CONFIG_SUITEB
111static int RSA_bits(const RSA *r)
112{
113 return BN_num_bits(r->n);
114}
115#endif /* CONFIG_SUITEB */
Hai Shalom39ba6fc2019-01-22 12:40:38 -0800116
117
118static const unsigned char * ASN1_STRING_get0_data(const ASN1_STRING *x)
119{
120 return ASN1_STRING_data((ASN1_STRING *) x);
121}
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700122#endif
123
Dmitry Shmidtff079172013-11-08 14:10:30 -0800124#ifdef ANDROID
125#include <openssl/pem.h>
126#include <keystore/keystore_get.h>
127
Pavel Grafov4d8552e2018-02-06 11:28:29 +0000128#include <log/log.h>
129#include <log/log_event_list.h>
130
131#define CERT_VALIDATION_FAILURE 210033
132
133static void log_cert_validation_failure(const char *reason)
134{
135 android_log_context ctx = create_android_logger(CERT_VALIDATION_FAILURE);
136 android_log_write_string8(ctx, reason);
137 android_log_write_list(ctx, LOG_ID_SECURITY);
138 android_log_destroy(&ctx);
139}
140
141
Dmitry Shmidtff079172013-11-08 14:10:30 -0800142static BIO * BIO_from_keystore(const char *key)
143{
144 BIO *bio = NULL;
145 uint8_t *value = NULL;
146 int length = keystore_get(key, strlen(key), &value);
147 if (length != -1 && (bio = BIO_new(BIO_s_mem())) != NULL)
148 BIO_write(bio, value, length);
149 free(value);
150 return bio;
151}
Dmitry Shmidtb97e4282016-02-08 10:16:07 -0800152
153
154static int tls_add_ca_from_keystore(X509_STORE *ctx, const char *key_alias)
155{
156 BIO *bio = BIO_from_keystore(key_alias);
157 STACK_OF(X509_INFO) *stack = NULL;
158 stack_index_t i;
159
160 if (bio) {
161 stack = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL);
162 BIO_free(bio);
163 }
164
165 if (!stack) {
166 wpa_printf(MSG_WARNING, "TLS: Failed to parse certificate: %s",
167 key_alias);
168 return -1;
169 }
170
171 for (i = 0; i < sk_X509_INFO_num(stack); ++i) {
172 X509_INFO *info = sk_X509_INFO_value(stack, i);
173
174 if (info->x509)
175 X509_STORE_add_cert(ctx, info->x509);
176 if (info->crl)
177 X509_STORE_add_crl(ctx, info->crl);
178 }
179
180 sk_X509_INFO_pop_free(stack, X509_INFO_free);
181
182 return 0;
183}
184
185
186static int tls_add_ca_from_keystore_encoded(X509_STORE *ctx,
187 const char *encoded_key_alias)
188{
189 int rc = -1;
190 int len = os_strlen(encoded_key_alias);
191 unsigned char *decoded_alias;
192
193 if (len & 1) {
194 wpa_printf(MSG_WARNING, "Invalid hex-encoded alias: %s",
195 encoded_key_alias);
196 return rc;
197 }
198
199 decoded_alias = os_malloc(len / 2 + 1);
200 if (decoded_alias) {
201 if (!hexstr2bin(encoded_key_alias, decoded_alias, len / 2)) {
202 decoded_alias[len / 2] = '\0';
203 rc = tls_add_ca_from_keystore(
204 ctx, (const char *) decoded_alias);
205 }
206 os_free(decoded_alias);
207 }
208
209 return rc;
210}
211
Dmitry Shmidtff079172013-11-08 14:10:30 -0800212#endif /* ANDROID */
213
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700214static int tls_openssl_ref_count = 0;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800215static int tls_ex_idx_session = -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700216
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700217struct tls_context {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700218 void (*event_cb)(void *ctx, enum tls_event ev,
219 union tls_event_data *data);
220 void *cb_ctx;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800221 int cert_in_cb;
Dmitry Shmidt34af3062013-07-11 10:46:32 -0700222 char *ocsp_stapling_response;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700223};
224
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700225static struct tls_context *tls_global = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700226
227
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800228struct tls_data {
229 SSL_CTX *ssl;
230 unsigned int tls_session_lifetime;
Hai Shalom39bc25d2019-02-06 16:32:13 -0800231 int check_crl;
232 int check_crl_strict;
233 char *ca_cert;
234 unsigned int crl_reload_interval;
235 struct os_reltime crl_last_reload;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800236};
237
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700238struct tls_connection {
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700239 struct tls_context *context;
Hai Shalom39bc25d2019-02-06 16:32:13 -0800240 struct tls_data *data;
Dmitry Shmidt216983b2015-02-06 10:50:36 -0800241 SSL_CTX *ssl_ctx;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700242 SSL *ssl;
243 BIO *ssl_in, *ssl_out;
Adam Langley1eb02ed2015-04-21 19:00:05 -0700244#if defined(ANDROID) || !defined(OPENSSL_NO_ENGINE)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700245 ENGINE *engine; /* functional reference to the engine */
246 EVP_PKEY *private_key; /* the private key if using engine */
247#endif /* OPENSSL_NO_ENGINE */
Dmitry Shmidt2f74e362015-01-21 13:19:05 -0800248 char *subject_match, *altsubject_match, *suffix_match, *domain_match;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700249 int read_alerts, write_alerts, failed;
250
251 tls_session_ticket_cb session_ticket_cb;
252 void *session_ticket_cb_ctx;
253
254 /* SessionTicket received from OpenSSL hello_extension_cb (server) */
255 u8 *session_ticket;
256 size_t session_ticket_len;
257
258 unsigned int ca_cert_verify:1;
259 unsigned int cert_probe:1;
260 unsigned int server_cert_only:1;
Jouni Malinen26af48b2014-04-09 13:02:53 +0300261 unsigned int invalid_hb_used:1;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800262 unsigned int success_data:1;
Roshan Pius3a1667e2018-07-03 15:17:14 -0700263 unsigned int client_hello_generated:1;
264 unsigned int server:1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700265
266 u8 srv_cert_hash[32];
Dmitry Shmidtc55524a2011-07-07 11:18:38 -0700267
268 unsigned int flags;
Dmitry Shmidt34af3062013-07-11 10:46:32 -0700269
270 X509 *peer_cert;
271 X509 *peer_issuer;
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -0800272 X509 *peer_issuer_issuer;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800273
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800274 unsigned char client_random[SSL3_RANDOM_SIZE];
275 unsigned char server_random[SSL3_RANDOM_SIZE];
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700276
277 u16 cipher_suite;
278 int server_dh_prime_len;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700279};
280
281
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700282static struct tls_context * tls_context_new(const struct tls_config *conf)
283{
284 struct tls_context *context = os_zalloc(sizeof(*context));
285 if (context == NULL)
286 return NULL;
287 if (conf) {
288 context->event_cb = conf->event_cb;
289 context->cb_ctx = conf->cb_ctx;
290 context->cert_in_cb = conf->cert_in_cb;
291 }
292 return context;
293}
294
295
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700296#ifdef CONFIG_NO_STDOUT_DEBUG
297
298static void _tls_show_errors(void)
299{
300 unsigned long err;
301
302 while ((err = ERR_get_error())) {
303 /* Just ignore the errors, since stdout is disabled */
304 }
305}
306#define tls_show_errors(l, f, t) _tls_show_errors()
307
308#else /* CONFIG_NO_STDOUT_DEBUG */
309
310static void tls_show_errors(int level, const char *func, const char *txt)
311{
312 unsigned long err;
313
314 wpa_printf(level, "OpenSSL: %s - %s %s",
315 func, txt, ERR_error_string(ERR_get_error(), NULL));
316
317 while ((err = ERR_get_error())) {
318 wpa_printf(MSG_INFO, "OpenSSL: pending error: %s",
319 ERR_error_string(err, NULL));
320 }
321}
322
323#endif /* CONFIG_NO_STDOUT_DEBUG */
324
325
Hai Shalom39bc25d2019-02-06 16:32:13 -0800326static X509_STORE * tls_crl_cert_reload(const char *ca_cert, int check_crl)
327{
328 int flags;
329 X509_STORE *store;
330
331 store = X509_STORE_new();
332 if (!store) {
333 wpa_printf(MSG_DEBUG,
334 "OpenSSL: %s - failed to allocate new certificate store",
335 __func__);
336 return NULL;
337 }
338
339 if (ca_cert && X509_STORE_load_locations(store, ca_cert, NULL) != 1) {
340 tls_show_errors(MSG_WARNING, __func__,
341 "Failed to load root certificates");
342 X509_STORE_free(store);
343 return NULL;
344 }
345
346 if (check_crl)
347 flags = X509_V_FLAG_CRL_CHECK;
348 if (check_crl == 2)
349 flags |= X509_V_FLAG_CRL_CHECK_ALL;
350
351 X509_STORE_set_flags(store, flags);
352
353 return store;
354}
355
356
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700357#ifdef CONFIG_NATIVE_WINDOWS
358
359/* Windows CryptoAPI and access to certificate stores */
360#include <wincrypt.h>
361
362#ifdef __MINGW32_VERSION
363/*
364 * MinGW does not yet include all the needed definitions for CryptoAPI, so
365 * define here whatever extra is needed.
366 */
367#define CERT_SYSTEM_STORE_CURRENT_USER (1 << 16)
368#define CERT_STORE_READONLY_FLAG 0x00008000
369#define CERT_STORE_OPEN_EXISTING_FLAG 0x00004000
370
371#endif /* __MINGW32_VERSION */
372
373
374struct cryptoapi_rsa_data {
375 const CERT_CONTEXT *cert;
376 HCRYPTPROV crypt_prov;
377 DWORD key_spec;
378 BOOL free_crypt_prov;
379};
380
381
382static void cryptoapi_error(const char *msg)
383{
384 wpa_printf(MSG_INFO, "CryptoAPI: %s; err=%u",
385 msg, (unsigned int) GetLastError());
386}
387
388
389static int cryptoapi_rsa_pub_enc(int flen, const unsigned char *from,
390 unsigned char *to, RSA *rsa, int padding)
391{
392 wpa_printf(MSG_DEBUG, "%s - not implemented", __func__);
393 return 0;
394}
395
396
397static int cryptoapi_rsa_pub_dec(int flen, const unsigned char *from,
398 unsigned char *to, RSA *rsa, int padding)
399{
400 wpa_printf(MSG_DEBUG, "%s - not implemented", __func__);
401 return 0;
402}
403
404
405static int cryptoapi_rsa_priv_enc(int flen, const unsigned char *from,
406 unsigned char *to, RSA *rsa, int padding)
407{
408 struct cryptoapi_rsa_data *priv =
409 (struct cryptoapi_rsa_data *) rsa->meth->app_data;
410 HCRYPTHASH hash;
411 DWORD hash_size, len, i;
412 unsigned char *buf = NULL;
413 int ret = 0;
414
415 if (priv == NULL) {
416 RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,
417 ERR_R_PASSED_NULL_PARAMETER);
418 return 0;
419 }
420
421 if (padding != RSA_PKCS1_PADDING) {
422 RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,
423 RSA_R_UNKNOWN_PADDING_TYPE);
424 return 0;
425 }
426
427 if (flen != 16 /* MD5 */ + 20 /* SHA-1 */) {
428 wpa_printf(MSG_INFO, "%s - only MD5-SHA1 hash supported",
429 __func__);
430 RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,
431 RSA_R_INVALID_MESSAGE_LENGTH);
432 return 0;
433 }
434
435 if (!CryptCreateHash(priv->crypt_prov, CALG_SSL3_SHAMD5, 0, 0, &hash))
436 {
437 cryptoapi_error("CryptCreateHash failed");
438 return 0;
439 }
440
441 len = sizeof(hash_size);
442 if (!CryptGetHashParam(hash, HP_HASHSIZE, (BYTE *) &hash_size, &len,
443 0)) {
444 cryptoapi_error("CryptGetHashParam failed");
445 goto err;
446 }
447
448 if ((int) hash_size != flen) {
449 wpa_printf(MSG_INFO, "CryptoAPI: Invalid hash size (%u != %d)",
450 (unsigned) hash_size, flen);
451 RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,
452 RSA_R_INVALID_MESSAGE_LENGTH);
453 goto err;
454 }
455 if (!CryptSetHashParam(hash, HP_HASHVAL, (BYTE * ) from, 0)) {
456 cryptoapi_error("CryptSetHashParam failed");
457 goto err;
458 }
459
460 len = RSA_size(rsa);
461 buf = os_malloc(len);
462 if (buf == NULL) {
463 RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE);
464 goto err;
465 }
466
467 if (!CryptSignHash(hash, priv->key_spec, NULL, 0, buf, &len)) {
468 cryptoapi_error("CryptSignHash failed");
469 goto err;
470 }
471
472 for (i = 0; i < len; i++)
473 to[i] = buf[len - i - 1];
474 ret = len;
475
476err:
477 os_free(buf);
478 CryptDestroyHash(hash);
479
480 return ret;
481}
482
483
484static int cryptoapi_rsa_priv_dec(int flen, const unsigned char *from,
485 unsigned char *to, RSA *rsa, int padding)
486{
487 wpa_printf(MSG_DEBUG, "%s - not implemented", __func__);
488 return 0;
489}
490
491
492static void cryptoapi_free_data(struct cryptoapi_rsa_data *priv)
493{
494 if (priv == NULL)
495 return;
496 if (priv->crypt_prov && priv->free_crypt_prov)
497 CryptReleaseContext(priv->crypt_prov, 0);
498 if (priv->cert)
499 CertFreeCertificateContext(priv->cert);
500 os_free(priv);
501}
502
503
504static int cryptoapi_finish(RSA *rsa)
505{
506 cryptoapi_free_data((struct cryptoapi_rsa_data *) rsa->meth->app_data);
507 os_free((void *) rsa->meth);
508 rsa->meth = NULL;
509 return 1;
510}
511
512
513static const CERT_CONTEXT * cryptoapi_find_cert(const char *name, DWORD store)
514{
515 HCERTSTORE cs;
516 const CERT_CONTEXT *ret = NULL;
517
518 cs = CertOpenStore((LPCSTR) CERT_STORE_PROV_SYSTEM, 0, 0,
519 store | CERT_STORE_OPEN_EXISTING_FLAG |
520 CERT_STORE_READONLY_FLAG, L"MY");
521 if (cs == NULL) {
522 cryptoapi_error("Failed to open 'My system store'");
523 return NULL;
524 }
525
526 if (strncmp(name, "cert://", 7) == 0) {
527 unsigned short wbuf[255];
528 MultiByteToWideChar(CP_ACP, 0, name + 7, -1, wbuf, 255);
529 ret = CertFindCertificateInStore(cs, X509_ASN_ENCODING |
530 PKCS_7_ASN_ENCODING,
531 0, CERT_FIND_SUBJECT_STR,
532 wbuf, NULL);
533 } else if (strncmp(name, "hash://", 7) == 0) {
534 CRYPT_HASH_BLOB blob;
535 int len;
536 const char *hash = name + 7;
537 unsigned char *buf;
538
539 len = os_strlen(hash) / 2;
540 buf = os_malloc(len);
541 if (buf && hexstr2bin(hash, buf, len) == 0) {
542 blob.cbData = len;
543 blob.pbData = buf;
544 ret = CertFindCertificateInStore(cs,
545 X509_ASN_ENCODING |
546 PKCS_7_ASN_ENCODING,
547 0, CERT_FIND_HASH,
548 &blob, NULL);
549 }
550 os_free(buf);
551 }
552
553 CertCloseStore(cs, 0);
554
555 return ret;
556}
557
558
559static int tls_cryptoapi_cert(SSL *ssl, const char *name)
560{
561 X509 *cert = NULL;
562 RSA *rsa = NULL, *pub_rsa;
563 struct cryptoapi_rsa_data *priv;
564 RSA_METHOD *rsa_meth;
565
566 if (name == NULL ||
567 (strncmp(name, "cert://", 7) != 0 &&
568 strncmp(name, "hash://", 7) != 0))
569 return -1;
570
571 priv = os_zalloc(sizeof(*priv));
572 rsa_meth = os_zalloc(sizeof(*rsa_meth));
573 if (priv == NULL || rsa_meth == NULL) {
574 wpa_printf(MSG_WARNING, "CryptoAPI: Failed to allocate memory "
575 "for CryptoAPI RSA method");
576 os_free(priv);
577 os_free(rsa_meth);
578 return -1;
579 }
580
581 priv->cert = cryptoapi_find_cert(name, CERT_SYSTEM_STORE_CURRENT_USER);
582 if (priv->cert == NULL) {
583 priv->cert = cryptoapi_find_cert(
584 name, CERT_SYSTEM_STORE_LOCAL_MACHINE);
585 }
586 if (priv->cert == NULL) {
587 wpa_printf(MSG_INFO, "CryptoAPI: Could not find certificate "
588 "'%s'", name);
589 goto err;
590 }
591
Dmitry Shmidt216983b2015-02-06 10:50:36 -0800592 cert = d2i_X509(NULL,
593 (const unsigned char **) &priv->cert->pbCertEncoded,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700594 priv->cert->cbCertEncoded);
595 if (cert == NULL) {
596 wpa_printf(MSG_INFO, "CryptoAPI: Could not process X509 DER "
597 "encoding");
598 goto err;
599 }
600
601 if (!CryptAcquireCertificatePrivateKey(priv->cert,
602 CRYPT_ACQUIRE_COMPARE_KEY_FLAG,
603 NULL, &priv->crypt_prov,
604 &priv->key_spec,
605 &priv->free_crypt_prov)) {
606 cryptoapi_error("Failed to acquire a private key for the "
607 "certificate");
608 goto err;
609 }
610
611 rsa_meth->name = "Microsoft CryptoAPI RSA Method";
612 rsa_meth->rsa_pub_enc = cryptoapi_rsa_pub_enc;
613 rsa_meth->rsa_pub_dec = cryptoapi_rsa_pub_dec;
614 rsa_meth->rsa_priv_enc = cryptoapi_rsa_priv_enc;
615 rsa_meth->rsa_priv_dec = cryptoapi_rsa_priv_dec;
616 rsa_meth->finish = cryptoapi_finish;
617 rsa_meth->flags = RSA_METHOD_FLAG_NO_CHECK;
618 rsa_meth->app_data = (char *) priv;
619
620 rsa = RSA_new();
621 if (rsa == NULL) {
622 SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,
623 ERR_R_MALLOC_FAILURE);
624 goto err;
625 }
626
627 if (!SSL_use_certificate(ssl, cert)) {
628 RSA_free(rsa);
629 rsa = NULL;
630 goto err;
631 }
632 pub_rsa = cert->cert_info->key->pkey->pkey.rsa;
633 X509_free(cert);
634 cert = NULL;
635
636 rsa->n = BN_dup(pub_rsa->n);
637 rsa->e = BN_dup(pub_rsa->e);
638 if (!RSA_set_method(rsa, rsa_meth))
639 goto err;
640
641 if (!SSL_use_RSAPrivateKey(ssl, rsa))
642 goto err;
643 RSA_free(rsa);
644
645 return 0;
646
647err:
648 if (cert)
649 X509_free(cert);
650 if (rsa)
651 RSA_free(rsa);
652 else {
653 os_free(rsa_meth);
654 cryptoapi_free_data(priv);
655 }
656 return -1;
657}
658
659
660static int tls_cryptoapi_ca_cert(SSL_CTX *ssl_ctx, SSL *ssl, const char *name)
661{
662 HCERTSTORE cs;
663 PCCERT_CONTEXT ctx = NULL;
664 X509 *cert;
665 char buf[128];
666 const char *store;
667#ifdef UNICODE
668 WCHAR *wstore;
669#endif /* UNICODE */
670
671 if (name == NULL || strncmp(name, "cert_store://", 13) != 0)
672 return -1;
673
674 store = name + 13;
675#ifdef UNICODE
676 wstore = os_malloc((os_strlen(store) + 1) * sizeof(WCHAR));
677 if (wstore == NULL)
678 return -1;
679 wsprintf(wstore, L"%S", store);
680 cs = CertOpenSystemStore(0, wstore);
681 os_free(wstore);
682#else /* UNICODE */
683 cs = CertOpenSystemStore(0, store);
684#endif /* UNICODE */
685 if (cs == NULL) {
686 wpa_printf(MSG_DEBUG, "%s: failed to open system cert store "
687 "'%s': error=%d", __func__, store,
688 (int) GetLastError());
689 return -1;
690 }
691
692 while ((ctx = CertEnumCertificatesInStore(cs, ctx))) {
Dmitry Shmidt216983b2015-02-06 10:50:36 -0800693 cert = d2i_X509(NULL,
694 (const unsigned char **) &ctx->pbCertEncoded,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700695 ctx->cbCertEncoded);
696 if (cert == NULL) {
697 wpa_printf(MSG_INFO, "CryptoAPI: Could not process "
698 "X509 DER encoding for CA cert");
699 continue;
700 }
701
702 X509_NAME_oneline(X509_get_subject_name(cert), buf,
703 sizeof(buf));
704 wpa_printf(MSG_DEBUG, "OpenSSL: Loaded CA certificate for "
705 "system certificate store: subject='%s'", buf);
706
Dmitry Shmidt849734c2016-05-27 09:59:01 -0700707 if (!X509_STORE_add_cert(SSL_CTX_get_cert_store(ssl_ctx),
708 cert)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700709 tls_show_errors(MSG_WARNING, __func__,
710 "Failed to add ca_cert to OpenSSL "
711 "certificate store");
712 }
713
714 X509_free(cert);
715 }
716
717 if (!CertCloseStore(cs, 0)) {
718 wpa_printf(MSG_DEBUG, "%s: failed to close system cert store "
719 "'%s': error=%d", __func__, name + 13,
720 (int) GetLastError());
721 }
722
723 return 0;
724}
725
726
727#else /* CONFIG_NATIVE_WINDOWS */
728
729static int tls_cryptoapi_cert(SSL *ssl, const char *name)
730{
731 return -1;
732}
733
734#endif /* CONFIG_NATIVE_WINDOWS */
735
736
737static void ssl_info_cb(const SSL *ssl, int where, int ret)
738{
739 const char *str;
740 int w;
741
742 wpa_printf(MSG_DEBUG, "SSL: (where=0x%x ret=0x%x)", where, ret);
743 w = where & ~SSL_ST_MASK;
744 if (w & SSL_ST_CONNECT)
745 str = "SSL_connect";
746 else if (w & SSL_ST_ACCEPT)
747 str = "SSL_accept";
748 else
749 str = "undefined";
750
751 if (where & SSL_CB_LOOP) {
752 wpa_printf(MSG_DEBUG, "SSL: %s:%s",
753 str, SSL_state_string_long(ssl));
754 } else if (where & SSL_CB_ALERT) {
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700755 struct tls_connection *conn = SSL_get_app_data((SSL *) ssl);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700756 wpa_printf(MSG_INFO, "SSL: SSL3 alert: %s:%s:%s",
757 where & SSL_CB_READ ?
758 "read (remote end reported an error)" :
759 "write (local SSL3 detected an error)",
760 SSL_alert_type_string_long(ret),
761 SSL_alert_desc_string_long(ret));
762 if ((ret >> 8) == SSL3_AL_FATAL) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700763 if (where & SSL_CB_READ)
764 conn->read_alerts++;
765 else
766 conn->write_alerts++;
767 }
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700768 if (conn->context->event_cb != NULL) {
Dmitry Shmidt04949592012-07-19 12:16:46 -0700769 union tls_event_data ev;
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700770 struct tls_context *context = conn->context;
Dmitry Shmidt04949592012-07-19 12:16:46 -0700771 os_memset(&ev, 0, sizeof(ev));
772 ev.alert.is_local = !(where & SSL_CB_READ);
773 ev.alert.type = SSL_alert_type_string_long(ret);
774 ev.alert.description = SSL_alert_desc_string_long(ret);
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700775 context->event_cb(context->cb_ctx, TLS_ALERT, &ev);
Dmitry Shmidt04949592012-07-19 12:16:46 -0700776 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700777 } else if (where & SSL_CB_EXIT && ret <= 0) {
778 wpa_printf(MSG_DEBUG, "SSL: %s:%s in %s",
779 str, ret == 0 ? "failed" : "error",
780 SSL_state_string_long(ssl));
781 }
782}
783
784
785#ifndef OPENSSL_NO_ENGINE
786/**
787 * tls_engine_load_dynamic_generic - load any openssl engine
788 * @pre: an array of commands and values that load an engine initialized
789 * in the engine specific function
790 * @post: an array of commands and values that initialize an already loaded
791 * engine (or %NULL if not required)
792 * @id: the engine id of the engine to load (only required if post is not %NULL
793 *
794 * This function is a generic function that loads any openssl engine.
795 *
796 * Returns: 0 on success, -1 on failure
797 */
798static int tls_engine_load_dynamic_generic(const char *pre[],
799 const char *post[], const char *id)
800{
801 ENGINE *engine;
802 const char *dynamic_id = "dynamic";
803
804 engine = ENGINE_by_id(id);
805 if (engine) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700806 wpa_printf(MSG_DEBUG, "ENGINE: engine '%s' is already "
807 "available", id);
Dmitry Shmidtd5ab1b52016-06-21 12:38:41 -0700808 /*
809 * If it was auto-loaded by ENGINE_by_id() we might still
810 * need to tell it which PKCS#11 module to use in legacy
811 * (non-p11-kit) environments. Do so now; even if it was
812 * properly initialised before, setting it again will be
813 * harmless.
814 */
815 goto found;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700816 }
817 ERR_clear_error();
818
819 engine = ENGINE_by_id(dynamic_id);
820 if (engine == NULL) {
821 wpa_printf(MSG_INFO, "ENGINE: Can't find engine %s [%s]",
822 dynamic_id,
823 ERR_error_string(ERR_get_error(), NULL));
824 return -1;
825 }
826
827 /* Perform the pre commands. This will load the engine. */
828 while (pre && pre[0]) {
829 wpa_printf(MSG_DEBUG, "ENGINE: '%s' '%s'", pre[0], pre[1]);
830 if (ENGINE_ctrl_cmd_string(engine, pre[0], pre[1], 0) == 0) {
831 wpa_printf(MSG_INFO, "ENGINE: ctrl cmd_string failed: "
832 "%s %s [%s]", pre[0], pre[1],
833 ERR_error_string(ERR_get_error(), NULL));
834 ENGINE_free(engine);
835 return -1;
836 }
837 pre += 2;
838 }
839
840 /*
841 * Free the reference to the "dynamic" engine. The loaded engine can
842 * now be looked up using ENGINE_by_id().
843 */
844 ENGINE_free(engine);
845
846 engine = ENGINE_by_id(id);
847 if (engine == NULL) {
848 wpa_printf(MSG_INFO, "ENGINE: Can't find engine %s [%s]",
849 id, ERR_error_string(ERR_get_error(), NULL));
850 return -1;
851 }
Dmitry Shmidtd5ab1b52016-06-21 12:38:41 -0700852 found:
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700853 while (post && post[0]) {
854 wpa_printf(MSG_DEBUG, "ENGINE: '%s' '%s'", post[0], post[1]);
855 if (ENGINE_ctrl_cmd_string(engine, post[0], post[1], 0) == 0) {
856 wpa_printf(MSG_DEBUG, "ENGINE: ctrl cmd_string failed:"
857 " %s %s [%s]", post[0], post[1],
858 ERR_error_string(ERR_get_error(), NULL));
859 ENGINE_remove(engine);
860 ENGINE_free(engine);
861 return -1;
862 }
863 post += 2;
864 }
865 ENGINE_free(engine);
866
867 return 0;
868}
869
870
871/**
872 * tls_engine_load_dynamic_pkcs11 - load the pkcs11 engine provided by opensc
873 * @pkcs11_so_path: pksc11_so_path from the configuration
874 * @pcks11_module_path: pkcs11_module_path from the configuration
875 */
876static int tls_engine_load_dynamic_pkcs11(const char *pkcs11_so_path,
877 const char *pkcs11_module_path)
878{
879 char *engine_id = "pkcs11";
880 const char *pre_cmd[] = {
881 "SO_PATH", NULL /* pkcs11_so_path */,
882 "ID", NULL /* engine_id */,
883 "LIST_ADD", "1",
884 /* "NO_VCHECK", "1", */
885 "LOAD", NULL,
886 NULL, NULL
887 };
888 const char *post_cmd[] = {
889 "MODULE_PATH", NULL /* pkcs11_module_path */,
890 NULL, NULL
891 };
892
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800893 if (!pkcs11_so_path)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700894 return 0;
895
896 pre_cmd[1] = pkcs11_so_path;
897 pre_cmd[3] = engine_id;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800898 if (pkcs11_module_path)
899 post_cmd[1] = pkcs11_module_path;
900 else
901 post_cmd[0] = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700902
903 wpa_printf(MSG_DEBUG, "ENGINE: Loading pkcs11 Engine from %s",
904 pkcs11_so_path);
905
906 return tls_engine_load_dynamic_generic(pre_cmd, post_cmd, engine_id);
907}
908
909
910/**
911 * tls_engine_load_dynamic_opensc - load the opensc engine provided by opensc
912 * @opensc_so_path: opensc_so_path from the configuration
913 */
914static int tls_engine_load_dynamic_opensc(const char *opensc_so_path)
915{
916 char *engine_id = "opensc";
917 const char *pre_cmd[] = {
918 "SO_PATH", NULL /* opensc_so_path */,
919 "ID", NULL /* engine_id */,
920 "LIST_ADD", "1",
921 "LOAD", NULL,
922 NULL, NULL
923 };
924
925 if (!opensc_so_path)
926 return 0;
927
928 pre_cmd[1] = opensc_so_path;
929 pre_cmd[3] = engine_id;
930
931 wpa_printf(MSG_DEBUG, "ENGINE: Loading OpenSC Engine from %s",
932 opensc_so_path);
933
934 return tls_engine_load_dynamic_generic(pre_cmd, NULL, engine_id);
935}
936#endif /* OPENSSL_NO_ENGINE */
937
938
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800939static void remove_session_cb(SSL_CTX *ctx, SSL_SESSION *sess)
940{
941 struct wpabuf *buf;
942
943 if (tls_ex_idx_session < 0)
944 return;
945 buf = SSL_SESSION_get_ex_data(sess, tls_ex_idx_session);
946 if (!buf)
947 return;
948 wpa_printf(MSG_DEBUG,
949 "OpenSSL: Free application session data %p (sess %p)",
950 buf, sess);
951 wpabuf_free(buf);
952
953 SSL_SESSION_set_ex_data(sess, tls_ex_idx_session, NULL);
954}
955
956
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700957void * tls_init(const struct tls_config *conf)
958{
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800959 struct tls_data *data;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700960 SSL_CTX *ssl;
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700961 struct tls_context *context;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800962 const char *ciphers;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700963
964 if (tls_openssl_ref_count == 0) {
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700965 tls_global = context = tls_context_new(conf);
966 if (context == NULL)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700967 return NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700968#ifdef CONFIG_FIPS
969#ifdef OPENSSL_FIPS
970 if (conf && conf->fips_mode) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800971 static int fips_enabled = 0;
972
973 if (!fips_enabled && !FIPS_mode_set(1)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700974 wpa_printf(MSG_ERROR, "Failed to enable FIPS "
975 "mode");
976 ERR_load_crypto_strings();
977 ERR_print_errors_fp(stderr);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700978 os_free(tls_global);
979 tls_global = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700980 return NULL;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800981 } else {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700982 wpa_printf(MSG_INFO, "Running in FIPS mode");
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800983 fips_enabled = 1;
984 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700985 }
986#else /* OPENSSL_FIPS */
987 if (conf && conf->fips_mode) {
988 wpa_printf(MSG_ERROR, "FIPS mode requested, but not "
989 "supported");
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700990 os_free(tls_global);
991 tls_global = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700992 return NULL;
993 }
994#endif /* OPENSSL_FIPS */
995#endif /* CONFIG_FIPS */
Roshan Pius3a1667e2018-07-03 15:17:14 -0700996#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
997 (defined(LIBRESSL_VERSION_NUMBER) && \
998 LIBRESSL_VERSION_NUMBER < 0x20700000L)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700999 SSL_load_error_strings();
1000 SSL_library_init();
Dmitry Shmidt216983b2015-02-06 10:50:36 -08001001#ifndef OPENSSL_NO_SHA256
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001002 EVP_add_digest(EVP_sha256());
1003#endif /* OPENSSL_NO_SHA256 */
1004 /* TODO: if /dev/urandom is available, PRNG is seeded
1005 * automatically. If this is not the case, random data should
1006 * be added here. */
1007
1008#ifdef PKCS12_FUNCS
1009#ifndef OPENSSL_NO_RC2
1010 /*
1011 * 40-bit RC2 is commonly used in PKCS#12 files, so enable it.
1012 * This is enabled by PKCS12_PBE_add() in OpenSSL 0.9.8
1013 * versions, but it looks like OpenSSL 1.0.0 does not do that
1014 * anymore.
1015 */
1016 EVP_add_cipher(EVP_rc2_40_cbc());
1017#endif /* OPENSSL_NO_RC2 */
1018 PKCS12_PBE_add();
1019#endif /* PKCS12_FUNCS */
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08001020#endif /* < 1.1.0 */
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001021 } else {
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001022 context = tls_context_new(conf);
1023 if (context == NULL)
1024 return NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001025 }
1026 tls_openssl_ref_count++;
1027
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001028 data = os_zalloc(sizeof(*data));
1029 if (data)
1030 ssl = SSL_CTX_new(SSLv23_method());
1031 else
1032 ssl = NULL;
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001033 if (ssl == NULL) {
1034 tls_openssl_ref_count--;
Dmitry Shmidt68d0e3e2013-10-28 17:59:21 -07001035 if (context != tls_global)
1036 os_free(context);
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001037 if (tls_openssl_ref_count == 0) {
1038 os_free(tls_global);
1039 tls_global = NULL;
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001040 }
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08001041 os_free(data);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001042 return NULL;
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001043 }
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001044 data->ssl = ssl;
Hai Shalom39bc25d2019-02-06 16:32:13 -08001045 if (conf) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001046 data->tls_session_lifetime = conf->tls_session_lifetime;
Hai Shalom39bc25d2019-02-06 16:32:13 -08001047 data->crl_reload_interval = conf->crl_reload_interval;
1048 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001049
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001050 SSL_CTX_set_options(ssl, SSL_OP_NO_SSLv2);
1051 SSL_CTX_set_options(ssl, SSL_OP_NO_SSLv3);
1052
Dmitry Shmidt29333592017-01-09 12:27:11 -08001053#ifdef SSL_MODE_NO_AUTO_CHAIN
1054 /* Number of deployed use cases assume the default OpenSSL behavior of
1055 * auto chaining the local certificate is in use. BoringSSL removed this
1056 * functionality by default, so we need to restore it here to avoid
1057 * breaking existing use cases. */
1058 SSL_CTX_clear_mode(ssl, SSL_MODE_NO_AUTO_CHAIN);
1059#endif /* SSL_MODE_NO_AUTO_CHAIN */
1060
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001061 SSL_CTX_set_info_callback(ssl, ssl_info_cb);
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001062 SSL_CTX_set_app_data(ssl, context);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001063 if (data->tls_session_lifetime > 0) {
1064 SSL_CTX_set_quiet_shutdown(ssl, 1);
1065 /*
1066 * Set default context here. In practice, this will be replaced
1067 * by the per-EAP method context in tls_connection_set_verify().
1068 */
1069 SSL_CTX_set_session_id_context(ssl, (u8 *) "hostapd", 7);
1070 SSL_CTX_set_session_cache_mode(ssl, SSL_SESS_CACHE_SERVER);
1071 SSL_CTX_set_timeout(ssl, data->tls_session_lifetime);
1072 SSL_CTX_sess_set_remove_cb(ssl, remove_session_cb);
1073 } else {
1074 SSL_CTX_set_session_cache_mode(ssl, SSL_SESS_CACHE_OFF);
1075 }
1076
1077 if (tls_ex_idx_session < 0) {
1078 tls_ex_idx_session = SSL_SESSION_get_ex_new_index(
1079 0, NULL, NULL, NULL, NULL);
1080 if (tls_ex_idx_session < 0) {
1081 tls_deinit(data);
1082 return NULL;
1083 }
1084 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001085
1086#ifndef OPENSSL_NO_ENGINE
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001087 wpa_printf(MSG_DEBUG, "ENGINE: Loading dynamic engine");
Hai Shalomce48b4a2018-09-05 11:41:35 -07001088#if OPENSSL_VERSION_NUMBER < 0x10100000L
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001089 ERR_load_ENGINE_strings();
1090 ENGINE_load_dynamic();
Hai Shalomce48b4a2018-09-05 11:41:35 -07001091#endif /* OPENSSL_VERSION_NUMBER */
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001092
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001093 if (conf &&
1094 (conf->opensc_engine_path || conf->pkcs11_engine_path ||
1095 conf->pkcs11_module_path)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001096 if (tls_engine_load_dynamic_opensc(conf->opensc_engine_path) ||
1097 tls_engine_load_dynamic_pkcs11(conf->pkcs11_engine_path,
1098 conf->pkcs11_module_path)) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001099 tls_deinit(data);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001100 return NULL;
1101 }
1102 }
1103#endif /* OPENSSL_NO_ENGINE */
1104
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001105 if (conf && conf->openssl_ciphers)
1106 ciphers = conf->openssl_ciphers;
1107 else
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001108 ciphers = TLS_DEFAULT_CIPHERS;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001109 if (SSL_CTX_set_cipher_list(ssl, ciphers) != 1) {
1110 wpa_printf(MSG_ERROR,
1111 "OpenSSL: Failed to set cipher string '%s'",
1112 ciphers);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001113 tls_deinit(data);
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001114 return NULL;
1115 }
1116
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001117 return data;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001118}
1119
1120
1121void tls_deinit(void *ssl_ctx)
1122{
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001123 struct tls_data *data = ssl_ctx;
1124 SSL_CTX *ssl = data->ssl;
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001125 struct tls_context *context = SSL_CTX_get_app_data(ssl);
1126 if (context != tls_global)
1127 os_free(context);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001128 if (data->tls_session_lifetime > 0)
1129 SSL_CTX_flush_sessions(ssl, 0);
Hai Shalom39bc25d2019-02-06 16:32:13 -08001130 os_free(data->ca_cert);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001131 SSL_CTX_free(ssl);
1132
1133 tls_openssl_ref_count--;
1134 if (tls_openssl_ref_count == 0) {
Roshan Pius3a1667e2018-07-03 15:17:14 -07001135#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
1136 (defined(LIBRESSL_VERSION_NUMBER) && \
1137 LIBRESSL_VERSION_NUMBER < 0x20700000L)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001138#ifndef OPENSSL_NO_ENGINE
1139 ENGINE_cleanup();
1140#endif /* OPENSSL_NO_ENGINE */
1141 CRYPTO_cleanup_all_ex_data();
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -07001142 ERR_remove_thread_state(NULL);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001143 ERR_free_strings();
1144 EVP_cleanup();
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08001145#endif /* < 1.1.0 */
Dmitry Shmidt34af3062013-07-11 10:46:32 -07001146 os_free(tls_global->ocsp_stapling_response);
1147 tls_global->ocsp_stapling_response = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001148 os_free(tls_global);
1149 tls_global = NULL;
1150 }
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001151
1152 os_free(data);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001153}
1154
1155
Dmitry Shmidt1d755d02015-04-28 10:34:29 -07001156#ifndef OPENSSL_NO_ENGINE
1157
1158/* Cryptoki return values */
1159#define CKR_PIN_INCORRECT 0x000000a0
1160#define CKR_PIN_INVALID 0x000000a1
1161#define CKR_PIN_LEN_RANGE 0x000000a2
1162
1163/* libp11 */
1164#define ERR_LIB_PKCS11 ERR_LIB_USER
1165
1166static int tls_is_pin_error(unsigned int err)
1167{
1168 return ERR_GET_LIB(err) == ERR_LIB_PKCS11 &&
1169 (ERR_GET_REASON(err) == CKR_PIN_INCORRECT ||
1170 ERR_GET_REASON(err) == CKR_PIN_INVALID ||
1171 ERR_GET_REASON(err) == CKR_PIN_LEN_RANGE);
1172}
1173
1174#endif /* OPENSSL_NO_ENGINE */
1175
1176
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001177#ifdef ANDROID
1178/* EVP_PKEY_from_keystore comes from system/security/keystore-engine. */
1179EVP_PKEY * EVP_PKEY_from_keystore(const char *key_id);
1180#endif /* ANDROID */
1181
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001182static int tls_engine_init(struct tls_connection *conn, const char *engine_id,
1183 const char *pin, const char *key_id,
1184 const char *cert_id, const char *ca_cert_id)
1185{
Adam Langley1eb02ed2015-04-21 19:00:05 -07001186#if defined(ANDROID) && defined(OPENSSL_IS_BORINGSSL)
1187#if !defined(OPENSSL_NO_ENGINE)
1188#error "This code depends on OPENSSL_NO_ENGINE being defined by BoringSSL."
1189#endif
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001190 if (!key_id)
1191 return TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED;
Adam Langley1eb02ed2015-04-21 19:00:05 -07001192 conn->engine = NULL;
1193 conn->private_key = EVP_PKEY_from_keystore(key_id);
1194 if (!conn->private_key) {
1195 wpa_printf(MSG_ERROR,
1196 "ENGINE: cannot load private key with id '%s' [%s]",
1197 key_id,
1198 ERR_error_string(ERR_get_error(), NULL));
1199 return TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED;
1200 }
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001201#endif /* ANDROID && OPENSSL_IS_BORINGSSL */
Adam Langley1eb02ed2015-04-21 19:00:05 -07001202
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001203#ifndef OPENSSL_NO_ENGINE
1204 int ret = -1;
1205 if (engine_id == NULL) {
1206 wpa_printf(MSG_ERROR, "ENGINE: Engine ID not set");
1207 return -1;
1208 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001209
1210 ERR_clear_error();
Kenny Rootdb3c5a42012-03-20 17:00:47 -07001211#ifdef ANDROID
1212 ENGINE_load_dynamic();
1213#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001214 conn->engine = ENGINE_by_id(engine_id);
1215 if (!conn->engine) {
1216 wpa_printf(MSG_ERROR, "ENGINE: engine %s not available [%s]",
1217 engine_id, ERR_error_string(ERR_get_error(), NULL));
1218 goto err;
1219 }
1220 if (ENGINE_init(conn->engine) != 1) {
1221 wpa_printf(MSG_ERROR, "ENGINE: engine init failed "
1222 "(engine: %s) [%s]", engine_id,
1223 ERR_error_string(ERR_get_error(), NULL));
1224 goto err;
1225 }
1226 wpa_printf(MSG_DEBUG, "ENGINE: engine initialized");
1227
Kenny Rootdb3c5a42012-03-20 17:00:47 -07001228#ifndef ANDROID
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001229 if (pin && ENGINE_ctrl_cmd_string(conn->engine, "PIN", pin, 0) == 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001230 wpa_printf(MSG_ERROR, "ENGINE: cannot set pin [%s]",
1231 ERR_error_string(ERR_get_error(), NULL));
1232 goto err;
1233 }
Kenny Rootdb3c5a42012-03-20 17:00:47 -07001234#endif
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001235 if (key_id) {
1236 /*
1237 * Ensure that the ENGINE does not attempt to use the OpenSSL
1238 * UI system to obtain a PIN, if we didn't provide one.
1239 */
1240 struct {
1241 const void *password;
1242 const char *prompt_info;
1243 } key_cb = { "", NULL };
1244
1245 /* load private key first in-case PIN is required for cert */
1246 conn->private_key = ENGINE_load_private_key(conn->engine,
1247 key_id, NULL,
1248 &key_cb);
1249 if (!conn->private_key) {
Dmitry Shmidt1d755d02015-04-28 10:34:29 -07001250 unsigned long err = ERR_get_error();
1251
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001252 wpa_printf(MSG_ERROR,
1253 "ENGINE: cannot load private key with id '%s' [%s]",
1254 key_id,
Dmitry Shmidt1d755d02015-04-28 10:34:29 -07001255 ERR_error_string(err, NULL));
1256 if (tls_is_pin_error(err))
1257 ret = TLS_SET_PARAMS_ENGINE_PRV_BAD_PIN;
1258 else
1259 ret = TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001260 goto err;
1261 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001262 }
1263
1264 /* handle a certificate and/or CA certificate */
1265 if (cert_id || ca_cert_id) {
1266 const char *cmd_name = "LOAD_CERT_CTRL";
1267
1268 /* test if the engine supports a LOAD_CERT_CTRL */
1269 if (!ENGINE_ctrl(conn->engine, ENGINE_CTRL_GET_CMD_FROM_NAME,
1270 0, (void *)cmd_name, NULL)) {
1271 wpa_printf(MSG_ERROR, "ENGINE: engine does not support"
1272 " loading certificates");
1273 ret = TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED;
1274 goto err;
1275 }
1276 }
1277
1278 return 0;
1279
1280err:
1281 if (conn->engine) {
1282 ENGINE_free(conn->engine);
1283 conn->engine = NULL;
1284 }
1285
1286 if (conn->private_key) {
1287 EVP_PKEY_free(conn->private_key);
1288 conn->private_key = NULL;
1289 }
1290
1291 return ret;
1292#else /* OPENSSL_NO_ENGINE */
1293 return 0;
1294#endif /* OPENSSL_NO_ENGINE */
1295}
1296
1297
1298static void tls_engine_deinit(struct tls_connection *conn)
1299{
Adam Langley1eb02ed2015-04-21 19:00:05 -07001300#if defined(ANDROID) || !defined(OPENSSL_NO_ENGINE)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001301 wpa_printf(MSG_DEBUG, "ENGINE: engine deinit");
1302 if (conn->private_key) {
1303 EVP_PKEY_free(conn->private_key);
1304 conn->private_key = NULL;
1305 }
1306 if (conn->engine) {
Adam Langley1eb02ed2015-04-21 19:00:05 -07001307#if !defined(OPENSSL_IS_BORINGSSL)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001308 ENGINE_finish(conn->engine);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001309#endif /* !OPENSSL_IS_BORINGSSL */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001310 conn->engine = NULL;
1311 }
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001312#endif /* ANDROID || !OPENSSL_NO_ENGINE */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001313}
1314
1315
1316int tls_get_errors(void *ssl_ctx)
1317{
1318 int count = 0;
1319 unsigned long err;
1320
1321 while ((err = ERR_get_error())) {
1322 wpa_printf(MSG_INFO, "TLS - SSL error: %s",
1323 ERR_error_string(err, NULL));
1324 count++;
1325 }
1326
1327 return count;
1328}
1329
Jouni Malinen26af48b2014-04-09 13:02:53 +03001330
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001331static const char * openssl_content_type(int content_type)
1332{
1333 switch (content_type) {
1334 case 20:
1335 return "change cipher spec";
1336 case 21:
1337 return "alert";
1338 case 22:
1339 return "handshake";
1340 case 23:
1341 return "application data";
1342 case 24:
1343 return "heartbeat";
1344 case 256:
1345 return "TLS header info"; /* pseudo content type */
1346 default:
1347 return "?";
1348 }
1349}
1350
1351
1352static const char * openssl_handshake_type(int content_type, const u8 *buf,
1353 size_t len)
1354{
1355 if (content_type != 22 || !buf || len == 0)
1356 return "";
1357 switch (buf[0]) {
1358 case 0:
1359 return "hello request";
1360 case 1:
1361 return "client hello";
1362 case 2:
1363 return "server hello";
1364 case 4:
1365 return "new session ticket";
1366 case 11:
1367 return "certificate";
1368 case 12:
1369 return "server key exchange";
1370 case 13:
1371 return "certificate request";
1372 case 14:
1373 return "server hello done";
1374 case 15:
1375 return "certificate verify";
1376 case 16:
1377 return "client key exchange";
1378 case 20:
1379 return "finished";
1380 case 21:
1381 return "certificate url";
1382 case 22:
1383 return "certificate status";
1384 default:
1385 return "?";
1386 }
1387}
1388
1389
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001390#ifdef CONFIG_SUITEB
1391
1392static void check_server_hello(struct tls_connection *conn,
1393 const u8 *pos, const u8 *end)
1394{
1395 size_t payload_len, id_len;
1396
1397 /*
1398 * Parse ServerHello to get the selected cipher suite since OpenSSL does
1399 * not make it cleanly available during handshake and we need to know
1400 * whether DHE was selected.
1401 */
1402
1403 if (end - pos < 3)
1404 return;
1405 payload_len = WPA_GET_BE24(pos);
1406 pos += 3;
1407
1408 if ((size_t) (end - pos) < payload_len)
1409 return;
1410 end = pos + payload_len;
1411
1412 /* Skip Version and Random */
1413 if (end - pos < 2 + SSL3_RANDOM_SIZE)
1414 return;
1415 pos += 2 + SSL3_RANDOM_SIZE;
1416
1417 /* Skip Session ID */
1418 if (end - pos < 1)
1419 return;
1420 id_len = *pos++;
1421 if ((size_t) (end - pos) < id_len)
1422 return;
1423 pos += id_len;
1424
1425 if (end - pos < 2)
1426 return;
1427 conn->cipher_suite = WPA_GET_BE16(pos);
1428 wpa_printf(MSG_DEBUG, "OpenSSL: Server selected cipher suite 0x%x",
1429 conn->cipher_suite);
1430}
1431
1432
1433static void check_server_key_exchange(SSL *ssl, struct tls_connection *conn,
1434 const u8 *pos, const u8 *end)
1435{
1436 size_t payload_len;
1437 u16 dh_len;
1438 BIGNUM *p;
1439 int bits;
1440
1441 if (!(conn->flags & TLS_CONN_SUITEB))
1442 return;
1443
1444 /* DHE is enabled only with DHE-RSA-AES256-GCM-SHA384 */
1445 if (conn->cipher_suite != 0x9f)
1446 return;
1447
1448 if (end - pos < 3)
1449 return;
1450 payload_len = WPA_GET_BE24(pos);
1451 pos += 3;
1452
1453 if ((size_t) (end - pos) < payload_len)
1454 return;
1455 end = pos + payload_len;
1456
1457 if (end - pos < 2)
1458 return;
1459 dh_len = WPA_GET_BE16(pos);
1460 pos += 2;
1461
1462 if ((size_t) (end - pos) < dh_len)
1463 return;
1464 p = BN_bin2bn(pos, dh_len, NULL);
1465 if (!p)
1466 return;
1467
1468 bits = BN_num_bits(p);
1469 BN_free(p);
1470
1471 conn->server_dh_prime_len = bits;
1472 wpa_printf(MSG_DEBUG, "OpenSSL: Server DH prime length: %d bits",
1473 conn->server_dh_prime_len);
1474}
1475
1476#endif /* CONFIG_SUITEB */
1477
1478
Jouni Malinen26af48b2014-04-09 13:02:53 +03001479static void tls_msg_cb(int write_p, int version, int content_type,
1480 const void *buf, size_t len, SSL *ssl, void *arg)
1481{
1482 struct tls_connection *conn = arg;
1483 const u8 *pos = buf;
1484
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001485 if (write_p == 2) {
1486 wpa_printf(MSG_DEBUG,
1487 "OpenSSL: session ver=0x%x content_type=%d",
1488 version, content_type);
1489 wpa_hexdump_key(MSG_MSGDUMP, "OpenSSL: Data", buf, len);
1490 return;
1491 }
1492
1493 wpa_printf(MSG_DEBUG, "OpenSSL: %s ver=0x%x content_type=%d (%s/%s)",
1494 write_p ? "TX" : "RX", version, content_type,
1495 openssl_content_type(content_type),
1496 openssl_handshake_type(content_type, buf, len));
Jouni Malinen26af48b2014-04-09 13:02:53 +03001497 wpa_hexdump_key(MSG_MSGDUMP, "OpenSSL: Message", buf, len);
1498 if (content_type == 24 && len >= 3 && pos[0] == 1) {
1499 size_t payload_len = WPA_GET_BE16(pos + 1);
1500 if (payload_len + 3 > len) {
1501 wpa_printf(MSG_ERROR, "OpenSSL: Heartbeat attack detected");
1502 conn->invalid_hb_used = 1;
1503 }
1504 }
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001505
1506#ifdef CONFIG_SUITEB
1507 /*
1508 * Need to parse these handshake messages to be able to check DH prime
1509 * length since OpenSSL does not expose the new cipher suite and DH
1510 * parameters during handshake (e.g., for cert_cb() callback).
1511 */
1512 if (content_type == 22 && pos && len > 0 && pos[0] == 2)
1513 check_server_hello(conn, pos + 1, pos + len);
1514 if (content_type == 22 && pos && len > 0 && pos[0] == 12)
1515 check_server_key_exchange(ssl, conn, pos + 1, pos + len);
1516#endif /* CONFIG_SUITEB */
Jouni Malinen26af48b2014-04-09 13:02:53 +03001517}
1518
1519
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001520struct tls_connection * tls_connection_init(void *ssl_ctx)
1521{
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001522 struct tls_data *data = ssl_ctx;
1523 SSL_CTX *ssl = data->ssl;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001524 struct tls_connection *conn;
1525 long options;
Hai Shalom39bc25d2019-02-06 16:32:13 -08001526 X509_STORE *new_cert_store;
1527 struct os_reltime now;
Dmitry Shmidt7d5c8f22014-03-03 13:53:28 -08001528 struct tls_context *context = SSL_CTX_get_app_data(ssl);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001529
Hai Shalom39bc25d2019-02-06 16:32:13 -08001530 /* Replace X509 store if it is time to update CRL. */
1531 if (data->crl_reload_interval > 0 && os_get_reltime(&now) == 0 &&
1532 os_reltime_expired(&now, &data->crl_last_reload,
1533 data->crl_reload_interval)) {
1534 wpa_printf(MSG_INFO,
1535 "OpenSSL: Flushing X509 store with ca_cert file");
1536 new_cert_store = tls_crl_cert_reload(data->ca_cert,
1537 data->check_crl);
1538 if (!new_cert_store) {
1539 wpa_printf(MSG_ERROR,
1540 "OpenSSL: Error replacing X509 store with ca_cert file");
1541 } else {
1542 /* Replace old store */
1543 SSL_CTX_set_cert_store(ssl, new_cert_store);
1544 data->crl_last_reload = now;
1545 }
1546 }
1547
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001548 conn = os_zalloc(sizeof(*conn));
1549 if (conn == NULL)
1550 return NULL;
Hai Shalom39bc25d2019-02-06 16:32:13 -08001551 conn->data = data;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001552 conn->ssl_ctx = ssl;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001553 conn->ssl = SSL_new(ssl);
1554 if (conn->ssl == NULL) {
1555 tls_show_errors(MSG_INFO, __func__,
1556 "Failed to initialize new SSL connection");
1557 os_free(conn);
1558 return NULL;
1559 }
1560
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001561 conn->context = context;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001562 SSL_set_app_data(conn->ssl, conn);
Jouni Malinen26af48b2014-04-09 13:02:53 +03001563 SSL_set_msg_callback(conn->ssl, tls_msg_cb);
1564 SSL_set_msg_callback_arg(conn->ssl, conn);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001565 options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
1566 SSL_OP_SINGLE_DH_USE;
1567#ifdef SSL_OP_NO_COMPRESSION
1568 options |= SSL_OP_NO_COMPRESSION;
1569#endif /* SSL_OP_NO_COMPRESSION */
1570 SSL_set_options(conn->ssl, options);
1571
1572 conn->ssl_in = BIO_new(BIO_s_mem());
1573 if (!conn->ssl_in) {
1574 tls_show_errors(MSG_INFO, __func__,
1575 "Failed to create a new BIO for ssl_in");
1576 SSL_free(conn->ssl);
1577 os_free(conn);
1578 return NULL;
1579 }
1580
1581 conn->ssl_out = BIO_new(BIO_s_mem());
1582 if (!conn->ssl_out) {
1583 tls_show_errors(MSG_INFO, __func__,
1584 "Failed to create a new BIO for ssl_out");
1585 SSL_free(conn->ssl);
1586 BIO_free(conn->ssl_in);
1587 os_free(conn);
1588 return NULL;
1589 }
1590
1591 SSL_set_bio(conn->ssl, conn->ssl_in, conn->ssl_out);
1592
1593 return conn;
1594}
1595
1596
1597void tls_connection_deinit(void *ssl_ctx, struct tls_connection *conn)
1598{
1599 if (conn == NULL)
1600 return;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001601 if (conn->success_data) {
1602 /*
1603 * Make sure ssl_clear_bad_session() does not remove this
1604 * session.
1605 */
1606 SSL_set_quiet_shutdown(conn->ssl, 1);
1607 SSL_shutdown(conn->ssl);
1608 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001609 SSL_free(conn->ssl);
1610 tls_engine_deinit(conn);
1611 os_free(conn->subject_match);
1612 os_free(conn->altsubject_match);
Dmitry Shmidt051af732013-10-22 13:52:46 -07001613 os_free(conn->suffix_match);
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001614 os_free(conn->domain_match);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001615 os_free(conn->session_ticket);
1616 os_free(conn);
1617}
1618
1619
1620int tls_connection_established(void *ssl_ctx, struct tls_connection *conn)
1621{
1622 return conn ? SSL_is_init_finished(conn->ssl) : 0;
1623}
1624
1625
Hai Shalom39ba6fc2019-01-22 12:40:38 -08001626char * tls_connection_peer_serial_num(void *tls_ctx,
1627 struct tls_connection *conn)
1628{
1629 ASN1_INTEGER *ser;
1630 char *serial_num;
1631 size_t len;
1632
1633 if (!conn->peer_cert)
1634 return NULL;
1635
1636 ser = X509_get_serialNumber(conn->peer_cert);
1637 if (!ser)
1638 return NULL;
1639
1640 len = ASN1_STRING_length(ser) * 2 + 1;
1641 serial_num = os_malloc(len);
1642 if (!serial_num)
1643 return NULL;
1644 wpa_snprintf_hex_uppercase(serial_num, len,
1645 ASN1_STRING_get0_data(ser),
1646 ASN1_STRING_length(ser));
1647 return serial_num;
1648}
1649
1650
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001651int tls_connection_shutdown(void *ssl_ctx, struct tls_connection *conn)
1652{
1653 if (conn == NULL)
1654 return -1;
1655
1656 /* Shutdown previous TLS connection without notifying the peer
1657 * because the connection was already terminated in practice
1658 * and "close notify" shutdown alert would confuse AS. */
1659 SSL_set_quiet_shutdown(conn->ssl, 1);
1660 SSL_shutdown(conn->ssl);
Jouni Malinenf291c682015-08-17 22:50:41 +03001661 return SSL_clear(conn->ssl) == 1 ? 0 : -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001662}
1663
1664
1665static int tls_match_altsubject_component(X509 *cert, int type,
1666 const char *value, size_t len)
1667{
1668 GENERAL_NAME *gen;
1669 void *ext;
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -07001670 int found = 0;
1671 stack_index_t i;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001672
1673 ext = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
1674
1675 for (i = 0; ext && i < sk_GENERAL_NAME_num(ext); i++) {
1676 gen = sk_GENERAL_NAME_value(ext, i);
1677 if (gen->type != type)
1678 continue;
1679 if (os_strlen((char *) gen->d.ia5->data) == len &&
1680 os_memcmp(value, gen->d.ia5->data, len) == 0)
1681 found++;
1682 }
1683
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08001684 sk_GENERAL_NAME_pop_free(ext, GENERAL_NAME_free);
1685
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001686 return found;
1687}
1688
1689
1690static int tls_match_altsubject(X509 *cert, const char *match)
1691{
1692 int type;
1693 const char *pos, *end;
1694 size_t len;
1695
1696 pos = match;
1697 do {
1698 if (os_strncmp(pos, "EMAIL:", 6) == 0) {
1699 type = GEN_EMAIL;
1700 pos += 6;
1701 } else if (os_strncmp(pos, "DNS:", 4) == 0) {
1702 type = GEN_DNS;
1703 pos += 4;
1704 } else if (os_strncmp(pos, "URI:", 4) == 0) {
1705 type = GEN_URI;
1706 pos += 4;
1707 } else {
1708 wpa_printf(MSG_INFO, "TLS: Invalid altSubjectName "
1709 "match '%s'", pos);
1710 return 0;
1711 }
1712 end = os_strchr(pos, ';');
1713 while (end) {
1714 if (os_strncmp(end + 1, "EMAIL:", 6) == 0 ||
1715 os_strncmp(end + 1, "DNS:", 4) == 0 ||
1716 os_strncmp(end + 1, "URI:", 4) == 0)
1717 break;
1718 end = os_strchr(end + 1, ';');
1719 }
1720 if (end)
1721 len = end - pos;
1722 else
1723 len = os_strlen(pos);
1724 if (tls_match_altsubject_component(cert, type, pos, len) > 0)
1725 return 1;
1726 pos = end + 1;
1727 } while (end);
1728
1729 return 0;
1730}
1731
1732
Dmitry Shmidtfa3fc4a2013-11-21 13:34:38 -08001733#ifndef CONFIG_NATIVE_WINDOWS
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001734static int domain_suffix_match(const u8 *val, size_t len, const char *match,
1735 int full)
Dmitry Shmidt051af732013-10-22 13:52:46 -07001736{
1737 size_t i, match_len;
1738
1739 /* Check for embedded nuls that could mess up suffix matching */
1740 for (i = 0; i < len; i++) {
1741 if (val[i] == '\0') {
1742 wpa_printf(MSG_DEBUG, "TLS: Embedded null in a string - reject");
1743 return 0;
1744 }
1745 }
1746
1747 match_len = os_strlen(match);
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001748 if (match_len > len || (full && match_len != len))
Dmitry Shmidt051af732013-10-22 13:52:46 -07001749 return 0;
1750
1751 if (os_strncasecmp((const char *) val + len - match_len, match,
1752 match_len) != 0)
1753 return 0; /* no match */
1754
1755 if (match_len == len)
1756 return 1; /* exact match */
1757
1758 if (val[len - match_len - 1] == '.')
1759 return 1; /* full label match completes suffix match */
1760
1761 wpa_printf(MSG_DEBUG, "TLS: Reject due to incomplete label match");
1762 return 0;
1763}
Dmitry Shmidtfa3fc4a2013-11-21 13:34:38 -08001764#endif /* CONFIG_NATIVE_WINDOWS */
Dmitry Shmidt051af732013-10-22 13:52:46 -07001765
1766
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001767static int tls_match_suffix(X509 *cert, const char *match, int full)
Dmitry Shmidt051af732013-10-22 13:52:46 -07001768{
Dmitry Shmidtfa3fc4a2013-11-21 13:34:38 -08001769#ifdef CONFIG_NATIVE_WINDOWS
1770 /* wincrypt.h has conflicting X509_NAME definition */
1771 return -1;
1772#else /* CONFIG_NATIVE_WINDOWS */
Dmitry Shmidt051af732013-10-22 13:52:46 -07001773 GENERAL_NAME *gen;
1774 void *ext;
1775 int i;
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -07001776 stack_index_t j;
Dmitry Shmidt051af732013-10-22 13:52:46 -07001777 int dns_name = 0;
1778 X509_NAME *name;
1779
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001780 wpa_printf(MSG_DEBUG, "TLS: Match domain against %s%s",
1781 full ? "": "suffix ", match);
Dmitry Shmidt051af732013-10-22 13:52:46 -07001782
1783 ext = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
1784
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -07001785 for (j = 0; ext && j < sk_GENERAL_NAME_num(ext); j++) {
1786 gen = sk_GENERAL_NAME_value(ext, j);
Dmitry Shmidt051af732013-10-22 13:52:46 -07001787 if (gen->type != GEN_DNS)
1788 continue;
1789 dns_name++;
1790 wpa_hexdump_ascii(MSG_DEBUG, "TLS: Certificate dNSName",
1791 gen->d.dNSName->data,
1792 gen->d.dNSName->length);
1793 if (domain_suffix_match(gen->d.dNSName->data,
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001794 gen->d.dNSName->length, match, full) ==
1795 1) {
1796 wpa_printf(MSG_DEBUG, "TLS: %s in dNSName found",
1797 full ? "Match" : "Suffix match");
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08001798 sk_GENERAL_NAME_pop_free(ext, GENERAL_NAME_free);
Dmitry Shmidt051af732013-10-22 13:52:46 -07001799 return 1;
1800 }
1801 }
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08001802 sk_GENERAL_NAME_pop_free(ext, GENERAL_NAME_free);
Dmitry Shmidt051af732013-10-22 13:52:46 -07001803
1804 if (dns_name) {
1805 wpa_printf(MSG_DEBUG, "TLS: None of the dNSName(s) matched");
1806 return 0;
1807 }
1808
1809 name = X509_get_subject_name(cert);
1810 i = -1;
1811 for (;;) {
1812 X509_NAME_ENTRY *e;
1813 ASN1_STRING *cn;
1814
1815 i = X509_NAME_get_index_by_NID(name, NID_commonName, i);
1816 if (i == -1)
1817 break;
1818 e = X509_NAME_get_entry(name, i);
1819 if (e == NULL)
1820 continue;
1821 cn = X509_NAME_ENTRY_get_data(e);
1822 if (cn == NULL)
1823 continue;
1824 wpa_hexdump_ascii(MSG_DEBUG, "TLS: Certificate commonName",
1825 cn->data, cn->length);
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001826 if (domain_suffix_match(cn->data, cn->length, match, full) == 1)
1827 {
1828 wpa_printf(MSG_DEBUG, "TLS: %s in commonName found",
1829 full ? "Match" : "Suffix match");
Dmitry Shmidt051af732013-10-22 13:52:46 -07001830 return 1;
1831 }
1832 }
1833
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001834 wpa_printf(MSG_DEBUG, "TLS: No CommonName %smatch found",
1835 full ? "": "suffix ");
Dmitry Shmidt051af732013-10-22 13:52:46 -07001836 return 0;
Dmitry Shmidtfa3fc4a2013-11-21 13:34:38 -08001837#endif /* CONFIG_NATIVE_WINDOWS */
Dmitry Shmidt051af732013-10-22 13:52:46 -07001838}
1839
1840
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001841static enum tls_fail_reason openssl_tls_fail_reason(int err)
1842{
1843 switch (err) {
1844 case X509_V_ERR_CERT_REVOKED:
1845 return TLS_FAIL_REVOKED;
1846 case X509_V_ERR_CERT_NOT_YET_VALID:
1847 case X509_V_ERR_CRL_NOT_YET_VALID:
1848 return TLS_FAIL_NOT_YET_VALID;
1849 case X509_V_ERR_CERT_HAS_EXPIRED:
1850 case X509_V_ERR_CRL_HAS_EXPIRED:
1851 return TLS_FAIL_EXPIRED;
1852 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
1853 case X509_V_ERR_UNABLE_TO_GET_CRL:
1854 case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
1855 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
1856 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
1857 case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
1858 case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
1859 case X509_V_ERR_CERT_CHAIN_TOO_LONG:
1860 case X509_V_ERR_PATH_LENGTH_EXCEEDED:
1861 case X509_V_ERR_INVALID_CA:
1862 return TLS_FAIL_UNTRUSTED;
1863 case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
1864 case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
1865 case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
1866 case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
1867 case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
1868 case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
1869 case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
1870 case X509_V_ERR_CERT_UNTRUSTED:
1871 case X509_V_ERR_CERT_REJECTED:
1872 return TLS_FAIL_BAD_CERTIFICATE;
1873 default:
1874 return TLS_FAIL_UNSPECIFIED;
1875 }
1876}
1877
1878
1879static struct wpabuf * get_x509_cert(X509 *cert)
1880{
1881 struct wpabuf *buf;
1882 u8 *tmp;
1883
1884 int cert_len = i2d_X509(cert, NULL);
1885 if (cert_len <= 0)
1886 return NULL;
1887
1888 buf = wpabuf_alloc(cert_len);
1889 if (buf == NULL)
1890 return NULL;
1891
1892 tmp = wpabuf_put(buf, cert_len);
1893 i2d_X509(cert, &tmp);
1894 return buf;
1895}
1896
1897
1898static void openssl_tls_fail_event(struct tls_connection *conn,
1899 X509 *err_cert, int err, int depth,
1900 const char *subject, const char *err_str,
1901 enum tls_fail_reason reason)
1902{
1903 union tls_event_data ev;
1904 struct wpabuf *cert = NULL;
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001905 struct tls_context *context = conn->context;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001906
Pavel Grafov4d8552e2018-02-06 11:28:29 +00001907#ifdef ANDROID
1908 log_cert_validation_failure(err_str);
1909#endif
1910
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001911 if (context->event_cb == NULL)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001912 return;
1913
1914 cert = get_x509_cert(err_cert);
1915 os_memset(&ev, 0, sizeof(ev));
1916 ev.cert_fail.reason = reason != TLS_FAIL_UNSPECIFIED ?
1917 reason : openssl_tls_fail_reason(err);
1918 ev.cert_fail.depth = depth;
1919 ev.cert_fail.subject = subject;
1920 ev.cert_fail.reason_txt = err_str;
1921 ev.cert_fail.cert = cert;
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001922 context->event_cb(context->cb_ctx, TLS_CERT_CHAIN_FAILURE, &ev);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001923 wpabuf_free(cert);
1924}
1925
1926
1927static void openssl_tls_cert_event(struct tls_connection *conn,
1928 X509 *err_cert, int depth,
1929 const char *subject)
1930{
1931 struct wpabuf *cert = NULL;
1932 union tls_event_data ev;
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001933 struct tls_context *context = conn->context;
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001934 char *altsubject[TLS_MAX_ALT_SUBJECT];
1935 int alt, num_altsubject = 0;
1936 GENERAL_NAME *gen;
1937 void *ext;
1938 stack_index_t i;
Hai Shalom39ba6fc2019-01-22 12:40:38 -08001939 ASN1_INTEGER *ser;
1940 char serial_num[128];
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001941#ifdef CONFIG_SHA256
1942 u8 hash[32];
1943#endif /* CONFIG_SHA256 */
1944
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001945 if (context->event_cb == NULL)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001946 return;
1947
1948 os_memset(&ev, 0, sizeof(ev));
Dmitry Shmidt55840ad2015-12-14 12:45:46 -08001949 if (conn->cert_probe || (conn->flags & TLS_CONN_EXT_CERT_CHECK) ||
1950 context->cert_in_cb) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001951 cert = get_x509_cert(err_cert);
1952 ev.peer_cert.cert = cert;
1953 }
1954#ifdef CONFIG_SHA256
1955 if (cert) {
1956 const u8 *addr[1];
1957 size_t len[1];
1958 addr[0] = wpabuf_head(cert);
1959 len[0] = wpabuf_len(cert);
1960 if (sha256_vector(1, addr, len, hash) == 0) {
1961 ev.peer_cert.hash = hash;
1962 ev.peer_cert.hash_len = sizeof(hash);
1963 }
1964 }
1965#endif /* CONFIG_SHA256 */
1966 ev.peer_cert.depth = depth;
1967 ev.peer_cert.subject = subject;
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001968
Hai Shalom39ba6fc2019-01-22 12:40:38 -08001969 ser = X509_get_serialNumber(err_cert);
1970 if (ser) {
1971 wpa_snprintf_hex_uppercase(serial_num, sizeof(serial_num),
1972 ASN1_STRING_get0_data(ser),
1973 ASN1_STRING_length(ser));
1974 ev.peer_cert.serial_num = serial_num;
1975 }
1976
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001977 ext = X509_get_ext_d2i(err_cert, NID_subject_alt_name, NULL, NULL);
1978 for (i = 0; ext && i < sk_GENERAL_NAME_num(ext); i++) {
1979 char *pos;
1980
1981 if (num_altsubject == TLS_MAX_ALT_SUBJECT)
1982 break;
1983 gen = sk_GENERAL_NAME_value(ext, i);
1984 if (gen->type != GEN_EMAIL &&
1985 gen->type != GEN_DNS &&
1986 gen->type != GEN_URI)
1987 continue;
1988
1989 pos = os_malloc(10 + gen->d.ia5->length + 1);
1990 if (pos == NULL)
1991 break;
1992 altsubject[num_altsubject++] = pos;
1993
1994 switch (gen->type) {
1995 case GEN_EMAIL:
1996 os_memcpy(pos, "EMAIL:", 6);
1997 pos += 6;
1998 break;
1999 case GEN_DNS:
2000 os_memcpy(pos, "DNS:", 4);
2001 pos += 4;
2002 break;
2003 case GEN_URI:
2004 os_memcpy(pos, "URI:", 4);
2005 pos += 4;
2006 break;
2007 }
2008
2009 os_memcpy(pos, gen->d.ia5->data, gen->d.ia5->length);
2010 pos += gen->d.ia5->length;
2011 *pos = '\0';
2012 }
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08002013 sk_GENERAL_NAME_pop_free(ext, GENERAL_NAME_free);
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08002014
2015 for (alt = 0; alt < num_altsubject; alt++)
2016 ev.peer_cert.altsubject[alt] = altsubject[alt];
2017 ev.peer_cert.num_altsubject = num_altsubject;
2018
Dmitry Shmidtea69e842013-05-13 14:52:28 -07002019 context->event_cb(context->cb_ctx, TLS_PEER_CERTIFICATE, &ev);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002020 wpabuf_free(cert);
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08002021 for (alt = 0; alt < num_altsubject; alt++)
2022 os_free(altsubject[alt]);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002023}
2024
2025
2026static int tls_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx)
2027{
2028 char buf[256];
2029 X509 *err_cert;
2030 int err, depth;
2031 SSL *ssl;
2032 struct tls_connection *conn;
Dmitry Shmidtea69e842013-05-13 14:52:28 -07002033 struct tls_context *context;
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08002034 char *match, *altmatch, *suffix_match, *domain_match;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002035 const char *err_str;
2036
2037 err_cert = X509_STORE_CTX_get_current_cert(x509_ctx);
Dmitry Shmidt96be6222014-02-13 10:16:51 -08002038 if (!err_cert)
2039 return 0;
2040
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002041 err = X509_STORE_CTX_get_error(x509_ctx);
2042 depth = X509_STORE_CTX_get_error_depth(x509_ctx);
2043 ssl = X509_STORE_CTX_get_ex_data(x509_ctx,
2044 SSL_get_ex_data_X509_STORE_CTX_idx());
2045 X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof(buf));
2046
2047 conn = SSL_get_app_data(ssl);
2048 if (conn == NULL)
2049 return 0;
Dmitry Shmidt34af3062013-07-11 10:46:32 -07002050
2051 if (depth == 0)
2052 conn->peer_cert = err_cert;
2053 else if (depth == 1)
2054 conn->peer_issuer = err_cert;
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08002055 else if (depth == 2)
2056 conn->peer_issuer_issuer = err_cert;
Dmitry Shmidt34af3062013-07-11 10:46:32 -07002057
Dmitry Shmidtea69e842013-05-13 14:52:28 -07002058 context = conn->context;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002059 match = conn->subject_match;
2060 altmatch = conn->altsubject_match;
Dmitry Shmidt051af732013-10-22 13:52:46 -07002061 suffix_match = conn->suffix_match;
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08002062 domain_match = conn->domain_match;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002063
2064 if (!preverify_ok && !conn->ca_cert_verify)
2065 preverify_ok = 1;
2066 if (!preverify_ok && depth > 0 && conn->server_cert_only)
2067 preverify_ok = 1;
Dmitry Shmidtc55524a2011-07-07 11:18:38 -07002068 if (!preverify_ok && (conn->flags & TLS_CONN_DISABLE_TIME_CHECKS) &&
2069 (err == X509_V_ERR_CERT_HAS_EXPIRED ||
2070 err == X509_V_ERR_CERT_NOT_YET_VALID)) {
2071 wpa_printf(MSG_DEBUG, "OpenSSL: Ignore certificate validity "
2072 "time mismatch");
2073 preverify_ok = 1;
2074 }
Hai Shalom39bc25d2019-02-06 16:32:13 -08002075 if (!preverify_ok && !conn->data->check_crl_strict &&
2076 (err == X509_V_ERR_CRL_HAS_EXPIRED ||
2077 err == X509_V_ERR_CRL_NOT_YET_VALID)) {
2078 wpa_printf(MSG_DEBUG,
2079 "OpenSSL: Ignore certificate validity CRL time mismatch");
2080 preverify_ok = 1;
2081 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002082
2083 err_str = X509_verify_cert_error_string(err);
2084
2085#ifdef CONFIG_SHA256
Dmitry Shmidt4dd28dc2015-03-10 11:21:43 -07002086 /*
2087 * Do not require preverify_ok so we can explicity allow otherwise
2088 * invalid pinned server certificates.
2089 */
2090 if (depth == 0 && conn->server_cert_only) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002091 struct wpabuf *cert;
2092 cert = get_x509_cert(err_cert);
2093 if (!cert) {
2094 wpa_printf(MSG_DEBUG, "OpenSSL: Could not fetch "
2095 "server certificate data");
2096 preverify_ok = 0;
2097 } else {
2098 u8 hash[32];
2099 const u8 *addr[1];
2100 size_t len[1];
2101 addr[0] = wpabuf_head(cert);
2102 len[0] = wpabuf_len(cert);
2103 if (sha256_vector(1, addr, len, hash) < 0 ||
2104 os_memcmp(conn->srv_cert_hash, hash, 32) != 0) {
2105 err_str = "Server certificate mismatch";
2106 err = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
2107 preverify_ok = 0;
Dmitry Shmidt4dd28dc2015-03-10 11:21:43 -07002108 } else if (!preverify_ok) {
2109 /*
2110 * Certificate matches pinned certificate, allow
2111 * regardless of other problems.
2112 */
2113 wpa_printf(MSG_DEBUG,
2114 "OpenSSL: Ignore validation issues for a pinned server certificate");
2115 preverify_ok = 1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002116 }
2117 wpabuf_free(cert);
2118 }
2119 }
2120#endif /* CONFIG_SHA256 */
2121
2122 if (!preverify_ok) {
2123 wpa_printf(MSG_WARNING, "TLS: Certificate verification failed,"
2124 " error %d (%s) depth %d for '%s'", err, err_str,
2125 depth, buf);
2126 openssl_tls_fail_event(conn, err_cert, err, depth, buf,
2127 err_str, TLS_FAIL_UNSPECIFIED);
2128 return preverify_ok;
2129 }
2130
2131 wpa_printf(MSG_DEBUG, "TLS: tls_verify_cb - preverify_ok=%d "
2132 "err=%d (%s) ca_cert_verify=%d depth=%d buf='%s'",
2133 preverify_ok, err, err_str,
2134 conn->ca_cert_verify, depth, buf);
2135 if (depth == 0 && match && os_strstr(buf, match) == NULL) {
2136 wpa_printf(MSG_WARNING, "TLS: Subject '%s' did not "
2137 "match with '%s'", buf, match);
2138 preverify_ok = 0;
2139 openssl_tls_fail_event(conn, err_cert, err, depth, buf,
2140 "Subject mismatch",
2141 TLS_FAIL_SUBJECT_MISMATCH);
2142 } else if (depth == 0 && altmatch &&
2143 !tls_match_altsubject(err_cert, altmatch)) {
2144 wpa_printf(MSG_WARNING, "TLS: altSubjectName match "
2145 "'%s' not found", altmatch);
2146 preverify_ok = 0;
2147 openssl_tls_fail_event(conn, err_cert, err, depth, buf,
2148 "AltSubject mismatch",
2149 TLS_FAIL_ALTSUBJECT_MISMATCH);
Dmitry Shmidt051af732013-10-22 13:52:46 -07002150 } else if (depth == 0 && suffix_match &&
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08002151 !tls_match_suffix(err_cert, suffix_match, 0)) {
Dmitry Shmidt051af732013-10-22 13:52:46 -07002152 wpa_printf(MSG_WARNING, "TLS: Domain suffix match '%s' not found",
2153 suffix_match);
2154 preverify_ok = 0;
2155 openssl_tls_fail_event(conn, err_cert, err, depth, buf,
2156 "Domain suffix mismatch",
2157 TLS_FAIL_DOMAIN_SUFFIX_MISMATCH);
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08002158 } else if (depth == 0 && domain_match &&
2159 !tls_match_suffix(err_cert, domain_match, 1)) {
2160 wpa_printf(MSG_WARNING, "TLS: Domain match '%s' not found",
2161 domain_match);
2162 preverify_ok = 0;
2163 openssl_tls_fail_event(conn, err_cert, err, depth, buf,
2164 "Domain mismatch",
2165 TLS_FAIL_DOMAIN_MISMATCH);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002166 } else
2167 openssl_tls_cert_event(conn, err_cert, depth, buf);
2168
2169 if (conn->cert_probe && preverify_ok && depth == 0) {
2170 wpa_printf(MSG_DEBUG, "OpenSSL: Reject server certificate "
2171 "on probe-only run");
2172 preverify_ok = 0;
2173 openssl_tls_fail_event(conn, err_cert, err, depth, buf,
2174 "Server certificate chain probe",
2175 TLS_FAIL_SERVER_CHAIN_PROBE);
2176 }
2177
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002178#ifdef CONFIG_SUITEB
2179 if (conn->flags & TLS_CONN_SUITEB) {
2180 EVP_PKEY *pk;
2181 RSA *rsa;
2182 int len = -1;
2183
2184 pk = X509_get_pubkey(err_cert);
2185 if (pk) {
2186 rsa = EVP_PKEY_get1_RSA(pk);
2187 if (rsa) {
2188 len = RSA_bits(rsa);
2189 RSA_free(rsa);
2190 }
2191 EVP_PKEY_free(pk);
2192 }
2193
2194 if (len >= 0) {
2195 wpa_printf(MSG_DEBUG,
2196 "OpenSSL: RSA modulus size: %d bits", len);
2197 if (len < 3072) {
2198 preverify_ok = 0;
2199 openssl_tls_fail_event(
2200 conn, err_cert, err,
2201 depth, buf,
2202 "Insufficient RSA modulus size",
2203 TLS_FAIL_INSUFFICIENT_KEY_LEN);
2204 }
2205 }
2206 }
2207#endif /* CONFIG_SUITEB */
2208
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002209#ifdef OPENSSL_IS_BORINGSSL
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08002210 if (depth == 0 && (conn->flags & TLS_CONN_REQUEST_OCSP) &&
2211 preverify_ok) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002212 enum ocsp_result res;
2213
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08002214 res = check_ocsp_resp(conn->ssl_ctx, conn->ssl, err_cert,
2215 conn->peer_issuer,
2216 conn->peer_issuer_issuer);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002217 if (res == OCSP_REVOKED) {
2218 preverify_ok = 0;
2219 openssl_tls_fail_event(conn, err_cert, err, depth, buf,
2220 "certificate revoked",
2221 TLS_FAIL_REVOKED);
2222 if (err == X509_V_OK)
2223 X509_STORE_CTX_set_error(
2224 x509_ctx, X509_V_ERR_CERT_REVOKED);
2225 } else if (res != OCSP_GOOD &&
2226 (conn->flags & TLS_CONN_REQUIRE_OCSP)) {
2227 preverify_ok = 0;
2228 openssl_tls_fail_event(conn, err_cert, err, depth, buf,
2229 "bad certificate status response",
2230 TLS_FAIL_UNSPECIFIED);
2231 }
2232 }
2233#endif /* OPENSSL_IS_BORINGSSL */
2234
Dmitry Shmidt55840ad2015-12-14 12:45:46 -08002235 if (depth == 0 && preverify_ok && context->event_cb != NULL)
Dmitry Shmidtea69e842013-05-13 14:52:28 -07002236 context->event_cb(context->cb_ctx,
2237 TLS_CERT_CHAIN_SUCCESS, NULL);
Dmitry Shmidt04949592012-07-19 12:16:46 -07002238
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002239 return preverify_ok;
2240}
2241
2242
2243#ifndef OPENSSL_NO_STDIO
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002244static int tls_load_ca_der(struct tls_data *data, const char *ca_cert)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002245{
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002246 SSL_CTX *ssl_ctx = data->ssl;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002247 X509_LOOKUP *lookup;
2248 int ret = 0;
2249
Dmitry Shmidt216983b2015-02-06 10:50:36 -08002250 lookup = X509_STORE_add_lookup(SSL_CTX_get_cert_store(ssl_ctx),
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002251 X509_LOOKUP_file());
2252 if (lookup == NULL) {
2253 tls_show_errors(MSG_WARNING, __func__,
2254 "Failed add lookup for X509 store");
2255 return -1;
2256 }
2257
2258 if (!X509_LOOKUP_load_file(lookup, ca_cert, X509_FILETYPE_ASN1)) {
2259 unsigned long err = ERR_peek_error();
2260 tls_show_errors(MSG_WARNING, __func__,
2261 "Failed load CA in DER format");
2262 if (ERR_GET_LIB(err) == ERR_LIB_X509 &&
2263 ERR_GET_REASON(err) == X509_R_CERT_ALREADY_IN_HASH_TABLE) {
2264 wpa_printf(MSG_DEBUG, "OpenSSL: %s - ignoring "
2265 "cert already in hash table error",
2266 __func__);
2267 } else
2268 ret = -1;
2269 }
2270
2271 return ret;
2272}
2273#endif /* OPENSSL_NO_STDIO */
2274
2275
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002276static int tls_connection_ca_cert(struct tls_data *data,
2277 struct tls_connection *conn,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002278 const char *ca_cert, const u8 *ca_cert_blob,
2279 size_t ca_cert_blob_len, const char *ca_path)
2280{
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002281 SSL_CTX *ssl_ctx = data->ssl;
Dmitry Shmidt216983b2015-02-06 10:50:36 -08002282 X509_STORE *store;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002283
2284 /*
2285 * Remove previously configured trusted CA certificates before adding
2286 * new ones.
2287 */
Dmitry Shmidt216983b2015-02-06 10:50:36 -08002288 store = X509_STORE_new();
2289 if (store == NULL) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002290 wpa_printf(MSG_DEBUG, "OpenSSL: %s - failed to allocate new "
2291 "certificate store", __func__);
2292 return -1;
2293 }
Dmitry Shmidt216983b2015-02-06 10:50:36 -08002294 SSL_CTX_set_cert_store(ssl_ctx, store);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002295
2296 SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb);
2297 conn->ca_cert_verify = 1;
2298
2299 if (ca_cert && os_strncmp(ca_cert, "probe://", 8) == 0) {
2300 wpa_printf(MSG_DEBUG, "OpenSSL: Probe for server certificate "
2301 "chain");
2302 conn->cert_probe = 1;
2303 conn->ca_cert_verify = 0;
2304 return 0;
2305 }
2306
2307 if (ca_cert && os_strncmp(ca_cert, "hash://", 7) == 0) {
2308#ifdef CONFIG_SHA256
2309 const char *pos = ca_cert + 7;
2310 if (os_strncmp(pos, "server/sha256/", 14) != 0) {
2311 wpa_printf(MSG_DEBUG, "OpenSSL: Unsupported ca_cert "
2312 "hash value '%s'", ca_cert);
2313 return -1;
2314 }
2315 pos += 14;
2316 if (os_strlen(pos) != 32 * 2) {
2317 wpa_printf(MSG_DEBUG, "OpenSSL: Unexpected SHA256 "
2318 "hash length in ca_cert '%s'", ca_cert);
2319 return -1;
2320 }
2321 if (hexstr2bin(pos, conn->srv_cert_hash, 32) < 0) {
2322 wpa_printf(MSG_DEBUG, "OpenSSL: Invalid SHA256 hash "
2323 "value in ca_cert '%s'", ca_cert);
2324 return -1;
2325 }
2326 conn->server_cert_only = 1;
2327 wpa_printf(MSG_DEBUG, "OpenSSL: Checking only server "
2328 "certificate match");
2329 return 0;
2330#else /* CONFIG_SHA256 */
2331 wpa_printf(MSG_INFO, "No SHA256 included in the build - "
2332 "cannot validate server certificate hash");
2333 return -1;
2334#endif /* CONFIG_SHA256 */
2335 }
2336
2337 if (ca_cert_blob) {
Dmitry Shmidt216983b2015-02-06 10:50:36 -08002338 X509 *cert = d2i_X509(NULL,
2339 (const unsigned char **) &ca_cert_blob,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002340 ca_cert_blob_len);
2341 if (cert == NULL) {
2342 tls_show_errors(MSG_WARNING, __func__,
2343 "Failed to parse ca_cert_blob");
2344 return -1;
2345 }
2346
Dmitry Shmidt216983b2015-02-06 10:50:36 -08002347 if (!X509_STORE_add_cert(SSL_CTX_get_cert_store(ssl_ctx),
2348 cert)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002349 unsigned long err = ERR_peek_error();
2350 tls_show_errors(MSG_WARNING, __func__,
2351 "Failed to add ca_cert_blob to "
2352 "certificate store");
2353 if (ERR_GET_LIB(err) == ERR_LIB_X509 &&
2354 ERR_GET_REASON(err) ==
2355 X509_R_CERT_ALREADY_IN_HASH_TABLE) {
2356 wpa_printf(MSG_DEBUG, "OpenSSL: %s - ignoring "
2357 "cert already in hash table error",
2358 __func__);
2359 } else {
2360 X509_free(cert);
2361 return -1;
2362 }
2363 }
2364 X509_free(cert);
2365 wpa_printf(MSG_DEBUG, "OpenSSL: %s - added ca_cert_blob "
2366 "to certificate store", __func__);
2367 return 0;
2368 }
2369
2370#ifdef ANDROID
Dmitry Shmidtb97e4282016-02-08 10:16:07 -08002371 /* Single alias */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002372 if (ca_cert && os_strncmp("keystore://", ca_cert, 11) == 0) {
Dmitry Shmidt849734c2016-05-27 09:59:01 -07002373 if (tls_add_ca_from_keystore(SSL_CTX_get_cert_store(ssl_ctx),
Dmitry Shmidtb97e4282016-02-08 10:16:07 -08002374 &ca_cert[11]) < 0)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002375 return -1;
Dmitry Shmidtb97e4282016-02-08 10:16:07 -08002376 SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb);
2377 return 0;
2378 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002379
Dmitry Shmidtb97e4282016-02-08 10:16:07 -08002380 /* Multiple aliases separated by space */
2381 if (ca_cert && os_strncmp("keystores://", ca_cert, 12) == 0) {
2382 char *aliases = os_strdup(&ca_cert[12]);
2383 const char *delim = " ";
2384 int rc = 0;
2385 char *savedptr;
2386 char *alias;
2387
2388 if (!aliases)
2389 return -1;
2390 alias = strtok_r(aliases, delim, &savedptr);
2391 for (; alias; alias = strtok_r(NULL, delim, &savedptr)) {
2392 if (tls_add_ca_from_keystore_encoded(
Dmitry Shmidt849734c2016-05-27 09:59:01 -07002393 SSL_CTX_get_cert_store(ssl_ctx), alias)) {
Dmitry Shmidtb97e4282016-02-08 10:16:07 -08002394 wpa_printf(MSG_WARNING,
2395 "OpenSSL: %s - Failed to add ca_cert %s from keystore",
2396 __func__, alias);
2397 rc = -1;
2398 break;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002399 }
2400 }
Dmitry Shmidtb97e4282016-02-08 10:16:07 -08002401 os_free(aliases);
2402 if (rc)
2403 return rc;
2404
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002405 SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb);
2406 return 0;
2407 }
2408#endif /* ANDROID */
2409
2410#ifdef CONFIG_NATIVE_WINDOWS
2411 if (ca_cert && tls_cryptoapi_ca_cert(ssl_ctx, conn->ssl, ca_cert) ==
2412 0) {
2413 wpa_printf(MSG_DEBUG, "OpenSSL: Added CA certificates from "
2414 "system certificate store");
2415 return 0;
2416 }
2417#endif /* CONFIG_NATIVE_WINDOWS */
2418
2419 if (ca_cert || ca_path) {
2420#ifndef OPENSSL_NO_STDIO
2421 if (SSL_CTX_load_verify_locations(ssl_ctx, ca_cert, ca_path) !=
2422 1) {
2423 tls_show_errors(MSG_WARNING, __func__,
2424 "Failed to load root certificates");
2425 if (ca_cert &&
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002426 tls_load_ca_der(data, ca_cert) == 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002427 wpa_printf(MSG_DEBUG, "OpenSSL: %s - loaded "
2428 "DER format CA certificate",
2429 __func__);
2430 } else
2431 return -1;
2432 } else {
2433 wpa_printf(MSG_DEBUG, "TLS: Trusted root "
2434 "certificate(s) loaded");
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002435 tls_get_errors(data);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002436 }
2437#else /* OPENSSL_NO_STDIO */
2438 wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO",
2439 __func__);
2440 return -1;
2441#endif /* OPENSSL_NO_STDIO */
2442 } else {
2443 /* No ca_cert configured - do not try to verify server
2444 * certificate */
2445 conn->ca_cert_verify = 0;
2446 }
2447
2448 return 0;
2449}
2450
2451
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002452static int tls_global_ca_cert(struct tls_data *data, const char *ca_cert)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002453{
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002454 SSL_CTX *ssl_ctx = data->ssl;
2455
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002456 if (ca_cert) {
2457 if (SSL_CTX_load_verify_locations(ssl_ctx, ca_cert, NULL) != 1)
2458 {
2459 tls_show_errors(MSG_WARNING, __func__,
2460 "Failed to load root certificates");
2461 return -1;
2462 }
2463
2464 wpa_printf(MSG_DEBUG, "TLS: Trusted root "
2465 "certificate(s) loaded");
2466
2467#ifndef OPENSSL_NO_STDIO
2468 /* Add the same CAs to the client certificate requests */
2469 SSL_CTX_set_client_CA_list(ssl_ctx,
2470 SSL_load_client_CA_file(ca_cert));
2471#endif /* OPENSSL_NO_STDIO */
Hai Shalom39bc25d2019-02-06 16:32:13 -08002472
2473 os_free(data->ca_cert);
2474 data->ca_cert = os_strdup(ca_cert);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002475 }
2476
2477 return 0;
2478}
2479
2480
Hai Shalom39bc25d2019-02-06 16:32:13 -08002481int tls_global_set_verify(void *ssl_ctx, int check_crl, int strict)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002482{
2483 int flags;
2484
2485 if (check_crl) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002486 struct tls_data *data = ssl_ctx;
2487 X509_STORE *cs = SSL_CTX_get_cert_store(data->ssl);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002488 if (cs == NULL) {
2489 tls_show_errors(MSG_INFO, __func__, "Failed to get "
2490 "certificate store when enabling "
2491 "check_crl");
2492 return -1;
2493 }
2494 flags = X509_V_FLAG_CRL_CHECK;
2495 if (check_crl == 2)
2496 flags |= X509_V_FLAG_CRL_CHECK_ALL;
2497 X509_STORE_set_flags(cs, flags);
Hai Shalom39bc25d2019-02-06 16:32:13 -08002498
2499 data->check_crl = check_crl;
2500 data->check_crl_strict = strict;
2501 os_get_reltime(&data->crl_last_reload);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002502 }
2503 return 0;
2504}
2505
2506
2507static int tls_connection_set_subject_match(struct tls_connection *conn,
2508 const char *subject_match,
Dmitry Shmidt051af732013-10-22 13:52:46 -07002509 const char *altsubject_match,
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08002510 const char *suffix_match,
2511 const char *domain_match)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002512{
2513 os_free(conn->subject_match);
2514 conn->subject_match = NULL;
2515 if (subject_match) {
2516 conn->subject_match = os_strdup(subject_match);
2517 if (conn->subject_match == NULL)
2518 return -1;
2519 }
2520
2521 os_free(conn->altsubject_match);
2522 conn->altsubject_match = NULL;
2523 if (altsubject_match) {
2524 conn->altsubject_match = os_strdup(altsubject_match);
2525 if (conn->altsubject_match == NULL)
2526 return -1;
2527 }
2528
Dmitry Shmidt051af732013-10-22 13:52:46 -07002529 os_free(conn->suffix_match);
2530 conn->suffix_match = NULL;
2531 if (suffix_match) {
2532 conn->suffix_match = os_strdup(suffix_match);
2533 if (conn->suffix_match == NULL)
2534 return -1;
2535 }
2536
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08002537 os_free(conn->domain_match);
2538 conn->domain_match = NULL;
2539 if (domain_match) {
2540 conn->domain_match = os_strdup(domain_match);
2541 if (conn->domain_match == NULL)
2542 return -1;
2543 }
2544
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002545 return 0;
2546}
2547
2548
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002549#ifdef CONFIG_SUITEB
2550#if OPENSSL_VERSION_NUMBER >= 0x10002000L
2551static int suiteb_cert_cb(SSL *ssl, void *arg)
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002552{
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002553 struct tls_connection *conn = arg;
2554
2555 /*
2556 * This cert_cb() is not really the best location for doing a
2557 * constraint check for the ServerKeyExchange message, but this seems to
2558 * be the only place where the current OpenSSL sequence can be
2559 * terminated cleanly with an TLS alert going out to the server.
2560 */
2561
2562 if (!(conn->flags & TLS_CONN_SUITEB))
2563 return 1;
2564
2565 /* DHE is enabled only with DHE-RSA-AES256-GCM-SHA384 */
2566 if (conn->cipher_suite != 0x9f)
2567 return 1;
2568
2569 if (conn->server_dh_prime_len >= 3072)
2570 return 1;
2571
2572 wpa_printf(MSG_DEBUG,
2573 "OpenSSL: Server DH prime length (%d bits) not sufficient for Suite B RSA - reject handshake",
2574 conn->server_dh_prime_len);
2575 return 0;
2576}
2577#endif /* OPENSSL_VERSION_NUMBER */
2578#endif /* CONFIG_SUITEB */
2579
2580
Roshan Pius3a1667e2018-07-03 15:17:14 -07002581static int tls_set_conn_flags(struct tls_connection *conn, unsigned int flags,
2582 const char *openssl_ciphers)
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002583{
2584 SSL *ssl = conn->ssl;
2585
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002586#ifdef SSL_OP_NO_TICKET
2587 if (flags & TLS_CONN_DISABLE_SESSION_TICKET)
2588 SSL_set_options(ssl, SSL_OP_NO_TICKET);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002589 else
2590 SSL_clear_options(ssl, SSL_OP_NO_TICKET);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002591#endif /* SSL_OP_NO_TICKET */
2592
2593#ifdef SSL_OP_NO_TLSv1
2594 if (flags & TLS_CONN_DISABLE_TLSv1_0)
2595 SSL_set_options(ssl, SSL_OP_NO_TLSv1);
2596 else
2597 SSL_clear_options(ssl, SSL_OP_NO_TLSv1);
2598#endif /* SSL_OP_NO_TLSv1 */
2599#ifdef SSL_OP_NO_TLSv1_1
2600 if (flags & TLS_CONN_DISABLE_TLSv1_1)
2601 SSL_set_options(ssl, SSL_OP_NO_TLSv1_1);
2602 else
2603 SSL_clear_options(ssl, SSL_OP_NO_TLSv1_1);
2604#endif /* SSL_OP_NO_TLSv1_1 */
2605#ifdef SSL_OP_NO_TLSv1_2
2606 if (flags & TLS_CONN_DISABLE_TLSv1_2)
2607 SSL_set_options(ssl, SSL_OP_NO_TLSv1_2);
2608 else
2609 SSL_clear_options(ssl, SSL_OP_NO_TLSv1_2);
2610#endif /* SSL_OP_NO_TLSv1_2 */
Roshan Pius3a1667e2018-07-03 15:17:14 -07002611#ifdef SSL_OP_NO_TLSv1_3
2612 if (flags & TLS_CONN_DISABLE_TLSv1_3)
2613 SSL_set_options(ssl, SSL_OP_NO_TLSv1_3);
2614 else
2615 SSL_clear_options(ssl, SSL_OP_NO_TLSv1_3);
2616#endif /* SSL_OP_NO_TLSv1_3 */
Hai Shalom39bc25d2019-02-06 16:32:13 -08002617#if OPENSSL_VERSION_NUMBER >= 0x10100000L
2618 if (flags & (TLS_CONN_ENABLE_TLSv1_0 |
2619 TLS_CONN_ENABLE_TLSv1_1 |
2620 TLS_CONN_ENABLE_TLSv1_2)) {
2621 int version = 0;
2622
2623 /* Explicit request to enable TLS versions even if needing to
2624 * override systemwide policies. */
2625 if (flags & TLS_CONN_ENABLE_TLSv1_0) {
2626 version = TLS1_VERSION;
2627 } else if (flags & TLS_CONN_ENABLE_TLSv1_1) {
2628 if (!(flags & TLS_CONN_DISABLE_TLSv1_0))
2629 version = TLS1_1_VERSION;
2630 } else if (flags & TLS_CONN_ENABLE_TLSv1_2) {
2631 if (!(flags & (TLS_CONN_DISABLE_TLSv1_0 |
2632 TLS_CONN_DISABLE_TLSv1_1)))
2633 version = TLS1_2_VERSION;
2634 }
2635 if (!version) {
2636 wpa_printf(MSG_DEBUG,
2637 "OpenSSL: Invalid TLS version configuration");
2638 return -1;
2639 }
2640
2641 if (SSL_set_min_proto_version(ssl, version) != 1) {
2642 wpa_printf(MSG_DEBUG,
2643 "OpenSSL: Failed to set minimum TLS version");
2644 return -1;
2645 }
2646 }
2647#endif /* >= 1.1.0 */
2648
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002649#ifdef CONFIG_SUITEB
Roshan Pius3a1667e2018-07-03 15:17:14 -07002650#ifdef OPENSSL_IS_BORINGSSL
2651 /* Start with defaults from BoringSSL */
2652 SSL_CTX_set_verify_algorithm_prefs(conn->ssl_ctx, NULL, 0);
2653#endif /* OPENSSL_IS_BORINGSSL */
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002654#if OPENSSL_VERSION_NUMBER >= 0x10002000L
2655 if (flags & TLS_CONN_SUITEB_NO_ECDH) {
2656 const char *ciphers = "DHE-RSA-AES256-GCM-SHA384";
2657
Roshan Pius3a1667e2018-07-03 15:17:14 -07002658 if (openssl_ciphers) {
2659 wpa_printf(MSG_DEBUG,
2660 "OpenSSL: Override ciphers for Suite B (no ECDH): %s",
2661 openssl_ciphers);
2662 ciphers = openssl_ciphers;
2663 }
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002664 if (SSL_set_cipher_list(ssl, ciphers) != 1) {
2665 wpa_printf(MSG_INFO,
2666 "OpenSSL: Failed to set Suite B ciphers");
2667 return -1;
2668 }
2669 } else if (flags & TLS_CONN_SUITEB) {
2670 EC_KEY *ecdh;
2671 const char *ciphers =
2672 "ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384";
Roshan Pius3a1667e2018-07-03 15:17:14 -07002673 int nid[1] = { NID_secp384r1 };
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002674
Roshan Pius3a1667e2018-07-03 15:17:14 -07002675 if (openssl_ciphers) {
2676 wpa_printf(MSG_DEBUG,
2677 "OpenSSL: Override ciphers for Suite B: %s",
2678 openssl_ciphers);
2679 ciphers = openssl_ciphers;
2680 }
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002681 if (SSL_set_cipher_list(ssl, ciphers) != 1) {
2682 wpa_printf(MSG_INFO,
2683 "OpenSSL: Failed to set Suite B ciphers");
2684 return -1;
2685 }
2686
Roshan Pius3a1667e2018-07-03 15:17:14 -07002687 if (SSL_set1_curves(ssl, nid, 1) != 1) {
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002688 wpa_printf(MSG_INFO,
2689 "OpenSSL: Failed to set Suite B curves");
2690 return -1;
2691 }
2692
2693 ecdh = EC_KEY_new_by_curve_name(NID_secp384r1);
2694 if (!ecdh || SSL_set_tmp_ecdh(ssl, ecdh) != 1) {
2695 EC_KEY_free(ecdh);
2696 wpa_printf(MSG_INFO,
2697 "OpenSSL: Failed to set ECDH parameter");
2698 return -1;
2699 }
2700 EC_KEY_free(ecdh);
2701 }
2702 if (flags & (TLS_CONN_SUITEB | TLS_CONN_SUITEB_NO_ECDH)) {
Roshan Pius3a1667e2018-07-03 15:17:14 -07002703#ifdef OPENSSL_IS_BORINGSSL
2704 uint16_t sigalgs[1] = { SSL_SIGN_RSA_PKCS1_SHA384 };
2705
2706 if (SSL_CTX_set_verify_algorithm_prefs(conn->ssl_ctx, sigalgs,
2707 1) != 1) {
2708 wpa_printf(MSG_INFO,
2709 "OpenSSL: Failed to set Suite B sigalgs");
2710 return -1;
2711 }
2712#else /* OPENSSL_IS_BORINGSSL */
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002713 /* ECDSA+SHA384 if need to add EC support here */
2714 if (SSL_set1_sigalgs_list(ssl, "RSA+SHA384") != 1) {
2715 wpa_printf(MSG_INFO,
2716 "OpenSSL: Failed to set Suite B sigalgs");
2717 return -1;
2718 }
Roshan Pius3a1667e2018-07-03 15:17:14 -07002719#endif /* OPENSSL_IS_BORINGSSL */
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002720
2721 SSL_set_options(ssl, SSL_OP_NO_TLSv1);
2722 SSL_set_options(ssl, SSL_OP_NO_TLSv1_1);
2723 SSL_set_cert_cb(ssl, suiteb_cert_cb, conn);
2724 }
2725#else /* OPENSSL_VERSION_NUMBER < 0x10002000L */
2726 if (flags & (TLS_CONN_SUITEB | TLS_CONN_SUITEB_NO_ECDH)) {
2727 wpa_printf(MSG_ERROR,
2728 "OpenSSL: Suite B RSA case not supported with this OpenSSL version");
2729 return -1;
2730 }
2731#endif /* OPENSSL_VERSION_NUMBER */
Roshan Pius3a1667e2018-07-03 15:17:14 -07002732
2733#ifdef OPENSSL_IS_BORINGSSL
2734 if (openssl_ciphers && os_strcmp(openssl_ciphers, "SUITEB192") == 0) {
2735 uint16_t sigalgs[1] = { SSL_SIGN_ECDSA_SECP384R1_SHA384 };
2736 int nid[1] = { NID_secp384r1 };
2737
2738 if (SSL_set1_curves(ssl, nid, 1) != 1) {
2739 wpa_printf(MSG_INFO,
2740 "OpenSSL: Failed to set Suite B curves");
2741 return -1;
2742 }
2743
2744 if (SSL_CTX_set_verify_algorithm_prefs(conn->ssl_ctx, sigalgs,
2745 1) != 1) {
2746 wpa_printf(MSG_INFO,
2747 "OpenSSL: Failed to set Suite B sigalgs");
2748 return -1;
2749 }
2750 }
Hai Shalom39bc25d2019-02-06 16:32:13 -08002751#else /* OPENSSL_IS_BORINGSSL */
2752 if (!(flags & (TLS_CONN_SUITEB | TLS_CONN_SUITEB_NO_ECDH)) &&
2753 openssl_ciphers && SSL_set_cipher_list(ssl, openssl_ciphers) != 1) {
2754 wpa_printf(MSG_INFO,
2755 "OpenSSL: Failed to set openssl_ciphers '%s'",
2756 openssl_ciphers);
2757 return -1;
2758 }
Roshan Pius3a1667e2018-07-03 15:17:14 -07002759#endif /* OPENSSL_IS_BORINGSSL */
Hai Shalom39bc25d2019-02-06 16:32:13 -08002760#else /* CONFIG_SUITEB */
2761 if (openssl_ciphers && SSL_set_cipher_list(ssl, openssl_ciphers) != 1) {
2762 wpa_printf(MSG_INFO,
2763 "OpenSSL: Failed to set openssl_ciphers '%s'",
2764 openssl_ciphers);
2765 return -1;
2766 }
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002767#endif /* CONFIG_SUITEB */
2768
2769 return 0;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002770}
2771
2772
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002773int tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn,
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002774 int verify_peer, unsigned int flags,
2775 const u8 *session_ctx, size_t session_ctx_len)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002776{
2777 static int counter = 0;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002778 struct tls_data *data = ssl_ctx;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002779
2780 if (conn == NULL)
2781 return -1;
2782
2783 if (verify_peer) {
2784 conn->ca_cert_verify = 1;
2785 SSL_set_verify(conn->ssl, SSL_VERIFY_PEER |
2786 SSL_VERIFY_FAIL_IF_NO_PEER_CERT |
2787 SSL_VERIFY_CLIENT_ONCE, tls_verify_cb);
2788 } else {
2789 conn->ca_cert_verify = 0;
2790 SSL_set_verify(conn->ssl, SSL_VERIFY_NONE, NULL);
2791 }
2792
Roshan Pius3a1667e2018-07-03 15:17:14 -07002793 if (tls_set_conn_flags(conn, flags, NULL) < 0)
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002794 return -1;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002795 conn->flags = flags;
2796
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002797 SSL_set_accept_state(conn->ssl);
2798
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002799 if (data->tls_session_lifetime == 0) {
2800 /*
2801 * Set session id context to a unique value to make sure
2802 * session resumption cannot be used either through session
2803 * caching or TLS ticket extension.
2804 */
2805 counter++;
2806 SSL_set_session_id_context(conn->ssl,
2807 (const unsigned char *) &counter,
2808 sizeof(counter));
2809 } else if (session_ctx) {
2810 SSL_set_session_id_context(conn->ssl, session_ctx,
2811 session_ctx_len);
2812 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002813
2814 return 0;
2815}
2816
2817
2818static int tls_connection_client_cert(struct tls_connection *conn,
2819 const char *client_cert,
2820 const u8 *client_cert_blob,
2821 size_t client_cert_blob_len)
2822{
2823 if (client_cert == NULL && client_cert_blob == NULL)
2824 return 0;
2825
Dmitry Shmidtde47be72016-01-07 12:52:55 -08002826#ifdef PKCS12_FUNCS
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002827#if OPENSSL_VERSION_NUMBER < 0x10002000L || defined(LIBRESSL_VERSION_NUMBER)
Dmitry Shmidtde47be72016-01-07 12:52:55 -08002828 /*
2829 * Clear previously set extra chain certificates, if any, from PKCS#12
2830 * processing in tls_parse_pkcs12() to allow OpenSSL to build a new
2831 * chain properly.
2832 */
2833 SSL_CTX_clear_extra_chain_certs(conn->ssl_ctx);
2834#endif /* OPENSSL_VERSION_NUMBER < 0x10002000L */
2835#endif /* PKCS12_FUNCS */
2836
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002837 if (client_cert_blob &&
2838 SSL_use_certificate_ASN1(conn->ssl, (u8 *) client_cert_blob,
2839 client_cert_blob_len) == 1) {
2840 wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_ASN1 --> "
2841 "OK");
2842 return 0;
2843 } else if (client_cert_blob) {
2844 tls_show_errors(MSG_DEBUG, __func__,
2845 "SSL_use_certificate_ASN1 failed");
2846 }
2847
2848 if (client_cert == NULL)
2849 return -1;
2850
2851#ifdef ANDROID
2852 if (os_strncmp("keystore://", client_cert, 11) == 0) {
2853 BIO *bio = BIO_from_keystore(&client_cert[11]);
2854 X509 *x509 = NULL;
2855 int ret = -1;
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002856 if (bio) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002857 x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002858 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002859 if (x509) {
2860 if (SSL_use_certificate(conn->ssl, x509) == 1)
2861 ret = 0;
2862 X509_free(x509);
2863 }
Paul Stewart50772e82017-01-25 13:59:16 -08002864
2865 /* Read additional certificates into the chain. */
2866 while (bio) {
2867 x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
2868 if (x509) {
2869 /* Takes ownership of x509 */
2870 SSL_add0_chain_cert(conn->ssl, x509);
2871 } else {
2872 BIO_free(bio);
2873 bio = NULL;
2874 }
2875 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002876 return ret;
2877 }
2878#endif /* ANDROID */
2879
2880#ifndef OPENSSL_NO_STDIO
2881 if (SSL_use_certificate_file(conn->ssl, client_cert,
2882 SSL_FILETYPE_ASN1) == 1) {
2883 wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_file (DER)"
2884 " --> OK");
2885 return 0;
2886 }
2887
Hai Shalom39bc25d2019-02-06 16:32:13 -08002888#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)\
2889 && !defined(ANDROID)
2890 if (SSL_use_certificate_chain_file(conn->ssl, client_cert) == 1) {
2891 ERR_clear_error();
2892 wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_chain_file"
2893 " --> OK");
2894 return 0;
2895 }
2896#else
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002897 if (SSL_use_certificate_file(conn->ssl, client_cert,
2898 SSL_FILETYPE_PEM) == 1) {
2899 ERR_clear_error();
2900 wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_file (PEM)"
2901 " --> OK");
2902 return 0;
2903 }
Hai Shalom39bc25d2019-02-06 16:32:13 -08002904#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002905
2906 tls_show_errors(MSG_DEBUG, __func__,
2907 "SSL_use_certificate_file failed");
2908#else /* OPENSSL_NO_STDIO */
2909 wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", __func__);
2910#endif /* OPENSSL_NO_STDIO */
2911
2912 return -1;
2913}
2914
2915
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002916static int tls_global_client_cert(struct tls_data *data,
2917 const char *client_cert)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002918{
2919#ifndef OPENSSL_NO_STDIO
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002920 SSL_CTX *ssl_ctx = data->ssl;
2921
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002922 if (client_cert == NULL)
2923 return 0;
2924
2925 if (SSL_CTX_use_certificate_file(ssl_ctx, client_cert,
2926 SSL_FILETYPE_ASN1) != 1 &&
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002927 SSL_CTX_use_certificate_chain_file(ssl_ctx, client_cert) != 1 &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002928 SSL_CTX_use_certificate_file(ssl_ctx, client_cert,
2929 SSL_FILETYPE_PEM) != 1) {
2930 tls_show_errors(MSG_INFO, __func__,
2931 "Failed to load client certificate");
2932 return -1;
2933 }
2934 return 0;
2935#else /* OPENSSL_NO_STDIO */
2936 if (client_cert == NULL)
2937 return 0;
2938 wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", __func__);
2939 return -1;
2940#endif /* OPENSSL_NO_STDIO */
2941}
2942
2943
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002944#ifdef PKCS12_FUNCS
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002945static int tls_parse_pkcs12(struct tls_data *data, SSL *ssl, PKCS12 *p12,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002946 const char *passwd)
2947{
2948 EVP_PKEY *pkey;
2949 X509 *cert;
2950 STACK_OF(X509) *certs;
2951 int res = 0;
2952 char buf[256];
2953
2954 pkey = NULL;
2955 cert = NULL;
2956 certs = NULL;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002957 if (!passwd)
2958 passwd = "";
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002959 if (!PKCS12_parse(p12, passwd, &pkey, &cert, &certs)) {
2960 tls_show_errors(MSG_DEBUG, __func__,
2961 "Failed to parse PKCS12 file");
2962 PKCS12_free(p12);
2963 return -1;
2964 }
2965 wpa_printf(MSG_DEBUG, "TLS: Successfully parsed PKCS12 data");
2966
2967 if (cert) {
2968 X509_NAME_oneline(X509_get_subject_name(cert), buf,
2969 sizeof(buf));
2970 wpa_printf(MSG_DEBUG, "TLS: Got certificate from PKCS12: "
2971 "subject='%s'", buf);
2972 if (ssl) {
2973 if (SSL_use_certificate(ssl, cert) != 1)
2974 res = -1;
2975 } else {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002976 if (SSL_CTX_use_certificate(data->ssl, cert) != 1)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002977 res = -1;
2978 }
2979 X509_free(cert);
2980 }
2981
2982 if (pkey) {
2983 wpa_printf(MSG_DEBUG, "TLS: Got private key from PKCS12");
2984 if (ssl) {
2985 if (SSL_use_PrivateKey(ssl, pkey) != 1)
2986 res = -1;
2987 } else {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002988 if (SSL_CTX_use_PrivateKey(data->ssl, pkey) != 1)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002989 res = -1;
2990 }
2991 EVP_PKEY_free(pkey);
2992 }
2993
2994 if (certs) {
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08002995#if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(LIBRESSL_VERSION_NUMBER)
Dmitry Shmidtb97e4282016-02-08 10:16:07 -08002996 if (ssl)
2997 SSL_clear_chain_certs(ssl);
2998 else
2999 SSL_CTX_clear_chain_certs(data->ssl);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003000 while ((cert = sk_X509_pop(certs)) != NULL) {
3001 X509_NAME_oneline(X509_get_subject_name(cert), buf,
3002 sizeof(buf));
3003 wpa_printf(MSG_DEBUG, "TLS: additional certificate"
3004 " from PKCS12: subject='%s'", buf);
Dmitry Shmidtb97e4282016-02-08 10:16:07 -08003005 if ((ssl && SSL_add1_chain_cert(ssl, cert) != 1) ||
3006 (!ssl && SSL_CTX_add1_chain_cert(data->ssl,
3007 cert) != 1)) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003008 tls_show_errors(MSG_DEBUG, __func__,
3009 "Failed to add additional certificate");
3010 res = -1;
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08003011 X509_free(cert);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003012 break;
3013 }
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08003014 X509_free(cert);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003015 }
3016 if (!res) {
3017 /* Try to continue anyway */
3018 }
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08003019 sk_X509_pop_free(certs, X509_free);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003020#ifndef OPENSSL_IS_BORINGSSL
Dmitry Shmidtb97e4282016-02-08 10:16:07 -08003021 if (ssl)
3022 res = SSL_build_cert_chain(
3023 ssl,
3024 SSL_BUILD_CHAIN_FLAG_CHECK |
3025 SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR);
3026 else
3027 res = SSL_CTX_build_cert_chain(
3028 data->ssl,
3029 SSL_BUILD_CHAIN_FLAG_CHECK |
3030 SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003031 if (!res) {
3032 tls_show_errors(MSG_DEBUG, __func__,
3033 "Failed to build certificate chain");
3034 } else if (res == 2) {
3035 wpa_printf(MSG_DEBUG,
3036 "TLS: Ignore certificate chain verification error when building chain with PKCS#12 extra certificates");
3037 }
3038#endif /* OPENSSL_IS_BORINGSSL */
3039 /*
3040 * Try to continue regardless of result since it is possible for
3041 * the extra certificates not to be required.
3042 */
3043 res = 0;
3044#else /* OPENSSL_VERSION_NUMBER >= 0x10002000L */
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003045 SSL_CTX_clear_extra_chain_certs(data->ssl);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003046 while ((cert = sk_X509_pop(certs)) != NULL) {
3047 X509_NAME_oneline(X509_get_subject_name(cert), buf,
3048 sizeof(buf));
3049 wpa_printf(MSG_DEBUG, "TLS: additional certificate"
3050 " from PKCS12: subject='%s'", buf);
3051 /*
3052 * There is no SSL equivalent for the chain cert - so
3053 * always add it to the context...
3054 */
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003055 if (SSL_CTX_add_extra_chain_cert(data->ssl, cert) != 1)
3056 {
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08003057 X509_free(cert);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003058 res = -1;
3059 break;
3060 }
3061 }
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08003062 sk_X509_pop_free(certs, X509_free);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003063#endif /* OPENSSL_VERSION_NUMBER >= 0x10002000L */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003064 }
3065
3066 PKCS12_free(p12);
3067
3068 if (res < 0)
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003069 tls_get_errors(data);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003070
3071 return res;
3072}
3073#endif /* PKCS12_FUNCS */
3074
3075
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003076static int tls_read_pkcs12(struct tls_data *data, SSL *ssl,
3077 const char *private_key, const char *passwd)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003078{
3079#ifdef PKCS12_FUNCS
3080 FILE *f;
3081 PKCS12 *p12;
3082
3083 f = fopen(private_key, "rb");
3084 if (f == NULL)
3085 return -1;
3086
3087 p12 = d2i_PKCS12_fp(f, NULL);
3088 fclose(f);
3089
3090 if (p12 == NULL) {
3091 tls_show_errors(MSG_INFO, __func__,
3092 "Failed to use PKCS#12 file");
3093 return -1;
3094 }
3095
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003096 return tls_parse_pkcs12(data, ssl, p12, passwd);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003097
3098#else /* PKCS12_FUNCS */
3099 wpa_printf(MSG_INFO, "TLS: PKCS12 support disabled - cannot read "
3100 "p12/pfx files");
3101 return -1;
3102#endif /* PKCS12_FUNCS */
3103}
3104
3105
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003106static int tls_read_pkcs12_blob(struct tls_data *data, SSL *ssl,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003107 const u8 *blob, size_t len, const char *passwd)
3108{
3109#ifdef PKCS12_FUNCS
3110 PKCS12 *p12;
3111
Dmitry Shmidt216983b2015-02-06 10:50:36 -08003112 p12 = d2i_PKCS12(NULL, (const unsigned char **) &blob, len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003113 if (p12 == NULL) {
3114 tls_show_errors(MSG_INFO, __func__,
3115 "Failed to use PKCS#12 blob");
3116 return -1;
3117 }
3118
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003119 return tls_parse_pkcs12(data, ssl, p12, passwd);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003120
3121#else /* PKCS12_FUNCS */
3122 wpa_printf(MSG_INFO, "TLS: PKCS12 support disabled - cannot parse "
3123 "p12/pfx blobs");
3124 return -1;
3125#endif /* PKCS12_FUNCS */
3126}
3127
3128
3129#ifndef OPENSSL_NO_ENGINE
3130static int tls_engine_get_cert(struct tls_connection *conn,
3131 const char *cert_id,
3132 X509 **cert)
3133{
3134 /* this runs after the private key is loaded so no PIN is required */
3135 struct {
3136 const char *cert_id;
3137 X509 *cert;
3138 } params;
3139 params.cert_id = cert_id;
3140 params.cert = NULL;
3141
3142 if (!ENGINE_ctrl_cmd(conn->engine, "LOAD_CERT_CTRL",
3143 0, &params, NULL, 1)) {
Dmitry Shmidt1d755d02015-04-28 10:34:29 -07003144 unsigned long err = ERR_get_error();
3145
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003146 wpa_printf(MSG_ERROR, "ENGINE: cannot load client cert with id"
3147 " '%s' [%s]", cert_id,
Dmitry Shmidt1d755d02015-04-28 10:34:29 -07003148 ERR_error_string(err, NULL));
3149 if (tls_is_pin_error(err))
3150 return TLS_SET_PARAMS_ENGINE_PRV_BAD_PIN;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003151 return TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED;
3152 }
3153 if (!params.cert) {
3154 wpa_printf(MSG_ERROR, "ENGINE: did not properly cert with id"
3155 " '%s'", cert_id);
3156 return TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED;
3157 }
3158 *cert = params.cert;
3159 return 0;
3160}
3161#endif /* OPENSSL_NO_ENGINE */
3162
3163
3164static int tls_connection_engine_client_cert(struct tls_connection *conn,
3165 const char *cert_id)
3166{
3167#ifndef OPENSSL_NO_ENGINE
3168 X509 *cert;
3169
3170 if (tls_engine_get_cert(conn, cert_id, &cert))
3171 return -1;
3172
3173 if (!SSL_use_certificate(conn->ssl, cert)) {
3174 tls_show_errors(MSG_ERROR, __func__,
3175 "SSL_use_certificate failed");
3176 X509_free(cert);
3177 return -1;
3178 }
3179 X509_free(cert);
3180 wpa_printf(MSG_DEBUG, "ENGINE: SSL_use_certificate --> "
3181 "OK");
3182 return 0;
3183
3184#else /* OPENSSL_NO_ENGINE */
3185 return -1;
3186#endif /* OPENSSL_NO_ENGINE */
3187}
3188
3189
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003190static int tls_connection_engine_ca_cert(struct tls_data *data,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003191 struct tls_connection *conn,
3192 const char *ca_cert_id)
3193{
3194#ifndef OPENSSL_NO_ENGINE
3195 X509 *cert;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003196 SSL_CTX *ssl_ctx = data->ssl;
Dmitry Shmidt216983b2015-02-06 10:50:36 -08003197 X509_STORE *store;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003198
3199 if (tls_engine_get_cert(conn, ca_cert_id, &cert))
3200 return -1;
3201
3202 /* start off the same as tls_connection_ca_cert */
Dmitry Shmidt216983b2015-02-06 10:50:36 -08003203 store = X509_STORE_new();
3204 if (store == NULL) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003205 wpa_printf(MSG_DEBUG, "OpenSSL: %s - failed to allocate new "
3206 "certificate store", __func__);
3207 X509_free(cert);
3208 return -1;
3209 }
Dmitry Shmidt216983b2015-02-06 10:50:36 -08003210 SSL_CTX_set_cert_store(ssl_ctx, store);
3211 if (!X509_STORE_add_cert(store, cert)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003212 unsigned long err = ERR_peek_error();
3213 tls_show_errors(MSG_WARNING, __func__,
3214 "Failed to add CA certificate from engine "
3215 "to certificate store");
3216 if (ERR_GET_LIB(err) == ERR_LIB_X509 &&
3217 ERR_GET_REASON(err) == X509_R_CERT_ALREADY_IN_HASH_TABLE) {
3218 wpa_printf(MSG_DEBUG, "OpenSSL: %s - ignoring cert"
3219 " already in hash table error",
3220 __func__);
3221 } else {
3222 X509_free(cert);
3223 return -1;
3224 }
3225 }
3226 X509_free(cert);
3227 wpa_printf(MSG_DEBUG, "OpenSSL: %s - added CA certificate from engine "
3228 "to certificate store", __func__);
3229 SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003230 conn->ca_cert_verify = 1;
3231
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003232 return 0;
3233
3234#else /* OPENSSL_NO_ENGINE */
3235 return -1;
3236#endif /* OPENSSL_NO_ENGINE */
3237}
3238
3239
3240static int tls_connection_engine_private_key(struct tls_connection *conn)
3241{
Adam Langley1eb02ed2015-04-21 19:00:05 -07003242#if defined(ANDROID) || !defined(OPENSSL_NO_ENGINE)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003243 if (SSL_use_PrivateKey(conn->ssl, conn->private_key) != 1) {
3244 tls_show_errors(MSG_ERROR, __func__,
3245 "ENGINE: cannot use private key for TLS");
3246 return -1;
3247 }
3248 if (!SSL_check_private_key(conn->ssl)) {
3249 tls_show_errors(MSG_INFO, __func__,
3250 "Private key failed verification");
3251 return -1;
3252 }
3253 return 0;
3254#else /* OPENSSL_NO_ENGINE */
3255 wpa_printf(MSG_ERROR, "SSL: Configuration uses engine, but "
3256 "engine support was not compiled in");
3257 return -1;
3258#endif /* OPENSSL_NO_ENGINE */
3259}
3260
3261
Roshan Pius3a1667e2018-07-03 15:17:14 -07003262#ifndef OPENSSL_NO_STDIO
3263static int tls_passwd_cb(char *buf, int size, int rwflag, void *password)
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07003264{
Roshan Pius3a1667e2018-07-03 15:17:14 -07003265 if (!password)
3266 return 0;
3267 os_strlcpy(buf, (const char *) password, size);
3268 return os_strlen(buf);
3269}
3270#endif /* OPENSSL_NO_STDIO */
3271
3272
3273static int tls_use_private_key_file(struct tls_data *data, SSL *ssl,
3274 const char *private_key,
3275 const char *private_key_passwd)
3276{
3277#ifndef OPENSSL_NO_STDIO
3278 BIO *bio;
3279 EVP_PKEY *pkey;
3280 int ret;
3281
3282 /* First try ASN.1 (DER). */
3283 bio = BIO_new_file(private_key, "r");
3284 if (!bio)
3285 return -1;
3286 pkey = d2i_PrivateKey_bio(bio, NULL);
3287 BIO_free(bio);
3288
3289 if (pkey) {
3290 wpa_printf(MSG_DEBUG, "OpenSSL: %s (DER) --> loaded", __func__);
3291 } else {
3292 /* Try PEM with the provided password. */
3293 bio = BIO_new_file(private_key, "r");
3294 if (!bio)
3295 return -1;
3296 pkey = PEM_read_bio_PrivateKey(bio, NULL, tls_passwd_cb,
3297 (void *) private_key_passwd);
3298 BIO_free(bio);
3299 if (!pkey)
3300 return -1;
3301 wpa_printf(MSG_DEBUG, "OpenSSL: %s (PEM) --> loaded", __func__);
3302 /* Clear errors from the previous failed load. */
3303 ERR_clear_error();
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07003304 }
Roshan Pius3a1667e2018-07-03 15:17:14 -07003305
3306 if (ssl)
3307 ret = SSL_use_PrivateKey(ssl, pkey);
3308 else
3309 ret = SSL_CTX_use_PrivateKey(data->ssl, pkey);
3310
3311 EVP_PKEY_free(pkey);
3312 return ret == 1 ? 0 : -1;
3313#else /* OPENSSL_NO_STDIO */
3314 wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", __func__);
3315 return -1;
3316#endif /* OPENSSL_NO_STDIO */
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07003317}
3318
3319
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003320static int tls_connection_private_key(struct tls_data *data,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003321 struct tls_connection *conn,
3322 const char *private_key,
3323 const char *private_key_passwd,
3324 const u8 *private_key_blob,
3325 size_t private_key_blob_len)
3326{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003327 int ok;
3328
3329 if (private_key == NULL && private_key_blob == NULL)
3330 return 0;
3331
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003332 ok = 0;
3333 while (private_key_blob) {
3334 if (SSL_use_PrivateKey_ASN1(EVP_PKEY_RSA, conn->ssl,
3335 (u8 *) private_key_blob,
3336 private_key_blob_len) == 1) {
3337 wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_PrivateKey_"
3338 "ASN1(EVP_PKEY_RSA) --> OK");
3339 ok = 1;
3340 break;
3341 }
3342
3343 if (SSL_use_PrivateKey_ASN1(EVP_PKEY_DSA, conn->ssl,
3344 (u8 *) private_key_blob,
3345 private_key_blob_len) == 1) {
3346 wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_PrivateKey_"
3347 "ASN1(EVP_PKEY_DSA) --> OK");
3348 ok = 1;
3349 break;
3350 }
3351
3352 if (SSL_use_RSAPrivateKey_ASN1(conn->ssl,
3353 (u8 *) private_key_blob,
3354 private_key_blob_len) == 1) {
3355 wpa_printf(MSG_DEBUG, "OpenSSL: "
3356 "SSL_use_RSAPrivateKey_ASN1 --> OK");
3357 ok = 1;
3358 break;
3359 }
3360
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003361 if (tls_read_pkcs12_blob(data, conn->ssl, private_key_blob,
Roshan Pius3a1667e2018-07-03 15:17:14 -07003362 private_key_blob_len,
3363 private_key_passwd) == 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003364 wpa_printf(MSG_DEBUG, "OpenSSL: PKCS#12 as blob --> "
3365 "OK");
3366 ok = 1;
3367 break;
3368 }
3369
3370 break;
3371 }
3372
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003373 while (!ok && private_key) {
Roshan Pius3a1667e2018-07-03 15:17:14 -07003374 if (tls_use_private_key_file(data, conn->ssl, private_key,
3375 private_key_passwd) == 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003376 ok = 1;
3377 break;
3378 }
3379
Roshan Pius3a1667e2018-07-03 15:17:14 -07003380 if (tls_read_pkcs12(data, conn->ssl, private_key,
3381 private_key_passwd) == 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003382 wpa_printf(MSG_DEBUG, "OpenSSL: Reading PKCS#12 file "
3383 "--> OK");
3384 ok = 1;
3385 break;
3386 }
3387
3388 if (tls_cryptoapi_cert(conn->ssl, private_key) == 0) {
3389 wpa_printf(MSG_DEBUG, "OpenSSL: Using CryptoAPI to "
3390 "access certificate store --> OK");
3391 ok = 1;
3392 break;
3393 }
3394
3395 break;
3396 }
3397
3398 if (!ok) {
3399 tls_show_errors(MSG_INFO, __func__,
3400 "Failed to load private key");
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003401 return -1;
3402 }
3403 ERR_clear_error();
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003404
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003405 if (!SSL_check_private_key(conn->ssl)) {
3406 tls_show_errors(MSG_INFO, __func__, "Private key failed "
3407 "verification");
3408 return -1;
3409 }
3410
3411 wpa_printf(MSG_DEBUG, "SSL: Private key loaded successfully");
3412 return 0;
3413}
3414
3415
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003416static int tls_global_private_key(struct tls_data *data,
3417 const char *private_key,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003418 const char *private_key_passwd)
3419{
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003420 SSL_CTX *ssl_ctx = data->ssl;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003421
3422 if (private_key == NULL)
3423 return 0;
3424
Roshan Pius3a1667e2018-07-03 15:17:14 -07003425 if (tls_use_private_key_file(data, NULL, private_key,
3426 private_key_passwd) &&
3427 tls_read_pkcs12(data, NULL, private_key, private_key_passwd)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003428 tls_show_errors(MSG_INFO, __func__,
3429 "Failed to load private key");
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003430 ERR_clear_error();
3431 return -1;
3432 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003433 ERR_clear_error();
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003434
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003435 if (!SSL_CTX_check_private_key(ssl_ctx)) {
3436 tls_show_errors(MSG_INFO, __func__,
3437 "Private key failed verification");
3438 return -1;
3439 }
3440
3441 return 0;
3442}
3443
3444
3445static int tls_connection_dh(struct tls_connection *conn, const char *dh_file)
3446{
3447#ifdef OPENSSL_NO_DH
3448 if (dh_file == NULL)
3449 return 0;
3450 wpa_printf(MSG_ERROR, "TLS: openssl does not include DH support, but "
3451 "dh_file specified");
3452 return -1;
3453#else /* OPENSSL_NO_DH */
3454 DH *dh;
3455 BIO *bio;
3456
3457 /* TODO: add support for dh_blob */
3458 if (dh_file == NULL)
3459 return 0;
3460 if (conn == NULL)
3461 return -1;
3462
3463 bio = BIO_new_file(dh_file, "r");
3464 if (bio == NULL) {
3465 wpa_printf(MSG_INFO, "TLS: Failed to open DH file '%s': %s",
3466 dh_file, ERR_error_string(ERR_get_error(), NULL));
3467 return -1;
3468 }
3469 dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
3470 BIO_free(bio);
3471#ifndef OPENSSL_NO_DSA
3472 while (dh == NULL) {
3473 DSA *dsa;
3474 wpa_printf(MSG_DEBUG, "TLS: Failed to parse DH file '%s': %s -"
3475 " trying to parse as DSA params", dh_file,
3476 ERR_error_string(ERR_get_error(), NULL));
3477 bio = BIO_new_file(dh_file, "r");
3478 if (bio == NULL)
3479 break;
3480 dsa = PEM_read_bio_DSAparams(bio, NULL, NULL, NULL);
3481 BIO_free(bio);
3482 if (!dsa) {
3483 wpa_printf(MSG_DEBUG, "TLS: Failed to parse DSA file "
3484 "'%s': %s", dh_file,
3485 ERR_error_string(ERR_get_error(), NULL));
3486 break;
3487 }
3488
3489 wpa_printf(MSG_DEBUG, "TLS: DH file in DSA param format");
3490 dh = DSA_dup_DH(dsa);
3491 DSA_free(dsa);
3492 if (dh == NULL) {
3493 wpa_printf(MSG_INFO, "TLS: Failed to convert DSA "
3494 "params into DH params");
3495 break;
3496 }
3497 break;
3498 }
3499#endif /* !OPENSSL_NO_DSA */
3500 if (dh == NULL) {
3501 wpa_printf(MSG_INFO, "TLS: Failed to read/parse DH/DSA file "
3502 "'%s'", dh_file);
3503 return -1;
3504 }
3505
3506 if (SSL_set_tmp_dh(conn->ssl, dh) != 1) {
3507 wpa_printf(MSG_INFO, "TLS: Failed to set DH params from '%s': "
3508 "%s", dh_file,
3509 ERR_error_string(ERR_get_error(), NULL));
3510 DH_free(dh);
3511 return -1;
3512 }
3513 DH_free(dh);
3514 return 0;
3515#endif /* OPENSSL_NO_DH */
3516}
3517
3518
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003519static int tls_global_dh(struct tls_data *data, const char *dh_file)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003520{
3521#ifdef OPENSSL_NO_DH
3522 if (dh_file == NULL)
3523 return 0;
3524 wpa_printf(MSG_ERROR, "TLS: openssl does not include DH support, but "
3525 "dh_file specified");
3526 return -1;
3527#else /* OPENSSL_NO_DH */
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003528 SSL_CTX *ssl_ctx = data->ssl;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003529 DH *dh;
3530 BIO *bio;
3531
3532 /* TODO: add support for dh_blob */
3533 if (dh_file == NULL)
3534 return 0;
3535 if (ssl_ctx == NULL)
3536 return -1;
3537
3538 bio = BIO_new_file(dh_file, "r");
3539 if (bio == NULL) {
3540 wpa_printf(MSG_INFO, "TLS: Failed to open DH file '%s': %s",
3541 dh_file, ERR_error_string(ERR_get_error(), NULL));
3542 return -1;
3543 }
3544 dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
3545 BIO_free(bio);
3546#ifndef OPENSSL_NO_DSA
3547 while (dh == NULL) {
3548 DSA *dsa;
3549 wpa_printf(MSG_DEBUG, "TLS: Failed to parse DH file '%s': %s -"
3550 " trying to parse as DSA params", dh_file,
3551 ERR_error_string(ERR_get_error(), NULL));
3552 bio = BIO_new_file(dh_file, "r");
3553 if (bio == NULL)
3554 break;
3555 dsa = PEM_read_bio_DSAparams(bio, NULL, NULL, NULL);
3556 BIO_free(bio);
3557 if (!dsa) {
3558 wpa_printf(MSG_DEBUG, "TLS: Failed to parse DSA file "
3559 "'%s': %s", dh_file,
3560 ERR_error_string(ERR_get_error(), NULL));
3561 break;
3562 }
3563
3564 wpa_printf(MSG_DEBUG, "TLS: DH file in DSA param format");
3565 dh = DSA_dup_DH(dsa);
3566 DSA_free(dsa);
3567 if (dh == NULL) {
3568 wpa_printf(MSG_INFO, "TLS: Failed to convert DSA "
3569 "params into DH params");
3570 break;
3571 }
3572 break;
3573 }
3574#endif /* !OPENSSL_NO_DSA */
3575 if (dh == NULL) {
3576 wpa_printf(MSG_INFO, "TLS: Failed to read/parse DH/DSA file "
3577 "'%s'", dh_file);
3578 return -1;
3579 }
3580
3581 if (SSL_CTX_set_tmp_dh(ssl_ctx, dh) != 1) {
3582 wpa_printf(MSG_INFO, "TLS: Failed to set DH params from '%s': "
3583 "%s", dh_file,
3584 ERR_error_string(ERR_get_error(), NULL));
3585 DH_free(dh);
3586 return -1;
3587 }
3588 DH_free(dh);
3589 return 0;
3590#endif /* OPENSSL_NO_DH */
3591}
3592
3593
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003594int tls_connection_get_random(void *ssl_ctx, struct tls_connection *conn,
3595 struct tls_random *keys)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003596{
3597 SSL *ssl;
3598
3599 if (conn == NULL || keys == NULL)
3600 return -1;
3601 ssl = conn->ssl;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003602 if (ssl == NULL)
3603 return -1;
3604
3605 os_memset(keys, 0, sizeof(*keys));
3606 keys->client_random = conn->client_random;
3607 keys->client_random_len = SSL_get_client_random(
3608 ssl, conn->client_random, sizeof(conn->client_random));
3609 keys->server_random = conn->server_random;
3610 keys->server_random_len = SSL_get_server_random(
3611 ssl, conn->server_random, sizeof(conn->server_random));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003612
3613 return 0;
3614}
3615
3616
Dmitry Shmidt849734c2016-05-27 09:59:01 -07003617#ifdef OPENSSL_NEED_EAP_FAST_PRF
Dmitry Shmidtaf9da312015-04-03 10:03:11 -07003618static int openssl_get_keyblock_size(SSL *ssl)
3619{
Roshan Pius3a1667e2018-07-03 15:17:14 -07003620#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
3621 (defined(LIBRESSL_VERSION_NUMBER) && \
3622 LIBRESSL_VERSION_NUMBER < 0x20700000L)
Dmitry Shmidtaf9da312015-04-03 10:03:11 -07003623 const EVP_CIPHER *c;
3624 const EVP_MD *h;
3625 int md_size;
3626
3627 if (ssl->enc_read_ctx == NULL || ssl->enc_read_ctx->cipher == NULL ||
3628 ssl->read_hash == NULL)
3629 return -1;
3630
3631 c = ssl->enc_read_ctx->cipher;
Dmitry Shmidtaf9da312015-04-03 10:03:11 -07003632 h = EVP_MD_CTX_md(ssl->read_hash);
Dmitry Shmidtaf9da312015-04-03 10:03:11 -07003633 if (h)
3634 md_size = EVP_MD_size(h);
Dmitry Shmidtaf9da312015-04-03 10:03:11 -07003635 else if (ssl->s3)
3636 md_size = ssl->s3->tmp.new_mac_secret_size;
Dmitry Shmidtaf9da312015-04-03 10:03:11 -07003637 else
3638 return -1;
3639
3640 wpa_printf(MSG_DEBUG, "OpenSSL: keyblock size: key_len=%d MD_size=%d "
3641 "IV_len=%d", EVP_CIPHER_key_length(c), md_size,
3642 EVP_CIPHER_iv_length(c));
3643 return 2 * (EVP_CIPHER_key_length(c) +
3644 md_size +
3645 EVP_CIPHER_iv_length(c));
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003646#else
3647 const SSL_CIPHER *ssl_cipher;
3648 int cipher, digest;
3649 const EVP_CIPHER *c;
3650 const EVP_MD *h;
3651
3652 ssl_cipher = SSL_get_current_cipher(ssl);
3653 if (!ssl_cipher)
3654 return -1;
3655 cipher = SSL_CIPHER_get_cipher_nid(ssl_cipher);
3656 digest = SSL_CIPHER_get_digest_nid(ssl_cipher);
3657 wpa_printf(MSG_DEBUG, "OpenSSL: cipher nid %d digest nid %d",
3658 cipher, digest);
3659 if (cipher < 0 || digest < 0)
3660 return -1;
3661 c = EVP_get_cipherbynid(cipher);
3662 h = EVP_get_digestbynid(digest);
3663 if (!c || !h)
3664 return -1;
3665
3666 wpa_printf(MSG_DEBUG,
3667 "OpenSSL: keyblock size: key_len=%d MD_size=%d IV_len=%d",
3668 EVP_CIPHER_key_length(c), EVP_MD_size(h),
3669 EVP_CIPHER_iv_length(c));
3670 return 2 * (EVP_CIPHER_key_length(c) + EVP_MD_size(h) +
3671 EVP_CIPHER_iv_length(c));
3672#endif
Dmitry Shmidtaf9da312015-04-03 10:03:11 -07003673}
Dmitry Shmidt849734c2016-05-27 09:59:01 -07003674#endif /* OPENSSL_NEED_EAP_FAST_PRF */
Dmitry Shmidtaf9da312015-04-03 10:03:11 -07003675
3676
Dmitry Shmidt849734c2016-05-27 09:59:01 -07003677int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn,
3678 const char *label, u8 *out, size_t out_len)
Dmitry Shmidtaf9da312015-04-03 10:03:11 -07003679{
Dmitry Shmidt849734c2016-05-27 09:59:01 -07003680 if (!conn ||
3681 SSL_export_keying_material(conn->ssl, out, out_len, label,
3682 os_strlen(label), NULL, 0, 0) != 1)
3683 return -1;
3684 return 0;
3685}
3686
3687
3688int tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn,
3689 u8 *out, size_t out_len)
3690{
3691#ifdef OPENSSL_NEED_EAP_FAST_PRF
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003692 SSL *ssl;
3693 SSL_SESSION *sess;
3694 u8 *rnd;
3695 int ret = -1;
3696 int skip = 0;
3697 u8 *tmp_out = NULL;
3698 u8 *_out = out;
3699 unsigned char client_random[SSL3_RANDOM_SIZE];
3700 unsigned char server_random[SSL3_RANDOM_SIZE];
3701 unsigned char master_key[64];
3702 size_t master_key_len;
3703 const char *ver;
3704
3705 /*
Dmitry Shmidt849734c2016-05-27 09:59:01 -07003706 * TLS library did not support EAP-FAST key generation, so get the
3707 * needed TLS session parameters and use an internal implementation of
3708 * TLS PRF to derive the key.
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003709 */
3710
3711 if (conn == NULL)
3712 return -1;
3713 ssl = conn->ssl;
3714 if (ssl == NULL)
3715 return -1;
3716 ver = SSL_get_version(ssl);
3717 sess = SSL_get_session(ssl);
3718 if (!ver || !sess)
3719 return -1;
3720
Dmitry Shmidt849734c2016-05-27 09:59:01 -07003721 skip = openssl_get_keyblock_size(ssl);
3722 if (skip < 0)
3723 return -1;
3724 tmp_out = os_malloc(skip + out_len);
3725 if (!tmp_out)
3726 return -1;
3727 _out = tmp_out;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003728
3729 rnd = os_malloc(2 * SSL3_RANDOM_SIZE);
3730 if (!rnd) {
3731 os_free(tmp_out);
3732 return -1;
3733 }
3734
3735 SSL_get_client_random(ssl, client_random, sizeof(client_random));
3736 SSL_get_server_random(ssl, server_random, sizeof(server_random));
3737 master_key_len = SSL_SESSION_get_master_key(sess, master_key,
3738 sizeof(master_key));
3739
Dmitry Shmidt849734c2016-05-27 09:59:01 -07003740 os_memcpy(rnd, server_random, SSL3_RANDOM_SIZE);
3741 os_memcpy(rnd + SSL3_RANDOM_SIZE, client_random, SSL3_RANDOM_SIZE);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003742
3743 if (os_strcmp(ver, "TLSv1.2") == 0) {
3744 tls_prf_sha256(master_key, master_key_len,
Dmitry Shmidt849734c2016-05-27 09:59:01 -07003745 "key expansion", rnd, 2 * SSL3_RANDOM_SIZE,
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003746 _out, skip + out_len);
3747 ret = 0;
3748 } else if (tls_prf_sha1_md5(master_key, master_key_len,
Dmitry Shmidt849734c2016-05-27 09:59:01 -07003749 "key expansion", rnd, 2 * SSL3_RANDOM_SIZE,
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003750 _out, skip + out_len) == 0) {
3751 ret = 0;
3752 }
3753 os_memset(master_key, 0, sizeof(master_key));
3754 os_free(rnd);
Dmitry Shmidt849734c2016-05-27 09:59:01 -07003755 if (ret == 0)
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003756 os_memcpy(out, _out + skip, out_len);
3757 bin_clear_free(tmp_out, skip);
3758
3759 return ret;
Dmitry Shmidt849734c2016-05-27 09:59:01 -07003760#else /* OPENSSL_NEED_EAP_FAST_PRF */
3761 wpa_printf(MSG_ERROR,
3762 "OpenSSL: EAP-FAST keys cannot be exported in FIPS mode");
3763 return -1;
3764#endif /* OPENSSL_NEED_EAP_FAST_PRF */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003765}
3766
3767
3768static struct wpabuf *
Roshan Pius3a1667e2018-07-03 15:17:14 -07003769openssl_handshake(struct tls_connection *conn, const struct wpabuf *in_data)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003770{
3771 int res;
3772 struct wpabuf *out_data;
3773
3774 /*
3775 * Give TLS handshake data from the server (if available) to OpenSSL
3776 * for processing.
3777 */
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003778 if (in_data && wpabuf_len(in_data) > 0 &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003779 BIO_write(conn->ssl_in, wpabuf_head(in_data), wpabuf_len(in_data))
3780 < 0) {
3781 tls_show_errors(MSG_INFO, __func__,
3782 "Handshake failed - BIO_write");
3783 return NULL;
3784 }
3785
3786 /* Initiate TLS handshake or continue the existing handshake */
Roshan Pius3a1667e2018-07-03 15:17:14 -07003787 if (conn->server)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003788 res = SSL_accept(conn->ssl);
3789 else
3790 res = SSL_connect(conn->ssl);
3791 if (res != 1) {
3792 int err = SSL_get_error(conn->ssl, res);
3793 if (err == SSL_ERROR_WANT_READ)
3794 wpa_printf(MSG_DEBUG, "SSL: SSL_connect - want "
3795 "more data");
3796 else if (err == SSL_ERROR_WANT_WRITE)
3797 wpa_printf(MSG_DEBUG, "SSL: SSL_connect - want to "
3798 "write");
3799 else {
3800 tls_show_errors(MSG_INFO, __func__, "SSL_connect");
3801 conn->failed++;
Roshan Pius3a1667e2018-07-03 15:17:14 -07003802 if (!conn->server && !conn->client_hello_generated) {
3803 /* The server would not understand TLS Alert
3804 * before ClientHello, so simply terminate
3805 * handshake on this type of error case caused
3806 * by a likely internal error like no ciphers
3807 * available. */
3808 wpa_printf(MSG_DEBUG,
3809 "OpenSSL: Could not generate ClientHello");
3810 conn->write_alerts++;
3811 return NULL;
3812 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003813 }
3814 }
3815
Roshan Pius3a1667e2018-07-03 15:17:14 -07003816 if (!conn->server && !conn->failed)
3817 conn->client_hello_generated = 1;
3818
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07003819#ifdef CONFIG_SUITEB
Roshan Pius3a1667e2018-07-03 15:17:14 -07003820 if ((conn->flags & TLS_CONN_SUITEB) && !conn->server &&
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07003821 os_strncmp(SSL_get_cipher(conn->ssl), "DHE-", 4) == 0 &&
3822 conn->server_dh_prime_len < 3072) {
3823 struct tls_context *context = conn->context;
3824
3825 /*
3826 * This should not be reached since earlier cert_cb should have
3827 * terminated the handshake. Keep this check here for extra
3828 * protection if anything goes wrong with the more low-level
3829 * checks based on having to parse the TLS handshake messages.
3830 */
3831 wpa_printf(MSG_DEBUG,
3832 "OpenSSL: Server DH prime length: %d bits",
3833 conn->server_dh_prime_len);
3834
3835 if (context->event_cb) {
3836 union tls_event_data ev;
3837
3838 os_memset(&ev, 0, sizeof(ev));
3839 ev.alert.is_local = 1;
3840 ev.alert.type = "fatal";
3841 ev.alert.description = "insufficient security";
3842 context->event_cb(context->cb_ctx, TLS_ALERT, &ev);
3843 }
3844 /*
3845 * Could send a TLS Alert to the server, but for now, simply
3846 * terminate handshake.
3847 */
3848 conn->failed++;
3849 conn->write_alerts++;
3850 return NULL;
3851 }
3852#endif /* CONFIG_SUITEB */
3853
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003854 /* Get the TLS handshake data to be sent to the server */
3855 res = BIO_ctrl_pending(conn->ssl_out);
3856 wpa_printf(MSG_DEBUG, "SSL: %d bytes pending from ssl_out", res);
3857 out_data = wpabuf_alloc(res);
3858 if (out_data == NULL) {
3859 wpa_printf(MSG_DEBUG, "SSL: Failed to allocate memory for "
3860 "handshake output (%d bytes)", res);
3861 if (BIO_reset(conn->ssl_out) < 0) {
3862 tls_show_errors(MSG_INFO, __func__,
3863 "BIO_reset failed");
3864 }
3865 return NULL;
3866 }
3867 res = res == 0 ? 0 : BIO_read(conn->ssl_out, wpabuf_mhead(out_data),
3868 res);
3869 if (res < 0) {
3870 tls_show_errors(MSG_INFO, __func__,
3871 "Handshake failed - BIO_read");
3872 if (BIO_reset(conn->ssl_out) < 0) {
3873 tls_show_errors(MSG_INFO, __func__,
3874 "BIO_reset failed");
3875 }
3876 wpabuf_free(out_data);
3877 return NULL;
3878 }
3879 wpabuf_put(out_data, res);
3880
3881 return out_data;
3882}
3883
3884
3885static struct wpabuf *
3886openssl_get_appl_data(struct tls_connection *conn, size_t max_len)
3887{
3888 struct wpabuf *appl_data;
3889 int res;
3890
3891 appl_data = wpabuf_alloc(max_len + 100);
3892 if (appl_data == NULL)
3893 return NULL;
3894
3895 res = SSL_read(conn->ssl, wpabuf_mhead(appl_data),
3896 wpabuf_size(appl_data));
3897 if (res < 0) {
3898 int err = SSL_get_error(conn->ssl, res);
3899 if (err == SSL_ERROR_WANT_READ ||
3900 err == SSL_ERROR_WANT_WRITE) {
3901 wpa_printf(MSG_DEBUG, "SSL: No Application Data "
3902 "included");
3903 } else {
3904 tls_show_errors(MSG_INFO, __func__,
3905 "Failed to read possible "
3906 "Application Data");
3907 }
3908 wpabuf_free(appl_data);
3909 return NULL;
3910 }
3911
3912 wpabuf_put(appl_data, res);
3913 wpa_hexdump_buf_key(MSG_MSGDUMP, "SSL: Application Data in Finished "
3914 "message", appl_data);
3915
3916 return appl_data;
3917}
3918
3919
3920static struct wpabuf *
3921openssl_connection_handshake(struct tls_connection *conn,
3922 const struct wpabuf *in_data,
Roshan Pius3a1667e2018-07-03 15:17:14 -07003923 struct wpabuf **appl_data)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003924{
3925 struct wpabuf *out_data;
3926
3927 if (appl_data)
3928 *appl_data = NULL;
3929
Roshan Pius3a1667e2018-07-03 15:17:14 -07003930 out_data = openssl_handshake(conn, in_data);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003931 if (out_data == NULL)
3932 return NULL;
Jouni Malinen26af48b2014-04-09 13:02:53 +03003933 if (conn->invalid_hb_used) {
3934 wpa_printf(MSG_INFO, "TLS: Heartbeat attack detected - do not send response");
3935 wpabuf_free(out_data);
3936 return NULL;
3937 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003938
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003939 if (SSL_is_init_finished(conn->ssl)) {
3940 wpa_printf(MSG_DEBUG,
3941 "OpenSSL: Handshake finished - resumed=%d",
3942 tls_connection_resumed(conn->ssl_ctx, conn));
3943 if (appl_data && in_data)
3944 *appl_data = openssl_get_appl_data(conn,
3945 wpabuf_len(in_data));
3946 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003947
Jouni Malinen26af48b2014-04-09 13:02:53 +03003948 if (conn->invalid_hb_used) {
3949 wpa_printf(MSG_INFO, "TLS: Heartbeat attack detected - do not send response");
3950 if (appl_data) {
3951 wpabuf_free(*appl_data);
3952 *appl_data = NULL;
3953 }
3954 wpabuf_free(out_data);
3955 return NULL;
3956 }
3957
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003958 return out_data;
3959}
3960
3961
3962struct wpabuf *
3963tls_connection_handshake(void *ssl_ctx, struct tls_connection *conn,
3964 const struct wpabuf *in_data,
3965 struct wpabuf **appl_data)
3966{
Roshan Pius3a1667e2018-07-03 15:17:14 -07003967 return openssl_connection_handshake(conn, in_data, appl_data);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003968}
3969
3970
3971struct wpabuf * tls_connection_server_handshake(void *tls_ctx,
3972 struct tls_connection *conn,
3973 const struct wpabuf *in_data,
3974 struct wpabuf **appl_data)
3975{
Roshan Pius3a1667e2018-07-03 15:17:14 -07003976 conn->server = 1;
3977 return openssl_connection_handshake(conn, in_data, appl_data);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003978}
3979
3980
3981struct wpabuf * tls_connection_encrypt(void *tls_ctx,
3982 struct tls_connection *conn,
3983 const struct wpabuf *in_data)
3984{
3985 int res;
3986 struct wpabuf *buf;
3987
3988 if (conn == NULL)
3989 return NULL;
3990
3991 /* Give plaintext data for OpenSSL to encrypt into the TLS tunnel. */
3992 if ((res = BIO_reset(conn->ssl_in)) < 0 ||
3993 (res = BIO_reset(conn->ssl_out)) < 0) {
3994 tls_show_errors(MSG_INFO, __func__, "BIO_reset failed");
3995 return NULL;
3996 }
3997 res = SSL_write(conn->ssl, wpabuf_head(in_data), wpabuf_len(in_data));
3998 if (res < 0) {
3999 tls_show_errors(MSG_INFO, __func__,
4000 "Encryption failed - SSL_write");
4001 return NULL;
4002 }
4003
4004 /* Read encrypted data to be sent to the server */
4005 buf = wpabuf_alloc(wpabuf_len(in_data) + 300);
4006 if (buf == NULL)
4007 return NULL;
4008 res = BIO_read(conn->ssl_out, wpabuf_mhead(buf), wpabuf_size(buf));
4009 if (res < 0) {
4010 tls_show_errors(MSG_INFO, __func__,
4011 "Encryption failed - BIO_read");
4012 wpabuf_free(buf);
4013 return NULL;
4014 }
4015 wpabuf_put(buf, res);
4016
4017 return buf;
4018}
4019
4020
4021struct wpabuf * tls_connection_decrypt(void *tls_ctx,
4022 struct tls_connection *conn,
4023 const struct wpabuf *in_data)
4024{
4025 int res;
4026 struct wpabuf *buf;
4027
4028 /* Give encrypted data from TLS tunnel for OpenSSL to decrypt. */
4029 res = BIO_write(conn->ssl_in, wpabuf_head(in_data),
4030 wpabuf_len(in_data));
4031 if (res < 0) {
4032 tls_show_errors(MSG_INFO, __func__,
4033 "Decryption failed - BIO_write");
4034 return NULL;
4035 }
4036 if (BIO_reset(conn->ssl_out) < 0) {
4037 tls_show_errors(MSG_INFO, __func__, "BIO_reset failed");
4038 return NULL;
4039 }
4040
4041 /* Read decrypted data for further processing */
4042 /*
4043 * Even though we try to disable TLS compression, it is possible that
4044 * this cannot be done with all TLS libraries. Add extra buffer space
4045 * to handle the possibility of the decrypted data being longer than
4046 * input data.
4047 */
4048 buf = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3);
4049 if (buf == NULL)
4050 return NULL;
4051 res = SSL_read(conn->ssl, wpabuf_mhead(buf), wpabuf_size(buf));
4052 if (res < 0) {
4053 tls_show_errors(MSG_INFO, __func__,
4054 "Decryption failed - SSL_read");
4055 wpabuf_free(buf);
4056 return NULL;
4057 }
4058 wpabuf_put(buf, res);
4059
Jouni Malinen26af48b2014-04-09 13:02:53 +03004060 if (conn->invalid_hb_used) {
4061 wpa_printf(MSG_INFO, "TLS: Heartbeat attack detected - do not send response");
4062 wpabuf_free(buf);
4063 return NULL;
4064 }
4065
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004066 return buf;
4067}
4068
4069
4070int tls_connection_resumed(void *ssl_ctx, struct tls_connection *conn)
4071{
Hai Shalomce48b4a2018-09-05 11:41:35 -07004072 return conn ? SSL_session_reused(conn->ssl) : 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004073}
4074
4075
4076int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn,
4077 u8 *ciphers)
4078{
Dmitry Shmidtde47be72016-01-07 12:52:55 -08004079 char buf[500], *pos, *end;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004080 u8 *c;
4081 int ret;
4082
4083 if (conn == NULL || conn->ssl == NULL || ciphers == NULL)
4084 return -1;
4085
4086 buf[0] = '\0';
4087 pos = buf;
4088 end = pos + sizeof(buf);
4089
4090 c = ciphers;
4091 while (*c != TLS_CIPHER_NONE) {
4092 const char *suite;
4093
4094 switch (*c) {
4095 case TLS_CIPHER_RC4_SHA:
4096 suite = "RC4-SHA";
4097 break;
4098 case TLS_CIPHER_AES128_SHA:
4099 suite = "AES128-SHA";
4100 break;
4101 case TLS_CIPHER_RSA_DHE_AES128_SHA:
4102 suite = "DHE-RSA-AES128-SHA";
4103 break;
4104 case TLS_CIPHER_ANON_DH_AES128_SHA:
4105 suite = "ADH-AES128-SHA";
4106 break;
Dmitry Shmidtde47be72016-01-07 12:52:55 -08004107 case TLS_CIPHER_RSA_DHE_AES256_SHA:
4108 suite = "DHE-RSA-AES256-SHA";
4109 break;
4110 case TLS_CIPHER_AES256_SHA:
4111 suite = "AES256-SHA";
4112 break;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004113 default:
4114 wpa_printf(MSG_DEBUG, "TLS: Unsupported "
4115 "cipher selection: %d", *c);
4116 return -1;
4117 }
4118 ret = os_snprintf(pos, end - pos, ":%s", suite);
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004119 if (os_snprintf_error(end - pos, ret))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004120 break;
4121 pos += ret;
4122
4123 c++;
4124 }
4125
4126 wpa_printf(MSG_DEBUG, "OpenSSL: cipher suites: %s", buf + 1);
4127
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08004128#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004129#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
4130 if (os_strstr(buf, ":ADH-")) {
4131 /*
4132 * Need to drop to security level 0 to allow anonymous
4133 * cipher suites for EAP-FAST.
4134 */
4135 SSL_set_security_level(conn->ssl, 0);
4136 } else if (SSL_get_security_level(conn->ssl) == 0) {
4137 /* Force at least security level 1 */
4138 SSL_set_security_level(conn->ssl, 1);
4139 }
4140#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
4141#endif
4142
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004143 if (SSL_set_cipher_list(conn->ssl, buf + 1) != 1) {
4144 tls_show_errors(MSG_INFO, __func__,
4145 "Cipher suite configuration failed");
4146 return -1;
4147 }
4148
4149 return 0;
4150}
4151
4152
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004153int tls_get_version(void *ssl_ctx, struct tls_connection *conn,
4154 char *buf, size_t buflen)
4155{
4156 const char *name;
4157 if (conn == NULL || conn->ssl == NULL)
4158 return -1;
4159
4160 name = SSL_get_version(conn->ssl);
4161 if (name == NULL)
4162 return -1;
4163
4164 os_strlcpy(buf, name, buflen);
4165 return 0;
4166}
4167
4168
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004169int tls_get_cipher(void *ssl_ctx, struct tls_connection *conn,
4170 char *buf, size_t buflen)
4171{
4172 const char *name;
4173 if (conn == NULL || conn->ssl == NULL)
4174 return -1;
4175
4176 name = SSL_get_cipher(conn->ssl);
4177 if (name == NULL)
4178 return -1;
4179
4180 os_strlcpy(buf, name, buflen);
4181 return 0;
4182}
4183
4184
4185int tls_connection_enable_workaround(void *ssl_ctx,
4186 struct tls_connection *conn)
4187{
4188 SSL_set_options(conn->ssl, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
4189
4190 return 0;
4191}
4192
4193
4194#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
4195/* ClientHello TLS extensions require a patch to openssl, so this function is
4196 * commented out unless explicitly needed for EAP-FAST in order to be able to
4197 * build this file with unmodified openssl. */
4198int tls_connection_client_hello_ext(void *ssl_ctx, struct tls_connection *conn,
4199 int ext_type, const u8 *data,
4200 size_t data_len)
4201{
4202 if (conn == NULL || conn->ssl == NULL || ext_type != 35)
4203 return -1;
4204
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004205 if (SSL_set_session_ticket_ext(conn->ssl, (void *) data,
4206 data_len) != 1)
4207 return -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004208
4209 return 0;
4210}
4211#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
4212
4213
4214int tls_connection_get_failed(void *ssl_ctx, struct tls_connection *conn)
4215{
4216 if (conn == NULL)
4217 return -1;
4218 return conn->failed;
4219}
4220
4221
4222int tls_connection_get_read_alerts(void *ssl_ctx, struct tls_connection *conn)
4223{
4224 if (conn == NULL)
4225 return -1;
4226 return conn->read_alerts;
4227}
4228
4229
4230int tls_connection_get_write_alerts(void *ssl_ctx, struct tls_connection *conn)
4231{
4232 if (conn == NULL)
4233 return -1;
4234 return conn->write_alerts;
4235}
4236
4237
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004238#ifdef HAVE_OCSP
4239
4240static void ocsp_debug_print_resp(OCSP_RESPONSE *rsp)
4241{
4242#ifndef CONFIG_NO_STDOUT_DEBUG
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004243 BIO *out;
4244 size_t rlen;
4245 char *txt;
4246 int res;
4247
4248 if (wpa_debug_level > MSG_DEBUG)
4249 return;
4250
4251 out = BIO_new(BIO_s_mem());
4252 if (!out)
4253 return;
4254
4255 OCSP_RESPONSE_print(out, rsp, 0);
4256 rlen = BIO_ctrl_pending(out);
4257 txt = os_malloc(rlen + 1);
4258 if (!txt) {
4259 BIO_free(out);
4260 return;
4261 }
4262
4263 res = BIO_read(out, txt, rlen);
4264 if (res > 0) {
4265 txt[res] = '\0';
4266 wpa_printf(MSG_DEBUG, "OpenSSL: OCSP Response\n%s", txt);
4267 }
4268 os_free(txt);
4269 BIO_free(out);
4270#endif /* CONFIG_NO_STDOUT_DEBUG */
4271}
4272
4273
Dmitry Shmidt71757432014-06-02 13:50:35 -07004274static void debug_print_cert(X509 *cert, const char *title)
4275{
4276#ifndef CONFIG_NO_STDOUT_DEBUG
4277 BIO *out;
4278 size_t rlen;
4279 char *txt;
4280 int res;
4281
4282 if (wpa_debug_level > MSG_DEBUG)
4283 return;
4284
4285 out = BIO_new(BIO_s_mem());
4286 if (!out)
4287 return;
4288
4289 X509_print(out, cert);
4290 rlen = BIO_ctrl_pending(out);
4291 txt = os_malloc(rlen + 1);
4292 if (!txt) {
4293 BIO_free(out);
4294 return;
4295 }
4296
4297 res = BIO_read(out, txt, rlen);
4298 if (res > 0) {
4299 txt[res] = '\0';
4300 wpa_printf(MSG_DEBUG, "OpenSSL: %s\n%s", title, txt);
4301 }
4302 os_free(txt);
4303
4304 BIO_free(out);
4305#endif /* CONFIG_NO_STDOUT_DEBUG */
4306}
4307
4308
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004309static int ocsp_resp_cb(SSL *s, void *arg)
4310{
4311 struct tls_connection *conn = arg;
4312 const unsigned char *p;
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07004313 int len, status, reason, res;
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004314 OCSP_RESPONSE *rsp;
4315 OCSP_BASICRESP *basic;
4316 OCSP_CERTID *id;
4317 ASN1_GENERALIZEDTIME *produced_at, *this_update, *next_update;
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004318 X509_STORE *store;
4319 STACK_OF(X509) *certs = NULL;
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004320
4321 len = SSL_get_tlsext_status_ocsp_resp(s, &p);
4322 if (!p) {
4323 wpa_printf(MSG_DEBUG, "OpenSSL: No OCSP response received");
4324 return (conn->flags & TLS_CONN_REQUIRE_OCSP) ? 0 : 1;
4325 }
4326
4327 wpa_hexdump(MSG_DEBUG, "OpenSSL: OCSP response", p, len);
4328
4329 rsp = d2i_OCSP_RESPONSE(NULL, &p, len);
4330 if (!rsp) {
4331 wpa_printf(MSG_INFO, "OpenSSL: Failed to parse OCSP response");
4332 return 0;
4333 }
4334
4335 ocsp_debug_print_resp(rsp);
4336
4337 status = OCSP_response_status(rsp);
4338 if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
4339 wpa_printf(MSG_INFO, "OpenSSL: OCSP responder error %d (%s)",
4340 status, OCSP_response_status_str(status));
4341 return 0;
4342 }
4343
4344 basic = OCSP_response_get1_basic(rsp);
4345 if (!basic) {
4346 wpa_printf(MSG_INFO, "OpenSSL: Could not find BasicOCSPResponse");
4347 return 0;
4348 }
4349
Dmitry Shmidt216983b2015-02-06 10:50:36 -08004350 store = SSL_CTX_get_cert_store(conn->ssl_ctx);
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004351 if (conn->peer_issuer) {
Dmitry Shmidt71757432014-06-02 13:50:35 -07004352 debug_print_cert(conn->peer_issuer, "Add OCSP issuer");
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004353
4354 if (X509_STORE_add_cert(store, conn->peer_issuer) != 1) {
4355 tls_show_errors(MSG_INFO, __func__,
Dmitry Shmidt7f656022015-02-25 14:36:37 -08004356 "OpenSSL: Could not add issuer to certificate store");
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004357 }
4358 certs = sk_X509_new_null();
4359 if (certs) {
4360 X509 *cert;
4361 cert = X509_dup(conn->peer_issuer);
4362 if (cert && !sk_X509_push(certs, cert)) {
4363 tls_show_errors(
4364 MSG_INFO, __func__,
Dmitry Shmidt7f656022015-02-25 14:36:37 -08004365 "OpenSSL: Could not add issuer to OCSP responder trust store");
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004366 X509_free(cert);
4367 sk_X509_free(certs);
4368 certs = NULL;
4369 }
Dmitry Shmidt7f656022015-02-25 14:36:37 -08004370 if (certs && conn->peer_issuer_issuer) {
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004371 cert = X509_dup(conn->peer_issuer_issuer);
4372 if (cert && !sk_X509_push(certs, cert)) {
4373 tls_show_errors(
4374 MSG_INFO, __func__,
Dmitry Shmidt7f656022015-02-25 14:36:37 -08004375 "OpenSSL: Could not add issuer's issuer to OCSP responder trust store");
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004376 X509_free(cert);
4377 }
4378 }
4379 }
4380 }
4381
4382 status = OCSP_basic_verify(basic, certs, store, OCSP_TRUSTOTHER);
4383 sk_X509_pop_free(certs, X509_free);
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004384 if (status <= 0) {
4385 tls_show_errors(MSG_INFO, __func__,
4386 "OpenSSL: OCSP response failed verification");
4387 OCSP_BASICRESP_free(basic);
4388 OCSP_RESPONSE_free(rsp);
4389 return 0;
4390 }
4391
4392 wpa_printf(MSG_DEBUG, "OpenSSL: OCSP response verification succeeded");
4393
Dmitry Shmidt56052862013-10-04 10:23:25 -07004394 if (!conn->peer_cert) {
4395 wpa_printf(MSG_DEBUG, "OpenSSL: Peer certificate not available for OCSP status check");
4396 OCSP_BASICRESP_free(basic);
4397 OCSP_RESPONSE_free(rsp);
4398 return 0;
4399 }
4400
4401 if (!conn->peer_issuer) {
4402 wpa_printf(MSG_DEBUG, "OpenSSL: Peer issuer certificate not available for OCSP status check");
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004403 OCSP_BASICRESP_free(basic);
4404 OCSP_RESPONSE_free(rsp);
4405 return 0;
4406 }
4407
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07004408 id = OCSP_cert_to_id(EVP_sha256(), conn->peer_cert, conn->peer_issuer);
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004409 if (!id) {
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07004410 wpa_printf(MSG_DEBUG,
4411 "OpenSSL: Could not create OCSP certificate identifier (SHA256)");
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004412 OCSP_BASICRESP_free(basic);
4413 OCSP_RESPONSE_free(rsp);
4414 return 0;
4415 }
4416
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07004417 res = OCSP_resp_find_status(basic, id, &status, &reason, &produced_at,
4418 &this_update, &next_update);
4419 if (!res) {
4420 id = OCSP_cert_to_id(NULL, conn->peer_cert, conn->peer_issuer);
4421 if (!id) {
4422 wpa_printf(MSG_DEBUG,
4423 "OpenSSL: Could not create OCSP certificate identifier (SHA1)");
4424 OCSP_BASICRESP_free(basic);
4425 OCSP_RESPONSE_free(rsp);
4426 return 0;
4427 }
4428
4429 res = OCSP_resp_find_status(basic, id, &status, &reason,
4430 &produced_at, &this_update,
4431 &next_update);
4432 }
4433
4434 if (!res) {
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004435 wpa_printf(MSG_INFO, "OpenSSL: Could not find current server certificate from OCSP response%s",
4436 (conn->flags & TLS_CONN_REQUIRE_OCSP) ? "" :
4437 " (OCSP not required)");
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08004438 OCSP_CERTID_free(id);
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004439 OCSP_BASICRESP_free(basic);
4440 OCSP_RESPONSE_free(rsp);
4441 return (conn->flags & TLS_CONN_REQUIRE_OCSP) ? 0 : 1;
4442 }
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08004443 OCSP_CERTID_free(id);
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004444
4445 if (!OCSP_check_validity(this_update, next_update, 5 * 60, -1)) {
4446 tls_show_errors(MSG_INFO, __func__,
4447 "OpenSSL: OCSP status times invalid");
4448 OCSP_BASICRESP_free(basic);
4449 OCSP_RESPONSE_free(rsp);
4450 return 0;
4451 }
4452
4453 OCSP_BASICRESP_free(basic);
4454 OCSP_RESPONSE_free(rsp);
4455
4456 wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status for server certificate: %s",
4457 OCSP_cert_status_str(status));
4458
4459 if (status == V_OCSP_CERTSTATUS_GOOD)
4460 return 1;
4461 if (status == V_OCSP_CERTSTATUS_REVOKED)
4462 return 0;
4463 if (conn->flags & TLS_CONN_REQUIRE_OCSP) {
4464 wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status unknown, but OCSP required");
4465 return 0;
4466 }
Dmitry Shmidt051af732013-10-22 13:52:46 -07004467 wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status unknown, but OCSP was not required, so allow connection to continue");
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004468 return 1;
4469}
4470
4471
4472static int ocsp_status_cb(SSL *s, void *arg)
4473{
4474 char *tmp;
4475 char *resp;
4476 size_t len;
4477
4478 if (tls_global->ocsp_stapling_response == NULL) {
4479 wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status callback - no response configured");
4480 return SSL_TLSEXT_ERR_OK;
4481 }
4482
4483 resp = os_readfile(tls_global->ocsp_stapling_response, &len);
4484 if (resp == NULL) {
4485 wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status callback - could not read response file");
4486 /* TODO: Build OCSPResponse with responseStatus = internalError
4487 */
4488 return SSL_TLSEXT_ERR_OK;
4489 }
4490 wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status callback - send cached response");
4491 tmp = OPENSSL_malloc(len);
4492 if (tmp == NULL) {
4493 os_free(resp);
4494 return SSL_TLSEXT_ERR_ALERT_FATAL;
4495 }
4496
4497 os_memcpy(tmp, resp, len);
4498 os_free(resp);
4499 SSL_set_tlsext_status_ocsp_resp(s, tmp, len);
4500
4501 return SSL_TLSEXT_ERR_OK;
4502}
4503
4504#endif /* HAVE_OCSP */
4505
4506
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004507int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
4508 const struct tls_connection_params *params)
4509{
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004510 struct tls_data *data = tls_ctx;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004511 int ret;
4512 unsigned long err;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004513 int can_pkcs11 = 0;
4514 const char *key_id = params->key_id;
4515 const char *cert_id = params->cert_id;
4516 const char *ca_cert_id = params->ca_cert_id;
4517 const char *engine_id = params->engine ? params->engine_id : NULL;
Roshan Pius3a1667e2018-07-03 15:17:14 -07004518 const char *ciphers;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004519
4520 if (conn == NULL)
4521 return -1;
4522
Dmitry Shmidt014a3ff2015-12-28 13:27:49 -08004523 if (params->flags & TLS_CONN_REQUIRE_OCSP_ALL) {
4524 wpa_printf(MSG_INFO,
4525 "OpenSSL: ocsp=3 not supported");
4526 return -1;
4527 }
4528
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004529 /*
4530 * If the engine isn't explicitly configured, and any of the
4531 * cert/key fields are actually PKCS#11 URIs, then automatically
4532 * use the PKCS#11 ENGINE.
4533 */
4534 if (!engine_id || os_strcmp(engine_id, "pkcs11") == 0)
4535 can_pkcs11 = 1;
4536
4537 if (!key_id && params->private_key && can_pkcs11 &&
4538 os_strncmp(params->private_key, "pkcs11:", 7) == 0) {
4539 can_pkcs11 = 2;
4540 key_id = params->private_key;
4541 }
4542
4543 if (!cert_id && params->client_cert && can_pkcs11 &&
4544 os_strncmp(params->client_cert, "pkcs11:", 7) == 0) {
4545 can_pkcs11 = 2;
4546 cert_id = params->client_cert;
4547 }
4548
4549 if (!ca_cert_id && params->ca_cert && can_pkcs11 &&
4550 os_strncmp(params->ca_cert, "pkcs11:", 7) == 0) {
4551 can_pkcs11 = 2;
4552 ca_cert_id = params->ca_cert;
4553 }
4554
4555 /* If we need to automatically enable the PKCS#11 ENGINE, do so. */
4556 if (can_pkcs11 == 2 && !engine_id)
4557 engine_id = "pkcs11";
4558
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004559#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08004560#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004561 if (params->flags & TLS_CONN_EAP_FAST) {
4562 wpa_printf(MSG_DEBUG,
4563 "OpenSSL: Use TLSv1_method() for EAP-FAST");
4564 if (SSL_set_ssl_method(conn->ssl, TLSv1_method()) != 1) {
4565 tls_show_errors(MSG_INFO, __func__,
4566 "Failed to set TLSv1_method() for EAP-FAST");
4567 return -1;
4568 }
4569 }
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004570#endif
Roshan Pius3a1667e2018-07-03 15:17:14 -07004571#if OPENSSL_VERSION_NUMBER >= 0x10101000L
4572#ifdef SSL_OP_NO_TLSv1_3
4573 if (params->flags & TLS_CONN_EAP_FAST) {
4574 /* Need to disable TLS v1.3 at least for now since OpenSSL 1.1.1
4575 * refuses to start the handshake with the modified ciphersuite
4576 * list (no TLS v1.3 ciphersuites included) for EAP-FAST. */
4577 wpa_printf(MSG_DEBUG, "OpenSSL: Disable TLSv1.3 for EAP-FAST");
4578 SSL_set_options(conn->ssl, SSL_OP_NO_TLSv1_3);
4579 }
4580#endif /* SSL_OP_NO_TLSv1_3 */
4581#endif
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004582#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004583
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004584 while ((err = ERR_get_error())) {
4585 wpa_printf(MSG_INFO, "%s: Clearing pending SSL error: %s",
4586 __func__, ERR_error_string(err, NULL));
4587 }
4588
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004589 if (engine_id) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004590 wpa_printf(MSG_DEBUG, "SSL: Initializing TLS engine");
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004591 ret = tls_engine_init(conn, engine_id, params->pin,
4592 key_id, cert_id, ca_cert_id);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004593 if (ret)
4594 return ret;
4595 }
4596 if (tls_connection_set_subject_match(conn,
4597 params->subject_match,
Dmitry Shmidt051af732013-10-22 13:52:46 -07004598 params->altsubject_match,
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08004599 params->suffix_match,
4600 params->domain_match))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004601 return -1;
4602
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004603 if (engine_id && ca_cert_id) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004604 if (tls_connection_engine_ca_cert(data, conn, ca_cert_id))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004605 return TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004606 } else if (tls_connection_ca_cert(data, conn, params->ca_cert,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004607 params->ca_cert_blob,
4608 params->ca_cert_blob_len,
4609 params->ca_path))
4610 return -1;
4611
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004612 if (engine_id && cert_id) {
4613 if (tls_connection_engine_client_cert(conn, cert_id))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004614 return TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED;
4615 } else if (tls_connection_client_cert(conn, params->client_cert,
4616 params->client_cert_blob,
4617 params->client_cert_blob_len))
4618 return -1;
4619
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004620 if (engine_id && key_id) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004621 wpa_printf(MSG_DEBUG, "TLS: Using private key from engine");
4622 if (tls_connection_engine_private_key(conn))
4623 return TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004624 } else if (tls_connection_private_key(data, conn,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004625 params->private_key,
4626 params->private_key_passwd,
4627 params->private_key_blob,
4628 params->private_key_blob_len)) {
4629 wpa_printf(MSG_INFO, "TLS: Failed to load private key '%s'",
4630 params->private_key);
4631 return -1;
4632 }
4633
4634 if (tls_connection_dh(conn, params->dh_file)) {
4635 wpa_printf(MSG_INFO, "TLS: Failed to load DH file '%s'",
4636 params->dh_file);
4637 return -1;
4638 }
4639
Roshan Pius3a1667e2018-07-03 15:17:14 -07004640 ciphers = params->openssl_ciphers;
4641#ifdef CONFIG_SUITEB
4642#ifdef OPENSSL_IS_BORINGSSL
4643 if (ciphers && os_strcmp(ciphers, "SUITEB192") == 0) {
4644 /* BoringSSL removed support for SUITEB192, so need to handle
4645 * this with hardcoded ciphersuite and additional checks for
4646 * other parameters. */
4647 ciphers = "ECDHE-ECDSA-AES256-GCM-SHA384";
4648 }
4649#endif /* OPENSSL_IS_BORINGSSL */
4650#endif /* CONFIG_SUITEB */
4651 if (ciphers && SSL_set_cipher_list(conn->ssl, ciphers) != 1) {
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004652 wpa_printf(MSG_INFO,
4653 "OpenSSL: Failed to set cipher string '%s'",
Roshan Pius3a1667e2018-07-03 15:17:14 -07004654 ciphers);
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004655 return -1;
4656 }
4657
Hai Shalom39bc25d2019-02-06 16:32:13 -08004658 if (!params->openssl_ecdh_curves) {
4659#ifndef OPENSSL_IS_BORINGSSL
4660#ifndef OPENSSL_NO_EC
4661#if (OPENSSL_VERSION_NUMBER >= 0x10002000L) && \
4662 (OPENSSL_VERSION_NUMBER < 0x10100000L)
4663 if (SSL_set_ecdh_auto(conn->ssl, 1) != 1) {
4664 wpa_printf(MSG_INFO,
4665 "OpenSSL: Failed to set ECDH curves to auto");
4666 return -1;
4667 }
4668#endif /* >= 1.0.2 && < 1.1.0 */
4669#endif /* OPENSSL_NO_EC */
4670#endif /* OPENSSL_IS_BORINGSSL */
4671 } else if (params->openssl_ecdh_curves[0]) {
4672#if defined(OPENSSL_IS_BORINGSSL) || (OPENSSL_VERSION_NUMBER < 0x10002000L)
4673 wpa_printf(MSG_INFO,
4674 "OpenSSL: ECDH configuration nnot supported");
4675 return -1;
4676#else /* OPENSSL_IS_BORINGSSL || < 1.0.2 */
4677#ifndef OPENSSL_NO_EC
4678 if (SSL_set1_curves_list(conn->ssl,
4679 params->openssl_ecdh_curves) != 1) {
4680 wpa_printf(MSG_INFO,
4681 "OpenSSL: Failed to set ECDH curves '%s'",
4682 params->openssl_ecdh_curves);
4683 return -1;
4684 }
4685#else /* OPENSSL_NO_EC */
4686 wpa_printf(MSG_INFO, "OpenSSL: ECDH not supported");
4687 return -1;
4688#endif /* OPENSSL_NO_EC */
4689#endif /* OPENSSL_IS_BORINGSSL */
4690 }
4691
Roshan Pius3a1667e2018-07-03 15:17:14 -07004692 if (tls_set_conn_flags(conn, params->flags,
4693 params->openssl_ciphers) < 0)
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07004694 return -1;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07004695
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004696#ifdef OPENSSL_IS_BORINGSSL
4697 if (params->flags & TLS_CONN_REQUEST_OCSP) {
4698 SSL_enable_ocsp_stapling(conn->ssl);
4699 }
4700#else /* OPENSSL_IS_BORINGSSL */
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004701#ifdef HAVE_OCSP
4702 if (params->flags & TLS_CONN_REQUEST_OCSP) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004703 SSL_CTX *ssl_ctx = data->ssl;
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004704 SSL_set_tlsext_status_type(conn->ssl, TLSEXT_STATUSTYPE_ocsp);
4705 SSL_CTX_set_tlsext_status_cb(ssl_ctx, ocsp_resp_cb);
4706 SSL_CTX_set_tlsext_status_arg(ssl_ctx, conn);
4707 }
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004708#else /* HAVE_OCSP */
4709 if (params->flags & TLS_CONN_REQUIRE_OCSP) {
4710 wpa_printf(MSG_INFO,
4711 "OpenSSL: No OCSP support included - reject configuration");
4712 return -1;
4713 }
4714 if (params->flags & TLS_CONN_REQUEST_OCSP) {
4715 wpa_printf(MSG_DEBUG,
4716 "OpenSSL: No OCSP support included - allow optional OCSP case to continue");
4717 }
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004718#endif /* HAVE_OCSP */
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004719#endif /* OPENSSL_IS_BORINGSSL */
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004720
Dmitry Shmidtc55524a2011-07-07 11:18:38 -07004721 conn->flags = params->flags;
4722
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004723 tls_get_errors(data);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004724
4725 return 0;
4726}
4727
4728
4729int tls_global_set_params(void *tls_ctx,
4730 const struct tls_connection_params *params)
4731{
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004732 struct tls_data *data = tls_ctx;
4733 SSL_CTX *ssl_ctx = data->ssl;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004734 unsigned long err;
4735
4736 while ((err = ERR_get_error())) {
4737 wpa_printf(MSG_INFO, "%s: Clearing pending SSL error: %s",
4738 __func__, ERR_error_string(err, NULL));
4739 }
4740
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004741 if (tls_global_ca_cert(data, params->ca_cert) ||
4742 tls_global_client_cert(data, params->client_cert) ||
4743 tls_global_private_key(data, params->private_key,
4744 params->private_key_passwd) ||
4745 tls_global_dh(data, params->dh_file)) {
4746 wpa_printf(MSG_INFO, "TLS: Failed to set global parameters");
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004747 return -1;
4748 }
4749
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004750 if (params->openssl_ciphers &&
4751 SSL_CTX_set_cipher_list(ssl_ctx, params->openssl_ciphers) != 1) {
4752 wpa_printf(MSG_INFO,
4753 "OpenSSL: Failed to set cipher string '%s'",
4754 params->openssl_ciphers);
4755 return -1;
4756 }
4757
Hai Shalom39bc25d2019-02-06 16:32:13 -08004758 if (!params->openssl_ecdh_curves) {
4759#ifndef OPENSSL_IS_BORINGSSL
4760#ifndef OPENSSL_NO_EC
4761#if (OPENSSL_VERSION_NUMBER >= 0x10002000L) && \
4762 (OPENSSL_VERSION_NUMBER < 0x10100000L)
4763 if (SSL_CTX_set_ecdh_auto(ssl_ctx, 1) != 1) {
4764 wpa_printf(MSG_INFO,
4765 "OpenSSL: Failed to set ECDH curves to auto");
4766 return -1;
4767 }
4768#endif /* >= 1.0.2 && < 1.1.0 */
4769#endif /* OPENSSL_NO_EC */
4770#endif /* OPENSSL_IS_BORINGSSL */
4771 } else if (params->openssl_ecdh_curves[0]) {
4772#if defined(OPENSSL_IS_BORINGSSL) || (OPENSSL_VERSION_NUMBER < 0x10002000L)
4773 wpa_printf(MSG_INFO,
4774 "OpenSSL: ECDH configuration nnot supported");
4775 return -1;
4776#else /* OPENSSL_IS_BORINGSSL || < 1.0.2 */
4777#ifndef OPENSSL_NO_EC
4778 if (SSL_CTX_set1_curves_list(ssl_ctx,
4779 params->openssl_ecdh_curves) !=
4780 1) {
4781 wpa_printf(MSG_INFO,
4782 "OpenSSL: Failed to set ECDH curves '%s'",
4783 params->openssl_ecdh_curves);
4784 return -1;
4785 }
4786#else /* OPENSSL_NO_EC */
4787 wpa_printf(MSG_INFO, "OpenSSL: ECDH not supported");
4788 return -1;
4789#endif /* OPENSSL_NO_EC */
4790#endif /* OPENSSL_IS_BORINGSSL */
4791 }
4792
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07004793#ifdef SSL_OP_NO_TICKET
4794 if (params->flags & TLS_CONN_DISABLE_SESSION_TICKET)
4795 SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TICKET);
4796 else
4797 SSL_CTX_clear_options(ssl_ctx, SSL_OP_NO_TICKET);
4798#endif /* SSL_OP_NO_TICKET */
4799
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004800#ifdef HAVE_OCSP
4801 SSL_CTX_set_tlsext_status_cb(ssl_ctx, ocsp_status_cb);
4802 SSL_CTX_set_tlsext_status_arg(ssl_ctx, ssl_ctx);
4803 os_free(tls_global->ocsp_stapling_response);
4804 if (params->ocsp_stapling_response)
4805 tls_global->ocsp_stapling_response =
4806 os_strdup(params->ocsp_stapling_response);
4807 else
4808 tls_global->ocsp_stapling_response = NULL;
4809#endif /* HAVE_OCSP */
4810
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004811 return 0;
4812}
4813
4814
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004815#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
4816/* Pre-shared secred requires a patch to openssl, so this function is
4817 * commented out unless explicitly needed for EAP-FAST in order to be able to
4818 * build this file with unmodified openssl. */
4819
Dmitry Shmidt1d6bf422016-01-19 15:51:35 -08004820#if (defined(OPENSSL_IS_BORINGSSL) || OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -07004821static int tls_sess_sec_cb(SSL *s, void *secret, int *secret_len,
4822 STACK_OF(SSL_CIPHER) *peer_ciphers,
4823 const SSL_CIPHER **cipher, void *arg)
4824#else /* OPENSSL_IS_BORINGSSL */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004825static int tls_sess_sec_cb(SSL *s, void *secret, int *secret_len,
4826 STACK_OF(SSL_CIPHER) *peer_ciphers,
4827 SSL_CIPHER **cipher, void *arg)
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -07004828#endif /* OPENSSL_IS_BORINGSSL */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004829{
4830 struct tls_connection *conn = arg;
4831 int ret;
4832
Roshan Pius3a1667e2018-07-03 15:17:14 -07004833#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
4834 (defined(LIBRESSL_VERSION_NUMBER) && \
4835 LIBRESSL_VERSION_NUMBER < 0x20700000L)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004836 if (conn == NULL || conn->session_ticket_cb == NULL)
4837 return 0;
4838
4839 ret = conn->session_ticket_cb(conn->session_ticket_cb_ctx,
4840 conn->session_ticket,
4841 conn->session_ticket_len,
4842 s->s3->client_random,
4843 s->s3->server_random, secret);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004844#else
4845 unsigned char client_random[SSL3_RANDOM_SIZE];
4846 unsigned char server_random[SSL3_RANDOM_SIZE];
4847
4848 if (conn == NULL || conn->session_ticket_cb == NULL)
4849 return 0;
4850
4851 SSL_get_client_random(s, client_random, sizeof(client_random));
4852 SSL_get_server_random(s, server_random, sizeof(server_random));
4853
4854 ret = conn->session_ticket_cb(conn->session_ticket_cb_ctx,
4855 conn->session_ticket,
4856 conn->session_ticket_len,
4857 client_random,
4858 server_random, secret);
4859#endif
4860
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004861 os_free(conn->session_ticket);
4862 conn->session_ticket = NULL;
4863
4864 if (ret <= 0)
4865 return 0;
4866
4867 *secret_len = SSL_MAX_MASTER_KEY_LENGTH;
4868 return 1;
4869}
4870
4871
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004872static int tls_session_ticket_ext_cb(SSL *s, const unsigned char *data,
4873 int len, void *arg)
4874{
4875 struct tls_connection *conn = arg;
4876
4877 if (conn == NULL || conn->session_ticket_cb == NULL)
4878 return 0;
4879
4880 wpa_printf(MSG_DEBUG, "OpenSSL: %s: length=%d", __func__, len);
4881
4882 os_free(conn->session_ticket);
4883 conn->session_ticket = NULL;
4884
4885 wpa_hexdump(MSG_DEBUG, "OpenSSL: ClientHello SessionTicket "
4886 "extension", data, len);
4887
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07004888 conn->session_ticket = os_memdup(data, len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004889 if (conn->session_ticket == NULL)
4890 return 0;
4891
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004892 conn->session_ticket_len = len;
4893
4894 return 1;
4895}
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004896#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
4897
4898
4899int tls_connection_set_session_ticket_cb(void *tls_ctx,
4900 struct tls_connection *conn,
4901 tls_session_ticket_cb cb,
4902 void *ctx)
4903{
4904#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
4905 conn->session_ticket_cb = cb;
4906 conn->session_ticket_cb_ctx = ctx;
4907
4908 if (cb) {
4909 if (SSL_set_session_secret_cb(conn->ssl, tls_sess_sec_cb,
4910 conn) != 1)
4911 return -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004912 SSL_set_session_ticket_ext_cb(conn->ssl,
4913 tls_session_ticket_ext_cb, conn);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004914 } else {
4915 if (SSL_set_session_secret_cb(conn->ssl, NULL, NULL) != 1)
4916 return -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004917 SSL_set_session_ticket_ext_cb(conn->ssl, NULL, NULL);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004918 }
4919
4920 return 0;
4921#else /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
4922 return -1;
4923#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
4924}
Dmitry Shmidtff787d52015-01-12 13:01:47 -08004925
4926
4927int tls_get_library_version(char *buf, size_t buf_len)
4928{
Dmitry Shmidt1d6bf422016-01-19 15:51:35 -08004929#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08004930 return os_snprintf(buf, buf_len, "OpenSSL build=%s run=%s",
4931 OPENSSL_VERSION_TEXT,
4932 OpenSSL_version(OPENSSL_VERSION));
4933#else
Dmitry Shmidtff787d52015-01-12 13:01:47 -08004934 return os_snprintf(buf, buf_len, "OpenSSL build=%s run=%s",
4935 OPENSSL_VERSION_TEXT,
4936 SSLeay_version(SSLEAY_VERSION));
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08004937#endif
Dmitry Shmidtff787d52015-01-12 13:01:47 -08004938}
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004939
4940
4941void tls_connection_set_success_data(struct tls_connection *conn,
4942 struct wpabuf *data)
4943{
4944 SSL_SESSION *sess;
4945 struct wpabuf *old;
4946
4947 if (tls_ex_idx_session < 0)
4948 goto fail;
4949 sess = SSL_get_session(conn->ssl);
4950 if (!sess)
4951 goto fail;
4952 old = SSL_SESSION_get_ex_data(sess, tls_ex_idx_session);
4953 if (old) {
4954 wpa_printf(MSG_DEBUG, "OpenSSL: Replacing old success data %p",
4955 old);
4956 wpabuf_free(old);
4957 }
4958 if (SSL_SESSION_set_ex_data(sess, tls_ex_idx_session, data) != 1)
4959 goto fail;
4960
4961 wpa_printf(MSG_DEBUG, "OpenSSL: Stored success data %p", data);
4962 conn->success_data = 1;
4963 return;
4964
4965fail:
4966 wpa_printf(MSG_INFO, "OpenSSL: Failed to store success data");
4967 wpabuf_free(data);
4968}
4969
4970
4971void tls_connection_set_success_data_resumed(struct tls_connection *conn)
4972{
4973 wpa_printf(MSG_DEBUG,
4974 "OpenSSL: Success data accepted for resumed session");
4975 conn->success_data = 1;
4976}
4977
4978
4979const struct wpabuf *
4980tls_connection_get_success_data(struct tls_connection *conn)
4981{
4982 SSL_SESSION *sess;
4983
4984 if (tls_ex_idx_session < 0 ||
4985 !(sess = SSL_get_session(conn->ssl)))
4986 return NULL;
4987 return SSL_SESSION_get_ex_data(sess, tls_ex_idx_session);
4988}
4989
4990
4991void tls_connection_remove_session(struct tls_connection *conn)
4992{
4993 SSL_SESSION *sess;
4994
4995 sess = SSL_get_session(conn->ssl);
4996 if (!sess)
4997 return;
4998
4999 if (SSL_CTX_remove_session(conn->ssl_ctx, sess) != 1)
5000 wpa_printf(MSG_DEBUG,
5001 "OpenSSL: Session was not cached");
5002 else
5003 wpa_printf(MSG_DEBUG,
5004 "OpenSSL: Removed cached session to disable session resumption");
5005}