blob: 5bb14e222bb2c5ef927de5cfd8dde81420f7284b [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
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700107#if OPENSSL_VERSION_NUMBER < 0x10100000L
108#ifdef CONFIG_SUITEB
109static int RSA_bits(const RSA *r)
110{
111 return BN_num_bits(r->n);
112}
113#endif /* CONFIG_SUITEB */
Hai Shalom39ba6fc2019-01-22 12:40:38 -0800114
115
116static const unsigned char * ASN1_STRING_get0_data(const ASN1_STRING *x)
117{
118 return ASN1_STRING_data((ASN1_STRING *) x);
119}
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700120#endif
121
Dmitry Shmidtff079172013-11-08 14:10:30 -0800122#ifdef ANDROID
123#include <openssl/pem.h>
124#include <keystore/keystore_get.h>
125
Pavel Grafov4d8552e2018-02-06 11:28:29 +0000126#include <log/log.h>
127#include <log/log_event_list.h>
128
129#define CERT_VALIDATION_FAILURE 210033
130
131static void log_cert_validation_failure(const char *reason)
132{
133 android_log_context ctx = create_android_logger(CERT_VALIDATION_FAILURE);
134 android_log_write_string8(ctx, reason);
135 android_log_write_list(ctx, LOG_ID_SECURITY);
136 android_log_destroy(&ctx);
137}
138
139
Dmitry Shmidtff079172013-11-08 14:10:30 -0800140static BIO * BIO_from_keystore(const char *key)
141{
142 BIO *bio = NULL;
143 uint8_t *value = NULL;
144 int length = keystore_get(key, strlen(key), &value);
145 if (length != -1 && (bio = BIO_new(BIO_s_mem())) != NULL)
146 BIO_write(bio, value, length);
147 free(value);
148 return bio;
149}
Dmitry Shmidtb97e4282016-02-08 10:16:07 -0800150
151
152static int tls_add_ca_from_keystore(X509_STORE *ctx, const char *key_alias)
153{
154 BIO *bio = BIO_from_keystore(key_alias);
155 STACK_OF(X509_INFO) *stack = NULL;
156 stack_index_t i;
157
158 if (bio) {
159 stack = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL);
160 BIO_free(bio);
161 }
162
163 if (!stack) {
164 wpa_printf(MSG_WARNING, "TLS: Failed to parse certificate: %s",
165 key_alias);
166 return -1;
167 }
168
169 for (i = 0; i < sk_X509_INFO_num(stack); ++i) {
170 X509_INFO *info = sk_X509_INFO_value(stack, i);
171
172 if (info->x509)
173 X509_STORE_add_cert(ctx, info->x509);
174 if (info->crl)
175 X509_STORE_add_crl(ctx, info->crl);
176 }
177
178 sk_X509_INFO_pop_free(stack, X509_INFO_free);
179
180 return 0;
181}
182
183
184static int tls_add_ca_from_keystore_encoded(X509_STORE *ctx,
185 const char *encoded_key_alias)
186{
187 int rc = -1;
188 int len = os_strlen(encoded_key_alias);
189 unsigned char *decoded_alias;
190
191 if (len & 1) {
192 wpa_printf(MSG_WARNING, "Invalid hex-encoded alias: %s",
193 encoded_key_alias);
194 return rc;
195 }
196
197 decoded_alias = os_malloc(len / 2 + 1);
198 if (decoded_alias) {
199 if (!hexstr2bin(encoded_key_alias, decoded_alias, len / 2)) {
200 decoded_alias[len / 2] = '\0';
201 rc = tls_add_ca_from_keystore(
202 ctx, (const char *) decoded_alias);
203 }
204 os_free(decoded_alias);
205 }
206
207 return rc;
208}
209
Dmitry Shmidtff079172013-11-08 14:10:30 -0800210#endif /* ANDROID */
211
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700212static int tls_openssl_ref_count = 0;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800213static int tls_ex_idx_session = -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700214
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700215struct tls_context {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700216 void (*event_cb)(void *ctx, enum tls_event ev,
217 union tls_event_data *data);
218 void *cb_ctx;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800219 int cert_in_cb;
Dmitry Shmidt34af3062013-07-11 10:46:32 -0700220 char *ocsp_stapling_response;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700221};
222
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700223static struct tls_context *tls_global = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700224
225
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800226struct tls_data {
227 SSL_CTX *ssl;
228 unsigned int tls_session_lifetime;
229};
230
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700231struct tls_connection {
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700232 struct tls_context *context;
Dmitry Shmidt216983b2015-02-06 10:50:36 -0800233 SSL_CTX *ssl_ctx;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700234 SSL *ssl;
235 BIO *ssl_in, *ssl_out;
Adam Langley1eb02ed2015-04-21 19:00:05 -0700236#if defined(ANDROID) || !defined(OPENSSL_NO_ENGINE)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700237 ENGINE *engine; /* functional reference to the engine */
238 EVP_PKEY *private_key; /* the private key if using engine */
239#endif /* OPENSSL_NO_ENGINE */
Dmitry Shmidt2f74e362015-01-21 13:19:05 -0800240 char *subject_match, *altsubject_match, *suffix_match, *domain_match;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700241 int read_alerts, write_alerts, failed;
242
243 tls_session_ticket_cb session_ticket_cb;
244 void *session_ticket_cb_ctx;
245
246 /* SessionTicket received from OpenSSL hello_extension_cb (server) */
247 u8 *session_ticket;
248 size_t session_ticket_len;
249
250 unsigned int ca_cert_verify:1;
251 unsigned int cert_probe:1;
252 unsigned int server_cert_only:1;
Jouni Malinen26af48b2014-04-09 13:02:53 +0300253 unsigned int invalid_hb_used:1;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800254 unsigned int success_data:1;
Roshan Pius3a1667e2018-07-03 15:17:14 -0700255 unsigned int client_hello_generated:1;
256 unsigned int server:1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700257
258 u8 srv_cert_hash[32];
Dmitry Shmidtc55524a2011-07-07 11:18:38 -0700259
260 unsigned int flags;
Dmitry Shmidt34af3062013-07-11 10:46:32 -0700261
262 X509 *peer_cert;
263 X509 *peer_issuer;
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -0800264 X509 *peer_issuer_issuer;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800265
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800266 unsigned char client_random[SSL3_RANDOM_SIZE];
267 unsigned char server_random[SSL3_RANDOM_SIZE];
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700268
269 u16 cipher_suite;
270 int server_dh_prime_len;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700271};
272
273
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700274static struct tls_context * tls_context_new(const struct tls_config *conf)
275{
276 struct tls_context *context = os_zalloc(sizeof(*context));
277 if (context == NULL)
278 return NULL;
279 if (conf) {
280 context->event_cb = conf->event_cb;
281 context->cb_ctx = conf->cb_ctx;
282 context->cert_in_cb = conf->cert_in_cb;
283 }
284 return context;
285}
286
287
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700288#ifdef CONFIG_NO_STDOUT_DEBUG
289
290static void _tls_show_errors(void)
291{
292 unsigned long err;
293
294 while ((err = ERR_get_error())) {
295 /* Just ignore the errors, since stdout is disabled */
296 }
297}
298#define tls_show_errors(l, f, t) _tls_show_errors()
299
300#else /* CONFIG_NO_STDOUT_DEBUG */
301
302static void tls_show_errors(int level, const char *func, const char *txt)
303{
304 unsigned long err;
305
306 wpa_printf(level, "OpenSSL: %s - %s %s",
307 func, txt, ERR_error_string(ERR_get_error(), NULL));
308
309 while ((err = ERR_get_error())) {
310 wpa_printf(MSG_INFO, "OpenSSL: pending error: %s",
311 ERR_error_string(err, NULL));
312 }
313}
314
315#endif /* CONFIG_NO_STDOUT_DEBUG */
316
317
318#ifdef CONFIG_NATIVE_WINDOWS
319
320/* Windows CryptoAPI and access to certificate stores */
321#include <wincrypt.h>
322
323#ifdef __MINGW32_VERSION
324/*
325 * MinGW does not yet include all the needed definitions for CryptoAPI, so
326 * define here whatever extra is needed.
327 */
328#define CERT_SYSTEM_STORE_CURRENT_USER (1 << 16)
329#define CERT_STORE_READONLY_FLAG 0x00008000
330#define CERT_STORE_OPEN_EXISTING_FLAG 0x00004000
331
332#endif /* __MINGW32_VERSION */
333
334
335struct cryptoapi_rsa_data {
336 const CERT_CONTEXT *cert;
337 HCRYPTPROV crypt_prov;
338 DWORD key_spec;
339 BOOL free_crypt_prov;
340};
341
342
343static void cryptoapi_error(const char *msg)
344{
345 wpa_printf(MSG_INFO, "CryptoAPI: %s; err=%u",
346 msg, (unsigned int) GetLastError());
347}
348
349
350static int cryptoapi_rsa_pub_enc(int flen, const unsigned char *from,
351 unsigned char *to, RSA *rsa, int padding)
352{
353 wpa_printf(MSG_DEBUG, "%s - not implemented", __func__);
354 return 0;
355}
356
357
358static int cryptoapi_rsa_pub_dec(int flen, const unsigned char *from,
359 unsigned char *to, RSA *rsa, int padding)
360{
361 wpa_printf(MSG_DEBUG, "%s - not implemented", __func__);
362 return 0;
363}
364
365
366static int cryptoapi_rsa_priv_enc(int flen, const unsigned char *from,
367 unsigned char *to, RSA *rsa, int padding)
368{
369 struct cryptoapi_rsa_data *priv =
370 (struct cryptoapi_rsa_data *) rsa->meth->app_data;
371 HCRYPTHASH hash;
372 DWORD hash_size, len, i;
373 unsigned char *buf = NULL;
374 int ret = 0;
375
376 if (priv == NULL) {
377 RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,
378 ERR_R_PASSED_NULL_PARAMETER);
379 return 0;
380 }
381
382 if (padding != RSA_PKCS1_PADDING) {
383 RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,
384 RSA_R_UNKNOWN_PADDING_TYPE);
385 return 0;
386 }
387
388 if (flen != 16 /* MD5 */ + 20 /* SHA-1 */) {
389 wpa_printf(MSG_INFO, "%s - only MD5-SHA1 hash supported",
390 __func__);
391 RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,
392 RSA_R_INVALID_MESSAGE_LENGTH);
393 return 0;
394 }
395
396 if (!CryptCreateHash(priv->crypt_prov, CALG_SSL3_SHAMD5, 0, 0, &hash))
397 {
398 cryptoapi_error("CryptCreateHash failed");
399 return 0;
400 }
401
402 len = sizeof(hash_size);
403 if (!CryptGetHashParam(hash, HP_HASHSIZE, (BYTE *) &hash_size, &len,
404 0)) {
405 cryptoapi_error("CryptGetHashParam failed");
406 goto err;
407 }
408
409 if ((int) hash_size != flen) {
410 wpa_printf(MSG_INFO, "CryptoAPI: Invalid hash size (%u != %d)",
411 (unsigned) hash_size, flen);
412 RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,
413 RSA_R_INVALID_MESSAGE_LENGTH);
414 goto err;
415 }
416 if (!CryptSetHashParam(hash, HP_HASHVAL, (BYTE * ) from, 0)) {
417 cryptoapi_error("CryptSetHashParam failed");
418 goto err;
419 }
420
421 len = RSA_size(rsa);
422 buf = os_malloc(len);
423 if (buf == NULL) {
424 RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE);
425 goto err;
426 }
427
428 if (!CryptSignHash(hash, priv->key_spec, NULL, 0, buf, &len)) {
429 cryptoapi_error("CryptSignHash failed");
430 goto err;
431 }
432
433 for (i = 0; i < len; i++)
434 to[i] = buf[len - i - 1];
435 ret = len;
436
437err:
438 os_free(buf);
439 CryptDestroyHash(hash);
440
441 return ret;
442}
443
444
445static int cryptoapi_rsa_priv_dec(int flen, const unsigned char *from,
446 unsigned char *to, RSA *rsa, int padding)
447{
448 wpa_printf(MSG_DEBUG, "%s - not implemented", __func__);
449 return 0;
450}
451
452
453static void cryptoapi_free_data(struct cryptoapi_rsa_data *priv)
454{
455 if (priv == NULL)
456 return;
457 if (priv->crypt_prov && priv->free_crypt_prov)
458 CryptReleaseContext(priv->crypt_prov, 0);
459 if (priv->cert)
460 CertFreeCertificateContext(priv->cert);
461 os_free(priv);
462}
463
464
465static int cryptoapi_finish(RSA *rsa)
466{
467 cryptoapi_free_data((struct cryptoapi_rsa_data *) rsa->meth->app_data);
468 os_free((void *) rsa->meth);
469 rsa->meth = NULL;
470 return 1;
471}
472
473
474static const CERT_CONTEXT * cryptoapi_find_cert(const char *name, DWORD store)
475{
476 HCERTSTORE cs;
477 const CERT_CONTEXT *ret = NULL;
478
479 cs = CertOpenStore((LPCSTR) CERT_STORE_PROV_SYSTEM, 0, 0,
480 store | CERT_STORE_OPEN_EXISTING_FLAG |
481 CERT_STORE_READONLY_FLAG, L"MY");
482 if (cs == NULL) {
483 cryptoapi_error("Failed to open 'My system store'");
484 return NULL;
485 }
486
487 if (strncmp(name, "cert://", 7) == 0) {
488 unsigned short wbuf[255];
489 MultiByteToWideChar(CP_ACP, 0, name + 7, -1, wbuf, 255);
490 ret = CertFindCertificateInStore(cs, X509_ASN_ENCODING |
491 PKCS_7_ASN_ENCODING,
492 0, CERT_FIND_SUBJECT_STR,
493 wbuf, NULL);
494 } else if (strncmp(name, "hash://", 7) == 0) {
495 CRYPT_HASH_BLOB blob;
496 int len;
497 const char *hash = name + 7;
498 unsigned char *buf;
499
500 len = os_strlen(hash) / 2;
501 buf = os_malloc(len);
502 if (buf && hexstr2bin(hash, buf, len) == 0) {
503 blob.cbData = len;
504 blob.pbData = buf;
505 ret = CertFindCertificateInStore(cs,
506 X509_ASN_ENCODING |
507 PKCS_7_ASN_ENCODING,
508 0, CERT_FIND_HASH,
509 &blob, NULL);
510 }
511 os_free(buf);
512 }
513
514 CertCloseStore(cs, 0);
515
516 return ret;
517}
518
519
520static int tls_cryptoapi_cert(SSL *ssl, const char *name)
521{
522 X509 *cert = NULL;
523 RSA *rsa = NULL, *pub_rsa;
524 struct cryptoapi_rsa_data *priv;
525 RSA_METHOD *rsa_meth;
526
527 if (name == NULL ||
528 (strncmp(name, "cert://", 7) != 0 &&
529 strncmp(name, "hash://", 7) != 0))
530 return -1;
531
532 priv = os_zalloc(sizeof(*priv));
533 rsa_meth = os_zalloc(sizeof(*rsa_meth));
534 if (priv == NULL || rsa_meth == NULL) {
535 wpa_printf(MSG_WARNING, "CryptoAPI: Failed to allocate memory "
536 "for CryptoAPI RSA method");
537 os_free(priv);
538 os_free(rsa_meth);
539 return -1;
540 }
541
542 priv->cert = cryptoapi_find_cert(name, CERT_SYSTEM_STORE_CURRENT_USER);
543 if (priv->cert == NULL) {
544 priv->cert = cryptoapi_find_cert(
545 name, CERT_SYSTEM_STORE_LOCAL_MACHINE);
546 }
547 if (priv->cert == NULL) {
548 wpa_printf(MSG_INFO, "CryptoAPI: Could not find certificate "
549 "'%s'", name);
550 goto err;
551 }
552
Dmitry Shmidt216983b2015-02-06 10:50:36 -0800553 cert = d2i_X509(NULL,
554 (const unsigned char **) &priv->cert->pbCertEncoded,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700555 priv->cert->cbCertEncoded);
556 if (cert == NULL) {
557 wpa_printf(MSG_INFO, "CryptoAPI: Could not process X509 DER "
558 "encoding");
559 goto err;
560 }
561
562 if (!CryptAcquireCertificatePrivateKey(priv->cert,
563 CRYPT_ACQUIRE_COMPARE_KEY_FLAG,
564 NULL, &priv->crypt_prov,
565 &priv->key_spec,
566 &priv->free_crypt_prov)) {
567 cryptoapi_error("Failed to acquire a private key for the "
568 "certificate");
569 goto err;
570 }
571
572 rsa_meth->name = "Microsoft CryptoAPI RSA Method";
573 rsa_meth->rsa_pub_enc = cryptoapi_rsa_pub_enc;
574 rsa_meth->rsa_pub_dec = cryptoapi_rsa_pub_dec;
575 rsa_meth->rsa_priv_enc = cryptoapi_rsa_priv_enc;
576 rsa_meth->rsa_priv_dec = cryptoapi_rsa_priv_dec;
577 rsa_meth->finish = cryptoapi_finish;
578 rsa_meth->flags = RSA_METHOD_FLAG_NO_CHECK;
579 rsa_meth->app_data = (char *) priv;
580
581 rsa = RSA_new();
582 if (rsa == NULL) {
583 SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,
584 ERR_R_MALLOC_FAILURE);
585 goto err;
586 }
587
588 if (!SSL_use_certificate(ssl, cert)) {
589 RSA_free(rsa);
590 rsa = NULL;
591 goto err;
592 }
593 pub_rsa = cert->cert_info->key->pkey->pkey.rsa;
594 X509_free(cert);
595 cert = NULL;
596
597 rsa->n = BN_dup(pub_rsa->n);
598 rsa->e = BN_dup(pub_rsa->e);
599 if (!RSA_set_method(rsa, rsa_meth))
600 goto err;
601
602 if (!SSL_use_RSAPrivateKey(ssl, rsa))
603 goto err;
604 RSA_free(rsa);
605
606 return 0;
607
608err:
609 if (cert)
610 X509_free(cert);
611 if (rsa)
612 RSA_free(rsa);
613 else {
614 os_free(rsa_meth);
615 cryptoapi_free_data(priv);
616 }
617 return -1;
618}
619
620
621static int tls_cryptoapi_ca_cert(SSL_CTX *ssl_ctx, SSL *ssl, const char *name)
622{
623 HCERTSTORE cs;
624 PCCERT_CONTEXT ctx = NULL;
625 X509 *cert;
626 char buf[128];
627 const char *store;
628#ifdef UNICODE
629 WCHAR *wstore;
630#endif /* UNICODE */
631
632 if (name == NULL || strncmp(name, "cert_store://", 13) != 0)
633 return -1;
634
635 store = name + 13;
636#ifdef UNICODE
637 wstore = os_malloc((os_strlen(store) + 1) * sizeof(WCHAR));
638 if (wstore == NULL)
639 return -1;
640 wsprintf(wstore, L"%S", store);
641 cs = CertOpenSystemStore(0, wstore);
642 os_free(wstore);
643#else /* UNICODE */
644 cs = CertOpenSystemStore(0, store);
645#endif /* UNICODE */
646 if (cs == NULL) {
647 wpa_printf(MSG_DEBUG, "%s: failed to open system cert store "
648 "'%s': error=%d", __func__, store,
649 (int) GetLastError());
650 return -1;
651 }
652
653 while ((ctx = CertEnumCertificatesInStore(cs, ctx))) {
Dmitry Shmidt216983b2015-02-06 10:50:36 -0800654 cert = d2i_X509(NULL,
655 (const unsigned char **) &ctx->pbCertEncoded,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700656 ctx->cbCertEncoded);
657 if (cert == NULL) {
658 wpa_printf(MSG_INFO, "CryptoAPI: Could not process "
659 "X509 DER encoding for CA cert");
660 continue;
661 }
662
663 X509_NAME_oneline(X509_get_subject_name(cert), buf,
664 sizeof(buf));
665 wpa_printf(MSG_DEBUG, "OpenSSL: Loaded CA certificate for "
666 "system certificate store: subject='%s'", buf);
667
Dmitry Shmidt849734c2016-05-27 09:59:01 -0700668 if (!X509_STORE_add_cert(SSL_CTX_get_cert_store(ssl_ctx),
669 cert)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700670 tls_show_errors(MSG_WARNING, __func__,
671 "Failed to add ca_cert to OpenSSL "
672 "certificate store");
673 }
674
675 X509_free(cert);
676 }
677
678 if (!CertCloseStore(cs, 0)) {
679 wpa_printf(MSG_DEBUG, "%s: failed to close system cert store "
680 "'%s': error=%d", __func__, name + 13,
681 (int) GetLastError());
682 }
683
684 return 0;
685}
686
687
688#else /* CONFIG_NATIVE_WINDOWS */
689
690static int tls_cryptoapi_cert(SSL *ssl, const char *name)
691{
692 return -1;
693}
694
695#endif /* CONFIG_NATIVE_WINDOWS */
696
697
698static void ssl_info_cb(const SSL *ssl, int where, int ret)
699{
700 const char *str;
701 int w;
702
703 wpa_printf(MSG_DEBUG, "SSL: (where=0x%x ret=0x%x)", where, ret);
704 w = where & ~SSL_ST_MASK;
705 if (w & SSL_ST_CONNECT)
706 str = "SSL_connect";
707 else if (w & SSL_ST_ACCEPT)
708 str = "SSL_accept";
709 else
710 str = "undefined";
711
712 if (where & SSL_CB_LOOP) {
713 wpa_printf(MSG_DEBUG, "SSL: %s:%s",
714 str, SSL_state_string_long(ssl));
715 } else if (where & SSL_CB_ALERT) {
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700716 struct tls_connection *conn = SSL_get_app_data((SSL *) ssl);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700717 wpa_printf(MSG_INFO, "SSL: SSL3 alert: %s:%s:%s",
718 where & SSL_CB_READ ?
719 "read (remote end reported an error)" :
720 "write (local SSL3 detected an error)",
721 SSL_alert_type_string_long(ret),
722 SSL_alert_desc_string_long(ret));
723 if ((ret >> 8) == SSL3_AL_FATAL) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700724 if (where & SSL_CB_READ)
725 conn->read_alerts++;
726 else
727 conn->write_alerts++;
728 }
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700729 if (conn->context->event_cb != NULL) {
Dmitry Shmidt04949592012-07-19 12:16:46 -0700730 union tls_event_data ev;
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700731 struct tls_context *context = conn->context;
Dmitry Shmidt04949592012-07-19 12:16:46 -0700732 os_memset(&ev, 0, sizeof(ev));
733 ev.alert.is_local = !(where & SSL_CB_READ);
734 ev.alert.type = SSL_alert_type_string_long(ret);
735 ev.alert.description = SSL_alert_desc_string_long(ret);
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700736 context->event_cb(context->cb_ctx, TLS_ALERT, &ev);
Dmitry Shmidt04949592012-07-19 12:16:46 -0700737 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700738 } else if (where & SSL_CB_EXIT && ret <= 0) {
739 wpa_printf(MSG_DEBUG, "SSL: %s:%s in %s",
740 str, ret == 0 ? "failed" : "error",
741 SSL_state_string_long(ssl));
742 }
743}
744
745
746#ifndef OPENSSL_NO_ENGINE
747/**
748 * tls_engine_load_dynamic_generic - load any openssl engine
749 * @pre: an array of commands and values that load an engine initialized
750 * in the engine specific function
751 * @post: an array of commands and values that initialize an already loaded
752 * engine (or %NULL if not required)
753 * @id: the engine id of the engine to load (only required if post is not %NULL
754 *
755 * This function is a generic function that loads any openssl engine.
756 *
757 * Returns: 0 on success, -1 on failure
758 */
759static int tls_engine_load_dynamic_generic(const char *pre[],
760 const char *post[], const char *id)
761{
762 ENGINE *engine;
763 const char *dynamic_id = "dynamic";
764
765 engine = ENGINE_by_id(id);
766 if (engine) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700767 wpa_printf(MSG_DEBUG, "ENGINE: engine '%s' is already "
768 "available", id);
Dmitry Shmidtd5ab1b52016-06-21 12:38:41 -0700769 /*
770 * If it was auto-loaded by ENGINE_by_id() we might still
771 * need to tell it which PKCS#11 module to use in legacy
772 * (non-p11-kit) environments. Do so now; even if it was
773 * properly initialised before, setting it again will be
774 * harmless.
775 */
776 goto found;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700777 }
778 ERR_clear_error();
779
780 engine = ENGINE_by_id(dynamic_id);
781 if (engine == NULL) {
782 wpa_printf(MSG_INFO, "ENGINE: Can't find engine %s [%s]",
783 dynamic_id,
784 ERR_error_string(ERR_get_error(), NULL));
785 return -1;
786 }
787
788 /* Perform the pre commands. This will load the engine. */
789 while (pre && pre[0]) {
790 wpa_printf(MSG_DEBUG, "ENGINE: '%s' '%s'", pre[0], pre[1]);
791 if (ENGINE_ctrl_cmd_string(engine, pre[0], pre[1], 0) == 0) {
792 wpa_printf(MSG_INFO, "ENGINE: ctrl cmd_string failed: "
793 "%s %s [%s]", pre[0], pre[1],
794 ERR_error_string(ERR_get_error(), NULL));
795 ENGINE_free(engine);
796 return -1;
797 }
798 pre += 2;
799 }
800
801 /*
802 * Free the reference to the "dynamic" engine. The loaded engine can
803 * now be looked up using ENGINE_by_id().
804 */
805 ENGINE_free(engine);
806
807 engine = ENGINE_by_id(id);
808 if (engine == NULL) {
809 wpa_printf(MSG_INFO, "ENGINE: Can't find engine %s [%s]",
810 id, ERR_error_string(ERR_get_error(), NULL));
811 return -1;
812 }
Dmitry Shmidtd5ab1b52016-06-21 12:38:41 -0700813 found:
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700814 while (post && post[0]) {
815 wpa_printf(MSG_DEBUG, "ENGINE: '%s' '%s'", post[0], post[1]);
816 if (ENGINE_ctrl_cmd_string(engine, post[0], post[1], 0) == 0) {
817 wpa_printf(MSG_DEBUG, "ENGINE: ctrl cmd_string failed:"
818 " %s %s [%s]", post[0], post[1],
819 ERR_error_string(ERR_get_error(), NULL));
820 ENGINE_remove(engine);
821 ENGINE_free(engine);
822 return -1;
823 }
824 post += 2;
825 }
826 ENGINE_free(engine);
827
828 return 0;
829}
830
831
832/**
833 * tls_engine_load_dynamic_pkcs11 - load the pkcs11 engine provided by opensc
834 * @pkcs11_so_path: pksc11_so_path from the configuration
835 * @pcks11_module_path: pkcs11_module_path from the configuration
836 */
837static int tls_engine_load_dynamic_pkcs11(const char *pkcs11_so_path,
838 const char *pkcs11_module_path)
839{
840 char *engine_id = "pkcs11";
841 const char *pre_cmd[] = {
842 "SO_PATH", NULL /* pkcs11_so_path */,
843 "ID", NULL /* engine_id */,
844 "LIST_ADD", "1",
845 /* "NO_VCHECK", "1", */
846 "LOAD", NULL,
847 NULL, NULL
848 };
849 const char *post_cmd[] = {
850 "MODULE_PATH", NULL /* pkcs11_module_path */,
851 NULL, NULL
852 };
853
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800854 if (!pkcs11_so_path)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700855 return 0;
856
857 pre_cmd[1] = pkcs11_so_path;
858 pre_cmd[3] = engine_id;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800859 if (pkcs11_module_path)
860 post_cmd[1] = pkcs11_module_path;
861 else
862 post_cmd[0] = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700863
864 wpa_printf(MSG_DEBUG, "ENGINE: Loading pkcs11 Engine from %s",
865 pkcs11_so_path);
866
867 return tls_engine_load_dynamic_generic(pre_cmd, post_cmd, engine_id);
868}
869
870
871/**
872 * tls_engine_load_dynamic_opensc - load the opensc engine provided by opensc
873 * @opensc_so_path: opensc_so_path from the configuration
874 */
875static int tls_engine_load_dynamic_opensc(const char *opensc_so_path)
876{
877 char *engine_id = "opensc";
878 const char *pre_cmd[] = {
879 "SO_PATH", NULL /* opensc_so_path */,
880 "ID", NULL /* engine_id */,
881 "LIST_ADD", "1",
882 "LOAD", NULL,
883 NULL, NULL
884 };
885
886 if (!opensc_so_path)
887 return 0;
888
889 pre_cmd[1] = opensc_so_path;
890 pre_cmd[3] = engine_id;
891
892 wpa_printf(MSG_DEBUG, "ENGINE: Loading OpenSC Engine from %s",
893 opensc_so_path);
894
895 return tls_engine_load_dynamic_generic(pre_cmd, NULL, engine_id);
896}
897#endif /* OPENSSL_NO_ENGINE */
898
899
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800900static void remove_session_cb(SSL_CTX *ctx, SSL_SESSION *sess)
901{
902 struct wpabuf *buf;
903
904 if (tls_ex_idx_session < 0)
905 return;
906 buf = SSL_SESSION_get_ex_data(sess, tls_ex_idx_session);
907 if (!buf)
908 return;
909 wpa_printf(MSG_DEBUG,
910 "OpenSSL: Free application session data %p (sess %p)",
911 buf, sess);
912 wpabuf_free(buf);
913
914 SSL_SESSION_set_ex_data(sess, tls_ex_idx_session, NULL);
915}
916
917
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700918void * tls_init(const struct tls_config *conf)
919{
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800920 struct tls_data *data;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700921 SSL_CTX *ssl;
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700922 struct tls_context *context;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800923 const char *ciphers;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700924
925 if (tls_openssl_ref_count == 0) {
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700926 tls_global = context = tls_context_new(conf);
927 if (context == NULL)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700928 return NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700929#ifdef CONFIG_FIPS
930#ifdef OPENSSL_FIPS
931 if (conf && conf->fips_mode) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800932 static int fips_enabled = 0;
933
934 if (!fips_enabled && !FIPS_mode_set(1)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700935 wpa_printf(MSG_ERROR, "Failed to enable FIPS "
936 "mode");
937 ERR_load_crypto_strings();
938 ERR_print_errors_fp(stderr);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700939 os_free(tls_global);
940 tls_global = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700941 return NULL;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800942 } else {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700943 wpa_printf(MSG_INFO, "Running in FIPS mode");
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800944 fips_enabled = 1;
945 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700946 }
947#else /* OPENSSL_FIPS */
948 if (conf && conf->fips_mode) {
949 wpa_printf(MSG_ERROR, "FIPS mode requested, but not "
950 "supported");
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700951 os_free(tls_global);
952 tls_global = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700953 return NULL;
954 }
955#endif /* OPENSSL_FIPS */
956#endif /* CONFIG_FIPS */
Roshan Pius3a1667e2018-07-03 15:17:14 -0700957#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
958 (defined(LIBRESSL_VERSION_NUMBER) && \
959 LIBRESSL_VERSION_NUMBER < 0x20700000L)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700960 SSL_load_error_strings();
961 SSL_library_init();
Dmitry Shmidt216983b2015-02-06 10:50:36 -0800962#ifndef OPENSSL_NO_SHA256
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700963 EVP_add_digest(EVP_sha256());
964#endif /* OPENSSL_NO_SHA256 */
965 /* TODO: if /dev/urandom is available, PRNG is seeded
966 * automatically. If this is not the case, random data should
967 * be added here. */
968
969#ifdef PKCS12_FUNCS
970#ifndef OPENSSL_NO_RC2
971 /*
972 * 40-bit RC2 is commonly used in PKCS#12 files, so enable it.
973 * This is enabled by PKCS12_PBE_add() in OpenSSL 0.9.8
974 * versions, but it looks like OpenSSL 1.0.0 does not do that
975 * anymore.
976 */
977 EVP_add_cipher(EVP_rc2_40_cbc());
978#endif /* OPENSSL_NO_RC2 */
979 PKCS12_PBE_add();
980#endif /* PKCS12_FUNCS */
Dmitry Shmidt57c2d392016-02-23 13:40:19 -0800981#endif /* < 1.1.0 */
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700982 } else {
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700983 context = tls_context_new(conf);
984 if (context == NULL)
985 return NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700986 }
987 tls_openssl_ref_count++;
988
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800989 data = os_zalloc(sizeof(*data));
990 if (data)
991 ssl = SSL_CTX_new(SSLv23_method());
992 else
993 ssl = NULL;
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700994 if (ssl == NULL) {
995 tls_openssl_ref_count--;
Dmitry Shmidt68d0e3e2013-10-28 17:59:21 -0700996 if (context != tls_global)
997 os_free(context);
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700998 if (tls_openssl_ref_count == 0) {
999 os_free(tls_global);
1000 tls_global = NULL;
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001001 }
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08001002 os_free(data);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001003 return NULL;
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001004 }
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001005 data->ssl = ssl;
1006 if (conf)
1007 data->tls_session_lifetime = conf->tls_session_lifetime;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001008
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001009 SSL_CTX_set_options(ssl, SSL_OP_NO_SSLv2);
1010 SSL_CTX_set_options(ssl, SSL_OP_NO_SSLv3);
1011
Dmitry Shmidt29333592017-01-09 12:27:11 -08001012#ifdef SSL_MODE_NO_AUTO_CHAIN
1013 /* Number of deployed use cases assume the default OpenSSL behavior of
1014 * auto chaining the local certificate is in use. BoringSSL removed this
1015 * functionality by default, so we need to restore it here to avoid
1016 * breaking existing use cases. */
1017 SSL_CTX_clear_mode(ssl, SSL_MODE_NO_AUTO_CHAIN);
1018#endif /* SSL_MODE_NO_AUTO_CHAIN */
1019
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001020 SSL_CTX_set_info_callback(ssl, ssl_info_cb);
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001021 SSL_CTX_set_app_data(ssl, context);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001022 if (data->tls_session_lifetime > 0) {
1023 SSL_CTX_set_quiet_shutdown(ssl, 1);
1024 /*
1025 * Set default context here. In practice, this will be replaced
1026 * by the per-EAP method context in tls_connection_set_verify().
1027 */
1028 SSL_CTX_set_session_id_context(ssl, (u8 *) "hostapd", 7);
1029 SSL_CTX_set_session_cache_mode(ssl, SSL_SESS_CACHE_SERVER);
1030 SSL_CTX_set_timeout(ssl, data->tls_session_lifetime);
1031 SSL_CTX_sess_set_remove_cb(ssl, remove_session_cb);
1032 } else {
1033 SSL_CTX_set_session_cache_mode(ssl, SSL_SESS_CACHE_OFF);
1034 }
1035
1036 if (tls_ex_idx_session < 0) {
1037 tls_ex_idx_session = SSL_SESSION_get_ex_new_index(
1038 0, NULL, NULL, NULL, NULL);
1039 if (tls_ex_idx_session < 0) {
1040 tls_deinit(data);
1041 return NULL;
1042 }
1043 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001044
1045#ifndef OPENSSL_NO_ENGINE
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001046 wpa_printf(MSG_DEBUG, "ENGINE: Loading dynamic engine");
Hai Shalomce48b4a2018-09-05 11:41:35 -07001047#if OPENSSL_VERSION_NUMBER < 0x10100000L
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001048 ERR_load_ENGINE_strings();
1049 ENGINE_load_dynamic();
Hai Shalomce48b4a2018-09-05 11:41:35 -07001050#endif /* OPENSSL_VERSION_NUMBER */
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001051
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001052 if (conf &&
1053 (conf->opensc_engine_path || conf->pkcs11_engine_path ||
1054 conf->pkcs11_module_path)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001055 if (tls_engine_load_dynamic_opensc(conf->opensc_engine_path) ||
1056 tls_engine_load_dynamic_pkcs11(conf->pkcs11_engine_path,
1057 conf->pkcs11_module_path)) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001058 tls_deinit(data);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001059 return NULL;
1060 }
1061 }
1062#endif /* OPENSSL_NO_ENGINE */
1063
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001064 if (conf && conf->openssl_ciphers)
1065 ciphers = conf->openssl_ciphers;
1066 else
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001067 ciphers = TLS_DEFAULT_CIPHERS;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001068 if (SSL_CTX_set_cipher_list(ssl, ciphers) != 1) {
1069 wpa_printf(MSG_ERROR,
1070 "OpenSSL: Failed to set cipher string '%s'",
1071 ciphers);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001072 tls_deinit(data);
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001073 return NULL;
1074 }
1075
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001076 return data;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001077}
1078
1079
1080void tls_deinit(void *ssl_ctx)
1081{
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001082 struct tls_data *data = ssl_ctx;
1083 SSL_CTX *ssl = data->ssl;
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001084 struct tls_context *context = SSL_CTX_get_app_data(ssl);
1085 if (context != tls_global)
1086 os_free(context);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001087 if (data->tls_session_lifetime > 0)
1088 SSL_CTX_flush_sessions(ssl, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001089 SSL_CTX_free(ssl);
1090
1091 tls_openssl_ref_count--;
1092 if (tls_openssl_ref_count == 0) {
Roshan Pius3a1667e2018-07-03 15:17:14 -07001093#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
1094 (defined(LIBRESSL_VERSION_NUMBER) && \
1095 LIBRESSL_VERSION_NUMBER < 0x20700000L)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001096#ifndef OPENSSL_NO_ENGINE
1097 ENGINE_cleanup();
1098#endif /* OPENSSL_NO_ENGINE */
1099 CRYPTO_cleanup_all_ex_data();
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -07001100 ERR_remove_thread_state(NULL);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001101 ERR_free_strings();
1102 EVP_cleanup();
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08001103#endif /* < 1.1.0 */
Dmitry Shmidt34af3062013-07-11 10:46:32 -07001104 os_free(tls_global->ocsp_stapling_response);
1105 tls_global->ocsp_stapling_response = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001106 os_free(tls_global);
1107 tls_global = NULL;
1108 }
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001109
1110 os_free(data);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001111}
1112
1113
Dmitry Shmidt1d755d02015-04-28 10:34:29 -07001114#ifndef OPENSSL_NO_ENGINE
1115
1116/* Cryptoki return values */
1117#define CKR_PIN_INCORRECT 0x000000a0
1118#define CKR_PIN_INVALID 0x000000a1
1119#define CKR_PIN_LEN_RANGE 0x000000a2
1120
1121/* libp11 */
1122#define ERR_LIB_PKCS11 ERR_LIB_USER
1123
1124static int tls_is_pin_error(unsigned int err)
1125{
1126 return ERR_GET_LIB(err) == ERR_LIB_PKCS11 &&
1127 (ERR_GET_REASON(err) == CKR_PIN_INCORRECT ||
1128 ERR_GET_REASON(err) == CKR_PIN_INVALID ||
1129 ERR_GET_REASON(err) == CKR_PIN_LEN_RANGE);
1130}
1131
1132#endif /* OPENSSL_NO_ENGINE */
1133
1134
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001135#ifdef ANDROID
1136/* EVP_PKEY_from_keystore comes from system/security/keystore-engine. */
1137EVP_PKEY * EVP_PKEY_from_keystore(const char *key_id);
1138#endif /* ANDROID */
1139
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001140static int tls_engine_init(struct tls_connection *conn, const char *engine_id,
1141 const char *pin, const char *key_id,
1142 const char *cert_id, const char *ca_cert_id)
1143{
Adam Langley1eb02ed2015-04-21 19:00:05 -07001144#if defined(ANDROID) && defined(OPENSSL_IS_BORINGSSL)
1145#if !defined(OPENSSL_NO_ENGINE)
1146#error "This code depends on OPENSSL_NO_ENGINE being defined by BoringSSL."
1147#endif
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001148 if (!key_id)
1149 return TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED;
Adam Langley1eb02ed2015-04-21 19:00:05 -07001150 conn->engine = NULL;
1151 conn->private_key = EVP_PKEY_from_keystore(key_id);
1152 if (!conn->private_key) {
1153 wpa_printf(MSG_ERROR,
1154 "ENGINE: cannot load private key with id '%s' [%s]",
1155 key_id,
1156 ERR_error_string(ERR_get_error(), NULL));
1157 return TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED;
1158 }
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001159#endif /* ANDROID && OPENSSL_IS_BORINGSSL */
Adam Langley1eb02ed2015-04-21 19:00:05 -07001160
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001161#ifndef OPENSSL_NO_ENGINE
1162 int ret = -1;
1163 if (engine_id == NULL) {
1164 wpa_printf(MSG_ERROR, "ENGINE: Engine ID not set");
1165 return -1;
1166 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001167
1168 ERR_clear_error();
Kenny Rootdb3c5a42012-03-20 17:00:47 -07001169#ifdef ANDROID
1170 ENGINE_load_dynamic();
1171#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001172 conn->engine = ENGINE_by_id(engine_id);
1173 if (!conn->engine) {
1174 wpa_printf(MSG_ERROR, "ENGINE: engine %s not available [%s]",
1175 engine_id, ERR_error_string(ERR_get_error(), NULL));
1176 goto err;
1177 }
1178 if (ENGINE_init(conn->engine) != 1) {
1179 wpa_printf(MSG_ERROR, "ENGINE: engine init failed "
1180 "(engine: %s) [%s]", engine_id,
1181 ERR_error_string(ERR_get_error(), NULL));
1182 goto err;
1183 }
1184 wpa_printf(MSG_DEBUG, "ENGINE: engine initialized");
1185
Kenny Rootdb3c5a42012-03-20 17:00:47 -07001186#ifndef ANDROID
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001187 if (pin && ENGINE_ctrl_cmd_string(conn->engine, "PIN", pin, 0) == 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001188 wpa_printf(MSG_ERROR, "ENGINE: cannot set pin [%s]",
1189 ERR_error_string(ERR_get_error(), NULL));
1190 goto err;
1191 }
Kenny Rootdb3c5a42012-03-20 17:00:47 -07001192#endif
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001193 if (key_id) {
1194 /*
1195 * Ensure that the ENGINE does not attempt to use the OpenSSL
1196 * UI system to obtain a PIN, if we didn't provide one.
1197 */
1198 struct {
1199 const void *password;
1200 const char *prompt_info;
1201 } key_cb = { "", NULL };
1202
1203 /* load private key first in-case PIN is required for cert */
1204 conn->private_key = ENGINE_load_private_key(conn->engine,
1205 key_id, NULL,
1206 &key_cb);
1207 if (!conn->private_key) {
Dmitry Shmidt1d755d02015-04-28 10:34:29 -07001208 unsigned long err = ERR_get_error();
1209
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001210 wpa_printf(MSG_ERROR,
1211 "ENGINE: cannot load private key with id '%s' [%s]",
1212 key_id,
Dmitry Shmidt1d755d02015-04-28 10:34:29 -07001213 ERR_error_string(err, NULL));
1214 if (tls_is_pin_error(err))
1215 ret = TLS_SET_PARAMS_ENGINE_PRV_BAD_PIN;
1216 else
1217 ret = TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001218 goto err;
1219 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001220 }
1221
1222 /* handle a certificate and/or CA certificate */
1223 if (cert_id || ca_cert_id) {
1224 const char *cmd_name = "LOAD_CERT_CTRL";
1225
1226 /* test if the engine supports a LOAD_CERT_CTRL */
1227 if (!ENGINE_ctrl(conn->engine, ENGINE_CTRL_GET_CMD_FROM_NAME,
1228 0, (void *)cmd_name, NULL)) {
1229 wpa_printf(MSG_ERROR, "ENGINE: engine does not support"
1230 " loading certificates");
1231 ret = TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED;
1232 goto err;
1233 }
1234 }
1235
1236 return 0;
1237
1238err:
1239 if (conn->engine) {
1240 ENGINE_free(conn->engine);
1241 conn->engine = NULL;
1242 }
1243
1244 if (conn->private_key) {
1245 EVP_PKEY_free(conn->private_key);
1246 conn->private_key = NULL;
1247 }
1248
1249 return ret;
1250#else /* OPENSSL_NO_ENGINE */
1251 return 0;
1252#endif /* OPENSSL_NO_ENGINE */
1253}
1254
1255
1256static void tls_engine_deinit(struct tls_connection *conn)
1257{
Adam Langley1eb02ed2015-04-21 19:00:05 -07001258#if defined(ANDROID) || !defined(OPENSSL_NO_ENGINE)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001259 wpa_printf(MSG_DEBUG, "ENGINE: engine deinit");
1260 if (conn->private_key) {
1261 EVP_PKEY_free(conn->private_key);
1262 conn->private_key = NULL;
1263 }
1264 if (conn->engine) {
Adam Langley1eb02ed2015-04-21 19:00:05 -07001265#if !defined(OPENSSL_IS_BORINGSSL)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001266 ENGINE_finish(conn->engine);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001267#endif /* !OPENSSL_IS_BORINGSSL */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001268 conn->engine = NULL;
1269 }
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001270#endif /* ANDROID || !OPENSSL_NO_ENGINE */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001271}
1272
1273
1274int tls_get_errors(void *ssl_ctx)
1275{
1276 int count = 0;
1277 unsigned long err;
1278
1279 while ((err = ERR_get_error())) {
1280 wpa_printf(MSG_INFO, "TLS - SSL error: %s",
1281 ERR_error_string(err, NULL));
1282 count++;
1283 }
1284
1285 return count;
1286}
1287
Jouni Malinen26af48b2014-04-09 13:02:53 +03001288
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001289static const char * openssl_content_type(int content_type)
1290{
1291 switch (content_type) {
1292 case 20:
1293 return "change cipher spec";
1294 case 21:
1295 return "alert";
1296 case 22:
1297 return "handshake";
1298 case 23:
1299 return "application data";
1300 case 24:
1301 return "heartbeat";
1302 case 256:
1303 return "TLS header info"; /* pseudo content type */
1304 default:
1305 return "?";
1306 }
1307}
1308
1309
1310static const char * openssl_handshake_type(int content_type, const u8 *buf,
1311 size_t len)
1312{
1313 if (content_type != 22 || !buf || len == 0)
1314 return "";
1315 switch (buf[0]) {
1316 case 0:
1317 return "hello request";
1318 case 1:
1319 return "client hello";
1320 case 2:
1321 return "server hello";
1322 case 4:
1323 return "new session ticket";
1324 case 11:
1325 return "certificate";
1326 case 12:
1327 return "server key exchange";
1328 case 13:
1329 return "certificate request";
1330 case 14:
1331 return "server hello done";
1332 case 15:
1333 return "certificate verify";
1334 case 16:
1335 return "client key exchange";
1336 case 20:
1337 return "finished";
1338 case 21:
1339 return "certificate url";
1340 case 22:
1341 return "certificate status";
1342 default:
1343 return "?";
1344 }
1345}
1346
1347
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001348#ifdef CONFIG_SUITEB
1349
1350static void check_server_hello(struct tls_connection *conn,
1351 const u8 *pos, const u8 *end)
1352{
1353 size_t payload_len, id_len;
1354
1355 /*
1356 * Parse ServerHello to get the selected cipher suite since OpenSSL does
1357 * not make it cleanly available during handshake and we need to know
1358 * whether DHE was selected.
1359 */
1360
1361 if (end - pos < 3)
1362 return;
1363 payload_len = WPA_GET_BE24(pos);
1364 pos += 3;
1365
1366 if ((size_t) (end - pos) < payload_len)
1367 return;
1368 end = pos + payload_len;
1369
1370 /* Skip Version and Random */
1371 if (end - pos < 2 + SSL3_RANDOM_SIZE)
1372 return;
1373 pos += 2 + SSL3_RANDOM_SIZE;
1374
1375 /* Skip Session ID */
1376 if (end - pos < 1)
1377 return;
1378 id_len = *pos++;
1379 if ((size_t) (end - pos) < id_len)
1380 return;
1381 pos += id_len;
1382
1383 if (end - pos < 2)
1384 return;
1385 conn->cipher_suite = WPA_GET_BE16(pos);
1386 wpa_printf(MSG_DEBUG, "OpenSSL: Server selected cipher suite 0x%x",
1387 conn->cipher_suite);
1388}
1389
1390
1391static void check_server_key_exchange(SSL *ssl, struct tls_connection *conn,
1392 const u8 *pos, const u8 *end)
1393{
1394 size_t payload_len;
1395 u16 dh_len;
1396 BIGNUM *p;
1397 int bits;
1398
1399 if (!(conn->flags & TLS_CONN_SUITEB))
1400 return;
1401
1402 /* DHE is enabled only with DHE-RSA-AES256-GCM-SHA384 */
1403 if (conn->cipher_suite != 0x9f)
1404 return;
1405
1406 if (end - pos < 3)
1407 return;
1408 payload_len = WPA_GET_BE24(pos);
1409 pos += 3;
1410
1411 if ((size_t) (end - pos) < payload_len)
1412 return;
1413 end = pos + payload_len;
1414
1415 if (end - pos < 2)
1416 return;
1417 dh_len = WPA_GET_BE16(pos);
1418 pos += 2;
1419
1420 if ((size_t) (end - pos) < dh_len)
1421 return;
1422 p = BN_bin2bn(pos, dh_len, NULL);
1423 if (!p)
1424 return;
1425
1426 bits = BN_num_bits(p);
1427 BN_free(p);
1428
1429 conn->server_dh_prime_len = bits;
1430 wpa_printf(MSG_DEBUG, "OpenSSL: Server DH prime length: %d bits",
1431 conn->server_dh_prime_len);
1432}
1433
1434#endif /* CONFIG_SUITEB */
1435
1436
Jouni Malinen26af48b2014-04-09 13:02:53 +03001437static void tls_msg_cb(int write_p, int version, int content_type,
1438 const void *buf, size_t len, SSL *ssl, void *arg)
1439{
1440 struct tls_connection *conn = arg;
1441 const u8 *pos = buf;
1442
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001443 if (write_p == 2) {
1444 wpa_printf(MSG_DEBUG,
1445 "OpenSSL: session ver=0x%x content_type=%d",
1446 version, content_type);
1447 wpa_hexdump_key(MSG_MSGDUMP, "OpenSSL: Data", buf, len);
1448 return;
1449 }
1450
1451 wpa_printf(MSG_DEBUG, "OpenSSL: %s ver=0x%x content_type=%d (%s/%s)",
1452 write_p ? "TX" : "RX", version, content_type,
1453 openssl_content_type(content_type),
1454 openssl_handshake_type(content_type, buf, len));
Jouni Malinen26af48b2014-04-09 13:02:53 +03001455 wpa_hexdump_key(MSG_MSGDUMP, "OpenSSL: Message", buf, len);
1456 if (content_type == 24 && len >= 3 && pos[0] == 1) {
1457 size_t payload_len = WPA_GET_BE16(pos + 1);
1458 if (payload_len + 3 > len) {
1459 wpa_printf(MSG_ERROR, "OpenSSL: Heartbeat attack detected");
1460 conn->invalid_hb_used = 1;
1461 }
1462 }
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001463
1464#ifdef CONFIG_SUITEB
1465 /*
1466 * Need to parse these handshake messages to be able to check DH prime
1467 * length since OpenSSL does not expose the new cipher suite and DH
1468 * parameters during handshake (e.g., for cert_cb() callback).
1469 */
1470 if (content_type == 22 && pos && len > 0 && pos[0] == 2)
1471 check_server_hello(conn, pos + 1, pos + len);
1472 if (content_type == 22 && pos && len > 0 && pos[0] == 12)
1473 check_server_key_exchange(ssl, conn, pos + 1, pos + len);
1474#endif /* CONFIG_SUITEB */
Jouni Malinen26af48b2014-04-09 13:02:53 +03001475}
1476
1477
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001478struct tls_connection * tls_connection_init(void *ssl_ctx)
1479{
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001480 struct tls_data *data = ssl_ctx;
1481 SSL_CTX *ssl = data->ssl;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001482 struct tls_connection *conn;
1483 long options;
Dmitry Shmidt7d5c8f22014-03-03 13:53:28 -08001484 struct tls_context *context = SSL_CTX_get_app_data(ssl);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001485
1486 conn = os_zalloc(sizeof(*conn));
1487 if (conn == NULL)
1488 return NULL;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001489 conn->ssl_ctx = ssl;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001490 conn->ssl = SSL_new(ssl);
1491 if (conn->ssl == NULL) {
1492 tls_show_errors(MSG_INFO, __func__,
1493 "Failed to initialize new SSL connection");
1494 os_free(conn);
1495 return NULL;
1496 }
1497
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001498 conn->context = context;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001499 SSL_set_app_data(conn->ssl, conn);
Jouni Malinen26af48b2014-04-09 13:02:53 +03001500 SSL_set_msg_callback(conn->ssl, tls_msg_cb);
1501 SSL_set_msg_callback_arg(conn->ssl, conn);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001502 options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
1503 SSL_OP_SINGLE_DH_USE;
1504#ifdef SSL_OP_NO_COMPRESSION
1505 options |= SSL_OP_NO_COMPRESSION;
1506#endif /* SSL_OP_NO_COMPRESSION */
1507 SSL_set_options(conn->ssl, options);
1508
1509 conn->ssl_in = BIO_new(BIO_s_mem());
1510 if (!conn->ssl_in) {
1511 tls_show_errors(MSG_INFO, __func__,
1512 "Failed to create a new BIO for ssl_in");
1513 SSL_free(conn->ssl);
1514 os_free(conn);
1515 return NULL;
1516 }
1517
1518 conn->ssl_out = BIO_new(BIO_s_mem());
1519 if (!conn->ssl_out) {
1520 tls_show_errors(MSG_INFO, __func__,
1521 "Failed to create a new BIO for ssl_out");
1522 SSL_free(conn->ssl);
1523 BIO_free(conn->ssl_in);
1524 os_free(conn);
1525 return NULL;
1526 }
1527
1528 SSL_set_bio(conn->ssl, conn->ssl_in, conn->ssl_out);
1529
1530 return conn;
1531}
1532
1533
1534void tls_connection_deinit(void *ssl_ctx, struct tls_connection *conn)
1535{
1536 if (conn == NULL)
1537 return;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001538 if (conn->success_data) {
1539 /*
1540 * Make sure ssl_clear_bad_session() does not remove this
1541 * session.
1542 */
1543 SSL_set_quiet_shutdown(conn->ssl, 1);
1544 SSL_shutdown(conn->ssl);
1545 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001546 SSL_free(conn->ssl);
1547 tls_engine_deinit(conn);
1548 os_free(conn->subject_match);
1549 os_free(conn->altsubject_match);
Dmitry Shmidt051af732013-10-22 13:52:46 -07001550 os_free(conn->suffix_match);
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001551 os_free(conn->domain_match);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001552 os_free(conn->session_ticket);
1553 os_free(conn);
1554}
1555
1556
1557int tls_connection_established(void *ssl_ctx, struct tls_connection *conn)
1558{
1559 return conn ? SSL_is_init_finished(conn->ssl) : 0;
1560}
1561
1562
Hai Shalom39ba6fc2019-01-22 12:40:38 -08001563char * tls_connection_peer_serial_num(void *tls_ctx,
1564 struct tls_connection *conn)
1565{
1566 ASN1_INTEGER *ser;
1567 char *serial_num;
1568 size_t len;
1569
1570 if (!conn->peer_cert)
1571 return NULL;
1572
1573 ser = X509_get_serialNumber(conn->peer_cert);
1574 if (!ser)
1575 return NULL;
1576
1577 len = ASN1_STRING_length(ser) * 2 + 1;
1578 serial_num = os_malloc(len);
1579 if (!serial_num)
1580 return NULL;
1581 wpa_snprintf_hex_uppercase(serial_num, len,
1582 ASN1_STRING_get0_data(ser),
1583 ASN1_STRING_length(ser));
1584 return serial_num;
1585}
1586
1587
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001588int tls_connection_shutdown(void *ssl_ctx, struct tls_connection *conn)
1589{
1590 if (conn == NULL)
1591 return -1;
1592
1593 /* Shutdown previous TLS connection without notifying the peer
1594 * because the connection was already terminated in practice
1595 * and "close notify" shutdown alert would confuse AS. */
1596 SSL_set_quiet_shutdown(conn->ssl, 1);
1597 SSL_shutdown(conn->ssl);
Jouni Malinenf291c682015-08-17 22:50:41 +03001598 return SSL_clear(conn->ssl) == 1 ? 0 : -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001599}
1600
1601
1602static int tls_match_altsubject_component(X509 *cert, int type,
1603 const char *value, size_t len)
1604{
1605 GENERAL_NAME *gen;
1606 void *ext;
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -07001607 int found = 0;
1608 stack_index_t i;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001609
1610 ext = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
1611
1612 for (i = 0; ext && i < sk_GENERAL_NAME_num(ext); i++) {
1613 gen = sk_GENERAL_NAME_value(ext, i);
1614 if (gen->type != type)
1615 continue;
1616 if (os_strlen((char *) gen->d.ia5->data) == len &&
1617 os_memcmp(value, gen->d.ia5->data, len) == 0)
1618 found++;
1619 }
1620
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08001621 sk_GENERAL_NAME_pop_free(ext, GENERAL_NAME_free);
1622
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001623 return found;
1624}
1625
1626
1627static int tls_match_altsubject(X509 *cert, const char *match)
1628{
1629 int type;
1630 const char *pos, *end;
1631 size_t len;
1632
1633 pos = match;
1634 do {
1635 if (os_strncmp(pos, "EMAIL:", 6) == 0) {
1636 type = GEN_EMAIL;
1637 pos += 6;
1638 } else if (os_strncmp(pos, "DNS:", 4) == 0) {
1639 type = GEN_DNS;
1640 pos += 4;
1641 } else if (os_strncmp(pos, "URI:", 4) == 0) {
1642 type = GEN_URI;
1643 pos += 4;
1644 } else {
1645 wpa_printf(MSG_INFO, "TLS: Invalid altSubjectName "
1646 "match '%s'", pos);
1647 return 0;
1648 }
1649 end = os_strchr(pos, ';');
1650 while (end) {
1651 if (os_strncmp(end + 1, "EMAIL:", 6) == 0 ||
1652 os_strncmp(end + 1, "DNS:", 4) == 0 ||
1653 os_strncmp(end + 1, "URI:", 4) == 0)
1654 break;
1655 end = os_strchr(end + 1, ';');
1656 }
1657 if (end)
1658 len = end - pos;
1659 else
1660 len = os_strlen(pos);
1661 if (tls_match_altsubject_component(cert, type, pos, len) > 0)
1662 return 1;
1663 pos = end + 1;
1664 } while (end);
1665
1666 return 0;
1667}
1668
1669
Dmitry Shmidtfa3fc4a2013-11-21 13:34:38 -08001670#ifndef CONFIG_NATIVE_WINDOWS
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001671static int domain_suffix_match(const u8 *val, size_t len, const char *match,
1672 int full)
Dmitry Shmidt051af732013-10-22 13:52:46 -07001673{
1674 size_t i, match_len;
1675
1676 /* Check for embedded nuls that could mess up suffix matching */
1677 for (i = 0; i < len; i++) {
1678 if (val[i] == '\0') {
1679 wpa_printf(MSG_DEBUG, "TLS: Embedded null in a string - reject");
1680 return 0;
1681 }
1682 }
1683
1684 match_len = os_strlen(match);
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001685 if (match_len > len || (full && match_len != len))
Dmitry Shmidt051af732013-10-22 13:52:46 -07001686 return 0;
1687
1688 if (os_strncasecmp((const char *) val + len - match_len, match,
1689 match_len) != 0)
1690 return 0; /* no match */
1691
1692 if (match_len == len)
1693 return 1; /* exact match */
1694
1695 if (val[len - match_len - 1] == '.')
1696 return 1; /* full label match completes suffix match */
1697
1698 wpa_printf(MSG_DEBUG, "TLS: Reject due to incomplete label match");
1699 return 0;
1700}
Dmitry Shmidtfa3fc4a2013-11-21 13:34:38 -08001701#endif /* CONFIG_NATIVE_WINDOWS */
Dmitry Shmidt051af732013-10-22 13:52:46 -07001702
1703
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001704static int tls_match_suffix(X509 *cert, const char *match, int full)
Dmitry Shmidt051af732013-10-22 13:52:46 -07001705{
Dmitry Shmidtfa3fc4a2013-11-21 13:34:38 -08001706#ifdef CONFIG_NATIVE_WINDOWS
1707 /* wincrypt.h has conflicting X509_NAME definition */
1708 return -1;
1709#else /* CONFIG_NATIVE_WINDOWS */
Dmitry Shmidt051af732013-10-22 13:52:46 -07001710 GENERAL_NAME *gen;
1711 void *ext;
1712 int i;
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -07001713 stack_index_t j;
Dmitry Shmidt051af732013-10-22 13:52:46 -07001714 int dns_name = 0;
1715 X509_NAME *name;
1716
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001717 wpa_printf(MSG_DEBUG, "TLS: Match domain against %s%s",
1718 full ? "": "suffix ", match);
Dmitry Shmidt051af732013-10-22 13:52:46 -07001719
1720 ext = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
1721
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -07001722 for (j = 0; ext && j < sk_GENERAL_NAME_num(ext); j++) {
1723 gen = sk_GENERAL_NAME_value(ext, j);
Dmitry Shmidt051af732013-10-22 13:52:46 -07001724 if (gen->type != GEN_DNS)
1725 continue;
1726 dns_name++;
1727 wpa_hexdump_ascii(MSG_DEBUG, "TLS: Certificate dNSName",
1728 gen->d.dNSName->data,
1729 gen->d.dNSName->length);
1730 if (domain_suffix_match(gen->d.dNSName->data,
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001731 gen->d.dNSName->length, match, full) ==
1732 1) {
1733 wpa_printf(MSG_DEBUG, "TLS: %s in dNSName found",
1734 full ? "Match" : "Suffix match");
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08001735 sk_GENERAL_NAME_pop_free(ext, GENERAL_NAME_free);
Dmitry Shmidt051af732013-10-22 13:52:46 -07001736 return 1;
1737 }
1738 }
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08001739 sk_GENERAL_NAME_pop_free(ext, GENERAL_NAME_free);
Dmitry Shmidt051af732013-10-22 13:52:46 -07001740
1741 if (dns_name) {
1742 wpa_printf(MSG_DEBUG, "TLS: None of the dNSName(s) matched");
1743 return 0;
1744 }
1745
1746 name = X509_get_subject_name(cert);
1747 i = -1;
1748 for (;;) {
1749 X509_NAME_ENTRY *e;
1750 ASN1_STRING *cn;
1751
1752 i = X509_NAME_get_index_by_NID(name, NID_commonName, i);
1753 if (i == -1)
1754 break;
1755 e = X509_NAME_get_entry(name, i);
1756 if (e == NULL)
1757 continue;
1758 cn = X509_NAME_ENTRY_get_data(e);
1759 if (cn == NULL)
1760 continue;
1761 wpa_hexdump_ascii(MSG_DEBUG, "TLS: Certificate commonName",
1762 cn->data, cn->length);
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001763 if (domain_suffix_match(cn->data, cn->length, match, full) == 1)
1764 {
1765 wpa_printf(MSG_DEBUG, "TLS: %s in commonName found",
1766 full ? "Match" : "Suffix match");
Dmitry Shmidt051af732013-10-22 13:52:46 -07001767 return 1;
1768 }
1769 }
1770
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001771 wpa_printf(MSG_DEBUG, "TLS: No CommonName %smatch found",
1772 full ? "": "suffix ");
Dmitry Shmidt051af732013-10-22 13:52:46 -07001773 return 0;
Dmitry Shmidtfa3fc4a2013-11-21 13:34:38 -08001774#endif /* CONFIG_NATIVE_WINDOWS */
Dmitry Shmidt051af732013-10-22 13:52:46 -07001775}
1776
1777
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001778static enum tls_fail_reason openssl_tls_fail_reason(int err)
1779{
1780 switch (err) {
1781 case X509_V_ERR_CERT_REVOKED:
1782 return TLS_FAIL_REVOKED;
1783 case X509_V_ERR_CERT_NOT_YET_VALID:
1784 case X509_V_ERR_CRL_NOT_YET_VALID:
1785 return TLS_FAIL_NOT_YET_VALID;
1786 case X509_V_ERR_CERT_HAS_EXPIRED:
1787 case X509_V_ERR_CRL_HAS_EXPIRED:
1788 return TLS_FAIL_EXPIRED;
1789 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
1790 case X509_V_ERR_UNABLE_TO_GET_CRL:
1791 case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
1792 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
1793 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
1794 case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
1795 case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
1796 case X509_V_ERR_CERT_CHAIN_TOO_LONG:
1797 case X509_V_ERR_PATH_LENGTH_EXCEEDED:
1798 case X509_V_ERR_INVALID_CA:
1799 return TLS_FAIL_UNTRUSTED;
1800 case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
1801 case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
1802 case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
1803 case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
1804 case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
1805 case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
1806 case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
1807 case X509_V_ERR_CERT_UNTRUSTED:
1808 case X509_V_ERR_CERT_REJECTED:
1809 return TLS_FAIL_BAD_CERTIFICATE;
1810 default:
1811 return TLS_FAIL_UNSPECIFIED;
1812 }
1813}
1814
1815
1816static struct wpabuf * get_x509_cert(X509 *cert)
1817{
1818 struct wpabuf *buf;
1819 u8 *tmp;
1820
1821 int cert_len = i2d_X509(cert, NULL);
1822 if (cert_len <= 0)
1823 return NULL;
1824
1825 buf = wpabuf_alloc(cert_len);
1826 if (buf == NULL)
1827 return NULL;
1828
1829 tmp = wpabuf_put(buf, cert_len);
1830 i2d_X509(cert, &tmp);
1831 return buf;
1832}
1833
1834
1835static void openssl_tls_fail_event(struct tls_connection *conn,
1836 X509 *err_cert, int err, int depth,
1837 const char *subject, const char *err_str,
1838 enum tls_fail_reason reason)
1839{
1840 union tls_event_data ev;
1841 struct wpabuf *cert = NULL;
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001842 struct tls_context *context = conn->context;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001843
Pavel Grafov4d8552e2018-02-06 11:28:29 +00001844#ifdef ANDROID
1845 log_cert_validation_failure(err_str);
1846#endif
1847
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001848 if (context->event_cb == NULL)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001849 return;
1850
1851 cert = get_x509_cert(err_cert);
1852 os_memset(&ev, 0, sizeof(ev));
1853 ev.cert_fail.reason = reason != TLS_FAIL_UNSPECIFIED ?
1854 reason : openssl_tls_fail_reason(err);
1855 ev.cert_fail.depth = depth;
1856 ev.cert_fail.subject = subject;
1857 ev.cert_fail.reason_txt = err_str;
1858 ev.cert_fail.cert = cert;
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001859 context->event_cb(context->cb_ctx, TLS_CERT_CHAIN_FAILURE, &ev);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001860 wpabuf_free(cert);
1861}
1862
1863
1864static void openssl_tls_cert_event(struct tls_connection *conn,
1865 X509 *err_cert, int depth,
1866 const char *subject)
1867{
1868 struct wpabuf *cert = NULL;
1869 union tls_event_data ev;
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001870 struct tls_context *context = conn->context;
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001871 char *altsubject[TLS_MAX_ALT_SUBJECT];
1872 int alt, num_altsubject = 0;
1873 GENERAL_NAME *gen;
1874 void *ext;
1875 stack_index_t i;
Hai Shalom39ba6fc2019-01-22 12:40:38 -08001876 ASN1_INTEGER *ser;
1877 char serial_num[128];
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001878#ifdef CONFIG_SHA256
1879 u8 hash[32];
1880#endif /* CONFIG_SHA256 */
1881
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001882 if (context->event_cb == NULL)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001883 return;
1884
1885 os_memset(&ev, 0, sizeof(ev));
Dmitry Shmidt55840ad2015-12-14 12:45:46 -08001886 if (conn->cert_probe || (conn->flags & TLS_CONN_EXT_CERT_CHECK) ||
1887 context->cert_in_cb) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001888 cert = get_x509_cert(err_cert);
1889 ev.peer_cert.cert = cert;
1890 }
1891#ifdef CONFIG_SHA256
1892 if (cert) {
1893 const u8 *addr[1];
1894 size_t len[1];
1895 addr[0] = wpabuf_head(cert);
1896 len[0] = wpabuf_len(cert);
1897 if (sha256_vector(1, addr, len, hash) == 0) {
1898 ev.peer_cert.hash = hash;
1899 ev.peer_cert.hash_len = sizeof(hash);
1900 }
1901 }
1902#endif /* CONFIG_SHA256 */
1903 ev.peer_cert.depth = depth;
1904 ev.peer_cert.subject = subject;
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001905
Hai Shalom39ba6fc2019-01-22 12:40:38 -08001906 ser = X509_get_serialNumber(err_cert);
1907 if (ser) {
1908 wpa_snprintf_hex_uppercase(serial_num, sizeof(serial_num),
1909 ASN1_STRING_get0_data(ser),
1910 ASN1_STRING_length(ser));
1911 ev.peer_cert.serial_num = serial_num;
1912 }
1913
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001914 ext = X509_get_ext_d2i(err_cert, NID_subject_alt_name, NULL, NULL);
1915 for (i = 0; ext && i < sk_GENERAL_NAME_num(ext); i++) {
1916 char *pos;
1917
1918 if (num_altsubject == TLS_MAX_ALT_SUBJECT)
1919 break;
1920 gen = sk_GENERAL_NAME_value(ext, i);
1921 if (gen->type != GEN_EMAIL &&
1922 gen->type != GEN_DNS &&
1923 gen->type != GEN_URI)
1924 continue;
1925
1926 pos = os_malloc(10 + gen->d.ia5->length + 1);
1927 if (pos == NULL)
1928 break;
1929 altsubject[num_altsubject++] = pos;
1930
1931 switch (gen->type) {
1932 case GEN_EMAIL:
1933 os_memcpy(pos, "EMAIL:", 6);
1934 pos += 6;
1935 break;
1936 case GEN_DNS:
1937 os_memcpy(pos, "DNS:", 4);
1938 pos += 4;
1939 break;
1940 case GEN_URI:
1941 os_memcpy(pos, "URI:", 4);
1942 pos += 4;
1943 break;
1944 }
1945
1946 os_memcpy(pos, gen->d.ia5->data, gen->d.ia5->length);
1947 pos += gen->d.ia5->length;
1948 *pos = '\0';
1949 }
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08001950 sk_GENERAL_NAME_pop_free(ext, GENERAL_NAME_free);
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001951
1952 for (alt = 0; alt < num_altsubject; alt++)
1953 ev.peer_cert.altsubject[alt] = altsubject[alt];
1954 ev.peer_cert.num_altsubject = num_altsubject;
1955
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001956 context->event_cb(context->cb_ctx, TLS_PEER_CERTIFICATE, &ev);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001957 wpabuf_free(cert);
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001958 for (alt = 0; alt < num_altsubject; alt++)
1959 os_free(altsubject[alt]);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001960}
1961
1962
1963static int tls_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx)
1964{
1965 char buf[256];
1966 X509 *err_cert;
1967 int err, depth;
1968 SSL *ssl;
1969 struct tls_connection *conn;
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001970 struct tls_context *context;
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001971 char *match, *altmatch, *suffix_match, *domain_match;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001972 const char *err_str;
1973
1974 err_cert = X509_STORE_CTX_get_current_cert(x509_ctx);
Dmitry Shmidt96be6222014-02-13 10:16:51 -08001975 if (!err_cert)
1976 return 0;
1977
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001978 err = X509_STORE_CTX_get_error(x509_ctx);
1979 depth = X509_STORE_CTX_get_error_depth(x509_ctx);
1980 ssl = X509_STORE_CTX_get_ex_data(x509_ctx,
1981 SSL_get_ex_data_X509_STORE_CTX_idx());
1982 X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof(buf));
1983
1984 conn = SSL_get_app_data(ssl);
1985 if (conn == NULL)
1986 return 0;
Dmitry Shmidt34af3062013-07-11 10:46:32 -07001987
1988 if (depth == 0)
1989 conn->peer_cert = err_cert;
1990 else if (depth == 1)
1991 conn->peer_issuer = err_cert;
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08001992 else if (depth == 2)
1993 conn->peer_issuer_issuer = err_cert;
Dmitry Shmidt34af3062013-07-11 10:46:32 -07001994
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001995 context = conn->context;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001996 match = conn->subject_match;
1997 altmatch = conn->altsubject_match;
Dmitry Shmidt051af732013-10-22 13:52:46 -07001998 suffix_match = conn->suffix_match;
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001999 domain_match = conn->domain_match;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002000
2001 if (!preverify_ok && !conn->ca_cert_verify)
2002 preverify_ok = 1;
2003 if (!preverify_ok && depth > 0 && conn->server_cert_only)
2004 preverify_ok = 1;
Dmitry Shmidtc55524a2011-07-07 11:18:38 -07002005 if (!preverify_ok && (conn->flags & TLS_CONN_DISABLE_TIME_CHECKS) &&
2006 (err == X509_V_ERR_CERT_HAS_EXPIRED ||
2007 err == X509_V_ERR_CERT_NOT_YET_VALID)) {
2008 wpa_printf(MSG_DEBUG, "OpenSSL: Ignore certificate validity "
2009 "time mismatch");
2010 preverify_ok = 1;
2011 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002012
2013 err_str = X509_verify_cert_error_string(err);
2014
2015#ifdef CONFIG_SHA256
Dmitry Shmidt4dd28dc2015-03-10 11:21:43 -07002016 /*
2017 * Do not require preverify_ok so we can explicity allow otherwise
2018 * invalid pinned server certificates.
2019 */
2020 if (depth == 0 && conn->server_cert_only) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002021 struct wpabuf *cert;
2022 cert = get_x509_cert(err_cert);
2023 if (!cert) {
2024 wpa_printf(MSG_DEBUG, "OpenSSL: Could not fetch "
2025 "server certificate data");
2026 preverify_ok = 0;
2027 } else {
2028 u8 hash[32];
2029 const u8 *addr[1];
2030 size_t len[1];
2031 addr[0] = wpabuf_head(cert);
2032 len[0] = wpabuf_len(cert);
2033 if (sha256_vector(1, addr, len, hash) < 0 ||
2034 os_memcmp(conn->srv_cert_hash, hash, 32) != 0) {
2035 err_str = "Server certificate mismatch";
2036 err = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
2037 preverify_ok = 0;
Dmitry Shmidt4dd28dc2015-03-10 11:21:43 -07002038 } else if (!preverify_ok) {
2039 /*
2040 * Certificate matches pinned certificate, allow
2041 * regardless of other problems.
2042 */
2043 wpa_printf(MSG_DEBUG,
2044 "OpenSSL: Ignore validation issues for a pinned server certificate");
2045 preverify_ok = 1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002046 }
2047 wpabuf_free(cert);
2048 }
2049 }
2050#endif /* CONFIG_SHA256 */
2051
2052 if (!preverify_ok) {
2053 wpa_printf(MSG_WARNING, "TLS: Certificate verification failed,"
2054 " error %d (%s) depth %d for '%s'", err, err_str,
2055 depth, buf);
2056 openssl_tls_fail_event(conn, err_cert, err, depth, buf,
2057 err_str, TLS_FAIL_UNSPECIFIED);
2058 return preverify_ok;
2059 }
2060
2061 wpa_printf(MSG_DEBUG, "TLS: tls_verify_cb - preverify_ok=%d "
2062 "err=%d (%s) ca_cert_verify=%d depth=%d buf='%s'",
2063 preverify_ok, err, err_str,
2064 conn->ca_cert_verify, depth, buf);
2065 if (depth == 0 && match && os_strstr(buf, match) == NULL) {
2066 wpa_printf(MSG_WARNING, "TLS: Subject '%s' did not "
2067 "match with '%s'", buf, match);
2068 preverify_ok = 0;
2069 openssl_tls_fail_event(conn, err_cert, err, depth, buf,
2070 "Subject mismatch",
2071 TLS_FAIL_SUBJECT_MISMATCH);
2072 } else if (depth == 0 && altmatch &&
2073 !tls_match_altsubject(err_cert, altmatch)) {
2074 wpa_printf(MSG_WARNING, "TLS: altSubjectName match "
2075 "'%s' not found", altmatch);
2076 preverify_ok = 0;
2077 openssl_tls_fail_event(conn, err_cert, err, depth, buf,
2078 "AltSubject mismatch",
2079 TLS_FAIL_ALTSUBJECT_MISMATCH);
Dmitry Shmidt051af732013-10-22 13:52:46 -07002080 } else if (depth == 0 && suffix_match &&
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08002081 !tls_match_suffix(err_cert, suffix_match, 0)) {
Dmitry Shmidt051af732013-10-22 13:52:46 -07002082 wpa_printf(MSG_WARNING, "TLS: Domain suffix match '%s' not found",
2083 suffix_match);
2084 preverify_ok = 0;
2085 openssl_tls_fail_event(conn, err_cert, err, depth, buf,
2086 "Domain suffix mismatch",
2087 TLS_FAIL_DOMAIN_SUFFIX_MISMATCH);
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08002088 } else if (depth == 0 && domain_match &&
2089 !tls_match_suffix(err_cert, domain_match, 1)) {
2090 wpa_printf(MSG_WARNING, "TLS: Domain match '%s' not found",
2091 domain_match);
2092 preverify_ok = 0;
2093 openssl_tls_fail_event(conn, err_cert, err, depth, buf,
2094 "Domain mismatch",
2095 TLS_FAIL_DOMAIN_MISMATCH);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002096 } else
2097 openssl_tls_cert_event(conn, err_cert, depth, buf);
2098
2099 if (conn->cert_probe && preverify_ok && depth == 0) {
2100 wpa_printf(MSG_DEBUG, "OpenSSL: Reject server certificate "
2101 "on probe-only run");
2102 preverify_ok = 0;
2103 openssl_tls_fail_event(conn, err_cert, err, depth, buf,
2104 "Server certificate chain probe",
2105 TLS_FAIL_SERVER_CHAIN_PROBE);
2106 }
2107
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002108#ifdef CONFIG_SUITEB
2109 if (conn->flags & TLS_CONN_SUITEB) {
2110 EVP_PKEY *pk;
2111 RSA *rsa;
2112 int len = -1;
2113
2114 pk = X509_get_pubkey(err_cert);
2115 if (pk) {
2116 rsa = EVP_PKEY_get1_RSA(pk);
2117 if (rsa) {
2118 len = RSA_bits(rsa);
2119 RSA_free(rsa);
2120 }
2121 EVP_PKEY_free(pk);
2122 }
2123
2124 if (len >= 0) {
2125 wpa_printf(MSG_DEBUG,
2126 "OpenSSL: RSA modulus size: %d bits", len);
2127 if (len < 3072) {
2128 preverify_ok = 0;
2129 openssl_tls_fail_event(
2130 conn, err_cert, err,
2131 depth, buf,
2132 "Insufficient RSA modulus size",
2133 TLS_FAIL_INSUFFICIENT_KEY_LEN);
2134 }
2135 }
2136 }
2137#endif /* CONFIG_SUITEB */
2138
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002139#ifdef OPENSSL_IS_BORINGSSL
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08002140 if (depth == 0 && (conn->flags & TLS_CONN_REQUEST_OCSP) &&
2141 preverify_ok) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002142 enum ocsp_result res;
2143
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08002144 res = check_ocsp_resp(conn->ssl_ctx, conn->ssl, err_cert,
2145 conn->peer_issuer,
2146 conn->peer_issuer_issuer);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002147 if (res == OCSP_REVOKED) {
2148 preverify_ok = 0;
2149 openssl_tls_fail_event(conn, err_cert, err, depth, buf,
2150 "certificate revoked",
2151 TLS_FAIL_REVOKED);
2152 if (err == X509_V_OK)
2153 X509_STORE_CTX_set_error(
2154 x509_ctx, X509_V_ERR_CERT_REVOKED);
2155 } else if (res != OCSP_GOOD &&
2156 (conn->flags & TLS_CONN_REQUIRE_OCSP)) {
2157 preverify_ok = 0;
2158 openssl_tls_fail_event(conn, err_cert, err, depth, buf,
2159 "bad certificate status response",
2160 TLS_FAIL_UNSPECIFIED);
2161 }
2162 }
2163#endif /* OPENSSL_IS_BORINGSSL */
2164
Dmitry Shmidt55840ad2015-12-14 12:45:46 -08002165 if (depth == 0 && preverify_ok && context->event_cb != NULL)
Dmitry Shmidtea69e842013-05-13 14:52:28 -07002166 context->event_cb(context->cb_ctx,
2167 TLS_CERT_CHAIN_SUCCESS, NULL);
Dmitry Shmidt04949592012-07-19 12:16:46 -07002168
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002169 return preverify_ok;
2170}
2171
2172
2173#ifndef OPENSSL_NO_STDIO
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002174static int tls_load_ca_der(struct tls_data *data, const char *ca_cert)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002175{
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002176 SSL_CTX *ssl_ctx = data->ssl;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002177 X509_LOOKUP *lookup;
2178 int ret = 0;
2179
Dmitry Shmidt216983b2015-02-06 10:50:36 -08002180 lookup = X509_STORE_add_lookup(SSL_CTX_get_cert_store(ssl_ctx),
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002181 X509_LOOKUP_file());
2182 if (lookup == NULL) {
2183 tls_show_errors(MSG_WARNING, __func__,
2184 "Failed add lookup for X509 store");
2185 return -1;
2186 }
2187
2188 if (!X509_LOOKUP_load_file(lookup, ca_cert, X509_FILETYPE_ASN1)) {
2189 unsigned long err = ERR_peek_error();
2190 tls_show_errors(MSG_WARNING, __func__,
2191 "Failed load CA in DER format");
2192 if (ERR_GET_LIB(err) == ERR_LIB_X509 &&
2193 ERR_GET_REASON(err) == X509_R_CERT_ALREADY_IN_HASH_TABLE) {
2194 wpa_printf(MSG_DEBUG, "OpenSSL: %s - ignoring "
2195 "cert already in hash table error",
2196 __func__);
2197 } else
2198 ret = -1;
2199 }
2200
2201 return ret;
2202}
2203#endif /* OPENSSL_NO_STDIO */
2204
2205
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002206static int tls_connection_ca_cert(struct tls_data *data,
2207 struct tls_connection *conn,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002208 const char *ca_cert, const u8 *ca_cert_blob,
2209 size_t ca_cert_blob_len, const char *ca_path)
2210{
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002211 SSL_CTX *ssl_ctx = data->ssl;
Dmitry Shmidt216983b2015-02-06 10:50:36 -08002212 X509_STORE *store;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002213
2214 /*
2215 * Remove previously configured trusted CA certificates before adding
2216 * new ones.
2217 */
Dmitry Shmidt216983b2015-02-06 10:50:36 -08002218 store = X509_STORE_new();
2219 if (store == NULL) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002220 wpa_printf(MSG_DEBUG, "OpenSSL: %s - failed to allocate new "
2221 "certificate store", __func__);
2222 return -1;
2223 }
Dmitry Shmidt216983b2015-02-06 10:50:36 -08002224 SSL_CTX_set_cert_store(ssl_ctx, store);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002225
2226 SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb);
2227 conn->ca_cert_verify = 1;
2228
2229 if (ca_cert && os_strncmp(ca_cert, "probe://", 8) == 0) {
2230 wpa_printf(MSG_DEBUG, "OpenSSL: Probe for server certificate "
2231 "chain");
2232 conn->cert_probe = 1;
2233 conn->ca_cert_verify = 0;
2234 return 0;
2235 }
2236
2237 if (ca_cert && os_strncmp(ca_cert, "hash://", 7) == 0) {
2238#ifdef CONFIG_SHA256
2239 const char *pos = ca_cert + 7;
2240 if (os_strncmp(pos, "server/sha256/", 14) != 0) {
2241 wpa_printf(MSG_DEBUG, "OpenSSL: Unsupported ca_cert "
2242 "hash value '%s'", ca_cert);
2243 return -1;
2244 }
2245 pos += 14;
2246 if (os_strlen(pos) != 32 * 2) {
2247 wpa_printf(MSG_DEBUG, "OpenSSL: Unexpected SHA256 "
2248 "hash length in ca_cert '%s'", ca_cert);
2249 return -1;
2250 }
2251 if (hexstr2bin(pos, conn->srv_cert_hash, 32) < 0) {
2252 wpa_printf(MSG_DEBUG, "OpenSSL: Invalid SHA256 hash "
2253 "value in ca_cert '%s'", ca_cert);
2254 return -1;
2255 }
2256 conn->server_cert_only = 1;
2257 wpa_printf(MSG_DEBUG, "OpenSSL: Checking only server "
2258 "certificate match");
2259 return 0;
2260#else /* CONFIG_SHA256 */
2261 wpa_printf(MSG_INFO, "No SHA256 included in the build - "
2262 "cannot validate server certificate hash");
2263 return -1;
2264#endif /* CONFIG_SHA256 */
2265 }
2266
2267 if (ca_cert_blob) {
Dmitry Shmidt216983b2015-02-06 10:50:36 -08002268 X509 *cert = d2i_X509(NULL,
2269 (const unsigned char **) &ca_cert_blob,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002270 ca_cert_blob_len);
2271 if (cert == NULL) {
2272 tls_show_errors(MSG_WARNING, __func__,
2273 "Failed to parse ca_cert_blob");
2274 return -1;
2275 }
2276
Dmitry Shmidt216983b2015-02-06 10:50:36 -08002277 if (!X509_STORE_add_cert(SSL_CTX_get_cert_store(ssl_ctx),
2278 cert)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002279 unsigned long err = ERR_peek_error();
2280 tls_show_errors(MSG_WARNING, __func__,
2281 "Failed to add ca_cert_blob to "
2282 "certificate store");
2283 if (ERR_GET_LIB(err) == ERR_LIB_X509 &&
2284 ERR_GET_REASON(err) ==
2285 X509_R_CERT_ALREADY_IN_HASH_TABLE) {
2286 wpa_printf(MSG_DEBUG, "OpenSSL: %s - ignoring "
2287 "cert already in hash table error",
2288 __func__);
2289 } else {
2290 X509_free(cert);
2291 return -1;
2292 }
2293 }
2294 X509_free(cert);
2295 wpa_printf(MSG_DEBUG, "OpenSSL: %s - added ca_cert_blob "
2296 "to certificate store", __func__);
2297 return 0;
2298 }
2299
2300#ifdef ANDROID
Dmitry Shmidtb97e4282016-02-08 10:16:07 -08002301 /* Single alias */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002302 if (ca_cert && os_strncmp("keystore://", ca_cert, 11) == 0) {
Dmitry Shmidt849734c2016-05-27 09:59:01 -07002303 if (tls_add_ca_from_keystore(SSL_CTX_get_cert_store(ssl_ctx),
Dmitry Shmidtb97e4282016-02-08 10:16:07 -08002304 &ca_cert[11]) < 0)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002305 return -1;
Dmitry Shmidtb97e4282016-02-08 10:16:07 -08002306 SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb);
2307 return 0;
2308 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002309
Dmitry Shmidtb97e4282016-02-08 10:16:07 -08002310 /* Multiple aliases separated by space */
2311 if (ca_cert && os_strncmp("keystores://", ca_cert, 12) == 0) {
2312 char *aliases = os_strdup(&ca_cert[12]);
2313 const char *delim = " ";
2314 int rc = 0;
2315 char *savedptr;
2316 char *alias;
2317
2318 if (!aliases)
2319 return -1;
2320 alias = strtok_r(aliases, delim, &savedptr);
2321 for (; alias; alias = strtok_r(NULL, delim, &savedptr)) {
2322 if (tls_add_ca_from_keystore_encoded(
Dmitry Shmidt849734c2016-05-27 09:59:01 -07002323 SSL_CTX_get_cert_store(ssl_ctx), alias)) {
Dmitry Shmidtb97e4282016-02-08 10:16:07 -08002324 wpa_printf(MSG_WARNING,
2325 "OpenSSL: %s - Failed to add ca_cert %s from keystore",
2326 __func__, alias);
2327 rc = -1;
2328 break;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002329 }
2330 }
Dmitry Shmidtb97e4282016-02-08 10:16:07 -08002331 os_free(aliases);
2332 if (rc)
2333 return rc;
2334
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002335 SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb);
2336 return 0;
2337 }
2338#endif /* ANDROID */
2339
2340#ifdef CONFIG_NATIVE_WINDOWS
2341 if (ca_cert && tls_cryptoapi_ca_cert(ssl_ctx, conn->ssl, ca_cert) ==
2342 0) {
2343 wpa_printf(MSG_DEBUG, "OpenSSL: Added CA certificates from "
2344 "system certificate store");
2345 return 0;
2346 }
2347#endif /* CONFIG_NATIVE_WINDOWS */
2348
2349 if (ca_cert || ca_path) {
2350#ifndef OPENSSL_NO_STDIO
2351 if (SSL_CTX_load_verify_locations(ssl_ctx, ca_cert, ca_path) !=
2352 1) {
2353 tls_show_errors(MSG_WARNING, __func__,
2354 "Failed to load root certificates");
2355 if (ca_cert &&
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002356 tls_load_ca_der(data, ca_cert) == 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002357 wpa_printf(MSG_DEBUG, "OpenSSL: %s - loaded "
2358 "DER format CA certificate",
2359 __func__);
2360 } else
2361 return -1;
2362 } else {
2363 wpa_printf(MSG_DEBUG, "TLS: Trusted root "
2364 "certificate(s) loaded");
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002365 tls_get_errors(data);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002366 }
2367#else /* OPENSSL_NO_STDIO */
2368 wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO",
2369 __func__);
2370 return -1;
2371#endif /* OPENSSL_NO_STDIO */
2372 } else {
2373 /* No ca_cert configured - do not try to verify server
2374 * certificate */
2375 conn->ca_cert_verify = 0;
2376 }
2377
2378 return 0;
2379}
2380
2381
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002382static int tls_global_ca_cert(struct tls_data *data, const char *ca_cert)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002383{
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002384 SSL_CTX *ssl_ctx = data->ssl;
2385
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002386 if (ca_cert) {
2387 if (SSL_CTX_load_verify_locations(ssl_ctx, ca_cert, NULL) != 1)
2388 {
2389 tls_show_errors(MSG_WARNING, __func__,
2390 "Failed to load root certificates");
2391 return -1;
2392 }
2393
2394 wpa_printf(MSG_DEBUG, "TLS: Trusted root "
2395 "certificate(s) loaded");
2396
2397#ifndef OPENSSL_NO_STDIO
2398 /* Add the same CAs to the client certificate requests */
2399 SSL_CTX_set_client_CA_list(ssl_ctx,
2400 SSL_load_client_CA_file(ca_cert));
2401#endif /* OPENSSL_NO_STDIO */
2402 }
2403
2404 return 0;
2405}
2406
2407
2408int tls_global_set_verify(void *ssl_ctx, int check_crl)
2409{
2410 int flags;
2411
2412 if (check_crl) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002413 struct tls_data *data = ssl_ctx;
2414 X509_STORE *cs = SSL_CTX_get_cert_store(data->ssl);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002415 if (cs == NULL) {
2416 tls_show_errors(MSG_INFO, __func__, "Failed to get "
2417 "certificate store when enabling "
2418 "check_crl");
2419 return -1;
2420 }
2421 flags = X509_V_FLAG_CRL_CHECK;
2422 if (check_crl == 2)
2423 flags |= X509_V_FLAG_CRL_CHECK_ALL;
2424 X509_STORE_set_flags(cs, flags);
2425 }
2426 return 0;
2427}
2428
2429
2430static int tls_connection_set_subject_match(struct tls_connection *conn,
2431 const char *subject_match,
Dmitry Shmidt051af732013-10-22 13:52:46 -07002432 const char *altsubject_match,
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08002433 const char *suffix_match,
2434 const char *domain_match)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002435{
2436 os_free(conn->subject_match);
2437 conn->subject_match = NULL;
2438 if (subject_match) {
2439 conn->subject_match = os_strdup(subject_match);
2440 if (conn->subject_match == NULL)
2441 return -1;
2442 }
2443
2444 os_free(conn->altsubject_match);
2445 conn->altsubject_match = NULL;
2446 if (altsubject_match) {
2447 conn->altsubject_match = os_strdup(altsubject_match);
2448 if (conn->altsubject_match == NULL)
2449 return -1;
2450 }
2451
Dmitry Shmidt051af732013-10-22 13:52:46 -07002452 os_free(conn->suffix_match);
2453 conn->suffix_match = NULL;
2454 if (suffix_match) {
2455 conn->suffix_match = os_strdup(suffix_match);
2456 if (conn->suffix_match == NULL)
2457 return -1;
2458 }
2459
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08002460 os_free(conn->domain_match);
2461 conn->domain_match = NULL;
2462 if (domain_match) {
2463 conn->domain_match = os_strdup(domain_match);
2464 if (conn->domain_match == NULL)
2465 return -1;
2466 }
2467
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002468 return 0;
2469}
2470
2471
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002472#ifdef CONFIG_SUITEB
2473#if OPENSSL_VERSION_NUMBER >= 0x10002000L
2474static int suiteb_cert_cb(SSL *ssl, void *arg)
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002475{
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002476 struct tls_connection *conn = arg;
2477
2478 /*
2479 * This cert_cb() is not really the best location for doing a
2480 * constraint check for the ServerKeyExchange message, but this seems to
2481 * be the only place where the current OpenSSL sequence can be
2482 * terminated cleanly with an TLS alert going out to the server.
2483 */
2484
2485 if (!(conn->flags & TLS_CONN_SUITEB))
2486 return 1;
2487
2488 /* DHE is enabled only with DHE-RSA-AES256-GCM-SHA384 */
2489 if (conn->cipher_suite != 0x9f)
2490 return 1;
2491
2492 if (conn->server_dh_prime_len >= 3072)
2493 return 1;
2494
2495 wpa_printf(MSG_DEBUG,
2496 "OpenSSL: Server DH prime length (%d bits) not sufficient for Suite B RSA - reject handshake",
2497 conn->server_dh_prime_len);
2498 return 0;
2499}
2500#endif /* OPENSSL_VERSION_NUMBER */
2501#endif /* CONFIG_SUITEB */
2502
2503
Roshan Pius3a1667e2018-07-03 15:17:14 -07002504static int tls_set_conn_flags(struct tls_connection *conn, unsigned int flags,
2505 const char *openssl_ciphers)
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002506{
2507 SSL *ssl = conn->ssl;
2508
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002509#ifdef SSL_OP_NO_TICKET
2510 if (flags & TLS_CONN_DISABLE_SESSION_TICKET)
2511 SSL_set_options(ssl, SSL_OP_NO_TICKET);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002512 else
2513 SSL_clear_options(ssl, SSL_OP_NO_TICKET);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002514#endif /* SSL_OP_NO_TICKET */
2515
2516#ifdef SSL_OP_NO_TLSv1
2517 if (flags & TLS_CONN_DISABLE_TLSv1_0)
2518 SSL_set_options(ssl, SSL_OP_NO_TLSv1);
2519 else
2520 SSL_clear_options(ssl, SSL_OP_NO_TLSv1);
2521#endif /* SSL_OP_NO_TLSv1 */
2522#ifdef SSL_OP_NO_TLSv1_1
2523 if (flags & TLS_CONN_DISABLE_TLSv1_1)
2524 SSL_set_options(ssl, SSL_OP_NO_TLSv1_1);
2525 else
2526 SSL_clear_options(ssl, SSL_OP_NO_TLSv1_1);
2527#endif /* SSL_OP_NO_TLSv1_1 */
2528#ifdef SSL_OP_NO_TLSv1_2
2529 if (flags & TLS_CONN_DISABLE_TLSv1_2)
2530 SSL_set_options(ssl, SSL_OP_NO_TLSv1_2);
2531 else
2532 SSL_clear_options(ssl, SSL_OP_NO_TLSv1_2);
2533#endif /* SSL_OP_NO_TLSv1_2 */
Roshan Pius3a1667e2018-07-03 15:17:14 -07002534#ifdef SSL_OP_NO_TLSv1_3
2535 if (flags & TLS_CONN_DISABLE_TLSv1_3)
2536 SSL_set_options(ssl, SSL_OP_NO_TLSv1_3);
2537 else
2538 SSL_clear_options(ssl, SSL_OP_NO_TLSv1_3);
2539#endif /* SSL_OP_NO_TLSv1_3 */
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002540#ifdef CONFIG_SUITEB
Roshan Pius3a1667e2018-07-03 15:17:14 -07002541#ifdef OPENSSL_IS_BORINGSSL
2542 /* Start with defaults from BoringSSL */
2543 SSL_CTX_set_verify_algorithm_prefs(conn->ssl_ctx, NULL, 0);
2544#endif /* OPENSSL_IS_BORINGSSL */
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002545#if OPENSSL_VERSION_NUMBER >= 0x10002000L
2546 if (flags & TLS_CONN_SUITEB_NO_ECDH) {
2547 const char *ciphers = "DHE-RSA-AES256-GCM-SHA384";
2548
Roshan Pius3a1667e2018-07-03 15:17:14 -07002549 if (openssl_ciphers) {
2550 wpa_printf(MSG_DEBUG,
2551 "OpenSSL: Override ciphers for Suite B (no ECDH): %s",
2552 openssl_ciphers);
2553 ciphers = openssl_ciphers;
2554 }
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002555 if (SSL_set_cipher_list(ssl, ciphers) != 1) {
2556 wpa_printf(MSG_INFO,
2557 "OpenSSL: Failed to set Suite B ciphers");
2558 return -1;
2559 }
2560 } else if (flags & TLS_CONN_SUITEB) {
2561 EC_KEY *ecdh;
2562 const char *ciphers =
2563 "ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384";
Roshan Pius3a1667e2018-07-03 15:17:14 -07002564 int nid[1] = { NID_secp384r1 };
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002565
Roshan Pius3a1667e2018-07-03 15:17:14 -07002566 if (openssl_ciphers) {
2567 wpa_printf(MSG_DEBUG,
2568 "OpenSSL: Override ciphers for Suite B: %s",
2569 openssl_ciphers);
2570 ciphers = openssl_ciphers;
2571 }
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002572 if (SSL_set_cipher_list(ssl, ciphers) != 1) {
2573 wpa_printf(MSG_INFO,
2574 "OpenSSL: Failed to set Suite B ciphers");
2575 return -1;
2576 }
2577
Roshan Pius3a1667e2018-07-03 15:17:14 -07002578 if (SSL_set1_curves(ssl, nid, 1) != 1) {
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002579 wpa_printf(MSG_INFO,
2580 "OpenSSL: Failed to set Suite B curves");
2581 return -1;
2582 }
2583
2584 ecdh = EC_KEY_new_by_curve_name(NID_secp384r1);
2585 if (!ecdh || SSL_set_tmp_ecdh(ssl, ecdh) != 1) {
2586 EC_KEY_free(ecdh);
2587 wpa_printf(MSG_INFO,
2588 "OpenSSL: Failed to set ECDH parameter");
2589 return -1;
2590 }
2591 EC_KEY_free(ecdh);
2592 }
2593 if (flags & (TLS_CONN_SUITEB | TLS_CONN_SUITEB_NO_ECDH)) {
Roshan Pius3a1667e2018-07-03 15:17:14 -07002594#ifdef OPENSSL_IS_BORINGSSL
2595 uint16_t sigalgs[1] = { SSL_SIGN_RSA_PKCS1_SHA384 };
2596
2597 if (SSL_CTX_set_verify_algorithm_prefs(conn->ssl_ctx, sigalgs,
2598 1) != 1) {
2599 wpa_printf(MSG_INFO,
2600 "OpenSSL: Failed to set Suite B sigalgs");
2601 return -1;
2602 }
2603#else /* OPENSSL_IS_BORINGSSL */
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002604 /* ECDSA+SHA384 if need to add EC support here */
2605 if (SSL_set1_sigalgs_list(ssl, "RSA+SHA384") != 1) {
2606 wpa_printf(MSG_INFO,
2607 "OpenSSL: Failed to set Suite B sigalgs");
2608 return -1;
2609 }
Roshan Pius3a1667e2018-07-03 15:17:14 -07002610#endif /* OPENSSL_IS_BORINGSSL */
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002611
2612 SSL_set_options(ssl, SSL_OP_NO_TLSv1);
2613 SSL_set_options(ssl, SSL_OP_NO_TLSv1_1);
2614 SSL_set_cert_cb(ssl, suiteb_cert_cb, conn);
2615 }
2616#else /* OPENSSL_VERSION_NUMBER < 0x10002000L */
2617 if (flags & (TLS_CONN_SUITEB | TLS_CONN_SUITEB_NO_ECDH)) {
2618 wpa_printf(MSG_ERROR,
2619 "OpenSSL: Suite B RSA case not supported with this OpenSSL version");
2620 return -1;
2621 }
2622#endif /* OPENSSL_VERSION_NUMBER */
Roshan Pius3a1667e2018-07-03 15:17:14 -07002623
2624#ifdef OPENSSL_IS_BORINGSSL
2625 if (openssl_ciphers && os_strcmp(openssl_ciphers, "SUITEB192") == 0) {
2626 uint16_t sigalgs[1] = { SSL_SIGN_ECDSA_SECP384R1_SHA384 };
2627 int nid[1] = { NID_secp384r1 };
2628
2629 if (SSL_set1_curves(ssl, nid, 1) != 1) {
2630 wpa_printf(MSG_INFO,
2631 "OpenSSL: Failed to set Suite B curves");
2632 return -1;
2633 }
2634
2635 if (SSL_CTX_set_verify_algorithm_prefs(conn->ssl_ctx, sigalgs,
2636 1) != 1) {
2637 wpa_printf(MSG_INFO,
2638 "OpenSSL: Failed to set Suite B sigalgs");
2639 return -1;
2640 }
2641 }
2642#endif /* OPENSSL_IS_BORINGSSL */
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002643#endif /* CONFIG_SUITEB */
2644
2645 return 0;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002646}
2647
2648
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002649int tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn,
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002650 int verify_peer, unsigned int flags,
2651 const u8 *session_ctx, size_t session_ctx_len)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002652{
2653 static int counter = 0;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002654 struct tls_data *data = ssl_ctx;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002655
2656 if (conn == NULL)
2657 return -1;
2658
2659 if (verify_peer) {
2660 conn->ca_cert_verify = 1;
2661 SSL_set_verify(conn->ssl, SSL_VERIFY_PEER |
2662 SSL_VERIFY_FAIL_IF_NO_PEER_CERT |
2663 SSL_VERIFY_CLIENT_ONCE, tls_verify_cb);
2664 } else {
2665 conn->ca_cert_verify = 0;
2666 SSL_set_verify(conn->ssl, SSL_VERIFY_NONE, NULL);
2667 }
2668
Roshan Pius3a1667e2018-07-03 15:17:14 -07002669 if (tls_set_conn_flags(conn, flags, NULL) < 0)
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002670 return -1;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002671 conn->flags = flags;
2672
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002673 SSL_set_accept_state(conn->ssl);
2674
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002675 if (data->tls_session_lifetime == 0) {
2676 /*
2677 * Set session id context to a unique value to make sure
2678 * session resumption cannot be used either through session
2679 * caching or TLS ticket extension.
2680 */
2681 counter++;
2682 SSL_set_session_id_context(conn->ssl,
2683 (const unsigned char *) &counter,
2684 sizeof(counter));
2685 } else if (session_ctx) {
2686 SSL_set_session_id_context(conn->ssl, session_ctx,
2687 session_ctx_len);
2688 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002689
2690 return 0;
2691}
2692
2693
2694static int tls_connection_client_cert(struct tls_connection *conn,
2695 const char *client_cert,
2696 const u8 *client_cert_blob,
2697 size_t client_cert_blob_len)
2698{
2699 if (client_cert == NULL && client_cert_blob == NULL)
2700 return 0;
2701
Dmitry Shmidtde47be72016-01-07 12:52:55 -08002702#ifdef PKCS12_FUNCS
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002703#if OPENSSL_VERSION_NUMBER < 0x10002000L || defined(LIBRESSL_VERSION_NUMBER)
Dmitry Shmidtde47be72016-01-07 12:52:55 -08002704 /*
2705 * Clear previously set extra chain certificates, if any, from PKCS#12
2706 * processing in tls_parse_pkcs12() to allow OpenSSL to build a new
2707 * chain properly.
2708 */
2709 SSL_CTX_clear_extra_chain_certs(conn->ssl_ctx);
2710#endif /* OPENSSL_VERSION_NUMBER < 0x10002000L */
2711#endif /* PKCS12_FUNCS */
2712
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002713 if (client_cert_blob &&
2714 SSL_use_certificate_ASN1(conn->ssl, (u8 *) client_cert_blob,
2715 client_cert_blob_len) == 1) {
2716 wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_ASN1 --> "
2717 "OK");
2718 return 0;
2719 } else if (client_cert_blob) {
2720 tls_show_errors(MSG_DEBUG, __func__,
2721 "SSL_use_certificate_ASN1 failed");
2722 }
2723
2724 if (client_cert == NULL)
2725 return -1;
2726
2727#ifdef ANDROID
2728 if (os_strncmp("keystore://", client_cert, 11) == 0) {
2729 BIO *bio = BIO_from_keystore(&client_cert[11]);
2730 X509 *x509 = NULL;
2731 int ret = -1;
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002732 if (bio) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002733 x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002734 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002735 if (x509) {
2736 if (SSL_use_certificate(conn->ssl, x509) == 1)
2737 ret = 0;
2738 X509_free(x509);
2739 }
Paul Stewart50772e82017-01-25 13:59:16 -08002740
2741 /* Read additional certificates into the chain. */
2742 while (bio) {
2743 x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
2744 if (x509) {
2745 /* Takes ownership of x509 */
2746 SSL_add0_chain_cert(conn->ssl, x509);
2747 } else {
2748 BIO_free(bio);
2749 bio = NULL;
2750 }
2751 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002752 return ret;
2753 }
2754#endif /* ANDROID */
2755
2756#ifndef OPENSSL_NO_STDIO
2757 if (SSL_use_certificate_file(conn->ssl, client_cert,
2758 SSL_FILETYPE_ASN1) == 1) {
2759 wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_file (DER)"
2760 " --> OK");
2761 return 0;
2762 }
2763
2764 if (SSL_use_certificate_file(conn->ssl, client_cert,
2765 SSL_FILETYPE_PEM) == 1) {
2766 ERR_clear_error();
2767 wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_file (PEM)"
2768 " --> OK");
2769 return 0;
2770 }
2771
2772 tls_show_errors(MSG_DEBUG, __func__,
2773 "SSL_use_certificate_file failed");
2774#else /* OPENSSL_NO_STDIO */
2775 wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", __func__);
2776#endif /* OPENSSL_NO_STDIO */
2777
2778 return -1;
2779}
2780
2781
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002782static int tls_global_client_cert(struct tls_data *data,
2783 const char *client_cert)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002784{
2785#ifndef OPENSSL_NO_STDIO
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002786 SSL_CTX *ssl_ctx = data->ssl;
2787
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002788 if (client_cert == NULL)
2789 return 0;
2790
2791 if (SSL_CTX_use_certificate_file(ssl_ctx, client_cert,
2792 SSL_FILETYPE_ASN1) != 1 &&
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002793 SSL_CTX_use_certificate_chain_file(ssl_ctx, client_cert) != 1 &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002794 SSL_CTX_use_certificate_file(ssl_ctx, client_cert,
2795 SSL_FILETYPE_PEM) != 1) {
2796 tls_show_errors(MSG_INFO, __func__,
2797 "Failed to load client certificate");
2798 return -1;
2799 }
2800 return 0;
2801#else /* OPENSSL_NO_STDIO */
2802 if (client_cert == NULL)
2803 return 0;
2804 wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", __func__);
2805 return -1;
2806#endif /* OPENSSL_NO_STDIO */
2807}
2808
2809
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002810#ifdef PKCS12_FUNCS
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002811static int tls_parse_pkcs12(struct tls_data *data, SSL *ssl, PKCS12 *p12,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002812 const char *passwd)
2813{
2814 EVP_PKEY *pkey;
2815 X509 *cert;
2816 STACK_OF(X509) *certs;
2817 int res = 0;
2818 char buf[256];
2819
2820 pkey = NULL;
2821 cert = NULL;
2822 certs = NULL;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002823 if (!passwd)
2824 passwd = "";
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002825 if (!PKCS12_parse(p12, passwd, &pkey, &cert, &certs)) {
2826 tls_show_errors(MSG_DEBUG, __func__,
2827 "Failed to parse PKCS12 file");
2828 PKCS12_free(p12);
2829 return -1;
2830 }
2831 wpa_printf(MSG_DEBUG, "TLS: Successfully parsed PKCS12 data");
2832
2833 if (cert) {
2834 X509_NAME_oneline(X509_get_subject_name(cert), buf,
2835 sizeof(buf));
2836 wpa_printf(MSG_DEBUG, "TLS: Got certificate from PKCS12: "
2837 "subject='%s'", buf);
2838 if (ssl) {
2839 if (SSL_use_certificate(ssl, cert) != 1)
2840 res = -1;
2841 } else {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002842 if (SSL_CTX_use_certificate(data->ssl, cert) != 1)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002843 res = -1;
2844 }
2845 X509_free(cert);
2846 }
2847
2848 if (pkey) {
2849 wpa_printf(MSG_DEBUG, "TLS: Got private key from PKCS12");
2850 if (ssl) {
2851 if (SSL_use_PrivateKey(ssl, pkey) != 1)
2852 res = -1;
2853 } else {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002854 if (SSL_CTX_use_PrivateKey(data->ssl, pkey) != 1)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002855 res = -1;
2856 }
2857 EVP_PKEY_free(pkey);
2858 }
2859
2860 if (certs) {
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08002861#if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(LIBRESSL_VERSION_NUMBER)
Dmitry Shmidtb97e4282016-02-08 10:16:07 -08002862 if (ssl)
2863 SSL_clear_chain_certs(ssl);
2864 else
2865 SSL_CTX_clear_chain_certs(data->ssl);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002866 while ((cert = sk_X509_pop(certs)) != NULL) {
2867 X509_NAME_oneline(X509_get_subject_name(cert), buf,
2868 sizeof(buf));
2869 wpa_printf(MSG_DEBUG, "TLS: additional certificate"
2870 " from PKCS12: subject='%s'", buf);
Dmitry Shmidtb97e4282016-02-08 10:16:07 -08002871 if ((ssl && SSL_add1_chain_cert(ssl, cert) != 1) ||
2872 (!ssl && SSL_CTX_add1_chain_cert(data->ssl,
2873 cert) != 1)) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002874 tls_show_errors(MSG_DEBUG, __func__,
2875 "Failed to add additional certificate");
2876 res = -1;
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08002877 X509_free(cert);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002878 break;
2879 }
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08002880 X509_free(cert);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002881 }
2882 if (!res) {
2883 /* Try to continue anyway */
2884 }
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08002885 sk_X509_pop_free(certs, X509_free);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002886#ifndef OPENSSL_IS_BORINGSSL
Dmitry Shmidtb97e4282016-02-08 10:16:07 -08002887 if (ssl)
2888 res = SSL_build_cert_chain(
2889 ssl,
2890 SSL_BUILD_CHAIN_FLAG_CHECK |
2891 SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR);
2892 else
2893 res = SSL_CTX_build_cert_chain(
2894 data->ssl,
2895 SSL_BUILD_CHAIN_FLAG_CHECK |
2896 SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002897 if (!res) {
2898 tls_show_errors(MSG_DEBUG, __func__,
2899 "Failed to build certificate chain");
2900 } else if (res == 2) {
2901 wpa_printf(MSG_DEBUG,
2902 "TLS: Ignore certificate chain verification error when building chain with PKCS#12 extra certificates");
2903 }
2904#endif /* OPENSSL_IS_BORINGSSL */
2905 /*
2906 * Try to continue regardless of result since it is possible for
2907 * the extra certificates not to be required.
2908 */
2909 res = 0;
2910#else /* OPENSSL_VERSION_NUMBER >= 0x10002000L */
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002911 SSL_CTX_clear_extra_chain_certs(data->ssl);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002912 while ((cert = sk_X509_pop(certs)) != NULL) {
2913 X509_NAME_oneline(X509_get_subject_name(cert), buf,
2914 sizeof(buf));
2915 wpa_printf(MSG_DEBUG, "TLS: additional certificate"
2916 " from PKCS12: subject='%s'", buf);
2917 /*
2918 * There is no SSL equivalent for the chain cert - so
2919 * always add it to the context...
2920 */
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002921 if (SSL_CTX_add_extra_chain_cert(data->ssl, cert) != 1)
2922 {
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08002923 X509_free(cert);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002924 res = -1;
2925 break;
2926 }
2927 }
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08002928 sk_X509_pop_free(certs, X509_free);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002929#endif /* OPENSSL_VERSION_NUMBER >= 0x10002000L */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002930 }
2931
2932 PKCS12_free(p12);
2933
2934 if (res < 0)
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002935 tls_get_errors(data);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002936
2937 return res;
2938}
2939#endif /* PKCS12_FUNCS */
2940
2941
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002942static int tls_read_pkcs12(struct tls_data *data, SSL *ssl,
2943 const char *private_key, const char *passwd)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002944{
2945#ifdef PKCS12_FUNCS
2946 FILE *f;
2947 PKCS12 *p12;
2948
2949 f = fopen(private_key, "rb");
2950 if (f == NULL)
2951 return -1;
2952
2953 p12 = d2i_PKCS12_fp(f, NULL);
2954 fclose(f);
2955
2956 if (p12 == NULL) {
2957 tls_show_errors(MSG_INFO, __func__,
2958 "Failed to use PKCS#12 file");
2959 return -1;
2960 }
2961
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002962 return tls_parse_pkcs12(data, ssl, p12, passwd);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002963
2964#else /* PKCS12_FUNCS */
2965 wpa_printf(MSG_INFO, "TLS: PKCS12 support disabled - cannot read "
2966 "p12/pfx files");
2967 return -1;
2968#endif /* PKCS12_FUNCS */
2969}
2970
2971
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002972static int tls_read_pkcs12_blob(struct tls_data *data, SSL *ssl,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002973 const u8 *blob, size_t len, const char *passwd)
2974{
2975#ifdef PKCS12_FUNCS
2976 PKCS12 *p12;
2977
Dmitry Shmidt216983b2015-02-06 10:50:36 -08002978 p12 = d2i_PKCS12(NULL, (const unsigned char **) &blob, len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002979 if (p12 == NULL) {
2980 tls_show_errors(MSG_INFO, __func__,
2981 "Failed to use PKCS#12 blob");
2982 return -1;
2983 }
2984
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002985 return tls_parse_pkcs12(data, ssl, p12, passwd);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002986
2987#else /* PKCS12_FUNCS */
2988 wpa_printf(MSG_INFO, "TLS: PKCS12 support disabled - cannot parse "
2989 "p12/pfx blobs");
2990 return -1;
2991#endif /* PKCS12_FUNCS */
2992}
2993
2994
2995#ifndef OPENSSL_NO_ENGINE
2996static int tls_engine_get_cert(struct tls_connection *conn,
2997 const char *cert_id,
2998 X509 **cert)
2999{
3000 /* this runs after the private key is loaded so no PIN is required */
3001 struct {
3002 const char *cert_id;
3003 X509 *cert;
3004 } params;
3005 params.cert_id = cert_id;
3006 params.cert = NULL;
3007
3008 if (!ENGINE_ctrl_cmd(conn->engine, "LOAD_CERT_CTRL",
3009 0, &params, NULL, 1)) {
Dmitry Shmidt1d755d02015-04-28 10:34:29 -07003010 unsigned long err = ERR_get_error();
3011
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003012 wpa_printf(MSG_ERROR, "ENGINE: cannot load client cert with id"
3013 " '%s' [%s]", cert_id,
Dmitry Shmidt1d755d02015-04-28 10:34:29 -07003014 ERR_error_string(err, NULL));
3015 if (tls_is_pin_error(err))
3016 return TLS_SET_PARAMS_ENGINE_PRV_BAD_PIN;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003017 return TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED;
3018 }
3019 if (!params.cert) {
3020 wpa_printf(MSG_ERROR, "ENGINE: did not properly cert with id"
3021 " '%s'", cert_id);
3022 return TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED;
3023 }
3024 *cert = params.cert;
3025 return 0;
3026}
3027#endif /* OPENSSL_NO_ENGINE */
3028
3029
3030static int tls_connection_engine_client_cert(struct tls_connection *conn,
3031 const char *cert_id)
3032{
3033#ifndef OPENSSL_NO_ENGINE
3034 X509 *cert;
3035
3036 if (tls_engine_get_cert(conn, cert_id, &cert))
3037 return -1;
3038
3039 if (!SSL_use_certificate(conn->ssl, cert)) {
3040 tls_show_errors(MSG_ERROR, __func__,
3041 "SSL_use_certificate failed");
3042 X509_free(cert);
3043 return -1;
3044 }
3045 X509_free(cert);
3046 wpa_printf(MSG_DEBUG, "ENGINE: SSL_use_certificate --> "
3047 "OK");
3048 return 0;
3049
3050#else /* OPENSSL_NO_ENGINE */
3051 return -1;
3052#endif /* OPENSSL_NO_ENGINE */
3053}
3054
3055
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003056static int tls_connection_engine_ca_cert(struct tls_data *data,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003057 struct tls_connection *conn,
3058 const char *ca_cert_id)
3059{
3060#ifndef OPENSSL_NO_ENGINE
3061 X509 *cert;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003062 SSL_CTX *ssl_ctx = data->ssl;
Dmitry Shmidt216983b2015-02-06 10:50:36 -08003063 X509_STORE *store;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003064
3065 if (tls_engine_get_cert(conn, ca_cert_id, &cert))
3066 return -1;
3067
3068 /* start off the same as tls_connection_ca_cert */
Dmitry Shmidt216983b2015-02-06 10:50:36 -08003069 store = X509_STORE_new();
3070 if (store == NULL) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003071 wpa_printf(MSG_DEBUG, "OpenSSL: %s - failed to allocate new "
3072 "certificate store", __func__);
3073 X509_free(cert);
3074 return -1;
3075 }
Dmitry Shmidt216983b2015-02-06 10:50:36 -08003076 SSL_CTX_set_cert_store(ssl_ctx, store);
3077 if (!X509_STORE_add_cert(store, cert)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003078 unsigned long err = ERR_peek_error();
3079 tls_show_errors(MSG_WARNING, __func__,
3080 "Failed to add CA certificate from engine "
3081 "to certificate store");
3082 if (ERR_GET_LIB(err) == ERR_LIB_X509 &&
3083 ERR_GET_REASON(err) == X509_R_CERT_ALREADY_IN_HASH_TABLE) {
3084 wpa_printf(MSG_DEBUG, "OpenSSL: %s - ignoring cert"
3085 " already in hash table error",
3086 __func__);
3087 } else {
3088 X509_free(cert);
3089 return -1;
3090 }
3091 }
3092 X509_free(cert);
3093 wpa_printf(MSG_DEBUG, "OpenSSL: %s - added CA certificate from engine "
3094 "to certificate store", __func__);
3095 SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003096 conn->ca_cert_verify = 1;
3097
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003098 return 0;
3099
3100#else /* OPENSSL_NO_ENGINE */
3101 return -1;
3102#endif /* OPENSSL_NO_ENGINE */
3103}
3104
3105
3106static int tls_connection_engine_private_key(struct tls_connection *conn)
3107{
Adam Langley1eb02ed2015-04-21 19:00:05 -07003108#if defined(ANDROID) || !defined(OPENSSL_NO_ENGINE)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003109 if (SSL_use_PrivateKey(conn->ssl, conn->private_key) != 1) {
3110 tls_show_errors(MSG_ERROR, __func__,
3111 "ENGINE: cannot use private key for TLS");
3112 return -1;
3113 }
3114 if (!SSL_check_private_key(conn->ssl)) {
3115 tls_show_errors(MSG_INFO, __func__,
3116 "Private key failed verification");
3117 return -1;
3118 }
3119 return 0;
3120#else /* OPENSSL_NO_ENGINE */
3121 wpa_printf(MSG_ERROR, "SSL: Configuration uses engine, but "
3122 "engine support was not compiled in");
3123 return -1;
3124#endif /* OPENSSL_NO_ENGINE */
3125}
3126
3127
Roshan Pius3a1667e2018-07-03 15:17:14 -07003128#ifndef OPENSSL_NO_STDIO
3129static int tls_passwd_cb(char *buf, int size, int rwflag, void *password)
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07003130{
Roshan Pius3a1667e2018-07-03 15:17:14 -07003131 if (!password)
3132 return 0;
3133 os_strlcpy(buf, (const char *) password, size);
3134 return os_strlen(buf);
3135}
3136#endif /* OPENSSL_NO_STDIO */
3137
3138
3139static int tls_use_private_key_file(struct tls_data *data, SSL *ssl,
3140 const char *private_key,
3141 const char *private_key_passwd)
3142{
3143#ifndef OPENSSL_NO_STDIO
3144 BIO *bio;
3145 EVP_PKEY *pkey;
3146 int ret;
3147
3148 /* First try ASN.1 (DER). */
3149 bio = BIO_new_file(private_key, "r");
3150 if (!bio)
3151 return -1;
3152 pkey = d2i_PrivateKey_bio(bio, NULL);
3153 BIO_free(bio);
3154
3155 if (pkey) {
3156 wpa_printf(MSG_DEBUG, "OpenSSL: %s (DER) --> loaded", __func__);
3157 } else {
3158 /* Try PEM with the provided password. */
3159 bio = BIO_new_file(private_key, "r");
3160 if (!bio)
3161 return -1;
3162 pkey = PEM_read_bio_PrivateKey(bio, NULL, tls_passwd_cb,
3163 (void *) private_key_passwd);
3164 BIO_free(bio);
3165 if (!pkey)
3166 return -1;
3167 wpa_printf(MSG_DEBUG, "OpenSSL: %s (PEM) --> loaded", __func__);
3168 /* Clear errors from the previous failed load. */
3169 ERR_clear_error();
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07003170 }
Roshan Pius3a1667e2018-07-03 15:17:14 -07003171
3172 if (ssl)
3173 ret = SSL_use_PrivateKey(ssl, pkey);
3174 else
3175 ret = SSL_CTX_use_PrivateKey(data->ssl, pkey);
3176
3177 EVP_PKEY_free(pkey);
3178 return ret == 1 ? 0 : -1;
3179#else /* OPENSSL_NO_STDIO */
3180 wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", __func__);
3181 return -1;
3182#endif /* OPENSSL_NO_STDIO */
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07003183}
3184
3185
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003186static int tls_connection_private_key(struct tls_data *data,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003187 struct tls_connection *conn,
3188 const char *private_key,
3189 const char *private_key_passwd,
3190 const u8 *private_key_blob,
3191 size_t private_key_blob_len)
3192{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003193 int ok;
3194
3195 if (private_key == NULL && private_key_blob == NULL)
3196 return 0;
3197
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003198 ok = 0;
3199 while (private_key_blob) {
3200 if (SSL_use_PrivateKey_ASN1(EVP_PKEY_RSA, conn->ssl,
3201 (u8 *) private_key_blob,
3202 private_key_blob_len) == 1) {
3203 wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_PrivateKey_"
3204 "ASN1(EVP_PKEY_RSA) --> OK");
3205 ok = 1;
3206 break;
3207 }
3208
3209 if (SSL_use_PrivateKey_ASN1(EVP_PKEY_DSA, conn->ssl,
3210 (u8 *) private_key_blob,
3211 private_key_blob_len) == 1) {
3212 wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_PrivateKey_"
3213 "ASN1(EVP_PKEY_DSA) --> OK");
3214 ok = 1;
3215 break;
3216 }
3217
3218 if (SSL_use_RSAPrivateKey_ASN1(conn->ssl,
3219 (u8 *) private_key_blob,
3220 private_key_blob_len) == 1) {
3221 wpa_printf(MSG_DEBUG, "OpenSSL: "
3222 "SSL_use_RSAPrivateKey_ASN1 --> OK");
3223 ok = 1;
3224 break;
3225 }
3226
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003227 if (tls_read_pkcs12_blob(data, conn->ssl, private_key_blob,
Roshan Pius3a1667e2018-07-03 15:17:14 -07003228 private_key_blob_len,
3229 private_key_passwd) == 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003230 wpa_printf(MSG_DEBUG, "OpenSSL: PKCS#12 as blob --> "
3231 "OK");
3232 ok = 1;
3233 break;
3234 }
3235
3236 break;
3237 }
3238
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003239 while (!ok && private_key) {
Roshan Pius3a1667e2018-07-03 15:17:14 -07003240 if (tls_use_private_key_file(data, conn->ssl, private_key,
3241 private_key_passwd) == 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003242 ok = 1;
3243 break;
3244 }
3245
Roshan Pius3a1667e2018-07-03 15:17:14 -07003246 if (tls_read_pkcs12(data, conn->ssl, private_key,
3247 private_key_passwd) == 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003248 wpa_printf(MSG_DEBUG, "OpenSSL: Reading PKCS#12 file "
3249 "--> OK");
3250 ok = 1;
3251 break;
3252 }
3253
3254 if (tls_cryptoapi_cert(conn->ssl, private_key) == 0) {
3255 wpa_printf(MSG_DEBUG, "OpenSSL: Using CryptoAPI to "
3256 "access certificate store --> OK");
3257 ok = 1;
3258 break;
3259 }
3260
3261 break;
3262 }
3263
3264 if (!ok) {
3265 tls_show_errors(MSG_INFO, __func__,
3266 "Failed to load private key");
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003267 return -1;
3268 }
3269 ERR_clear_error();
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003270
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003271 if (!SSL_check_private_key(conn->ssl)) {
3272 tls_show_errors(MSG_INFO, __func__, "Private key failed "
3273 "verification");
3274 return -1;
3275 }
3276
3277 wpa_printf(MSG_DEBUG, "SSL: Private key loaded successfully");
3278 return 0;
3279}
3280
3281
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003282static int tls_global_private_key(struct tls_data *data,
3283 const char *private_key,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003284 const char *private_key_passwd)
3285{
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003286 SSL_CTX *ssl_ctx = data->ssl;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003287
3288 if (private_key == NULL)
3289 return 0;
3290
Roshan Pius3a1667e2018-07-03 15:17:14 -07003291 if (tls_use_private_key_file(data, NULL, private_key,
3292 private_key_passwd) &&
3293 tls_read_pkcs12(data, NULL, private_key, private_key_passwd)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003294 tls_show_errors(MSG_INFO, __func__,
3295 "Failed to load private key");
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003296 ERR_clear_error();
3297 return -1;
3298 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003299 ERR_clear_error();
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003300
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003301 if (!SSL_CTX_check_private_key(ssl_ctx)) {
3302 tls_show_errors(MSG_INFO, __func__,
3303 "Private key failed verification");
3304 return -1;
3305 }
3306
3307 return 0;
3308}
3309
3310
3311static int tls_connection_dh(struct tls_connection *conn, const char *dh_file)
3312{
3313#ifdef OPENSSL_NO_DH
3314 if (dh_file == NULL)
3315 return 0;
3316 wpa_printf(MSG_ERROR, "TLS: openssl does not include DH support, but "
3317 "dh_file specified");
3318 return -1;
3319#else /* OPENSSL_NO_DH */
3320 DH *dh;
3321 BIO *bio;
3322
3323 /* TODO: add support for dh_blob */
3324 if (dh_file == NULL)
3325 return 0;
3326 if (conn == NULL)
3327 return -1;
3328
3329 bio = BIO_new_file(dh_file, "r");
3330 if (bio == NULL) {
3331 wpa_printf(MSG_INFO, "TLS: Failed to open DH file '%s': %s",
3332 dh_file, ERR_error_string(ERR_get_error(), NULL));
3333 return -1;
3334 }
3335 dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
3336 BIO_free(bio);
3337#ifndef OPENSSL_NO_DSA
3338 while (dh == NULL) {
3339 DSA *dsa;
3340 wpa_printf(MSG_DEBUG, "TLS: Failed to parse DH file '%s': %s -"
3341 " trying to parse as DSA params", dh_file,
3342 ERR_error_string(ERR_get_error(), NULL));
3343 bio = BIO_new_file(dh_file, "r");
3344 if (bio == NULL)
3345 break;
3346 dsa = PEM_read_bio_DSAparams(bio, NULL, NULL, NULL);
3347 BIO_free(bio);
3348 if (!dsa) {
3349 wpa_printf(MSG_DEBUG, "TLS: Failed to parse DSA file "
3350 "'%s': %s", dh_file,
3351 ERR_error_string(ERR_get_error(), NULL));
3352 break;
3353 }
3354
3355 wpa_printf(MSG_DEBUG, "TLS: DH file in DSA param format");
3356 dh = DSA_dup_DH(dsa);
3357 DSA_free(dsa);
3358 if (dh == NULL) {
3359 wpa_printf(MSG_INFO, "TLS: Failed to convert DSA "
3360 "params into DH params");
3361 break;
3362 }
3363 break;
3364 }
3365#endif /* !OPENSSL_NO_DSA */
3366 if (dh == NULL) {
3367 wpa_printf(MSG_INFO, "TLS: Failed to read/parse DH/DSA file "
3368 "'%s'", dh_file);
3369 return -1;
3370 }
3371
3372 if (SSL_set_tmp_dh(conn->ssl, dh) != 1) {
3373 wpa_printf(MSG_INFO, "TLS: Failed to set DH params from '%s': "
3374 "%s", dh_file,
3375 ERR_error_string(ERR_get_error(), NULL));
3376 DH_free(dh);
3377 return -1;
3378 }
3379 DH_free(dh);
3380 return 0;
3381#endif /* OPENSSL_NO_DH */
3382}
3383
3384
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003385static int tls_global_dh(struct tls_data *data, const char *dh_file)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003386{
3387#ifdef OPENSSL_NO_DH
3388 if (dh_file == NULL)
3389 return 0;
3390 wpa_printf(MSG_ERROR, "TLS: openssl does not include DH support, but "
3391 "dh_file specified");
3392 return -1;
3393#else /* OPENSSL_NO_DH */
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003394 SSL_CTX *ssl_ctx = data->ssl;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003395 DH *dh;
3396 BIO *bio;
3397
3398 /* TODO: add support for dh_blob */
3399 if (dh_file == NULL)
3400 return 0;
3401 if (ssl_ctx == NULL)
3402 return -1;
3403
3404 bio = BIO_new_file(dh_file, "r");
3405 if (bio == NULL) {
3406 wpa_printf(MSG_INFO, "TLS: Failed to open DH file '%s': %s",
3407 dh_file, ERR_error_string(ERR_get_error(), NULL));
3408 return -1;
3409 }
3410 dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
3411 BIO_free(bio);
3412#ifndef OPENSSL_NO_DSA
3413 while (dh == NULL) {
3414 DSA *dsa;
3415 wpa_printf(MSG_DEBUG, "TLS: Failed to parse DH file '%s': %s -"
3416 " trying to parse as DSA params", dh_file,
3417 ERR_error_string(ERR_get_error(), NULL));
3418 bio = BIO_new_file(dh_file, "r");
3419 if (bio == NULL)
3420 break;
3421 dsa = PEM_read_bio_DSAparams(bio, NULL, NULL, NULL);
3422 BIO_free(bio);
3423 if (!dsa) {
3424 wpa_printf(MSG_DEBUG, "TLS: Failed to parse DSA file "
3425 "'%s': %s", dh_file,
3426 ERR_error_string(ERR_get_error(), NULL));
3427 break;
3428 }
3429
3430 wpa_printf(MSG_DEBUG, "TLS: DH file in DSA param format");
3431 dh = DSA_dup_DH(dsa);
3432 DSA_free(dsa);
3433 if (dh == NULL) {
3434 wpa_printf(MSG_INFO, "TLS: Failed to convert DSA "
3435 "params into DH params");
3436 break;
3437 }
3438 break;
3439 }
3440#endif /* !OPENSSL_NO_DSA */
3441 if (dh == NULL) {
3442 wpa_printf(MSG_INFO, "TLS: Failed to read/parse DH/DSA file "
3443 "'%s'", dh_file);
3444 return -1;
3445 }
3446
3447 if (SSL_CTX_set_tmp_dh(ssl_ctx, dh) != 1) {
3448 wpa_printf(MSG_INFO, "TLS: Failed to set DH params from '%s': "
3449 "%s", dh_file,
3450 ERR_error_string(ERR_get_error(), NULL));
3451 DH_free(dh);
3452 return -1;
3453 }
3454 DH_free(dh);
3455 return 0;
3456#endif /* OPENSSL_NO_DH */
3457}
3458
3459
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003460int tls_connection_get_random(void *ssl_ctx, struct tls_connection *conn,
3461 struct tls_random *keys)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003462{
3463 SSL *ssl;
3464
3465 if (conn == NULL || keys == NULL)
3466 return -1;
3467 ssl = conn->ssl;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003468 if (ssl == NULL)
3469 return -1;
3470
3471 os_memset(keys, 0, sizeof(*keys));
3472 keys->client_random = conn->client_random;
3473 keys->client_random_len = SSL_get_client_random(
3474 ssl, conn->client_random, sizeof(conn->client_random));
3475 keys->server_random = conn->server_random;
3476 keys->server_random_len = SSL_get_server_random(
3477 ssl, conn->server_random, sizeof(conn->server_random));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003478
3479 return 0;
3480}
3481
3482
Dmitry Shmidt849734c2016-05-27 09:59:01 -07003483#ifdef OPENSSL_NEED_EAP_FAST_PRF
Dmitry Shmidtaf9da312015-04-03 10:03:11 -07003484static int openssl_get_keyblock_size(SSL *ssl)
3485{
Roshan Pius3a1667e2018-07-03 15:17:14 -07003486#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
3487 (defined(LIBRESSL_VERSION_NUMBER) && \
3488 LIBRESSL_VERSION_NUMBER < 0x20700000L)
Dmitry Shmidtaf9da312015-04-03 10:03:11 -07003489 const EVP_CIPHER *c;
3490 const EVP_MD *h;
3491 int md_size;
3492
3493 if (ssl->enc_read_ctx == NULL || ssl->enc_read_ctx->cipher == NULL ||
3494 ssl->read_hash == NULL)
3495 return -1;
3496
3497 c = ssl->enc_read_ctx->cipher;
Dmitry Shmidtaf9da312015-04-03 10:03:11 -07003498 h = EVP_MD_CTX_md(ssl->read_hash);
Dmitry Shmidtaf9da312015-04-03 10:03:11 -07003499 if (h)
3500 md_size = EVP_MD_size(h);
Dmitry Shmidtaf9da312015-04-03 10:03:11 -07003501 else if (ssl->s3)
3502 md_size = ssl->s3->tmp.new_mac_secret_size;
Dmitry Shmidtaf9da312015-04-03 10:03:11 -07003503 else
3504 return -1;
3505
3506 wpa_printf(MSG_DEBUG, "OpenSSL: keyblock size: key_len=%d MD_size=%d "
3507 "IV_len=%d", EVP_CIPHER_key_length(c), md_size,
3508 EVP_CIPHER_iv_length(c));
3509 return 2 * (EVP_CIPHER_key_length(c) +
3510 md_size +
3511 EVP_CIPHER_iv_length(c));
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003512#else
3513 const SSL_CIPHER *ssl_cipher;
3514 int cipher, digest;
3515 const EVP_CIPHER *c;
3516 const EVP_MD *h;
3517
3518 ssl_cipher = SSL_get_current_cipher(ssl);
3519 if (!ssl_cipher)
3520 return -1;
3521 cipher = SSL_CIPHER_get_cipher_nid(ssl_cipher);
3522 digest = SSL_CIPHER_get_digest_nid(ssl_cipher);
3523 wpa_printf(MSG_DEBUG, "OpenSSL: cipher nid %d digest nid %d",
3524 cipher, digest);
3525 if (cipher < 0 || digest < 0)
3526 return -1;
3527 c = EVP_get_cipherbynid(cipher);
3528 h = EVP_get_digestbynid(digest);
3529 if (!c || !h)
3530 return -1;
3531
3532 wpa_printf(MSG_DEBUG,
3533 "OpenSSL: keyblock size: key_len=%d MD_size=%d IV_len=%d",
3534 EVP_CIPHER_key_length(c), EVP_MD_size(h),
3535 EVP_CIPHER_iv_length(c));
3536 return 2 * (EVP_CIPHER_key_length(c) + EVP_MD_size(h) +
3537 EVP_CIPHER_iv_length(c));
3538#endif
Dmitry Shmidtaf9da312015-04-03 10:03:11 -07003539}
Dmitry Shmidt849734c2016-05-27 09:59:01 -07003540#endif /* OPENSSL_NEED_EAP_FAST_PRF */
Dmitry Shmidtaf9da312015-04-03 10:03:11 -07003541
3542
Dmitry Shmidt849734c2016-05-27 09:59:01 -07003543int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn,
3544 const char *label, u8 *out, size_t out_len)
Dmitry Shmidtaf9da312015-04-03 10:03:11 -07003545{
Dmitry Shmidt849734c2016-05-27 09:59:01 -07003546 if (!conn ||
3547 SSL_export_keying_material(conn->ssl, out, out_len, label,
3548 os_strlen(label), NULL, 0, 0) != 1)
3549 return -1;
3550 return 0;
3551}
3552
3553
3554int tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn,
3555 u8 *out, size_t out_len)
3556{
3557#ifdef OPENSSL_NEED_EAP_FAST_PRF
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003558 SSL *ssl;
3559 SSL_SESSION *sess;
3560 u8 *rnd;
3561 int ret = -1;
3562 int skip = 0;
3563 u8 *tmp_out = NULL;
3564 u8 *_out = out;
3565 unsigned char client_random[SSL3_RANDOM_SIZE];
3566 unsigned char server_random[SSL3_RANDOM_SIZE];
3567 unsigned char master_key[64];
3568 size_t master_key_len;
3569 const char *ver;
3570
3571 /*
Dmitry Shmidt849734c2016-05-27 09:59:01 -07003572 * TLS library did not support EAP-FAST key generation, so get the
3573 * needed TLS session parameters and use an internal implementation of
3574 * TLS PRF to derive the key.
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003575 */
3576
3577 if (conn == NULL)
3578 return -1;
3579 ssl = conn->ssl;
3580 if (ssl == NULL)
3581 return -1;
3582 ver = SSL_get_version(ssl);
3583 sess = SSL_get_session(ssl);
3584 if (!ver || !sess)
3585 return -1;
3586
Dmitry Shmidt849734c2016-05-27 09:59:01 -07003587 skip = openssl_get_keyblock_size(ssl);
3588 if (skip < 0)
3589 return -1;
3590 tmp_out = os_malloc(skip + out_len);
3591 if (!tmp_out)
3592 return -1;
3593 _out = tmp_out;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003594
3595 rnd = os_malloc(2 * SSL3_RANDOM_SIZE);
3596 if (!rnd) {
3597 os_free(tmp_out);
3598 return -1;
3599 }
3600
3601 SSL_get_client_random(ssl, client_random, sizeof(client_random));
3602 SSL_get_server_random(ssl, server_random, sizeof(server_random));
3603 master_key_len = SSL_SESSION_get_master_key(sess, master_key,
3604 sizeof(master_key));
3605
Dmitry Shmidt849734c2016-05-27 09:59:01 -07003606 os_memcpy(rnd, server_random, SSL3_RANDOM_SIZE);
3607 os_memcpy(rnd + SSL3_RANDOM_SIZE, client_random, SSL3_RANDOM_SIZE);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003608
3609 if (os_strcmp(ver, "TLSv1.2") == 0) {
3610 tls_prf_sha256(master_key, master_key_len,
Dmitry Shmidt849734c2016-05-27 09:59:01 -07003611 "key expansion", rnd, 2 * SSL3_RANDOM_SIZE,
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003612 _out, skip + out_len);
3613 ret = 0;
3614 } else if (tls_prf_sha1_md5(master_key, master_key_len,
Dmitry Shmidt849734c2016-05-27 09:59:01 -07003615 "key expansion", rnd, 2 * SSL3_RANDOM_SIZE,
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003616 _out, skip + out_len) == 0) {
3617 ret = 0;
3618 }
3619 os_memset(master_key, 0, sizeof(master_key));
3620 os_free(rnd);
Dmitry Shmidt849734c2016-05-27 09:59:01 -07003621 if (ret == 0)
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003622 os_memcpy(out, _out + skip, out_len);
3623 bin_clear_free(tmp_out, skip);
3624
3625 return ret;
Dmitry Shmidt849734c2016-05-27 09:59:01 -07003626#else /* OPENSSL_NEED_EAP_FAST_PRF */
3627 wpa_printf(MSG_ERROR,
3628 "OpenSSL: EAP-FAST keys cannot be exported in FIPS mode");
3629 return -1;
3630#endif /* OPENSSL_NEED_EAP_FAST_PRF */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003631}
3632
3633
3634static struct wpabuf *
Roshan Pius3a1667e2018-07-03 15:17:14 -07003635openssl_handshake(struct tls_connection *conn, const struct wpabuf *in_data)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003636{
3637 int res;
3638 struct wpabuf *out_data;
3639
3640 /*
3641 * Give TLS handshake data from the server (if available) to OpenSSL
3642 * for processing.
3643 */
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003644 if (in_data && wpabuf_len(in_data) > 0 &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003645 BIO_write(conn->ssl_in, wpabuf_head(in_data), wpabuf_len(in_data))
3646 < 0) {
3647 tls_show_errors(MSG_INFO, __func__,
3648 "Handshake failed - BIO_write");
3649 return NULL;
3650 }
3651
3652 /* Initiate TLS handshake or continue the existing handshake */
Roshan Pius3a1667e2018-07-03 15:17:14 -07003653 if (conn->server)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003654 res = SSL_accept(conn->ssl);
3655 else
3656 res = SSL_connect(conn->ssl);
3657 if (res != 1) {
3658 int err = SSL_get_error(conn->ssl, res);
3659 if (err == SSL_ERROR_WANT_READ)
3660 wpa_printf(MSG_DEBUG, "SSL: SSL_connect - want "
3661 "more data");
3662 else if (err == SSL_ERROR_WANT_WRITE)
3663 wpa_printf(MSG_DEBUG, "SSL: SSL_connect - want to "
3664 "write");
3665 else {
3666 tls_show_errors(MSG_INFO, __func__, "SSL_connect");
3667 conn->failed++;
Roshan Pius3a1667e2018-07-03 15:17:14 -07003668 if (!conn->server && !conn->client_hello_generated) {
3669 /* The server would not understand TLS Alert
3670 * before ClientHello, so simply terminate
3671 * handshake on this type of error case caused
3672 * by a likely internal error like no ciphers
3673 * available. */
3674 wpa_printf(MSG_DEBUG,
3675 "OpenSSL: Could not generate ClientHello");
3676 conn->write_alerts++;
3677 return NULL;
3678 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003679 }
3680 }
3681
Roshan Pius3a1667e2018-07-03 15:17:14 -07003682 if (!conn->server && !conn->failed)
3683 conn->client_hello_generated = 1;
3684
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07003685#ifdef CONFIG_SUITEB
Roshan Pius3a1667e2018-07-03 15:17:14 -07003686 if ((conn->flags & TLS_CONN_SUITEB) && !conn->server &&
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07003687 os_strncmp(SSL_get_cipher(conn->ssl), "DHE-", 4) == 0 &&
3688 conn->server_dh_prime_len < 3072) {
3689 struct tls_context *context = conn->context;
3690
3691 /*
3692 * This should not be reached since earlier cert_cb should have
3693 * terminated the handshake. Keep this check here for extra
3694 * protection if anything goes wrong with the more low-level
3695 * checks based on having to parse the TLS handshake messages.
3696 */
3697 wpa_printf(MSG_DEBUG,
3698 "OpenSSL: Server DH prime length: %d bits",
3699 conn->server_dh_prime_len);
3700
3701 if (context->event_cb) {
3702 union tls_event_data ev;
3703
3704 os_memset(&ev, 0, sizeof(ev));
3705 ev.alert.is_local = 1;
3706 ev.alert.type = "fatal";
3707 ev.alert.description = "insufficient security";
3708 context->event_cb(context->cb_ctx, TLS_ALERT, &ev);
3709 }
3710 /*
3711 * Could send a TLS Alert to the server, but for now, simply
3712 * terminate handshake.
3713 */
3714 conn->failed++;
3715 conn->write_alerts++;
3716 return NULL;
3717 }
3718#endif /* CONFIG_SUITEB */
3719
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003720 /* Get the TLS handshake data to be sent to the server */
3721 res = BIO_ctrl_pending(conn->ssl_out);
3722 wpa_printf(MSG_DEBUG, "SSL: %d bytes pending from ssl_out", res);
3723 out_data = wpabuf_alloc(res);
3724 if (out_data == NULL) {
3725 wpa_printf(MSG_DEBUG, "SSL: Failed to allocate memory for "
3726 "handshake output (%d bytes)", res);
3727 if (BIO_reset(conn->ssl_out) < 0) {
3728 tls_show_errors(MSG_INFO, __func__,
3729 "BIO_reset failed");
3730 }
3731 return NULL;
3732 }
3733 res = res == 0 ? 0 : BIO_read(conn->ssl_out, wpabuf_mhead(out_data),
3734 res);
3735 if (res < 0) {
3736 tls_show_errors(MSG_INFO, __func__,
3737 "Handshake failed - BIO_read");
3738 if (BIO_reset(conn->ssl_out) < 0) {
3739 tls_show_errors(MSG_INFO, __func__,
3740 "BIO_reset failed");
3741 }
3742 wpabuf_free(out_data);
3743 return NULL;
3744 }
3745 wpabuf_put(out_data, res);
3746
3747 return out_data;
3748}
3749
3750
3751static struct wpabuf *
3752openssl_get_appl_data(struct tls_connection *conn, size_t max_len)
3753{
3754 struct wpabuf *appl_data;
3755 int res;
3756
3757 appl_data = wpabuf_alloc(max_len + 100);
3758 if (appl_data == NULL)
3759 return NULL;
3760
3761 res = SSL_read(conn->ssl, wpabuf_mhead(appl_data),
3762 wpabuf_size(appl_data));
3763 if (res < 0) {
3764 int err = SSL_get_error(conn->ssl, res);
3765 if (err == SSL_ERROR_WANT_READ ||
3766 err == SSL_ERROR_WANT_WRITE) {
3767 wpa_printf(MSG_DEBUG, "SSL: No Application Data "
3768 "included");
3769 } else {
3770 tls_show_errors(MSG_INFO, __func__,
3771 "Failed to read possible "
3772 "Application Data");
3773 }
3774 wpabuf_free(appl_data);
3775 return NULL;
3776 }
3777
3778 wpabuf_put(appl_data, res);
3779 wpa_hexdump_buf_key(MSG_MSGDUMP, "SSL: Application Data in Finished "
3780 "message", appl_data);
3781
3782 return appl_data;
3783}
3784
3785
3786static struct wpabuf *
3787openssl_connection_handshake(struct tls_connection *conn,
3788 const struct wpabuf *in_data,
Roshan Pius3a1667e2018-07-03 15:17:14 -07003789 struct wpabuf **appl_data)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003790{
3791 struct wpabuf *out_data;
3792
3793 if (appl_data)
3794 *appl_data = NULL;
3795
Roshan Pius3a1667e2018-07-03 15:17:14 -07003796 out_data = openssl_handshake(conn, in_data);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003797 if (out_data == NULL)
3798 return NULL;
Jouni Malinen26af48b2014-04-09 13:02:53 +03003799 if (conn->invalid_hb_used) {
3800 wpa_printf(MSG_INFO, "TLS: Heartbeat attack detected - do not send response");
3801 wpabuf_free(out_data);
3802 return NULL;
3803 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003804
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003805 if (SSL_is_init_finished(conn->ssl)) {
3806 wpa_printf(MSG_DEBUG,
3807 "OpenSSL: Handshake finished - resumed=%d",
3808 tls_connection_resumed(conn->ssl_ctx, conn));
3809 if (appl_data && in_data)
3810 *appl_data = openssl_get_appl_data(conn,
3811 wpabuf_len(in_data));
3812 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003813
Jouni Malinen26af48b2014-04-09 13:02:53 +03003814 if (conn->invalid_hb_used) {
3815 wpa_printf(MSG_INFO, "TLS: Heartbeat attack detected - do not send response");
3816 if (appl_data) {
3817 wpabuf_free(*appl_data);
3818 *appl_data = NULL;
3819 }
3820 wpabuf_free(out_data);
3821 return NULL;
3822 }
3823
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003824 return out_data;
3825}
3826
3827
3828struct wpabuf *
3829tls_connection_handshake(void *ssl_ctx, struct tls_connection *conn,
3830 const struct wpabuf *in_data,
3831 struct wpabuf **appl_data)
3832{
Roshan Pius3a1667e2018-07-03 15:17:14 -07003833 return openssl_connection_handshake(conn, in_data, appl_data);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003834}
3835
3836
3837struct wpabuf * tls_connection_server_handshake(void *tls_ctx,
3838 struct tls_connection *conn,
3839 const struct wpabuf *in_data,
3840 struct wpabuf **appl_data)
3841{
Roshan Pius3a1667e2018-07-03 15:17:14 -07003842 conn->server = 1;
3843 return openssl_connection_handshake(conn, in_data, appl_data);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003844}
3845
3846
3847struct wpabuf * tls_connection_encrypt(void *tls_ctx,
3848 struct tls_connection *conn,
3849 const struct wpabuf *in_data)
3850{
3851 int res;
3852 struct wpabuf *buf;
3853
3854 if (conn == NULL)
3855 return NULL;
3856
3857 /* Give plaintext data for OpenSSL to encrypt into the TLS tunnel. */
3858 if ((res = BIO_reset(conn->ssl_in)) < 0 ||
3859 (res = BIO_reset(conn->ssl_out)) < 0) {
3860 tls_show_errors(MSG_INFO, __func__, "BIO_reset failed");
3861 return NULL;
3862 }
3863 res = SSL_write(conn->ssl, wpabuf_head(in_data), wpabuf_len(in_data));
3864 if (res < 0) {
3865 tls_show_errors(MSG_INFO, __func__,
3866 "Encryption failed - SSL_write");
3867 return NULL;
3868 }
3869
3870 /* Read encrypted data to be sent to the server */
3871 buf = wpabuf_alloc(wpabuf_len(in_data) + 300);
3872 if (buf == NULL)
3873 return NULL;
3874 res = BIO_read(conn->ssl_out, wpabuf_mhead(buf), wpabuf_size(buf));
3875 if (res < 0) {
3876 tls_show_errors(MSG_INFO, __func__,
3877 "Encryption failed - BIO_read");
3878 wpabuf_free(buf);
3879 return NULL;
3880 }
3881 wpabuf_put(buf, res);
3882
3883 return buf;
3884}
3885
3886
3887struct wpabuf * tls_connection_decrypt(void *tls_ctx,
3888 struct tls_connection *conn,
3889 const struct wpabuf *in_data)
3890{
3891 int res;
3892 struct wpabuf *buf;
3893
3894 /* Give encrypted data from TLS tunnel for OpenSSL to decrypt. */
3895 res = BIO_write(conn->ssl_in, wpabuf_head(in_data),
3896 wpabuf_len(in_data));
3897 if (res < 0) {
3898 tls_show_errors(MSG_INFO, __func__,
3899 "Decryption failed - BIO_write");
3900 return NULL;
3901 }
3902 if (BIO_reset(conn->ssl_out) < 0) {
3903 tls_show_errors(MSG_INFO, __func__, "BIO_reset failed");
3904 return NULL;
3905 }
3906
3907 /* Read decrypted data for further processing */
3908 /*
3909 * Even though we try to disable TLS compression, it is possible that
3910 * this cannot be done with all TLS libraries. Add extra buffer space
3911 * to handle the possibility of the decrypted data being longer than
3912 * input data.
3913 */
3914 buf = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3);
3915 if (buf == NULL)
3916 return NULL;
3917 res = SSL_read(conn->ssl, wpabuf_mhead(buf), wpabuf_size(buf));
3918 if (res < 0) {
3919 tls_show_errors(MSG_INFO, __func__,
3920 "Decryption failed - SSL_read");
3921 wpabuf_free(buf);
3922 return NULL;
3923 }
3924 wpabuf_put(buf, res);
3925
Jouni Malinen26af48b2014-04-09 13:02:53 +03003926 if (conn->invalid_hb_used) {
3927 wpa_printf(MSG_INFO, "TLS: Heartbeat attack detected - do not send response");
3928 wpabuf_free(buf);
3929 return NULL;
3930 }
3931
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003932 return buf;
3933}
3934
3935
3936int tls_connection_resumed(void *ssl_ctx, struct tls_connection *conn)
3937{
Hai Shalomce48b4a2018-09-05 11:41:35 -07003938 return conn ? SSL_session_reused(conn->ssl) : 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003939}
3940
3941
3942int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn,
3943 u8 *ciphers)
3944{
Dmitry Shmidtde47be72016-01-07 12:52:55 -08003945 char buf[500], *pos, *end;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003946 u8 *c;
3947 int ret;
3948
3949 if (conn == NULL || conn->ssl == NULL || ciphers == NULL)
3950 return -1;
3951
3952 buf[0] = '\0';
3953 pos = buf;
3954 end = pos + sizeof(buf);
3955
3956 c = ciphers;
3957 while (*c != TLS_CIPHER_NONE) {
3958 const char *suite;
3959
3960 switch (*c) {
3961 case TLS_CIPHER_RC4_SHA:
3962 suite = "RC4-SHA";
3963 break;
3964 case TLS_CIPHER_AES128_SHA:
3965 suite = "AES128-SHA";
3966 break;
3967 case TLS_CIPHER_RSA_DHE_AES128_SHA:
3968 suite = "DHE-RSA-AES128-SHA";
3969 break;
3970 case TLS_CIPHER_ANON_DH_AES128_SHA:
3971 suite = "ADH-AES128-SHA";
3972 break;
Dmitry Shmidtde47be72016-01-07 12:52:55 -08003973 case TLS_CIPHER_RSA_DHE_AES256_SHA:
3974 suite = "DHE-RSA-AES256-SHA";
3975 break;
3976 case TLS_CIPHER_AES256_SHA:
3977 suite = "AES256-SHA";
3978 break;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003979 default:
3980 wpa_printf(MSG_DEBUG, "TLS: Unsupported "
3981 "cipher selection: %d", *c);
3982 return -1;
3983 }
3984 ret = os_snprintf(pos, end - pos, ":%s", suite);
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08003985 if (os_snprintf_error(end - pos, ret))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003986 break;
3987 pos += ret;
3988
3989 c++;
3990 }
3991
3992 wpa_printf(MSG_DEBUG, "OpenSSL: cipher suites: %s", buf + 1);
3993
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08003994#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003995#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
3996 if (os_strstr(buf, ":ADH-")) {
3997 /*
3998 * Need to drop to security level 0 to allow anonymous
3999 * cipher suites for EAP-FAST.
4000 */
4001 SSL_set_security_level(conn->ssl, 0);
4002 } else if (SSL_get_security_level(conn->ssl) == 0) {
4003 /* Force at least security level 1 */
4004 SSL_set_security_level(conn->ssl, 1);
4005 }
4006#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
4007#endif
4008
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004009 if (SSL_set_cipher_list(conn->ssl, buf + 1) != 1) {
4010 tls_show_errors(MSG_INFO, __func__,
4011 "Cipher suite configuration failed");
4012 return -1;
4013 }
4014
4015 return 0;
4016}
4017
4018
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004019int tls_get_version(void *ssl_ctx, struct tls_connection *conn,
4020 char *buf, size_t buflen)
4021{
4022 const char *name;
4023 if (conn == NULL || conn->ssl == NULL)
4024 return -1;
4025
4026 name = SSL_get_version(conn->ssl);
4027 if (name == NULL)
4028 return -1;
4029
4030 os_strlcpy(buf, name, buflen);
4031 return 0;
4032}
4033
4034
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004035int tls_get_cipher(void *ssl_ctx, struct tls_connection *conn,
4036 char *buf, size_t buflen)
4037{
4038 const char *name;
4039 if (conn == NULL || conn->ssl == NULL)
4040 return -1;
4041
4042 name = SSL_get_cipher(conn->ssl);
4043 if (name == NULL)
4044 return -1;
4045
4046 os_strlcpy(buf, name, buflen);
4047 return 0;
4048}
4049
4050
4051int tls_connection_enable_workaround(void *ssl_ctx,
4052 struct tls_connection *conn)
4053{
4054 SSL_set_options(conn->ssl, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
4055
4056 return 0;
4057}
4058
4059
4060#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
4061/* ClientHello TLS extensions require a patch to openssl, so this function is
4062 * commented out unless explicitly needed for EAP-FAST in order to be able to
4063 * build this file with unmodified openssl. */
4064int tls_connection_client_hello_ext(void *ssl_ctx, struct tls_connection *conn,
4065 int ext_type, const u8 *data,
4066 size_t data_len)
4067{
4068 if (conn == NULL || conn->ssl == NULL || ext_type != 35)
4069 return -1;
4070
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004071 if (SSL_set_session_ticket_ext(conn->ssl, (void *) data,
4072 data_len) != 1)
4073 return -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004074
4075 return 0;
4076}
4077#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
4078
4079
4080int tls_connection_get_failed(void *ssl_ctx, struct tls_connection *conn)
4081{
4082 if (conn == NULL)
4083 return -1;
4084 return conn->failed;
4085}
4086
4087
4088int tls_connection_get_read_alerts(void *ssl_ctx, struct tls_connection *conn)
4089{
4090 if (conn == NULL)
4091 return -1;
4092 return conn->read_alerts;
4093}
4094
4095
4096int tls_connection_get_write_alerts(void *ssl_ctx, struct tls_connection *conn)
4097{
4098 if (conn == NULL)
4099 return -1;
4100 return conn->write_alerts;
4101}
4102
4103
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004104#ifdef HAVE_OCSP
4105
4106static void ocsp_debug_print_resp(OCSP_RESPONSE *rsp)
4107{
4108#ifndef CONFIG_NO_STDOUT_DEBUG
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004109 BIO *out;
4110 size_t rlen;
4111 char *txt;
4112 int res;
4113
4114 if (wpa_debug_level > MSG_DEBUG)
4115 return;
4116
4117 out = BIO_new(BIO_s_mem());
4118 if (!out)
4119 return;
4120
4121 OCSP_RESPONSE_print(out, rsp, 0);
4122 rlen = BIO_ctrl_pending(out);
4123 txt = os_malloc(rlen + 1);
4124 if (!txt) {
4125 BIO_free(out);
4126 return;
4127 }
4128
4129 res = BIO_read(out, txt, rlen);
4130 if (res > 0) {
4131 txt[res] = '\0';
4132 wpa_printf(MSG_DEBUG, "OpenSSL: OCSP Response\n%s", txt);
4133 }
4134 os_free(txt);
4135 BIO_free(out);
4136#endif /* CONFIG_NO_STDOUT_DEBUG */
4137}
4138
4139
Dmitry Shmidt71757432014-06-02 13:50:35 -07004140static void debug_print_cert(X509 *cert, const char *title)
4141{
4142#ifndef CONFIG_NO_STDOUT_DEBUG
4143 BIO *out;
4144 size_t rlen;
4145 char *txt;
4146 int res;
4147
4148 if (wpa_debug_level > MSG_DEBUG)
4149 return;
4150
4151 out = BIO_new(BIO_s_mem());
4152 if (!out)
4153 return;
4154
4155 X509_print(out, cert);
4156 rlen = BIO_ctrl_pending(out);
4157 txt = os_malloc(rlen + 1);
4158 if (!txt) {
4159 BIO_free(out);
4160 return;
4161 }
4162
4163 res = BIO_read(out, txt, rlen);
4164 if (res > 0) {
4165 txt[res] = '\0';
4166 wpa_printf(MSG_DEBUG, "OpenSSL: %s\n%s", title, txt);
4167 }
4168 os_free(txt);
4169
4170 BIO_free(out);
4171#endif /* CONFIG_NO_STDOUT_DEBUG */
4172}
4173
4174
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004175static int ocsp_resp_cb(SSL *s, void *arg)
4176{
4177 struct tls_connection *conn = arg;
4178 const unsigned char *p;
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07004179 int len, status, reason, res;
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004180 OCSP_RESPONSE *rsp;
4181 OCSP_BASICRESP *basic;
4182 OCSP_CERTID *id;
4183 ASN1_GENERALIZEDTIME *produced_at, *this_update, *next_update;
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004184 X509_STORE *store;
4185 STACK_OF(X509) *certs = NULL;
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004186
4187 len = SSL_get_tlsext_status_ocsp_resp(s, &p);
4188 if (!p) {
4189 wpa_printf(MSG_DEBUG, "OpenSSL: No OCSP response received");
4190 return (conn->flags & TLS_CONN_REQUIRE_OCSP) ? 0 : 1;
4191 }
4192
4193 wpa_hexdump(MSG_DEBUG, "OpenSSL: OCSP response", p, len);
4194
4195 rsp = d2i_OCSP_RESPONSE(NULL, &p, len);
4196 if (!rsp) {
4197 wpa_printf(MSG_INFO, "OpenSSL: Failed to parse OCSP response");
4198 return 0;
4199 }
4200
4201 ocsp_debug_print_resp(rsp);
4202
4203 status = OCSP_response_status(rsp);
4204 if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
4205 wpa_printf(MSG_INFO, "OpenSSL: OCSP responder error %d (%s)",
4206 status, OCSP_response_status_str(status));
4207 return 0;
4208 }
4209
4210 basic = OCSP_response_get1_basic(rsp);
4211 if (!basic) {
4212 wpa_printf(MSG_INFO, "OpenSSL: Could not find BasicOCSPResponse");
4213 return 0;
4214 }
4215
Dmitry Shmidt216983b2015-02-06 10:50:36 -08004216 store = SSL_CTX_get_cert_store(conn->ssl_ctx);
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004217 if (conn->peer_issuer) {
Dmitry Shmidt71757432014-06-02 13:50:35 -07004218 debug_print_cert(conn->peer_issuer, "Add OCSP issuer");
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004219
4220 if (X509_STORE_add_cert(store, conn->peer_issuer) != 1) {
4221 tls_show_errors(MSG_INFO, __func__,
Dmitry Shmidt7f656022015-02-25 14:36:37 -08004222 "OpenSSL: Could not add issuer to certificate store");
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004223 }
4224 certs = sk_X509_new_null();
4225 if (certs) {
4226 X509 *cert;
4227 cert = X509_dup(conn->peer_issuer);
4228 if (cert && !sk_X509_push(certs, cert)) {
4229 tls_show_errors(
4230 MSG_INFO, __func__,
Dmitry Shmidt7f656022015-02-25 14:36:37 -08004231 "OpenSSL: Could not add issuer to OCSP responder trust store");
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004232 X509_free(cert);
4233 sk_X509_free(certs);
4234 certs = NULL;
4235 }
Dmitry Shmidt7f656022015-02-25 14:36:37 -08004236 if (certs && conn->peer_issuer_issuer) {
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004237 cert = X509_dup(conn->peer_issuer_issuer);
4238 if (cert && !sk_X509_push(certs, cert)) {
4239 tls_show_errors(
4240 MSG_INFO, __func__,
Dmitry Shmidt7f656022015-02-25 14:36:37 -08004241 "OpenSSL: Could not add issuer's issuer to OCSP responder trust store");
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004242 X509_free(cert);
4243 }
4244 }
4245 }
4246 }
4247
4248 status = OCSP_basic_verify(basic, certs, store, OCSP_TRUSTOTHER);
4249 sk_X509_pop_free(certs, X509_free);
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004250 if (status <= 0) {
4251 tls_show_errors(MSG_INFO, __func__,
4252 "OpenSSL: OCSP response failed verification");
4253 OCSP_BASICRESP_free(basic);
4254 OCSP_RESPONSE_free(rsp);
4255 return 0;
4256 }
4257
4258 wpa_printf(MSG_DEBUG, "OpenSSL: OCSP response verification succeeded");
4259
Dmitry Shmidt56052862013-10-04 10:23:25 -07004260 if (!conn->peer_cert) {
4261 wpa_printf(MSG_DEBUG, "OpenSSL: Peer certificate not available for OCSP status check");
4262 OCSP_BASICRESP_free(basic);
4263 OCSP_RESPONSE_free(rsp);
4264 return 0;
4265 }
4266
4267 if (!conn->peer_issuer) {
4268 wpa_printf(MSG_DEBUG, "OpenSSL: Peer issuer certificate not available for OCSP status check");
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004269 OCSP_BASICRESP_free(basic);
4270 OCSP_RESPONSE_free(rsp);
4271 return 0;
4272 }
4273
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07004274 id = OCSP_cert_to_id(EVP_sha256(), conn->peer_cert, conn->peer_issuer);
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004275 if (!id) {
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07004276 wpa_printf(MSG_DEBUG,
4277 "OpenSSL: Could not create OCSP certificate identifier (SHA256)");
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004278 OCSP_BASICRESP_free(basic);
4279 OCSP_RESPONSE_free(rsp);
4280 return 0;
4281 }
4282
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07004283 res = OCSP_resp_find_status(basic, id, &status, &reason, &produced_at,
4284 &this_update, &next_update);
4285 if (!res) {
4286 id = OCSP_cert_to_id(NULL, conn->peer_cert, conn->peer_issuer);
4287 if (!id) {
4288 wpa_printf(MSG_DEBUG,
4289 "OpenSSL: Could not create OCSP certificate identifier (SHA1)");
4290 OCSP_BASICRESP_free(basic);
4291 OCSP_RESPONSE_free(rsp);
4292 return 0;
4293 }
4294
4295 res = OCSP_resp_find_status(basic, id, &status, &reason,
4296 &produced_at, &this_update,
4297 &next_update);
4298 }
4299
4300 if (!res) {
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004301 wpa_printf(MSG_INFO, "OpenSSL: Could not find current server certificate from OCSP response%s",
4302 (conn->flags & TLS_CONN_REQUIRE_OCSP) ? "" :
4303 " (OCSP not required)");
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08004304 OCSP_CERTID_free(id);
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004305 OCSP_BASICRESP_free(basic);
4306 OCSP_RESPONSE_free(rsp);
4307 return (conn->flags & TLS_CONN_REQUIRE_OCSP) ? 0 : 1;
4308 }
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08004309 OCSP_CERTID_free(id);
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004310
4311 if (!OCSP_check_validity(this_update, next_update, 5 * 60, -1)) {
4312 tls_show_errors(MSG_INFO, __func__,
4313 "OpenSSL: OCSP status times invalid");
4314 OCSP_BASICRESP_free(basic);
4315 OCSP_RESPONSE_free(rsp);
4316 return 0;
4317 }
4318
4319 OCSP_BASICRESP_free(basic);
4320 OCSP_RESPONSE_free(rsp);
4321
4322 wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status for server certificate: %s",
4323 OCSP_cert_status_str(status));
4324
4325 if (status == V_OCSP_CERTSTATUS_GOOD)
4326 return 1;
4327 if (status == V_OCSP_CERTSTATUS_REVOKED)
4328 return 0;
4329 if (conn->flags & TLS_CONN_REQUIRE_OCSP) {
4330 wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status unknown, but OCSP required");
4331 return 0;
4332 }
Dmitry Shmidt051af732013-10-22 13:52:46 -07004333 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 -07004334 return 1;
4335}
4336
4337
4338static int ocsp_status_cb(SSL *s, void *arg)
4339{
4340 char *tmp;
4341 char *resp;
4342 size_t len;
4343
4344 if (tls_global->ocsp_stapling_response == NULL) {
4345 wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status callback - no response configured");
4346 return SSL_TLSEXT_ERR_OK;
4347 }
4348
4349 resp = os_readfile(tls_global->ocsp_stapling_response, &len);
4350 if (resp == NULL) {
4351 wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status callback - could not read response file");
4352 /* TODO: Build OCSPResponse with responseStatus = internalError
4353 */
4354 return SSL_TLSEXT_ERR_OK;
4355 }
4356 wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status callback - send cached response");
4357 tmp = OPENSSL_malloc(len);
4358 if (tmp == NULL) {
4359 os_free(resp);
4360 return SSL_TLSEXT_ERR_ALERT_FATAL;
4361 }
4362
4363 os_memcpy(tmp, resp, len);
4364 os_free(resp);
4365 SSL_set_tlsext_status_ocsp_resp(s, tmp, len);
4366
4367 return SSL_TLSEXT_ERR_OK;
4368}
4369
4370#endif /* HAVE_OCSP */
4371
4372
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004373int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
4374 const struct tls_connection_params *params)
4375{
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004376 struct tls_data *data = tls_ctx;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004377 int ret;
4378 unsigned long err;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004379 int can_pkcs11 = 0;
4380 const char *key_id = params->key_id;
4381 const char *cert_id = params->cert_id;
4382 const char *ca_cert_id = params->ca_cert_id;
4383 const char *engine_id = params->engine ? params->engine_id : NULL;
Roshan Pius3a1667e2018-07-03 15:17:14 -07004384 const char *ciphers;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004385
4386 if (conn == NULL)
4387 return -1;
4388
Dmitry Shmidt014a3ff2015-12-28 13:27:49 -08004389 if (params->flags & TLS_CONN_REQUIRE_OCSP_ALL) {
4390 wpa_printf(MSG_INFO,
4391 "OpenSSL: ocsp=3 not supported");
4392 return -1;
4393 }
4394
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004395 /*
4396 * If the engine isn't explicitly configured, and any of the
4397 * cert/key fields are actually PKCS#11 URIs, then automatically
4398 * use the PKCS#11 ENGINE.
4399 */
4400 if (!engine_id || os_strcmp(engine_id, "pkcs11") == 0)
4401 can_pkcs11 = 1;
4402
4403 if (!key_id && params->private_key && can_pkcs11 &&
4404 os_strncmp(params->private_key, "pkcs11:", 7) == 0) {
4405 can_pkcs11 = 2;
4406 key_id = params->private_key;
4407 }
4408
4409 if (!cert_id && params->client_cert && can_pkcs11 &&
4410 os_strncmp(params->client_cert, "pkcs11:", 7) == 0) {
4411 can_pkcs11 = 2;
4412 cert_id = params->client_cert;
4413 }
4414
4415 if (!ca_cert_id && params->ca_cert && can_pkcs11 &&
4416 os_strncmp(params->ca_cert, "pkcs11:", 7) == 0) {
4417 can_pkcs11 = 2;
4418 ca_cert_id = params->ca_cert;
4419 }
4420
4421 /* If we need to automatically enable the PKCS#11 ENGINE, do so. */
4422 if (can_pkcs11 == 2 && !engine_id)
4423 engine_id = "pkcs11";
4424
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004425#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08004426#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004427 if (params->flags & TLS_CONN_EAP_FAST) {
4428 wpa_printf(MSG_DEBUG,
4429 "OpenSSL: Use TLSv1_method() for EAP-FAST");
4430 if (SSL_set_ssl_method(conn->ssl, TLSv1_method()) != 1) {
4431 tls_show_errors(MSG_INFO, __func__,
4432 "Failed to set TLSv1_method() for EAP-FAST");
4433 return -1;
4434 }
4435 }
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004436#endif
Roshan Pius3a1667e2018-07-03 15:17:14 -07004437#if OPENSSL_VERSION_NUMBER >= 0x10101000L
4438#ifdef SSL_OP_NO_TLSv1_3
4439 if (params->flags & TLS_CONN_EAP_FAST) {
4440 /* Need to disable TLS v1.3 at least for now since OpenSSL 1.1.1
4441 * refuses to start the handshake with the modified ciphersuite
4442 * list (no TLS v1.3 ciphersuites included) for EAP-FAST. */
4443 wpa_printf(MSG_DEBUG, "OpenSSL: Disable TLSv1.3 for EAP-FAST");
4444 SSL_set_options(conn->ssl, SSL_OP_NO_TLSv1_3);
4445 }
4446#endif /* SSL_OP_NO_TLSv1_3 */
4447#endif
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004448#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004449
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004450 while ((err = ERR_get_error())) {
4451 wpa_printf(MSG_INFO, "%s: Clearing pending SSL error: %s",
4452 __func__, ERR_error_string(err, NULL));
4453 }
4454
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004455 if (engine_id) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004456 wpa_printf(MSG_DEBUG, "SSL: Initializing TLS engine");
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004457 ret = tls_engine_init(conn, engine_id, params->pin,
4458 key_id, cert_id, ca_cert_id);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004459 if (ret)
4460 return ret;
4461 }
4462 if (tls_connection_set_subject_match(conn,
4463 params->subject_match,
Dmitry Shmidt051af732013-10-22 13:52:46 -07004464 params->altsubject_match,
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08004465 params->suffix_match,
4466 params->domain_match))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004467 return -1;
4468
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004469 if (engine_id && ca_cert_id) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004470 if (tls_connection_engine_ca_cert(data, conn, ca_cert_id))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004471 return TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004472 } else if (tls_connection_ca_cert(data, conn, params->ca_cert,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004473 params->ca_cert_blob,
4474 params->ca_cert_blob_len,
4475 params->ca_path))
4476 return -1;
4477
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004478 if (engine_id && cert_id) {
4479 if (tls_connection_engine_client_cert(conn, cert_id))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004480 return TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED;
4481 } else if (tls_connection_client_cert(conn, params->client_cert,
4482 params->client_cert_blob,
4483 params->client_cert_blob_len))
4484 return -1;
4485
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004486 if (engine_id && key_id) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004487 wpa_printf(MSG_DEBUG, "TLS: Using private key from engine");
4488 if (tls_connection_engine_private_key(conn))
4489 return TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004490 } else if (tls_connection_private_key(data, conn,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004491 params->private_key,
4492 params->private_key_passwd,
4493 params->private_key_blob,
4494 params->private_key_blob_len)) {
4495 wpa_printf(MSG_INFO, "TLS: Failed to load private key '%s'",
4496 params->private_key);
4497 return -1;
4498 }
4499
4500 if (tls_connection_dh(conn, params->dh_file)) {
4501 wpa_printf(MSG_INFO, "TLS: Failed to load DH file '%s'",
4502 params->dh_file);
4503 return -1;
4504 }
4505
Roshan Pius3a1667e2018-07-03 15:17:14 -07004506 ciphers = params->openssl_ciphers;
4507#ifdef CONFIG_SUITEB
4508#ifdef OPENSSL_IS_BORINGSSL
4509 if (ciphers && os_strcmp(ciphers, "SUITEB192") == 0) {
4510 /* BoringSSL removed support for SUITEB192, so need to handle
4511 * this with hardcoded ciphersuite and additional checks for
4512 * other parameters. */
4513 ciphers = "ECDHE-ECDSA-AES256-GCM-SHA384";
4514 }
4515#endif /* OPENSSL_IS_BORINGSSL */
4516#endif /* CONFIG_SUITEB */
4517 if (ciphers && SSL_set_cipher_list(conn->ssl, ciphers) != 1) {
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004518 wpa_printf(MSG_INFO,
4519 "OpenSSL: Failed to set cipher string '%s'",
Roshan Pius3a1667e2018-07-03 15:17:14 -07004520 ciphers);
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004521 return -1;
4522 }
4523
Roshan Pius3a1667e2018-07-03 15:17:14 -07004524 if (tls_set_conn_flags(conn, params->flags,
4525 params->openssl_ciphers) < 0)
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07004526 return -1;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07004527
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004528#ifdef OPENSSL_IS_BORINGSSL
4529 if (params->flags & TLS_CONN_REQUEST_OCSP) {
4530 SSL_enable_ocsp_stapling(conn->ssl);
4531 }
4532#else /* OPENSSL_IS_BORINGSSL */
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004533#ifdef HAVE_OCSP
4534 if (params->flags & TLS_CONN_REQUEST_OCSP) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004535 SSL_CTX *ssl_ctx = data->ssl;
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004536 SSL_set_tlsext_status_type(conn->ssl, TLSEXT_STATUSTYPE_ocsp);
4537 SSL_CTX_set_tlsext_status_cb(ssl_ctx, ocsp_resp_cb);
4538 SSL_CTX_set_tlsext_status_arg(ssl_ctx, conn);
4539 }
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004540#else /* HAVE_OCSP */
4541 if (params->flags & TLS_CONN_REQUIRE_OCSP) {
4542 wpa_printf(MSG_INFO,
4543 "OpenSSL: No OCSP support included - reject configuration");
4544 return -1;
4545 }
4546 if (params->flags & TLS_CONN_REQUEST_OCSP) {
4547 wpa_printf(MSG_DEBUG,
4548 "OpenSSL: No OCSP support included - allow optional OCSP case to continue");
4549 }
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004550#endif /* HAVE_OCSP */
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004551#endif /* OPENSSL_IS_BORINGSSL */
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004552
Dmitry Shmidtc55524a2011-07-07 11:18:38 -07004553 conn->flags = params->flags;
4554
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004555 tls_get_errors(data);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004556
4557 return 0;
4558}
4559
4560
4561int tls_global_set_params(void *tls_ctx,
4562 const struct tls_connection_params *params)
4563{
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004564 struct tls_data *data = tls_ctx;
4565 SSL_CTX *ssl_ctx = data->ssl;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004566 unsigned long err;
4567
4568 while ((err = ERR_get_error())) {
4569 wpa_printf(MSG_INFO, "%s: Clearing pending SSL error: %s",
4570 __func__, ERR_error_string(err, NULL));
4571 }
4572
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004573 if (tls_global_ca_cert(data, params->ca_cert) ||
4574 tls_global_client_cert(data, params->client_cert) ||
4575 tls_global_private_key(data, params->private_key,
4576 params->private_key_passwd) ||
4577 tls_global_dh(data, params->dh_file)) {
4578 wpa_printf(MSG_INFO, "TLS: Failed to set global parameters");
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004579 return -1;
4580 }
4581
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004582 if (params->openssl_ciphers &&
4583 SSL_CTX_set_cipher_list(ssl_ctx, params->openssl_ciphers) != 1) {
4584 wpa_printf(MSG_INFO,
4585 "OpenSSL: Failed to set cipher string '%s'",
4586 params->openssl_ciphers);
4587 return -1;
4588 }
4589
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07004590#ifdef SSL_OP_NO_TICKET
4591 if (params->flags & TLS_CONN_DISABLE_SESSION_TICKET)
4592 SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TICKET);
4593 else
4594 SSL_CTX_clear_options(ssl_ctx, SSL_OP_NO_TICKET);
4595#endif /* SSL_OP_NO_TICKET */
4596
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004597#ifdef HAVE_OCSP
4598 SSL_CTX_set_tlsext_status_cb(ssl_ctx, ocsp_status_cb);
4599 SSL_CTX_set_tlsext_status_arg(ssl_ctx, ssl_ctx);
4600 os_free(tls_global->ocsp_stapling_response);
4601 if (params->ocsp_stapling_response)
4602 tls_global->ocsp_stapling_response =
4603 os_strdup(params->ocsp_stapling_response);
4604 else
4605 tls_global->ocsp_stapling_response = NULL;
4606#endif /* HAVE_OCSP */
4607
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004608 return 0;
4609}
4610
4611
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004612#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
4613/* Pre-shared secred requires a patch to openssl, so this function is
4614 * commented out unless explicitly needed for EAP-FAST in order to be able to
4615 * build this file with unmodified openssl. */
4616
Dmitry Shmidt1d6bf422016-01-19 15:51:35 -08004617#if (defined(OPENSSL_IS_BORINGSSL) || OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -07004618static int tls_sess_sec_cb(SSL *s, void *secret, int *secret_len,
4619 STACK_OF(SSL_CIPHER) *peer_ciphers,
4620 const SSL_CIPHER **cipher, void *arg)
4621#else /* OPENSSL_IS_BORINGSSL */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004622static int tls_sess_sec_cb(SSL *s, void *secret, int *secret_len,
4623 STACK_OF(SSL_CIPHER) *peer_ciphers,
4624 SSL_CIPHER **cipher, void *arg)
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -07004625#endif /* OPENSSL_IS_BORINGSSL */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004626{
4627 struct tls_connection *conn = arg;
4628 int ret;
4629
Roshan Pius3a1667e2018-07-03 15:17:14 -07004630#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
4631 (defined(LIBRESSL_VERSION_NUMBER) && \
4632 LIBRESSL_VERSION_NUMBER < 0x20700000L)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004633 if (conn == NULL || conn->session_ticket_cb == NULL)
4634 return 0;
4635
4636 ret = conn->session_ticket_cb(conn->session_ticket_cb_ctx,
4637 conn->session_ticket,
4638 conn->session_ticket_len,
4639 s->s3->client_random,
4640 s->s3->server_random, secret);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004641#else
4642 unsigned char client_random[SSL3_RANDOM_SIZE];
4643 unsigned char server_random[SSL3_RANDOM_SIZE];
4644
4645 if (conn == NULL || conn->session_ticket_cb == NULL)
4646 return 0;
4647
4648 SSL_get_client_random(s, client_random, sizeof(client_random));
4649 SSL_get_server_random(s, server_random, sizeof(server_random));
4650
4651 ret = conn->session_ticket_cb(conn->session_ticket_cb_ctx,
4652 conn->session_ticket,
4653 conn->session_ticket_len,
4654 client_random,
4655 server_random, secret);
4656#endif
4657
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004658 os_free(conn->session_ticket);
4659 conn->session_ticket = NULL;
4660
4661 if (ret <= 0)
4662 return 0;
4663
4664 *secret_len = SSL_MAX_MASTER_KEY_LENGTH;
4665 return 1;
4666}
4667
4668
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004669static int tls_session_ticket_ext_cb(SSL *s, const unsigned char *data,
4670 int len, void *arg)
4671{
4672 struct tls_connection *conn = arg;
4673
4674 if (conn == NULL || conn->session_ticket_cb == NULL)
4675 return 0;
4676
4677 wpa_printf(MSG_DEBUG, "OpenSSL: %s: length=%d", __func__, len);
4678
4679 os_free(conn->session_ticket);
4680 conn->session_ticket = NULL;
4681
4682 wpa_hexdump(MSG_DEBUG, "OpenSSL: ClientHello SessionTicket "
4683 "extension", data, len);
4684
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07004685 conn->session_ticket = os_memdup(data, len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004686 if (conn->session_ticket == NULL)
4687 return 0;
4688
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004689 conn->session_ticket_len = len;
4690
4691 return 1;
4692}
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004693#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
4694
4695
4696int tls_connection_set_session_ticket_cb(void *tls_ctx,
4697 struct tls_connection *conn,
4698 tls_session_ticket_cb cb,
4699 void *ctx)
4700{
4701#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
4702 conn->session_ticket_cb = cb;
4703 conn->session_ticket_cb_ctx = ctx;
4704
4705 if (cb) {
4706 if (SSL_set_session_secret_cb(conn->ssl, tls_sess_sec_cb,
4707 conn) != 1)
4708 return -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004709 SSL_set_session_ticket_ext_cb(conn->ssl,
4710 tls_session_ticket_ext_cb, conn);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004711 } else {
4712 if (SSL_set_session_secret_cb(conn->ssl, NULL, NULL) != 1)
4713 return -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004714 SSL_set_session_ticket_ext_cb(conn->ssl, NULL, NULL);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004715 }
4716
4717 return 0;
4718#else /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
4719 return -1;
4720#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
4721}
Dmitry Shmidtff787d52015-01-12 13:01:47 -08004722
4723
4724int tls_get_library_version(char *buf, size_t buf_len)
4725{
Dmitry Shmidt1d6bf422016-01-19 15:51:35 -08004726#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08004727 return os_snprintf(buf, buf_len, "OpenSSL build=%s run=%s",
4728 OPENSSL_VERSION_TEXT,
4729 OpenSSL_version(OPENSSL_VERSION));
4730#else
Dmitry Shmidtff787d52015-01-12 13:01:47 -08004731 return os_snprintf(buf, buf_len, "OpenSSL build=%s run=%s",
4732 OPENSSL_VERSION_TEXT,
4733 SSLeay_version(SSLEAY_VERSION));
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08004734#endif
Dmitry Shmidtff787d52015-01-12 13:01:47 -08004735}
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004736
4737
4738void tls_connection_set_success_data(struct tls_connection *conn,
4739 struct wpabuf *data)
4740{
4741 SSL_SESSION *sess;
4742 struct wpabuf *old;
4743
4744 if (tls_ex_idx_session < 0)
4745 goto fail;
4746 sess = SSL_get_session(conn->ssl);
4747 if (!sess)
4748 goto fail;
4749 old = SSL_SESSION_get_ex_data(sess, tls_ex_idx_session);
4750 if (old) {
4751 wpa_printf(MSG_DEBUG, "OpenSSL: Replacing old success data %p",
4752 old);
4753 wpabuf_free(old);
4754 }
4755 if (SSL_SESSION_set_ex_data(sess, tls_ex_idx_session, data) != 1)
4756 goto fail;
4757
4758 wpa_printf(MSG_DEBUG, "OpenSSL: Stored success data %p", data);
4759 conn->success_data = 1;
4760 return;
4761
4762fail:
4763 wpa_printf(MSG_INFO, "OpenSSL: Failed to store success data");
4764 wpabuf_free(data);
4765}
4766
4767
4768void tls_connection_set_success_data_resumed(struct tls_connection *conn)
4769{
4770 wpa_printf(MSG_DEBUG,
4771 "OpenSSL: Success data accepted for resumed session");
4772 conn->success_data = 1;
4773}
4774
4775
4776const struct wpabuf *
4777tls_connection_get_success_data(struct tls_connection *conn)
4778{
4779 SSL_SESSION *sess;
4780
4781 if (tls_ex_idx_session < 0 ||
4782 !(sess = SSL_get_session(conn->ssl)))
4783 return NULL;
4784 return SSL_SESSION_get_ex_data(sess, tls_ex_idx_session);
4785}
4786
4787
4788void tls_connection_remove_session(struct tls_connection *conn)
4789{
4790 SSL_SESSION *sess;
4791
4792 sess = SSL_get_session(conn->ssl);
4793 if (!sess)
4794 return;
4795
4796 if (SSL_CTX_remove_session(conn->ssl_ctx, sess) != 1)
4797 wpa_printf(MSG_DEBUG,
4798 "OpenSSL: Session was not cached");
4799 else
4800 wpa_printf(MSG_DEBUG,
4801 "OpenSSL: Removed cached session to disable session resumption");
4802}