18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SSL/TLS interface functions for OpenSSL 3d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_SMARTCARD 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_ENGINE 13db3c5a43353099fd4771f3b7a13efae905878ce9Kenny Root#ifndef ANDROID 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define OPENSSL_NO_ENGINE 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 17db3c5a43353099fd4771f3b7a13efae905878ce9Kenny Root#endif 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <openssl/ssl.h> 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <openssl/err.h> 21849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt#include <openssl/opensslv.h> 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <openssl/pkcs12.h> 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <openssl/x509v3.h> 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_ENGINE 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <openssl/engine.h> 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 27d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#ifndef OPENSSL_NO_DSA 28d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#include <openssl/dsa.h> 29d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif 30d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#ifndef OPENSSL_NO_DH 31d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#include <openssl/dh.h> 32d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif 33d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto.h" 36af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt#include "sha1.h" 37d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#include "sha256.h" 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "tls.h" 39d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt#include "tls_openssl.h" 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt#if !defined(CONFIG_FIPS) && \ 42849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt (defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || \ 43849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt defined(EAP_SERVER_FAST)) 44849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt#define OPENSSL_NEED_EAP_FAST_PRF 45849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt#endif 46849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt 479ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt#if defined(OPENSSL_IS_BORINGSSL) 489ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt/* stack_index_t is the return type of OpenSSL's sk_XXX_num() functions. */ 499ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidttypedef size_t stack_index_t; 509ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt#else 519ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidttypedef int stack_index_t; 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54ff07917b8921a2a178ed9188a63b166af144ae53Dmitry Shmidt#ifdef SSL_set_tlsext_status_type 55ff07917b8921a2a178ed9188a63b166af144ae53Dmitry Shmidt#ifndef OPENSSL_NO_TLSEXT 56ff07917b8921a2a178ed9188a63b166af144ae53Dmitry Shmidt#define HAVE_OCSP 57ff07917b8921a2a178ed9188a63b166af144ae53Dmitry Shmidt#include <openssl/ocsp.h> 58ff07917b8921a2a178ed9188a63b166af144ae53Dmitry Shmidt#endif /* OPENSSL_NO_TLSEXT */ 59ff07917b8921a2a178ed9188a63b166af144ae53Dmitry Shmidt#endif /* SSL_set_tlsext_status_type */ 60ff07917b8921a2a178ed9188a63b166af144ae53Dmitry Shmidt 61849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt#if (OPENSSL_VERSION_NUMBER < 0x10100000L || \ 62849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt defined(LIBRESSL_VERSION_NUMBER)) && \ 63849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt !defined(BORINGSSL_API_VERSION) 64de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt/* 65de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt * SSL_get_client_random() and SSL_get_server_random() were added in OpenSSL 66849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt * 1.1.0 and newer BoringSSL revisions. Provide compatibility wrappers for 67849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt * older versions. 68de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt */ 69de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt 70de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidtstatic size_t SSL_get_client_random(const SSL *ssl, unsigned char *out, 71de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt size_t outlen) 72de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt{ 73de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt if (!ssl->s3 || outlen < SSL3_RANDOM_SIZE) 74de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt return 0; 75de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt os_memcpy(out, ssl->s3->client_random, SSL3_RANDOM_SIZE); 76de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt return SSL3_RANDOM_SIZE; 77de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt} 78de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt 79de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt 80de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidtstatic size_t SSL_get_server_random(const SSL *ssl, unsigned char *out, 81de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt size_t outlen) 82de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt{ 83de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt if (!ssl->s3 || outlen < SSL3_RANDOM_SIZE) 84de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt return 0; 85de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt os_memcpy(out, ssl->s3->server_random, SSL3_RANDOM_SIZE); 86de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt return SSL3_RANDOM_SIZE; 87de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt} 88de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt 89de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt 90849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt#ifdef OPENSSL_NEED_EAP_FAST_PRF 91de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidtstatic size_t SSL_SESSION_get_master_key(const SSL_SESSION *session, 92de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt unsigned char *out, size_t outlen) 93de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt{ 94de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt if (!session || session->master_key_length < 0 || 95de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt (size_t) session->master_key_length > outlen) 96de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt return 0; 97de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt if ((size_t) session->master_key_length < outlen) 98de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt outlen = session->master_key_length; 99de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt os_memcpy(out, session->master_key, outlen); 100de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt return outlen; 101de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt} 102849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt#endif /* OPENSSL_NEED_EAP_FAST_PRF */ 103de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt 104de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt#endif 105de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt 1063f3ca3bb849b192d41b99aae775f6fc52f67118dKenny Root#ifdef ANDROID 1073f3ca3bb849b192d41b99aae775f6fc52f67118dKenny Root#include <openssl/pem.h> 1083f3ca3bb849b192d41b99aae775f6fc52f67118dKenny Root#include <keystore/keystore_get.h> 1093f3ca3bb849b192d41b99aae775f6fc52f67118dKenny Root 1103f3ca3bb849b192d41b99aae775f6fc52f67118dKenny Rootstatic BIO * BIO_from_keystore(const char *key) 1113f3ca3bb849b192d41b99aae775f6fc52f67118dKenny Root{ 112ff07917b8921a2a178ed9188a63b166af144ae53Dmitry Shmidt BIO *bio = NULL; 113ff07917b8921a2a178ed9188a63b166af144ae53Dmitry Shmidt uint8_t *value = NULL; 114ff07917b8921a2a178ed9188a63b166af144ae53Dmitry Shmidt int length = keystore_get(key, strlen(key), &value); 115ff07917b8921a2a178ed9188a63b166af144ae53Dmitry Shmidt if (length != -1 && (bio = BIO_new(BIO_s_mem())) != NULL) 116ff07917b8921a2a178ed9188a63b166af144ae53Dmitry Shmidt BIO_write(bio, value, length); 117ff07917b8921a2a178ed9188a63b166af144ae53Dmitry Shmidt free(value); 118ff07917b8921a2a178ed9188a63b166af144ae53Dmitry Shmidt return bio; 1193f3ca3bb849b192d41b99aae775f6fc52f67118dKenny Root} 120b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt 121b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt 122b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidtstatic int tls_add_ca_from_keystore(X509_STORE *ctx, const char *key_alias) 123b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt{ 124b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt BIO *bio = BIO_from_keystore(key_alias); 125b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt STACK_OF(X509_INFO) *stack = NULL; 126b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt stack_index_t i; 127b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt 128b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if (bio) { 129b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt stack = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL); 130b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt BIO_free(bio); 131b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt } 132b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt 133b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if (!stack) { 134b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt wpa_printf(MSG_WARNING, "TLS: Failed to parse certificate: %s", 135b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt key_alias); 136b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt return -1; 137b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt } 138b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt 139b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt for (i = 0; i < sk_X509_INFO_num(stack); ++i) { 140b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt X509_INFO *info = sk_X509_INFO_value(stack, i); 141b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt 142b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if (info->x509) 143b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt X509_STORE_add_cert(ctx, info->x509); 144b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if (info->crl) 145b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt X509_STORE_add_crl(ctx, info->crl); 146b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt } 147b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt 148b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt sk_X509_INFO_pop_free(stack, X509_INFO_free); 149b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt 150b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt return 0; 151b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt} 152b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt 153b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt 154b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidtstatic int tls_add_ca_from_keystore_encoded(X509_STORE *ctx, 155b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt const char *encoded_key_alias) 156b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt{ 157b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt int rc = -1; 158b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt int len = os_strlen(encoded_key_alias); 159b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt unsigned char *decoded_alias; 160b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt 161b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if (len & 1) { 162b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt wpa_printf(MSG_WARNING, "Invalid hex-encoded alias: %s", 163b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt encoded_key_alias); 164b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt return rc; 165b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt } 166b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt 167b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt decoded_alias = os_malloc(len / 2 + 1); 168b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if (decoded_alias) { 169b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if (!hexstr2bin(encoded_key_alias, decoded_alias, len / 2)) { 170b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt decoded_alias[len / 2] = '\0'; 171b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt rc = tls_add_ca_from_keystore( 172b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt ctx, (const char *) decoded_alias); 173b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt } 174b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt os_free(decoded_alias); 175b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt } 176b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt 177b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt return rc; 178b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt} 179b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt 1803f3ca3bb849b192d41b99aae775f6fc52f67118dKenny Root#endif /* ANDROID */ 1813f3ca3bb849b192d41b99aae775f6fc52f67118dKenny Root 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_openssl_ref_count = 0; 183d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int tls_ex_idx_session = -1; 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 185ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidtstruct tls_context { 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void (*event_cb)(void *ctx, enum tls_event ev, 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union tls_event_data *data); 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *cb_ctx; 1891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int cert_in_cb; 19034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt char *ocsp_stapling_response; 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 193ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidtstatic struct tls_context *tls_global = NULL; 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 196d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstruct tls_data { 197d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX *ssl; 198d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt unsigned int tls_session_lifetime; 199d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt}; 200d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct tls_connection { 202ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt struct tls_context *context; 203216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt SSL_CTX *ssl_ctx; 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL *ssl; 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO *ssl_in, *ssl_out; 2061eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley#if defined(ANDROID) || !defined(OPENSSL_NO_ENGINE) 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE *engine; /* functional reference to the engine */ 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EVP_PKEY *private_key; /* the private key if using engine */ 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 2102f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt char *subject_match, *altsubject_match, *suffix_match, *domain_match; 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int read_alerts, write_alerts, failed; 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_session_ticket_cb session_ticket_cb; 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *session_ticket_cb_ctx; 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* SessionTicket received from OpenSSL hello_extension_cb (server) */ 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *session_ticket; 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t session_ticket_len; 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int ca_cert_verify:1; 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int cert_probe:1; 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int server_cert_only:1; 22326af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen unsigned int invalid_hb_used:1; 224d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt unsigned int success_data:1; 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 srv_cert_hash[32]; 227c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt 228c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt unsigned int flags; 22934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 23034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt X509 *peer_cert; 23134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt X509 *peer_issuer; 232fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt X509 *peer_issuer_issuer; 233d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 234d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt unsigned char client_random[SSL3_RANDOM_SIZE]; 235d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt unsigned char server_random[SSL3_RANDOM_SIZE]; 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 239ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidtstatic struct tls_context * tls_context_new(const struct tls_config *conf) 240ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt{ 241ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt struct tls_context *context = os_zalloc(sizeof(*context)); 242ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt if (context == NULL) 243ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt return NULL; 244ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt if (conf) { 245ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt context->event_cb = conf->event_cb; 246ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt context->cb_ctx = conf->cb_ctx; 247ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt context->cert_in_cb = conf->cert_in_cb; 248ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt } 249ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt return context; 250ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt} 251ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt 252ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_NO_STDOUT_DEBUG 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void _tls_show_errors(void) 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned long err; 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while ((err = ERR_get_error())) { 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Just ignore the errors, since stdout is disabled */ 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define tls_show_errors(l, f, t) _tls_show_errors() 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_NO_STDOUT_DEBUG */ 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void tls_show_errors(int level, const char *func, const char *txt) 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned long err; 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(level, "OpenSSL: %s - %s %s", 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt func, txt, ERR_error_string(ERR_get_error(), NULL)); 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while ((err = ERR_get_error())) { 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "OpenSSL: pending error: %s", 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(err, NULL)); 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_STDOUT_DEBUG */ 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_NATIVE_WINDOWS 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Windows CryptoAPI and access to certificate stores */ 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <wincrypt.h> 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef __MINGW32_VERSION 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * MinGW does not yet include all the needed definitions for CryptoAPI, so 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * define here whatever extra is needed. 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define CERT_SYSTEM_STORE_CURRENT_USER (1 << 16) 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define CERT_STORE_READONLY_FLAG 0x00008000 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define CERT_STORE_OPEN_EXISTING_FLAG 0x00004000 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* __MINGW32_VERSION */ 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct cryptoapi_rsa_data { 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const CERT_CONTEXT *cert; 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HCRYPTPROV crypt_prov; 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD key_spec; 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BOOL free_crypt_prov; 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void cryptoapi_error(const char *msg) 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "CryptoAPI: %s; err=%u", 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg, (unsigned int) GetLastError()); 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int cryptoapi_rsa_pub_enc(int flen, const unsigned char *from, 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char *to, RSA *rsa, int padding) 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s - not implemented", __func__); 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int cryptoapi_rsa_pub_dec(int flen, const unsigned char *from, 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char *to, RSA *rsa, int padding) 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s - not implemented", __func__); 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int cryptoapi_rsa_priv_enc(int flen, const unsigned char *from, 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char *to, RSA *rsa, int padding) 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct cryptoapi_rsa_data *priv = 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (struct cryptoapi_rsa_data *) rsa->meth->app_data; 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HCRYPTHASH hash; 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD hash_size, len, i; 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char *buf = NULL; 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = 0; 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (priv == NULL) { 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_R_PASSED_NULL_PARAMETER); 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (padding != RSA_PKCS1_PADDING) { 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSA_R_UNKNOWN_PADDING_TYPE); 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (flen != 16 /* MD5 */ + 20 /* SHA-1 */) { 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "%s - only MD5-SHA1 hash supported", 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__); 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSA_R_INVALID_MESSAGE_LENGTH); 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptCreateHash(priv->crypt_prov, CALG_SSL3_SHAMD5, 0, 0, &hash)) 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_error("CryptCreateHash failed"); 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = sizeof(hash_size); 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptGetHashParam(hash, HP_HASHSIZE, (BYTE *) &hash_size, &len, 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0)) { 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_error("CryptGetHashParam failed"); 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((int) hash_size != flen) { 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "CryptoAPI: Invalid hash size (%u != %d)", 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned) hash_size, flen); 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSA_R_INVALID_MESSAGE_LENGTH); 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptSetHashParam(hash, HP_HASHVAL, (BYTE * ) from, 0)) { 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_error("CryptSetHashParam failed"); 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = RSA_size(rsa); 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = os_malloc(len); 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) { 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE); 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptSignHash(hash, priv->key_spec, NULL, 0, buf, &len)) { 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_error("CryptSignHash failed"); 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < len; i++) 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt to[i] = buf[len - i - 1]; 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = len; 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidterr: 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CryptDestroyHash(hash); 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int cryptoapi_rsa_priv_dec(int flen, const unsigned char *from, 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char *to, RSA *rsa, int padding) 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s - not implemented", __func__); 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void cryptoapi_free_data(struct cryptoapi_rsa_data *priv) 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (priv == NULL) 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (priv->crypt_prov && priv->free_crypt_prov) 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CryptReleaseContext(priv->crypt_prov, 0); 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (priv->cert) 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CertFreeCertificateContext(priv->cert); 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(priv); 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int cryptoapi_finish(RSA *rsa) 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_free_data((struct cryptoapi_rsa_data *) rsa->meth->app_data); 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free((void *) rsa->meth); 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa->meth = NULL; 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const CERT_CONTEXT * cryptoapi_find_cert(const char *name, DWORD store) 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HCERTSTORE cs; 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const CERT_CONTEXT *ret = NULL; 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cs = CertOpenStore((LPCSTR) CERT_STORE_PROV_SYSTEM, 0, 0, 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt store | CERT_STORE_OPEN_EXISTING_FLAG | 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CERT_STORE_READONLY_FLAG, L"MY"); 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cs == NULL) { 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_error("Failed to open 'My system store'"); 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (strncmp(name, "cert://", 7) == 0) { 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned short wbuf[255]; 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MultiByteToWideChar(CP_ACP, 0, name + 7, -1, wbuf, 255); 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = CertFindCertificateInStore(cs, X509_ASN_ENCODING | 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PKCS_7_ASN_ENCODING, 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0, CERT_FIND_SUBJECT_STR, 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wbuf, NULL); 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (strncmp(name, "hash://", 7) == 0) { 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CRYPT_HASH_BLOB blob; 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len; 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *hash = name + 7; 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char *buf; 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = os_strlen(hash) / 2; 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = os_malloc(len); 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf && hexstr2bin(hash, buf, len) == 0) { 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt blob.cbData = len; 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt blob.pbData = buf; 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = CertFindCertificateInStore(cs, 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_ASN_ENCODING | 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PKCS_7_ASN_ENCODING, 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0, CERT_FIND_HASH, 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &blob, NULL); 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CertCloseStore(cs, 0); 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_cryptoapi_cert(SSL *ssl, const char *name) 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *cert = NULL; 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSA *rsa = NULL, *pub_rsa; 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct cryptoapi_rsa_data *priv; 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSA_METHOD *rsa_meth; 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (name == NULL || 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (strncmp(name, "cert://", 7) != 0 && 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt strncmp(name, "hash://", 7) != 0)) 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priv = os_zalloc(sizeof(*priv)); 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_meth = os_zalloc(sizeof(*rsa_meth)); 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (priv == NULL || rsa_meth == NULL) { 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "CryptoAPI: Failed to allocate memory " 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for CryptoAPI RSA method"); 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(priv); 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(rsa_meth); 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priv->cert = cryptoapi_find_cert(name, CERT_SYSTEM_STORE_CURRENT_USER); 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (priv->cert == NULL) { 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priv->cert = cryptoapi_find_cert( 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name, CERT_SYSTEM_STORE_LOCAL_MACHINE); 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (priv->cert == NULL) { 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "CryptoAPI: Could not find certificate " 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s'", name); 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 518216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt cert = d2i_X509(NULL, 519216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt (const unsigned char **) &priv->cert->pbCertEncoded, 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priv->cert->cbCertEncoded); 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert == NULL) { 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "CryptoAPI: Could not process X509 DER " 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "encoding"); 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptAcquireCertificatePrivateKey(priv->cert, 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CRYPT_ACQUIRE_COMPARE_KEY_FLAG, 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, &priv->crypt_prov, 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &priv->key_spec, 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &priv->free_crypt_prov)) { 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_error("Failed to acquire a private key for the " 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate"); 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_meth->name = "Microsoft CryptoAPI RSA Method"; 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_meth->rsa_pub_enc = cryptoapi_rsa_pub_enc; 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_meth->rsa_pub_dec = cryptoapi_rsa_pub_dec; 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_meth->rsa_priv_enc = cryptoapi_rsa_priv_enc; 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_meth->rsa_priv_dec = cryptoapi_rsa_priv_dec; 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_meth->finish = cryptoapi_finish; 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_meth->flags = RSA_METHOD_FLAG_NO_CHECK; 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_meth->app_data = (char *) priv; 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa = RSA_new(); 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rsa == NULL) { 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_R_MALLOC_FAILURE); 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!SSL_use_certificate(ssl, cert)) { 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSA_free(rsa); 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa = NULL; 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pub_rsa = cert->cert_info->key->pkey->pkey.rsa; 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert = NULL; 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa->n = BN_dup(pub_rsa->n); 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa->e = BN_dup(pub_rsa->e); 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!RSA_set_method(rsa, rsa_meth)) 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!SSL_use_RSAPrivateKey(ssl, rsa)) 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSA_free(rsa); 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidterr: 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert) 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rsa) 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSA_free(rsa); 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(rsa_meth); 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_free_data(priv); 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_cryptoapi_ca_cert(SSL_CTX *ssl_ctx, SSL *ssl, const char *name) 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HCERTSTORE cs; 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PCCERT_CONTEXT ctx = NULL; 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *cert; 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char buf[128]; 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *store; 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef UNICODE 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WCHAR *wstore; 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* UNICODE */ 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (name == NULL || strncmp(name, "cert_store://", 13) != 0) 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt store = name + 13; 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef UNICODE 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wstore = os_malloc((os_strlen(store) + 1) * sizeof(WCHAR)); 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wstore == NULL) 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wsprintf(wstore, L"%S", store); 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cs = CertOpenSystemStore(0, wstore); 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(wstore); 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* UNICODE */ 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cs = CertOpenSystemStore(0, store); 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* UNICODE */ 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cs == NULL) { 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: failed to open system cert store " 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s': error=%d", __func__, store, 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) GetLastError()); 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while ((ctx = CertEnumCertificatesInStore(cs, ctx))) { 619216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt cert = d2i_X509(NULL, 620216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt (const unsigned char **) &ctx->pbCertEncoded, 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->cbCertEncoded); 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert == NULL) { 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "CryptoAPI: Could not process " 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "X509 DER encoding for CA cert"); 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_NAME_oneline(X509_get_subject_name(cert), buf, 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(buf)); 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Loaded CA certificate for " 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "system certificate store: subject='%s'", buf); 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 633849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt if (!X509_STORE_add_cert(SSL_CTX_get_cert_store(ssl_ctx), 634849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt cert)) { 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_WARNING, __func__, 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to add ca_cert to OpenSSL " 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate store"); 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CertCloseStore(cs, 0)) { 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: failed to close system cert store " 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s': error=%d", __func__, name + 13, 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) GetLastError()); 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_NATIVE_WINDOWS */ 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_cryptoapi_cert(SSL *ssl, const char *name) 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void ssl_info_cb(const SSL *ssl, int where, int ret) 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *str; 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int w; 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: (where=0x%x ret=0x%x)", where, ret); 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt w = where & ~SSL_ST_MASK; 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (w & SSL_ST_CONNECT) 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt str = "SSL_connect"; 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (w & SSL_ST_ACCEPT) 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt str = "SSL_accept"; 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt str = "undefined"; 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (where & SSL_CB_LOOP) { 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: %s:%s", 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt str, SSL_state_string_long(ssl)); 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (where & SSL_CB_ALERT) { 681ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt struct tls_connection *conn = SSL_get_app_data((SSL *) ssl); 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "SSL: SSL3 alert: %s:%s:%s", 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt where & SSL_CB_READ ? 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "read (remote end reported an error)" : 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "write (local SSL3 detected an error)", 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_alert_type_string_long(ret), 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_alert_desc_string_long(ret)); 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((ret >> 8) == SSL3_AL_FATAL) { 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (where & SSL_CB_READ) 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->read_alerts++; 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->write_alerts++; 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 694ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt if (conn->context->event_cb != NULL) { 69504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt union tls_event_data ev; 696ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt struct tls_context *context = conn->context; 69704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memset(&ev, 0, sizeof(ev)); 69804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ev.alert.is_local = !(where & SSL_CB_READ); 69904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ev.alert.type = SSL_alert_type_string_long(ret); 70004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ev.alert.description = SSL_alert_desc_string_long(ret); 701ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt context->event_cb(context->cb_ctx, TLS_ALERT, &ev); 70204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (where & SSL_CB_EXIT && ret <= 0) { 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: %s:%s in %s", 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt str, ret == 0 ? "failed" : "error", 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_state_string_long(ssl)); 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_ENGINE 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tls_engine_load_dynamic_generic - load any openssl engine 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @pre: an array of commands and values that load an engine initialized 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * in the engine specific function 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @post: an array of commands and values that initialize an already loaded 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * engine (or %NULL if not required) 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @id: the engine id of the engine to load (only required if post is not %NULL 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is a generic function that loads any openssl engine. 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_engine_load_dynamic_generic(const char *pre[], 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *post[], const char *id) 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE *engine; 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *dynamic_id = "dynamic"; 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt engine = ENGINE_by_id(id); 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (engine) { 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: engine '%s' is already " 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "available", id); 734d5ab1b53af720d05586ccc0addabe93459f1f388Dmitry Shmidt /* 735d5ab1b53af720d05586ccc0addabe93459f1f388Dmitry Shmidt * If it was auto-loaded by ENGINE_by_id() we might still 736d5ab1b53af720d05586ccc0addabe93459f1f388Dmitry Shmidt * need to tell it which PKCS#11 module to use in legacy 737d5ab1b53af720d05586ccc0addabe93459f1f388Dmitry Shmidt * (non-p11-kit) environments. Do so now; even if it was 738d5ab1b53af720d05586ccc0addabe93459f1f388Dmitry Shmidt * properly initialised before, setting it again will be 739d5ab1b53af720d05586ccc0addabe93459f1f388Dmitry Shmidt * harmless. 740d5ab1b53af720d05586ccc0addabe93459f1f388Dmitry Shmidt */ 741d5ab1b53af720d05586ccc0addabe93459f1f388Dmitry Shmidt goto found; 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_clear_error(); 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt engine = ENGINE_by_id(dynamic_id); 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (engine == NULL) { 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "ENGINE: Can't find engine %s [%s]", 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dynamic_id, 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Perform the pre commands. This will load the engine. */ 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pre && pre[0]) { 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: '%s' '%s'", pre[0], pre[1]); 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ENGINE_ctrl_cmd_string(engine, pre[0], pre[1], 0) == 0) { 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "ENGINE: ctrl cmd_string failed: " 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%s %s [%s]", pre[0], pre[1], 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE_free(engine); 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pre += 2; 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Free the reference to the "dynamic" engine. The loaded engine can 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * now be looked up using ENGINE_by_id(). 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE_free(engine); 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt engine = ENGINE_by_id(id); 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (engine == NULL) { 7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "ENGINE: Can't find engine %s [%s]", 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt id, ERR_error_string(ERR_get_error(), NULL)); 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 778d5ab1b53af720d05586ccc0addabe93459f1f388Dmitry Shmidt found: 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (post && post[0]) { 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: '%s' '%s'", post[0], post[1]); 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ENGINE_ctrl_cmd_string(engine, post[0], post[1], 0) == 0) { 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: ctrl cmd_string failed:" 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " %s %s [%s]", post[0], post[1], 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE_remove(engine); 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE_free(engine); 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt post += 2; 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE_free(engine); 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tls_engine_load_dynamic_pkcs11 - load the pkcs11 engine provided by opensc 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @pkcs11_so_path: pksc11_so_path from the configuration 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @pcks11_module_path: pkcs11_module_path from the configuration 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_engine_load_dynamic_pkcs11(const char *pkcs11_so_path, 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *pkcs11_module_path) 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *engine_id = "pkcs11"; 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *pre_cmd[] = { 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SO_PATH", NULL /* pkcs11_so_path */, 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ID", NULL /* engine_id */, 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "LIST_ADD", "1", 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* "NO_VCHECK", "1", */ 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "LOAD", NULL, 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, NULL 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt }; 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *post_cmd[] = { 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "MODULE_PATH", NULL /* pkcs11_module_path */, 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, NULL 8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt }; 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8196c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!pkcs11_so_path) 8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pre_cmd[1] = pkcs11_so_path; 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pre_cmd[3] = engine_id; 8246c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (pkcs11_module_path) 8256c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt post_cmd[1] = pkcs11_module_path; 8266c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt else 8276c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt post_cmd[0] = NULL; 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: Loading pkcs11 Engine from %s", 8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pkcs11_so_path); 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_engine_load_dynamic_generic(pre_cmd, post_cmd, engine_id); 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tls_engine_load_dynamic_opensc - load the opensc engine provided by opensc 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @opensc_so_path: opensc_so_path from the configuration 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_engine_load_dynamic_opensc(const char *opensc_so_path) 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *engine_id = "opensc"; 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *pre_cmd[] = { 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SO_PATH", NULL /* opensc_so_path */, 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ID", NULL /* engine_id */, 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "LIST_ADD", "1", 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "LOAD", NULL, 8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, NULL 8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt }; 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!opensc_so_path) 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pre_cmd[1] = opensc_so_path; 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pre_cmd[3] = engine_id; 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: Loading OpenSC Engine from %s", 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt opensc_so_path); 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_engine_load_dynamic_generic(pre_cmd, NULL, engine_id); 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 865d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic void remove_session_cb(SSL_CTX *ctx, SSL_SESSION *sess) 866d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 867d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct wpabuf *buf; 868d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 869d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (tls_ex_idx_session < 0) 870d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return; 871d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt buf = SSL_SESSION_get_ex_data(sess, tls_ex_idx_session); 872d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!buf) 873d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return; 874d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_DEBUG, 875d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "OpenSSL: Free application session data %p (sess %p)", 876d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt buf, sess); 877d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpabuf_free(buf); 878d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 879d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_SESSION_set_ex_data(sess, tls_ex_idx_session, NULL); 880d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 881d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 882d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid * tls_init(const struct tls_config *conf) 8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 885d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct tls_data *data; 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX *ssl; 887ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt struct tls_context *context; 8886c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt const char *ciphers; 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_openssl_ref_count == 0) { 891ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt tls_global = context = tls_context_new(conf); 892ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt if (context == NULL) 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_FIPS 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef OPENSSL_FIPS 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf && conf->fips_mode) { 897d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt static int fips_enabled = 0; 898d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 899d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!fips_enabled && !FIPS_mode_set(1)) { 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to enable FIPS " 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "mode"); 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_load_crypto_strings(); 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_print_errors_fp(stderr); 90461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(tls_global); 90561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt tls_global = NULL; 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 907d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } else { 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "Running in FIPS mode"); 909d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fips_enabled = 1; 910d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_FIPS */ 9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf && conf->fips_mode) { 9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "FIPS mode requested, but not " 9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "supported"); 91661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(tls_global); 91761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt tls_global = NULL; 9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_FIPS */ 9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_FIPS */ 9229839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) 9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_load_error_strings(); 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_library_init(); 925216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt#ifndef OPENSSL_NO_SHA256 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EVP_add_digest(EVP_sha256()); 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_SHA256 */ 9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: if /dev/urandom is available, PRNG is seeded 9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * automatically. If this is not the case, random data should 9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * be added here. */ 9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef PKCS12_FUNCS 9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_RC2 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 40-bit RC2 is commonly used in PKCS#12 files, so enable it. 9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This is enabled by PKCS12_PBE_add() in OpenSSL 0.9.8 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * versions, but it looks like OpenSSL 1.0.0 does not do that 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * anymore. 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EVP_add_cipher(EVP_rc2_40_cbc()); 9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_RC2 */ 9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PKCS12_PBE_add(); 9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* PKCS12_FUNCS */ 94457c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt#endif /* < 1.1.0 */ 945ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt } else { 946ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt context = tls_context_new(conf); 947ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt if (context == NULL) 948ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt return NULL; 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_openssl_ref_count++; 9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 952d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt data = os_zalloc(sizeof(*data)); 953d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (data) 954d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ssl = SSL_CTX_new(SSLv23_method()); 955d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt else 956d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ssl = NULL; 957ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt if (ssl == NULL) { 958ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt tls_openssl_ref_count--; 95968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (context != tls_global) 96068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt os_free(context); 961ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt if (tls_openssl_ref_count == 0) { 962ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt os_free(tls_global); 963ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt tls_global = NULL; 964ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt } 96557c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt os_free(data); 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 967ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt } 968d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt data->ssl = ssl; 969d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (conf) 970d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt data->tls_session_lifetime = conf->tls_session_lifetime; 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9726c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt SSL_CTX_set_options(ssl, SSL_OP_NO_SSLv2); 9736c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt SSL_CTX_set_options(ssl, SSL_OP_NO_SSLv3); 9746c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 975293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt#ifdef SSL_MODE_NO_AUTO_CHAIN 976293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt /* Number of deployed use cases assume the default OpenSSL behavior of 977293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt * auto chaining the local certificate is in use. BoringSSL removed this 978293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt * functionality by default, so we need to restore it here to avoid 979293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt * breaking existing use cases. */ 980293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt SSL_CTX_clear_mode(ssl, SSL_MODE_NO_AUTO_CHAIN); 981293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt#endif /* SSL_MODE_NO_AUTO_CHAIN */ 982293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_set_info_callback(ssl, ssl_info_cb); 984ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt SSL_CTX_set_app_data(ssl, context); 985d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (data->tls_session_lifetime > 0) { 986d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX_set_quiet_shutdown(ssl, 1); 987d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt /* 988d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * Set default context here. In practice, this will be replaced 989d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * by the per-EAP method context in tls_connection_set_verify(). 990d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt */ 991d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX_set_session_id_context(ssl, (u8 *) "hostapd", 7); 992d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX_set_session_cache_mode(ssl, SSL_SESS_CACHE_SERVER); 993d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX_set_timeout(ssl, data->tls_session_lifetime); 994d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX_sess_set_remove_cb(ssl, remove_session_cb); 995d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } else { 996d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX_set_session_cache_mode(ssl, SSL_SESS_CACHE_OFF); 997d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 998d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 999d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (tls_ex_idx_session < 0) { 1000d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt tls_ex_idx_session = SSL_SESSION_get_ex_new_index( 1001d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 0, NULL, NULL, NULL, NULL); 1002d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (tls_ex_idx_session < 0) { 1003d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt tls_deinit(data); 1004d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return NULL; 1005d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 1006d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_ENGINE 10096c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: Loading dynamic engine"); 10106c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ERR_load_ENGINE_strings(); 10116c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ENGINE_load_dynamic(); 10126c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf && 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (conf->opensc_engine_path || conf->pkcs11_engine_path || 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->pkcs11_module_path)) { 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_engine_load_dynamic_opensc(conf->opensc_engine_path) || 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_engine_load_dynamic_pkcs11(conf->pkcs11_engine_path, 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->pkcs11_module_path)) { 1019d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt tls_deinit(data); 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10256c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (conf && conf->openssl_ciphers) 10266c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ciphers = conf->openssl_ciphers; 10276c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt else 10286c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ciphers = "DEFAULT:!EXP:!LOW"; 10296c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (SSL_CTX_set_cipher_list(ssl, ciphers) != 1) { 10306c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_ERROR, 10316c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "OpenSSL: Failed to set cipher string '%s'", 10326c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ciphers); 1033d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt tls_deinit(data); 10346c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return NULL; 10356c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 10366c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1037d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return data; 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid tls_deinit(void *ssl_ctx) 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1043d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct tls_data *data = ssl_ctx; 1044d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX *ssl = data->ssl; 1045ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt struct tls_context *context = SSL_CTX_get_app_data(ssl); 1046ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt if (context != tls_global) 1047ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt os_free(context); 1048d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (data->tls_session_lifetime > 0) 1049d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX_flush_sessions(ssl, 0); 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_free(ssl); 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_openssl_ref_count--; 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_openssl_ref_count == 0) { 10549839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) 10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_ENGINE 10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE_cleanup(); 10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CRYPTO_cleanup_all_ex_data(); 10599ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt ERR_remove_thread_state(NULL); 10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_free_strings(); 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EVP_cleanup(); 106257c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt#endif /* < 1.1.0 */ 106334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt os_free(tls_global->ocsp_stapling_response); 106434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt tls_global->ocsp_stapling_response = NULL; 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(tls_global); 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_global = NULL; 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1068d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1069d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt os_free(data); 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10731d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt#ifndef OPENSSL_NO_ENGINE 10741d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt 10751d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt/* Cryptoki return values */ 10761d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt#define CKR_PIN_INCORRECT 0x000000a0 10771d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt#define CKR_PIN_INVALID 0x000000a1 10781d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt#define CKR_PIN_LEN_RANGE 0x000000a2 10791d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt 10801d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt/* libp11 */ 10811d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt#define ERR_LIB_PKCS11 ERR_LIB_USER 10821d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt 10831d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidtstatic int tls_is_pin_error(unsigned int err) 10841d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt{ 10851d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt return ERR_GET_LIB(err) == ERR_LIB_PKCS11 && 10861d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt (ERR_GET_REASON(err) == CKR_PIN_INCORRECT || 10871d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt ERR_GET_REASON(err) == CKR_PIN_INVALID || 10881d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt ERR_GET_REASON(err) == CKR_PIN_LEN_RANGE); 10891d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt} 10901d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt 10911d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 10921d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt 10931d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt 1094d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#ifdef ANDROID 1095d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt/* EVP_PKEY_from_keystore comes from system/security/keystore-engine. */ 1096d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry ShmidtEVP_PKEY * EVP_PKEY_from_keystore(const char *key_id); 1097d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* ANDROID */ 1098d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_engine_init(struct tls_connection *conn, const char *engine_id, 11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *pin, const char *key_id, 11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *cert_id, const char *ca_cert_id) 11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11031eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley#if defined(ANDROID) && defined(OPENSSL_IS_BORINGSSL) 11041eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley#if !defined(OPENSSL_NO_ENGINE) 11051eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley#error "This code depends on OPENSSL_NO_ENGINE being defined by BoringSSL." 11061eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley#endif 1107d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!key_id) 1108d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED; 11091eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley conn->engine = NULL; 11101eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley conn->private_key = EVP_PKEY_from_keystore(key_id); 11111eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley if (!conn->private_key) { 11121eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley wpa_printf(MSG_ERROR, 11131eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley "ENGINE: cannot load private key with id '%s' [%s]", 11141eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley key_id, 11151eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley ERR_error_string(ERR_get_error(), NULL)); 11161eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley return TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED; 11171eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley } 1118d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* ANDROID && OPENSSL_IS_BORINGSSL */ 11191eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley 11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_ENGINE 11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = -1; 11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (engine_id == NULL) { 11238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "ENGINE: Engine ID not set"); 11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_clear_error(); 1128db3c5a43353099fd4771f3b7a13efae905878ce9Kenny Root#ifdef ANDROID 1129db3c5a43353099fd4771f3b7a13efae905878ce9Kenny Root ENGINE_load_dynamic(); 1130db3c5a43353099fd4771f3b7a13efae905878ce9Kenny Root#endif 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->engine = ENGINE_by_id(engine_id); 11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!conn->engine) { 11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "ENGINE: engine %s not available [%s]", 11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt engine_id, ERR_error_string(ERR_get_error(), NULL)); 11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ENGINE_init(conn->engine) != 1) { 11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "ENGINE: engine init failed " 11398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(engine: %s) [%s]", engine_id, 11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 11428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: engine initialized"); 11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1145db3c5a43353099fd4771f3b7a13efae905878ce9Kenny Root#ifndef ANDROID 11466c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (pin && ENGINE_ctrl_cmd_string(conn->engine, "PIN", pin, 0) == 0) { 11478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "ENGINE: cannot set pin [%s]", 11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1151db3c5a43353099fd4771f3b7a13efae905878ce9Kenny Root#endif 11526c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (key_id) { 11536c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* 11546c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * Ensure that the ENGINE does not attempt to use the OpenSSL 11556c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * UI system to obtain a PIN, if we didn't provide one. 11566c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt */ 11576c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct { 11586c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt const void *password; 11596c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt const char *prompt_info; 11606c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } key_cb = { "", NULL }; 11616c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 11626c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* load private key first in-case PIN is required for cert */ 11636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt conn->private_key = ENGINE_load_private_key(conn->engine, 11646c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt key_id, NULL, 11656c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt &key_cb); 11666c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!conn->private_key) { 11671d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt unsigned long err = ERR_get_error(); 11681d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt 11696c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_ERROR, 11706c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "ENGINE: cannot load private key with id '%s' [%s]", 11716c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt key_id, 11721d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt ERR_error_string(err, NULL)); 11731d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt if (tls_is_pin_error(err)) 11741d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt ret = TLS_SET_PARAMS_ENGINE_PRV_BAD_PIN; 11751d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt else 11761d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt ret = TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED; 11776c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt goto err; 11786c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* handle a certificate and/or CA certificate */ 11828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert_id || ca_cert_id) { 11838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *cmd_name = "LOAD_CERT_CTRL"; 11848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* test if the engine supports a LOAD_CERT_CTRL */ 11868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ENGINE_ctrl(conn->engine, ENGINE_CTRL_GET_CMD_FROM_NAME, 11878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0, (void *)cmd_name, NULL)) { 11888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "ENGINE: engine does not support" 11898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " loading certificates"); 11908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED; 11918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 11928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 11968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidterr: 11988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->engine) { 11998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE_free(conn->engine); 12008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->engine = NULL; 12018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->private_key) { 12048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EVP_PKEY_free(conn->private_key); 12058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->private_key = NULL; 12068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 12098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_ENGINE */ 12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 12118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 12128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void tls_engine_deinit(struct tls_connection *conn) 12168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12171eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley#if defined(ANDROID) || !defined(OPENSSL_NO_ENGINE) 12188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: engine deinit"); 12198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->private_key) { 12208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EVP_PKEY_free(conn->private_key); 12218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->private_key = NULL; 12228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->engine) { 12241eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley#if !defined(OPENSSL_IS_BORINGSSL) 12258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE_finish(conn->engine); 1226d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* !OPENSSL_IS_BORINGSSL */ 12278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->engine = NULL; 12288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1229d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* ANDROID || !OPENSSL_NO_ENGINE */ 12308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_get_errors(void *ssl_ctx) 12348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int count = 0; 12368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned long err; 12378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while ((err = ERR_get_error())) { 12398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS - SSL error: %s", 12408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(err, NULL)); 12418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count++; 12428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return count; 12458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 124726af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen 1248d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic const char * openssl_content_type(int content_type) 1249d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 1250d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt switch (content_type) { 1251d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 20: 1252d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "change cipher spec"; 1253d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 21: 1254d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "alert"; 1255d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 22: 1256d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "handshake"; 1257d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 23: 1258d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "application data"; 1259d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 24: 1260d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "heartbeat"; 1261d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 256: 1262d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "TLS header info"; /* pseudo content type */ 1263d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt default: 1264d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "?"; 1265d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 1266d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 1267d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1268d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1269d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic const char * openssl_handshake_type(int content_type, const u8 *buf, 1270d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt size_t len) 1271d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 1272d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (content_type != 22 || !buf || len == 0) 1273d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return ""; 1274d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt switch (buf[0]) { 1275d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 0: 1276d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "hello request"; 1277d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 1: 1278d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "client hello"; 1279d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 2: 1280d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "server hello"; 1281d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 4: 1282d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "new session ticket"; 1283d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 11: 1284d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "certificate"; 1285d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 12: 1286d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "server key exchange"; 1287d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 13: 1288d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "certificate request"; 1289d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 14: 1290d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "server hello done"; 1291d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 15: 1292d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "certificate verify"; 1293d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 16: 1294d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "client key exchange"; 1295d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 20: 1296d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "finished"; 1297d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 21: 1298d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "certificate url"; 1299d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 22: 1300d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "certificate status"; 1301d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt default: 1302d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "?"; 1303d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 1304d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 1305d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1306d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 130726af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinenstatic void tls_msg_cb(int write_p, int version, int content_type, 130826af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen const void *buf, size_t len, SSL *ssl, void *arg) 130926af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen{ 131026af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen struct tls_connection *conn = arg; 131126af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen const u8 *pos = buf; 131226af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen 1313d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (write_p == 2) { 1314d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_DEBUG, 1315d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "OpenSSL: session ver=0x%x content_type=%d", 1316d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt version, content_type); 1317d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_hexdump_key(MSG_MSGDUMP, "OpenSSL: Data", buf, len); 1318d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return; 1319d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 1320d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1321d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s ver=0x%x content_type=%d (%s/%s)", 1322d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt write_p ? "TX" : "RX", version, content_type, 1323d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt openssl_content_type(content_type), 1324d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt openssl_handshake_type(content_type, buf, len)); 132526af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen wpa_hexdump_key(MSG_MSGDUMP, "OpenSSL: Message", buf, len); 132626af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen if (content_type == 24 && len >= 3 && pos[0] == 1) { 132726af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen size_t payload_len = WPA_GET_BE16(pos + 1); 132826af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen if (payload_len + 3 > len) { 132926af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen wpa_printf(MSG_ERROR, "OpenSSL: Heartbeat attack detected"); 133026af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen conn->invalid_hb_used = 1; 133126af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen } 133226af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen } 133326af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen} 133426af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen 133526af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen 13368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct tls_connection * tls_connection_init(void *ssl_ctx) 13378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1338d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct tls_data *data = ssl_ctx; 1339d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX *ssl = data->ssl; 13408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn; 13418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt long options; 13427d5c8f257a74ac0d12828962a492e8b84ef83923Dmitry Shmidt struct tls_context *context = SSL_CTX_get_app_data(ssl); 13438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn = os_zalloc(sizeof(*conn)); 13458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 13468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1347d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt conn->ssl_ctx = ssl; 13488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ssl = SSL_new(ssl); 13498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->ssl == NULL) { 13508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 13518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to initialize new SSL connection"); 13528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn); 13538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 13548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1356ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt conn->context = context; 13578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_app_data(conn->ssl, conn); 135826af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen SSL_set_msg_callback(conn->ssl, tls_msg_cb); 135926af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen SSL_set_msg_callback_arg(conn->ssl, conn); 13608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | 13618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_OP_SINGLE_DH_USE; 13628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef SSL_OP_NO_COMPRESSION 13638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt options |= SSL_OP_NO_COMPRESSION; 13648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* SSL_OP_NO_COMPRESSION */ 13658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_options(conn->ssl, options); 13668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ssl_in = BIO_new(BIO_s_mem()); 13688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!conn->ssl_in) { 13698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 13708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to create a new BIO for ssl_in"); 13718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_free(conn->ssl); 13728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn); 13738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 13748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ssl_out = BIO_new(BIO_s_mem()); 13778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!conn->ssl_out) { 13788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 13798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to create a new BIO for ssl_out"); 13808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_free(conn->ssl); 13818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO_free(conn->ssl_in); 13828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn); 13838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 13848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_bio(conn->ssl, conn->ssl_in, conn->ssl_out); 13878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return conn; 13898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid tls_connection_deinit(void *ssl_ctx, struct tls_connection *conn) 13938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 13958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1396d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (conn->success_data) { 1397d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt /* 1398d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * Make sure ssl_clear_bad_session() does not remove this 1399d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * session. 1400d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt */ 1401d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_set_quiet_shutdown(conn->ssl, 1); 1402d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_shutdown(conn->ssl); 1403d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 14048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_free(conn->ssl); 14058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_engine_deinit(conn); 14068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->subject_match); 14078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->altsubject_match); 1408051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt os_free(conn->suffix_match); 14092f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt os_free(conn->domain_match); 14108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->session_ticket); 14118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn); 14128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_established(void *ssl_ctx, struct tls_connection *conn) 14168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return conn ? SSL_is_init_finished(conn->ssl) : 0; 14188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_shutdown(void *ssl_ctx, struct tls_connection *conn) 14228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 14248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Shutdown previous TLS connection without notifying the peer 14278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * because the connection was already terminated in practice 14288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * and "close notify" shutdown alert would confuse AS. */ 14298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_quiet_shutdown(conn->ssl, 1); 14308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_shutdown(conn->ssl); 1431f291c682d490cef0b520b68e694a2bf97126b441Jouni Malinen return SSL_clear(conn->ssl) == 1 ? 0 : -1; 14328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_match_altsubject_component(X509 *cert, int type, 14368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *value, size_t len) 14378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt GENERAL_NAME *gen; 14398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *ext; 14409ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt int found = 0; 14419ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt stack_index_t i; 14428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ext = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL); 14448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; ext && i < sk_GENERAL_NAME_num(ext); i++) { 14468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gen = sk_GENERAL_NAME_value(ext, i); 14478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (gen->type != type) 14488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 14498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strlen((char *) gen->d.ia5->data) == len && 14508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(value, gen->d.ia5->data, len) == 0) 14518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt found++; 14528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 145457c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt sk_GENERAL_NAME_pop_free(ext, GENERAL_NAME_free); 145557c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt 14568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return found; 14578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_match_altsubject(X509 *cert, const char *match) 14618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int type; 14638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *pos, *end; 14648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len; 14658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = match; 14678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt do { 14688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strncmp(pos, "EMAIL:", 6) == 0) { 14698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = GEN_EMAIL; 14708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 6; 14718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (os_strncmp(pos, "DNS:", 4) == 0) { 14728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = GEN_DNS; 14738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 4; 14748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (os_strncmp(pos, "URI:", 4) == 0) { 14758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = GEN_URI; 14768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 4; 14778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 14788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Invalid altSubjectName " 14798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "match '%s'", pos); 14808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 14818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = os_strchr(pos, ';'); 14838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (end) { 14848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strncmp(end + 1, "EMAIL:", 6) == 0 || 14858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strncmp(end + 1, "DNS:", 4) == 0 || 14868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strncmp(end + 1, "URI:", 4) == 0) 14878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 14888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = os_strchr(end + 1, ';'); 14898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end) 14918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = end - pos; 14928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 14938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = os_strlen(pos); 14948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_match_altsubject_component(cert, type, pos, len) > 0) 14958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 14968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = end + 1; 14978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } while (end); 14988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 15008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1503fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt#ifndef CONFIG_NATIVE_WINDOWS 15042f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidtstatic int domain_suffix_match(const u8 *val, size_t len, const char *match, 15052f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt int full) 1506051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt{ 1507051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt size_t i, match_len; 1508051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1509051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt /* Check for embedded nuls that could mess up suffix matching */ 1510051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt for (i = 0; i < len; i++) { 1511051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (val[i] == '\0') { 1512051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Embedded null in a string - reject"); 1513051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return 0; 1514051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } 1515051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } 1516051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1517051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt match_len = os_strlen(match); 15182f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (match_len > len || (full && match_len != len)) 1519051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return 0; 1520051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1521051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (os_strncasecmp((const char *) val + len - match_len, match, 1522051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt match_len) != 0) 1523051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return 0; /* no match */ 1524051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1525051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (match_len == len) 1526051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return 1; /* exact match */ 1527051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1528051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (val[len - match_len - 1] == '.') 1529051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return 1; /* full label match completes suffix match */ 1530051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1531051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Reject due to incomplete label match"); 1532051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return 0; 1533051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt} 1534fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 1535051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1536051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 15372f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidtstatic int tls_match_suffix(X509 *cert, const char *match, int full) 1538051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt{ 1539fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt#ifdef CONFIG_NATIVE_WINDOWS 1540fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt /* wincrypt.h has conflicting X509_NAME definition */ 1541fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt return -1; 1542fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt#else /* CONFIG_NATIVE_WINDOWS */ 1543051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt GENERAL_NAME *gen; 1544051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt void *ext; 1545051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt int i; 15469ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt stack_index_t j; 1547051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt int dns_name = 0; 1548051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt X509_NAME *name; 1549051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 15502f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Match domain against %s%s", 15512f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt full ? "": "suffix ", match); 1552051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1553051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt ext = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL); 1554051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 15559ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt for (j = 0; ext && j < sk_GENERAL_NAME_num(ext); j++) { 15569ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt gen = sk_GENERAL_NAME_value(ext, j); 1557051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (gen->type != GEN_DNS) 1558051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt continue; 1559051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt dns_name++; 1560051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "TLS: Certificate dNSName", 1561051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt gen->d.dNSName->data, 1562051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt gen->d.dNSName->length); 1563051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (domain_suffix_match(gen->d.dNSName->data, 15642f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt gen->d.dNSName->length, match, full) == 15652f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 1) { 15662f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: %s in dNSName found", 15672f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt full ? "Match" : "Suffix match"); 156857c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt sk_GENERAL_NAME_pop_free(ext, GENERAL_NAME_free); 1569051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return 1; 1570051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } 1571051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } 157257c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt sk_GENERAL_NAME_pop_free(ext, GENERAL_NAME_free); 1573051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1574051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (dns_name) { 1575051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: None of the dNSName(s) matched"); 1576051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return 0; 1577051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } 1578051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1579051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt name = X509_get_subject_name(cert); 1580051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt i = -1; 1581051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt for (;;) { 1582051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt X509_NAME_ENTRY *e; 1583051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt ASN1_STRING *cn; 1584051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1585051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt i = X509_NAME_get_index_by_NID(name, NID_commonName, i); 1586051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (i == -1) 1587051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt break; 1588051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt e = X509_NAME_get_entry(name, i); 1589051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (e == NULL) 1590051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt continue; 1591051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt cn = X509_NAME_ENTRY_get_data(e); 1592051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (cn == NULL) 1593051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt continue; 1594051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "TLS: Certificate commonName", 1595051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt cn->data, cn->length); 15962f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (domain_suffix_match(cn->data, cn->length, match, full) == 1) 15972f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt { 15982f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: %s in commonName found", 15992f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt full ? "Match" : "Suffix match"); 1600051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return 1; 1601051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } 1602051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } 1603051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 16042f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: No CommonName %smatch found", 16052f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt full ? "": "suffix "); 1606051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return 0; 1607fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 1608051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt} 1609051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1610051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 16118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic enum tls_fail_reason openssl_tls_fail_reason(int err) 16128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (err) { 16148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_CERT_REVOKED: 16158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_FAIL_REVOKED; 16168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_CERT_NOT_YET_VALID: 16178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_CRL_NOT_YET_VALID: 16188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_FAIL_NOT_YET_VALID; 16198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_CERT_HAS_EXPIRED: 16208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_CRL_HAS_EXPIRED: 16218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_FAIL_EXPIRED; 16228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: 16238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_UNABLE_TO_GET_CRL: 16248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER: 16258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: 16268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: 16278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: 16288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: 16298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_CERT_CHAIN_TOO_LONG: 16308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_PATH_LENGTH_EXCEEDED: 16318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_INVALID_CA: 16328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_FAIL_UNTRUSTED; 16338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: 16348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: 16358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: 16368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: 16378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: 16388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: 16398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: 16408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_CERT_UNTRUSTED: 16418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_CERT_REJECTED: 16428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_FAIL_BAD_CERTIFICATE; 16438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 16448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_FAIL_UNSPECIFIED; 16458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * get_x509_cert(X509 *cert) 16508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 16528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *tmp; 16538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int cert_len = i2d_X509(cert, NULL); 16558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert_len <= 0) 16568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 16578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = wpabuf_alloc(cert_len); 16598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 16608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 16618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = wpabuf_put(buf, cert_len); 16638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i2d_X509(cert, &tmp); 16648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 16658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void openssl_tls_fail_event(struct tls_connection *conn, 16698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *err_cert, int err, int depth, 16708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *subject, const char *err_str, 16718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum tls_fail_reason reason) 16728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union tls_event_data ev; 16748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *cert = NULL; 1675ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt struct tls_context *context = conn->context; 16768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1677ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt if (context->event_cb == NULL) 16788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 16798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert = get_x509_cert(err_cert); 16818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&ev, 0, sizeof(ev)); 16828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.cert_fail.reason = reason != TLS_FAIL_UNSPECIFIED ? 16838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reason : openssl_tls_fail_reason(err); 16848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.cert_fail.depth = depth; 16858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.cert_fail.subject = subject; 16868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.cert_fail.reason_txt = err_str; 16878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.cert_fail.cert = cert; 1688ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt context->event_cb(context->cb_ctx, TLS_CERT_CHAIN_FAILURE, &ev); 16898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(cert); 16908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void openssl_tls_cert_event(struct tls_connection *conn, 16948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *err_cert, int depth, 16958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *subject) 16968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *cert = NULL; 16988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union tls_event_data ev; 1699ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt struct tls_context *context = conn->context; 17002f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt char *altsubject[TLS_MAX_ALT_SUBJECT]; 17012f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt int alt, num_altsubject = 0; 17022f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt GENERAL_NAME *gen; 17032f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt void *ext; 17042f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt stack_index_t i; 17058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_SHA256 17068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 hash[32]; 17078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_SHA256 */ 17088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1709ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt if (context->event_cb == NULL) 17108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&ev, 0, sizeof(ev)); 171355840adb6cd32ca52064f327b72a40e769f70661Dmitry Shmidt if (conn->cert_probe || (conn->flags & TLS_CONN_EXT_CERT_CHECK) || 171455840adb6cd32ca52064f327b72a40e769f70661Dmitry Shmidt context->cert_in_cb) { 17158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert = get_x509_cert(err_cert); 17168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.peer_cert.cert = cert; 17178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_SHA256 17198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert) { 17208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr[1]; 17218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len[1]; 17228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr[0] = wpabuf_head(cert); 17238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len[0] = wpabuf_len(cert); 17248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sha256_vector(1, addr, len, hash) == 0) { 17258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.peer_cert.hash = hash; 17268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.peer_cert.hash_len = sizeof(hash); 17278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_SHA256 */ 17308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.peer_cert.depth = depth; 17318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.peer_cert.subject = subject; 17322f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 17332f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt ext = X509_get_ext_d2i(err_cert, NID_subject_alt_name, NULL, NULL); 17342f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt for (i = 0; ext && i < sk_GENERAL_NAME_num(ext); i++) { 17352f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt char *pos; 17362f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 17372f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (num_altsubject == TLS_MAX_ALT_SUBJECT) 17382f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt break; 17392f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt gen = sk_GENERAL_NAME_value(ext, i); 17402f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (gen->type != GEN_EMAIL && 17412f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt gen->type != GEN_DNS && 17422f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt gen->type != GEN_URI) 17432f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt continue; 17442f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 17452f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt pos = os_malloc(10 + gen->d.ia5->length + 1); 17462f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (pos == NULL) 17472f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt break; 17482f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt altsubject[num_altsubject++] = pos; 17492f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 17502f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt switch (gen->type) { 17512f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt case GEN_EMAIL: 17522f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt os_memcpy(pos, "EMAIL:", 6); 17532f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt pos += 6; 17542f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt break; 17552f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt case GEN_DNS: 17562f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt os_memcpy(pos, "DNS:", 4); 17572f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt pos += 4; 17582f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt break; 17592f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt case GEN_URI: 17602f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt os_memcpy(pos, "URI:", 4); 17612f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt pos += 4; 17622f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt break; 17632f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 17642f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 1765d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt os_memcpy(pos, gen->d.ia5->data, gen->d.ia5->length); 1766d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt pos += gen->d.ia5->length; 1767d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt *pos = '\0'; 1768d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 176957c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt sk_GENERAL_NAME_pop_free(ext, GENERAL_NAME_free); 1770d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1771d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt for (alt = 0; alt < num_altsubject; alt++) 1772d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ev.peer_cert.altsubject[alt] = altsubject[alt]; 1773d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ev.peer_cert.num_altsubject = num_altsubject; 1774d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1775d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt context->event_cb(context->cb_ctx, TLS_PEER_CERTIFICATE, &ev); 1776d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpabuf_free(cert); 1777d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt for (alt = 0; alt < num_altsubject; alt++) 1778d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt os_free(altsubject[alt]); 1779d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 1780d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1781d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 17828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx) 17838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char buf[256]; 17858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *err_cert; 17868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int err, depth; 17878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL *ssl; 17888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn; 1789ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt struct tls_context *context; 17902f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt char *match, *altmatch, *suffix_match, *domain_match; 17918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *err_str; 17928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err_cert = X509_STORE_CTX_get_current_cert(x509_ctx); 179496be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt if (!err_cert) 179596be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt return 0; 179696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt 17978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err = X509_STORE_CTX_get_error(x509_ctx); 17988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt depth = X509_STORE_CTX_get_error_depth(x509_ctx); 17998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssl = X509_STORE_CTX_get_ex_data(x509_ctx, 18008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_get_ex_data_X509_STORE_CTX_idx()); 18018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof(buf)); 18028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn = SSL_get_app_data(ssl); 18048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 18058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 180634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 180734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (depth == 0) 180834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt conn->peer_cert = err_cert; 180934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt else if (depth == 1) 181034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt conn->peer_issuer = err_cert; 1811fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt else if (depth == 2) 1812fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt conn->peer_issuer_issuer = err_cert; 181334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 1814ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt context = conn->context; 18158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt match = conn->subject_match; 18168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt altmatch = conn->altsubject_match; 1817051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt suffix_match = conn->suffix_match; 18182f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt domain_match = conn->domain_match; 18198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!preverify_ok && !conn->ca_cert_verify) 18218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt preverify_ok = 1; 18228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!preverify_ok && depth > 0 && conn->server_cert_only) 18238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt preverify_ok = 1; 1824c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt if (!preverify_ok && (conn->flags & TLS_CONN_DISABLE_TIME_CHECKS) && 1825c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt (err == X509_V_ERR_CERT_HAS_EXPIRED || 1826c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt err == X509_V_ERR_CERT_NOT_YET_VALID)) { 1827c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Ignore certificate validity " 1828c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt "time mismatch"); 1829c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt preverify_ok = 1; 1830c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt } 18318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err_str = X509_verify_cert_error_string(err); 18338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_SHA256 18354dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt /* 18364dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt * Do not require preverify_ok so we can explicity allow otherwise 18374dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt * invalid pinned server certificates. 18384dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt */ 18394dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt if (depth == 0 && conn->server_cert_only) { 18408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *cert; 18418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert = get_x509_cert(err_cert); 18428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!cert) { 18438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Could not fetch " 18448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "server certificate data"); 18458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt preverify_ok = 0; 18468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 18478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 hash[32]; 18488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr[1]; 18498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len[1]; 18508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr[0] = wpabuf_head(cert); 18518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len[0] = wpabuf_len(cert); 18528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sha256_vector(1, addr, len, hash) < 0 || 18538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(conn->srv_cert_hash, hash, 32) != 0) { 18548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err_str = "Server certificate mismatch"; 18558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN; 18568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt preverify_ok = 0; 18574dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt } else if (!preverify_ok) { 18584dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt /* 18594dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt * Certificate matches pinned certificate, allow 18604dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt * regardless of other problems. 18614dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt */ 18624dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt wpa_printf(MSG_DEBUG, 18634dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt "OpenSSL: Ignore validation issues for a pinned server certificate"); 18644dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt preverify_ok = 1; 18658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(cert); 18678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_SHA256 */ 18708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!preverify_ok) { 18728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "TLS: Certificate verification failed," 18738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " error %d (%s) depth %d for '%s'", err, err_str, 18748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt depth, buf); 18758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt openssl_tls_fail_event(conn, err_cert, err, depth, buf, 18768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err_str, TLS_FAIL_UNSPECIFIED); 18778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return preverify_ok; 18788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: tls_verify_cb - preverify_ok=%d " 18818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "err=%d (%s) ca_cert_verify=%d depth=%d buf='%s'", 18828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt preverify_ok, err, err_str, 18838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ca_cert_verify, depth, buf); 18848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (depth == 0 && match && os_strstr(buf, match) == NULL) { 18858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "TLS: Subject '%s' did not " 18868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "match with '%s'", buf, match); 18878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt preverify_ok = 0; 18888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt openssl_tls_fail_event(conn, err_cert, err, depth, buf, 18898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Subject mismatch", 18908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_FAIL_SUBJECT_MISMATCH); 18918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (depth == 0 && altmatch && 18928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !tls_match_altsubject(err_cert, altmatch)) { 18938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "TLS: altSubjectName match " 18948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s' not found", altmatch); 18958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt preverify_ok = 0; 18968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt openssl_tls_fail_event(conn, err_cert, err, depth, buf, 18978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "AltSubject mismatch", 18988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_FAIL_ALTSUBJECT_MISMATCH); 1899051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } else if (depth == 0 && suffix_match && 19002f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt !tls_match_suffix(err_cert, suffix_match, 0)) { 1901051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt wpa_printf(MSG_WARNING, "TLS: Domain suffix match '%s' not found", 1902051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt suffix_match); 1903051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt preverify_ok = 0; 1904051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt openssl_tls_fail_event(conn, err_cert, err, depth, buf, 1905051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt "Domain suffix mismatch", 1906051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt TLS_FAIL_DOMAIN_SUFFIX_MISMATCH); 19072f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } else if (depth == 0 && domain_match && 19082f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt !tls_match_suffix(err_cert, domain_match, 1)) { 19092f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_WARNING, "TLS: Domain match '%s' not found", 19102f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt domain_match); 19112f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt preverify_ok = 0; 19122f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt openssl_tls_fail_event(conn, err_cert, err, depth, buf, 19132f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt "Domain mismatch", 19142f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt TLS_FAIL_DOMAIN_MISMATCH); 19158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 19168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt openssl_tls_cert_event(conn, err_cert, depth, buf); 19178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->cert_probe && preverify_ok && depth == 0) { 19198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Reject server certificate " 19208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "on probe-only run"); 19218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt preverify_ok = 0; 19228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt openssl_tls_fail_event(conn, err_cert, err, depth, buf, 19238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Server certificate chain probe", 19248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_FAIL_SERVER_CHAIN_PROBE); 19258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1927d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#ifdef OPENSSL_IS_BORINGSSL 1928d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt if (depth == 0 && (conn->flags & TLS_CONN_REQUEST_OCSP) && 1929d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt preverify_ok) { 1930d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt enum ocsp_result res; 1931d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1932d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt res = check_ocsp_resp(conn->ssl_ctx, conn->ssl, err_cert, 1933d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt conn->peer_issuer, 1934d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt conn->peer_issuer_issuer); 1935d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (res == OCSP_REVOKED) { 1936d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt preverify_ok = 0; 1937d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt openssl_tls_fail_event(conn, err_cert, err, depth, buf, 1938d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "certificate revoked", 1939d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt TLS_FAIL_REVOKED); 1940d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (err == X509_V_OK) 1941d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt X509_STORE_CTX_set_error( 1942d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt x509_ctx, X509_V_ERR_CERT_REVOKED); 1943d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } else if (res != OCSP_GOOD && 1944d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt (conn->flags & TLS_CONN_REQUIRE_OCSP)) { 1945d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt preverify_ok = 0; 1946d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt openssl_tls_fail_event(conn, err_cert, err, depth, buf, 1947d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "bad certificate status response", 1948d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt TLS_FAIL_UNSPECIFIED); 1949d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 1950d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 1951d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* OPENSSL_IS_BORINGSSL */ 1952d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 195355840adb6cd32ca52064f327b72a40e769f70661Dmitry Shmidt if (depth == 0 && preverify_ok && context->event_cb != NULL) 1954ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt context->event_cb(context->cb_ctx, 1955ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt TLS_CERT_CHAIN_SUCCESS, NULL); 195604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 19578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return preverify_ok; 19588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_STDIO 1962d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int tls_load_ca_der(struct tls_data *data, const char *ca_cert) 19638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1964d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX *ssl_ctx = data->ssl; 19658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_LOOKUP *lookup; 19668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = 0; 19678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1968216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt lookup = X509_STORE_add_lookup(SSL_CTX_get_cert_store(ssl_ctx), 19698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_LOOKUP_file()); 19708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (lookup == NULL) { 19718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_WARNING, __func__, 19728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed add lookup for X509 store"); 19738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 19748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!X509_LOOKUP_load_file(lookup, ca_cert, X509_FILETYPE_ASN1)) { 19778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned long err = ERR_peek_error(); 19788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_WARNING, __func__, 19798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed load CA in DER format"); 19808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ERR_GET_LIB(err) == ERR_LIB_X509 && 19818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_GET_REASON(err) == X509_R_CERT_ALREADY_IN_HASH_TABLE) { 19828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - ignoring " 19838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "cert already in hash table error", 19848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__); 19858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 19868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 19878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 19908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_STDIO */ 19928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1994d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int tls_connection_ca_cert(struct tls_data *data, 1995d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct tls_connection *conn, 19968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *ca_cert, const u8 *ca_cert_blob, 19978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t ca_cert_blob_len, const char *ca_path) 19988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1999d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX *ssl_ctx = data->ssl; 2000216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt X509_STORE *store; 20018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 20038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Remove previously configured trusted CA certificates before adding 20048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * new ones. 20058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2006216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt store = X509_STORE_new(); 2007216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (store == NULL) { 20088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - failed to allocate new " 20098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate store", __func__); 20108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 20118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2012216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt SSL_CTX_set_cert_store(ssl_ctx, store); 20138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb); 20158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ca_cert_verify = 1; 20168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ca_cert && os_strncmp(ca_cert, "probe://", 8) == 0) { 20188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Probe for server certificate " 20198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "chain"); 20208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->cert_probe = 1; 20218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ca_cert_verify = 0; 20228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 20238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ca_cert && os_strncmp(ca_cert, "hash://", 7) == 0) { 20268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_SHA256 20278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *pos = ca_cert + 7; 20288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strncmp(pos, "server/sha256/", 14) != 0) { 20298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Unsupported ca_cert " 20308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "hash value '%s'", ca_cert); 20318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 20328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 14; 20348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strlen(pos) != 32 * 2) { 20358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Unexpected SHA256 " 20368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "hash length in ca_cert '%s'", ca_cert); 20378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 20388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hexstr2bin(pos, conn->srv_cert_hash, 32) < 0) { 20408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Invalid SHA256 hash " 20418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "value in ca_cert '%s'", ca_cert); 20428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 20438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->server_cert_only = 1; 20458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Checking only server " 20468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate match"); 20478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 20488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_SHA256 */ 20498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "No SHA256 included in the build - " 20508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "cannot validate server certificate hash"); 20518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 20528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_SHA256 */ 20538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ca_cert_blob) { 2056216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt X509 *cert = d2i_X509(NULL, 2057216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt (const unsigned char **) &ca_cert_blob, 20588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ca_cert_blob_len); 20598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert == NULL) { 20608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_WARNING, __func__, 20618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to parse ca_cert_blob"); 20628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 20638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2065216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!X509_STORE_add_cert(SSL_CTX_get_cert_store(ssl_ctx), 2066216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt cert)) { 20678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned long err = ERR_peek_error(); 20688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_WARNING, __func__, 20698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to add ca_cert_blob to " 20708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate store"); 20718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ERR_GET_LIB(err) == ERR_LIB_X509 && 20728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_GET_REASON(err) == 20738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_R_CERT_ALREADY_IN_HASH_TABLE) { 20748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - ignoring " 20758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "cert already in hash table error", 20768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__); 20778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 20788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 20798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 20808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 20838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - added ca_cert_blob " 20848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "to certificate store", __func__); 20858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 20868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef ANDROID 2089b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt /* Single alias */ 20908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ca_cert && os_strncmp("keystore://", ca_cert, 11) == 0) { 2091849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt if (tls_add_ca_from_keystore(SSL_CTX_get_cert_store(ssl_ctx), 2092b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt &ca_cert[11]) < 0) 20938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2094b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb); 2095b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt return 0; 2096b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt } 20978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2098b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt /* Multiple aliases separated by space */ 2099b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if (ca_cert && os_strncmp("keystores://", ca_cert, 12) == 0) { 2100b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt char *aliases = os_strdup(&ca_cert[12]); 2101b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt const char *delim = " "; 2102b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt int rc = 0; 2103b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt char *savedptr; 2104b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt char *alias; 2105b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt 2106b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if (!aliases) 2107b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt return -1; 2108b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt alias = strtok_r(aliases, delim, &savedptr); 2109b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt for (; alias; alias = strtok_r(NULL, delim, &savedptr)) { 2110b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if (tls_add_ca_from_keystore_encoded( 2111849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt SSL_CTX_get_cert_store(ssl_ctx), alias)) { 2112b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt wpa_printf(MSG_WARNING, 2113b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt "OpenSSL: %s - Failed to add ca_cert %s from keystore", 2114b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt __func__, alias); 2115b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt rc = -1; 2116b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt break; 21178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2119b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt os_free(aliases); 2120b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if (rc) 2121b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt return rc; 2122b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt 21238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb); 21248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 21258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* ANDROID */ 21278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_NATIVE_WINDOWS 21298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ca_cert && tls_cryptoapi_ca_cert(ssl_ctx, conn->ssl, ca_cert) == 21308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) { 21318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Added CA certificates from " 21328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "system certificate store"); 21338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 21348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 21368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ca_cert || ca_path) { 21388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_STDIO 21398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_CTX_load_verify_locations(ssl_ctx, ca_cert, ca_path) != 21408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1) { 21418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_WARNING, __func__, 21428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to load root certificates"); 21438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ca_cert && 2144d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt tls_load_ca_der(data, ca_cert) == 0) { 21458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - loaded " 21468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "DER format CA certificate", 21478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__); 21488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 21498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 21508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 21518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Trusted root " 21528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate(s) loaded"); 2153d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt tls_get_errors(data); 21548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_STDIO */ 21568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", 21578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__); 21588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 21598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_STDIO */ 21608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 21618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* No ca_cert configured - do not try to verify server 21628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * certificate */ 21638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ca_cert_verify = 0; 21648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 21678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2170d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int tls_global_ca_cert(struct tls_data *data, const char *ca_cert) 21718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2172d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX *ssl_ctx = data->ssl; 2173d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 21748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ca_cert) { 21758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_CTX_load_verify_locations(ssl_ctx, ca_cert, NULL) != 1) 21768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 21778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_WARNING, __func__, 21788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to load root certificates"); 21798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 21808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Trusted root " 21838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate(s) loaded"); 21848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_STDIO 21868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Add the same CAs to the client certificate requests */ 21878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_set_client_CA_list(ssl_ctx, 21888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_load_client_CA_file(ca_cert)); 21898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_STDIO */ 21908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 21938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_global_set_verify(void *ssl_ctx, int check_crl) 21978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int flags; 21998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (check_crl) { 2201d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct tls_data *data = ssl_ctx; 2202d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt X509_STORE *cs = SSL_CTX_get_cert_store(data->ssl); 22038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cs == NULL) { 22048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, "Failed to get " 22058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate store when enabling " 22068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "check_crl"); 22078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt flags = X509_V_FLAG_CRL_CHECK; 22108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (check_crl == 2) 22118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt flags |= X509_V_FLAG_CRL_CHECK_ALL; 22128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_STORE_set_flags(cs, flags); 22138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 22158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_connection_set_subject_match(struct tls_connection *conn, 22198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *subject_match, 2220051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt const char *altsubject_match, 22212f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt const char *suffix_match, 22222f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt const char *domain_match) 22238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->subject_match); 22258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->subject_match = NULL; 22268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (subject_match) { 22278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->subject_match = os_strdup(subject_match); 22288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->subject_match == NULL) 22298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->altsubject_match); 22338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->altsubject_match = NULL; 22348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (altsubject_match) { 22358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->altsubject_match = os_strdup(altsubject_match); 22368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->altsubject_match == NULL) 22378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2240051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt os_free(conn->suffix_match); 2241051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt conn->suffix_match = NULL; 2242051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (suffix_match) { 2243051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt conn->suffix_match = os_strdup(suffix_match); 2244051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (conn->suffix_match == NULL) 2245051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return -1; 2246051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } 2247051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 22482f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt os_free(conn->domain_match); 22492f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt conn->domain_match = NULL; 22502f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (domain_match) { 22512f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt conn->domain_match = os_strdup(domain_match); 22522f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (conn->domain_match == NULL) 22532f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt return -1; 22542f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 22552f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 22568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 22578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2260d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic void tls_set_conn_flags(SSL *ssl, unsigned int flags) 2261d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 2262d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#ifdef SSL_OP_NO_TICKET 2263d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (flags & TLS_CONN_DISABLE_SESSION_TICKET) 2264d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_set_options(ssl, SSL_OP_NO_TICKET); 2265d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt else 2266d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_clear_options(ssl, SSL_OP_NO_TICKET); 2267d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* SSL_OP_NO_TICKET */ 2268d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 2269d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#ifdef SSL_OP_NO_TLSv1 2270d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (flags & TLS_CONN_DISABLE_TLSv1_0) 2271d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_set_options(ssl, SSL_OP_NO_TLSv1); 2272d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt else 2273d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_clear_options(ssl, SSL_OP_NO_TLSv1); 2274d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* SSL_OP_NO_TLSv1 */ 2275d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#ifdef SSL_OP_NO_TLSv1_1 2276d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (flags & TLS_CONN_DISABLE_TLSv1_1) 2277d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_set_options(ssl, SSL_OP_NO_TLSv1_1); 2278d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt else 2279d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_clear_options(ssl, SSL_OP_NO_TLSv1_1); 2280d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* SSL_OP_NO_TLSv1_1 */ 2281d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#ifdef SSL_OP_NO_TLSv1_2 2282d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (flags & TLS_CONN_DISABLE_TLSv1_2) 2283d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_set_options(ssl, SSL_OP_NO_TLSv1_2); 2284d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt else 2285d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_clear_options(ssl, SSL_OP_NO_TLSv1_2); 2286d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* SSL_OP_NO_TLSv1_2 */ 2287d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 2288d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 2289d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 22908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn, 2291d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt int verify_peer, unsigned int flags, 2292d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const u8 *session_ctx, size_t session_ctx_len) 22938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt static int counter = 0; 2295d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct tls_data *data = ssl_ctx; 22968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 22988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (verify_peer) { 23018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ca_cert_verify = 1; 23028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_verify(conn->ssl, SSL_VERIFY_PEER | 23038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_VERIFY_FAIL_IF_NO_PEER_CERT | 23048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_VERIFY_CLIENT_ONCE, tls_verify_cb); 23058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 23068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ca_cert_verify = 0; 23078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_verify(conn->ssl, SSL_VERIFY_NONE, NULL); 23088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2310d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt tls_set_conn_flags(conn->ssl, flags); 2311d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt conn->flags = flags; 2312d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 23138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_accept_state(conn->ssl); 23148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2315d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (data->tls_session_lifetime == 0) { 2316d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt /* 2317d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * Set session id context to a unique value to make sure 2318d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * session resumption cannot be used either through session 2319d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * caching or TLS ticket extension. 2320d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt */ 2321d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt counter++; 2322d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_set_session_id_context(conn->ssl, 2323d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt (const unsigned char *) &counter, 2324d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt sizeof(counter)); 2325d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } else if (session_ctx) { 2326d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_set_session_id_context(conn->ssl, session_ctx, 2327d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt session_ctx_len); 2328d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 23298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 23318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_connection_client_cert(struct tls_connection *conn, 23358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *client_cert, 23368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *client_cert_blob, 23378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t client_cert_blob_len) 23388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (client_cert == NULL && client_cert_blob == NULL) 23408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 23418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2342de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt#ifdef PKCS12_FUNCS 23439839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#if OPENSSL_VERSION_NUMBER < 0x10002000L || defined(LIBRESSL_VERSION_NUMBER) 2344de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt /* 2345de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt * Clear previously set extra chain certificates, if any, from PKCS#12 2346de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt * processing in tls_parse_pkcs12() to allow OpenSSL to build a new 2347de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt * chain properly. 2348de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt */ 2349de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt SSL_CTX_clear_extra_chain_certs(conn->ssl_ctx); 2350de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt#endif /* OPENSSL_VERSION_NUMBER < 0x10002000L */ 2351de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt#endif /* PKCS12_FUNCS */ 2352de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt 23538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (client_cert_blob && 23548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_use_certificate_ASN1(conn->ssl, (u8 *) client_cert_blob, 23558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client_cert_blob_len) == 1) { 23568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_ASN1 --> " 23578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "OK"); 23588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 23598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (client_cert_blob) { 23608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_DEBUG, __func__, 23618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SSL_use_certificate_ASN1 failed"); 23628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (client_cert == NULL) 23658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 23668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef ANDROID 23688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strncmp("keystore://", client_cert, 11) == 0) { 23698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO *bio = BIO_from_keystore(&client_cert[11]); 23708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *x509 = NULL; 23718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = -1; 237250772e8622904b97ec2840383b4f7395e952344cPaul Stewart if (bio) 23738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL); 237450772e8622904b97ec2840383b4f7395e952344cPaul Stewart 23758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (x509) { 23768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_certificate(conn->ssl, x509) == 1) 23778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = 0; 23788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(x509); 23798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 238050772e8622904b97ec2840383b4f7395e952344cPaul Stewart 238150772e8622904b97ec2840383b4f7395e952344cPaul Stewart /* Read additional certificates into the chain. */ 238250772e8622904b97ec2840383b4f7395e952344cPaul Stewart while (bio) { 238350772e8622904b97ec2840383b4f7395e952344cPaul Stewart x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL); 238450772e8622904b97ec2840383b4f7395e952344cPaul Stewart if (x509) { 238550772e8622904b97ec2840383b4f7395e952344cPaul Stewart /* Takes ownership of x509 */ 238650772e8622904b97ec2840383b4f7395e952344cPaul Stewart SSL_add0_chain_cert(conn->ssl, x509); 238750772e8622904b97ec2840383b4f7395e952344cPaul Stewart } else { 238850772e8622904b97ec2840383b4f7395e952344cPaul Stewart BIO_free(bio); 238950772e8622904b97ec2840383b4f7395e952344cPaul Stewart bio = NULL; 239050772e8622904b97ec2840383b4f7395e952344cPaul Stewart } 239150772e8622904b97ec2840383b4f7395e952344cPaul Stewart } 23928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 23938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* ANDROID */ 23958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_STDIO 23978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_certificate_file(conn->ssl, client_cert, 23988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_FILETYPE_ASN1) == 1) { 23998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_file (DER)" 24008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " --> OK"); 24018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 24028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_certificate_file(conn->ssl, client_cert, 24058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_FILETYPE_PEM) == 1) { 24068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_clear_error(); 24078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_file (PEM)" 24088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " --> OK"); 24098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 24108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_DEBUG, __func__, 24138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SSL_use_certificate_file failed"); 24148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_STDIO */ 24158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", __func__); 24168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_STDIO */ 24178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 24198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2422d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int tls_global_client_cert(struct tls_data *data, 2423d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const char *client_cert) 24248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_STDIO 2426d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX *ssl_ctx = data->ssl; 2427d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 24288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (client_cert == NULL) 24298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 24308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_CTX_use_certificate_file(ssl_ctx, client_cert, 24328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_FILETYPE_ASN1) != 1 && 24331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt SSL_CTX_use_certificate_chain_file(ssl_ctx, client_cert) != 1 && 24348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_use_certificate_file(ssl_ctx, client_cert, 24358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_FILETYPE_PEM) != 1) { 24368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 24378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to load client certificate"); 24388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 24398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 24418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_STDIO */ 24428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (client_cert == NULL) 24438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 24448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", __func__); 24458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 24468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_STDIO */ 24478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_passwd_cb(char *buf, int size, int rwflag, void *password) 24518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (password == NULL) { 24538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 24548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(buf, (char *) password, size); 24568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return os_strlen(buf); 24578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef PKCS12_FUNCS 2461d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int tls_parse_pkcs12(struct tls_data *data, SSL *ssl, PKCS12 *p12, 24628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *passwd) 24638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EVP_PKEY *pkey; 24658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *cert; 24668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt STACK_OF(X509) *certs; 24678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res = 0; 24688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char buf[256]; 24698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pkey = NULL; 24718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert = NULL; 24728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt certs = NULL; 2473d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!passwd) 2474d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt passwd = ""; 24758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!PKCS12_parse(p12, passwd, &pkey, &cert, &certs)) { 24768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_DEBUG, __func__, 24778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to parse PKCS12 file"); 24788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PKCS12_free(p12); 24798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 24808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Successfully parsed PKCS12 data"); 24828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert) { 24848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_NAME_oneline(X509_get_subject_name(cert), buf, 24858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(buf)); 24868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Got certificate from PKCS12: " 24878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "subject='%s'", buf); 24888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssl) { 24898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_certificate(ssl, cert) != 1) 24908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 24918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 2492d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (SSL_CTX_use_certificate(data->ssl, cert) != 1) 24938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 24948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 24968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pkey) { 24998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Got private key from PKCS12"); 25008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssl) { 25018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_PrivateKey(ssl, pkey) != 1) 25028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 25038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 2504d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (SSL_CTX_use_PrivateKey(data->ssl, pkey) != 1) 25058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 25068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EVP_PKEY_free(pkey); 25088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (certs) { 2511d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt#if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(LIBRESSL_VERSION_NUMBER) 2512b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if (ssl) 2513b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt SSL_clear_chain_certs(ssl); 2514b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt else 2515b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt SSL_CTX_clear_chain_certs(data->ssl); 2516d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt while ((cert = sk_X509_pop(certs)) != NULL) { 2517d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt X509_NAME_oneline(X509_get_subject_name(cert), buf, 2518d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt sizeof(buf)); 2519d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: additional certificate" 2520d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt " from PKCS12: subject='%s'", buf); 2521b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if ((ssl && SSL_add1_chain_cert(ssl, cert) != 1) || 2522b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt (!ssl && SSL_CTX_add1_chain_cert(data->ssl, 2523b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt cert) != 1)) { 2524d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt tls_show_errors(MSG_DEBUG, __func__, 2525d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "Failed to add additional certificate"); 2526d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt res = -1; 252757c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt X509_free(cert); 2528d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt break; 2529d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 253057c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt X509_free(cert); 2531d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 2532d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!res) { 2533d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt /* Try to continue anyway */ 2534d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 253557c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt sk_X509_pop_free(certs, X509_free); 2536d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#ifndef OPENSSL_IS_BORINGSSL 2537b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if (ssl) 2538b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt res = SSL_build_cert_chain( 2539b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt ssl, 2540b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt SSL_BUILD_CHAIN_FLAG_CHECK | 2541b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR); 2542b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt else 2543b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt res = SSL_CTX_build_cert_chain( 2544b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt data->ssl, 2545b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt SSL_BUILD_CHAIN_FLAG_CHECK | 2546b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR); 2547d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!res) { 2548d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt tls_show_errors(MSG_DEBUG, __func__, 2549d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "Failed to build certificate chain"); 2550d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } else if (res == 2) { 2551d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_DEBUG, 2552d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "TLS: Ignore certificate chain verification error when building chain with PKCS#12 extra certificates"); 2553d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 2554d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* OPENSSL_IS_BORINGSSL */ 2555d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt /* 2556d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * Try to continue regardless of result since it is possible for 2557d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * the extra certificates not to be required. 2558d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt */ 2559d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt res = 0; 2560d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#else /* OPENSSL_VERSION_NUMBER >= 0x10002000L */ 2561d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX_clear_extra_chain_certs(data->ssl); 25628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while ((cert = sk_X509_pop(certs)) != NULL) { 25638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_NAME_oneline(X509_get_subject_name(cert), buf, 25648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(buf)); 25658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: additional certificate" 25668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " from PKCS12: subject='%s'", buf); 25678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 25688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * There is no SSL equivalent for the chain cert - so 25698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * always add it to the context... 25708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2571d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (SSL_CTX_add_extra_chain_cert(data->ssl, cert) != 1) 2572d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt { 257357c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt X509_free(cert); 25748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 25758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 25768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 257857c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt sk_X509_pop_free(certs, X509_free); 2579d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* OPENSSL_VERSION_NUMBER >= 0x10002000L */ 25808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PKCS12_free(p12); 25838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) 2585d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt tls_get_errors(data); 25868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 25888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* PKCS12_FUNCS */ 25908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2592d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int tls_read_pkcs12(struct tls_data *data, SSL *ssl, 2593d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const char *private_key, const char *passwd) 25948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef PKCS12_FUNCS 25968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FILE *f; 25978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PKCS12 *p12; 25988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt f = fopen(private_key, "rb"); 26008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (f == NULL) 26018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p12 = d2i_PKCS12_fp(f, NULL); 26048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fclose(f); 26058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p12 == NULL) { 26078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 26088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to use PKCS#12 file"); 26098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2612d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return tls_parse_pkcs12(data, ssl, p12, passwd); 26138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* PKCS12_FUNCS */ 26158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: PKCS12 support disabled - cannot read " 26168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "p12/pfx files"); 26178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* PKCS12_FUNCS */ 26198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2622d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int tls_read_pkcs12_blob(struct tls_data *data, SSL *ssl, 26238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *blob, size_t len, const char *passwd) 26248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef PKCS12_FUNCS 26268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PKCS12 *p12; 26278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2628216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p12 = d2i_PKCS12(NULL, (const unsigned char **) &blob, len); 26298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p12 == NULL) { 26308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 26318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to use PKCS#12 blob"); 26328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2635d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return tls_parse_pkcs12(data, ssl, p12, passwd); 26368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* PKCS12_FUNCS */ 26388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: PKCS12 support disabled - cannot parse " 26398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "p12/pfx blobs"); 26408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* PKCS12_FUNCS */ 26428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_ENGINE 26468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_engine_get_cert(struct tls_connection *conn, 26478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *cert_id, 26488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 **cert) 26498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* this runs after the private key is loaded so no PIN is required */ 26518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct { 26528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *cert_id; 26538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *cert; 26548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } params; 26558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.cert_id = cert_id; 26568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.cert = NULL; 26578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ENGINE_ctrl_cmd(conn->engine, "LOAD_CERT_CTRL", 26598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0, ¶ms, NULL, 1)) { 26601d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt unsigned long err = ERR_get_error(); 26611d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt 26628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "ENGINE: cannot load client cert with id" 26638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " '%s' [%s]", cert_id, 26641d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt ERR_error_string(err, NULL)); 26651d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt if (tls_is_pin_error(err)) 26661d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt return TLS_SET_PARAMS_ENGINE_PRV_BAD_PIN; 26678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED; 26688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!params.cert) { 26708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "ENGINE: did not properly cert with id" 26718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " '%s'", cert_id); 26728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED; 26738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *cert = params.cert; 26758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 26788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_connection_engine_client_cert(struct tls_connection *conn, 26818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *cert_id) 26828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_ENGINE 26848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *cert; 26858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_engine_get_cert(conn, cert_id, &cert)) 26878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!SSL_use_certificate(conn->ssl, cert)) { 26908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_ERROR, __func__, 26918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SSL_use_certificate failed"); 26928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 26938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 26968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: SSL_use_certificate --> " 26978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "OK"); 26988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_ENGINE */ 27018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 27038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2706d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int tls_connection_engine_ca_cert(struct tls_data *data, 27078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn, 27088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *ca_cert_id) 27098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_ENGINE 27118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *cert; 2712d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX *ssl_ctx = data->ssl; 2713216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt X509_STORE *store; 27148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_engine_get_cert(conn, ca_cert_id, &cert)) 27168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* start off the same as tls_connection_ca_cert */ 2719216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt store = X509_STORE_new(); 2720216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (store == NULL) { 27218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - failed to allocate new " 27228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate store", __func__); 27238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 27248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2726216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt SSL_CTX_set_cert_store(ssl_ctx, store); 2727216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!X509_STORE_add_cert(store, cert)) { 27288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned long err = ERR_peek_error(); 27298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_WARNING, __func__, 27308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to add CA certificate from engine " 27318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "to certificate store"); 27328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ERR_GET_LIB(err) == ERR_LIB_X509 && 27338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_GET_REASON(err) == X509_R_CERT_ALREADY_IN_HASH_TABLE) { 27348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - ignoring cert" 27358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " already in hash table error", 27368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__); 27378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 27388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 27398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 27438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - added CA certificate from engine " 27448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "to certificate store", __func__); 27458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb); 274661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt conn->ca_cert_verify = 1; 274761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 27488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 27498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_ENGINE */ 27518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 27538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_connection_engine_private_key(struct tls_connection *conn) 27578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27581eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley#if defined(ANDROID) || !defined(OPENSSL_NO_ENGINE) 27598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_PrivateKey(conn->ssl, conn->private_key) != 1) { 27608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_ERROR, __func__, 27618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ENGINE: cannot use private key for TLS"); 27628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!SSL_check_private_key(conn->ssl)) { 27658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 27668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Private key failed verification"); 27678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 27708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_ENGINE */ 27718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "SSL: Configuration uses engine, but " 27728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "engine support was not compiled in"); 27738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 27758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2778d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int tls_connection_private_key(struct tls_data *data, 27798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn, 27808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *private_key, 27818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *private_key_passwd, 27828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *private_key_blob, 27838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t private_key_blob_len) 27848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2785d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX *ssl_ctx = data->ssl; 27868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *passwd; 27878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ok; 27888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (private_key == NULL && private_key_blob == NULL) 27908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 27918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (private_key_passwd) { 27938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt passwd = os_strdup(private_key_passwd); 27948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (passwd == NULL) 27958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 27978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt passwd = NULL; 27988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_set_default_passwd_cb(ssl_ctx, tls_passwd_cb); 28008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, passwd); 28018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 0; 28038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (private_key_blob) { 28048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_PrivateKey_ASN1(EVP_PKEY_RSA, conn->ssl, 28058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) private_key_blob, 28068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt private_key_blob_len) == 1) { 28078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_PrivateKey_" 28088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ASN1(EVP_PKEY_RSA) --> OK"); 28098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 1; 28108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 28118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_PrivateKey_ASN1(EVP_PKEY_DSA, conn->ssl, 28148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) private_key_blob, 28158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt private_key_blob_len) == 1) { 28168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_PrivateKey_" 28178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ASN1(EVP_PKEY_DSA) --> OK"); 28188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 1; 28198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 28208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_RSAPrivateKey_ASN1(conn->ssl, 28238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) private_key_blob, 28248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt private_key_blob_len) == 1) { 28258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: " 28268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SSL_use_RSAPrivateKey_ASN1 --> OK"); 28278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 1; 28288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 28298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2831d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (tls_read_pkcs12_blob(data, conn->ssl, private_key_blob, 28328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt private_key_blob_len, passwd) == 0) { 28338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: PKCS#12 as blob --> " 28348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "OK"); 28358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 1; 28368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 28378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 28408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (!ok && private_key) { 28438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_STDIO 28448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_PrivateKey_file(conn->ssl, private_key, 28458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_FILETYPE_ASN1) == 1) { 28468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: " 28478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SSL_use_PrivateKey_File (DER) --> OK"); 28488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 1; 28498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 28508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_PrivateKey_file(conn->ssl, private_key, 28538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_FILETYPE_PEM) == 1) { 28548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: " 28558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SSL_use_PrivateKey_File (PEM) --> OK"); 28568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 1; 28578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 28588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_STDIO */ 28608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", 28618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__); 28628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_STDIO */ 28638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2864d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (tls_read_pkcs12(data, conn->ssl, private_key, passwd) 28658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt == 0) { 28668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Reading PKCS#12 file " 28678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "--> OK"); 28688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 1; 28698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 28708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_cryptoapi_cert(conn->ssl, private_key) == 0) { 28738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Using CryptoAPI to " 28748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "access certificate store --> OK"); 28758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 1; 28768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 28778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 28808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ok) { 28838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 28848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to load private key"); 28858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(passwd); 28868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 28878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_clear_error(); 28898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_set_default_passwd_cb(ssl_ctx, NULL); 28908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(passwd); 289161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 28928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!SSL_check_private_key(conn->ssl)) { 28938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, "Private key failed " 28948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "verification"); 28958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 28968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Private key loaded successfully"); 28998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 29008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2903d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int tls_global_private_key(struct tls_data *data, 2904d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const char *private_key, 29058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *private_key_passwd) 29068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2907d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX *ssl_ctx = data->ssl; 29088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *passwd; 29098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (private_key == NULL) 29118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 29128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (private_key_passwd) { 29148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt passwd = os_strdup(private_key_passwd); 29158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (passwd == NULL) 29168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 29178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 29188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt passwd = NULL; 29198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_set_default_passwd_cb(ssl_ctx, tls_passwd_cb); 29218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, passwd); 29228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ( 29238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_STDIO 29248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_use_PrivateKey_file(ssl_ctx, private_key, 29258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_FILETYPE_ASN1) != 1 && 29268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_use_PrivateKey_file(ssl_ctx, private_key, 29278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_FILETYPE_PEM) != 1 && 29288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_STDIO */ 2929d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt tls_read_pkcs12(data, NULL, private_key, passwd)) { 29308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 29318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to load private key"); 29328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(passwd); 29338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_clear_error(); 29348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 29358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(passwd); 29378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_clear_error(); 29388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_set_default_passwd_cb(ssl_ctx, NULL); 293961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 29408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!SSL_CTX_check_private_key(ssl_ctx)) { 29418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 29428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Private key failed verification"); 29438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 29448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 29478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_connection_dh(struct tls_connection *conn, const char *dh_file) 29518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef OPENSSL_NO_DH 29538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dh_file == NULL) 29548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 29558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "TLS: openssl does not include DH support, but " 29568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dh_file specified"); 29578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 29588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_DH */ 29598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DH *dh; 29608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO *bio; 29618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: add support for dh_blob */ 29638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dh_file == NULL) 29648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 29658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 29668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 29678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bio = BIO_new_file(dh_file, "r"); 29698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bio == NULL) { 29708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to open DH file '%s': %s", 29718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dh_file, ERR_error_string(ERR_get_error(), NULL)); 29728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 29738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); 29758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO_free(bio); 29768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_DSA 29778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (dh == NULL) { 29788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DSA *dsa; 29798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Failed to parse DH file '%s': %s -" 29808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " trying to parse as DSA params", dh_file, 29818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 29828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bio = BIO_new_file(dh_file, "r"); 29838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bio == NULL) 29848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 29858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dsa = PEM_read_bio_DSAparams(bio, NULL, NULL, NULL); 29868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO_free(bio); 29878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!dsa) { 29888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Failed to parse DSA file " 29898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s': %s", dh_file, 29908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 29918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 29928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: DH file in DSA param format"); 29958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dh = DSA_dup_DH(dsa); 29968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DSA_free(dsa); 29978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dh == NULL) { 29988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to convert DSA " 29998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "params into DH params"); 30008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* !OPENSSL_NO_DSA */ 30058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dh == NULL) { 30068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to read/parse DH/DSA file " 30078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s'", dh_file); 30088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 30098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_set_tmp_dh(conn->ssl, dh) != 1) { 30128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to set DH params from '%s': " 30138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%s", dh_file, 30148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 30158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DH_free(dh); 30168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 30178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DH_free(dh); 30198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 30208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_DH */ 30218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3024d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int tls_global_dh(struct tls_data *data, const char *dh_file) 30258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 30268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef OPENSSL_NO_DH 30278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dh_file == NULL) 30288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 30298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "TLS: openssl does not include DH support, but " 30308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dh_file specified"); 30318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 30328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_DH */ 3033d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX *ssl_ctx = data->ssl; 30348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DH *dh; 30358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO *bio; 30368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: add support for dh_blob */ 30388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dh_file == NULL) 30398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 30408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssl_ctx == NULL) 30418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 30428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bio = BIO_new_file(dh_file, "r"); 30448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bio == NULL) { 30458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to open DH file '%s': %s", 30468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dh_file, ERR_error_string(ERR_get_error(), NULL)); 30478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 30488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); 30508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO_free(bio); 30518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_DSA 30528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (dh == NULL) { 30538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DSA *dsa; 30548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Failed to parse DH file '%s': %s -" 30558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " trying to parse as DSA params", dh_file, 30568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 30578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bio = BIO_new_file(dh_file, "r"); 30588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bio == NULL) 30598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dsa = PEM_read_bio_DSAparams(bio, NULL, NULL, NULL); 30618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO_free(bio); 30628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!dsa) { 30638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Failed to parse DSA file " 30648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s': %s", dh_file, 30658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 30668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: DH file in DSA param format"); 30708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dh = DSA_dup_DH(dsa); 30718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DSA_free(dsa); 30728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dh == NULL) { 30738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to convert DSA " 30748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "params into DH params"); 30758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* !OPENSSL_NO_DSA */ 30808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dh == NULL) { 30818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to read/parse DH/DSA file " 30828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s'", dh_file); 30838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 30848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_CTX_set_tmp_dh(ssl_ctx, dh) != 1) { 30878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to set DH params from '%s': " 30888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%s", dh_file, 30898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 30908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DH_free(dh); 30918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 30928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DH_free(dh); 30948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 30958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_DH */ 30968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3099d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtint tls_connection_get_random(void *ssl_ctx, struct tls_connection *conn, 3100d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct tls_random *keys) 31018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 31028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL *ssl; 31038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL || keys == NULL) 31058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 31068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssl = conn->ssl; 3107d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (ssl == NULL) 3108d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return -1; 3109d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3110d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt os_memset(keys, 0, sizeof(*keys)); 3111d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt keys->client_random = conn->client_random; 3112d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt keys->client_random_len = SSL_get_client_random( 3113d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ssl, conn->client_random, sizeof(conn->client_random)); 3114d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt keys->server_random = conn->server_random; 3115d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt keys->server_random_len = SSL_get_server_random( 3116d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ssl, conn->server_random, sizeof(conn->server_random)); 31178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 31198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3122849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt#ifdef OPENSSL_NEED_EAP_FAST_PRF 3123af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidtstatic int openssl_get_keyblock_size(SSL *ssl) 3124af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt{ 3125d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) 3126af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt const EVP_CIPHER *c; 3127af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt const EVP_MD *h; 3128af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt int md_size; 3129af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt 3130af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt if (ssl->enc_read_ctx == NULL || ssl->enc_read_ctx->cipher == NULL || 3131af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt ssl->read_hash == NULL) 3132af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt return -1; 3133af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt 3134af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt c = ssl->enc_read_ctx->cipher; 3135af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt h = EVP_MD_CTX_md(ssl->read_hash); 3136af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt if (h) 3137af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt md_size = EVP_MD_size(h); 3138af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt else if (ssl->s3) 3139af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt md_size = ssl->s3->tmp.new_mac_secret_size; 3140af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt else 3141af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt return -1; 3142af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt 3143af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: keyblock size: key_len=%d MD_size=%d " 3144af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt "IV_len=%d", EVP_CIPHER_key_length(c), md_size, 3145af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt EVP_CIPHER_iv_length(c)); 3146af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt return 2 * (EVP_CIPHER_key_length(c) + 3147af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt md_size + 3148af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt EVP_CIPHER_iv_length(c)); 3149d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#else 3150d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const SSL_CIPHER *ssl_cipher; 3151d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt int cipher, digest; 3152d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const EVP_CIPHER *c; 3153d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const EVP_MD *h; 3154d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3155d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ssl_cipher = SSL_get_current_cipher(ssl); 3156d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!ssl_cipher) 3157d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return -1; 3158d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt cipher = SSL_CIPHER_get_cipher_nid(ssl_cipher); 3159d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt digest = SSL_CIPHER_get_digest_nid(ssl_cipher); 3160d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: cipher nid %d digest nid %d", 3161d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt cipher, digest); 3162d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (cipher < 0 || digest < 0) 3163d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return -1; 3164d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt c = EVP_get_cipherbynid(cipher); 3165d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt h = EVP_get_digestbynid(digest); 3166d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!c || !h) 3167d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return -1; 3168d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3169d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_DEBUG, 3170d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "OpenSSL: keyblock size: key_len=%d MD_size=%d IV_len=%d", 3171d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt EVP_CIPHER_key_length(c), EVP_MD_size(h), 3172d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt EVP_CIPHER_iv_length(c)); 3173d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return 2 * (EVP_CIPHER_key_length(c) + EVP_MD_size(h) + 3174d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt EVP_CIPHER_iv_length(c)); 3175d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif 3176af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt} 3177849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt#endif /* OPENSSL_NEED_EAP_FAST_PRF */ 3178af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt 3179af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt 3180849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidtint tls_connection_export_key(void *tls_ctx, struct tls_connection *conn, 3181849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt const char *label, u8 *out, size_t out_len) 3182af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt{ 3183849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt if (!conn || 3184849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt SSL_export_keying_material(conn->ssl, out, out_len, label, 3185849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt os_strlen(label), NULL, 0, 0) != 1) 3186849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt return -1; 3187849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt return 0; 3188849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt} 3189849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt 3190849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt 3191849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidtint tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn, 3192849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt u8 *out, size_t out_len) 3193849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt{ 3194849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt#ifdef OPENSSL_NEED_EAP_FAST_PRF 3195d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL *ssl; 3196d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_SESSION *sess; 3197d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt u8 *rnd; 3198d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt int ret = -1; 3199d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt int skip = 0; 3200d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt u8 *tmp_out = NULL; 3201d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt u8 *_out = out; 3202d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt unsigned char client_random[SSL3_RANDOM_SIZE]; 3203d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt unsigned char server_random[SSL3_RANDOM_SIZE]; 3204d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt unsigned char master_key[64]; 3205d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt size_t master_key_len; 3206d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const char *ver; 3207d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3208d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt /* 3209849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt * TLS library did not support EAP-FAST key generation, so get the 3210849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt * needed TLS session parameters and use an internal implementation of 3211849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt * TLS PRF to derive the key. 3212d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt */ 3213d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3214d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (conn == NULL) 3215d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return -1; 3216d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ssl = conn->ssl; 3217d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (ssl == NULL) 3218d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return -1; 3219d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ver = SSL_get_version(ssl); 3220d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt sess = SSL_get_session(ssl); 3221d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!ver || !sess) 3222d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return -1; 3223d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3224849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt skip = openssl_get_keyblock_size(ssl); 3225849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt if (skip < 0) 3226849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt return -1; 3227849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt tmp_out = os_malloc(skip + out_len); 3228849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt if (!tmp_out) 3229849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt return -1; 3230849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt _out = tmp_out; 3231d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3232d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt rnd = os_malloc(2 * SSL3_RANDOM_SIZE); 3233d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!rnd) { 3234d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt os_free(tmp_out); 3235d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return -1; 3236d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 3237d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3238d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_get_client_random(ssl, client_random, sizeof(client_random)); 3239d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_get_server_random(ssl, server_random, sizeof(server_random)); 3240d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt master_key_len = SSL_SESSION_get_master_key(sess, master_key, 3241d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt sizeof(master_key)); 3242d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3243849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt os_memcpy(rnd, server_random, SSL3_RANDOM_SIZE); 3244849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt os_memcpy(rnd + SSL3_RANDOM_SIZE, client_random, SSL3_RANDOM_SIZE); 3245d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3246d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (os_strcmp(ver, "TLSv1.2") == 0) { 3247d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt tls_prf_sha256(master_key, master_key_len, 3248849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt "key expansion", rnd, 2 * SSL3_RANDOM_SIZE, 3249d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt _out, skip + out_len); 3250af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt ret = 0; 3251d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } else if (tls_prf_sha1_md5(master_key, master_key_len, 3252849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt "key expansion", rnd, 2 * SSL3_RANDOM_SIZE, 3253d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt _out, skip + out_len) == 0) { 3254d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ret = 0; 3255d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 3256d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt os_memset(master_key, 0, sizeof(master_key)); 3257af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt os_free(rnd); 3258849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt if (ret == 0) 3259af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt os_memcpy(out, _out + skip, out_len); 3260af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt bin_clear_free(tmp_out, skip); 3261af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt 3262af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt return ret; 3263849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt#else /* OPENSSL_NEED_EAP_FAST_PRF */ 3264849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt wpa_printf(MSG_ERROR, 3265849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt "OpenSSL: EAP-FAST keys cannot be exported in FIPS mode"); 3266849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt return -1; 3267849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt#endif /* OPENSSL_NEED_EAP_FAST_PRF */ 32688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 32698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * 32728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtopenssl_handshake(struct tls_connection *conn, const struct wpabuf *in_data, 32738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int server) 32748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 32758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 32768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *out_data; 32778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 32798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Give TLS handshake data from the server (if available) to OpenSSL 32808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * for processing. 32818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3282d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (in_data && wpabuf_len(in_data) > 0 && 32838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO_write(conn->ssl_in, wpabuf_head(in_data), wpabuf_len(in_data)) 32848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt < 0) { 32858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 32868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Handshake failed - BIO_write"); 32878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 32888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Initiate TLS handshake or continue the existing handshake */ 32918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (server) 32928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = SSL_accept(conn->ssl); 32938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 32948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = SSL_connect(conn->ssl); 32958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res != 1) { 32968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int err = SSL_get_error(conn->ssl, res); 32978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (err == SSL_ERROR_WANT_READ) 32988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: SSL_connect - want " 32998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "more data"); 33008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (err == SSL_ERROR_WANT_WRITE) 33018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: SSL_connect - want to " 33028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "write"); 33038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 33048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, "SSL_connect"); 33058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->failed++; 33068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Get the TLS handshake data to be sent to the server */ 33108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = BIO_ctrl_pending(conn->ssl_out); 33118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: %d bytes pending from ssl_out", res); 33128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out_data = wpabuf_alloc(res); 33138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (out_data == NULL) { 33148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Failed to allocate memory for " 33158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "handshake output (%d bytes)", res); 33168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (BIO_reset(conn->ssl_out) < 0) { 33178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 33188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "BIO_reset failed"); 33198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 33218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = res == 0 ? 0 : BIO_read(conn->ssl_out, wpabuf_mhead(out_data), 33238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res); 33248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 33258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 33268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Handshake failed - BIO_read"); 33278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (BIO_reset(conn->ssl_out) < 0) { 33288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 33298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "BIO_reset failed"); 33308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(out_data); 33328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 33338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put(out_data, res); 33358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return out_data; 33378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 33388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * 33418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtopenssl_get_appl_data(struct tls_connection *conn, size_t max_len) 33428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 33438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *appl_data; 33448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 33458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt appl_data = wpabuf_alloc(max_len + 100); 33478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (appl_data == NULL) 33488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 33498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = SSL_read(conn->ssl, wpabuf_mhead(appl_data), 33518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_size(appl_data)); 33528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 33538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int err = SSL_get_error(conn->ssl, res); 33548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (err == SSL_ERROR_WANT_READ || 33558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err == SSL_ERROR_WANT_WRITE) { 33568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: No Application Data " 33578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "included"); 33588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 33598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 33608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to read possible " 33618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Application Data"); 33628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(appl_data); 33648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 33658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put(appl_data, res); 33688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_buf_key(MSG_MSGDUMP, "SSL: Application Data in Finished " 33698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "message", appl_data); 33708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return appl_data; 33728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 33738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * 33768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtopenssl_connection_handshake(struct tls_connection *conn, 33778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *in_data, 33788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf **appl_data, int server) 33798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 33808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *out_data; 33818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (appl_data) 33838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *appl_data = NULL; 33848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out_data = openssl_handshake(conn, in_data, server); 33868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (out_data == NULL) 33878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 338826af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen if (conn->invalid_hb_used) { 338926af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen wpa_printf(MSG_INFO, "TLS: Heartbeat attack detected - do not send response"); 339026af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen wpabuf_free(out_data); 339126af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen return NULL; 339226af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen } 33938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3394d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (SSL_is_init_finished(conn->ssl)) { 3395d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_DEBUG, 3396d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "OpenSSL: Handshake finished - resumed=%d", 3397d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt tls_connection_resumed(conn->ssl_ctx, conn)); 3398d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (appl_data && in_data) 3399d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt *appl_data = openssl_get_appl_data(conn, 3400d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpabuf_len(in_data)); 3401d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 34028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 340326af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen if (conn->invalid_hb_used) { 340426af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen wpa_printf(MSG_INFO, "TLS: Heartbeat attack detected - do not send response"); 340526af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen if (appl_data) { 340626af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen wpabuf_free(*appl_data); 340726af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen *appl_data = NULL; 340826af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen } 340926af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen wpabuf_free(out_data); 341026af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen return NULL; 341126af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen } 341226af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen 34138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return out_data; 34148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 34158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * 34188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttls_connection_handshake(void *ssl_ctx, struct tls_connection *conn, 34198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *in_data, 34208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf **appl_data) 34218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 34228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return openssl_connection_handshake(conn, in_data, appl_data, 0); 34238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 34248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * tls_connection_server_handshake(void *tls_ctx, 34278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn, 34288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *in_data, 34298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf **appl_data) 34308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 34318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return openssl_connection_handshake(conn, in_data, appl_data, 1); 34328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 34338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * tls_connection_encrypt(void *tls_ctx, 34368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn, 34378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *in_data) 34388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 34398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 34408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 34418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 34438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 34448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Give plaintext data for OpenSSL to encrypt into the TLS tunnel. */ 34468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((res = BIO_reset(conn->ssl_in)) < 0 || 34478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (res = BIO_reset(conn->ssl_out)) < 0) { 34488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, "BIO_reset failed"); 34498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 34508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = SSL_write(conn->ssl, wpabuf_head(in_data), wpabuf_len(in_data)); 34528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 34538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 34548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Encryption failed - SSL_write"); 34558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 34568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Read encrypted data to be sent to the server */ 34598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = wpabuf_alloc(wpabuf_len(in_data) + 300); 34608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 34618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 34628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = BIO_read(conn->ssl_out, wpabuf_mhead(buf), wpabuf_size(buf)); 34638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 34648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 34658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Encryption failed - BIO_read"); 34668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(buf); 34678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 34688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put(buf, res); 34708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 34728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 34738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * tls_connection_decrypt(void *tls_ctx, 34768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn, 34778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *in_data) 34788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 34798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 34808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 34818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Give encrypted data from TLS tunnel for OpenSSL to decrypt. */ 34838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = BIO_write(conn->ssl_in, wpabuf_head(in_data), 34848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_len(in_data)); 34858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 34868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 34878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Decryption failed - BIO_write"); 34888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 34898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (BIO_reset(conn->ssl_out) < 0) { 34918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, "BIO_reset failed"); 34928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 34938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Read decrypted data for further processing */ 34968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 34978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Even though we try to disable TLS compression, it is possible that 34988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * this cannot be done with all TLS libraries. Add extra buffer space 34998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to handle the possibility of the decrypted data being longer than 35008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * input data. 35018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 35028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3); 35038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 35048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 35058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = SSL_read(conn->ssl, wpabuf_mhead(buf), wpabuf_size(buf)); 35068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 35078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 35088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Decryption failed - SSL_read"); 35098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(buf); 35108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 35118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 35128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put(buf, res); 35138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 351426af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen if (conn->invalid_hb_used) { 351526af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen wpa_printf(MSG_INFO, "TLS: Heartbeat attack detected - do not send response"); 351626af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen wpabuf_free(buf); 351726af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen return NULL; 351826af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen } 351926af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen 35208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 35218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 35228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_resumed(void *ssl_ctx, struct tls_connection *conn) 35258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3526216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return conn ? SSL_cache_hit(conn->ssl) : 0; 35278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 35288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn, 35318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *ciphers) 35328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3533de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt char buf[500], *pos, *end; 35348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *c; 35358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 35368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL || conn->ssl == NULL || ciphers == NULL) 35388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 35398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[0] = '\0'; 35418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = buf; 35428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + sizeof(buf); 35438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt c = ciphers; 35458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (*c != TLS_CIPHER_NONE) { 35468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *suite; 35478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (*c) { 35498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TLS_CIPHER_RC4_SHA: 35508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suite = "RC4-SHA"; 35518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 35528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TLS_CIPHER_AES128_SHA: 35538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suite = "AES128-SHA"; 35548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 35558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TLS_CIPHER_RSA_DHE_AES128_SHA: 35568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suite = "DHE-RSA-AES128-SHA"; 35578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 35588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TLS_CIPHER_ANON_DH_AES128_SHA: 35598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suite = "ADH-AES128-SHA"; 35608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3561de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt case TLS_CIPHER_RSA_DHE_AES256_SHA: 3562de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt suite = "DHE-RSA-AES256-SHA"; 3563de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt break; 3564de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt case TLS_CIPHER_AES256_SHA: 3565de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt suite = "AES256-SHA"; 3566de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt break; 35678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 35688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Unsupported " 35698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "cipher selection: %d", *c); 35708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 35718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 35728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, ":%s", suite); 35736c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(end - pos, ret)) 35748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 35758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 35768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt c++; 35788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 35798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: cipher suites: %s", buf + 1); 35818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3582d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) 3583d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) 3584d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (os_strstr(buf, ":ADH-")) { 3585d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt /* 3586d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * Need to drop to security level 0 to allow anonymous 3587d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * cipher suites for EAP-FAST. 3588d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt */ 3589d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_set_security_level(conn->ssl, 0); 3590d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } else if (SSL_get_security_level(conn->ssl) == 0) { 3591d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt /* Force at least security level 1 */ 3592d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_set_security_level(conn->ssl, 1); 3593d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 3594d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */ 3595d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif 3596d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 35978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_set_cipher_list(conn->ssl, buf + 1) != 1) { 35988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 35998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Cipher suite configuration failed"); 36008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 36018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 36028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 36048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 36058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3607d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtint tls_get_version(void *ssl_ctx, struct tls_connection *conn, 3608d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt char *buf, size_t buflen) 3609d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 3610d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const char *name; 3611d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (conn == NULL || conn->ssl == NULL) 3612d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return -1; 3613d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3614d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt name = SSL_get_version(conn->ssl); 3615d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (name == NULL) 3616d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return -1; 3617d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3618d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt os_strlcpy(buf, name, buflen); 3619d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return 0; 3620d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 3621d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3622d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 36238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_get_cipher(void *ssl_ctx, struct tls_connection *conn, 36248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *buf, size_t buflen) 36258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 36268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *name; 36278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL || conn->ssl == NULL) 36288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 36298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name = SSL_get_cipher(conn->ssl); 36318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (name == NULL) 36328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 36338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(buf, name, buflen); 36358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 36368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 36378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_enable_workaround(void *ssl_ctx, 36408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn) 36418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 36428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_options(conn->ssl, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS); 36438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 36458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 36468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) 36498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* ClientHello TLS extensions require a patch to openssl, so this function is 36508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * commented out unless explicitly needed for EAP-FAST in order to be able to 36518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * build this file with unmodified openssl. */ 36528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_client_hello_ext(void *ssl_ctx, struct tls_connection *conn, 36538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ext_type, const u8 *data, 36548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t data_len) 36558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 36568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL || conn->ssl == NULL || ext_type != 35) 36578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 36588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_set_session_ticket_ext(conn->ssl, (void *) data, 36608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data_len) != 1) 36618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 36628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 36648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 36658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */ 36668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_get_failed(void *ssl_ctx, struct tls_connection *conn) 36698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 36708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 36718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 36728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return conn->failed; 36738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 36748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_get_read_alerts(void *ssl_ctx, struct tls_connection *conn) 36778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 36788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 36798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 36808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return conn->read_alerts; 36818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 36828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_get_write_alerts(void *ssl_ctx, struct tls_connection *conn) 36858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 36868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 36878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 36888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return conn->write_alerts; 36898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 36908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 369234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#ifdef HAVE_OCSP 369334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 369434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidtstatic void ocsp_debug_print_resp(OCSP_RESPONSE *rsp) 369534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt{ 369634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#ifndef CONFIG_NO_STDOUT_DEBUG 369734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt BIO *out; 369834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt size_t rlen; 369934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt char *txt; 370034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt int res; 370134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 370234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (wpa_debug_level > MSG_DEBUG) 370334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return; 370434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 370534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt out = BIO_new(BIO_s_mem()); 370634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (!out) 370734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return; 370834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 370934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_RESPONSE_print(out, rsp, 0); 371034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt rlen = BIO_ctrl_pending(out); 371134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt txt = os_malloc(rlen + 1); 371234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (!txt) { 371334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt BIO_free(out); 371434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return; 371534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 371634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 371734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt res = BIO_read(out, txt, rlen); 371834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (res > 0) { 371934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt txt[res] = '\0'; 372034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: OCSP Response\n%s", txt); 372134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 372234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt os_free(txt); 372334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt BIO_free(out); 372434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#endif /* CONFIG_NO_STDOUT_DEBUG */ 372534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt} 372634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 372734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 3728717574375e969e8272c6d1a26137286eac158abbDmitry Shmidtstatic void debug_print_cert(X509 *cert, const char *title) 3729717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt{ 3730717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt#ifndef CONFIG_NO_STDOUT_DEBUG 3731717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt BIO *out; 3732717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt size_t rlen; 3733717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt char *txt; 3734717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt int res; 3735717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt 3736717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt if (wpa_debug_level > MSG_DEBUG) 3737717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt return; 3738717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt 3739717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt out = BIO_new(BIO_s_mem()); 3740717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt if (!out) 3741717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt return; 3742717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt 3743717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt X509_print(out, cert); 3744717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt rlen = BIO_ctrl_pending(out); 3745717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt txt = os_malloc(rlen + 1); 3746717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt if (!txt) { 3747717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt BIO_free(out); 3748717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt return; 3749717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt } 3750717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt 3751717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt res = BIO_read(out, txt, rlen); 3752717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt if (res > 0) { 3753717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt txt[res] = '\0'; 3754717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s\n%s", title, txt); 3755717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt } 3756717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt os_free(txt); 3757717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt 3758717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt BIO_free(out); 3759717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt#endif /* CONFIG_NO_STDOUT_DEBUG */ 3760717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt} 3761717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt 3762717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt 376334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidtstatic int ocsp_resp_cb(SSL *s, void *arg) 376434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt{ 376534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt struct tls_connection *conn = arg; 376634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt const unsigned char *p; 376734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt int len, status, reason; 376834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_RESPONSE *rsp; 376934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_BASICRESP *basic; 377034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_CERTID *id; 377134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt ASN1_GENERALIZEDTIME *produced_at, *this_update, *next_update; 3772fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt X509_STORE *store; 3773fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt STACK_OF(X509) *certs = NULL; 377434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 377534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt len = SSL_get_tlsext_status_ocsp_resp(s, &p); 377634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (!p) { 377734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: No OCSP response received"); 377834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return (conn->flags & TLS_CONN_REQUIRE_OCSP) ? 0 : 1; 377934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 378034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 378134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "OpenSSL: OCSP response", p, len); 378234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 378334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt rsp = d2i_OCSP_RESPONSE(NULL, &p, len); 378434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (!rsp) { 378534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_INFO, "OpenSSL: Failed to parse OCSP response"); 378634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return 0; 378734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 378834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 378934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt ocsp_debug_print_resp(rsp); 379034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 379134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt status = OCSP_response_status(rsp); 379234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) { 379334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_INFO, "OpenSSL: OCSP responder error %d (%s)", 379434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt status, OCSP_response_status_str(status)); 379534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return 0; 379634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 379734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 379834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt basic = OCSP_response_get1_basic(rsp); 379934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (!basic) { 380034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_INFO, "OpenSSL: Could not find BasicOCSPResponse"); 380134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return 0; 380234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 380334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 3804216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt store = SSL_CTX_get_cert_store(conn->ssl_ctx); 3805fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (conn->peer_issuer) { 3806717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt debug_print_cert(conn->peer_issuer, "Add OCSP issuer"); 3807fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 3808fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (X509_STORE_add_cert(store, conn->peer_issuer) != 1) { 3809fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 38107f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt "OpenSSL: Could not add issuer to certificate store"); 3811fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 3812fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt certs = sk_X509_new_null(); 3813fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (certs) { 3814fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt X509 *cert; 3815fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt cert = X509_dup(conn->peer_issuer); 3816fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (cert && !sk_X509_push(certs, cert)) { 3817fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt tls_show_errors( 3818fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt MSG_INFO, __func__, 38197f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt "OpenSSL: Could not add issuer to OCSP responder trust store"); 3820fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt X509_free(cert); 3821fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt sk_X509_free(certs); 3822fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt certs = NULL; 3823fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 38247f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt if (certs && conn->peer_issuer_issuer) { 3825fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt cert = X509_dup(conn->peer_issuer_issuer); 3826fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (cert && !sk_X509_push(certs, cert)) { 3827fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt tls_show_errors( 3828fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt MSG_INFO, __func__, 38297f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt "OpenSSL: Could not add issuer's issuer to OCSP responder trust store"); 3830fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt X509_free(cert); 3831fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 3832fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 3833fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 3834fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 3835fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 3836fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt status = OCSP_basic_verify(basic, certs, store, OCSP_TRUSTOTHER); 3837fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt sk_X509_pop_free(certs, X509_free); 383834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (status <= 0) { 383934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 384034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt "OpenSSL: OCSP response failed verification"); 384134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_BASICRESP_free(basic); 384234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_RESPONSE_free(rsp); 384334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return 0; 384434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 384534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 384634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: OCSP response verification succeeded"); 384734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 38485605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (!conn->peer_cert) { 38495605286c30e1701491bd3af974ae423727750eddDmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Peer certificate not available for OCSP status check"); 38505605286c30e1701491bd3af974ae423727750eddDmitry Shmidt OCSP_BASICRESP_free(basic); 38515605286c30e1701491bd3af974ae423727750eddDmitry Shmidt OCSP_RESPONSE_free(rsp); 38525605286c30e1701491bd3af974ae423727750eddDmitry Shmidt return 0; 38535605286c30e1701491bd3af974ae423727750eddDmitry Shmidt } 38545605286c30e1701491bd3af974ae423727750eddDmitry Shmidt 38555605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (!conn->peer_issuer) { 38565605286c30e1701491bd3af974ae423727750eddDmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Peer issuer certificate not available for OCSP status check"); 385734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_BASICRESP_free(basic); 385834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_RESPONSE_free(rsp); 385934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return 0; 386034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 386134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 386234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt id = OCSP_cert_to_id(NULL, conn->peer_cert, conn->peer_issuer); 386334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (!id) { 386434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Could not create OCSP certificate identifier"); 386534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_BASICRESP_free(basic); 386634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_RESPONSE_free(rsp); 386734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return 0; 386834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 386934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 387034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (!OCSP_resp_find_status(basic, id, &status, &reason, &produced_at, 387134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt &this_update, &next_update)) { 387234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_INFO, "OpenSSL: Could not find current server certificate from OCSP response%s", 387334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt (conn->flags & TLS_CONN_REQUIRE_OCSP) ? "" : 387434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt " (OCSP not required)"); 387557c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt OCSP_CERTID_free(id); 387634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_BASICRESP_free(basic); 387734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_RESPONSE_free(rsp); 387834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return (conn->flags & TLS_CONN_REQUIRE_OCSP) ? 0 : 1; 387934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 388057c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt OCSP_CERTID_free(id); 388134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 388234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (!OCSP_check_validity(this_update, next_update, 5 * 60, -1)) { 388334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 388434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt "OpenSSL: OCSP status times invalid"); 388534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_BASICRESP_free(basic); 388634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_RESPONSE_free(rsp); 388734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return 0; 388834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 388934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 389034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_BASICRESP_free(basic); 389134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_RESPONSE_free(rsp); 389234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 389334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status for server certificate: %s", 389434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_cert_status_str(status)); 389534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 389634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (status == V_OCSP_CERTSTATUS_GOOD) 389734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return 1; 389834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (status == V_OCSP_CERTSTATUS_REVOKED) 389934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return 0; 390034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (conn->flags & TLS_CONN_REQUIRE_OCSP) { 390134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status unknown, but OCSP required"); 390234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return 0; 390334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 3904051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status unknown, but OCSP was not required, so allow connection to continue"); 390534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return 1; 390634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt} 390734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 390834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 390934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidtstatic int ocsp_status_cb(SSL *s, void *arg) 391034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt{ 391134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt char *tmp; 391234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt char *resp; 391334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt size_t len; 391434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 391534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (tls_global->ocsp_stapling_response == NULL) { 391634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status callback - no response configured"); 391734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return SSL_TLSEXT_ERR_OK; 391834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 391934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 392034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt resp = os_readfile(tls_global->ocsp_stapling_response, &len); 392134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (resp == NULL) { 392234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status callback - could not read response file"); 392334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt /* TODO: Build OCSPResponse with responseStatus = internalError 392434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt */ 392534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return SSL_TLSEXT_ERR_OK; 392634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 392734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status callback - send cached response"); 392834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt tmp = OPENSSL_malloc(len); 392934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (tmp == NULL) { 393034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt os_free(resp); 393134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return SSL_TLSEXT_ERR_ALERT_FATAL; 393234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 393334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 393434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt os_memcpy(tmp, resp, len); 393534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt os_free(resp); 393634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt SSL_set_tlsext_status_ocsp_resp(s, tmp, len); 393734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 393834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return SSL_TLSEXT_ERR_OK; 393934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt} 394034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 394134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#endif /* HAVE_OCSP */ 394234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 394334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 39448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_set_params(void *tls_ctx, struct tls_connection *conn, 39458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct tls_connection_params *params) 39468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3947d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct tls_data *data = tls_ctx; 39488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 39498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned long err; 39506c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt int can_pkcs11 = 0; 39516c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt const char *key_id = params->key_id; 39526c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt const char *cert_id = params->cert_id; 39536c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt const char *ca_cert_id = params->ca_cert_id; 39546c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt const char *engine_id = params->engine ? params->engine_id : NULL; 39558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 39578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 39588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3959014a3ff83915745d57480e99b47e281a82143c79Dmitry Shmidt if (params->flags & TLS_CONN_REQUIRE_OCSP_ALL) { 3960014a3ff83915745d57480e99b47e281a82143c79Dmitry Shmidt wpa_printf(MSG_INFO, 3961014a3ff83915745d57480e99b47e281a82143c79Dmitry Shmidt "OpenSSL: ocsp=3 not supported"); 3962014a3ff83915745d57480e99b47e281a82143c79Dmitry Shmidt return -1; 3963014a3ff83915745d57480e99b47e281a82143c79Dmitry Shmidt } 3964014a3ff83915745d57480e99b47e281a82143c79Dmitry Shmidt 39656c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* 39666c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * If the engine isn't explicitly configured, and any of the 39676c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * cert/key fields are actually PKCS#11 URIs, then automatically 39686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * use the PKCS#11 ENGINE. 39696c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt */ 39706c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!engine_id || os_strcmp(engine_id, "pkcs11") == 0) 39716c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt can_pkcs11 = 1; 39726c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 39736c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!key_id && params->private_key && can_pkcs11 && 39746c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_strncmp(params->private_key, "pkcs11:", 7) == 0) { 39756c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt can_pkcs11 = 2; 39766c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt key_id = params->private_key; 39776c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 39786c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 39796c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!cert_id && params->client_cert && can_pkcs11 && 39806c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_strncmp(params->client_cert, "pkcs11:", 7) == 0) { 39816c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt can_pkcs11 = 2; 39826c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt cert_id = params->client_cert; 39836c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 39846c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 39856c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!ca_cert_id && params->ca_cert && can_pkcs11 && 39866c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_strncmp(params->ca_cert, "pkcs11:", 7) == 0) { 39876c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt can_pkcs11 = 2; 39886c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ca_cert_id = params->ca_cert; 39896c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 39906c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 39916c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* If we need to automatically enable the PKCS#11 ENGINE, do so. */ 39926c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (can_pkcs11 == 2 && !engine_id) 39936c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt engine_id = "pkcs11"; 39946c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 3995d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) 39969839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) 39976c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (params->flags & TLS_CONN_EAP_FAST) { 39986c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, 39996c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "OpenSSL: Use TLSv1_method() for EAP-FAST"); 40006c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (SSL_set_ssl_method(conn->ssl, TLSv1_method()) != 1) { 40016c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt tls_show_errors(MSG_INFO, __func__, 40026c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "Failed to set TLSv1_method() for EAP-FAST"); 40036c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return -1; 40046c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 40056c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 4006d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif 4007d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */ 40086c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 40098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while ((err = ERR_get_error())) { 40108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "%s: Clearing pending SSL error: %s", 40118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__, ERR_error_string(err, NULL)); 40128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 40138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40146c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (engine_id) { 40158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Initializing TLS engine"); 40166c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ret = tls_engine_init(conn, engine_id, params->pin, 40176c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt key_id, cert_id, ca_cert_id); 40188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret) 40198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 40208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 40218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_connection_set_subject_match(conn, 40228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->subject_match, 4023051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt params->altsubject_match, 40242f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt params->suffix_match, 40252f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt params->domain_match)) 40268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 40278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40286c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (engine_id && ca_cert_id) { 4029d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (tls_connection_engine_ca_cert(data, conn, ca_cert_id)) 40308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED; 4031d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } else if (tls_connection_ca_cert(data, conn, params->ca_cert, 40328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->ca_cert_blob, 40338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->ca_cert_blob_len, 40348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->ca_path)) 40358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 40368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40376c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (engine_id && cert_id) { 40386c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (tls_connection_engine_client_cert(conn, cert_id)) 40398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED; 40408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (tls_connection_client_cert(conn, params->client_cert, 40418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->client_cert_blob, 40428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->client_cert_blob_len)) 40438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 40448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40456c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (engine_id && key_id) { 40468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Using private key from engine"); 40478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_connection_engine_private_key(conn)) 40488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED; 4049d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } else if (tls_connection_private_key(data, conn, 40508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->private_key, 40518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->private_key_passwd, 40528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->private_key_blob, 40538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->private_key_blob_len)) { 40548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to load private key '%s'", 40558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->private_key); 40568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 40578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 40588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_connection_dh(conn, params->dh_file)) { 40608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to load DH file '%s'", 40618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->dh_file); 40628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 40638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 40648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40656c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (params->openssl_ciphers && 40666c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt SSL_set_cipher_list(conn->ssl, params->openssl_ciphers) != 1) { 40676c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_INFO, 40686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "OpenSSL: Failed to set cipher string '%s'", 40696c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt params->openssl_ciphers); 40706c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return -1; 40716c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 40726c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 4073d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt tls_set_conn_flags(conn->ssl, params->flags); 407413ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt 4075d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#ifdef OPENSSL_IS_BORINGSSL 4076d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (params->flags & TLS_CONN_REQUEST_OCSP) { 4077d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_enable_ocsp_stapling(conn->ssl); 4078d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 4079d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#else /* OPENSSL_IS_BORINGSSL */ 408034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#ifdef HAVE_OCSP 408134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (params->flags & TLS_CONN_REQUEST_OCSP) { 4082d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX *ssl_ctx = data->ssl; 408334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt SSL_set_tlsext_status_type(conn->ssl, TLSEXT_STATUSTYPE_ocsp); 408434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt SSL_CTX_set_tlsext_status_cb(ssl_ctx, ocsp_resp_cb); 408534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt SSL_CTX_set_tlsext_status_arg(ssl_ctx, conn); 408634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 4087d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#else /* HAVE_OCSP */ 4088d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (params->flags & TLS_CONN_REQUIRE_OCSP) { 4089d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_INFO, 4090d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "OpenSSL: No OCSP support included - reject configuration"); 4091d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return -1; 4092d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 4093d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (params->flags & TLS_CONN_REQUEST_OCSP) { 4094d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_DEBUG, 4095d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "OpenSSL: No OCSP support included - allow optional OCSP case to continue"); 4096d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 409734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#endif /* HAVE_OCSP */ 4098d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* OPENSSL_IS_BORINGSSL */ 409934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 4100c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt conn->flags = params->flags; 4101c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt 4102d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt tls_get_errors(data); 41038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 41058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 41068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_global_set_params(void *tls_ctx, 41098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct tls_connection_params *params) 41108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4111d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct tls_data *data = tls_ctx; 4112d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX *ssl_ctx = data->ssl; 41138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned long err; 41148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while ((err = ERR_get_error())) { 41168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "%s: Clearing pending SSL error: %s", 41178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__, ERR_error_string(err, NULL)); 41188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 41198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4120d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (tls_global_ca_cert(data, params->ca_cert) || 4121d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt tls_global_client_cert(data, params->client_cert) || 4122d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt tls_global_private_key(data, params->private_key, 4123d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt params->private_key_passwd) || 4124d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt tls_global_dh(data, params->dh_file)) { 4125d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to set global parameters"); 41268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 41278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 41288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41296c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (params->openssl_ciphers && 41306c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt SSL_CTX_set_cipher_list(ssl_ctx, params->openssl_ciphers) != 1) { 41316c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_INFO, 41326c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "OpenSSL: Failed to set cipher string '%s'", 41336c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt params->openssl_ciphers); 41346c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return -1; 41356c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 41366c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 413761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef SSL_OP_NO_TICKET 413861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (params->flags & TLS_CONN_DISABLE_SESSION_TICKET) 413961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TICKET); 414061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt else 414161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt SSL_CTX_clear_options(ssl_ctx, SSL_OP_NO_TICKET); 414261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* SSL_OP_NO_TICKET */ 414361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 414434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#ifdef HAVE_OCSP 414534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt SSL_CTX_set_tlsext_status_cb(ssl_ctx, ocsp_status_cb); 414634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt SSL_CTX_set_tlsext_status_arg(ssl_ctx, ssl_ctx); 414734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt os_free(tls_global->ocsp_stapling_response); 414834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (params->ocsp_stapling_response) 414934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt tls_global->ocsp_stapling_response = 415034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt os_strdup(params->ocsp_stapling_response); 415134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt else 415234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt tls_global->ocsp_stapling_response = NULL; 415334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#endif /* HAVE_OCSP */ 415434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 41558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 41568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 41578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) 41608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Pre-shared secred requires a patch to openssl, so this function is 41618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * commented out unless explicitly needed for EAP-FAST in order to be able to 41628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * build this file with unmodified openssl. */ 41638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41641d6bf427f4769edb60865a3999d01eeb8f8fcb19Dmitry Shmidt#if (defined(OPENSSL_IS_BORINGSSL) || OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER) 41659ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidtstatic int tls_sess_sec_cb(SSL *s, void *secret, int *secret_len, 41669ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt STACK_OF(SSL_CIPHER) *peer_ciphers, 41679ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt const SSL_CIPHER **cipher, void *arg) 41689ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt#else /* OPENSSL_IS_BORINGSSL */ 41698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_sess_sec_cb(SSL *s, void *secret, int *secret_len, 41708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt STACK_OF(SSL_CIPHER) *peer_ciphers, 41718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CIPHER **cipher, void *arg) 41729ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt#endif /* OPENSSL_IS_BORINGSSL */ 41738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 41748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn = arg; 41758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 41768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4177d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) 41788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL || conn->session_ticket_cb == NULL) 41798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 41808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = conn->session_ticket_cb(conn->session_ticket_cb_ctx, 41828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket, 41838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket_len, 41848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->s3->client_random, 41858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->s3->server_random, secret); 4186d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#else 4187d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt unsigned char client_random[SSL3_RANDOM_SIZE]; 4188d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt unsigned char server_random[SSL3_RANDOM_SIZE]; 4189d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 4190d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (conn == NULL || conn->session_ticket_cb == NULL) 4191d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return 0; 4192d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 4193d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_get_client_random(s, client_random, sizeof(client_random)); 4194d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_get_server_random(s, server_random, sizeof(server_random)); 4195d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 4196d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ret = conn->session_ticket_cb(conn->session_ticket_cb_ctx, 4197d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt conn->session_ticket, 4198d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt conn->session_ticket_len, 4199d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt client_random, 4200d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt server_random, secret); 4201d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif 4202d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 42038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->session_ticket); 42048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket = NULL; 42058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret <= 0) 42078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 42088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *secret_len = SSL_MAX_MASTER_KEY_LENGTH; 42108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 42118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 42128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_session_ticket_ext_cb(SSL *s, const unsigned char *data, 42158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len, void *arg) 42168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 42178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn = arg; 42188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL || conn->session_ticket_cb == NULL) 42208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 42218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s: length=%d", __func__, len); 42238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->session_ticket); 42258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket = NULL; 42268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "OpenSSL: ClientHello SessionTicket " 42288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "extension", data, len); 42298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket = os_malloc(len); 42318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->session_ticket == NULL) 42328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 42338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(conn->session_ticket, data, len); 42358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket_len = len; 42368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 42388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 42398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */ 42408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_set_session_ticket_cb(void *tls_ctx, 42438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn, 42448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_session_ticket_cb cb, 42458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *ctx) 42468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 42478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) 42488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket_cb = cb; 42498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket_cb_ctx = ctx; 42508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cb) { 42528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_set_session_secret_cb(conn->ssl, tls_sess_sec_cb, 42538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn) != 1) 42548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 42558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_session_ticket_ext_cb(conn->ssl, 42568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_session_ticket_ext_cb, conn); 42578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 42588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_set_session_secret_cb(conn->ssl, NULL, NULL) != 1) 42598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 42608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_session_ticket_ext_cb(conn->ssl, NULL, NULL); 42618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 42628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 42648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */ 42658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 42668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */ 42678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4268ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 4269ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 4270ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidtint tls_get_library_version(char *buf, size_t buf_len) 4271ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt{ 42721d6bf427f4769edb60865a3999d01eeb8f8fcb19Dmitry Shmidt#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) 4273d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt return os_snprintf(buf, buf_len, "OpenSSL build=%s run=%s", 4274d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt OPENSSL_VERSION_TEXT, 4275d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt OpenSSL_version(OPENSSL_VERSION)); 4276d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt#else 4277ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return os_snprintf(buf, buf_len, "OpenSSL build=%s run=%s", 4278ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt OPENSSL_VERSION_TEXT, 4279ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt SSLeay_version(SSLEAY_VERSION)); 4280d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt#endif 4281ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt} 4282d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 4283d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 4284d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtvoid tls_connection_set_success_data(struct tls_connection *conn, 4285d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct wpabuf *data) 4286d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 4287d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_SESSION *sess; 4288d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct wpabuf *old; 4289d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 4290d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (tls_ex_idx_session < 0) 4291d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt goto fail; 4292d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt sess = SSL_get_session(conn->ssl); 4293d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!sess) 4294d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt goto fail; 4295d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt old = SSL_SESSION_get_ex_data(sess, tls_ex_idx_session); 4296d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (old) { 4297d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Replacing old success data %p", 4298d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt old); 4299d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpabuf_free(old); 4300d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 4301d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (SSL_SESSION_set_ex_data(sess, tls_ex_idx_session, data) != 1) 4302d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt goto fail; 4303d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 4304d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Stored success data %p", data); 4305d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt conn->success_data = 1; 4306d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return; 4307d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 4308d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtfail: 4309d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_INFO, "OpenSSL: Failed to store success data"); 4310d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpabuf_free(data); 4311d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 4312d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 4313d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 4314d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtvoid tls_connection_set_success_data_resumed(struct tls_connection *conn) 4315d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 4316d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_DEBUG, 4317d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "OpenSSL: Success data accepted for resumed session"); 4318d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt conn->success_data = 1; 4319d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 4320d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 4321d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 4322d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtconst struct wpabuf * 4323d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidttls_connection_get_success_data(struct tls_connection *conn) 4324d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 4325d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_SESSION *sess; 4326d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 4327d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (tls_ex_idx_session < 0 || 4328d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt !(sess = SSL_get_session(conn->ssl))) 4329d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return NULL; 4330d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return SSL_SESSION_get_ex_data(sess, tls_ex_idx_session); 4331d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 4332d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 4333d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 4334d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtvoid tls_connection_remove_session(struct tls_connection *conn) 4335d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 4336d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_SESSION *sess; 4337d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 4338d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt sess = SSL_get_session(conn->ssl); 4339d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!sess) 4340d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return; 4341d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 4342d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (SSL_CTX_remove_session(conn->ssl_ctx, sess) != 1) 4343d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_DEBUG, 4344d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "OpenSSL: Session was not cached"); 4345d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt else 4346d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_DEBUG, 4347d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "OpenSSL: Removed cached session to disable session resumption"); 4348d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 4349