blob: 7243d9fb95716d8bd7ddd74175a82ac425710eff [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 || \
62 defined(LIBRESSL_VERSION_NUMBER)) && \
63 !defined(BORINGSSL_API_VERSION)
Dmitry Shmidtde47be72016-01-07 12:52:55 -080064/*
65 * SSL_get_client_random() and SSL_get_server_random() were added in OpenSSL
Dmitry Shmidt849734c2016-05-27 09:59:01 -070066 * 1.1.0 and newer BoringSSL revisions. Provide compatibility wrappers for
67 * older versions.
Dmitry Shmidtde47be72016-01-07 12:52:55 -080068 */
69
70static size_t SSL_get_client_random(const SSL *ssl, unsigned char *out,
71 size_t outlen)
72{
73 if (!ssl->s3 || outlen < SSL3_RANDOM_SIZE)
74 return 0;
75 os_memcpy(out, ssl->s3->client_random, SSL3_RANDOM_SIZE);
76 return SSL3_RANDOM_SIZE;
77}
78
79
80static size_t SSL_get_server_random(const SSL *ssl, unsigned char *out,
81 size_t outlen)
82{
83 if (!ssl->s3 || outlen < SSL3_RANDOM_SIZE)
84 return 0;
85 os_memcpy(out, ssl->s3->server_random, SSL3_RANDOM_SIZE);
86 return SSL3_RANDOM_SIZE;
87}
88
89
Dmitry Shmidt849734c2016-05-27 09:59:01 -070090#ifdef OPENSSL_NEED_EAP_FAST_PRF
Dmitry Shmidtde47be72016-01-07 12:52:55 -080091static size_t SSL_SESSION_get_master_key(const SSL_SESSION *session,
92 unsigned char *out, size_t outlen)
93{
94 if (!session || session->master_key_length < 0 ||
95 (size_t) session->master_key_length > outlen)
96 return 0;
97 if ((size_t) session->master_key_length < outlen)
98 outlen = session->master_key_length;
99 os_memcpy(out, session->master_key, outlen);
100 return outlen;
101}
Dmitry Shmidt849734c2016-05-27 09:59:01 -0700102#endif /* OPENSSL_NEED_EAP_FAST_PRF */
Dmitry Shmidtde47be72016-01-07 12:52:55 -0800103
104#endif
105
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700106#if OPENSSL_VERSION_NUMBER < 0x10100000L
107#ifdef CONFIG_SUITEB
108static int RSA_bits(const RSA *r)
109{
110 return BN_num_bits(r->n);
111}
112#endif /* CONFIG_SUITEB */
113#endif
114
Dmitry Shmidtff079172013-11-08 14:10:30 -0800115#ifdef ANDROID
116#include <openssl/pem.h>
117#include <keystore/keystore_get.h>
118
Pavel Grafov4d8552e2018-02-06 11:28:29 +0000119#include <log/log.h>
120#include <log/log_event_list.h>
121
122#define CERT_VALIDATION_FAILURE 210033
123
124static void log_cert_validation_failure(const char *reason)
125{
126 android_log_context ctx = create_android_logger(CERT_VALIDATION_FAILURE);
127 android_log_write_string8(ctx, reason);
128 android_log_write_list(ctx, LOG_ID_SECURITY);
129 android_log_destroy(&ctx);
130}
131
132
Dmitry Shmidtff079172013-11-08 14:10:30 -0800133static BIO * BIO_from_keystore(const char *key)
134{
135 BIO *bio = NULL;
136 uint8_t *value = NULL;
137 int length = keystore_get(key, strlen(key), &value);
138 if (length != -1 && (bio = BIO_new(BIO_s_mem())) != NULL)
139 BIO_write(bio, value, length);
140 free(value);
141 return bio;
142}
Dmitry Shmidtb97e4282016-02-08 10:16:07 -0800143
144
145static int tls_add_ca_from_keystore(X509_STORE *ctx, const char *key_alias)
146{
147 BIO *bio = BIO_from_keystore(key_alias);
148 STACK_OF(X509_INFO) *stack = NULL;
149 stack_index_t i;
150
151 if (bio) {
152 stack = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL);
153 BIO_free(bio);
154 }
155
156 if (!stack) {
157 wpa_printf(MSG_WARNING, "TLS: Failed to parse certificate: %s",
158 key_alias);
159 return -1;
160 }
161
162 for (i = 0; i < sk_X509_INFO_num(stack); ++i) {
163 X509_INFO *info = sk_X509_INFO_value(stack, i);
164
165 if (info->x509)
166 X509_STORE_add_cert(ctx, info->x509);
167 if (info->crl)
168 X509_STORE_add_crl(ctx, info->crl);
169 }
170
171 sk_X509_INFO_pop_free(stack, X509_INFO_free);
172
173 return 0;
174}
175
176
177static int tls_add_ca_from_keystore_encoded(X509_STORE *ctx,
178 const char *encoded_key_alias)
179{
180 int rc = -1;
181 int len = os_strlen(encoded_key_alias);
182 unsigned char *decoded_alias;
183
184 if (len & 1) {
185 wpa_printf(MSG_WARNING, "Invalid hex-encoded alias: %s",
186 encoded_key_alias);
187 return rc;
188 }
189
190 decoded_alias = os_malloc(len / 2 + 1);
191 if (decoded_alias) {
192 if (!hexstr2bin(encoded_key_alias, decoded_alias, len / 2)) {
193 decoded_alias[len / 2] = '\0';
194 rc = tls_add_ca_from_keystore(
195 ctx, (const char *) decoded_alias);
196 }
197 os_free(decoded_alias);
198 }
199
200 return rc;
201}
202
Dmitry Shmidtff079172013-11-08 14:10:30 -0800203#endif /* ANDROID */
204
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700205static int tls_openssl_ref_count = 0;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800206static int tls_ex_idx_session = -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700207
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700208struct tls_context {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700209 void (*event_cb)(void *ctx, enum tls_event ev,
210 union tls_event_data *data);
211 void *cb_ctx;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800212 int cert_in_cb;
Dmitry Shmidt34af3062013-07-11 10:46:32 -0700213 char *ocsp_stapling_response;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700214};
215
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700216static struct tls_context *tls_global = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700217
218
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800219struct tls_data {
220 SSL_CTX *ssl;
221 unsigned int tls_session_lifetime;
222};
223
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700224struct tls_connection {
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700225 struct tls_context *context;
Dmitry Shmidt216983b2015-02-06 10:50:36 -0800226 SSL_CTX *ssl_ctx;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700227 SSL *ssl;
228 BIO *ssl_in, *ssl_out;
Adam Langley1eb02ed2015-04-21 19:00:05 -0700229#if defined(ANDROID) || !defined(OPENSSL_NO_ENGINE)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700230 ENGINE *engine; /* functional reference to the engine */
231 EVP_PKEY *private_key; /* the private key if using engine */
232#endif /* OPENSSL_NO_ENGINE */
Dmitry Shmidt2f74e362015-01-21 13:19:05 -0800233 char *subject_match, *altsubject_match, *suffix_match, *domain_match;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700234 int read_alerts, write_alerts, failed;
235
236 tls_session_ticket_cb session_ticket_cb;
237 void *session_ticket_cb_ctx;
238
239 /* SessionTicket received from OpenSSL hello_extension_cb (server) */
240 u8 *session_ticket;
241 size_t session_ticket_len;
242
243 unsigned int ca_cert_verify:1;
244 unsigned int cert_probe:1;
245 unsigned int server_cert_only:1;
Jouni Malinen26af48b2014-04-09 13:02:53 +0300246 unsigned int invalid_hb_used:1;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800247 unsigned int success_data:1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700248
249 u8 srv_cert_hash[32];
Dmitry Shmidtc55524a2011-07-07 11:18:38 -0700250
251 unsigned int flags;
Dmitry Shmidt34af3062013-07-11 10:46:32 -0700252
253 X509 *peer_cert;
254 X509 *peer_issuer;
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -0800255 X509 *peer_issuer_issuer;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800256
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800257 unsigned char client_random[SSL3_RANDOM_SIZE];
258 unsigned char server_random[SSL3_RANDOM_SIZE];
Dmitry Shmidtd2986c22017-10-23 14:22:09 -0700259
260 u16 cipher_suite;
261 int server_dh_prime_len;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700262};
263
264
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700265static struct tls_context * tls_context_new(const struct tls_config *conf)
266{
267 struct tls_context *context = os_zalloc(sizeof(*context));
268 if (context == NULL)
269 return NULL;
270 if (conf) {
271 context->event_cb = conf->event_cb;
272 context->cb_ctx = conf->cb_ctx;
273 context->cert_in_cb = conf->cert_in_cb;
274 }
275 return context;
276}
277
278
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700279#ifdef CONFIG_NO_STDOUT_DEBUG
280
281static void _tls_show_errors(void)
282{
283 unsigned long err;
284
285 while ((err = ERR_get_error())) {
286 /* Just ignore the errors, since stdout is disabled */
287 }
288}
289#define tls_show_errors(l, f, t) _tls_show_errors()
290
291#else /* CONFIG_NO_STDOUT_DEBUG */
292
293static void tls_show_errors(int level, const char *func, const char *txt)
294{
295 unsigned long err;
296
297 wpa_printf(level, "OpenSSL: %s - %s %s",
298 func, txt, ERR_error_string(ERR_get_error(), NULL));
299
300 while ((err = ERR_get_error())) {
301 wpa_printf(MSG_INFO, "OpenSSL: pending error: %s",
302 ERR_error_string(err, NULL));
303 }
304}
305
306#endif /* CONFIG_NO_STDOUT_DEBUG */
307
308
309#ifdef CONFIG_NATIVE_WINDOWS
310
311/* Windows CryptoAPI and access to certificate stores */
312#include <wincrypt.h>
313
314#ifdef __MINGW32_VERSION
315/*
316 * MinGW does not yet include all the needed definitions for CryptoAPI, so
317 * define here whatever extra is needed.
318 */
319#define CERT_SYSTEM_STORE_CURRENT_USER (1 << 16)
320#define CERT_STORE_READONLY_FLAG 0x00008000
321#define CERT_STORE_OPEN_EXISTING_FLAG 0x00004000
322
323#endif /* __MINGW32_VERSION */
324
325
326struct cryptoapi_rsa_data {
327 const CERT_CONTEXT *cert;
328 HCRYPTPROV crypt_prov;
329 DWORD key_spec;
330 BOOL free_crypt_prov;
331};
332
333
334static void cryptoapi_error(const char *msg)
335{
336 wpa_printf(MSG_INFO, "CryptoAPI: %s; err=%u",
337 msg, (unsigned int) GetLastError());
338}
339
340
341static int cryptoapi_rsa_pub_enc(int flen, const unsigned char *from,
342 unsigned char *to, RSA *rsa, int padding)
343{
344 wpa_printf(MSG_DEBUG, "%s - not implemented", __func__);
345 return 0;
346}
347
348
349static int cryptoapi_rsa_pub_dec(int flen, const unsigned char *from,
350 unsigned char *to, RSA *rsa, int padding)
351{
352 wpa_printf(MSG_DEBUG, "%s - not implemented", __func__);
353 return 0;
354}
355
356
357static int cryptoapi_rsa_priv_enc(int flen, const unsigned char *from,
358 unsigned char *to, RSA *rsa, int padding)
359{
360 struct cryptoapi_rsa_data *priv =
361 (struct cryptoapi_rsa_data *) rsa->meth->app_data;
362 HCRYPTHASH hash;
363 DWORD hash_size, len, i;
364 unsigned char *buf = NULL;
365 int ret = 0;
366
367 if (priv == NULL) {
368 RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,
369 ERR_R_PASSED_NULL_PARAMETER);
370 return 0;
371 }
372
373 if (padding != RSA_PKCS1_PADDING) {
374 RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,
375 RSA_R_UNKNOWN_PADDING_TYPE);
376 return 0;
377 }
378
379 if (flen != 16 /* MD5 */ + 20 /* SHA-1 */) {
380 wpa_printf(MSG_INFO, "%s - only MD5-SHA1 hash supported",
381 __func__);
382 RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,
383 RSA_R_INVALID_MESSAGE_LENGTH);
384 return 0;
385 }
386
387 if (!CryptCreateHash(priv->crypt_prov, CALG_SSL3_SHAMD5, 0, 0, &hash))
388 {
389 cryptoapi_error("CryptCreateHash failed");
390 return 0;
391 }
392
393 len = sizeof(hash_size);
394 if (!CryptGetHashParam(hash, HP_HASHSIZE, (BYTE *) &hash_size, &len,
395 0)) {
396 cryptoapi_error("CryptGetHashParam failed");
397 goto err;
398 }
399
400 if ((int) hash_size != flen) {
401 wpa_printf(MSG_INFO, "CryptoAPI: Invalid hash size (%u != %d)",
402 (unsigned) hash_size, flen);
403 RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,
404 RSA_R_INVALID_MESSAGE_LENGTH);
405 goto err;
406 }
407 if (!CryptSetHashParam(hash, HP_HASHVAL, (BYTE * ) from, 0)) {
408 cryptoapi_error("CryptSetHashParam failed");
409 goto err;
410 }
411
412 len = RSA_size(rsa);
413 buf = os_malloc(len);
414 if (buf == NULL) {
415 RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE);
416 goto err;
417 }
418
419 if (!CryptSignHash(hash, priv->key_spec, NULL, 0, buf, &len)) {
420 cryptoapi_error("CryptSignHash failed");
421 goto err;
422 }
423
424 for (i = 0; i < len; i++)
425 to[i] = buf[len - i - 1];
426 ret = len;
427
428err:
429 os_free(buf);
430 CryptDestroyHash(hash);
431
432 return ret;
433}
434
435
436static int cryptoapi_rsa_priv_dec(int flen, const unsigned char *from,
437 unsigned char *to, RSA *rsa, int padding)
438{
439 wpa_printf(MSG_DEBUG, "%s - not implemented", __func__);
440 return 0;
441}
442
443
444static void cryptoapi_free_data(struct cryptoapi_rsa_data *priv)
445{
446 if (priv == NULL)
447 return;
448 if (priv->crypt_prov && priv->free_crypt_prov)
449 CryptReleaseContext(priv->crypt_prov, 0);
450 if (priv->cert)
451 CertFreeCertificateContext(priv->cert);
452 os_free(priv);
453}
454
455
456static int cryptoapi_finish(RSA *rsa)
457{
458 cryptoapi_free_data((struct cryptoapi_rsa_data *) rsa->meth->app_data);
459 os_free((void *) rsa->meth);
460 rsa->meth = NULL;
461 return 1;
462}
463
464
465static const CERT_CONTEXT * cryptoapi_find_cert(const char *name, DWORD store)
466{
467 HCERTSTORE cs;
468 const CERT_CONTEXT *ret = NULL;
469
470 cs = CertOpenStore((LPCSTR) CERT_STORE_PROV_SYSTEM, 0, 0,
471 store | CERT_STORE_OPEN_EXISTING_FLAG |
472 CERT_STORE_READONLY_FLAG, L"MY");
473 if (cs == NULL) {
474 cryptoapi_error("Failed to open 'My system store'");
475 return NULL;
476 }
477
478 if (strncmp(name, "cert://", 7) == 0) {
479 unsigned short wbuf[255];
480 MultiByteToWideChar(CP_ACP, 0, name + 7, -1, wbuf, 255);
481 ret = CertFindCertificateInStore(cs, X509_ASN_ENCODING |
482 PKCS_7_ASN_ENCODING,
483 0, CERT_FIND_SUBJECT_STR,
484 wbuf, NULL);
485 } else if (strncmp(name, "hash://", 7) == 0) {
486 CRYPT_HASH_BLOB blob;
487 int len;
488 const char *hash = name + 7;
489 unsigned char *buf;
490
491 len = os_strlen(hash) / 2;
492 buf = os_malloc(len);
493 if (buf && hexstr2bin(hash, buf, len) == 0) {
494 blob.cbData = len;
495 blob.pbData = buf;
496 ret = CertFindCertificateInStore(cs,
497 X509_ASN_ENCODING |
498 PKCS_7_ASN_ENCODING,
499 0, CERT_FIND_HASH,
500 &blob, NULL);
501 }
502 os_free(buf);
503 }
504
505 CertCloseStore(cs, 0);
506
507 return ret;
508}
509
510
511static int tls_cryptoapi_cert(SSL *ssl, const char *name)
512{
513 X509 *cert = NULL;
514 RSA *rsa = NULL, *pub_rsa;
515 struct cryptoapi_rsa_data *priv;
516 RSA_METHOD *rsa_meth;
517
518 if (name == NULL ||
519 (strncmp(name, "cert://", 7) != 0 &&
520 strncmp(name, "hash://", 7) != 0))
521 return -1;
522
523 priv = os_zalloc(sizeof(*priv));
524 rsa_meth = os_zalloc(sizeof(*rsa_meth));
525 if (priv == NULL || rsa_meth == NULL) {
526 wpa_printf(MSG_WARNING, "CryptoAPI: Failed to allocate memory "
527 "for CryptoAPI RSA method");
528 os_free(priv);
529 os_free(rsa_meth);
530 return -1;
531 }
532
533 priv->cert = cryptoapi_find_cert(name, CERT_SYSTEM_STORE_CURRENT_USER);
534 if (priv->cert == NULL) {
535 priv->cert = cryptoapi_find_cert(
536 name, CERT_SYSTEM_STORE_LOCAL_MACHINE);
537 }
538 if (priv->cert == NULL) {
539 wpa_printf(MSG_INFO, "CryptoAPI: Could not find certificate "
540 "'%s'", name);
541 goto err;
542 }
543
Dmitry Shmidt216983b2015-02-06 10:50:36 -0800544 cert = d2i_X509(NULL,
545 (const unsigned char **) &priv->cert->pbCertEncoded,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700546 priv->cert->cbCertEncoded);
547 if (cert == NULL) {
548 wpa_printf(MSG_INFO, "CryptoAPI: Could not process X509 DER "
549 "encoding");
550 goto err;
551 }
552
553 if (!CryptAcquireCertificatePrivateKey(priv->cert,
554 CRYPT_ACQUIRE_COMPARE_KEY_FLAG,
555 NULL, &priv->crypt_prov,
556 &priv->key_spec,
557 &priv->free_crypt_prov)) {
558 cryptoapi_error("Failed to acquire a private key for the "
559 "certificate");
560 goto err;
561 }
562
563 rsa_meth->name = "Microsoft CryptoAPI RSA Method";
564 rsa_meth->rsa_pub_enc = cryptoapi_rsa_pub_enc;
565 rsa_meth->rsa_pub_dec = cryptoapi_rsa_pub_dec;
566 rsa_meth->rsa_priv_enc = cryptoapi_rsa_priv_enc;
567 rsa_meth->rsa_priv_dec = cryptoapi_rsa_priv_dec;
568 rsa_meth->finish = cryptoapi_finish;
569 rsa_meth->flags = RSA_METHOD_FLAG_NO_CHECK;
570 rsa_meth->app_data = (char *) priv;
571
572 rsa = RSA_new();
573 if (rsa == NULL) {
574 SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,
575 ERR_R_MALLOC_FAILURE);
576 goto err;
577 }
578
579 if (!SSL_use_certificate(ssl, cert)) {
580 RSA_free(rsa);
581 rsa = NULL;
582 goto err;
583 }
584 pub_rsa = cert->cert_info->key->pkey->pkey.rsa;
585 X509_free(cert);
586 cert = NULL;
587
588 rsa->n = BN_dup(pub_rsa->n);
589 rsa->e = BN_dup(pub_rsa->e);
590 if (!RSA_set_method(rsa, rsa_meth))
591 goto err;
592
593 if (!SSL_use_RSAPrivateKey(ssl, rsa))
594 goto err;
595 RSA_free(rsa);
596
597 return 0;
598
599err:
600 if (cert)
601 X509_free(cert);
602 if (rsa)
603 RSA_free(rsa);
604 else {
605 os_free(rsa_meth);
606 cryptoapi_free_data(priv);
607 }
608 return -1;
609}
610
611
612static int tls_cryptoapi_ca_cert(SSL_CTX *ssl_ctx, SSL *ssl, const char *name)
613{
614 HCERTSTORE cs;
615 PCCERT_CONTEXT ctx = NULL;
616 X509 *cert;
617 char buf[128];
618 const char *store;
619#ifdef UNICODE
620 WCHAR *wstore;
621#endif /* UNICODE */
622
623 if (name == NULL || strncmp(name, "cert_store://", 13) != 0)
624 return -1;
625
626 store = name + 13;
627#ifdef UNICODE
628 wstore = os_malloc((os_strlen(store) + 1) * sizeof(WCHAR));
629 if (wstore == NULL)
630 return -1;
631 wsprintf(wstore, L"%S", store);
632 cs = CertOpenSystemStore(0, wstore);
633 os_free(wstore);
634#else /* UNICODE */
635 cs = CertOpenSystemStore(0, store);
636#endif /* UNICODE */
637 if (cs == NULL) {
638 wpa_printf(MSG_DEBUG, "%s: failed to open system cert store "
639 "'%s': error=%d", __func__, store,
640 (int) GetLastError());
641 return -1;
642 }
643
644 while ((ctx = CertEnumCertificatesInStore(cs, ctx))) {
Dmitry Shmidt216983b2015-02-06 10:50:36 -0800645 cert = d2i_X509(NULL,
646 (const unsigned char **) &ctx->pbCertEncoded,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700647 ctx->cbCertEncoded);
648 if (cert == NULL) {
649 wpa_printf(MSG_INFO, "CryptoAPI: Could not process "
650 "X509 DER encoding for CA cert");
651 continue;
652 }
653
654 X509_NAME_oneline(X509_get_subject_name(cert), buf,
655 sizeof(buf));
656 wpa_printf(MSG_DEBUG, "OpenSSL: Loaded CA certificate for "
657 "system certificate store: subject='%s'", buf);
658
Dmitry Shmidt849734c2016-05-27 09:59:01 -0700659 if (!X509_STORE_add_cert(SSL_CTX_get_cert_store(ssl_ctx),
660 cert)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700661 tls_show_errors(MSG_WARNING, __func__,
662 "Failed to add ca_cert to OpenSSL "
663 "certificate store");
664 }
665
666 X509_free(cert);
667 }
668
669 if (!CertCloseStore(cs, 0)) {
670 wpa_printf(MSG_DEBUG, "%s: failed to close system cert store "
671 "'%s': error=%d", __func__, name + 13,
672 (int) GetLastError());
673 }
674
675 return 0;
676}
677
678
679#else /* CONFIG_NATIVE_WINDOWS */
680
681static int tls_cryptoapi_cert(SSL *ssl, const char *name)
682{
683 return -1;
684}
685
686#endif /* CONFIG_NATIVE_WINDOWS */
687
688
689static void ssl_info_cb(const SSL *ssl, int where, int ret)
690{
691 const char *str;
692 int w;
693
694 wpa_printf(MSG_DEBUG, "SSL: (where=0x%x ret=0x%x)", where, ret);
695 w = where & ~SSL_ST_MASK;
696 if (w & SSL_ST_CONNECT)
697 str = "SSL_connect";
698 else if (w & SSL_ST_ACCEPT)
699 str = "SSL_accept";
700 else
701 str = "undefined";
702
703 if (where & SSL_CB_LOOP) {
704 wpa_printf(MSG_DEBUG, "SSL: %s:%s",
705 str, SSL_state_string_long(ssl));
706 } else if (where & SSL_CB_ALERT) {
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700707 struct tls_connection *conn = SSL_get_app_data((SSL *) ssl);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700708 wpa_printf(MSG_INFO, "SSL: SSL3 alert: %s:%s:%s",
709 where & SSL_CB_READ ?
710 "read (remote end reported an error)" :
711 "write (local SSL3 detected an error)",
712 SSL_alert_type_string_long(ret),
713 SSL_alert_desc_string_long(ret));
714 if ((ret >> 8) == SSL3_AL_FATAL) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700715 if (where & SSL_CB_READ)
716 conn->read_alerts++;
717 else
718 conn->write_alerts++;
719 }
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700720 if (conn->context->event_cb != NULL) {
Dmitry Shmidt04949592012-07-19 12:16:46 -0700721 union tls_event_data ev;
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700722 struct tls_context *context = conn->context;
Dmitry Shmidt04949592012-07-19 12:16:46 -0700723 os_memset(&ev, 0, sizeof(ev));
724 ev.alert.is_local = !(where & SSL_CB_READ);
725 ev.alert.type = SSL_alert_type_string_long(ret);
726 ev.alert.description = SSL_alert_desc_string_long(ret);
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700727 context->event_cb(context->cb_ctx, TLS_ALERT, &ev);
Dmitry Shmidt04949592012-07-19 12:16:46 -0700728 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700729 } else if (where & SSL_CB_EXIT && ret <= 0) {
730 wpa_printf(MSG_DEBUG, "SSL: %s:%s in %s",
731 str, ret == 0 ? "failed" : "error",
732 SSL_state_string_long(ssl));
733 }
734}
735
736
737#ifndef OPENSSL_NO_ENGINE
738/**
739 * tls_engine_load_dynamic_generic - load any openssl engine
740 * @pre: an array of commands and values that load an engine initialized
741 * in the engine specific function
742 * @post: an array of commands and values that initialize an already loaded
743 * engine (or %NULL if not required)
744 * @id: the engine id of the engine to load (only required if post is not %NULL
745 *
746 * This function is a generic function that loads any openssl engine.
747 *
748 * Returns: 0 on success, -1 on failure
749 */
750static int tls_engine_load_dynamic_generic(const char *pre[],
751 const char *post[], const char *id)
752{
753 ENGINE *engine;
754 const char *dynamic_id = "dynamic";
755
756 engine = ENGINE_by_id(id);
757 if (engine) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700758 wpa_printf(MSG_DEBUG, "ENGINE: engine '%s' is already "
759 "available", id);
Dmitry Shmidtd5ab1b52016-06-21 12:38:41 -0700760 /*
761 * If it was auto-loaded by ENGINE_by_id() we might still
762 * need to tell it which PKCS#11 module to use in legacy
763 * (non-p11-kit) environments. Do so now; even if it was
764 * properly initialised before, setting it again will be
765 * harmless.
766 */
767 goto found;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700768 }
769 ERR_clear_error();
770
771 engine = ENGINE_by_id(dynamic_id);
772 if (engine == NULL) {
773 wpa_printf(MSG_INFO, "ENGINE: Can't find engine %s [%s]",
774 dynamic_id,
775 ERR_error_string(ERR_get_error(), NULL));
776 return -1;
777 }
778
779 /* Perform the pre commands. This will load the engine. */
780 while (pre && pre[0]) {
781 wpa_printf(MSG_DEBUG, "ENGINE: '%s' '%s'", pre[0], pre[1]);
782 if (ENGINE_ctrl_cmd_string(engine, pre[0], pre[1], 0) == 0) {
783 wpa_printf(MSG_INFO, "ENGINE: ctrl cmd_string failed: "
784 "%s %s [%s]", pre[0], pre[1],
785 ERR_error_string(ERR_get_error(), NULL));
786 ENGINE_free(engine);
787 return -1;
788 }
789 pre += 2;
790 }
791
792 /*
793 * Free the reference to the "dynamic" engine. The loaded engine can
794 * now be looked up using ENGINE_by_id().
795 */
796 ENGINE_free(engine);
797
798 engine = ENGINE_by_id(id);
799 if (engine == NULL) {
800 wpa_printf(MSG_INFO, "ENGINE: Can't find engine %s [%s]",
801 id, ERR_error_string(ERR_get_error(), NULL));
802 return -1;
803 }
Dmitry Shmidtd5ab1b52016-06-21 12:38:41 -0700804 found:
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700805 while (post && post[0]) {
806 wpa_printf(MSG_DEBUG, "ENGINE: '%s' '%s'", post[0], post[1]);
807 if (ENGINE_ctrl_cmd_string(engine, post[0], post[1], 0) == 0) {
808 wpa_printf(MSG_DEBUG, "ENGINE: ctrl cmd_string failed:"
809 " %s %s [%s]", post[0], post[1],
810 ERR_error_string(ERR_get_error(), NULL));
811 ENGINE_remove(engine);
812 ENGINE_free(engine);
813 return -1;
814 }
815 post += 2;
816 }
817 ENGINE_free(engine);
818
819 return 0;
820}
821
822
823/**
824 * tls_engine_load_dynamic_pkcs11 - load the pkcs11 engine provided by opensc
825 * @pkcs11_so_path: pksc11_so_path from the configuration
826 * @pcks11_module_path: pkcs11_module_path from the configuration
827 */
828static int tls_engine_load_dynamic_pkcs11(const char *pkcs11_so_path,
829 const char *pkcs11_module_path)
830{
831 char *engine_id = "pkcs11";
832 const char *pre_cmd[] = {
833 "SO_PATH", NULL /* pkcs11_so_path */,
834 "ID", NULL /* engine_id */,
835 "LIST_ADD", "1",
836 /* "NO_VCHECK", "1", */
837 "LOAD", NULL,
838 NULL, NULL
839 };
840 const char *post_cmd[] = {
841 "MODULE_PATH", NULL /* pkcs11_module_path */,
842 NULL, NULL
843 };
844
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800845 if (!pkcs11_so_path)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700846 return 0;
847
848 pre_cmd[1] = pkcs11_so_path;
849 pre_cmd[3] = engine_id;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800850 if (pkcs11_module_path)
851 post_cmd[1] = pkcs11_module_path;
852 else
853 post_cmd[0] = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700854
855 wpa_printf(MSG_DEBUG, "ENGINE: Loading pkcs11 Engine from %s",
856 pkcs11_so_path);
857
858 return tls_engine_load_dynamic_generic(pre_cmd, post_cmd, engine_id);
859}
860
861
862/**
863 * tls_engine_load_dynamic_opensc - load the opensc engine provided by opensc
864 * @opensc_so_path: opensc_so_path from the configuration
865 */
866static int tls_engine_load_dynamic_opensc(const char *opensc_so_path)
867{
868 char *engine_id = "opensc";
869 const char *pre_cmd[] = {
870 "SO_PATH", NULL /* opensc_so_path */,
871 "ID", NULL /* engine_id */,
872 "LIST_ADD", "1",
873 "LOAD", NULL,
874 NULL, NULL
875 };
876
877 if (!opensc_so_path)
878 return 0;
879
880 pre_cmd[1] = opensc_so_path;
881 pre_cmd[3] = engine_id;
882
883 wpa_printf(MSG_DEBUG, "ENGINE: Loading OpenSC Engine from %s",
884 opensc_so_path);
885
886 return tls_engine_load_dynamic_generic(pre_cmd, NULL, engine_id);
887}
888#endif /* OPENSSL_NO_ENGINE */
889
890
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800891static void remove_session_cb(SSL_CTX *ctx, SSL_SESSION *sess)
892{
893 struct wpabuf *buf;
894
895 if (tls_ex_idx_session < 0)
896 return;
897 buf = SSL_SESSION_get_ex_data(sess, tls_ex_idx_session);
898 if (!buf)
899 return;
900 wpa_printf(MSG_DEBUG,
901 "OpenSSL: Free application session data %p (sess %p)",
902 buf, sess);
903 wpabuf_free(buf);
904
905 SSL_SESSION_set_ex_data(sess, tls_ex_idx_session, NULL);
906}
907
908
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700909void * tls_init(const struct tls_config *conf)
910{
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800911 struct tls_data *data;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700912 SSL_CTX *ssl;
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700913 struct tls_context *context;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800914 const char *ciphers;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700915
916 if (tls_openssl_ref_count == 0) {
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700917 tls_global = context = tls_context_new(conf);
918 if (context == NULL)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700919 return NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700920#ifdef CONFIG_FIPS
921#ifdef OPENSSL_FIPS
922 if (conf && conf->fips_mode) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800923 static int fips_enabled = 0;
924
925 if (!fips_enabled && !FIPS_mode_set(1)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700926 wpa_printf(MSG_ERROR, "Failed to enable FIPS "
927 "mode");
928 ERR_load_crypto_strings();
929 ERR_print_errors_fp(stderr);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700930 os_free(tls_global);
931 tls_global = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700932 return NULL;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800933 } else {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700934 wpa_printf(MSG_INFO, "Running in FIPS mode");
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800935 fips_enabled = 1;
936 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700937 }
938#else /* OPENSSL_FIPS */
939 if (conf && conf->fips_mode) {
940 wpa_printf(MSG_ERROR, "FIPS mode requested, but not "
941 "supported");
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700942 os_free(tls_global);
943 tls_global = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700944 return NULL;
945 }
946#endif /* OPENSSL_FIPS */
947#endif /* CONFIG_FIPS */
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800948#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700949 SSL_load_error_strings();
950 SSL_library_init();
Dmitry Shmidt216983b2015-02-06 10:50:36 -0800951#ifndef OPENSSL_NO_SHA256
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700952 EVP_add_digest(EVP_sha256());
953#endif /* OPENSSL_NO_SHA256 */
954 /* TODO: if /dev/urandom is available, PRNG is seeded
955 * automatically. If this is not the case, random data should
956 * be added here. */
957
958#ifdef PKCS12_FUNCS
959#ifndef OPENSSL_NO_RC2
960 /*
961 * 40-bit RC2 is commonly used in PKCS#12 files, so enable it.
962 * This is enabled by PKCS12_PBE_add() in OpenSSL 0.9.8
963 * versions, but it looks like OpenSSL 1.0.0 does not do that
964 * anymore.
965 */
966 EVP_add_cipher(EVP_rc2_40_cbc());
967#endif /* OPENSSL_NO_RC2 */
968 PKCS12_PBE_add();
969#endif /* PKCS12_FUNCS */
Dmitry Shmidt57c2d392016-02-23 13:40:19 -0800970#endif /* < 1.1.0 */
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700971 } else {
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700972 context = tls_context_new(conf);
973 if (context == NULL)
974 return NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700975 }
976 tls_openssl_ref_count++;
977
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800978 data = os_zalloc(sizeof(*data));
979 if (data)
980 ssl = SSL_CTX_new(SSLv23_method());
981 else
982 ssl = NULL;
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700983 if (ssl == NULL) {
984 tls_openssl_ref_count--;
Dmitry Shmidt68d0e3e2013-10-28 17:59:21 -0700985 if (context != tls_global)
986 os_free(context);
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700987 if (tls_openssl_ref_count == 0) {
988 os_free(tls_global);
989 tls_global = NULL;
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700990 }
Dmitry Shmidt57c2d392016-02-23 13:40:19 -0800991 os_free(data);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700992 return NULL;
Dmitry Shmidtea69e842013-05-13 14:52:28 -0700993 }
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800994 data->ssl = ssl;
995 if (conf)
996 data->tls_session_lifetime = conf->tls_session_lifetime;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700997
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800998 SSL_CTX_set_options(ssl, SSL_OP_NO_SSLv2);
999 SSL_CTX_set_options(ssl, SSL_OP_NO_SSLv3);
1000
Dmitry Shmidt29333592017-01-09 12:27:11 -08001001#ifdef SSL_MODE_NO_AUTO_CHAIN
1002 /* Number of deployed use cases assume the default OpenSSL behavior of
1003 * auto chaining the local certificate is in use. BoringSSL removed this
1004 * functionality by default, so we need to restore it here to avoid
1005 * breaking existing use cases. */
1006 SSL_CTX_clear_mode(ssl, SSL_MODE_NO_AUTO_CHAIN);
1007#endif /* SSL_MODE_NO_AUTO_CHAIN */
1008
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001009 SSL_CTX_set_info_callback(ssl, ssl_info_cb);
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001010 SSL_CTX_set_app_data(ssl, context);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001011 if (data->tls_session_lifetime > 0) {
1012 SSL_CTX_set_quiet_shutdown(ssl, 1);
1013 /*
1014 * Set default context here. In practice, this will be replaced
1015 * by the per-EAP method context in tls_connection_set_verify().
1016 */
1017 SSL_CTX_set_session_id_context(ssl, (u8 *) "hostapd", 7);
1018 SSL_CTX_set_session_cache_mode(ssl, SSL_SESS_CACHE_SERVER);
1019 SSL_CTX_set_timeout(ssl, data->tls_session_lifetime);
1020 SSL_CTX_sess_set_remove_cb(ssl, remove_session_cb);
1021 } else {
1022 SSL_CTX_set_session_cache_mode(ssl, SSL_SESS_CACHE_OFF);
1023 }
1024
1025 if (tls_ex_idx_session < 0) {
1026 tls_ex_idx_session = SSL_SESSION_get_ex_new_index(
1027 0, NULL, NULL, NULL, NULL);
1028 if (tls_ex_idx_session < 0) {
1029 tls_deinit(data);
1030 return NULL;
1031 }
1032 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001033
1034#ifndef OPENSSL_NO_ENGINE
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001035 wpa_printf(MSG_DEBUG, "ENGINE: Loading dynamic engine");
1036 ERR_load_ENGINE_strings();
1037 ENGINE_load_dynamic();
1038
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001039 if (conf &&
1040 (conf->opensc_engine_path || conf->pkcs11_engine_path ||
1041 conf->pkcs11_module_path)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001042 if (tls_engine_load_dynamic_opensc(conf->opensc_engine_path) ||
1043 tls_engine_load_dynamic_pkcs11(conf->pkcs11_engine_path,
1044 conf->pkcs11_module_path)) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001045 tls_deinit(data);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001046 return NULL;
1047 }
1048 }
1049#endif /* OPENSSL_NO_ENGINE */
1050
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001051 if (conf && conf->openssl_ciphers)
1052 ciphers = conf->openssl_ciphers;
1053 else
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001054 ciphers = TLS_DEFAULT_CIPHERS;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001055 if (SSL_CTX_set_cipher_list(ssl, ciphers) != 1) {
1056 wpa_printf(MSG_ERROR,
1057 "OpenSSL: Failed to set cipher string '%s'",
1058 ciphers);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001059 tls_deinit(data);
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001060 return NULL;
1061 }
1062
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001063 return data;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001064}
1065
1066
1067void tls_deinit(void *ssl_ctx)
1068{
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001069 struct tls_data *data = ssl_ctx;
1070 SSL_CTX *ssl = data->ssl;
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001071 struct tls_context *context = SSL_CTX_get_app_data(ssl);
1072 if (context != tls_global)
1073 os_free(context);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001074 if (data->tls_session_lifetime > 0)
1075 SSL_CTX_flush_sessions(ssl, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001076 SSL_CTX_free(ssl);
1077
1078 tls_openssl_ref_count--;
1079 if (tls_openssl_ref_count == 0) {
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001080#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001081#ifndef OPENSSL_NO_ENGINE
1082 ENGINE_cleanup();
1083#endif /* OPENSSL_NO_ENGINE */
1084 CRYPTO_cleanup_all_ex_data();
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -07001085 ERR_remove_thread_state(NULL);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001086 ERR_free_strings();
1087 EVP_cleanup();
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08001088#endif /* < 1.1.0 */
Dmitry Shmidt34af3062013-07-11 10:46:32 -07001089 os_free(tls_global->ocsp_stapling_response);
1090 tls_global->ocsp_stapling_response = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001091 os_free(tls_global);
1092 tls_global = NULL;
1093 }
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001094
1095 os_free(data);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001096}
1097
1098
Dmitry Shmidt1d755d02015-04-28 10:34:29 -07001099#ifndef OPENSSL_NO_ENGINE
1100
1101/* Cryptoki return values */
1102#define CKR_PIN_INCORRECT 0x000000a0
1103#define CKR_PIN_INVALID 0x000000a1
1104#define CKR_PIN_LEN_RANGE 0x000000a2
1105
1106/* libp11 */
1107#define ERR_LIB_PKCS11 ERR_LIB_USER
1108
1109static int tls_is_pin_error(unsigned int err)
1110{
1111 return ERR_GET_LIB(err) == ERR_LIB_PKCS11 &&
1112 (ERR_GET_REASON(err) == CKR_PIN_INCORRECT ||
1113 ERR_GET_REASON(err) == CKR_PIN_INVALID ||
1114 ERR_GET_REASON(err) == CKR_PIN_LEN_RANGE);
1115}
1116
1117#endif /* OPENSSL_NO_ENGINE */
1118
1119
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001120#ifdef ANDROID
1121/* EVP_PKEY_from_keystore comes from system/security/keystore-engine. */
1122EVP_PKEY * EVP_PKEY_from_keystore(const char *key_id);
1123#endif /* ANDROID */
1124
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001125static int tls_engine_init(struct tls_connection *conn, const char *engine_id,
1126 const char *pin, const char *key_id,
1127 const char *cert_id, const char *ca_cert_id)
1128{
Adam Langley1eb02ed2015-04-21 19:00:05 -07001129#if defined(ANDROID) && defined(OPENSSL_IS_BORINGSSL)
1130#if !defined(OPENSSL_NO_ENGINE)
1131#error "This code depends on OPENSSL_NO_ENGINE being defined by BoringSSL."
1132#endif
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001133 if (!key_id)
1134 return TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED;
Adam Langley1eb02ed2015-04-21 19:00:05 -07001135 conn->engine = NULL;
1136 conn->private_key = EVP_PKEY_from_keystore(key_id);
1137 if (!conn->private_key) {
1138 wpa_printf(MSG_ERROR,
1139 "ENGINE: cannot load private key with id '%s' [%s]",
1140 key_id,
1141 ERR_error_string(ERR_get_error(), NULL));
1142 return TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED;
1143 }
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001144#endif /* ANDROID && OPENSSL_IS_BORINGSSL */
Adam Langley1eb02ed2015-04-21 19:00:05 -07001145
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001146#ifndef OPENSSL_NO_ENGINE
1147 int ret = -1;
1148 if (engine_id == NULL) {
1149 wpa_printf(MSG_ERROR, "ENGINE: Engine ID not set");
1150 return -1;
1151 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001152
1153 ERR_clear_error();
Kenny Rootdb3c5a42012-03-20 17:00:47 -07001154#ifdef ANDROID
1155 ENGINE_load_dynamic();
1156#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001157 conn->engine = ENGINE_by_id(engine_id);
1158 if (!conn->engine) {
1159 wpa_printf(MSG_ERROR, "ENGINE: engine %s not available [%s]",
1160 engine_id, ERR_error_string(ERR_get_error(), NULL));
1161 goto err;
1162 }
1163 if (ENGINE_init(conn->engine) != 1) {
1164 wpa_printf(MSG_ERROR, "ENGINE: engine init failed "
1165 "(engine: %s) [%s]", engine_id,
1166 ERR_error_string(ERR_get_error(), NULL));
1167 goto err;
1168 }
1169 wpa_printf(MSG_DEBUG, "ENGINE: engine initialized");
1170
Kenny Rootdb3c5a42012-03-20 17:00:47 -07001171#ifndef ANDROID
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001172 if (pin && ENGINE_ctrl_cmd_string(conn->engine, "PIN", pin, 0) == 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001173 wpa_printf(MSG_ERROR, "ENGINE: cannot set pin [%s]",
1174 ERR_error_string(ERR_get_error(), NULL));
1175 goto err;
1176 }
Kenny Rootdb3c5a42012-03-20 17:00:47 -07001177#endif
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001178 if (key_id) {
1179 /*
1180 * Ensure that the ENGINE does not attempt to use the OpenSSL
1181 * UI system to obtain a PIN, if we didn't provide one.
1182 */
1183 struct {
1184 const void *password;
1185 const char *prompt_info;
1186 } key_cb = { "", NULL };
1187
1188 /* load private key first in-case PIN is required for cert */
1189 conn->private_key = ENGINE_load_private_key(conn->engine,
1190 key_id, NULL,
1191 &key_cb);
1192 if (!conn->private_key) {
Dmitry Shmidt1d755d02015-04-28 10:34:29 -07001193 unsigned long err = ERR_get_error();
1194
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001195 wpa_printf(MSG_ERROR,
1196 "ENGINE: cannot load private key with id '%s' [%s]",
1197 key_id,
Dmitry Shmidt1d755d02015-04-28 10:34:29 -07001198 ERR_error_string(err, NULL));
1199 if (tls_is_pin_error(err))
1200 ret = TLS_SET_PARAMS_ENGINE_PRV_BAD_PIN;
1201 else
1202 ret = TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001203 goto err;
1204 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001205 }
1206
1207 /* handle a certificate and/or CA certificate */
1208 if (cert_id || ca_cert_id) {
1209 const char *cmd_name = "LOAD_CERT_CTRL";
1210
1211 /* test if the engine supports a LOAD_CERT_CTRL */
1212 if (!ENGINE_ctrl(conn->engine, ENGINE_CTRL_GET_CMD_FROM_NAME,
1213 0, (void *)cmd_name, NULL)) {
1214 wpa_printf(MSG_ERROR, "ENGINE: engine does not support"
1215 " loading certificates");
1216 ret = TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED;
1217 goto err;
1218 }
1219 }
1220
1221 return 0;
1222
1223err:
1224 if (conn->engine) {
1225 ENGINE_free(conn->engine);
1226 conn->engine = NULL;
1227 }
1228
1229 if (conn->private_key) {
1230 EVP_PKEY_free(conn->private_key);
1231 conn->private_key = NULL;
1232 }
1233
1234 return ret;
1235#else /* OPENSSL_NO_ENGINE */
1236 return 0;
1237#endif /* OPENSSL_NO_ENGINE */
1238}
1239
1240
1241static void tls_engine_deinit(struct tls_connection *conn)
1242{
Adam Langley1eb02ed2015-04-21 19:00:05 -07001243#if defined(ANDROID) || !defined(OPENSSL_NO_ENGINE)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001244 wpa_printf(MSG_DEBUG, "ENGINE: engine deinit");
1245 if (conn->private_key) {
1246 EVP_PKEY_free(conn->private_key);
1247 conn->private_key = NULL;
1248 }
1249 if (conn->engine) {
Adam Langley1eb02ed2015-04-21 19:00:05 -07001250#if !defined(OPENSSL_IS_BORINGSSL)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001251 ENGINE_finish(conn->engine);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001252#endif /* !OPENSSL_IS_BORINGSSL */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001253 conn->engine = NULL;
1254 }
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001255#endif /* ANDROID || !OPENSSL_NO_ENGINE */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001256}
1257
1258
1259int tls_get_errors(void *ssl_ctx)
1260{
1261 int count = 0;
1262 unsigned long err;
1263
1264 while ((err = ERR_get_error())) {
1265 wpa_printf(MSG_INFO, "TLS - SSL error: %s",
1266 ERR_error_string(err, NULL));
1267 count++;
1268 }
1269
1270 return count;
1271}
1272
Jouni Malinen26af48b2014-04-09 13:02:53 +03001273
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001274static const char * openssl_content_type(int content_type)
1275{
1276 switch (content_type) {
1277 case 20:
1278 return "change cipher spec";
1279 case 21:
1280 return "alert";
1281 case 22:
1282 return "handshake";
1283 case 23:
1284 return "application data";
1285 case 24:
1286 return "heartbeat";
1287 case 256:
1288 return "TLS header info"; /* pseudo content type */
1289 default:
1290 return "?";
1291 }
1292}
1293
1294
1295static const char * openssl_handshake_type(int content_type, const u8 *buf,
1296 size_t len)
1297{
1298 if (content_type != 22 || !buf || len == 0)
1299 return "";
1300 switch (buf[0]) {
1301 case 0:
1302 return "hello request";
1303 case 1:
1304 return "client hello";
1305 case 2:
1306 return "server hello";
1307 case 4:
1308 return "new session ticket";
1309 case 11:
1310 return "certificate";
1311 case 12:
1312 return "server key exchange";
1313 case 13:
1314 return "certificate request";
1315 case 14:
1316 return "server hello done";
1317 case 15:
1318 return "certificate verify";
1319 case 16:
1320 return "client key exchange";
1321 case 20:
1322 return "finished";
1323 case 21:
1324 return "certificate url";
1325 case 22:
1326 return "certificate status";
1327 default:
1328 return "?";
1329 }
1330}
1331
1332
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001333#ifdef CONFIG_SUITEB
1334
1335static void check_server_hello(struct tls_connection *conn,
1336 const u8 *pos, const u8 *end)
1337{
1338 size_t payload_len, id_len;
1339
1340 /*
1341 * Parse ServerHello to get the selected cipher suite since OpenSSL does
1342 * not make it cleanly available during handshake and we need to know
1343 * whether DHE was selected.
1344 */
1345
1346 if (end - pos < 3)
1347 return;
1348 payload_len = WPA_GET_BE24(pos);
1349 pos += 3;
1350
1351 if ((size_t) (end - pos) < payload_len)
1352 return;
1353 end = pos + payload_len;
1354
1355 /* Skip Version and Random */
1356 if (end - pos < 2 + SSL3_RANDOM_SIZE)
1357 return;
1358 pos += 2 + SSL3_RANDOM_SIZE;
1359
1360 /* Skip Session ID */
1361 if (end - pos < 1)
1362 return;
1363 id_len = *pos++;
1364 if ((size_t) (end - pos) < id_len)
1365 return;
1366 pos += id_len;
1367
1368 if (end - pos < 2)
1369 return;
1370 conn->cipher_suite = WPA_GET_BE16(pos);
1371 wpa_printf(MSG_DEBUG, "OpenSSL: Server selected cipher suite 0x%x",
1372 conn->cipher_suite);
1373}
1374
1375
1376static void check_server_key_exchange(SSL *ssl, struct tls_connection *conn,
1377 const u8 *pos, const u8 *end)
1378{
1379 size_t payload_len;
1380 u16 dh_len;
1381 BIGNUM *p;
1382 int bits;
1383
1384 if (!(conn->flags & TLS_CONN_SUITEB))
1385 return;
1386
1387 /* DHE is enabled only with DHE-RSA-AES256-GCM-SHA384 */
1388 if (conn->cipher_suite != 0x9f)
1389 return;
1390
1391 if (end - pos < 3)
1392 return;
1393 payload_len = WPA_GET_BE24(pos);
1394 pos += 3;
1395
1396 if ((size_t) (end - pos) < payload_len)
1397 return;
1398 end = pos + payload_len;
1399
1400 if (end - pos < 2)
1401 return;
1402 dh_len = WPA_GET_BE16(pos);
1403 pos += 2;
1404
1405 if ((size_t) (end - pos) < dh_len)
1406 return;
1407 p = BN_bin2bn(pos, dh_len, NULL);
1408 if (!p)
1409 return;
1410
1411 bits = BN_num_bits(p);
1412 BN_free(p);
1413
1414 conn->server_dh_prime_len = bits;
1415 wpa_printf(MSG_DEBUG, "OpenSSL: Server DH prime length: %d bits",
1416 conn->server_dh_prime_len);
1417}
1418
1419#endif /* CONFIG_SUITEB */
1420
1421
Jouni Malinen26af48b2014-04-09 13:02:53 +03001422static void tls_msg_cb(int write_p, int version, int content_type,
1423 const void *buf, size_t len, SSL *ssl, void *arg)
1424{
1425 struct tls_connection *conn = arg;
1426 const u8 *pos = buf;
1427
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001428 if (write_p == 2) {
1429 wpa_printf(MSG_DEBUG,
1430 "OpenSSL: session ver=0x%x content_type=%d",
1431 version, content_type);
1432 wpa_hexdump_key(MSG_MSGDUMP, "OpenSSL: Data", buf, len);
1433 return;
1434 }
1435
1436 wpa_printf(MSG_DEBUG, "OpenSSL: %s ver=0x%x content_type=%d (%s/%s)",
1437 write_p ? "TX" : "RX", version, content_type,
1438 openssl_content_type(content_type),
1439 openssl_handshake_type(content_type, buf, len));
Jouni Malinen26af48b2014-04-09 13:02:53 +03001440 wpa_hexdump_key(MSG_MSGDUMP, "OpenSSL: Message", buf, len);
1441 if (content_type == 24 && len >= 3 && pos[0] == 1) {
1442 size_t payload_len = WPA_GET_BE16(pos + 1);
1443 if (payload_len + 3 > len) {
1444 wpa_printf(MSG_ERROR, "OpenSSL: Heartbeat attack detected");
1445 conn->invalid_hb_used = 1;
1446 }
1447 }
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07001448
1449#ifdef CONFIG_SUITEB
1450 /*
1451 * Need to parse these handshake messages to be able to check DH prime
1452 * length since OpenSSL does not expose the new cipher suite and DH
1453 * parameters during handshake (e.g., for cert_cb() callback).
1454 */
1455 if (content_type == 22 && pos && len > 0 && pos[0] == 2)
1456 check_server_hello(conn, pos + 1, pos + len);
1457 if (content_type == 22 && pos && len > 0 && pos[0] == 12)
1458 check_server_key_exchange(ssl, conn, pos + 1, pos + len);
1459#endif /* CONFIG_SUITEB */
Jouni Malinen26af48b2014-04-09 13:02:53 +03001460}
1461
1462
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001463struct tls_connection * tls_connection_init(void *ssl_ctx)
1464{
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001465 struct tls_data *data = ssl_ctx;
1466 SSL_CTX *ssl = data->ssl;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001467 struct tls_connection *conn;
1468 long options;
Dmitry Shmidt7d5c8f22014-03-03 13:53:28 -08001469 struct tls_context *context = SSL_CTX_get_app_data(ssl);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001470
1471 conn = os_zalloc(sizeof(*conn));
1472 if (conn == NULL)
1473 return NULL;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001474 conn->ssl_ctx = ssl;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001475 conn->ssl = SSL_new(ssl);
1476 if (conn->ssl == NULL) {
1477 tls_show_errors(MSG_INFO, __func__,
1478 "Failed to initialize new SSL connection");
1479 os_free(conn);
1480 return NULL;
1481 }
1482
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001483 conn->context = context;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001484 SSL_set_app_data(conn->ssl, conn);
Jouni Malinen26af48b2014-04-09 13:02:53 +03001485 SSL_set_msg_callback(conn->ssl, tls_msg_cb);
1486 SSL_set_msg_callback_arg(conn->ssl, conn);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001487 options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
1488 SSL_OP_SINGLE_DH_USE;
1489#ifdef SSL_OP_NO_COMPRESSION
1490 options |= SSL_OP_NO_COMPRESSION;
1491#endif /* SSL_OP_NO_COMPRESSION */
1492 SSL_set_options(conn->ssl, options);
1493
1494 conn->ssl_in = BIO_new(BIO_s_mem());
1495 if (!conn->ssl_in) {
1496 tls_show_errors(MSG_INFO, __func__,
1497 "Failed to create a new BIO for ssl_in");
1498 SSL_free(conn->ssl);
1499 os_free(conn);
1500 return NULL;
1501 }
1502
1503 conn->ssl_out = BIO_new(BIO_s_mem());
1504 if (!conn->ssl_out) {
1505 tls_show_errors(MSG_INFO, __func__,
1506 "Failed to create a new BIO for ssl_out");
1507 SSL_free(conn->ssl);
1508 BIO_free(conn->ssl_in);
1509 os_free(conn);
1510 return NULL;
1511 }
1512
1513 SSL_set_bio(conn->ssl, conn->ssl_in, conn->ssl_out);
1514
1515 return conn;
1516}
1517
1518
1519void tls_connection_deinit(void *ssl_ctx, struct tls_connection *conn)
1520{
1521 if (conn == NULL)
1522 return;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001523 if (conn->success_data) {
1524 /*
1525 * Make sure ssl_clear_bad_session() does not remove this
1526 * session.
1527 */
1528 SSL_set_quiet_shutdown(conn->ssl, 1);
1529 SSL_shutdown(conn->ssl);
1530 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001531 SSL_free(conn->ssl);
1532 tls_engine_deinit(conn);
1533 os_free(conn->subject_match);
1534 os_free(conn->altsubject_match);
Dmitry Shmidt051af732013-10-22 13:52:46 -07001535 os_free(conn->suffix_match);
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001536 os_free(conn->domain_match);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001537 os_free(conn->session_ticket);
1538 os_free(conn);
1539}
1540
1541
1542int tls_connection_established(void *ssl_ctx, struct tls_connection *conn)
1543{
1544 return conn ? SSL_is_init_finished(conn->ssl) : 0;
1545}
1546
1547
1548int tls_connection_shutdown(void *ssl_ctx, struct tls_connection *conn)
1549{
1550 if (conn == NULL)
1551 return -1;
1552
1553 /* Shutdown previous TLS connection without notifying the peer
1554 * because the connection was already terminated in practice
1555 * and "close notify" shutdown alert would confuse AS. */
1556 SSL_set_quiet_shutdown(conn->ssl, 1);
1557 SSL_shutdown(conn->ssl);
Jouni Malinenf291c682015-08-17 22:50:41 +03001558 return SSL_clear(conn->ssl) == 1 ? 0 : -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001559}
1560
1561
1562static int tls_match_altsubject_component(X509 *cert, int type,
1563 const char *value, size_t len)
1564{
1565 GENERAL_NAME *gen;
1566 void *ext;
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -07001567 int found = 0;
1568 stack_index_t i;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001569
1570 ext = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
1571
1572 for (i = 0; ext && i < sk_GENERAL_NAME_num(ext); i++) {
1573 gen = sk_GENERAL_NAME_value(ext, i);
1574 if (gen->type != type)
1575 continue;
1576 if (os_strlen((char *) gen->d.ia5->data) == len &&
1577 os_memcmp(value, gen->d.ia5->data, len) == 0)
1578 found++;
1579 }
1580
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08001581 sk_GENERAL_NAME_pop_free(ext, GENERAL_NAME_free);
1582
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001583 return found;
1584}
1585
1586
1587static int tls_match_altsubject(X509 *cert, const char *match)
1588{
1589 int type;
1590 const char *pos, *end;
1591 size_t len;
1592
1593 pos = match;
1594 do {
1595 if (os_strncmp(pos, "EMAIL:", 6) == 0) {
1596 type = GEN_EMAIL;
1597 pos += 6;
1598 } else if (os_strncmp(pos, "DNS:", 4) == 0) {
1599 type = GEN_DNS;
1600 pos += 4;
1601 } else if (os_strncmp(pos, "URI:", 4) == 0) {
1602 type = GEN_URI;
1603 pos += 4;
1604 } else {
1605 wpa_printf(MSG_INFO, "TLS: Invalid altSubjectName "
1606 "match '%s'", pos);
1607 return 0;
1608 }
1609 end = os_strchr(pos, ';');
1610 while (end) {
1611 if (os_strncmp(end + 1, "EMAIL:", 6) == 0 ||
1612 os_strncmp(end + 1, "DNS:", 4) == 0 ||
1613 os_strncmp(end + 1, "URI:", 4) == 0)
1614 break;
1615 end = os_strchr(end + 1, ';');
1616 }
1617 if (end)
1618 len = end - pos;
1619 else
1620 len = os_strlen(pos);
1621 if (tls_match_altsubject_component(cert, type, pos, len) > 0)
1622 return 1;
1623 pos = end + 1;
1624 } while (end);
1625
1626 return 0;
1627}
1628
1629
Dmitry Shmidtfa3fc4a2013-11-21 13:34:38 -08001630#ifndef CONFIG_NATIVE_WINDOWS
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001631static int domain_suffix_match(const u8 *val, size_t len, const char *match,
1632 int full)
Dmitry Shmidt051af732013-10-22 13:52:46 -07001633{
1634 size_t i, match_len;
1635
1636 /* Check for embedded nuls that could mess up suffix matching */
1637 for (i = 0; i < len; i++) {
1638 if (val[i] == '\0') {
1639 wpa_printf(MSG_DEBUG, "TLS: Embedded null in a string - reject");
1640 return 0;
1641 }
1642 }
1643
1644 match_len = os_strlen(match);
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001645 if (match_len > len || (full && match_len != len))
Dmitry Shmidt051af732013-10-22 13:52:46 -07001646 return 0;
1647
1648 if (os_strncasecmp((const char *) val + len - match_len, match,
1649 match_len) != 0)
1650 return 0; /* no match */
1651
1652 if (match_len == len)
1653 return 1; /* exact match */
1654
1655 if (val[len - match_len - 1] == '.')
1656 return 1; /* full label match completes suffix match */
1657
1658 wpa_printf(MSG_DEBUG, "TLS: Reject due to incomplete label match");
1659 return 0;
1660}
Dmitry Shmidtfa3fc4a2013-11-21 13:34:38 -08001661#endif /* CONFIG_NATIVE_WINDOWS */
Dmitry Shmidt051af732013-10-22 13:52:46 -07001662
1663
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001664static int tls_match_suffix(X509 *cert, const char *match, int full)
Dmitry Shmidt051af732013-10-22 13:52:46 -07001665{
Dmitry Shmidtfa3fc4a2013-11-21 13:34:38 -08001666#ifdef CONFIG_NATIVE_WINDOWS
1667 /* wincrypt.h has conflicting X509_NAME definition */
1668 return -1;
1669#else /* CONFIG_NATIVE_WINDOWS */
Dmitry Shmidt051af732013-10-22 13:52:46 -07001670 GENERAL_NAME *gen;
1671 void *ext;
1672 int i;
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -07001673 stack_index_t j;
Dmitry Shmidt051af732013-10-22 13:52:46 -07001674 int dns_name = 0;
1675 X509_NAME *name;
1676
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001677 wpa_printf(MSG_DEBUG, "TLS: Match domain against %s%s",
1678 full ? "": "suffix ", match);
Dmitry Shmidt051af732013-10-22 13:52:46 -07001679
1680 ext = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
1681
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -07001682 for (j = 0; ext && j < sk_GENERAL_NAME_num(ext); j++) {
1683 gen = sk_GENERAL_NAME_value(ext, j);
Dmitry Shmidt051af732013-10-22 13:52:46 -07001684 if (gen->type != GEN_DNS)
1685 continue;
1686 dns_name++;
1687 wpa_hexdump_ascii(MSG_DEBUG, "TLS: Certificate dNSName",
1688 gen->d.dNSName->data,
1689 gen->d.dNSName->length);
1690 if (domain_suffix_match(gen->d.dNSName->data,
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001691 gen->d.dNSName->length, match, full) ==
1692 1) {
1693 wpa_printf(MSG_DEBUG, "TLS: %s in dNSName found",
1694 full ? "Match" : "Suffix match");
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08001695 sk_GENERAL_NAME_pop_free(ext, GENERAL_NAME_free);
Dmitry Shmidt051af732013-10-22 13:52:46 -07001696 return 1;
1697 }
1698 }
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08001699 sk_GENERAL_NAME_pop_free(ext, GENERAL_NAME_free);
Dmitry Shmidt051af732013-10-22 13:52:46 -07001700
1701 if (dns_name) {
1702 wpa_printf(MSG_DEBUG, "TLS: None of the dNSName(s) matched");
1703 return 0;
1704 }
1705
1706 name = X509_get_subject_name(cert);
1707 i = -1;
1708 for (;;) {
1709 X509_NAME_ENTRY *e;
1710 ASN1_STRING *cn;
1711
1712 i = X509_NAME_get_index_by_NID(name, NID_commonName, i);
1713 if (i == -1)
1714 break;
1715 e = X509_NAME_get_entry(name, i);
1716 if (e == NULL)
1717 continue;
1718 cn = X509_NAME_ENTRY_get_data(e);
1719 if (cn == NULL)
1720 continue;
1721 wpa_hexdump_ascii(MSG_DEBUG, "TLS: Certificate commonName",
1722 cn->data, cn->length);
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001723 if (domain_suffix_match(cn->data, cn->length, match, full) == 1)
1724 {
1725 wpa_printf(MSG_DEBUG, "TLS: %s in commonName found",
1726 full ? "Match" : "Suffix match");
Dmitry Shmidt051af732013-10-22 13:52:46 -07001727 return 1;
1728 }
1729 }
1730
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001731 wpa_printf(MSG_DEBUG, "TLS: No CommonName %smatch found",
1732 full ? "": "suffix ");
Dmitry Shmidt051af732013-10-22 13:52:46 -07001733 return 0;
Dmitry Shmidtfa3fc4a2013-11-21 13:34:38 -08001734#endif /* CONFIG_NATIVE_WINDOWS */
Dmitry Shmidt051af732013-10-22 13:52:46 -07001735}
1736
1737
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001738static enum tls_fail_reason openssl_tls_fail_reason(int err)
1739{
1740 switch (err) {
1741 case X509_V_ERR_CERT_REVOKED:
1742 return TLS_FAIL_REVOKED;
1743 case X509_V_ERR_CERT_NOT_YET_VALID:
1744 case X509_V_ERR_CRL_NOT_YET_VALID:
1745 return TLS_FAIL_NOT_YET_VALID;
1746 case X509_V_ERR_CERT_HAS_EXPIRED:
1747 case X509_V_ERR_CRL_HAS_EXPIRED:
1748 return TLS_FAIL_EXPIRED;
1749 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
1750 case X509_V_ERR_UNABLE_TO_GET_CRL:
1751 case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
1752 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
1753 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
1754 case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
1755 case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
1756 case X509_V_ERR_CERT_CHAIN_TOO_LONG:
1757 case X509_V_ERR_PATH_LENGTH_EXCEEDED:
1758 case X509_V_ERR_INVALID_CA:
1759 return TLS_FAIL_UNTRUSTED;
1760 case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
1761 case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
1762 case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
1763 case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
1764 case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
1765 case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
1766 case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
1767 case X509_V_ERR_CERT_UNTRUSTED:
1768 case X509_V_ERR_CERT_REJECTED:
1769 return TLS_FAIL_BAD_CERTIFICATE;
1770 default:
1771 return TLS_FAIL_UNSPECIFIED;
1772 }
1773}
1774
1775
1776static struct wpabuf * get_x509_cert(X509 *cert)
1777{
1778 struct wpabuf *buf;
1779 u8 *tmp;
1780
1781 int cert_len = i2d_X509(cert, NULL);
1782 if (cert_len <= 0)
1783 return NULL;
1784
1785 buf = wpabuf_alloc(cert_len);
1786 if (buf == NULL)
1787 return NULL;
1788
1789 tmp = wpabuf_put(buf, cert_len);
1790 i2d_X509(cert, &tmp);
1791 return buf;
1792}
1793
1794
1795static void openssl_tls_fail_event(struct tls_connection *conn,
1796 X509 *err_cert, int err, int depth,
1797 const char *subject, const char *err_str,
1798 enum tls_fail_reason reason)
1799{
1800 union tls_event_data ev;
1801 struct wpabuf *cert = NULL;
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001802 struct tls_context *context = conn->context;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001803
Pavel Grafov4d8552e2018-02-06 11:28:29 +00001804#ifdef ANDROID
1805 log_cert_validation_failure(err_str);
1806#endif
1807
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001808 if (context->event_cb == NULL)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001809 return;
1810
1811 cert = get_x509_cert(err_cert);
1812 os_memset(&ev, 0, sizeof(ev));
1813 ev.cert_fail.reason = reason != TLS_FAIL_UNSPECIFIED ?
1814 reason : openssl_tls_fail_reason(err);
1815 ev.cert_fail.depth = depth;
1816 ev.cert_fail.subject = subject;
1817 ev.cert_fail.reason_txt = err_str;
1818 ev.cert_fail.cert = cert;
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001819 context->event_cb(context->cb_ctx, TLS_CERT_CHAIN_FAILURE, &ev);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001820 wpabuf_free(cert);
1821}
1822
1823
1824static void openssl_tls_cert_event(struct tls_connection *conn,
1825 X509 *err_cert, int depth,
1826 const char *subject)
1827{
1828 struct wpabuf *cert = NULL;
1829 union tls_event_data ev;
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001830 struct tls_context *context = conn->context;
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001831 char *altsubject[TLS_MAX_ALT_SUBJECT];
1832 int alt, num_altsubject = 0;
1833 GENERAL_NAME *gen;
1834 void *ext;
1835 stack_index_t i;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001836#ifdef CONFIG_SHA256
1837 u8 hash[32];
1838#endif /* CONFIG_SHA256 */
1839
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001840 if (context->event_cb == NULL)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001841 return;
1842
1843 os_memset(&ev, 0, sizeof(ev));
Dmitry Shmidt55840ad2015-12-14 12:45:46 -08001844 if (conn->cert_probe || (conn->flags & TLS_CONN_EXT_CERT_CHECK) ||
1845 context->cert_in_cb) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001846 cert = get_x509_cert(err_cert);
1847 ev.peer_cert.cert = cert;
1848 }
1849#ifdef CONFIG_SHA256
1850 if (cert) {
1851 const u8 *addr[1];
1852 size_t len[1];
1853 addr[0] = wpabuf_head(cert);
1854 len[0] = wpabuf_len(cert);
1855 if (sha256_vector(1, addr, len, hash) == 0) {
1856 ev.peer_cert.hash = hash;
1857 ev.peer_cert.hash_len = sizeof(hash);
1858 }
1859 }
1860#endif /* CONFIG_SHA256 */
1861 ev.peer_cert.depth = depth;
1862 ev.peer_cert.subject = subject;
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001863
1864 ext = X509_get_ext_d2i(err_cert, NID_subject_alt_name, NULL, NULL);
1865 for (i = 0; ext && i < sk_GENERAL_NAME_num(ext); i++) {
1866 char *pos;
1867
1868 if (num_altsubject == TLS_MAX_ALT_SUBJECT)
1869 break;
1870 gen = sk_GENERAL_NAME_value(ext, i);
1871 if (gen->type != GEN_EMAIL &&
1872 gen->type != GEN_DNS &&
1873 gen->type != GEN_URI)
1874 continue;
1875
1876 pos = os_malloc(10 + gen->d.ia5->length + 1);
1877 if (pos == NULL)
1878 break;
1879 altsubject[num_altsubject++] = pos;
1880
1881 switch (gen->type) {
1882 case GEN_EMAIL:
1883 os_memcpy(pos, "EMAIL:", 6);
1884 pos += 6;
1885 break;
1886 case GEN_DNS:
1887 os_memcpy(pos, "DNS:", 4);
1888 pos += 4;
1889 break;
1890 case GEN_URI:
1891 os_memcpy(pos, "URI:", 4);
1892 pos += 4;
1893 break;
1894 }
1895
1896 os_memcpy(pos, gen->d.ia5->data, gen->d.ia5->length);
1897 pos += gen->d.ia5->length;
1898 *pos = '\0';
1899 }
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08001900 sk_GENERAL_NAME_pop_free(ext, GENERAL_NAME_free);
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001901
1902 for (alt = 0; alt < num_altsubject; alt++)
1903 ev.peer_cert.altsubject[alt] = altsubject[alt];
1904 ev.peer_cert.num_altsubject = num_altsubject;
1905
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001906 context->event_cb(context->cb_ctx, TLS_PEER_CERTIFICATE, &ev);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001907 wpabuf_free(cert);
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001908 for (alt = 0; alt < num_altsubject; alt++)
1909 os_free(altsubject[alt]);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001910}
1911
1912
1913static int tls_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx)
1914{
1915 char buf[256];
1916 X509 *err_cert;
1917 int err, depth;
1918 SSL *ssl;
1919 struct tls_connection *conn;
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001920 struct tls_context *context;
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001921 char *match, *altmatch, *suffix_match, *domain_match;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001922 const char *err_str;
1923
1924 err_cert = X509_STORE_CTX_get_current_cert(x509_ctx);
Dmitry Shmidt96be6222014-02-13 10:16:51 -08001925 if (!err_cert)
1926 return 0;
1927
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001928 err = X509_STORE_CTX_get_error(x509_ctx);
1929 depth = X509_STORE_CTX_get_error_depth(x509_ctx);
1930 ssl = X509_STORE_CTX_get_ex_data(x509_ctx,
1931 SSL_get_ex_data_X509_STORE_CTX_idx());
1932 X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof(buf));
1933
1934 conn = SSL_get_app_data(ssl);
1935 if (conn == NULL)
1936 return 0;
Dmitry Shmidt34af3062013-07-11 10:46:32 -07001937
1938 if (depth == 0)
1939 conn->peer_cert = err_cert;
1940 else if (depth == 1)
1941 conn->peer_issuer = err_cert;
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08001942 else if (depth == 2)
1943 conn->peer_issuer_issuer = err_cert;
Dmitry Shmidt34af3062013-07-11 10:46:32 -07001944
Dmitry Shmidtea69e842013-05-13 14:52:28 -07001945 context = conn->context;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001946 match = conn->subject_match;
1947 altmatch = conn->altsubject_match;
Dmitry Shmidt051af732013-10-22 13:52:46 -07001948 suffix_match = conn->suffix_match;
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08001949 domain_match = conn->domain_match;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001950
1951 if (!preverify_ok && !conn->ca_cert_verify)
1952 preverify_ok = 1;
1953 if (!preverify_ok && depth > 0 && conn->server_cert_only)
1954 preverify_ok = 1;
Dmitry Shmidtc55524a2011-07-07 11:18:38 -07001955 if (!preverify_ok && (conn->flags & TLS_CONN_DISABLE_TIME_CHECKS) &&
1956 (err == X509_V_ERR_CERT_HAS_EXPIRED ||
1957 err == X509_V_ERR_CERT_NOT_YET_VALID)) {
1958 wpa_printf(MSG_DEBUG, "OpenSSL: Ignore certificate validity "
1959 "time mismatch");
1960 preverify_ok = 1;
1961 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001962
1963 err_str = X509_verify_cert_error_string(err);
1964
1965#ifdef CONFIG_SHA256
Dmitry Shmidt4dd28dc2015-03-10 11:21:43 -07001966 /*
1967 * Do not require preverify_ok so we can explicity allow otherwise
1968 * invalid pinned server certificates.
1969 */
1970 if (depth == 0 && conn->server_cert_only) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001971 struct wpabuf *cert;
1972 cert = get_x509_cert(err_cert);
1973 if (!cert) {
1974 wpa_printf(MSG_DEBUG, "OpenSSL: Could not fetch "
1975 "server certificate data");
1976 preverify_ok = 0;
1977 } else {
1978 u8 hash[32];
1979 const u8 *addr[1];
1980 size_t len[1];
1981 addr[0] = wpabuf_head(cert);
1982 len[0] = wpabuf_len(cert);
1983 if (sha256_vector(1, addr, len, hash) < 0 ||
1984 os_memcmp(conn->srv_cert_hash, hash, 32) != 0) {
1985 err_str = "Server certificate mismatch";
1986 err = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
1987 preverify_ok = 0;
Dmitry Shmidt4dd28dc2015-03-10 11:21:43 -07001988 } else if (!preverify_ok) {
1989 /*
1990 * Certificate matches pinned certificate, allow
1991 * regardless of other problems.
1992 */
1993 wpa_printf(MSG_DEBUG,
1994 "OpenSSL: Ignore validation issues for a pinned server certificate");
1995 preverify_ok = 1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001996 }
1997 wpabuf_free(cert);
1998 }
1999 }
2000#endif /* CONFIG_SHA256 */
2001
2002 if (!preverify_ok) {
2003 wpa_printf(MSG_WARNING, "TLS: Certificate verification failed,"
2004 " error %d (%s) depth %d for '%s'", err, err_str,
2005 depth, buf);
2006 openssl_tls_fail_event(conn, err_cert, err, depth, buf,
2007 err_str, TLS_FAIL_UNSPECIFIED);
2008 return preverify_ok;
2009 }
2010
2011 wpa_printf(MSG_DEBUG, "TLS: tls_verify_cb - preverify_ok=%d "
2012 "err=%d (%s) ca_cert_verify=%d depth=%d buf='%s'",
2013 preverify_ok, err, err_str,
2014 conn->ca_cert_verify, depth, buf);
2015 if (depth == 0 && match && os_strstr(buf, match) == NULL) {
2016 wpa_printf(MSG_WARNING, "TLS: Subject '%s' did not "
2017 "match with '%s'", buf, match);
2018 preverify_ok = 0;
2019 openssl_tls_fail_event(conn, err_cert, err, depth, buf,
2020 "Subject mismatch",
2021 TLS_FAIL_SUBJECT_MISMATCH);
2022 } else if (depth == 0 && altmatch &&
2023 !tls_match_altsubject(err_cert, altmatch)) {
2024 wpa_printf(MSG_WARNING, "TLS: altSubjectName match "
2025 "'%s' not found", altmatch);
2026 preverify_ok = 0;
2027 openssl_tls_fail_event(conn, err_cert, err, depth, buf,
2028 "AltSubject mismatch",
2029 TLS_FAIL_ALTSUBJECT_MISMATCH);
Dmitry Shmidt051af732013-10-22 13:52:46 -07002030 } else if (depth == 0 && suffix_match &&
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08002031 !tls_match_suffix(err_cert, suffix_match, 0)) {
Dmitry Shmidt051af732013-10-22 13:52:46 -07002032 wpa_printf(MSG_WARNING, "TLS: Domain suffix match '%s' not found",
2033 suffix_match);
2034 preverify_ok = 0;
2035 openssl_tls_fail_event(conn, err_cert, err, depth, buf,
2036 "Domain suffix mismatch",
2037 TLS_FAIL_DOMAIN_SUFFIX_MISMATCH);
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08002038 } else if (depth == 0 && domain_match &&
2039 !tls_match_suffix(err_cert, domain_match, 1)) {
2040 wpa_printf(MSG_WARNING, "TLS: Domain match '%s' not found",
2041 domain_match);
2042 preverify_ok = 0;
2043 openssl_tls_fail_event(conn, err_cert, err, depth, buf,
2044 "Domain mismatch",
2045 TLS_FAIL_DOMAIN_MISMATCH);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002046 } else
2047 openssl_tls_cert_event(conn, err_cert, depth, buf);
2048
2049 if (conn->cert_probe && preverify_ok && depth == 0) {
2050 wpa_printf(MSG_DEBUG, "OpenSSL: Reject server certificate "
2051 "on probe-only run");
2052 preverify_ok = 0;
2053 openssl_tls_fail_event(conn, err_cert, err, depth, buf,
2054 "Server certificate chain probe",
2055 TLS_FAIL_SERVER_CHAIN_PROBE);
2056 }
2057
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002058#ifdef CONFIG_SUITEB
2059 if (conn->flags & TLS_CONN_SUITEB) {
2060 EVP_PKEY *pk;
2061 RSA *rsa;
2062 int len = -1;
2063
2064 pk = X509_get_pubkey(err_cert);
2065 if (pk) {
2066 rsa = EVP_PKEY_get1_RSA(pk);
2067 if (rsa) {
2068 len = RSA_bits(rsa);
2069 RSA_free(rsa);
2070 }
2071 EVP_PKEY_free(pk);
2072 }
2073
2074 if (len >= 0) {
2075 wpa_printf(MSG_DEBUG,
2076 "OpenSSL: RSA modulus size: %d bits", len);
2077 if (len < 3072) {
2078 preverify_ok = 0;
2079 openssl_tls_fail_event(
2080 conn, err_cert, err,
2081 depth, buf,
2082 "Insufficient RSA modulus size",
2083 TLS_FAIL_INSUFFICIENT_KEY_LEN);
2084 }
2085 }
2086 }
2087#endif /* CONFIG_SUITEB */
2088
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002089#ifdef OPENSSL_IS_BORINGSSL
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08002090 if (depth == 0 && (conn->flags & TLS_CONN_REQUEST_OCSP) &&
2091 preverify_ok) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002092 enum ocsp_result res;
2093
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08002094 res = check_ocsp_resp(conn->ssl_ctx, conn->ssl, err_cert,
2095 conn->peer_issuer,
2096 conn->peer_issuer_issuer);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002097 if (res == OCSP_REVOKED) {
2098 preverify_ok = 0;
2099 openssl_tls_fail_event(conn, err_cert, err, depth, buf,
2100 "certificate revoked",
2101 TLS_FAIL_REVOKED);
2102 if (err == X509_V_OK)
2103 X509_STORE_CTX_set_error(
2104 x509_ctx, X509_V_ERR_CERT_REVOKED);
2105 } else if (res != OCSP_GOOD &&
2106 (conn->flags & TLS_CONN_REQUIRE_OCSP)) {
2107 preverify_ok = 0;
2108 openssl_tls_fail_event(conn, err_cert, err, depth, buf,
2109 "bad certificate status response",
2110 TLS_FAIL_UNSPECIFIED);
2111 }
2112 }
2113#endif /* OPENSSL_IS_BORINGSSL */
2114
Dmitry Shmidt55840ad2015-12-14 12:45:46 -08002115 if (depth == 0 && preverify_ok && context->event_cb != NULL)
Dmitry Shmidtea69e842013-05-13 14:52:28 -07002116 context->event_cb(context->cb_ctx,
2117 TLS_CERT_CHAIN_SUCCESS, NULL);
Dmitry Shmidt04949592012-07-19 12:16:46 -07002118
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002119 return preverify_ok;
2120}
2121
2122
2123#ifndef OPENSSL_NO_STDIO
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002124static int tls_load_ca_der(struct tls_data *data, const char *ca_cert)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002125{
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002126 SSL_CTX *ssl_ctx = data->ssl;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002127 X509_LOOKUP *lookup;
2128 int ret = 0;
2129
Dmitry Shmidt216983b2015-02-06 10:50:36 -08002130 lookup = X509_STORE_add_lookup(SSL_CTX_get_cert_store(ssl_ctx),
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002131 X509_LOOKUP_file());
2132 if (lookup == NULL) {
2133 tls_show_errors(MSG_WARNING, __func__,
2134 "Failed add lookup for X509 store");
2135 return -1;
2136 }
2137
2138 if (!X509_LOOKUP_load_file(lookup, ca_cert, X509_FILETYPE_ASN1)) {
2139 unsigned long err = ERR_peek_error();
2140 tls_show_errors(MSG_WARNING, __func__,
2141 "Failed load CA in DER format");
2142 if (ERR_GET_LIB(err) == ERR_LIB_X509 &&
2143 ERR_GET_REASON(err) == X509_R_CERT_ALREADY_IN_HASH_TABLE) {
2144 wpa_printf(MSG_DEBUG, "OpenSSL: %s - ignoring "
2145 "cert already in hash table error",
2146 __func__);
2147 } else
2148 ret = -1;
2149 }
2150
2151 return ret;
2152}
2153#endif /* OPENSSL_NO_STDIO */
2154
2155
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002156static int tls_connection_ca_cert(struct tls_data *data,
2157 struct tls_connection *conn,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002158 const char *ca_cert, const u8 *ca_cert_blob,
2159 size_t ca_cert_blob_len, const char *ca_path)
2160{
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002161 SSL_CTX *ssl_ctx = data->ssl;
Dmitry Shmidt216983b2015-02-06 10:50:36 -08002162 X509_STORE *store;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002163
2164 /*
2165 * Remove previously configured trusted CA certificates before adding
2166 * new ones.
2167 */
Dmitry Shmidt216983b2015-02-06 10:50:36 -08002168 store = X509_STORE_new();
2169 if (store == NULL) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002170 wpa_printf(MSG_DEBUG, "OpenSSL: %s - failed to allocate new "
2171 "certificate store", __func__);
2172 return -1;
2173 }
Dmitry Shmidt216983b2015-02-06 10:50:36 -08002174 SSL_CTX_set_cert_store(ssl_ctx, store);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002175
2176 SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb);
2177 conn->ca_cert_verify = 1;
2178
2179 if (ca_cert && os_strncmp(ca_cert, "probe://", 8) == 0) {
2180 wpa_printf(MSG_DEBUG, "OpenSSL: Probe for server certificate "
2181 "chain");
2182 conn->cert_probe = 1;
2183 conn->ca_cert_verify = 0;
2184 return 0;
2185 }
2186
2187 if (ca_cert && os_strncmp(ca_cert, "hash://", 7) == 0) {
2188#ifdef CONFIG_SHA256
2189 const char *pos = ca_cert + 7;
2190 if (os_strncmp(pos, "server/sha256/", 14) != 0) {
2191 wpa_printf(MSG_DEBUG, "OpenSSL: Unsupported ca_cert "
2192 "hash value '%s'", ca_cert);
2193 return -1;
2194 }
2195 pos += 14;
2196 if (os_strlen(pos) != 32 * 2) {
2197 wpa_printf(MSG_DEBUG, "OpenSSL: Unexpected SHA256 "
2198 "hash length in ca_cert '%s'", ca_cert);
2199 return -1;
2200 }
2201 if (hexstr2bin(pos, conn->srv_cert_hash, 32) < 0) {
2202 wpa_printf(MSG_DEBUG, "OpenSSL: Invalid SHA256 hash "
2203 "value in ca_cert '%s'", ca_cert);
2204 return -1;
2205 }
2206 conn->server_cert_only = 1;
2207 wpa_printf(MSG_DEBUG, "OpenSSL: Checking only server "
2208 "certificate match");
2209 return 0;
2210#else /* CONFIG_SHA256 */
2211 wpa_printf(MSG_INFO, "No SHA256 included in the build - "
2212 "cannot validate server certificate hash");
2213 return -1;
2214#endif /* CONFIG_SHA256 */
2215 }
2216
2217 if (ca_cert_blob) {
Dmitry Shmidt216983b2015-02-06 10:50:36 -08002218 X509 *cert = d2i_X509(NULL,
2219 (const unsigned char **) &ca_cert_blob,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002220 ca_cert_blob_len);
2221 if (cert == NULL) {
2222 tls_show_errors(MSG_WARNING, __func__,
2223 "Failed to parse ca_cert_blob");
2224 return -1;
2225 }
2226
Dmitry Shmidt216983b2015-02-06 10:50:36 -08002227 if (!X509_STORE_add_cert(SSL_CTX_get_cert_store(ssl_ctx),
2228 cert)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002229 unsigned long err = ERR_peek_error();
2230 tls_show_errors(MSG_WARNING, __func__,
2231 "Failed to add ca_cert_blob to "
2232 "certificate store");
2233 if (ERR_GET_LIB(err) == ERR_LIB_X509 &&
2234 ERR_GET_REASON(err) ==
2235 X509_R_CERT_ALREADY_IN_HASH_TABLE) {
2236 wpa_printf(MSG_DEBUG, "OpenSSL: %s - ignoring "
2237 "cert already in hash table error",
2238 __func__);
2239 } else {
2240 X509_free(cert);
2241 return -1;
2242 }
2243 }
2244 X509_free(cert);
2245 wpa_printf(MSG_DEBUG, "OpenSSL: %s - added ca_cert_blob "
2246 "to certificate store", __func__);
2247 return 0;
2248 }
2249
2250#ifdef ANDROID
Dmitry Shmidtb97e4282016-02-08 10:16:07 -08002251 /* Single alias */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002252 if (ca_cert && os_strncmp("keystore://", ca_cert, 11) == 0) {
Dmitry Shmidt849734c2016-05-27 09:59:01 -07002253 if (tls_add_ca_from_keystore(SSL_CTX_get_cert_store(ssl_ctx),
Dmitry Shmidtb97e4282016-02-08 10:16:07 -08002254 &ca_cert[11]) < 0)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002255 return -1;
Dmitry Shmidtb97e4282016-02-08 10:16:07 -08002256 SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb);
2257 return 0;
2258 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002259
Dmitry Shmidtb97e4282016-02-08 10:16:07 -08002260 /* Multiple aliases separated by space */
2261 if (ca_cert && os_strncmp("keystores://", ca_cert, 12) == 0) {
2262 char *aliases = os_strdup(&ca_cert[12]);
2263 const char *delim = " ";
2264 int rc = 0;
2265 char *savedptr;
2266 char *alias;
2267
2268 if (!aliases)
2269 return -1;
2270 alias = strtok_r(aliases, delim, &savedptr);
2271 for (; alias; alias = strtok_r(NULL, delim, &savedptr)) {
2272 if (tls_add_ca_from_keystore_encoded(
Dmitry Shmidt849734c2016-05-27 09:59:01 -07002273 SSL_CTX_get_cert_store(ssl_ctx), alias)) {
Dmitry Shmidtb97e4282016-02-08 10:16:07 -08002274 wpa_printf(MSG_WARNING,
2275 "OpenSSL: %s - Failed to add ca_cert %s from keystore",
2276 __func__, alias);
2277 rc = -1;
2278 break;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002279 }
2280 }
Dmitry Shmidtb97e4282016-02-08 10:16:07 -08002281 os_free(aliases);
2282 if (rc)
2283 return rc;
2284
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002285 SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb);
2286 return 0;
2287 }
2288#endif /* ANDROID */
2289
2290#ifdef CONFIG_NATIVE_WINDOWS
2291 if (ca_cert && tls_cryptoapi_ca_cert(ssl_ctx, conn->ssl, ca_cert) ==
2292 0) {
2293 wpa_printf(MSG_DEBUG, "OpenSSL: Added CA certificates from "
2294 "system certificate store");
2295 return 0;
2296 }
2297#endif /* CONFIG_NATIVE_WINDOWS */
2298
2299 if (ca_cert || ca_path) {
2300#ifndef OPENSSL_NO_STDIO
2301 if (SSL_CTX_load_verify_locations(ssl_ctx, ca_cert, ca_path) !=
2302 1) {
2303 tls_show_errors(MSG_WARNING, __func__,
2304 "Failed to load root certificates");
2305 if (ca_cert &&
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002306 tls_load_ca_der(data, ca_cert) == 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002307 wpa_printf(MSG_DEBUG, "OpenSSL: %s - loaded "
2308 "DER format CA certificate",
2309 __func__);
2310 } else
2311 return -1;
2312 } else {
2313 wpa_printf(MSG_DEBUG, "TLS: Trusted root "
2314 "certificate(s) loaded");
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002315 tls_get_errors(data);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002316 }
2317#else /* OPENSSL_NO_STDIO */
2318 wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO",
2319 __func__);
2320 return -1;
2321#endif /* OPENSSL_NO_STDIO */
2322 } else {
2323 /* No ca_cert configured - do not try to verify server
2324 * certificate */
2325 conn->ca_cert_verify = 0;
2326 }
2327
2328 return 0;
2329}
2330
2331
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002332static int tls_global_ca_cert(struct tls_data *data, const char *ca_cert)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002333{
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002334 SSL_CTX *ssl_ctx = data->ssl;
2335
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002336 if (ca_cert) {
2337 if (SSL_CTX_load_verify_locations(ssl_ctx, ca_cert, NULL) != 1)
2338 {
2339 tls_show_errors(MSG_WARNING, __func__,
2340 "Failed to load root certificates");
2341 return -1;
2342 }
2343
2344 wpa_printf(MSG_DEBUG, "TLS: Trusted root "
2345 "certificate(s) loaded");
2346
2347#ifndef OPENSSL_NO_STDIO
2348 /* Add the same CAs to the client certificate requests */
2349 SSL_CTX_set_client_CA_list(ssl_ctx,
2350 SSL_load_client_CA_file(ca_cert));
2351#endif /* OPENSSL_NO_STDIO */
2352 }
2353
2354 return 0;
2355}
2356
2357
2358int tls_global_set_verify(void *ssl_ctx, int check_crl)
2359{
2360 int flags;
2361
2362 if (check_crl) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002363 struct tls_data *data = ssl_ctx;
2364 X509_STORE *cs = SSL_CTX_get_cert_store(data->ssl);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002365 if (cs == NULL) {
2366 tls_show_errors(MSG_INFO, __func__, "Failed to get "
2367 "certificate store when enabling "
2368 "check_crl");
2369 return -1;
2370 }
2371 flags = X509_V_FLAG_CRL_CHECK;
2372 if (check_crl == 2)
2373 flags |= X509_V_FLAG_CRL_CHECK_ALL;
2374 X509_STORE_set_flags(cs, flags);
2375 }
2376 return 0;
2377}
2378
2379
2380static int tls_connection_set_subject_match(struct tls_connection *conn,
2381 const char *subject_match,
Dmitry Shmidt051af732013-10-22 13:52:46 -07002382 const char *altsubject_match,
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08002383 const char *suffix_match,
2384 const char *domain_match)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002385{
2386 os_free(conn->subject_match);
2387 conn->subject_match = NULL;
2388 if (subject_match) {
2389 conn->subject_match = os_strdup(subject_match);
2390 if (conn->subject_match == NULL)
2391 return -1;
2392 }
2393
2394 os_free(conn->altsubject_match);
2395 conn->altsubject_match = NULL;
2396 if (altsubject_match) {
2397 conn->altsubject_match = os_strdup(altsubject_match);
2398 if (conn->altsubject_match == NULL)
2399 return -1;
2400 }
2401
Dmitry Shmidt051af732013-10-22 13:52:46 -07002402 os_free(conn->suffix_match);
2403 conn->suffix_match = NULL;
2404 if (suffix_match) {
2405 conn->suffix_match = os_strdup(suffix_match);
2406 if (conn->suffix_match == NULL)
2407 return -1;
2408 }
2409
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08002410 os_free(conn->domain_match);
2411 conn->domain_match = NULL;
2412 if (domain_match) {
2413 conn->domain_match = os_strdup(domain_match);
2414 if (conn->domain_match == NULL)
2415 return -1;
2416 }
2417
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002418 return 0;
2419}
2420
2421
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002422#ifdef CONFIG_SUITEB
2423#if OPENSSL_VERSION_NUMBER >= 0x10002000L
2424static int suiteb_cert_cb(SSL *ssl, void *arg)
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002425{
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002426 struct tls_connection *conn = arg;
2427
2428 /*
2429 * This cert_cb() is not really the best location for doing a
2430 * constraint check for the ServerKeyExchange message, but this seems to
2431 * be the only place where the current OpenSSL sequence can be
2432 * terminated cleanly with an TLS alert going out to the server.
2433 */
2434
2435 if (!(conn->flags & TLS_CONN_SUITEB))
2436 return 1;
2437
2438 /* DHE is enabled only with DHE-RSA-AES256-GCM-SHA384 */
2439 if (conn->cipher_suite != 0x9f)
2440 return 1;
2441
2442 if (conn->server_dh_prime_len >= 3072)
2443 return 1;
2444
2445 wpa_printf(MSG_DEBUG,
2446 "OpenSSL: Server DH prime length (%d bits) not sufficient for Suite B RSA - reject handshake",
2447 conn->server_dh_prime_len);
2448 return 0;
2449}
2450#endif /* OPENSSL_VERSION_NUMBER */
2451#endif /* CONFIG_SUITEB */
2452
2453
2454static int tls_set_conn_flags(struct tls_connection *conn, unsigned int flags)
2455{
2456 SSL *ssl = conn->ssl;
2457
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002458#ifdef SSL_OP_NO_TICKET
2459 if (flags & TLS_CONN_DISABLE_SESSION_TICKET)
2460 SSL_set_options(ssl, SSL_OP_NO_TICKET);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002461 else
2462 SSL_clear_options(ssl, SSL_OP_NO_TICKET);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002463#endif /* SSL_OP_NO_TICKET */
2464
2465#ifdef SSL_OP_NO_TLSv1
2466 if (flags & TLS_CONN_DISABLE_TLSv1_0)
2467 SSL_set_options(ssl, SSL_OP_NO_TLSv1);
2468 else
2469 SSL_clear_options(ssl, SSL_OP_NO_TLSv1);
2470#endif /* SSL_OP_NO_TLSv1 */
2471#ifdef SSL_OP_NO_TLSv1_1
2472 if (flags & TLS_CONN_DISABLE_TLSv1_1)
2473 SSL_set_options(ssl, SSL_OP_NO_TLSv1_1);
2474 else
2475 SSL_clear_options(ssl, SSL_OP_NO_TLSv1_1);
2476#endif /* SSL_OP_NO_TLSv1_1 */
2477#ifdef SSL_OP_NO_TLSv1_2
2478 if (flags & TLS_CONN_DISABLE_TLSv1_2)
2479 SSL_set_options(ssl, SSL_OP_NO_TLSv1_2);
2480 else
2481 SSL_clear_options(ssl, SSL_OP_NO_TLSv1_2);
2482#endif /* SSL_OP_NO_TLSv1_2 */
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002483#ifdef CONFIG_SUITEB
2484#if OPENSSL_VERSION_NUMBER >= 0x10002000L
2485 if (flags & TLS_CONN_SUITEB_NO_ECDH) {
2486 const char *ciphers = "DHE-RSA-AES256-GCM-SHA384";
2487
2488 if (SSL_set_cipher_list(ssl, ciphers) != 1) {
2489 wpa_printf(MSG_INFO,
2490 "OpenSSL: Failed to set Suite B ciphers");
2491 return -1;
2492 }
2493 } else if (flags & TLS_CONN_SUITEB) {
2494 EC_KEY *ecdh;
2495 const char *ciphers =
2496 "ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384";
2497
2498 if (SSL_set_cipher_list(ssl, ciphers) != 1) {
2499 wpa_printf(MSG_INFO,
2500 "OpenSSL: Failed to set Suite B ciphers");
2501 return -1;
2502 }
2503
2504 if (SSL_set1_curves_list(ssl, "P-384") != 1) {
2505 wpa_printf(MSG_INFO,
2506 "OpenSSL: Failed to set Suite B curves");
2507 return -1;
2508 }
2509
2510 ecdh = EC_KEY_new_by_curve_name(NID_secp384r1);
2511 if (!ecdh || SSL_set_tmp_ecdh(ssl, ecdh) != 1) {
2512 EC_KEY_free(ecdh);
2513 wpa_printf(MSG_INFO,
2514 "OpenSSL: Failed to set ECDH parameter");
2515 return -1;
2516 }
2517 EC_KEY_free(ecdh);
2518 }
2519 if (flags & (TLS_CONN_SUITEB | TLS_CONN_SUITEB_NO_ECDH)) {
2520 /* ECDSA+SHA384 if need to add EC support here */
2521 if (SSL_set1_sigalgs_list(ssl, "RSA+SHA384") != 1) {
2522 wpa_printf(MSG_INFO,
2523 "OpenSSL: Failed to set Suite B sigalgs");
2524 return -1;
2525 }
2526
2527 SSL_set_options(ssl, SSL_OP_NO_TLSv1);
2528 SSL_set_options(ssl, SSL_OP_NO_TLSv1_1);
2529 SSL_set_cert_cb(ssl, suiteb_cert_cb, conn);
2530 }
2531#else /* OPENSSL_VERSION_NUMBER < 0x10002000L */
2532 if (flags & (TLS_CONN_SUITEB | TLS_CONN_SUITEB_NO_ECDH)) {
2533 wpa_printf(MSG_ERROR,
2534 "OpenSSL: Suite B RSA case not supported with this OpenSSL version");
2535 return -1;
2536 }
2537#endif /* OPENSSL_VERSION_NUMBER */
2538#endif /* CONFIG_SUITEB */
2539
2540 return 0;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002541}
2542
2543
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002544int tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn,
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002545 int verify_peer, unsigned int flags,
2546 const u8 *session_ctx, size_t session_ctx_len)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002547{
2548 static int counter = 0;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002549 struct tls_data *data = ssl_ctx;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002550
2551 if (conn == NULL)
2552 return -1;
2553
2554 if (verify_peer) {
2555 conn->ca_cert_verify = 1;
2556 SSL_set_verify(conn->ssl, SSL_VERIFY_PEER |
2557 SSL_VERIFY_FAIL_IF_NO_PEER_CERT |
2558 SSL_VERIFY_CLIENT_ONCE, tls_verify_cb);
2559 } else {
2560 conn->ca_cert_verify = 0;
2561 SSL_set_verify(conn->ssl, SSL_VERIFY_NONE, NULL);
2562 }
2563
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002564 if (tls_set_conn_flags(conn, flags) < 0)
2565 return -1;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002566 conn->flags = flags;
2567
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002568 SSL_set_accept_state(conn->ssl);
2569
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002570 if (data->tls_session_lifetime == 0) {
2571 /*
2572 * Set session id context to a unique value to make sure
2573 * session resumption cannot be used either through session
2574 * caching or TLS ticket extension.
2575 */
2576 counter++;
2577 SSL_set_session_id_context(conn->ssl,
2578 (const unsigned char *) &counter,
2579 sizeof(counter));
2580 } else if (session_ctx) {
2581 SSL_set_session_id_context(conn->ssl, session_ctx,
2582 session_ctx_len);
2583 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002584
2585 return 0;
2586}
2587
2588
2589static int tls_connection_client_cert(struct tls_connection *conn,
2590 const char *client_cert,
2591 const u8 *client_cert_blob,
2592 size_t client_cert_blob_len)
2593{
2594 if (client_cert == NULL && client_cert_blob == NULL)
2595 return 0;
2596
Dmitry Shmidtde47be72016-01-07 12:52:55 -08002597#ifdef PKCS12_FUNCS
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002598#if OPENSSL_VERSION_NUMBER < 0x10002000L || defined(LIBRESSL_VERSION_NUMBER)
Dmitry Shmidtde47be72016-01-07 12:52:55 -08002599 /*
2600 * Clear previously set extra chain certificates, if any, from PKCS#12
2601 * processing in tls_parse_pkcs12() to allow OpenSSL to build a new
2602 * chain properly.
2603 */
2604 SSL_CTX_clear_extra_chain_certs(conn->ssl_ctx);
2605#endif /* OPENSSL_VERSION_NUMBER < 0x10002000L */
2606#endif /* PKCS12_FUNCS */
2607
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002608 if (client_cert_blob &&
2609 SSL_use_certificate_ASN1(conn->ssl, (u8 *) client_cert_blob,
2610 client_cert_blob_len) == 1) {
2611 wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_ASN1 --> "
2612 "OK");
2613 return 0;
2614 } else if (client_cert_blob) {
2615 tls_show_errors(MSG_DEBUG, __func__,
2616 "SSL_use_certificate_ASN1 failed");
2617 }
2618
2619 if (client_cert == NULL)
2620 return -1;
2621
2622#ifdef ANDROID
2623 if (os_strncmp("keystore://", client_cert, 11) == 0) {
2624 BIO *bio = BIO_from_keystore(&client_cert[11]);
2625 X509 *x509 = NULL;
2626 int ret = -1;
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002627 if (bio) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002628 x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07002629 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002630 if (x509) {
2631 if (SSL_use_certificate(conn->ssl, x509) == 1)
2632 ret = 0;
2633 X509_free(x509);
2634 }
Paul Stewart50772e82017-01-25 13:59:16 -08002635
2636 /* Read additional certificates into the chain. */
2637 while (bio) {
2638 x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
2639 if (x509) {
2640 /* Takes ownership of x509 */
2641 SSL_add0_chain_cert(conn->ssl, x509);
2642 } else {
2643 BIO_free(bio);
2644 bio = NULL;
2645 }
2646 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002647 return ret;
2648 }
2649#endif /* ANDROID */
2650
2651#ifndef OPENSSL_NO_STDIO
2652 if (SSL_use_certificate_file(conn->ssl, client_cert,
2653 SSL_FILETYPE_ASN1) == 1) {
2654 wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_file (DER)"
2655 " --> OK");
2656 return 0;
2657 }
2658
2659 if (SSL_use_certificate_file(conn->ssl, client_cert,
2660 SSL_FILETYPE_PEM) == 1) {
2661 ERR_clear_error();
2662 wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_file (PEM)"
2663 " --> OK");
2664 return 0;
2665 }
2666
2667 tls_show_errors(MSG_DEBUG, __func__,
2668 "SSL_use_certificate_file failed");
2669#else /* OPENSSL_NO_STDIO */
2670 wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", __func__);
2671#endif /* OPENSSL_NO_STDIO */
2672
2673 return -1;
2674}
2675
2676
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002677static int tls_global_client_cert(struct tls_data *data,
2678 const char *client_cert)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002679{
2680#ifndef OPENSSL_NO_STDIO
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002681 SSL_CTX *ssl_ctx = data->ssl;
2682
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002683 if (client_cert == NULL)
2684 return 0;
2685
2686 if (SSL_CTX_use_certificate_file(ssl_ctx, client_cert,
2687 SSL_FILETYPE_ASN1) != 1 &&
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002688 SSL_CTX_use_certificate_chain_file(ssl_ctx, client_cert) != 1 &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002689 SSL_CTX_use_certificate_file(ssl_ctx, client_cert,
2690 SSL_FILETYPE_PEM) != 1) {
2691 tls_show_errors(MSG_INFO, __func__,
2692 "Failed to load client certificate");
2693 return -1;
2694 }
2695 return 0;
2696#else /* OPENSSL_NO_STDIO */
2697 if (client_cert == NULL)
2698 return 0;
2699 wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", __func__);
2700 return -1;
2701#endif /* OPENSSL_NO_STDIO */
2702}
2703
2704
2705static int tls_passwd_cb(char *buf, int size, int rwflag, void *password)
2706{
2707 if (password == NULL) {
2708 return 0;
2709 }
2710 os_strlcpy(buf, (char *) password, size);
2711 return os_strlen(buf);
2712}
2713
2714
2715#ifdef PKCS12_FUNCS
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002716static int tls_parse_pkcs12(struct tls_data *data, SSL *ssl, PKCS12 *p12,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002717 const char *passwd)
2718{
2719 EVP_PKEY *pkey;
2720 X509 *cert;
2721 STACK_OF(X509) *certs;
2722 int res = 0;
2723 char buf[256];
2724
2725 pkey = NULL;
2726 cert = NULL;
2727 certs = NULL;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002728 if (!passwd)
2729 passwd = "";
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002730 if (!PKCS12_parse(p12, passwd, &pkey, &cert, &certs)) {
2731 tls_show_errors(MSG_DEBUG, __func__,
2732 "Failed to parse PKCS12 file");
2733 PKCS12_free(p12);
2734 return -1;
2735 }
2736 wpa_printf(MSG_DEBUG, "TLS: Successfully parsed PKCS12 data");
2737
2738 if (cert) {
2739 X509_NAME_oneline(X509_get_subject_name(cert), buf,
2740 sizeof(buf));
2741 wpa_printf(MSG_DEBUG, "TLS: Got certificate from PKCS12: "
2742 "subject='%s'", buf);
2743 if (ssl) {
2744 if (SSL_use_certificate(ssl, cert) != 1)
2745 res = -1;
2746 } else {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002747 if (SSL_CTX_use_certificate(data->ssl, cert) != 1)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002748 res = -1;
2749 }
2750 X509_free(cert);
2751 }
2752
2753 if (pkey) {
2754 wpa_printf(MSG_DEBUG, "TLS: Got private key from PKCS12");
2755 if (ssl) {
2756 if (SSL_use_PrivateKey(ssl, pkey) != 1)
2757 res = -1;
2758 } else {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002759 if (SSL_CTX_use_PrivateKey(data->ssl, pkey) != 1)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002760 res = -1;
2761 }
2762 EVP_PKEY_free(pkey);
2763 }
2764
2765 if (certs) {
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08002766#if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(LIBRESSL_VERSION_NUMBER)
Dmitry Shmidtb97e4282016-02-08 10:16:07 -08002767 if (ssl)
2768 SSL_clear_chain_certs(ssl);
2769 else
2770 SSL_CTX_clear_chain_certs(data->ssl);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002771 while ((cert = sk_X509_pop(certs)) != NULL) {
2772 X509_NAME_oneline(X509_get_subject_name(cert), buf,
2773 sizeof(buf));
2774 wpa_printf(MSG_DEBUG, "TLS: additional certificate"
2775 " from PKCS12: subject='%s'", buf);
Dmitry Shmidtb97e4282016-02-08 10:16:07 -08002776 if ((ssl && SSL_add1_chain_cert(ssl, cert) != 1) ||
2777 (!ssl && SSL_CTX_add1_chain_cert(data->ssl,
2778 cert) != 1)) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002779 tls_show_errors(MSG_DEBUG, __func__,
2780 "Failed to add additional certificate");
2781 res = -1;
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08002782 X509_free(cert);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002783 break;
2784 }
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08002785 X509_free(cert);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002786 }
2787 if (!res) {
2788 /* Try to continue anyway */
2789 }
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08002790 sk_X509_pop_free(certs, X509_free);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002791#ifndef OPENSSL_IS_BORINGSSL
Dmitry Shmidtb97e4282016-02-08 10:16:07 -08002792 if (ssl)
2793 res = SSL_build_cert_chain(
2794 ssl,
2795 SSL_BUILD_CHAIN_FLAG_CHECK |
2796 SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR);
2797 else
2798 res = SSL_CTX_build_cert_chain(
2799 data->ssl,
2800 SSL_BUILD_CHAIN_FLAG_CHECK |
2801 SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002802 if (!res) {
2803 tls_show_errors(MSG_DEBUG, __func__,
2804 "Failed to build certificate chain");
2805 } else if (res == 2) {
2806 wpa_printf(MSG_DEBUG,
2807 "TLS: Ignore certificate chain verification error when building chain with PKCS#12 extra certificates");
2808 }
2809#endif /* OPENSSL_IS_BORINGSSL */
2810 /*
2811 * Try to continue regardless of result since it is possible for
2812 * the extra certificates not to be required.
2813 */
2814 res = 0;
2815#else /* OPENSSL_VERSION_NUMBER >= 0x10002000L */
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002816 SSL_CTX_clear_extra_chain_certs(data->ssl);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002817 while ((cert = sk_X509_pop(certs)) != NULL) {
2818 X509_NAME_oneline(X509_get_subject_name(cert), buf,
2819 sizeof(buf));
2820 wpa_printf(MSG_DEBUG, "TLS: additional certificate"
2821 " from PKCS12: subject='%s'", buf);
2822 /*
2823 * There is no SSL equivalent for the chain cert - so
2824 * always add it to the context...
2825 */
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002826 if (SSL_CTX_add_extra_chain_cert(data->ssl, cert) != 1)
2827 {
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08002828 X509_free(cert);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002829 res = -1;
2830 break;
2831 }
2832 }
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08002833 sk_X509_pop_free(certs, X509_free);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002834#endif /* OPENSSL_VERSION_NUMBER >= 0x10002000L */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002835 }
2836
2837 PKCS12_free(p12);
2838
2839 if (res < 0)
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002840 tls_get_errors(data);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002841
2842 return res;
2843}
2844#endif /* PKCS12_FUNCS */
2845
2846
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002847static int tls_read_pkcs12(struct tls_data *data, SSL *ssl,
2848 const char *private_key, const char *passwd)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002849{
2850#ifdef PKCS12_FUNCS
2851 FILE *f;
2852 PKCS12 *p12;
2853
2854 f = fopen(private_key, "rb");
2855 if (f == NULL)
2856 return -1;
2857
2858 p12 = d2i_PKCS12_fp(f, NULL);
2859 fclose(f);
2860
2861 if (p12 == NULL) {
2862 tls_show_errors(MSG_INFO, __func__,
2863 "Failed to use PKCS#12 file");
2864 return -1;
2865 }
2866
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002867 return tls_parse_pkcs12(data, ssl, p12, passwd);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002868
2869#else /* PKCS12_FUNCS */
2870 wpa_printf(MSG_INFO, "TLS: PKCS12 support disabled - cannot read "
2871 "p12/pfx files");
2872 return -1;
2873#endif /* PKCS12_FUNCS */
2874}
2875
2876
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002877static int tls_read_pkcs12_blob(struct tls_data *data, SSL *ssl,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002878 const u8 *blob, size_t len, const char *passwd)
2879{
2880#ifdef PKCS12_FUNCS
2881 PKCS12 *p12;
2882
Dmitry Shmidt216983b2015-02-06 10:50:36 -08002883 p12 = d2i_PKCS12(NULL, (const unsigned char **) &blob, len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002884 if (p12 == NULL) {
2885 tls_show_errors(MSG_INFO, __func__,
2886 "Failed to use PKCS#12 blob");
2887 return -1;
2888 }
2889
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002890 return tls_parse_pkcs12(data, ssl, p12, passwd);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002891
2892#else /* PKCS12_FUNCS */
2893 wpa_printf(MSG_INFO, "TLS: PKCS12 support disabled - cannot parse "
2894 "p12/pfx blobs");
2895 return -1;
2896#endif /* PKCS12_FUNCS */
2897}
2898
2899
2900#ifndef OPENSSL_NO_ENGINE
2901static int tls_engine_get_cert(struct tls_connection *conn,
2902 const char *cert_id,
2903 X509 **cert)
2904{
2905 /* this runs after the private key is loaded so no PIN is required */
2906 struct {
2907 const char *cert_id;
2908 X509 *cert;
2909 } params;
2910 params.cert_id = cert_id;
2911 params.cert = NULL;
2912
2913 if (!ENGINE_ctrl_cmd(conn->engine, "LOAD_CERT_CTRL",
2914 0, &params, NULL, 1)) {
Dmitry Shmidt1d755d02015-04-28 10:34:29 -07002915 unsigned long err = ERR_get_error();
2916
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002917 wpa_printf(MSG_ERROR, "ENGINE: cannot load client cert with id"
2918 " '%s' [%s]", cert_id,
Dmitry Shmidt1d755d02015-04-28 10:34:29 -07002919 ERR_error_string(err, NULL));
2920 if (tls_is_pin_error(err))
2921 return TLS_SET_PARAMS_ENGINE_PRV_BAD_PIN;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002922 return TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED;
2923 }
2924 if (!params.cert) {
2925 wpa_printf(MSG_ERROR, "ENGINE: did not properly cert with id"
2926 " '%s'", cert_id);
2927 return TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED;
2928 }
2929 *cert = params.cert;
2930 return 0;
2931}
2932#endif /* OPENSSL_NO_ENGINE */
2933
2934
2935static int tls_connection_engine_client_cert(struct tls_connection *conn,
2936 const char *cert_id)
2937{
2938#ifndef OPENSSL_NO_ENGINE
2939 X509 *cert;
2940
2941 if (tls_engine_get_cert(conn, cert_id, &cert))
2942 return -1;
2943
2944 if (!SSL_use_certificate(conn->ssl, cert)) {
2945 tls_show_errors(MSG_ERROR, __func__,
2946 "SSL_use_certificate failed");
2947 X509_free(cert);
2948 return -1;
2949 }
2950 X509_free(cert);
2951 wpa_printf(MSG_DEBUG, "ENGINE: SSL_use_certificate --> "
2952 "OK");
2953 return 0;
2954
2955#else /* OPENSSL_NO_ENGINE */
2956 return -1;
2957#endif /* OPENSSL_NO_ENGINE */
2958}
2959
2960
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002961static int tls_connection_engine_ca_cert(struct tls_data *data,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002962 struct tls_connection *conn,
2963 const char *ca_cert_id)
2964{
2965#ifndef OPENSSL_NO_ENGINE
2966 X509 *cert;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002967 SSL_CTX *ssl_ctx = data->ssl;
Dmitry Shmidt216983b2015-02-06 10:50:36 -08002968 X509_STORE *store;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002969
2970 if (tls_engine_get_cert(conn, ca_cert_id, &cert))
2971 return -1;
2972
2973 /* start off the same as tls_connection_ca_cert */
Dmitry Shmidt216983b2015-02-06 10:50:36 -08002974 store = X509_STORE_new();
2975 if (store == NULL) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002976 wpa_printf(MSG_DEBUG, "OpenSSL: %s - failed to allocate new "
2977 "certificate store", __func__);
2978 X509_free(cert);
2979 return -1;
2980 }
Dmitry Shmidt216983b2015-02-06 10:50:36 -08002981 SSL_CTX_set_cert_store(ssl_ctx, store);
2982 if (!X509_STORE_add_cert(store, cert)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002983 unsigned long err = ERR_peek_error();
2984 tls_show_errors(MSG_WARNING, __func__,
2985 "Failed to add CA certificate from engine "
2986 "to certificate store");
2987 if (ERR_GET_LIB(err) == ERR_LIB_X509 &&
2988 ERR_GET_REASON(err) == X509_R_CERT_ALREADY_IN_HASH_TABLE) {
2989 wpa_printf(MSG_DEBUG, "OpenSSL: %s - ignoring cert"
2990 " already in hash table error",
2991 __func__);
2992 } else {
2993 X509_free(cert);
2994 return -1;
2995 }
2996 }
2997 X509_free(cert);
2998 wpa_printf(MSG_DEBUG, "OpenSSL: %s - added CA certificate from engine "
2999 "to certificate store", __func__);
3000 SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003001 conn->ca_cert_verify = 1;
3002
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003003 return 0;
3004
3005#else /* OPENSSL_NO_ENGINE */
3006 return -1;
3007#endif /* OPENSSL_NO_ENGINE */
3008}
3009
3010
3011static int tls_connection_engine_private_key(struct tls_connection *conn)
3012{
Adam Langley1eb02ed2015-04-21 19:00:05 -07003013#if defined(ANDROID) || !defined(OPENSSL_NO_ENGINE)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003014 if (SSL_use_PrivateKey(conn->ssl, conn->private_key) != 1) {
3015 tls_show_errors(MSG_ERROR, __func__,
3016 "ENGINE: cannot use private key for TLS");
3017 return -1;
3018 }
3019 if (!SSL_check_private_key(conn->ssl)) {
3020 tls_show_errors(MSG_INFO, __func__,
3021 "Private key failed verification");
3022 return -1;
3023 }
3024 return 0;
3025#else /* OPENSSL_NO_ENGINE */
3026 wpa_printf(MSG_ERROR, "SSL: Configuration uses engine, but "
3027 "engine support was not compiled in");
3028 return -1;
3029#endif /* OPENSSL_NO_ENGINE */
3030}
3031
3032
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07003033static void tls_clear_default_passwd_cb(SSL_CTX *ssl_ctx, SSL *ssl)
3034{
3035#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) && !defined(OPENSSL_IS_BORINGSSL)
3036 if (ssl) {
3037 SSL_set_default_passwd_cb(ssl, NULL);
3038 SSL_set_default_passwd_cb_userdata(ssl, NULL);
3039 }
3040#endif /* >= 1.1.0f && !LibreSSL && !BoringSSL */
3041 SSL_CTX_set_default_passwd_cb(ssl_ctx, NULL);
3042 SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, NULL);
3043}
3044
3045
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003046static int tls_connection_private_key(struct tls_data *data,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003047 struct tls_connection *conn,
3048 const char *private_key,
3049 const char *private_key_passwd,
3050 const u8 *private_key_blob,
3051 size_t private_key_blob_len)
3052{
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003053 SSL_CTX *ssl_ctx = data->ssl;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003054 char *passwd;
3055 int ok;
3056
3057 if (private_key == NULL && private_key_blob == NULL)
3058 return 0;
3059
3060 if (private_key_passwd) {
3061 passwd = os_strdup(private_key_passwd);
3062 if (passwd == NULL)
3063 return -1;
3064 } else
3065 passwd = NULL;
3066
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07003067#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) && !defined(OPENSSL_IS_BORINGSSL)
3068 /*
3069 * In OpenSSL >= 1.1.0f SSL_use_PrivateKey_file() uses the callback
3070 * from the SSL object. See OpenSSL commit d61461a75253.
3071 */
3072 SSL_set_default_passwd_cb(conn->ssl, tls_passwd_cb);
3073 SSL_set_default_passwd_cb_userdata(conn->ssl, passwd);
3074#endif /* >= 1.1.0f && !LibreSSL && !BoringSSL */
3075 /* Keep these for OpenSSL < 1.1.0f */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003076 SSL_CTX_set_default_passwd_cb(ssl_ctx, tls_passwd_cb);
3077 SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, passwd);
3078
3079 ok = 0;
3080 while (private_key_blob) {
3081 if (SSL_use_PrivateKey_ASN1(EVP_PKEY_RSA, conn->ssl,
3082 (u8 *) private_key_blob,
3083 private_key_blob_len) == 1) {
3084 wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_PrivateKey_"
3085 "ASN1(EVP_PKEY_RSA) --> OK");
3086 ok = 1;
3087 break;
3088 }
3089
3090 if (SSL_use_PrivateKey_ASN1(EVP_PKEY_DSA, conn->ssl,
3091 (u8 *) private_key_blob,
3092 private_key_blob_len) == 1) {
3093 wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_PrivateKey_"
3094 "ASN1(EVP_PKEY_DSA) --> OK");
3095 ok = 1;
3096 break;
3097 }
3098
3099 if (SSL_use_RSAPrivateKey_ASN1(conn->ssl,
3100 (u8 *) private_key_blob,
3101 private_key_blob_len) == 1) {
3102 wpa_printf(MSG_DEBUG, "OpenSSL: "
3103 "SSL_use_RSAPrivateKey_ASN1 --> OK");
3104 ok = 1;
3105 break;
3106 }
3107
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003108 if (tls_read_pkcs12_blob(data, conn->ssl, private_key_blob,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003109 private_key_blob_len, passwd) == 0) {
3110 wpa_printf(MSG_DEBUG, "OpenSSL: PKCS#12 as blob --> "
3111 "OK");
3112 ok = 1;
3113 break;
3114 }
3115
3116 break;
3117 }
3118
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003119 while (!ok && private_key) {
3120#ifndef OPENSSL_NO_STDIO
3121 if (SSL_use_PrivateKey_file(conn->ssl, private_key,
3122 SSL_FILETYPE_ASN1) == 1) {
3123 wpa_printf(MSG_DEBUG, "OpenSSL: "
3124 "SSL_use_PrivateKey_File (DER) --> OK");
3125 ok = 1;
3126 break;
3127 }
3128
3129 if (SSL_use_PrivateKey_file(conn->ssl, private_key,
3130 SSL_FILETYPE_PEM) == 1) {
3131 wpa_printf(MSG_DEBUG, "OpenSSL: "
3132 "SSL_use_PrivateKey_File (PEM) --> OK");
3133 ok = 1;
3134 break;
3135 }
3136#else /* OPENSSL_NO_STDIO */
3137 wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO",
3138 __func__);
3139#endif /* OPENSSL_NO_STDIO */
3140
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003141 if (tls_read_pkcs12(data, conn->ssl, private_key, passwd)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003142 == 0) {
3143 wpa_printf(MSG_DEBUG, "OpenSSL: Reading PKCS#12 file "
3144 "--> OK");
3145 ok = 1;
3146 break;
3147 }
3148
3149 if (tls_cryptoapi_cert(conn->ssl, private_key) == 0) {
3150 wpa_printf(MSG_DEBUG, "OpenSSL: Using CryptoAPI to "
3151 "access certificate store --> OK");
3152 ok = 1;
3153 break;
3154 }
3155
3156 break;
3157 }
3158
3159 if (!ok) {
3160 tls_show_errors(MSG_INFO, __func__,
3161 "Failed to load private key");
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07003162 tls_clear_default_passwd_cb(ssl_ctx, conn->ssl);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003163 os_free(passwd);
3164 return -1;
3165 }
3166 ERR_clear_error();
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07003167 tls_clear_default_passwd_cb(ssl_ctx, conn->ssl);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003168 os_free(passwd);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003169
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003170 if (!SSL_check_private_key(conn->ssl)) {
3171 tls_show_errors(MSG_INFO, __func__, "Private key failed "
3172 "verification");
3173 return -1;
3174 }
3175
3176 wpa_printf(MSG_DEBUG, "SSL: Private key loaded successfully");
3177 return 0;
3178}
3179
3180
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003181static int tls_global_private_key(struct tls_data *data,
3182 const char *private_key,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003183 const char *private_key_passwd)
3184{
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003185 SSL_CTX *ssl_ctx = data->ssl;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003186 char *passwd;
3187
3188 if (private_key == NULL)
3189 return 0;
3190
3191 if (private_key_passwd) {
3192 passwd = os_strdup(private_key_passwd);
3193 if (passwd == NULL)
3194 return -1;
3195 } else
3196 passwd = NULL;
3197
3198 SSL_CTX_set_default_passwd_cb(ssl_ctx, tls_passwd_cb);
3199 SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, passwd);
3200 if (
3201#ifndef OPENSSL_NO_STDIO
3202 SSL_CTX_use_PrivateKey_file(ssl_ctx, private_key,
3203 SSL_FILETYPE_ASN1) != 1 &&
3204 SSL_CTX_use_PrivateKey_file(ssl_ctx, private_key,
3205 SSL_FILETYPE_PEM) != 1 &&
3206#endif /* OPENSSL_NO_STDIO */
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003207 tls_read_pkcs12(data, NULL, private_key, passwd)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003208 tls_show_errors(MSG_INFO, __func__,
3209 "Failed to load private key");
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07003210 tls_clear_default_passwd_cb(ssl_ctx, NULL);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003211 os_free(passwd);
3212 ERR_clear_error();
3213 return -1;
3214 }
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07003215 tls_clear_default_passwd_cb(ssl_ctx, NULL);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003216 os_free(passwd);
3217 ERR_clear_error();
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003218
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003219 if (!SSL_CTX_check_private_key(ssl_ctx)) {
3220 tls_show_errors(MSG_INFO, __func__,
3221 "Private key failed verification");
3222 return -1;
3223 }
3224
3225 return 0;
3226}
3227
3228
3229static int tls_connection_dh(struct tls_connection *conn, const char *dh_file)
3230{
3231#ifdef OPENSSL_NO_DH
3232 if (dh_file == NULL)
3233 return 0;
3234 wpa_printf(MSG_ERROR, "TLS: openssl does not include DH support, but "
3235 "dh_file specified");
3236 return -1;
3237#else /* OPENSSL_NO_DH */
3238 DH *dh;
3239 BIO *bio;
3240
3241 /* TODO: add support for dh_blob */
3242 if (dh_file == NULL)
3243 return 0;
3244 if (conn == NULL)
3245 return -1;
3246
3247 bio = BIO_new_file(dh_file, "r");
3248 if (bio == NULL) {
3249 wpa_printf(MSG_INFO, "TLS: Failed to open DH file '%s': %s",
3250 dh_file, ERR_error_string(ERR_get_error(), NULL));
3251 return -1;
3252 }
3253 dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
3254 BIO_free(bio);
3255#ifndef OPENSSL_NO_DSA
3256 while (dh == NULL) {
3257 DSA *dsa;
3258 wpa_printf(MSG_DEBUG, "TLS: Failed to parse DH file '%s': %s -"
3259 " trying to parse as DSA params", dh_file,
3260 ERR_error_string(ERR_get_error(), NULL));
3261 bio = BIO_new_file(dh_file, "r");
3262 if (bio == NULL)
3263 break;
3264 dsa = PEM_read_bio_DSAparams(bio, NULL, NULL, NULL);
3265 BIO_free(bio);
3266 if (!dsa) {
3267 wpa_printf(MSG_DEBUG, "TLS: Failed to parse DSA file "
3268 "'%s': %s", dh_file,
3269 ERR_error_string(ERR_get_error(), NULL));
3270 break;
3271 }
3272
3273 wpa_printf(MSG_DEBUG, "TLS: DH file in DSA param format");
3274 dh = DSA_dup_DH(dsa);
3275 DSA_free(dsa);
3276 if (dh == NULL) {
3277 wpa_printf(MSG_INFO, "TLS: Failed to convert DSA "
3278 "params into DH params");
3279 break;
3280 }
3281 break;
3282 }
3283#endif /* !OPENSSL_NO_DSA */
3284 if (dh == NULL) {
3285 wpa_printf(MSG_INFO, "TLS: Failed to read/parse DH/DSA file "
3286 "'%s'", dh_file);
3287 return -1;
3288 }
3289
3290 if (SSL_set_tmp_dh(conn->ssl, dh) != 1) {
3291 wpa_printf(MSG_INFO, "TLS: Failed to set DH params from '%s': "
3292 "%s", dh_file,
3293 ERR_error_string(ERR_get_error(), NULL));
3294 DH_free(dh);
3295 return -1;
3296 }
3297 DH_free(dh);
3298 return 0;
3299#endif /* OPENSSL_NO_DH */
3300}
3301
3302
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003303static int tls_global_dh(struct tls_data *data, const char *dh_file)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003304{
3305#ifdef OPENSSL_NO_DH
3306 if (dh_file == NULL)
3307 return 0;
3308 wpa_printf(MSG_ERROR, "TLS: openssl does not include DH support, but "
3309 "dh_file specified");
3310 return -1;
3311#else /* OPENSSL_NO_DH */
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003312 SSL_CTX *ssl_ctx = data->ssl;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003313 DH *dh;
3314 BIO *bio;
3315
3316 /* TODO: add support for dh_blob */
3317 if (dh_file == NULL)
3318 return 0;
3319 if (ssl_ctx == NULL)
3320 return -1;
3321
3322 bio = BIO_new_file(dh_file, "r");
3323 if (bio == NULL) {
3324 wpa_printf(MSG_INFO, "TLS: Failed to open DH file '%s': %s",
3325 dh_file, ERR_error_string(ERR_get_error(), NULL));
3326 return -1;
3327 }
3328 dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
3329 BIO_free(bio);
3330#ifndef OPENSSL_NO_DSA
3331 while (dh == NULL) {
3332 DSA *dsa;
3333 wpa_printf(MSG_DEBUG, "TLS: Failed to parse DH file '%s': %s -"
3334 " trying to parse as DSA params", dh_file,
3335 ERR_error_string(ERR_get_error(), NULL));
3336 bio = BIO_new_file(dh_file, "r");
3337 if (bio == NULL)
3338 break;
3339 dsa = PEM_read_bio_DSAparams(bio, NULL, NULL, NULL);
3340 BIO_free(bio);
3341 if (!dsa) {
3342 wpa_printf(MSG_DEBUG, "TLS: Failed to parse DSA file "
3343 "'%s': %s", dh_file,
3344 ERR_error_string(ERR_get_error(), NULL));
3345 break;
3346 }
3347
3348 wpa_printf(MSG_DEBUG, "TLS: DH file in DSA param format");
3349 dh = DSA_dup_DH(dsa);
3350 DSA_free(dsa);
3351 if (dh == NULL) {
3352 wpa_printf(MSG_INFO, "TLS: Failed to convert DSA "
3353 "params into DH params");
3354 break;
3355 }
3356 break;
3357 }
3358#endif /* !OPENSSL_NO_DSA */
3359 if (dh == NULL) {
3360 wpa_printf(MSG_INFO, "TLS: Failed to read/parse DH/DSA file "
3361 "'%s'", dh_file);
3362 return -1;
3363 }
3364
3365 if (SSL_CTX_set_tmp_dh(ssl_ctx, dh) != 1) {
3366 wpa_printf(MSG_INFO, "TLS: Failed to set DH params from '%s': "
3367 "%s", dh_file,
3368 ERR_error_string(ERR_get_error(), NULL));
3369 DH_free(dh);
3370 return -1;
3371 }
3372 DH_free(dh);
3373 return 0;
3374#endif /* OPENSSL_NO_DH */
3375}
3376
3377
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003378int tls_connection_get_random(void *ssl_ctx, struct tls_connection *conn,
3379 struct tls_random *keys)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003380{
3381 SSL *ssl;
3382
3383 if (conn == NULL || keys == NULL)
3384 return -1;
3385 ssl = conn->ssl;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003386 if (ssl == NULL)
3387 return -1;
3388
3389 os_memset(keys, 0, sizeof(*keys));
3390 keys->client_random = conn->client_random;
3391 keys->client_random_len = SSL_get_client_random(
3392 ssl, conn->client_random, sizeof(conn->client_random));
3393 keys->server_random = conn->server_random;
3394 keys->server_random_len = SSL_get_server_random(
3395 ssl, conn->server_random, sizeof(conn->server_random));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003396
3397 return 0;
3398}
3399
3400
Dmitry Shmidt849734c2016-05-27 09:59:01 -07003401#ifdef OPENSSL_NEED_EAP_FAST_PRF
Dmitry Shmidtaf9da312015-04-03 10:03:11 -07003402static int openssl_get_keyblock_size(SSL *ssl)
3403{
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08003404#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
Dmitry Shmidtaf9da312015-04-03 10:03:11 -07003405 const EVP_CIPHER *c;
3406 const EVP_MD *h;
3407 int md_size;
3408
3409 if (ssl->enc_read_ctx == NULL || ssl->enc_read_ctx->cipher == NULL ||
3410 ssl->read_hash == NULL)
3411 return -1;
3412
3413 c = ssl->enc_read_ctx->cipher;
Dmitry Shmidtaf9da312015-04-03 10:03:11 -07003414 h = EVP_MD_CTX_md(ssl->read_hash);
Dmitry Shmidtaf9da312015-04-03 10:03:11 -07003415 if (h)
3416 md_size = EVP_MD_size(h);
Dmitry Shmidtaf9da312015-04-03 10:03:11 -07003417 else if (ssl->s3)
3418 md_size = ssl->s3->tmp.new_mac_secret_size;
Dmitry Shmidtaf9da312015-04-03 10:03:11 -07003419 else
3420 return -1;
3421
3422 wpa_printf(MSG_DEBUG, "OpenSSL: keyblock size: key_len=%d MD_size=%d "
3423 "IV_len=%d", EVP_CIPHER_key_length(c), md_size,
3424 EVP_CIPHER_iv_length(c));
3425 return 2 * (EVP_CIPHER_key_length(c) +
3426 md_size +
3427 EVP_CIPHER_iv_length(c));
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003428#else
3429 const SSL_CIPHER *ssl_cipher;
3430 int cipher, digest;
3431 const EVP_CIPHER *c;
3432 const EVP_MD *h;
3433
3434 ssl_cipher = SSL_get_current_cipher(ssl);
3435 if (!ssl_cipher)
3436 return -1;
3437 cipher = SSL_CIPHER_get_cipher_nid(ssl_cipher);
3438 digest = SSL_CIPHER_get_digest_nid(ssl_cipher);
3439 wpa_printf(MSG_DEBUG, "OpenSSL: cipher nid %d digest nid %d",
3440 cipher, digest);
3441 if (cipher < 0 || digest < 0)
3442 return -1;
3443 c = EVP_get_cipherbynid(cipher);
3444 h = EVP_get_digestbynid(digest);
3445 if (!c || !h)
3446 return -1;
3447
3448 wpa_printf(MSG_DEBUG,
3449 "OpenSSL: keyblock size: key_len=%d MD_size=%d IV_len=%d",
3450 EVP_CIPHER_key_length(c), EVP_MD_size(h),
3451 EVP_CIPHER_iv_length(c));
3452 return 2 * (EVP_CIPHER_key_length(c) + EVP_MD_size(h) +
3453 EVP_CIPHER_iv_length(c));
3454#endif
Dmitry Shmidtaf9da312015-04-03 10:03:11 -07003455}
Dmitry Shmidt849734c2016-05-27 09:59:01 -07003456#endif /* OPENSSL_NEED_EAP_FAST_PRF */
Dmitry Shmidtaf9da312015-04-03 10:03:11 -07003457
3458
Dmitry Shmidt849734c2016-05-27 09:59:01 -07003459int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn,
3460 const char *label, u8 *out, size_t out_len)
Dmitry Shmidtaf9da312015-04-03 10:03:11 -07003461{
Dmitry Shmidt849734c2016-05-27 09:59:01 -07003462 if (!conn ||
3463 SSL_export_keying_material(conn->ssl, out, out_len, label,
3464 os_strlen(label), NULL, 0, 0) != 1)
3465 return -1;
3466 return 0;
3467}
3468
3469
3470int tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn,
3471 u8 *out, size_t out_len)
3472{
3473#ifdef OPENSSL_NEED_EAP_FAST_PRF
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003474 SSL *ssl;
3475 SSL_SESSION *sess;
3476 u8 *rnd;
3477 int ret = -1;
3478 int skip = 0;
3479 u8 *tmp_out = NULL;
3480 u8 *_out = out;
3481 unsigned char client_random[SSL3_RANDOM_SIZE];
3482 unsigned char server_random[SSL3_RANDOM_SIZE];
3483 unsigned char master_key[64];
3484 size_t master_key_len;
3485 const char *ver;
3486
3487 /*
Dmitry Shmidt849734c2016-05-27 09:59:01 -07003488 * TLS library did not support EAP-FAST key generation, so get the
3489 * needed TLS session parameters and use an internal implementation of
3490 * TLS PRF to derive the key.
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003491 */
3492
3493 if (conn == NULL)
3494 return -1;
3495 ssl = conn->ssl;
3496 if (ssl == NULL)
3497 return -1;
3498 ver = SSL_get_version(ssl);
3499 sess = SSL_get_session(ssl);
3500 if (!ver || !sess)
3501 return -1;
3502
Dmitry Shmidt849734c2016-05-27 09:59:01 -07003503 skip = openssl_get_keyblock_size(ssl);
3504 if (skip < 0)
3505 return -1;
3506 tmp_out = os_malloc(skip + out_len);
3507 if (!tmp_out)
3508 return -1;
3509 _out = tmp_out;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003510
3511 rnd = os_malloc(2 * SSL3_RANDOM_SIZE);
3512 if (!rnd) {
3513 os_free(tmp_out);
3514 return -1;
3515 }
3516
3517 SSL_get_client_random(ssl, client_random, sizeof(client_random));
3518 SSL_get_server_random(ssl, server_random, sizeof(server_random));
3519 master_key_len = SSL_SESSION_get_master_key(sess, master_key,
3520 sizeof(master_key));
3521
Dmitry Shmidt849734c2016-05-27 09:59:01 -07003522 os_memcpy(rnd, server_random, SSL3_RANDOM_SIZE);
3523 os_memcpy(rnd + SSL3_RANDOM_SIZE, client_random, SSL3_RANDOM_SIZE);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003524
3525 if (os_strcmp(ver, "TLSv1.2") == 0) {
3526 tls_prf_sha256(master_key, master_key_len,
Dmitry Shmidt849734c2016-05-27 09:59:01 -07003527 "key expansion", rnd, 2 * SSL3_RANDOM_SIZE,
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003528 _out, skip + out_len);
3529 ret = 0;
3530 } else if (tls_prf_sha1_md5(master_key, master_key_len,
Dmitry Shmidt849734c2016-05-27 09:59:01 -07003531 "key expansion", rnd, 2 * SSL3_RANDOM_SIZE,
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003532 _out, skip + out_len) == 0) {
3533 ret = 0;
3534 }
3535 os_memset(master_key, 0, sizeof(master_key));
3536 os_free(rnd);
Dmitry Shmidt849734c2016-05-27 09:59:01 -07003537 if (ret == 0)
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003538 os_memcpy(out, _out + skip, out_len);
3539 bin_clear_free(tmp_out, skip);
3540
3541 return ret;
Dmitry Shmidt849734c2016-05-27 09:59:01 -07003542#else /* OPENSSL_NEED_EAP_FAST_PRF */
3543 wpa_printf(MSG_ERROR,
3544 "OpenSSL: EAP-FAST keys cannot be exported in FIPS mode");
3545 return -1;
3546#endif /* OPENSSL_NEED_EAP_FAST_PRF */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003547}
3548
3549
3550static struct wpabuf *
3551openssl_handshake(struct tls_connection *conn, const struct wpabuf *in_data,
3552 int server)
3553{
3554 int res;
3555 struct wpabuf *out_data;
3556
3557 /*
3558 * Give TLS handshake data from the server (if available) to OpenSSL
3559 * for processing.
3560 */
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003561 if (in_data && wpabuf_len(in_data) > 0 &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003562 BIO_write(conn->ssl_in, wpabuf_head(in_data), wpabuf_len(in_data))
3563 < 0) {
3564 tls_show_errors(MSG_INFO, __func__,
3565 "Handshake failed - BIO_write");
3566 return NULL;
3567 }
3568
3569 /* Initiate TLS handshake or continue the existing handshake */
3570 if (server)
3571 res = SSL_accept(conn->ssl);
3572 else
3573 res = SSL_connect(conn->ssl);
3574 if (res != 1) {
3575 int err = SSL_get_error(conn->ssl, res);
3576 if (err == SSL_ERROR_WANT_READ)
3577 wpa_printf(MSG_DEBUG, "SSL: SSL_connect - want "
3578 "more data");
3579 else if (err == SSL_ERROR_WANT_WRITE)
3580 wpa_printf(MSG_DEBUG, "SSL: SSL_connect - want to "
3581 "write");
3582 else {
3583 tls_show_errors(MSG_INFO, __func__, "SSL_connect");
3584 conn->failed++;
3585 }
3586 }
3587
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07003588#ifdef CONFIG_SUITEB
3589 if ((conn->flags & TLS_CONN_SUITEB) && !server &&
3590 os_strncmp(SSL_get_cipher(conn->ssl), "DHE-", 4) == 0 &&
3591 conn->server_dh_prime_len < 3072) {
3592 struct tls_context *context = conn->context;
3593
3594 /*
3595 * This should not be reached since earlier cert_cb should have
3596 * terminated the handshake. Keep this check here for extra
3597 * protection if anything goes wrong with the more low-level
3598 * checks based on having to parse the TLS handshake messages.
3599 */
3600 wpa_printf(MSG_DEBUG,
3601 "OpenSSL: Server DH prime length: %d bits",
3602 conn->server_dh_prime_len);
3603
3604 if (context->event_cb) {
3605 union tls_event_data ev;
3606
3607 os_memset(&ev, 0, sizeof(ev));
3608 ev.alert.is_local = 1;
3609 ev.alert.type = "fatal";
3610 ev.alert.description = "insufficient security";
3611 context->event_cb(context->cb_ctx, TLS_ALERT, &ev);
3612 }
3613 /*
3614 * Could send a TLS Alert to the server, but for now, simply
3615 * terminate handshake.
3616 */
3617 conn->failed++;
3618 conn->write_alerts++;
3619 return NULL;
3620 }
3621#endif /* CONFIG_SUITEB */
3622
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003623 /* Get the TLS handshake data to be sent to the server */
3624 res = BIO_ctrl_pending(conn->ssl_out);
3625 wpa_printf(MSG_DEBUG, "SSL: %d bytes pending from ssl_out", res);
3626 out_data = wpabuf_alloc(res);
3627 if (out_data == NULL) {
3628 wpa_printf(MSG_DEBUG, "SSL: Failed to allocate memory for "
3629 "handshake output (%d bytes)", res);
3630 if (BIO_reset(conn->ssl_out) < 0) {
3631 tls_show_errors(MSG_INFO, __func__,
3632 "BIO_reset failed");
3633 }
3634 return NULL;
3635 }
3636 res = res == 0 ? 0 : BIO_read(conn->ssl_out, wpabuf_mhead(out_data),
3637 res);
3638 if (res < 0) {
3639 tls_show_errors(MSG_INFO, __func__,
3640 "Handshake failed - BIO_read");
3641 if (BIO_reset(conn->ssl_out) < 0) {
3642 tls_show_errors(MSG_INFO, __func__,
3643 "BIO_reset failed");
3644 }
3645 wpabuf_free(out_data);
3646 return NULL;
3647 }
3648 wpabuf_put(out_data, res);
3649
3650 return out_data;
3651}
3652
3653
3654static struct wpabuf *
3655openssl_get_appl_data(struct tls_connection *conn, size_t max_len)
3656{
3657 struct wpabuf *appl_data;
3658 int res;
3659
3660 appl_data = wpabuf_alloc(max_len + 100);
3661 if (appl_data == NULL)
3662 return NULL;
3663
3664 res = SSL_read(conn->ssl, wpabuf_mhead(appl_data),
3665 wpabuf_size(appl_data));
3666 if (res < 0) {
3667 int err = SSL_get_error(conn->ssl, res);
3668 if (err == SSL_ERROR_WANT_READ ||
3669 err == SSL_ERROR_WANT_WRITE) {
3670 wpa_printf(MSG_DEBUG, "SSL: No Application Data "
3671 "included");
3672 } else {
3673 tls_show_errors(MSG_INFO, __func__,
3674 "Failed to read possible "
3675 "Application Data");
3676 }
3677 wpabuf_free(appl_data);
3678 return NULL;
3679 }
3680
3681 wpabuf_put(appl_data, res);
3682 wpa_hexdump_buf_key(MSG_MSGDUMP, "SSL: Application Data in Finished "
3683 "message", appl_data);
3684
3685 return appl_data;
3686}
3687
3688
3689static struct wpabuf *
3690openssl_connection_handshake(struct tls_connection *conn,
3691 const struct wpabuf *in_data,
3692 struct wpabuf **appl_data, int server)
3693{
3694 struct wpabuf *out_data;
3695
3696 if (appl_data)
3697 *appl_data = NULL;
3698
3699 out_data = openssl_handshake(conn, in_data, server);
3700 if (out_data == NULL)
3701 return NULL;
Jouni Malinen26af48b2014-04-09 13:02:53 +03003702 if (conn->invalid_hb_used) {
3703 wpa_printf(MSG_INFO, "TLS: Heartbeat attack detected - do not send response");
3704 wpabuf_free(out_data);
3705 return NULL;
3706 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003707
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003708 if (SSL_is_init_finished(conn->ssl)) {
3709 wpa_printf(MSG_DEBUG,
3710 "OpenSSL: Handshake finished - resumed=%d",
3711 tls_connection_resumed(conn->ssl_ctx, conn));
3712 if (appl_data && in_data)
3713 *appl_data = openssl_get_appl_data(conn,
3714 wpabuf_len(in_data));
3715 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003716
Jouni Malinen26af48b2014-04-09 13:02:53 +03003717 if (conn->invalid_hb_used) {
3718 wpa_printf(MSG_INFO, "TLS: Heartbeat attack detected - do not send response");
3719 if (appl_data) {
3720 wpabuf_free(*appl_data);
3721 *appl_data = NULL;
3722 }
3723 wpabuf_free(out_data);
3724 return NULL;
3725 }
3726
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003727 return out_data;
3728}
3729
3730
3731struct wpabuf *
3732tls_connection_handshake(void *ssl_ctx, struct tls_connection *conn,
3733 const struct wpabuf *in_data,
3734 struct wpabuf **appl_data)
3735{
3736 return openssl_connection_handshake(conn, in_data, appl_data, 0);
3737}
3738
3739
3740struct wpabuf * tls_connection_server_handshake(void *tls_ctx,
3741 struct tls_connection *conn,
3742 const struct wpabuf *in_data,
3743 struct wpabuf **appl_data)
3744{
3745 return openssl_connection_handshake(conn, in_data, appl_data, 1);
3746}
3747
3748
3749struct wpabuf * tls_connection_encrypt(void *tls_ctx,
3750 struct tls_connection *conn,
3751 const struct wpabuf *in_data)
3752{
3753 int res;
3754 struct wpabuf *buf;
3755
3756 if (conn == NULL)
3757 return NULL;
3758
3759 /* Give plaintext data for OpenSSL to encrypt into the TLS tunnel. */
3760 if ((res = BIO_reset(conn->ssl_in)) < 0 ||
3761 (res = BIO_reset(conn->ssl_out)) < 0) {
3762 tls_show_errors(MSG_INFO, __func__, "BIO_reset failed");
3763 return NULL;
3764 }
3765 res = SSL_write(conn->ssl, wpabuf_head(in_data), wpabuf_len(in_data));
3766 if (res < 0) {
3767 tls_show_errors(MSG_INFO, __func__,
3768 "Encryption failed - SSL_write");
3769 return NULL;
3770 }
3771
3772 /* Read encrypted data to be sent to the server */
3773 buf = wpabuf_alloc(wpabuf_len(in_data) + 300);
3774 if (buf == NULL)
3775 return NULL;
3776 res = BIO_read(conn->ssl_out, wpabuf_mhead(buf), wpabuf_size(buf));
3777 if (res < 0) {
3778 tls_show_errors(MSG_INFO, __func__,
3779 "Encryption failed - BIO_read");
3780 wpabuf_free(buf);
3781 return NULL;
3782 }
3783 wpabuf_put(buf, res);
3784
3785 return buf;
3786}
3787
3788
3789struct wpabuf * tls_connection_decrypt(void *tls_ctx,
3790 struct tls_connection *conn,
3791 const struct wpabuf *in_data)
3792{
3793 int res;
3794 struct wpabuf *buf;
3795
3796 /* Give encrypted data from TLS tunnel for OpenSSL to decrypt. */
3797 res = BIO_write(conn->ssl_in, wpabuf_head(in_data),
3798 wpabuf_len(in_data));
3799 if (res < 0) {
3800 tls_show_errors(MSG_INFO, __func__,
3801 "Decryption failed - BIO_write");
3802 return NULL;
3803 }
3804 if (BIO_reset(conn->ssl_out) < 0) {
3805 tls_show_errors(MSG_INFO, __func__, "BIO_reset failed");
3806 return NULL;
3807 }
3808
3809 /* Read decrypted data for further processing */
3810 /*
3811 * Even though we try to disable TLS compression, it is possible that
3812 * this cannot be done with all TLS libraries. Add extra buffer space
3813 * to handle the possibility of the decrypted data being longer than
3814 * input data.
3815 */
3816 buf = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3);
3817 if (buf == NULL)
3818 return NULL;
3819 res = SSL_read(conn->ssl, wpabuf_mhead(buf), wpabuf_size(buf));
3820 if (res < 0) {
3821 tls_show_errors(MSG_INFO, __func__,
3822 "Decryption failed - SSL_read");
3823 wpabuf_free(buf);
3824 return NULL;
3825 }
3826 wpabuf_put(buf, res);
3827
Jouni Malinen26af48b2014-04-09 13:02:53 +03003828 if (conn->invalid_hb_used) {
3829 wpa_printf(MSG_INFO, "TLS: Heartbeat attack detected - do not send response");
3830 wpabuf_free(buf);
3831 return NULL;
3832 }
3833
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003834 return buf;
3835}
3836
3837
3838int tls_connection_resumed(void *ssl_ctx, struct tls_connection *conn)
3839{
Dmitry Shmidt216983b2015-02-06 10:50:36 -08003840 return conn ? SSL_cache_hit(conn->ssl) : 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003841}
3842
3843
3844int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn,
3845 u8 *ciphers)
3846{
Dmitry Shmidtde47be72016-01-07 12:52:55 -08003847 char buf[500], *pos, *end;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003848 u8 *c;
3849 int ret;
3850
3851 if (conn == NULL || conn->ssl == NULL || ciphers == NULL)
3852 return -1;
3853
3854 buf[0] = '\0';
3855 pos = buf;
3856 end = pos + sizeof(buf);
3857
3858 c = ciphers;
3859 while (*c != TLS_CIPHER_NONE) {
3860 const char *suite;
3861
3862 switch (*c) {
3863 case TLS_CIPHER_RC4_SHA:
3864 suite = "RC4-SHA";
3865 break;
3866 case TLS_CIPHER_AES128_SHA:
3867 suite = "AES128-SHA";
3868 break;
3869 case TLS_CIPHER_RSA_DHE_AES128_SHA:
3870 suite = "DHE-RSA-AES128-SHA";
3871 break;
3872 case TLS_CIPHER_ANON_DH_AES128_SHA:
3873 suite = "ADH-AES128-SHA";
3874 break;
Dmitry Shmidtde47be72016-01-07 12:52:55 -08003875 case TLS_CIPHER_RSA_DHE_AES256_SHA:
3876 suite = "DHE-RSA-AES256-SHA";
3877 break;
3878 case TLS_CIPHER_AES256_SHA:
3879 suite = "AES256-SHA";
3880 break;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003881 default:
3882 wpa_printf(MSG_DEBUG, "TLS: Unsupported "
3883 "cipher selection: %d", *c);
3884 return -1;
3885 }
3886 ret = os_snprintf(pos, end - pos, ":%s", suite);
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08003887 if (os_snprintf_error(end - pos, ret))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003888 break;
3889 pos += ret;
3890
3891 c++;
3892 }
3893
3894 wpa_printf(MSG_DEBUG, "OpenSSL: cipher suites: %s", buf + 1);
3895
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08003896#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003897#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
3898 if (os_strstr(buf, ":ADH-")) {
3899 /*
3900 * Need to drop to security level 0 to allow anonymous
3901 * cipher suites for EAP-FAST.
3902 */
3903 SSL_set_security_level(conn->ssl, 0);
3904 } else if (SSL_get_security_level(conn->ssl) == 0) {
3905 /* Force at least security level 1 */
3906 SSL_set_security_level(conn->ssl, 1);
3907 }
3908#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
3909#endif
3910
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003911 if (SSL_set_cipher_list(conn->ssl, buf + 1) != 1) {
3912 tls_show_errors(MSG_INFO, __func__,
3913 "Cipher suite configuration failed");
3914 return -1;
3915 }
3916
3917 return 0;
3918}
3919
3920
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003921int tls_get_version(void *ssl_ctx, struct tls_connection *conn,
3922 char *buf, size_t buflen)
3923{
3924 const char *name;
3925 if (conn == NULL || conn->ssl == NULL)
3926 return -1;
3927
3928 name = SSL_get_version(conn->ssl);
3929 if (name == NULL)
3930 return -1;
3931
3932 os_strlcpy(buf, name, buflen);
3933 return 0;
3934}
3935
3936
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003937int tls_get_cipher(void *ssl_ctx, struct tls_connection *conn,
3938 char *buf, size_t buflen)
3939{
3940 const char *name;
3941 if (conn == NULL || conn->ssl == NULL)
3942 return -1;
3943
3944 name = SSL_get_cipher(conn->ssl);
3945 if (name == NULL)
3946 return -1;
3947
3948 os_strlcpy(buf, name, buflen);
3949 return 0;
3950}
3951
3952
3953int tls_connection_enable_workaround(void *ssl_ctx,
3954 struct tls_connection *conn)
3955{
3956 SSL_set_options(conn->ssl, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
3957
3958 return 0;
3959}
3960
3961
3962#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
3963/* ClientHello TLS extensions require a patch to openssl, so this function is
3964 * commented out unless explicitly needed for EAP-FAST in order to be able to
3965 * build this file with unmodified openssl. */
3966int tls_connection_client_hello_ext(void *ssl_ctx, struct tls_connection *conn,
3967 int ext_type, const u8 *data,
3968 size_t data_len)
3969{
3970 if (conn == NULL || conn->ssl == NULL || ext_type != 35)
3971 return -1;
3972
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003973 if (SSL_set_session_ticket_ext(conn->ssl, (void *) data,
3974 data_len) != 1)
3975 return -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003976
3977 return 0;
3978}
3979#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
3980
3981
3982int tls_connection_get_failed(void *ssl_ctx, struct tls_connection *conn)
3983{
3984 if (conn == NULL)
3985 return -1;
3986 return conn->failed;
3987}
3988
3989
3990int tls_connection_get_read_alerts(void *ssl_ctx, struct tls_connection *conn)
3991{
3992 if (conn == NULL)
3993 return -1;
3994 return conn->read_alerts;
3995}
3996
3997
3998int tls_connection_get_write_alerts(void *ssl_ctx, struct tls_connection *conn)
3999{
4000 if (conn == NULL)
4001 return -1;
4002 return conn->write_alerts;
4003}
4004
4005
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004006#ifdef HAVE_OCSP
4007
4008static void ocsp_debug_print_resp(OCSP_RESPONSE *rsp)
4009{
4010#ifndef CONFIG_NO_STDOUT_DEBUG
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004011 BIO *out;
4012 size_t rlen;
4013 char *txt;
4014 int res;
4015
4016 if (wpa_debug_level > MSG_DEBUG)
4017 return;
4018
4019 out = BIO_new(BIO_s_mem());
4020 if (!out)
4021 return;
4022
4023 OCSP_RESPONSE_print(out, rsp, 0);
4024 rlen = BIO_ctrl_pending(out);
4025 txt = os_malloc(rlen + 1);
4026 if (!txt) {
4027 BIO_free(out);
4028 return;
4029 }
4030
4031 res = BIO_read(out, txt, rlen);
4032 if (res > 0) {
4033 txt[res] = '\0';
4034 wpa_printf(MSG_DEBUG, "OpenSSL: OCSP Response\n%s", txt);
4035 }
4036 os_free(txt);
4037 BIO_free(out);
4038#endif /* CONFIG_NO_STDOUT_DEBUG */
4039}
4040
4041
Dmitry Shmidt71757432014-06-02 13:50:35 -07004042static void debug_print_cert(X509 *cert, const char *title)
4043{
4044#ifndef CONFIG_NO_STDOUT_DEBUG
4045 BIO *out;
4046 size_t rlen;
4047 char *txt;
4048 int res;
4049
4050 if (wpa_debug_level > MSG_DEBUG)
4051 return;
4052
4053 out = BIO_new(BIO_s_mem());
4054 if (!out)
4055 return;
4056
4057 X509_print(out, cert);
4058 rlen = BIO_ctrl_pending(out);
4059 txt = os_malloc(rlen + 1);
4060 if (!txt) {
4061 BIO_free(out);
4062 return;
4063 }
4064
4065 res = BIO_read(out, txt, rlen);
4066 if (res > 0) {
4067 txt[res] = '\0';
4068 wpa_printf(MSG_DEBUG, "OpenSSL: %s\n%s", title, txt);
4069 }
4070 os_free(txt);
4071
4072 BIO_free(out);
4073#endif /* CONFIG_NO_STDOUT_DEBUG */
4074}
4075
4076
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004077static int ocsp_resp_cb(SSL *s, void *arg)
4078{
4079 struct tls_connection *conn = arg;
4080 const unsigned char *p;
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07004081 int len, status, reason, res;
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004082 OCSP_RESPONSE *rsp;
4083 OCSP_BASICRESP *basic;
4084 OCSP_CERTID *id;
4085 ASN1_GENERALIZEDTIME *produced_at, *this_update, *next_update;
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004086 X509_STORE *store;
4087 STACK_OF(X509) *certs = NULL;
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004088
4089 len = SSL_get_tlsext_status_ocsp_resp(s, &p);
4090 if (!p) {
4091 wpa_printf(MSG_DEBUG, "OpenSSL: No OCSP response received");
4092 return (conn->flags & TLS_CONN_REQUIRE_OCSP) ? 0 : 1;
4093 }
4094
4095 wpa_hexdump(MSG_DEBUG, "OpenSSL: OCSP response", p, len);
4096
4097 rsp = d2i_OCSP_RESPONSE(NULL, &p, len);
4098 if (!rsp) {
4099 wpa_printf(MSG_INFO, "OpenSSL: Failed to parse OCSP response");
4100 return 0;
4101 }
4102
4103 ocsp_debug_print_resp(rsp);
4104
4105 status = OCSP_response_status(rsp);
4106 if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
4107 wpa_printf(MSG_INFO, "OpenSSL: OCSP responder error %d (%s)",
4108 status, OCSP_response_status_str(status));
4109 return 0;
4110 }
4111
4112 basic = OCSP_response_get1_basic(rsp);
4113 if (!basic) {
4114 wpa_printf(MSG_INFO, "OpenSSL: Could not find BasicOCSPResponse");
4115 return 0;
4116 }
4117
Dmitry Shmidt216983b2015-02-06 10:50:36 -08004118 store = SSL_CTX_get_cert_store(conn->ssl_ctx);
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004119 if (conn->peer_issuer) {
Dmitry Shmidt71757432014-06-02 13:50:35 -07004120 debug_print_cert(conn->peer_issuer, "Add OCSP issuer");
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004121
4122 if (X509_STORE_add_cert(store, conn->peer_issuer) != 1) {
4123 tls_show_errors(MSG_INFO, __func__,
Dmitry Shmidt7f656022015-02-25 14:36:37 -08004124 "OpenSSL: Could not add issuer to certificate store");
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004125 }
4126 certs = sk_X509_new_null();
4127 if (certs) {
4128 X509 *cert;
4129 cert = X509_dup(conn->peer_issuer);
4130 if (cert && !sk_X509_push(certs, cert)) {
4131 tls_show_errors(
4132 MSG_INFO, __func__,
Dmitry Shmidt7f656022015-02-25 14:36:37 -08004133 "OpenSSL: Could not add issuer to OCSP responder trust store");
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004134 X509_free(cert);
4135 sk_X509_free(certs);
4136 certs = NULL;
4137 }
Dmitry Shmidt7f656022015-02-25 14:36:37 -08004138 if (certs && conn->peer_issuer_issuer) {
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004139 cert = X509_dup(conn->peer_issuer_issuer);
4140 if (cert && !sk_X509_push(certs, cert)) {
4141 tls_show_errors(
4142 MSG_INFO, __func__,
Dmitry Shmidt7f656022015-02-25 14:36:37 -08004143 "OpenSSL: Could not add issuer's issuer to OCSP responder trust store");
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004144 X509_free(cert);
4145 }
4146 }
4147 }
4148 }
4149
4150 status = OCSP_basic_verify(basic, certs, store, OCSP_TRUSTOTHER);
4151 sk_X509_pop_free(certs, X509_free);
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004152 if (status <= 0) {
4153 tls_show_errors(MSG_INFO, __func__,
4154 "OpenSSL: OCSP response failed verification");
4155 OCSP_BASICRESP_free(basic);
4156 OCSP_RESPONSE_free(rsp);
4157 return 0;
4158 }
4159
4160 wpa_printf(MSG_DEBUG, "OpenSSL: OCSP response verification succeeded");
4161
Dmitry Shmidt56052862013-10-04 10:23:25 -07004162 if (!conn->peer_cert) {
4163 wpa_printf(MSG_DEBUG, "OpenSSL: Peer certificate not available for OCSP status check");
4164 OCSP_BASICRESP_free(basic);
4165 OCSP_RESPONSE_free(rsp);
4166 return 0;
4167 }
4168
4169 if (!conn->peer_issuer) {
4170 wpa_printf(MSG_DEBUG, "OpenSSL: Peer issuer certificate not available for OCSP status check");
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004171 OCSP_BASICRESP_free(basic);
4172 OCSP_RESPONSE_free(rsp);
4173 return 0;
4174 }
4175
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07004176 id = OCSP_cert_to_id(EVP_sha256(), conn->peer_cert, conn->peer_issuer);
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004177 if (!id) {
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07004178 wpa_printf(MSG_DEBUG,
4179 "OpenSSL: Could not create OCSP certificate identifier (SHA256)");
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004180 OCSP_BASICRESP_free(basic);
4181 OCSP_RESPONSE_free(rsp);
4182 return 0;
4183 }
4184
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07004185 res = OCSP_resp_find_status(basic, id, &status, &reason, &produced_at,
4186 &this_update, &next_update);
4187 if (!res) {
4188 id = OCSP_cert_to_id(NULL, conn->peer_cert, conn->peer_issuer);
4189 if (!id) {
4190 wpa_printf(MSG_DEBUG,
4191 "OpenSSL: Could not create OCSP certificate identifier (SHA1)");
4192 OCSP_BASICRESP_free(basic);
4193 OCSP_RESPONSE_free(rsp);
4194 return 0;
4195 }
4196
4197 res = OCSP_resp_find_status(basic, id, &status, &reason,
4198 &produced_at, &this_update,
4199 &next_update);
4200 }
4201
4202 if (!res) {
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004203 wpa_printf(MSG_INFO, "OpenSSL: Could not find current server certificate from OCSP response%s",
4204 (conn->flags & TLS_CONN_REQUIRE_OCSP) ? "" :
4205 " (OCSP not required)");
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08004206 OCSP_CERTID_free(id);
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004207 OCSP_BASICRESP_free(basic);
4208 OCSP_RESPONSE_free(rsp);
4209 return (conn->flags & TLS_CONN_REQUIRE_OCSP) ? 0 : 1;
4210 }
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08004211 OCSP_CERTID_free(id);
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004212
4213 if (!OCSP_check_validity(this_update, next_update, 5 * 60, -1)) {
4214 tls_show_errors(MSG_INFO, __func__,
4215 "OpenSSL: OCSP status times invalid");
4216 OCSP_BASICRESP_free(basic);
4217 OCSP_RESPONSE_free(rsp);
4218 return 0;
4219 }
4220
4221 OCSP_BASICRESP_free(basic);
4222 OCSP_RESPONSE_free(rsp);
4223
4224 wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status for server certificate: %s",
4225 OCSP_cert_status_str(status));
4226
4227 if (status == V_OCSP_CERTSTATUS_GOOD)
4228 return 1;
4229 if (status == V_OCSP_CERTSTATUS_REVOKED)
4230 return 0;
4231 if (conn->flags & TLS_CONN_REQUIRE_OCSP) {
4232 wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status unknown, but OCSP required");
4233 return 0;
4234 }
Dmitry Shmidt051af732013-10-22 13:52:46 -07004235 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 -07004236 return 1;
4237}
4238
4239
4240static int ocsp_status_cb(SSL *s, void *arg)
4241{
4242 char *tmp;
4243 char *resp;
4244 size_t len;
4245
4246 if (tls_global->ocsp_stapling_response == NULL) {
4247 wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status callback - no response configured");
4248 return SSL_TLSEXT_ERR_OK;
4249 }
4250
4251 resp = os_readfile(tls_global->ocsp_stapling_response, &len);
4252 if (resp == NULL) {
4253 wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status callback - could not read response file");
4254 /* TODO: Build OCSPResponse with responseStatus = internalError
4255 */
4256 return SSL_TLSEXT_ERR_OK;
4257 }
4258 wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status callback - send cached response");
4259 tmp = OPENSSL_malloc(len);
4260 if (tmp == NULL) {
4261 os_free(resp);
4262 return SSL_TLSEXT_ERR_ALERT_FATAL;
4263 }
4264
4265 os_memcpy(tmp, resp, len);
4266 os_free(resp);
4267 SSL_set_tlsext_status_ocsp_resp(s, tmp, len);
4268
4269 return SSL_TLSEXT_ERR_OK;
4270}
4271
4272#endif /* HAVE_OCSP */
4273
4274
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004275int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
4276 const struct tls_connection_params *params)
4277{
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004278 struct tls_data *data = tls_ctx;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004279 int ret;
4280 unsigned long err;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004281 int can_pkcs11 = 0;
4282 const char *key_id = params->key_id;
4283 const char *cert_id = params->cert_id;
4284 const char *ca_cert_id = params->ca_cert_id;
4285 const char *engine_id = params->engine ? params->engine_id : NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004286
4287 if (conn == NULL)
4288 return -1;
4289
Dmitry Shmidt014a3ff2015-12-28 13:27:49 -08004290 if (params->flags & TLS_CONN_REQUIRE_OCSP_ALL) {
4291 wpa_printf(MSG_INFO,
4292 "OpenSSL: ocsp=3 not supported");
4293 return -1;
4294 }
4295
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004296 /*
4297 * If the engine isn't explicitly configured, and any of the
4298 * cert/key fields are actually PKCS#11 URIs, then automatically
4299 * use the PKCS#11 ENGINE.
4300 */
4301 if (!engine_id || os_strcmp(engine_id, "pkcs11") == 0)
4302 can_pkcs11 = 1;
4303
4304 if (!key_id && params->private_key && can_pkcs11 &&
4305 os_strncmp(params->private_key, "pkcs11:", 7) == 0) {
4306 can_pkcs11 = 2;
4307 key_id = params->private_key;
4308 }
4309
4310 if (!cert_id && params->client_cert && can_pkcs11 &&
4311 os_strncmp(params->client_cert, "pkcs11:", 7) == 0) {
4312 can_pkcs11 = 2;
4313 cert_id = params->client_cert;
4314 }
4315
4316 if (!ca_cert_id && params->ca_cert && can_pkcs11 &&
4317 os_strncmp(params->ca_cert, "pkcs11:", 7) == 0) {
4318 can_pkcs11 = 2;
4319 ca_cert_id = params->ca_cert;
4320 }
4321
4322 /* If we need to automatically enable the PKCS#11 ENGINE, do so. */
4323 if (can_pkcs11 == 2 && !engine_id)
4324 engine_id = "pkcs11";
4325
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004326#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08004327#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004328 if (params->flags & TLS_CONN_EAP_FAST) {
4329 wpa_printf(MSG_DEBUG,
4330 "OpenSSL: Use TLSv1_method() for EAP-FAST");
4331 if (SSL_set_ssl_method(conn->ssl, TLSv1_method()) != 1) {
4332 tls_show_errors(MSG_INFO, __func__,
4333 "Failed to set TLSv1_method() for EAP-FAST");
4334 return -1;
4335 }
4336 }
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004337#endif
4338#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004339
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004340 while ((err = ERR_get_error())) {
4341 wpa_printf(MSG_INFO, "%s: Clearing pending SSL error: %s",
4342 __func__, ERR_error_string(err, NULL));
4343 }
4344
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004345 if (engine_id) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004346 wpa_printf(MSG_DEBUG, "SSL: Initializing TLS engine");
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004347 ret = tls_engine_init(conn, engine_id, params->pin,
4348 key_id, cert_id, ca_cert_id);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004349 if (ret)
4350 return ret;
4351 }
4352 if (tls_connection_set_subject_match(conn,
4353 params->subject_match,
Dmitry Shmidt051af732013-10-22 13:52:46 -07004354 params->altsubject_match,
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08004355 params->suffix_match,
4356 params->domain_match))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004357 return -1;
4358
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004359 if (engine_id && ca_cert_id) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004360 if (tls_connection_engine_ca_cert(data, conn, ca_cert_id))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004361 return TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004362 } else if (tls_connection_ca_cert(data, conn, params->ca_cert,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004363 params->ca_cert_blob,
4364 params->ca_cert_blob_len,
4365 params->ca_path))
4366 return -1;
4367
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004368 if (engine_id && cert_id) {
4369 if (tls_connection_engine_client_cert(conn, cert_id))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004370 return TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED;
4371 } else if (tls_connection_client_cert(conn, params->client_cert,
4372 params->client_cert_blob,
4373 params->client_cert_blob_len))
4374 return -1;
4375
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004376 if (engine_id && key_id) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004377 wpa_printf(MSG_DEBUG, "TLS: Using private key from engine");
4378 if (tls_connection_engine_private_key(conn))
4379 return TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004380 } else if (tls_connection_private_key(data, conn,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004381 params->private_key,
4382 params->private_key_passwd,
4383 params->private_key_blob,
4384 params->private_key_blob_len)) {
4385 wpa_printf(MSG_INFO, "TLS: Failed to load private key '%s'",
4386 params->private_key);
4387 return -1;
4388 }
4389
4390 if (tls_connection_dh(conn, params->dh_file)) {
4391 wpa_printf(MSG_INFO, "TLS: Failed to load DH file '%s'",
4392 params->dh_file);
4393 return -1;
4394 }
4395
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004396 if (params->openssl_ciphers &&
4397 SSL_set_cipher_list(conn->ssl, params->openssl_ciphers) != 1) {
4398 wpa_printf(MSG_INFO,
4399 "OpenSSL: Failed to set cipher string '%s'",
4400 params->openssl_ciphers);
4401 return -1;
4402 }
4403
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07004404 if (tls_set_conn_flags(conn, params->flags) < 0)
4405 return -1;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07004406
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004407#ifdef OPENSSL_IS_BORINGSSL
4408 if (params->flags & TLS_CONN_REQUEST_OCSP) {
4409 SSL_enable_ocsp_stapling(conn->ssl);
4410 }
4411#else /* OPENSSL_IS_BORINGSSL */
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004412#ifdef HAVE_OCSP
4413 if (params->flags & TLS_CONN_REQUEST_OCSP) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004414 SSL_CTX *ssl_ctx = data->ssl;
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004415 SSL_set_tlsext_status_type(conn->ssl, TLSEXT_STATUSTYPE_ocsp);
4416 SSL_CTX_set_tlsext_status_cb(ssl_ctx, ocsp_resp_cb);
4417 SSL_CTX_set_tlsext_status_arg(ssl_ctx, conn);
4418 }
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004419#else /* HAVE_OCSP */
4420 if (params->flags & TLS_CONN_REQUIRE_OCSP) {
4421 wpa_printf(MSG_INFO,
4422 "OpenSSL: No OCSP support included - reject configuration");
4423 return -1;
4424 }
4425 if (params->flags & TLS_CONN_REQUEST_OCSP) {
4426 wpa_printf(MSG_DEBUG,
4427 "OpenSSL: No OCSP support included - allow optional OCSP case to continue");
4428 }
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004429#endif /* HAVE_OCSP */
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004430#endif /* OPENSSL_IS_BORINGSSL */
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004431
Dmitry Shmidtc55524a2011-07-07 11:18:38 -07004432 conn->flags = params->flags;
4433
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004434 tls_get_errors(data);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004435
4436 return 0;
4437}
4438
4439
4440int tls_global_set_params(void *tls_ctx,
4441 const struct tls_connection_params *params)
4442{
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004443 struct tls_data *data = tls_ctx;
4444 SSL_CTX *ssl_ctx = data->ssl;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004445 unsigned long err;
4446
4447 while ((err = ERR_get_error())) {
4448 wpa_printf(MSG_INFO, "%s: Clearing pending SSL error: %s",
4449 __func__, ERR_error_string(err, NULL));
4450 }
4451
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004452 if (tls_global_ca_cert(data, params->ca_cert) ||
4453 tls_global_client_cert(data, params->client_cert) ||
4454 tls_global_private_key(data, params->private_key,
4455 params->private_key_passwd) ||
4456 tls_global_dh(data, params->dh_file)) {
4457 wpa_printf(MSG_INFO, "TLS: Failed to set global parameters");
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004458 return -1;
4459 }
4460
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004461 if (params->openssl_ciphers &&
4462 SSL_CTX_set_cipher_list(ssl_ctx, params->openssl_ciphers) != 1) {
4463 wpa_printf(MSG_INFO,
4464 "OpenSSL: Failed to set cipher string '%s'",
4465 params->openssl_ciphers);
4466 return -1;
4467 }
4468
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07004469#ifdef SSL_OP_NO_TICKET
4470 if (params->flags & TLS_CONN_DISABLE_SESSION_TICKET)
4471 SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TICKET);
4472 else
4473 SSL_CTX_clear_options(ssl_ctx, SSL_OP_NO_TICKET);
4474#endif /* SSL_OP_NO_TICKET */
4475
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004476#ifdef HAVE_OCSP
4477 SSL_CTX_set_tlsext_status_cb(ssl_ctx, ocsp_status_cb);
4478 SSL_CTX_set_tlsext_status_arg(ssl_ctx, ssl_ctx);
4479 os_free(tls_global->ocsp_stapling_response);
4480 if (params->ocsp_stapling_response)
4481 tls_global->ocsp_stapling_response =
4482 os_strdup(params->ocsp_stapling_response);
4483 else
4484 tls_global->ocsp_stapling_response = NULL;
4485#endif /* HAVE_OCSP */
4486
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004487 return 0;
4488}
4489
4490
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004491#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
4492/* Pre-shared secred requires a patch to openssl, so this function is
4493 * commented out unless explicitly needed for EAP-FAST in order to be able to
4494 * build this file with unmodified openssl. */
4495
Dmitry Shmidt1d6bf422016-01-19 15:51:35 -08004496#if (defined(OPENSSL_IS_BORINGSSL) || OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -07004497static int tls_sess_sec_cb(SSL *s, void *secret, int *secret_len,
4498 STACK_OF(SSL_CIPHER) *peer_ciphers,
4499 const SSL_CIPHER **cipher, void *arg)
4500#else /* OPENSSL_IS_BORINGSSL */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004501static int tls_sess_sec_cb(SSL *s, void *secret, int *secret_len,
4502 STACK_OF(SSL_CIPHER) *peer_ciphers,
4503 SSL_CIPHER **cipher, void *arg)
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -07004504#endif /* OPENSSL_IS_BORINGSSL */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004505{
4506 struct tls_connection *conn = arg;
4507 int ret;
4508
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08004509#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004510 if (conn == NULL || conn->session_ticket_cb == NULL)
4511 return 0;
4512
4513 ret = conn->session_ticket_cb(conn->session_ticket_cb_ctx,
4514 conn->session_ticket,
4515 conn->session_ticket_len,
4516 s->s3->client_random,
4517 s->s3->server_random, secret);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004518#else
4519 unsigned char client_random[SSL3_RANDOM_SIZE];
4520 unsigned char server_random[SSL3_RANDOM_SIZE];
4521
4522 if (conn == NULL || conn->session_ticket_cb == NULL)
4523 return 0;
4524
4525 SSL_get_client_random(s, client_random, sizeof(client_random));
4526 SSL_get_server_random(s, server_random, sizeof(server_random));
4527
4528 ret = conn->session_ticket_cb(conn->session_ticket_cb_ctx,
4529 conn->session_ticket,
4530 conn->session_ticket_len,
4531 client_random,
4532 server_random, secret);
4533#endif
4534
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004535 os_free(conn->session_ticket);
4536 conn->session_ticket = NULL;
4537
4538 if (ret <= 0)
4539 return 0;
4540
4541 *secret_len = SSL_MAX_MASTER_KEY_LENGTH;
4542 return 1;
4543}
4544
4545
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004546static int tls_session_ticket_ext_cb(SSL *s, const unsigned char *data,
4547 int len, void *arg)
4548{
4549 struct tls_connection *conn = arg;
4550
4551 if (conn == NULL || conn->session_ticket_cb == NULL)
4552 return 0;
4553
4554 wpa_printf(MSG_DEBUG, "OpenSSL: %s: length=%d", __func__, len);
4555
4556 os_free(conn->session_ticket);
4557 conn->session_ticket = NULL;
4558
4559 wpa_hexdump(MSG_DEBUG, "OpenSSL: ClientHello SessionTicket "
4560 "extension", data, len);
4561
Dmitry Shmidtd2986c22017-10-23 14:22:09 -07004562 conn->session_ticket = os_memdup(data, len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004563 if (conn->session_ticket == NULL)
4564 return 0;
4565
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004566 conn->session_ticket_len = len;
4567
4568 return 1;
4569}
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004570#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
4571
4572
4573int tls_connection_set_session_ticket_cb(void *tls_ctx,
4574 struct tls_connection *conn,
4575 tls_session_ticket_cb cb,
4576 void *ctx)
4577{
4578#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
4579 conn->session_ticket_cb = cb;
4580 conn->session_ticket_cb_ctx = ctx;
4581
4582 if (cb) {
4583 if (SSL_set_session_secret_cb(conn->ssl, tls_sess_sec_cb,
4584 conn) != 1)
4585 return -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004586 SSL_set_session_ticket_ext_cb(conn->ssl,
4587 tls_session_ticket_ext_cb, conn);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004588 } else {
4589 if (SSL_set_session_secret_cb(conn->ssl, NULL, NULL) != 1)
4590 return -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004591 SSL_set_session_ticket_ext_cb(conn->ssl, NULL, NULL);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004592 }
4593
4594 return 0;
4595#else /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
4596 return -1;
4597#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
4598}
Dmitry Shmidtff787d52015-01-12 13:01:47 -08004599
4600
4601int tls_get_library_version(char *buf, size_t buf_len)
4602{
Dmitry Shmidt1d6bf422016-01-19 15:51:35 -08004603#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08004604 return os_snprintf(buf, buf_len, "OpenSSL build=%s run=%s",
4605 OPENSSL_VERSION_TEXT,
4606 OpenSSL_version(OPENSSL_VERSION));
4607#else
Dmitry Shmidtff787d52015-01-12 13:01:47 -08004608 return os_snprintf(buf, buf_len, "OpenSSL build=%s run=%s",
4609 OPENSSL_VERSION_TEXT,
4610 SSLeay_version(SSLEAY_VERSION));
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08004611#endif
Dmitry Shmidtff787d52015-01-12 13:01:47 -08004612}
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004613
4614
4615void tls_connection_set_success_data(struct tls_connection *conn,
4616 struct wpabuf *data)
4617{
4618 SSL_SESSION *sess;
4619 struct wpabuf *old;
4620
4621 if (tls_ex_idx_session < 0)
4622 goto fail;
4623 sess = SSL_get_session(conn->ssl);
4624 if (!sess)
4625 goto fail;
4626 old = SSL_SESSION_get_ex_data(sess, tls_ex_idx_session);
4627 if (old) {
4628 wpa_printf(MSG_DEBUG, "OpenSSL: Replacing old success data %p",
4629 old);
4630 wpabuf_free(old);
4631 }
4632 if (SSL_SESSION_set_ex_data(sess, tls_ex_idx_session, data) != 1)
4633 goto fail;
4634
4635 wpa_printf(MSG_DEBUG, "OpenSSL: Stored success data %p", data);
4636 conn->success_data = 1;
4637 return;
4638
4639fail:
4640 wpa_printf(MSG_INFO, "OpenSSL: Failed to store success data");
4641 wpabuf_free(data);
4642}
4643
4644
4645void tls_connection_set_success_data_resumed(struct tls_connection *conn)
4646{
4647 wpa_printf(MSG_DEBUG,
4648 "OpenSSL: Success data accepted for resumed session");
4649 conn->success_data = 1;
4650}
4651
4652
4653const struct wpabuf *
4654tls_connection_get_success_data(struct tls_connection *conn)
4655{
4656 SSL_SESSION *sess;
4657
4658 if (tls_ex_idx_session < 0 ||
4659 !(sess = SSL_get_session(conn->ssl)))
4660 return NULL;
4661 return SSL_SESSION_get_ex_data(sess, tls_ex_idx_session);
4662}
4663
4664
4665void tls_connection_remove_session(struct tls_connection *conn)
4666{
4667 SSL_SESSION *sess;
4668
4669 sess = SSL_get_session(conn->ssl);
4670 if (!sess)
4671 return;
4672
4673 if (SSL_CTX_remove_session(conn->ssl_ctx, sess) != 1)
4674 wpa_printf(MSG_DEBUG,
4675 "OpenSSL: Session was not cached");
4676 else
4677 wpa_printf(MSG_DEBUG,
4678 "OpenSSL: Removed cached session to disable session resumption");
4679}