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 106d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt#if OPENSSL_VERSION_NUMBER < 0x10100000L 107d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt#ifdef CONFIG_SUITEB 108d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidtstatic int RSA_bits(const RSA *r) 109d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt{ 110d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt return BN_num_bits(r->n); 111d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt} 112d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt#endif /* CONFIG_SUITEB */ 113d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt#endif 114d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 1153f3ca3bb849b192d41b99aae775f6fc52f67118dKenny Root#ifdef ANDROID 1163f3ca3bb849b192d41b99aae775f6fc52f67118dKenny Root#include <openssl/pem.h> 1173f3ca3bb849b192d41b99aae775f6fc52f67118dKenny Root#include <keystore/keystore_get.h> 1183f3ca3bb849b192d41b99aae775f6fc52f67118dKenny Root 1194d8552e9d137f0aab7d64e1476b7f892d0468aebPavel Grafov#include <log/log.h> 1204d8552e9d137f0aab7d64e1476b7f892d0468aebPavel Grafov#include <log/log_event_list.h> 1214d8552e9d137f0aab7d64e1476b7f892d0468aebPavel Grafov 1224d8552e9d137f0aab7d64e1476b7f892d0468aebPavel Grafov#define CERT_VALIDATION_FAILURE 210033 1234d8552e9d137f0aab7d64e1476b7f892d0468aebPavel Grafov 1244d8552e9d137f0aab7d64e1476b7f892d0468aebPavel Grafovstatic void log_cert_validation_failure(const char *reason) 1254d8552e9d137f0aab7d64e1476b7f892d0468aebPavel Grafov{ 1264d8552e9d137f0aab7d64e1476b7f892d0468aebPavel Grafov android_log_context ctx = create_android_logger(CERT_VALIDATION_FAILURE); 1274d8552e9d137f0aab7d64e1476b7f892d0468aebPavel Grafov android_log_write_string8(ctx, reason); 1284d8552e9d137f0aab7d64e1476b7f892d0468aebPavel Grafov android_log_write_list(ctx, LOG_ID_SECURITY); 1294d8552e9d137f0aab7d64e1476b7f892d0468aebPavel Grafov android_log_destroy(&ctx); 1304d8552e9d137f0aab7d64e1476b7f892d0468aebPavel Grafov} 1314d8552e9d137f0aab7d64e1476b7f892d0468aebPavel Grafov 1324d8552e9d137f0aab7d64e1476b7f892d0468aebPavel Grafov 1333f3ca3bb849b192d41b99aae775f6fc52f67118dKenny Rootstatic BIO * BIO_from_keystore(const char *key) 1343f3ca3bb849b192d41b99aae775f6fc52f67118dKenny Root{ 135ff07917b8921a2a178ed9188a63b166af144ae53Dmitry Shmidt BIO *bio = NULL; 136ff07917b8921a2a178ed9188a63b166af144ae53Dmitry Shmidt uint8_t *value = NULL; 137ff07917b8921a2a178ed9188a63b166af144ae53Dmitry Shmidt int length = keystore_get(key, strlen(key), &value); 138ff07917b8921a2a178ed9188a63b166af144ae53Dmitry Shmidt if (length != -1 && (bio = BIO_new(BIO_s_mem())) != NULL) 139ff07917b8921a2a178ed9188a63b166af144ae53Dmitry Shmidt BIO_write(bio, value, length); 140ff07917b8921a2a178ed9188a63b166af144ae53Dmitry Shmidt free(value); 141ff07917b8921a2a178ed9188a63b166af144ae53Dmitry Shmidt return bio; 1423f3ca3bb849b192d41b99aae775f6fc52f67118dKenny Root} 143b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt 144b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt 145b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidtstatic int tls_add_ca_from_keystore(X509_STORE *ctx, const char *key_alias) 146b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt{ 147b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt BIO *bio = BIO_from_keystore(key_alias); 148b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt STACK_OF(X509_INFO) *stack = NULL; 149b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt stack_index_t i; 150b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt 151b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if (bio) { 152b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt stack = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL); 153b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt BIO_free(bio); 154b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt } 155b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt 156b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if (!stack) { 157b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt wpa_printf(MSG_WARNING, "TLS: Failed to parse certificate: %s", 158b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt key_alias); 159b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt return -1; 160b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt } 161b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt 162b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt for (i = 0; i < sk_X509_INFO_num(stack); ++i) { 163b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt X509_INFO *info = sk_X509_INFO_value(stack, i); 164b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt 165b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if (info->x509) 166b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt X509_STORE_add_cert(ctx, info->x509); 167b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if (info->crl) 168b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt X509_STORE_add_crl(ctx, info->crl); 169b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt } 170b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt 171b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt sk_X509_INFO_pop_free(stack, X509_INFO_free); 172b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt 173b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt return 0; 174b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt} 175b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt 176b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt 177b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidtstatic int tls_add_ca_from_keystore_encoded(X509_STORE *ctx, 178b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt const char *encoded_key_alias) 179b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt{ 180b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt int rc = -1; 181b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt int len = os_strlen(encoded_key_alias); 182b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt unsigned char *decoded_alias; 183b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt 184b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if (len & 1) { 185b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt wpa_printf(MSG_WARNING, "Invalid hex-encoded alias: %s", 186b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt encoded_key_alias); 187b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt return rc; 188b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt } 189b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt 190b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt decoded_alias = os_malloc(len / 2 + 1); 191b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if (decoded_alias) { 192b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if (!hexstr2bin(encoded_key_alias, decoded_alias, len / 2)) { 193b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt decoded_alias[len / 2] = '\0'; 194b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt rc = tls_add_ca_from_keystore( 195b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt ctx, (const char *) decoded_alias); 196b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt } 197b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt os_free(decoded_alias); 198b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt } 199b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt 200b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt return rc; 201b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt} 202b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt 2033f3ca3bb849b192d41b99aae775f6fc52f67118dKenny Root#endif /* ANDROID */ 2043f3ca3bb849b192d41b99aae775f6fc52f67118dKenny Root 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_openssl_ref_count = 0; 206d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int tls_ex_idx_session = -1; 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 208ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidtstruct tls_context { 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void (*event_cb)(void *ctx, enum tls_event ev, 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union tls_event_data *data); 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *cb_ctx; 2121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int cert_in_cb; 21334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt char *ocsp_stapling_response; 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 216ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidtstatic struct tls_context *tls_global = NULL; 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 219d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstruct tls_data { 220d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX *ssl; 221d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt unsigned int tls_session_lifetime; 222d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt}; 223d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct tls_connection { 225ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt struct tls_context *context; 226216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt SSL_CTX *ssl_ctx; 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL *ssl; 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO *ssl_in, *ssl_out; 2291eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley#if defined(ANDROID) || !defined(OPENSSL_NO_ENGINE) 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE *engine; /* functional reference to the engine */ 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EVP_PKEY *private_key; /* the private key if using engine */ 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 2332f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt char *subject_match, *altsubject_match, *suffix_match, *domain_match; 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int read_alerts, write_alerts, failed; 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_session_ticket_cb session_ticket_cb; 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *session_ticket_cb_ctx; 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* SessionTicket received from OpenSSL hello_extension_cb (server) */ 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *session_ticket; 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t session_ticket_len; 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int ca_cert_verify:1; 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int cert_probe:1; 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int server_cert_only:1; 24626af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen unsigned int invalid_hb_used:1; 247d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt unsigned int success_data:1; 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 srv_cert_hash[32]; 250c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt 251c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt unsigned int flags; 25234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 25334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt X509 *peer_cert; 25434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt X509 *peer_issuer; 255fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt X509 *peer_issuer_issuer; 256d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 257d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt unsigned char client_random[SSL3_RANDOM_SIZE]; 258d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt unsigned char server_random[SSL3_RANDOM_SIZE]; 259d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 260d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt u16 cipher_suite; 261d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt int server_dh_prime_len; 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 265ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidtstatic struct tls_context * tls_context_new(const struct tls_config *conf) 266ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt{ 267ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt struct tls_context *context = os_zalloc(sizeof(*context)); 268ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt if (context == NULL) 269ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt return NULL; 270ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt if (conf) { 271ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt context->event_cb = conf->event_cb; 272ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt context->cb_ctx = conf->cb_ctx; 273ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt context->cert_in_cb = conf->cert_in_cb; 274ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt } 275ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt return context; 276ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt} 277ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt 278ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_NO_STDOUT_DEBUG 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void _tls_show_errors(void) 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned long err; 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while ((err = ERR_get_error())) { 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Just ignore the errors, since stdout is disabled */ 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define tls_show_errors(l, f, t) _tls_show_errors() 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_NO_STDOUT_DEBUG */ 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void tls_show_errors(int level, const char *func, const char *txt) 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned long err; 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(level, "OpenSSL: %s - %s %s", 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt func, txt, ERR_error_string(ERR_get_error(), NULL)); 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while ((err = ERR_get_error())) { 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "OpenSSL: pending error: %s", 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(err, NULL)); 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_STDOUT_DEBUG */ 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_NATIVE_WINDOWS 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Windows CryptoAPI and access to certificate stores */ 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <wincrypt.h> 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef __MINGW32_VERSION 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * MinGW does not yet include all the needed definitions for CryptoAPI, so 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * define here whatever extra is needed. 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define CERT_SYSTEM_STORE_CURRENT_USER (1 << 16) 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define CERT_STORE_READONLY_FLAG 0x00008000 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define CERT_STORE_OPEN_EXISTING_FLAG 0x00004000 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* __MINGW32_VERSION */ 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct cryptoapi_rsa_data { 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const CERT_CONTEXT *cert; 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HCRYPTPROV crypt_prov; 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD key_spec; 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BOOL free_crypt_prov; 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void cryptoapi_error(const char *msg) 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "CryptoAPI: %s; err=%u", 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg, (unsigned int) GetLastError()); 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int cryptoapi_rsa_pub_enc(int flen, const unsigned char *from, 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char *to, RSA *rsa, int padding) 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s - not implemented", __func__); 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int cryptoapi_rsa_pub_dec(int flen, const unsigned char *from, 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char *to, RSA *rsa, int padding) 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s - not implemented", __func__); 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int cryptoapi_rsa_priv_enc(int flen, const unsigned char *from, 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char *to, RSA *rsa, int padding) 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct cryptoapi_rsa_data *priv = 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (struct cryptoapi_rsa_data *) rsa->meth->app_data; 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HCRYPTHASH hash; 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD hash_size, len, i; 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char *buf = NULL; 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = 0; 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (priv == NULL) { 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_R_PASSED_NULL_PARAMETER); 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (padding != RSA_PKCS1_PADDING) { 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSA_R_UNKNOWN_PADDING_TYPE); 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (flen != 16 /* MD5 */ + 20 /* SHA-1 */) { 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "%s - only MD5-SHA1 hash supported", 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__); 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSA_R_INVALID_MESSAGE_LENGTH); 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptCreateHash(priv->crypt_prov, CALG_SSL3_SHAMD5, 0, 0, &hash)) 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_error("CryptCreateHash failed"); 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = sizeof(hash_size); 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptGetHashParam(hash, HP_HASHSIZE, (BYTE *) &hash_size, &len, 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0)) { 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_error("CryptGetHashParam failed"); 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((int) hash_size != flen) { 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "CryptoAPI: Invalid hash size (%u != %d)", 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned) hash_size, flen); 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSA_R_INVALID_MESSAGE_LENGTH); 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptSetHashParam(hash, HP_HASHVAL, (BYTE * ) from, 0)) { 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_error("CryptSetHashParam failed"); 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = RSA_size(rsa); 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = os_malloc(len); 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) { 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE); 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptSignHash(hash, priv->key_spec, NULL, 0, buf, &len)) { 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_error("CryptSignHash failed"); 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < len; i++) 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt to[i] = buf[len - i - 1]; 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = len; 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidterr: 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CryptDestroyHash(hash); 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int cryptoapi_rsa_priv_dec(int flen, const unsigned char *from, 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char *to, RSA *rsa, int padding) 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s - not implemented", __func__); 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void cryptoapi_free_data(struct cryptoapi_rsa_data *priv) 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (priv == NULL) 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (priv->crypt_prov && priv->free_crypt_prov) 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CryptReleaseContext(priv->crypt_prov, 0); 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (priv->cert) 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CertFreeCertificateContext(priv->cert); 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(priv); 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int cryptoapi_finish(RSA *rsa) 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_free_data((struct cryptoapi_rsa_data *) rsa->meth->app_data); 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free((void *) rsa->meth); 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa->meth = NULL; 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const CERT_CONTEXT * cryptoapi_find_cert(const char *name, DWORD store) 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HCERTSTORE cs; 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const CERT_CONTEXT *ret = NULL; 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cs = CertOpenStore((LPCSTR) CERT_STORE_PROV_SYSTEM, 0, 0, 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt store | CERT_STORE_OPEN_EXISTING_FLAG | 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CERT_STORE_READONLY_FLAG, L"MY"); 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cs == NULL) { 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_error("Failed to open 'My system store'"); 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (strncmp(name, "cert://", 7) == 0) { 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned short wbuf[255]; 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MultiByteToWideChar(CP_ACP, 0, name + 7, -1, wbuf, 255); 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = CertFindCertificateInStore(cs, X509_ASN_ENCODING | 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PKCS_7_ASN_ENCODING, 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0, CERT_FIND_SUBJECT_STR, 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wbuf, NULL); 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (strncmp(name, "hash://", 7) == 0) { 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CRYPT_HASH_BLOB blob; 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len; 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *hash = name + 7; 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char *buf; 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = os_strlen(hash) / 2; 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = os_malloc(len); 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf && hexstr2bin(hash, buf, len) == 0) { 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt blob.cbData = len; 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt blob.pbData = buf; 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = CertFindCertificateInStore(cs, 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_ASN_ENCODING | 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PKCS_7_ASN_ENCODING, 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0, CERT_FIND_HASH, 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &blob, NULL); 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CertCloseStore(cs, 0); 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_cryptoapi_cert(SSL *ssl, const char *name) 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *cert = NULL; 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSA *rsa = NULL, *pub_rsa; 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct cryptoapi_rsa_data *priv; 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSA_METHOD *rsa_meth; 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (name == NULL || 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (strncmp(name, "cert://", 7) != 0 && 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt strncmp(name, "hash://", 7) != 0)) 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priv = os_zalloc(sizeof(*priv)); 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_meth = os_zalloc(sizeof(*rsa_meth)); 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (priv == NULL || rsa_meth == NULL) { 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "CryptoAPI: Failed to allocate memory " 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for CryptoAPI RSA method"); 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(priv); 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(rsa_meth); 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priv->cert = cryptoapi_find_cert(name, CERT_SYSTEM_STORE_CURRENT_USER); 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (priv->cert == NULL) { 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priv->cert = cryptoapi_find_cert( 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name, CERT_SYSTEM_STORE_LOCAL_MACHINE); 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (priv->cert == NULL) { 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "CryptoAPI: Could not find certificate " 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s'", name); 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 544216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt cert = d2i_X509(NULL, 545216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt (const unsigned char **) &priv->cert->pbCertEncoded, 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priv->cert->cbCertEncoded); 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert == NULL) { 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "CryptoAPI: Could not process X509 DER " 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "encoding"); 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptAcquireCertificatePrivateKey(priv->cert, 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CRYPT_ACQUIRE_COMPARE_KEY_FLAG, 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, &priv->crypt_prov, 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &priv->key_spec, 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &priv->free_crypt_prov)) { 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_error("Failed to acquire a private key for the " 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate"); 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_meth->name = "Microsoft CryptoAPI RSA Method"; 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_meth->rsa_pub_enc = cryptoapi_rsa_pub_enc; 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_meth->rsa_pub_dec = cryptoapi_rsa_pub_dec; 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_meth->rsa_priv_enc = cryptoapi_rsa_priv_enc; 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_meth->rsa_priv_dec = cryptoapi_rsa_priv_dec; 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_meth->finish = cryptoapi_finish; 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_meth->flags = RSA_METHOD_FLAG_NO_CHECK; 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_meth->app_data = (char *) priv; 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa = RSA_new(); 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rsa == NULL) { 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_R_MALLOC_FAILURE); 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!SSL_use_certificate(ssl, cert)) { 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSA_free(rsa); 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa = NULL; 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pub_rsa = cert->cert_info->key->pkey->pkey.rsa; 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert = NULL; 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa->n = BN_dup(pub_rsa->n); 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa->e = BN_dup(pub_rsa->e); 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!RSA_set_method(rsa, rsa_meth)) 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!SSL_use_RSAPrivateKey(ssl, rsa)) 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSA_free(rsa); 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidterr: 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert) 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rsa) 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSA_free(rsa); 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(rsa_meth); 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_free_data(priv); 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_cryptoapi_ca_cert(SSL_CTX *ssl_ctx, SSL *ssl, const char *name) 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HCERTSTORE cs; 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PCCERT_CONTEXT ctx = NULL; 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *cert; 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char buf[128]; 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *store; 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef UNICODE 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WCHAR *wstore; 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* UNICODE */ 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (name == NULL || strncmp(name, "cert_store://", 13) != 0) 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt store = name + 13; 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef UNICODE 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wstore = os_malloc((os_strlen(store) + 1) * sizeof(WCHAR)); 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wstore == NULL) 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wsprintf(wstore, L"%S", store); 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cs = CertOpenSystemStore(0, wstore); 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(wstore); 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* UNICODE */ 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cs = CertOpenSystemStore(0, store); 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* UNICODE */ 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cs == NULL) { 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: failed to open system cert store " 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s': error=%d", __func__, store, 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) GetLastError()); 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while ((ctx = CertEnumCertificatesInStore(cs, ctx))) { 645216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt cert = d2i_X509(NULL, 646216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt (const unsigned char **) &ctx->pbCertEncoded, 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->cbCertEncoded); 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert == NULL) { 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "CryptoAPI: Could not process " 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "X509 DER encoding for CA cert"); 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_NAME_oneline(X509_get_subject_name(cert), buf, 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(buf)); 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Loaded CA certificate for " 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "system certificate store: subject='%s'", buf); 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 659849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt if (!X509_STORE_add_cert(SSL_CTX_get_cert_store(ssl_ctx), 660849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt cert)) { 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_WARNING, __func__, 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to add ca_cert to OpenSSL " 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate store"); 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CertCloseStore(cs, 0)) { 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: failed to close system cert store " 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s': error=%d", __func__, name + 13, 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) GetLastError()); 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_NATIVE_WINDOWS */ 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_cryptoapi_cert(SSL *ssl, const char *name) 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void ssl_info_cb(const SSL *ssl, int where, int ret) 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *str; 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int w; 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: (where=0x%x ret=0x%x)", where, ret); 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt w = where & ~SSL_ST_MASK; 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (w & SSL_ST_CONNECT) 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt str = "SSL_connect"; 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (w & SSL_ST_ACCEPT) 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt str = "SSL_accept"; 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt str = "undefined"; 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (where & SSL_CB_LOOP) { 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: %s:%s", 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt str, SSL_state_string_long(ssl)); 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (where & SSL_CB_ALERT) { 707ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt struct tls_connection *conn = SSL_get_app_data((SSL *) ssl); 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "SSL: SSL3 alert: %s:%s:%s", 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt where & SSL_CB_READ ? 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "read (remote end reported an error)" : 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "write (local SSL3 detected an error)", 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_alert_type_string_long(ret), 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_alert_desc_string_long(ret)); 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((ret >> 8) == SSL3_AL_FATAL) { 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (where & SSL_CB_READ) 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->read_alerts++; 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->write_alerts++; 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 720ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt if (conn->context->event_cb != NULL) { 72104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt union tls_event_data ev; 722ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt struct tls_context *context = conn->context; 72304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memset(&ev, 0, sizeof(ev)); 72404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ev.alert.is_local = !(where & SSL_CB_READ); 72504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ev.alert.type = SSL_alert_type_string_long(ret); 72604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ev.alert.description = SSL_alert_desc_string_long(ret); 727ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt context->event_cb(context->cb_ctx, TLS_ALERT, &ev); 72804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (where & SSL_CB_EXIT && ret <= 0) { 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: %s:%s in %s", 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt str, ret == 0 ? "failed" : "error", 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_state_string_long(ssl)); 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_ENGINE 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tls_engine_load_dynamic_generic - load any openssl engine 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @pre: an array of commands and values that load an engine initialized 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * in the engine specific function 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @post: an array of commands and values that initialize an already loaded 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * engine (or %NULL if not required) 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @id: the engine id of the engine to load (only required if post is not %NULL 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is a generic function that loads any openssl engine. 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_engine_load_dynamic_generic(const char *pre[], 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *post[], const char *id) 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE *engine; 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *dynamic_id = "dynamic"; 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt engine = ENGINE_by_id(id); 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (engine) { 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: engine '%s' is already " 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "available", id); 760d5ab1b53af720d05586ccc0addabe93459f1f388Dmitry Shmidt /* 761d5ab1b53af720d05586ccc0addabe93459f1f388Dmitry Shmidt * If it was auto-loaded by ENGINE_by_id() we might still 762d5ab1b53af720d05586ccc0addabe93459f1f388Dmitry Shmidt * need to tell it which PKCS#11 module to use in legacy 763d5ab1b53af720d05586ccc0addabe93459f1f388Dmitry Shmidt * (non-p11-kit) environments. Do so now; even if it was 764d5ab1b53af720d05586ccc0addabe93459f1f388Dmitry Shmidt * properly initialised before, setting it again will be 765d5ab1b53af720d05586ccc0addabe93459f1f388Dmitry Shmidt * harmless. 766d5ab1b53af720d05586ccc0addabe93459f1f388Dmitry Shmidt */ 767d5ab1b53af720d05586ccc0addabe93459f1f388Dmitry Shmidt goto found; 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_clear_error(); 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt engine = ENGINE_by_id(dynamic_id); 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (engine == NULL) { 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "ENGINE: Can't find engine %s [%s]", 7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dynamic_id, 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Perform the pre commands. This will load the engine. */ 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pre && pre[0]) { 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: '%s' '%s'", pre[0], pre[1]); 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ENGINE_ctrl_cmd_string(engine, pre[0], pre[1], 0) == 0) { 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "ENGINE: ctrl cmd_string failed: " 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%s %s [%s]", pre[0], pre[1], 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE_free(engine); 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pre += 2; 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Free the reference to the "dynamic" engine. The loaded engine can 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * now be looked up using ENGINE_by_id(). 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE_free(engine); 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt engine = ENGINE_by_id(id); 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (engine == NULL) { 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "ENGINE: Can't find engine %s [%s]", 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt id, ERR_error_string(ERR_get_error(), NULL)); 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 804d5ab1b53af720d05586ccc0addabe93459f1f388Dmitry Shmidt found: 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (post && post[0]) { 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: '%s' '%s'", post[0], post[1]); 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ENGINE_ctrl_cmd_string(engine, post[0], post[1], 0) == 0) { 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: ctrl cmd_string failed:" 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " %s %s [%s]", post[0], post[1], 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE_remove(engine); 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE_free(engine); 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt post += 2; 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE_free(engine); 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tls_engine_load_dynamic_pkcs11 - load the pkcs11 engine provided by opensc 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @pkcs11_so_path: pksc11_so_path from the configuration 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @pcks11_module_path: pkcs11_module_path from the configuration 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_engine_load_dynamic_pkcs11(const char *pkcs11_so_path, 8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *pkcs11_module_path) 8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *engine_id = "pkcs11"; 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *pre_cmd[] = { 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SO_PATH", NULL /* pkcs11_so_path */, 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ID", NULL /* engine_id */, 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "LIST_ADD", "1", 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* "NO_VCHECK", "1", */ 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "LOAD", NULL, 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, NULL 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt }; 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *post_cmd[] = { 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "MODULE_PATH", NULL /* pkcs11_module_path */, 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, NULL 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt }; 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8456c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!pkcs11_so_path) 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pre_cmd[1] = pkcs11_so_path; 8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pre_cmd[3] = engine_id; 8506c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (pkcs11_module_path) 8516c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt post_cmd[1] = pkcs11_module_path; 8526c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt else 8536c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt post_cmd[0] = NULL; 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: Loading pkcs11 Engine from %s", 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pkcs11_so_path); 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_engine_load_dynamic_generic(pre_cmd, post_cmd, engine_id); 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tls_engine_load_dynamic_opensc - load the opensc engine provided by opensc 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @opensc_so_path: opensc_so_path from the configuration 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_engine_load_dynamic_opensc(const char *opensc_so_path) 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *engine_id = "opensc"; 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *pre_cmd[] = { 8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SO_PATH", NULL /* opensc_so_path */, 8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ID", NULL /* engine_id */, 8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "LIST_ADD", "1", 8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "LOAD", NULL, 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, NULL 8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt }; 8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!opensc_so_path) 8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pre_cmd[1] = opensc_so_path; 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pre_cmd[3] = engine_id; 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: Loading OpenSC Engine from %s", 8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt opensc_so_path); 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_engine_load_dynamic_generic(pre_cmd, NULL, engine_id); 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 891d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic void remove_session_cb(SSL_CTX *ctx, SSL_SESSION *sess) 892d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 893d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct wpabuf *buf; 894d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 895d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (tls_ex_idx_session < 0) 896d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return; 897d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt buf = SSL_SESSION_get_ex_data(sess, tls_ex_idx_session); 898d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!buf) 899d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return; 900d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_DEBUG, 901d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "OpenSSL: Free application session data %p (sess %p)", 902d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt buf, sess); 903d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpabuf_free(buf); 904d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 905d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_SESSION_set_ex_data(sess, tls_ex_idx_session, NULL); 906d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 907d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 908d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid * tls_init(const struct tls_config *conf) 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 911d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct tls_data *data; 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX *ssl; 913ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt struct tls_context *context; 9146c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt const char *ciphers; 9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_openssl_ref_count == 0) { 917ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt tls_global = context = tls_context_new(conf); 918ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt if (context == NULL) 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_FIPS 9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef OPENSSL_FIPS 9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf && conf->fips_mode) { 923d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt static int fips_enabled = 0; 924d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 925d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!fips_enabled && !FIPS_mode_set(1)) { 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to enable FIPS " 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "mode"); 9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_load_crypto_strings(); 9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_print_errors_fp(stderr); 93061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(tls_global); 93161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt tls_global = NULL; 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 933d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } else { 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "Running in FIPS mode"); 935d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fips_enabled = 1; 936d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_FIPS */ 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf && conf->fips_mode) { 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "FIPS mode requested, but not " 9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "supported"); 94261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(tls_global); 94361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt tls_global = NULL; 9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_FIPS */ 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_FIPS */ 9489839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_load_error_strings(); 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_library_init(); 951216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt#ifndef OPENSSL_NO_SHA256 9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EVP_add_digest(EVP_sha256()); 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_SHA256 */ 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: if /dev/urandom is available, PRNG is seeded 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * automatically. If this is not the case, random data should 9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * be added here. */ 9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef PKCS12_FUNCS 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_RC2 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 40-bit RC2 is commonly used in PKCS#12 files, so enable it. 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This is enabled by PKCS12_PBE_add() in OpenSSL 0.9.8 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * versions, but it looks like OpenSSL 1.0.0 does not do that 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * anymore. 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EVP_add_cipher(EVP_rc2_40_cbc()); 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_RC2 */ 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PKCS12_PBE_add(); 9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* PKCS12_FUNCS */ 97057c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt#endif /* < 1.1.0 */ 971ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt } else { 972ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt context = tls_context_new(conf); 973ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt if (context == NULL) 974ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt return NULL; 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_openssl_ref_count++; 9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 978d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt data = os_zalloc(sizeof(*data)); 979d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (data) 980d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ssl = SSL_CTX_new(SSLv23_method()); 981d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt else 982d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ssl = NULL; 983ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt if (ssl == NULL) { 984ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt tls_openssl_ref_count--; 98568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (context != tls_global) 98668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt os_free(context); 987ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt if (tls_openssl_ref_count == 0) { 988ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt os_free(tls_global); 989ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt tls_global = NULL; 990ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt } 99157c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt os_free(data); 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 993ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt } 994d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt data->ssl = ssl; 995d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (conf) 996d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt data->tls_session_lifetime = conf->tls_session_lifetime; 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9986c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt SSL_CTX_set_options(ssl, SSL_OP_NO_SSLv2); 9996c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt SSL_CTX_set_options(ssl, SSL_OP_NO_SSLv3); 10006c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1001293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt#ifdef SSL_MODE_NO_AUTO_CHAIN 1002293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt /* Number of deployed use cases assume the default OpenSSL behavior of 1003293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt * auto chaining the local certificate is in use. BoringSSL removed this 1004293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt * functionality by default, so we need to restore it here to avoid 1005293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt * breaking existing use cases. */ 1006293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt SSL_CTX_clear_mode(ssl, SSL_MODE_NO_AUTO_CHAIN); 1007293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt#endif /* SSL_MODE_NO_AUTO_CHAIN */ 1008293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_set_info_callback(ssl, ssl_info_cb); 1010ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt SSL_CTX_set_app_data(ssl, context); 1011d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (data->tls_session_lifetime > 0) { 1012d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX_set_quiet_shutdown(ssl, 1); 1013d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt /* 1014d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * Set default context here. In practice, this will be replaced 1015d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * by the per-EAP method context in tls_connection_set_verify(). 1016d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt */ 1017d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX_set_session_id_context(ssl, (u8 *) "hostapd", 7); 1018d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX_set_session_cache_mode(ssl, SSL_SESS_CACHE_SERVER); 1019d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX_set_timeout(ssl, data->tls_session_lifetime); 1020d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX_sess_set_remove_cb(ssl, remove_session_cb); 1021d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } else { 1022d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX_set_session_cache_mode(ssl, SSL_SESS_CACHE_OFF); 1023d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 1024d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1025d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (tls_ex_idx_session < 0) { 1026d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt tls_ex_idx_session = SSL_SESSION_get_ex_new_index( 1027d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 0, NULL, NULL, NULL, NULL); 1028d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (tls_ex_idx_session < 0) { 1029d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt tls_deinit(data); 1030d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return NULL; 1031d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 1032d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_ENGINE 10356c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: Loading dynamic engine"); 10366c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ERR_load_ENGINE_strings(); 10376c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ENGINE_load_dynamic(); 10386c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf && 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (conf->opensc_engine_path || conf->pkcs11_engine_path || 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->pkcs11_module_path)) { 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_engine_load_dynamic_opensc(conf->opensc_engine_path) || 10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_engine_load_dynamic_pkcs11(conf->pkcs11_engine_path, 10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->pkcs11_module_path)) { 1045d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt tls_deinit(data); 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10516c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (conf && conf->openssl_ciphers) 10526c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ciphers = conf->openssl_ciphers; 10536c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt else 1054d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt ciphers = TLS_DEFAULT_CIPHERS; 10556c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (SSL_CTX_set_cipher_list(ssl, ciphers) != 1) { 10566c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_ERROR, 10576c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "OpenSSL: Failed to set cipher string '%s'", 10586c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ciphers); 1059d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt tls_deinit(data); 10606c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return NULL; 10616c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 10626c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1063d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return data; 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid tls_deinit(void *ssl_ctx) 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1069d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct tls_data *data = ssl_ctx; 1070d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX *ssl = data->ssl; 1071ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt struct tls_context *context = SSL_CTX_get_app_data(ssl); 1072ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt if (context != tls_global) 1073ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt os_free(context); 1074d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (data->tls_session_lifetime > 0) 1075d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX_flush_sessions(ssl, 0); 10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_free(ssl); 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_openssl_ref_count--; 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_openssl_ref_count == 0) { 10809839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) 10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_ENGINE 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE_cleanup(); 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CRYPTO_cleanup_all_ex_data(); 10859ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt ERR_remove_thread_state(NULL); 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_free_strings(); 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EVP_cleanup(); 108857c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt#endif /* < 1.1.0 */ 108934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt os_free(tls_global->ocsp_stapling_response); 109034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt tls_global->ocsp_stapling_response = NULL; 10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(tls_global); 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_global = NULL; 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1094d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1095d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt os_free(data); 10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10991d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt#ifndef OPENSSL_NO_ENGINE 11001d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt 11011d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt/* Cryptoki return values */ 11021d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt#define CKR_PIN_INCORRECT 0x000000a0 11031d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt#define CKR_PIN_INVALID 0x000000a1 11041d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt#define CKR_PIN_LEN_RANGE 0x000000a2 11051d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt 11061d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt/* libp11 */ 11071d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt#define ERR_LIB_PKCS11 ERR_LIB_USER 11081d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt 11091d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidtstatic int tls_is_pin_error(unsigned int err) 11101d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt{ 11111d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt return ERR_GET_LIB(err) == ERR_LIB_PKCS11 && 11121d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt (ERR_GET_REASON(err) == CKR_PIN_INCORRECT || 11131d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt ERR_GET_REASON(err) == CKR_PIN_INVALID || 11141d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt ERR_GET_REASON(err) == CKR_PIN_LEN_RANGE); 11151d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt} 11161d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt 11171d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 11181d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt 11191d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt 1120d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#ifdef ANDROID 1121d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt/* EVP_PKEY_from_keystore comes from system/security/keystore-engine. */ 1122d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry ShmidtEVP_PKEY * EVP_PKEY_from_keystore(const char *key_id); 1123d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* ANDROID */ 1124d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_engine_init(struct tls_connection *conn, const char *engine_id, 11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *pin, const char *key_id, 11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *cert_id, const char *ca_cert_id) 11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11291eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley#if defined(ANDROID) && defined(OPENSSL_IS_BORINGSSL) 11301eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley#if !defined(OPENSSL_NO_ENGINE) 11311eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley#error "This code depends on OPENSSL_NO_ENGINE being defined by BoringSSL." 11321eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley#endif 1133d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!key_id) 1134d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED; 11351eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley conn->engine = NULL; 11361eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley conn->private_key = EVP_PKEY_from_keystore(key_id); 11371eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley if (!conn->private_key) { 11381eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley wpa_printf(MSG_ERROR, 11391eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley "ENGINE: cannot load private key with id '%s' [%s]", 11401eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley key_id, 11411eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley ERR_error_string(ERR_get_error(), NULL)); 11421eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley return TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED; 11431eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley } 1144d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* ANDROID && OPENSSL_IS_BORINGSSL */ 11451eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley 11468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_ENGINE 11478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = -1; 11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (engine_id == NULL) { 11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "ENGINE: Engine ID not set"); 11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_clear_error(); 1154db3c5a43353099fd4771f3b7a13efae905878ce9Kenny Root#ifdef ANDROID 1155db3c5a43353099fd4771f3b7a13efae905878ce9Kenny Root ENGINE_load_dynamic(); 1156db3c5a43353099fd4771f3b7a13efae905878ce9Kenny Root#endif 11578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->engine = ENGINE_by_id(engine_id); 11588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!conn->engine) { 11598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "ENGINE: engine %s not available [%s]", 11608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt engine_id, ERR_error_string(ERR_get_error(), NULL)); 11618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 11628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ENGINE_init(conn->engine) != 1) { 11648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "ENGINE: engine init failed " 11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(engine: %s) [%s]", engine_id, 11668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: engine initialized"); 11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1171db3c5a43353099fd4771f3b7a13efae905878ce9Kenny Root#ifndef ANDROID 11726c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (pin && ENGINE_ctrl_cmd_string(conn->engine, "PIN", pin, 0) == 0) { 11738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "ENGINE: cannot set pin [%s]", 11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 11758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 11768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1177db3c5a43353099fd4771f3b7a13efae905878ce9Kenny Root#endif 11786c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (key_id) { 11796c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* 11806c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * Ensure that the ENGINE does not attempt to use the OpenSSL 11816c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * UI system to obtain a PIN, if we didn't provide one. 11826c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt */ 11836c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct { 11846c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt const void *password; 11856c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt const char *prompt_info; 11866c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } key_cb = { "", NULL }; 11876c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 11886c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* load private key first in-case PIN is required for cert */ 11896c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt conn->private_key = ENGINE_load_private_key(conn->engine, 11906c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt key_id, NULL, 11916c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt &key_cb); 11926c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!conn->private_key) { 11931d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt unsigned long err = ERR_get_error(); 11941d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt 11956c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_ERROR, 11966c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "ENGINE: cannot load private key with id '%s' [%s]", 11976c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt key_id, 11981d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt ERR_error_string(err, NULL)); 11991d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt if (tls_is_pin_error(err)) 12001d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt ret = TLS_SET_PARAMS_ENGINE_PRV_BAD_PIN; 12011d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt else 12021d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt ret = TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED; 12036c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt goto err; 12046c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 12058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* handle a certificate and/or CA certificate */ 12088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert_id || ca_cert_id) { 12098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *cmd_name = "LOAD_CERT_CTRL"; 12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* test if the engine supports a LOAD_CERT_CTRL */ 12128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ENGINE_ctrl(conn->engine, ENGINE_CTRL_GET_CMD_FROM_NAME, 12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0, (void *)cmd_name, NULL)) { 12148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "ENGINE: engine does not support" 12158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " loading certificates"); 12168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED; 12178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 12188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 12228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidterr: 12248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->engine) { 12258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE_free(conn->engine); 12268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->engine = NULL; 12278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->private_key) { 12308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EVP_PKEY_free(conn->private_key); 12318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->private_key = NULL; 12328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 12358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_ENGINE */ 12368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 12378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 12388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void tls_engine_deinit(struct tls_connection *conn) 12428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12431eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley#if defined(ANDROID) || !defined(OPENSSL_NO_ENGINE) 12448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: engine deinit"); 12458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->private_key) { 12468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EVP_PKEY_free(conn->private_key); 12478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->private_key = NULL; 12488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->engine) { 12501eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley#if !defined(OPENSSL_IS_BORINGSSL) 12518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE_finish(conn->engine); 1252d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* !OPENSSL_IS_BORINGSSL */ 12538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->engine = NULL; 12548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1255d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* ANDROID || !OPENSSL_NO_ENGINE */ 12568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_get_errors(void *ssl_ctx) 12608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int count = 0; 12628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned long err; 12638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while ((err = ERR_get_error())) { 12658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS - SSL error: %s", 12668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(err, NULL)); 12678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count++; 12688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return count; 12718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 127326af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen 1274d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic const char * openssl_content_type(int content_type) 1275d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 1276d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt switch (content_type) { 1277d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 20: 1278d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "change cipher spec"; 1279d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 21: 1280d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "alert"; 1281d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 22: 1282d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "handshake"; 1283d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 23: 1284d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "application data"; 1285d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 24: 1286d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "heartbeat"; 1287d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 256: 1288d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "TLS header info"; /* pseudo content type */ 1289d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt default: 1290d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "?"; 1291d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 1292d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 1293d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1294d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1295d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic const char * openssl_handshake_type(int content_type, const u8 *buf, 1296d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt size_t len) 1297d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 1298d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (content_type != 22 || !buf || len == 0) 1299d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return ""; 1300d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt switch (buf[0]) { 1301d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 0: 1302d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "hello request"; 1303d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 1: 1304d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "client hello"; 1305d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 2: 1306d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "server hello"; 1307d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 4: 1308d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "new session ticket"; 1309d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 11: 1310d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "certificate"; 1311d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 12: 1312d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "server key exchange"; 1313d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 13: 1314d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "certificate request"; 1315d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 14: 1316d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "server hello done"; 1317d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 15: 1318d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "certificate verify"; 1319d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 16: 1320d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "client key exchange"; 1321d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 20: 1322d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "finished"; 1323d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 21: 1324d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "certificate url"; 1325d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 22: 1326d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "certificate status"; 1327d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt default: 1328d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return "?"; 1329d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 1330d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 1331d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1332d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1333d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt#ifdef CONFIG_SUITEB 1334d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 1335d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidtstatic void check_server_hello(struct tls_connection *conn, 1336d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt const u8 *pos, const u8 *end) 1337d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt{ 1338d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt size_t payload_len, id_len; 1339d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 1340d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt /* 1341d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt * Parse ServerHello to get the selected cipher suite since OpenSSL does 1342d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt * not make it cleanly available during handshake and we need to know 1343d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt * whether DHE was selected. 1344d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt */ 1345d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 1346d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (end - pos < 3) 1347d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt return; 1348d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt payload_len = WPA_GET_BE24(pos); 1349d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt pos += 3; 1350d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 1351d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if ((size_t) (end - pos) < payload_len) 1352d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt return; 1353d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt end = pos + payload_len; 1354d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 1355d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt /* Skip Version and Random */ 1356d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (end - pos < 2 + SSL3_RANDOM_SIZE) 1357d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt return; 1358d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt pos += 2 + SSL3_RANDOM_SIZE; 1359d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 1360d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt /* Skip Session ID */ 1361d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (end - pos < 1) 1362d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt return; 1363d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt id_len = *pos++; 1364d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if ((size_t) (end - pos) < id_len) 1365d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt return; 1366d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt pos += id_len; 1367d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 1368d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (end - pos < 2) 1369d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt return; 1370d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt conn->cipher_suite = WPA_GET_BE16(pos); 1371d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Server selected cipher suite 0x%x", 1372d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt conn->cipher_suite); 1373d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt} 1374d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 1375d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 1376d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidtstatic void check_server_key_exchange(SSL *ssl, struct tls_connection *conn, 1377d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt const u8 *pos, const u8 *end) 1378d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt{ 1379d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt size_t payload_len; 1380d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt u16 dh_len; 1381d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt BIGNUM *p; 1382d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt int bits; 1383d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 1384d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (!(conn->flags & TLS_CONN_SUITEB)) 1385d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt return; 1386d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 1387d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt /* DHE is enabled only with DHE-RSA-AES256-GCM-SHA384 */ 1388d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (conn->cipher_suite != 0x9f) 1389d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt return; 1390d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 1391d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (end - pos < 3) 1392d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt return; 1393d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt payload_len = WPA_GET_BE24(pos); 1394d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt pos += 3; 1395d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 1396d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if ((size_t) (end - pos) < payload_len) 1397d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt return; 1398d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt end = pos + payload_len; 1399d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 1400d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (end - pos < 2) 1401d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt return; 1402d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt dh_len = WPA_GET_BE16(pos); 1403d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt pos += 2; 1404d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 1405d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if ((size_t) (end - pos) < dh_len) 1406d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt return; 1407d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt p = BN_bin2bn(pos, dh_len, NULL); 1408d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (!p) 1409d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt return; 1410d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 1411d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt bits = BN_num_bits(p); 1412d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt BN_free(p); 1413d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 1414d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt conn->server_dh_prime_len = bits; 1415d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Server DH prime length: %d bits", 1416d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt conn->server_dh_prime_len); 1417d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt} 1418d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 1419d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt#endif /* CONFIG_SUITEB */ 1420d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 1421d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 142226af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinenstatic void tls_msg_cb(int write_p, int version, int content_type, 142326af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen const void *buf, size_t len, SSL *ssl, void *arg) 142426af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen{ 142526af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen struct tls_connection *conn = arg; 142626af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen const u8 *pos = buf; 142726af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen 1428d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (write_p == 2) { 1429d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_DEBUG, 1430d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "OpenSSL: session ver=0x%x content_type=%d", 1431d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt version, content_type); 1432d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_hexdump_key(MSG_MSGDUMP, "OpenSSL: Data", buf, len); 1433d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return; 1434d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 1435d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1436d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s ver=0x%x content_type=%d (%s/%s)", 1437d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt write_p ? "TX" : "RX", version, content_type, 1438d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt openssl_content_type(content_type), 1439d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt openssl_handshake_type(content_type, buf, len)); 144026af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen wpa_hexdump_key(MSG_MSGDUMP, "OpenSSL: Message", buf, len); 144126af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen if (content_type == 24 && len >= 3 && pos[0] == 1) { 144226af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen size_t payload_len = WPA_GET_BE16(pos + 1); 144326af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen if (payload_len + 3 > len) { 144426af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen wpa_printf(MSG_ERROR, "OpenSSL: Heartbeat attack detected"); 144526af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen conn->invalid_hb_used = 1; 144626af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen } 144726af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen } 1448d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 1449d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt#ifdef CONFIG_SUITEB 1450d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt /* 1451d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt * Need to parse these handshake messages to be able to check DH prime 1452d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt * length since OpenSSL does not expose the new cipher suite and DH 1453d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt * parameters during handshake (e.g., for cert_cb() callback). 1454d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt */ 1455d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (content_type == 22 && pos && len > 0 && pos[0] == 2) 1456d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt check_server_hello(conn, pos + 1, pos + len); 1457d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (content_type == 22 && pos && len > 0 && pos[0] == 12) 1458d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt check_server_key_exchange(ssl, conn, pos + 1, pos + len); 1459d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt#endif /* CONFIG_SUITEB */ 146026af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen} 146126af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen 146226af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen 14638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct tls_connection * tls_connection_init(void *ssl_ctx) 14648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1465d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct tls_data *data = ssl_ctx; 1466d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX *ssl = data->ssl; 14678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn; 14688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt long options; 14697d5c8f257a74ac0d12828962a492e8b84ef83923Dmitry Shmidt struct tls_context *context = SSL_CTX_get_app_data(ssl); 14708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn = os_zalloc(sizeof(*conn)); 14728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 14738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1474d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt conn->ssl_ctx = ssl; 14758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ssl = SSL_new(ssl); 14768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->ssl == NULL) { 14778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 14788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to initialize new SSL connection"); 14798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn); 14808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 14818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1483ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt conn->context = context; 14848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_app_data(conn->ssl, conn); 148526af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen SSL_set_msg_callback(conn->ssl, tls_msg_cb); 148626af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen SSL_set_msg_callback_arg(conn->ssl, conn); 14878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | 14888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_OP_SINGLE_DH_USE; 14898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef SSL_OP_NO_COMPRESSION 14908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt options |= SSL_OP_NO_COMPRESSION; 14918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* SSL_OP_NO_COMPRESSION */ 14928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_options(conn->ssl, options); 14938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ssl_in = BIO_new(BIO_s_mem()); 14958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!conn->ssl_in) { 14968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 14978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to create a new BIO for ssl_in"); 14988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_free(conn->ssl); 14998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn); 15008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 15018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ssl_out = BIO_new(BIO_s_mem()); 15048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!conn->ssl_out) { 15058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 15068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to create a new BIO for ssl_out"); 15078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_free(conn->ssl); 15088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO_free(conn->ssl_in); 15098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn); 15108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 15118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_bio(conn->ssl, conn->ssl_in, conn->ssl_out); 15148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return conn; 15168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid tls_connection_deinit(void *ssl_ctx, struct tls_connection *conn) 15208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 15228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1523d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (conn->success_data) { 1524d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt /* 1525d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * Make sure ssl_clear_bad_session() does not remove this 1526d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * session. 1527d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt */ 1528d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_set_quiet_shutdown(conn->ssl, 1); 1529d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_shutdown(conn->ssl); 1530d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 15318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_free(conn->ssl); 15328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_engine_deinit(conn); 15338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->subject_match); 15348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->altsubject_match); 1535051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt os_free(conn->suffix_match); 15362f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt os_free(conn->domain_match); 15378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->session_ticket); 15388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn); 15398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_established(void *ssl_ctx, struct tls_connection *conn) 15438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return conn ? SSL_is_init_finished(conn->ssl) : 0; 15458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_shutdown(void *ssl_ctx, struct tls_connection *conn) 15498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 15518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 15528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Shutdown previous TLS connection without notifying the peer 15548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * because the connection was already terminated in practice 15558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * and "close notify" shutdown alert would confuse AS. */ 15568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_quiet_shutdown(conn->ssl, 1); 15578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_shutdown(conn->ssl); 1558f291c682d490cef0b520b68e694a2bf97126b441Jouni Malinen return SSL_clear(conn->ssl) == 1 ? 0 : -1; 15598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_match_altsubject_component(X509 *cert, int type, 15638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *value, size_t len) 15648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt GENERAL_NAME *gen; 15668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *ext; 15679ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt int found = 0; 15689ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt stack_index_t i; 15698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ext = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL); 15718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; ext && i < sk_GENERAL_NAME_num(ext); i++) { 15738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gen = sk_GENERAL_NAME_value(ext, i); 15748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (gen->type != type) 15758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 15768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strlen((char *) gen->d.ia5->data) == len && 15778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(value, gen->d.ia5->data, len) == 0) 15788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt found++; 15798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 158157c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt sk_GENERAL_NAME_pop_free(ext, GENERAL_NAME_free); 158257c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt 15838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return found; 15848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_match_altsubject(X509 *cert, const char *match) 15888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int type; 15908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *pos, *end; 15918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len; 15928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = match; 15948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt do { 15958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strncmp(pos, "EMAIL:", 6) == 0) { 15968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = GEN_EMAIL; 15978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 6; 15988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (os_strncmp(pos, "DNS:", 4) == 0) { 15998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = GEN_DNS; 16008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 4; 16018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (os_strncmp(pos, "URI:", 4) == 0) { 16028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = GEN_URI; 16038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 4; 16048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 16058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Invalid altSubjectName " 16068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "match '%s'", pos); 16078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 16088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = os_strchr(pos, ';'); 16108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (end) { 16118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strncmp(end + 1, "EMAIL:", 6) == 0 || 16128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strncmp(end + 1, "DNS:", 4) == 0 || 16138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strncmp(end + 1, "URI:", 4) == 0) 16148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = os_strchr(end + 1, ';'); 16168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end) 16188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = end - pos; 16198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 16208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = os_strlen(pos); 16218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_match_altsubject_component(cert, type, pos, len) > 0) 16228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 16238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = end + 1; 16248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } while (end); 16258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 16278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1630fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt#ifndef CONFIG_NATIVE_WINDOWS 16312f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidtstatic int domain_suffix_match(const u8 *val, size_t len, const char *match, 16322f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt int full) 1633051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt{ 1634051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt size_t i, match_len; 1635051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1636051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt /* Check for embedded nuls that could mess up suffix matching */ 1637051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt for (i = 0; i < len; i++) { 1638051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (val[i] == '\0') { 1639051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Embedded null in a string - reject"); 1640051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return 0; 1641051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } 1642051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } 1643051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1644051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt match_len = os_strlen(match); 16452f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (match_len > len || (full && match_len != len)) 1646051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return 0; 1647051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1648051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (os_strncasecmp((const char *) val + len - match_len, match, 1649051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt match_len) != 0) 1650051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return 0; /* no match */ 1651051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1652051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (match_len == len) 1653051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return 1; /* exact match */ 1654051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1655051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (val[len - match_len - 1] == '.') 1656051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return 1; /* full label match completes suffix match */ 1657051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1658051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Reject due to incomplete label match"); 1659051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return 0; 1660051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt} 1661fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 1662051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1663051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 16642f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidtstatic int tls_match_suffix(X509 *cert, const char *match, int full) 1665051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt{ 1666fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt#ifdef CONFIG_NATIVE_WINDOWS 1667fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt /* wincrypt.h has conflicting X509_NAME definition */ 1668fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt return -1; 1669fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt#else /* CONFIG_NATIVE_WINDOWS */ 1670051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt GENERAL_NAME *gen; 1671051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt void *ext; 1672051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt int i; 16739ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt stack_index_t j; 1674051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt int dns_name = 0; 1675051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt X509_NAME *name; 1676051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 16772f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Match domain against %s%s", 16782f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt full ? "": "suffix ", match); 1679051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1680051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt ext = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL); 1681051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 16829ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt for (j = 0; ext && j < sk_GENERAL_NAME_num(ext); j++) { 16839ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt gen = sk_GENERAL_NAME_value(ext, j); 1684051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (gen->type != GEN_DNS) 1685051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt continue; 1686051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt dns_name++; 1687051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "TLS: Certificate dNSName", 1688051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt gen->d.dNSName->data, 1689051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt gen->d.dNSName->length); 1690051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (domain_suffix_match(gen->d.dNSName->data, 16912f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt gen->d.dNSName->length, match, full) == 16922f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 1) { 16932f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: %s in dNSName found", 16942f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt full ? "Match" : "Suffix match"); 169557c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt sk_GENERAL_NAME_pop_free(ext, GENERAL_NAME_free); 1696051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return 1; 1697051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } 1698051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } 169957c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt sk_GENERAL_NAME_pop_free(ext, GENERAL_NAME_free); 1700051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1701051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (dns_name) { 1702051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: None of the dNSName(s) matched"); 1703051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return 0; 1704051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } 1705051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1706051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt name = X509_get_subject_name(cert); 1707051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt i = -1; 1708051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt for (;;) { 1709051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt X509_NAME_ENTRY *e; 1710051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt ASN1_STRING *cn; 1711051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1712051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt i = X509_NAME_get_index_by_NID(name, NID_commonName, i); 1713051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (i == -1) 1714051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt break; 1715051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt e = X509_NAME_get_entry(name, i); 1716051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (e == NULL) 1717051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt continue; 1718051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt cn = X509_NAME_ENTRY_get_data(e); 1719051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (cn == NULL) 1720051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt continue; 1721051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "TLS: Certificate commonName", 1722051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt cn->data, cn->length); 17232f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (domain_suffix_match(cn->data, cn->length, match, full) == 1) 17242f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt { 17252f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: %s in commonName found", 17262f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt full ? "Match" : "Suffix match"); 1727051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return 1; 1728051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } 1729051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } 1730051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 17312f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: No CommonName %smatch found", 17322f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt full ? "": "suffix "); 1733051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return 0; 1734fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 1735051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt} 1736051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1737051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 17388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic enum tls_fail_reason openssl_tls_fail_reason(int err) 17398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (err) { 17418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_CERT_REVOKED: 17428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_FAIL_REVOKED; 17438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_CERT_NOT_YET_VALID: 17448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_CRL_NOT_YET_VALID: 17458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_FAIL_NOT_YET_VALID; 17468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_CERT_HAS_EXPIRED: 17478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_CRL_HAS_EXPIRED: 17488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_FAIL_EXPIRED; 17498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: 17508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_UNABLE_TO_GET_CRL: 17518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER: 17528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: 17538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: 17548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: 17558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: 17568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_CERT_CHAIN_TOO_LONG: 17578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_PATH_LENGTH_EXCEEDED: 17588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_INVALID_CA: 17598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_FAIL_UNTRUSTED; 17608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: 17618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: 17628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: 17638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: 17648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: 17658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: 17668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: 17678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_CERT_UNTRUSTED: 17688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_CERT_REJECTED: 17698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_FAIL_BAD_CERTIFICATE; 17708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 17718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_FAIL_UNSPECIFIED; 17728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * get_x509_cert(X509 *cert) 17778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 17798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *tmp; 17808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int cert_len = i2d_X509(cert, NULL); 17828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert_len <= 0) 17838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 17848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = wpabuf_alloc(cert_len); 17868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 17878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 17888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = wpabuf_put(buf, cert_len); 17908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i2d_X509(cert, &tmp); 17918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 17928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void openssl_tls_fail_event(struct tls_connection *conn, 17968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *err_cert, int err, int depth, 17978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *subject, const char *err_str, 17988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum tls_fail_reason reason) 17998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union tls_event_data ev; 18018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *cert = NULL; 1802ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt struct tls_context *context = conn->context; 18038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18044d8552e9d137f0aab7d64e1476b7f892d0468aebPavel Grafov#ifdef ANDROID 18054d8552e9d137f0aab7d64e1476b7f892d0468aebPavel Grafov log_cert_validation_failure(err_str); 18064d8552e9d137f0aab7d64e1476b7f892d0468aebPavel Grafov#endif 18074d8552e9d137f0aab7d64e1476b7f892d0468aebPavel Grafov 1808ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt if (context->event_cb == NULL) 18098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert = get_x509_cert(err_cert); 18128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&ev, 0, sizeof(ev)); 18138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.cert_fail.reason = reason != TLS_FAIL_UNSPECIFIED ? 18148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reason : openssl_tls_fail_reason(err); 18158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.cert_fail.depth = depth; 18168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.cert_fail.subject = subject; 18178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.cert_fail.reason_txt = err_str; 18188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.cert_fail.cert = cert; 1819ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt context->event_cb(context->cb_ctx, TLS_CERT_CHAIN_FAILURE, &ev); 18208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(cert); 18218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void openssl_tls_cert_event(struct tls_connection *conn, 18258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *err_cert, int depth, 18268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *subject) 18278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *cert = NULL; 18298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union tls_event_data ev; 1830ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt struct tls_context *context = conn->context; 18312f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt char *altsubject[TLS_MAX_ALT_SUBJECT]; 18322f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt int alt, num_altsubject = 0; 18332f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt GENERAL_NAME *gen; 18342f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt void *ext; 18352f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt stack_index_t i; 18368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_SHA256 18378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 hash[32]; 18388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_SHA256 */ 18398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1840ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt if (context->event_cb == NULL) 18418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&ev, 0, sizeof(ev)); 184455840adb6cd32ca52064f327b72a40e769f70661Dmitry Shmidt if (conn->cert_probe || (conn->flags & TLS_CONN_EXT_CERT_CHECK) || 184555840adb6cd32ca52064f327b72a40e769f70661Dmitry Shmidt context->cert_in_cb) { 18468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert = get_x509_cert(err_cert); 18478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.peer_cert.cert = cert; 18488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_SHA256 18508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert) { 18518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr[1]; 18528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len[1]; 18538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr[0] = wpabuf_head(cert); 18548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len[0] = wpabuf_len(cert); 18558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sha256_vector(1, addr, len, hash) == 0) { 18568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.peer_cert.hash = hash; 18578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.peer_cert.hash_len = sizeof(hash); 18588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_SHA256 */ 18618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.peer_cert.depth = depth; 18628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.peer_cert.subject = subject; 18632f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 18642f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt ext = X509_get_ext_d2i(err_cert, NID_subject_alt_name, NULL, NULL); 18652f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt for (i = 0; ext && i < sk_GENERAL_NAME_num(ext); i++) { 18662f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt char *pos; 18672f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 18682f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (num_altsubject == TLS_MAX_ALT_SUBJECT) 18692f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt break; 18702f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt gen = sk_GENERAL_NAME_value(ext, i); 18712f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (gen->type != GEN_EMAIL && 18722f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt gen->type != GEN_DNS && 18732f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt gen->type != GEN_URI) 18742f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt continue; 18752f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 18762f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt pos = os_malloc(10 + gen->d.ia5->length + 1); 18772f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (pos == NULL) 18782f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt break; 18792f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt altsubject[num_altsubject++] = pos; 18802f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 18812f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt switch (gen->type) { 18822f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt case GEN_EMAIL: 18832f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt os_memcpy(pos, "EMAIL:", 6); 18842f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt pos += 6; 18852f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt break; 18862f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt case GEN_DNS: 18872f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt os_memcpy(pos, "DNS:", 4); 18882f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt pos += 4; 18892f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt break; 18902f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt case GEN_URI: 18912f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt os_memcpy(pos, "URI:", 4); 18922f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt pos += 4; 18932f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt break; 18942f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 18952f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 1896d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt os_memcpy(pos, gen->d.ia5->data, gen->d.ia5->length); 1897d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt pos += gen->d.ia5->length; 1898d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt *pos = '\0'; 1899d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 190057c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt sk_GENERAL_NAME_pop_free(ext, GENERAL_NAME_free); 1901d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1902d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt for (alt = 0; alt < num_altsubject; alt++) 1903d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ev.peer_cert.altsubject[alt] = altsubject[alt]; 1904d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ev.peer_cert.num_altsubject = num_altsubject; 1905d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1906d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt context->event_cb(context->cb_ctx, TLS_PEER_CERTIFICATE, &ev); 1907d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpabuf_free(cert); 1908d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt for (alt = 0; alt < num_altsubject; alt++) 1909d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt os_free(altsubject[alt]); 1910d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 1911d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1912d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 19138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx) 19148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char buf[256]; 19168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *err_cert; 19178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int err, depth; 19188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL *ssl; 19198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn; 1920ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt struct tls_context *context; 19212f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt char *match, *altmatch, *suffix_match, *domain_match; 19228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *err_str; 19238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err_cert = X509_STORE_CTX_get_current_cert(x509_ctx); 192596be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt if (!err_cert) 192696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt return 0; 192796be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt 19288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err = X509_STORE_CTX_get_error(x509_ctx); 19298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt depth = X509_STORE_CTX_get_error_depth(x509_ctx); 19308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssl = X509_STORE_CTX_get_ex_data(x509_ctx, 19318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_get_ex_data_X509_STORE_CTX_idx()); 19328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof(buf)); 19338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn = SSL_get_app_data(ssl); 19358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 19368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 193734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 193834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (depth == 0) 193934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt conn->peer_cert = err_cert; 194034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt else if (depth == 1) 194134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt conn->peer_issuer = err_cert; 1942fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt else if (depth == 2) 1943fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt conn->peer_issuer_issuer = err_cert; 194434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 1945ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt context = conn->context; 19468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt match = conn->subject_match; 19478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt altmatch = conn->altsubject_match; 1948051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt suffix_match = conn->suffix_match; 19492f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt domain_match = conn->domain_match; 19508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!preverify_ok && !conn->ca_cert_verify) 19528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt preverify_ok = 1; 19538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!preverify_ok && depth > 0 && conn->server_cert_only) 19548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt preverify_ok = 1; 1955c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt if (!preverify_ok && (conn->flags & TLS_CONN_DISABLE_TIME_CHECKS) && 1956c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt (err == X509_V_ERR_CERT_HAS_EXPIRED || 1957c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt err == X509_V_ERR_CERT_NOT_YET_VALID)) { 1958c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Ignore certificate validity " 1959c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt "time mismatch"); 1960c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt preverify_ok = 1; 1961c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt } 19628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err_str = X509_verify_cert_error_string(err); 19648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_SHA256 19664dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt /* 19674dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt * Do not require preverify_ok so we can explicity allow otherwise 19684dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt * invalid pinned server certificates. 19694dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt */ 19704dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt if (depth == 0 && conn->server_cert_only) { 19718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *cert; 19728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert = get_x509_cert(err_cert); 19738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!cert) { 19748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Could not fetch " 19758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "server certificate data"); 19768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt preverify_ok = 0; 19778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 19788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 hash[32]; 19798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr[1]; 19808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len[1]; 19818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr[0] = wpabuf_head(cert); 19828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len[0] = wpabuf_len(cert); 19838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sha256_vector(1, addr, len, hash) < 0 || 19848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(conn->srv_cert_hash, hash, 32) != 0) { 19858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err_str = "Server certificate mismatch"; 19868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN; 19878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt preverify_ok = 0; 19884dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt } else if (!preverify_ok) { 19894dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt /* 19904dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt * Certificate matches pinned certificate, allow 19914dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt * regardless of other problems. 19924dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt */ 19934dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt wpa_printf(MSG_DEBUG, 19944dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt "OpenSSL: Ignore validation issues for a pinned server certificate"); 19954dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt preverify_ok = 1; 19968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(cert); 19988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_SHA256 */ 20018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!preverify_ok) { 20038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "TLS: Certificate verification failed," 20048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " error %d (%s) depth %d for '%s'", err, err_str, 20058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt depth, buf); 20068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt openssl_tls_fail_event(conn, err_cert, err, depth, buf, 20078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err_str, TLS_FAIL_UNSPECIFIED); 20088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return preverify_ok; 20098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: tls_verify_cb - preverify_ok=%d " 20128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "err=%d (%s) ca_cert_verify=%d depth=%d buf='%s'", 20138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt preverify_ok, err, err_str, 20148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ca_cert_verify, depth, buf); 20158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (depth == 0 && match && os_strstr(buf, match) == NULL) { 20168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "TLS: Subject '%s' did not " 20178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "match with '%s'", buf, match); 20188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt preverify_ok = 0; 20198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt openssl_tls_fail_event(conn, err_cert, err, depth, buf, 20208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Subject mismatch", 20218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_FAIL_SUBJECT_MISMATCH); 20228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (depth == 0 && altmatch && 20238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !tls_match_altsubject(err_cert, altmatch)) { 20248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "TLS: altSubjectName match " 20258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s' not found", altmatch); 20268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt preverify_ok = 0; 20278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt openssl_tls_fail_event(conn, err_cert, err, depth, buf, 20288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "AltSubject mismatch", 20298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_FAIL_ALTSUBJECT_MISMATCH); 2030051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } else if (depth == 0 && suffix_match && 20312f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt !tls_match_suffix(err_cert, suffix_match, 0)) { 2032051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt wpa_printf(MSG_WARNING, "TLS: Domain suffix match '%s' not found", 2033051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt suffix_match); 2034051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt preverify_ok = 0; 2035051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt openssl_tls_fail_event(conn, err_cert, err, depth, buf, 2036051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt "Domain suffix mismatch", 2037051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt TLS_FAIL_DOMAIN_SUFFIX_MISMATCH); 20382f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } else if (depth == 0 && domain_match && 20392f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt !tls_match_suffix(err_cert, domain_match, 1)) { 20402f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_WARNING, "TLS: Domain match '%s' not found", 20412f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt domain_match); 20422f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt preverify_ok = 0; 20432f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt openssl_tls_fail_event(conn, err_cert, err, depth, buf, 20442f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt "Domain mismatch", 20452f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt TLS_FAIL_DOMAIN_MISMATCH); 20468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 20478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt openssl_tls_cert_event(conn, err_cert, depth, buf); 20488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->cert_probe && preverify_ok && depth == 0) { 20508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Reject server certificate " 20518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "on probe-only run"); 20528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt preverify_ok = 0; 20538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt openssl_tls_fail_event(conn, err_cert, err, depth, buf, 20548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Server certificate chain probe", 20558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_FAIL_SERVER_CHAIN_PROBE); 20568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2058d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt#ifdef CONFIG_SUITEB 2059d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (conn->flags & TLS_CONN_SUITEB) { 2060d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt EVP_PKEY *pk; 2061d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt RSA *rsa; 2062d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt int len = -1; 2063d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 2064d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt pk = X509_get_pubkey(err_cert); 2065d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (pk) { 2066d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt rsa = EVP_PKEY_get1_RSA(pk); 2067d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (rsa) { 2068d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt len = RSA_bits(rsa); 2069d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt RSA_free(rsa); 2070d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt } 2071d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt EVP_PKEY_free(pk); 2072d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt } 2073d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 2074d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (len >= 0) { 2075d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt wpa_printf(MSG_DEBUG, 2076d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt "OpenSSL: RSA modulus size: %d bits", len); 2077d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (len < 3072) { 2078d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt preverify_ok = 0; 2079d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt openssl_tls_fail_event( 2080d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt conn, err_cert, err, 2081d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt depth, buf, 2082d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt "Insufficient RSA modulus size", 2083d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt TLS_FAIL_INSUFFICIENT_KEY_LEN); 2084d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt } 2085d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt } 2086d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt } 2087d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt#endif /* CONFIG_SUITEB */ 2088d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 2089d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#ifdef OPENSSL_IS_BORINGSSL 2090d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt if (depth == 0 && (conn->flags & TLS_CONN_REQUEST_OCSP) && 2091d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt preverify_ok) { 2092d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt enum ocsp_result res; 2093d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 2094d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt res = check_ocsp_resp(conn->ssl_ctx, conn->ssl, err_cert, 2095d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt conn->peer_issuer, 2096d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt conn->peer_issuer_issuer); 2097d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (res == OCSP_REVOKED) { 2098d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt preverify_ok = 0; 2099d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt openssl_tls_fail_event(conn, err_cert, err, depth, buf, 2100d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "certificate revoked", 2101d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt TLS_FAIL_REVOKED); 2102d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (err == X509_V_OK) 2103d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt X509_STORE_CTX_set_error( 2104d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt x509_ctx, X509_V_ERR_CERT_REVOKED); 2105d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } else if (res != OCSP_GOOD && 2106d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt (conn->flags & TLS_CONN_REQUIRE_OCSP)) { 2107d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt preverify_ok = 0; 2108d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt openssl_tls_fail_event(conn, err_cert, err, depth, buf, 2109d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "bad certificate status response", 2110d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt TLS_FAIL_UNSPECIFIED); 2111d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 2112d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 2113d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* OPENSSL_IS_BORINGSSL */ 2114d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 211555840adb6cd32ca52064f327b72a40e769f70661Dmitry Shmidt if (depth == 0 && preverify_ok && context->event_cb != NULL) 2116ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt context->event_cb(context->cb_ctx, 2117ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt TLS_CERT_CHAIN_SUCCESS, NULL); 211804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 21198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return preverify_ok; 21208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_STDIO 2124d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int tls_load_ca_der(struct tls_data *data, const char *ca_cert) 21258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2126d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX *ssl_ctx = data->ssl; 21278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_LOOKUP *lookup; 21288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = 0; 21298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2130216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt lookup = X509_STORE_add_lookup(SSL_CTX_get_cert_store(ssl_ctx), 21318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_LOOKUP_file()); 21328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (lookup == NULL) { 21338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_WARNING, __func__, 21348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed add lookup for X509 store"); 21358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 21368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!X509_LOOKUP_load_file(lookup, ca_cert, X509_FILETYPE_ASN1)) { 21398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned long err = ERR_peek_error(); 21408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_WARNING, __func__, 21418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed load CA in DER format"); 21428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ERR_GET_LIB(err) == ERR_LIB_X509 && 21438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_GET_REASON(err) == X509_R_CERT_ALREADY_IN_HASH_TABLE) { 21448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - ignoring " 21458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "cert already in hash table error", 21468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__); 21478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 21488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 21498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 21528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_STDIO */ 21548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2156d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int tls_connection_ca_cert(struct tls_data *data, 2157d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct tls_connection *conn, 21588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *ca_cert, const u8 *ca_cert_blob, 21598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t ca_cert_blob_len, const char *ca_path) 21608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2161d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX *ssl_ctx = data->ssl; 2162216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt X509_STORE *store; 21638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 21658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Remove previously configured trusted CA certificates before adding 21668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * new ones. 21678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2168216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt store = X509_STORE_new(); 2169216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (store == NULL) { 21708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - failed to allocate new " 21718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate store", __func__); 21728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 21738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2174216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt SSL_CTX_set_cert_store(ssl_ctx, store); 21758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb); 21778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ca_cert_verify = 1; 21788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ca_cert && os_strncmp(ca_cert, "probe://", 8) == 0) { 21808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Probe for server certificate " 21818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "chain"); 21828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->cert_probe = 1; 21838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ca_cert_verify = 0; 21848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 21858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ca_cert && os_strncmp(ca_cert, "hash://", 7) == 0) { 21888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_SHA256 21898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *pos = ca_cert + 7; 21908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strncmp(pos, "server/sha256/", 14) != 0) { 21918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Unsupported ca_cert " 21928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "hash value '%s'", ca_cert); 21938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 21948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 14; 21968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strlen(pos) != 32 * 2) { 21978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Unexpected SHA256 " 21988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "hash length in ca_cert '%s'", ca_cert); 21998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hexstr2bin(pos, conn->srv_cert_hash, 32) < 0) { 22028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Invalid SHA256 hash " 22038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "value in ca_cert '%s'", ca_cert); 22048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->server_cert_only = 1; 22078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Checking only server " 22088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate match"); 22098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 22108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_SHA256 */ 22118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "No SHA256 included in the build - " 22128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "cannot validate server certificate hash"); 22138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_SHA256 */ 22158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ca_cert_blob) { 2218216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt X509 *cert = d2i_X509(NULL, 2219216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt (const unsigned char **) &ca_cert_blob, 22208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ca_cert_blob_len); 22218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert == NULL) { 22228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_WARNING, __func__, 22238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to parse ca_cert_blob"); 22248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2227216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!X509_STORE_add_cert(SSL_CTX_get_cert_store(ssl_ctx), 2228216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt cert)) { 22298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned long err = ERR_peek_error(); 22308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_WARNING, __func__, 22318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to add ca_cert_blob to " 22328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate store"); 22338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ERR_GET_LIB(err) == ERR_LIB_X509 && 22348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_GET_REASON(err) == 22358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_R_CERT_ALREADY_IN_HASH_TABLE) { 22368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - ignoring " 22378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "cert already in hash table error", 22388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__); 22398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 22408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 22418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 22458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - added ca_cert_blob " 22468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "to certificate store", __func__); 22478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 22488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef ANDROID 2251b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt /* Single alias */ 22528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ca_cert && os_strncmp("keystore://", ca_cert, 11) == 0) { 2253849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt if (tls_add_ca_from_keystore(SSL_CTX_get_cert_store(ssl_ctx), 2254b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt &ca_cert[11]) < 0) 22558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2256b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb); 2257b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt return 0; 2258b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt } 22598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2260b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt /* Multiple aliases separated by space */ 2261b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if (ca_cert && os_strncmp("keystores://", ca_cert, 12) == 0) { 2262b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt char *aliases = os_strdup(&ca_cert[12]); 2263b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt const char *delim = " "; 2264b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt int rc = 0; 2265b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt char *savedptr; 2266b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt char *alias; 2267b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt 2268b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if (!aliases) 2269b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt return -1; 2270b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt alias = strtok_r(aliases, delim, &savedptr); 2271b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt for (; alias; alias = strtok_r(NULL, delim, &savedptr)) { 2272b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if (tls_add_ca_from_keystore_encoded( 2273849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt SSL_CTX_get_cert_store(ssl_ctx), alias)) { 2274b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt wpa_printf(MSG_WARNING, 2275b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt "OpenSSL: %s - Failed to add ca_cert %s from keystore", 2276b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt __func__, alias); 2277b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt rc = -1; 2278b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt break; 22798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2281b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt os_free(aliases); 2282b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if (rc) 2283b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt return rc; 2284b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt 22858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb); 22868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 22878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* ANDROID */ 22898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_NATIVE_WINDOWS 22918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ca_cert && tls_cryptoapi_ca_cert(ssl_ctx, conn->ssl, ca_cert) == 22928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) { 22938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Added CA certificates from " 22948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "system certificate store"); 22958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 22968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 22988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ca_cert || ca_path) { 23008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_STDIO 23018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_CTX_load_verify_locations(ssl_ctx, ca_cert, ca_path) != 23028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1) { 23038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_WARNING, __func__, 23048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to load root certificates"); 23058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ca_cert && 2306d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt tls_load_ca_der(data, ca_cert) == 0) { 23078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - loaded " 23088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "DER format CA certificate", 23098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__); 23108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 23118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 23128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 23138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Trusted root " 23148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate(s) loaded"); 2315d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt tls_get_errors(data); 23168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_STDIO */ 23188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", 23198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__); 23208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 23218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_STDIO */ 23228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 23238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* No ca_cert configured - do not try to verify server 23248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * certificate */ 23258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ca_cert_verify = 0; 23268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 23298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2332d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int tls_global_ca_cert(struct tls_data *data, const char *ca_cert) 23338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2334d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX *ssl_ctx = data->ssl; 2335d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 23368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ca_cert) { 23378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_CTX_load_verify_locations(ssl_ctx, ca_cert, NULL) != 1) 23388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 23398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_WARNING, __func__, 23408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to load root certificates"); 23418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 23428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Trusted root " 23458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate(s) loaded"); 23468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_STDIO 23488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Add the same CAs to the client certificate requests */ 23498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_set_client_CA_list(ssl_ctx, 23508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_load_client_CA_file(ca_cert)); 23518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_STDIO */ 23528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 23558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_global_set_verify(void *ssl_ctx, int check_crl) 23598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int flags; 23618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (check_crl) { 2363d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct tls_data *data = ssl_ctx; 2364d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt X509_STORE *cs = SSL_CTX_get_cert_store(data->ssl); 23658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cs == NULL) { 23668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, "Failed to get " 23678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate store when enabling " 23688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "check_crl"); 23698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 23708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt flags = X509_V_FLAG_CRL_CHECK; 23728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (check_crl == 2) 23738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt flags |= X509_V_FLAG_CRL_CHECK_ALL; 23748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_STORE_set_flags(cs, flags); 23758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 23778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_connection_set_subject_match(struct tls_connection *conn, 23818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *subject_match, 2382051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt const char *altsubject_match, 23832f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt const char *suffix_match, 23842f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt const char *domain_match) 23858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->subject_match); 23878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->subject_match = NULL; 23888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (subject_match) { 23898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->subject_match = os_strdup(subject_match); 23908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->subject_match == NULL) 23918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 23928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->altsubject_match); 23958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->altsubject_match = NULL; 23968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (altsubject_match) { 23978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->altsubject_match = os_strdup(altsubject_match); 23988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->altsubject_match == NULL) 23998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 24008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2402051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt os_free(conn->suffix_match); 2403051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt conn->suffix_match = NULL; 2404051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (suffix_match) { 2405051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt conn->suffix_match = os_strdup(suffix_match); 2406051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (conn->suffix_match == NULL) 2407051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return -1; 2408051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } 2409051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 24102f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt os_free(conn->domain_match); 24112f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt conn->domain_match = NULL; 24122f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (domain_match) { 24132f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt conn->domain_match = os_strdup(domain_match); 24142f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (conn->domain_match == NULL) 24152f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt return -1; 24162f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 24172f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 24188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 24198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2422d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt#ifdef CONFIG_SUITEB 2423d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt#if OPENSSL_VERSION_NUMBER >= 0x10002000L 2424d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidtstatic int suiteb_cert_cb(SSL *ssl, void *arg) 2425d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 2426d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt struct tls_connection *conn = arg; 2427d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 2428d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt /* 2429d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt * This cert_cb() is not really the best location for doing a 2430d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt * constraint check for the ServerKeyExchange message, but this seems to 2431d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt * be the only place where the current OpenSSL sequence can be 2432d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt * terminated cleanly with an TLS alert going out to the server. 2433d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt */ 2434d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 2435d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (!(conn->flags & TLS_CONN_SUITEB)) 2436d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt return 1; 2437d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 2438d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt /* DHE is enabled only with DHE-RSA-AES256-GCM-SHA384 */ 2439d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (conn->cipher_suite != 0x9f) 2440d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt return 1; 2441d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 2442d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (conn->server_dh_prime_len >= 3072) 2443d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt return 1; 2444d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 2445d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt wpa_printf(MSG_DEBUG, 2446d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt "OpenSSL: Server DH prime length (%d bits) not sufficient for Suite B RSA - reject handshake", 2447d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt conn->server_dh_prime_len); 2448d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt return 0; 2449d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt} 2450d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt#endif /* OPENSSL_VERSION_NUMBER */ 2451d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt#endif /* CONFIG_SUITEB */ 2452d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 2453d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 2454d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidtstatic int tls_set_conn_flags(struct tls_connection *conn, unsigned int flags) 2455d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt{ 2456d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt SSL *ssl = conn->ssl; 2457d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 2458d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#ifdef SSL_OP_NO_TICKET 2459d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (flags & TLS_CONN_DISABLE_SESSION_TICKET) 2460d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_set_options(ssl, SSL_OP_NO_TICKET); 2461d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt else 2462d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_clear_options(ssl, SSL_OP_NO_TICKET); 2463d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* SSL_OP_NO_TICKET */ 2464d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 2465d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#ifdef SSL_OP_NO_TLSv1 2466d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (flags & TLS_CONN_DISABLE_TLSv1_0) 2467d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_set_options(ssl, SSL_OP_NO_TLSv1); 2468d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt else 2469d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_clear_options(ssl, SSL_OP_NO_TLSv1); 2470d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* SSL_OP_NO_TLSv1 */ 2471d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#ifdef SSL_OP_NO_TLSv1_1 2472d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (flags & TLS_CONN_DISABLE_TLSv1_1) 2473d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_set_options(ssl, SSL_OP_NO_TLSv1_1); 2474d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt else 2475d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_clear_options(ssl, SSL_OP_NO_TLSv1_1); 2476d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* SSL_OP_NO_TLSv1_1 */ 2477d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#ifdef SSL_OP_NO_TLSv1_2 2478d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (flags & TLS_CONN_DISABLE_TLSv1_2) 2479d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_set_options(ssl, SSL_OP_NO_TLSv1_2); 2480d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt else 2481d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_clear_options(ssl, SSL_OP_NO_TLSv1_2); 2482d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* SSL_OP_NO_TLSv1_2 */ 2483d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt#ifdef CONFIG_SUITEB 2484d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt#if OPENSSL_VERSION_NUMBER >= 0x10002000L 2485d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (flags & TLS_CONN_SUITEB_NO_ECDH) { 2486d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt const char *ciphers = "DHE-RSA-AES256-GCM-SHA384"; 2487d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 2488d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (SSL_set_cipher_list(ssl, ciphers) != 1) { 2489d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt wpa_printf(MSG_INFO, 2490d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt "OpenSSL: Failed to set Suite B ciphers"); 2491d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt return -1; 2492d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt } 2493d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt } else if (flags & TLS_CONN_SUITEB) { 2494d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt EC_KEY *ecdh; 2495d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt const char *ciphers = 2496d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt "ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384"; 2497d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 2498d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (SSL_set_cipher_list(ssl, ciphers) != 1) { 2499d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt wpa_printf(MSG_INFO, 2500d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt "OpenSSL: Failed to set Suite B ciphers"); 2501d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt return -1; 2502d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt } 2503d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 2504d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (SSL_set1_curves_list(ssl, "P-384") != 1) { 2505d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt wpa_printf(MSG_INFO, 2506d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt "OpenSSL: Failed to set Suite B curves"); 2507d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt return -1; 2508d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt } 2509d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 2510d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt ecdh = EC_KEY_new_by_curve_name(NID_secp384r1); 2511d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (!ecdh || SSL_set_tmp_ecdh(ssl, ecdh) != 1) { 2512d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt EC_KEY_free(ecdh); 2513d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt wpa_printf(MSG_INFO, 2514d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt "OpenSSL: Failed to set ECDH parameter"); 2515d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt return -1; 2516d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt } 2517d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt EC_KEY_free(ecdh); 2518d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt } 2519d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (flags & (TLS_CONN_SUITEB | TLS_CONN_SUITEB_NO_ECDH)) { 2520d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt /* ECDSA+SHA384 if need to add EC support here */ 2521d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (SSL_set1_sigalgs_list(ssl, "RSA+SHA384") != 1) { 2522d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt wpa_printf(MSG_INFO, 2523d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt "OpenSSL: Failed to set Suite B sigalgs"); 2524d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt return -1; 2525d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt } 2526d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 2527d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt SSL_set_options(ssl, SSL_OP_NO_TLSv1); 2528d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt SSL_set_options(ssl, SSL_OP_NO_TLSv1_1); 2529d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt SSL_set_cert_cb(ssl, suiteb_cert_cb, conn); 2530d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt } 2531d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt#else /* OPENSSL_VERSION_NUMBER < 0x10002000L */ 2532d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (flags & (TLS_CONN_SUITEB | TLS_CONN_SUITEB_NO_ECDH)) { 2533d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt wpa_printf(MSG_ERROR, 2534d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt "OpenSSL: Suite B RSA case not supported with this OpenSSL version"); 2535d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt return -1; 2536d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt } 2537d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt#endif /* OPENSSL_VERSION_NUMBER */ 2538d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt#endif /* CONFIG_SUITEB */ 2539d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 2540d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt return 0; 2541d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 2542d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 2543d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 25448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn, 2545d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt int verify_peer, unsigned int flags, 2546d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const u8 *session_ctx, size_t session_ctx_len) 25478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt static int counter = 0; 2549d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct tls_data *data = ssl_ctx; 25508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 25528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 25538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (verify_peer) { 25558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ca_cert_verify = 1; 25568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_verify(conn->ssl, SSL_VERIFY_PEER | 25578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_VERIFY_FAIL_IF_NO_PEER_CERT | 25588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_VERIFY_CLIENT_ONCE, tls_verify_cb); 25598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 25608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ca_cert_verify = 0; 25618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_verify(conn->ssl, SSL_VERIFY_NONE, NULL); 25628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2564d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (tls_set_conn_flags(conn, flags) < 0) 2565d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt return -1; 2566d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt conn->flags = flags; 2567d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 25688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_accept_state(conn->ssl); 25698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2570d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (data->tls_session_lifetime == 0) { 2571d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt /* 2572d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * Set session id context to a unique value to make sure 2573d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * session resumption cannot be used either through session 2574d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * caching or TLS ticket extension. 2575d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt */ 2576d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt counter++; 2577d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_set_session_id_context(conn->ssl, 2578d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt (const unsigned char *) &counter, 2579d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt sizeof(counter)); 2580d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } else if (session_ctx) { 2581d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_set_session_id_context(conn->ssl, session_ctx, 2582d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt session_ctx_len); 2583d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 25848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 25868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_connection_client_cert(struct tls_connection *conn, 25908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *client_cert, 25918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *client_cert_blob, 25928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t client_cert_blob_len) 25938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (client_cert == NULL && client_cert_blob == NULL) 25958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 25968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2597de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt#ifdef PKCS12_FUNCS 25989839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#if OPENSSL_VERSION_NUMBER < 0x10002000L || defined(LIBRESSL_VERSION_NUMBER) 2599de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt /* 2600de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt * Clear previously set extra chain certificates, if any, from PKCS#12 2601de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt * processing in tls_parse_pkcs12() to allow OpenSSL to build a new 2602de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt * chain properly. 2603de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt */ 2604de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt SSL_CTX_clear_extra_chain_certs(conn->ssl_ctx); 2605de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt#endif /* OPENSSL_VERSION_NUMBER < 0x10002000L */ 2606de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt#endif /* PKCS12_FUNCS */ 2607de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt 26088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (client_cert_blob && 26098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_use_certificate_ASN1(conn->ssl, (u8 *) client_cert_blob, 26108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client_cert_blob_len) == 1) { 26118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_ASN1 --> " 26128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "OK"); 26138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (client_cert_blob) { 26158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_DEBUG, __func__, 26168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SSL_use_certificate_ASN1 failed"); 26178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (client_cert == NULL) 26208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef ANDROID 26238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strncmp("keystore://", client_cert, 11) == 0) { 26248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO *bio = BIO_from_keystore(&client_cert[11]); 26258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *x509 = NULL; 26268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = -1; 2627d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (bio) { 26288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL); 2629d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt } 26308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (x509) { 26318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_certificate(conn->ssl, x509) == 1) 26328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = 0; 26338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(x509); 26348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 263550772e8622904b97ec2840383b4f7395e952344cPaul Stewart 263650772e8622904b97ec2840383b4f7395e952344cPaul Stewart /* Read additional certificates into the chain. */ 263750772e8622904b97ec2840383b4f7395e952344cPaul Stewart while (bio) { 263850772e8622904b97ec2840383b4f7395e952344cPaul Stewart x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL); 263950772e8622904b97ec2840383b4f7395e952344cPaul Stewart if (x509) { 264050772e8622904b97ec2840383b4f7395e952344cPaul Stewart /* Takes ownership of x509 */ 264150772e8622904b97ec2840383b4f7395e952344cPaul Stewart SSL_add0_chain_cert(conn->ssl, x509); 264250772e8622904b97ec2840383b4f7395e952344cPaul Stewart } else { 264350772e8622904b97ec2840383b4f7395e952344cPaul Stewart BIO_free(bio); 264450772e8622904b97ec2840383b4f7395e952344cPaul Stewart bio = NULL; 264550772e8622904b97ec2840383b4f7395e952344cPaul Stewart } 264650772e8622904b97ec2840383b4f7395e952344cPaul Stewart } 26478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 26488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* ANDROID */ 26508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_STDIO 26528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_certificate_file(conn->ssl, client_cert, 26538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_FILETYPE_ASN1) == 1) { 26548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_file (DER)" 26558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " --> OK"); 26568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_certificate_file(conn->ssl, client_cert, 26608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_FILETYPE_PEM) == 1) { 26618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_clear_error(); 26628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_file (PEM)" 26638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " --> OK"); 26648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_DEBUG, __func__, 26688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SSL_use_certificate_file failed"); 26698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_STDIO */ 26708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", __func__); 26718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_STDIO */ 26728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2677d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int tls_global_client_cert(struct tls_data *data, 2678d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const char *client_cert) 26798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_STDIO 2681d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX *ssl_ctx = data->ssl; 2682d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 26838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (client_cert == NULL) 26848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_CTX_use_certificate_file(ssl_ctx, client_cert, 26878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_FILETYPE_ASN1) != 1 && 26881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt SSL_CTX_use_certificate_chain_file(ssl_ctx, client_cert) != 1 && 26898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_use_certificate_file(ssl_ctx, client_cert, 26908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_FILETYPE_PEM) != 1) { 26918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 26928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to load client certificate"); 26938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_STDIO */ 26978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (client_cert == NULL) 26988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", __func__); 27008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_STDIO */ 27028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_passwd_cb(char *buf, int size, int rwflag, void *password) 27068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (password == NULL) { 27088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 27098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(buf, (char *) password, size); 27118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return os_strlen(buf); 27128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef PKCS12_FUNCS 2716d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int tls_parse_pkcs12(struct tls_data *data, SSL *ssl, PKCS12 *p12, 27178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *passwd) 27188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EVP_PKEY *pkey; 27208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *cert; 27218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt STACK_OF(X509) *certs; 27228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res = 0; 27238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char buf[256]; 27248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pkey = NULL; 27268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert = NULL; 27278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt certs = NULL; 2728d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!passwd) 2729d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt passwd = ""; 27308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!PKCS12_parse(p12, passwd, &pkey, &cert, &certs)) { 27318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_DEBUG, __func__, 27328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to parse PKCS12 file"); 27338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PKCS12_free(p12); 27348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Successfully parsed PKCS12 data"); 27378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert) { 27398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_NAME_oneline(X509_get_subject_name(cert), buf, 27408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(buf)); 27418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Got certificate from PKCS12: " 27428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "subject='%s'", buf); 27438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssl) { 27448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_certificate(ssl, cert) != 1) 27458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 27468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 2747d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (SSL_CTX_use_certificate(data->ssl, cert) != 1) 27488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 27498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 27518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pkey) { 27548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Got private key from PKCS12"); 27558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssl) { 27568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_PrivateKey(ssl, pkey) != 1) 27578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 27588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 2759d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (SSL_CTX_use_PrivateKey(data->ssl, pkey) != 1) 27608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 27618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EVP_PKEY_free(pkey); 27638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (certs) { 2766d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt#if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(LIBRESSL_VERSION_NUMBER) 2767b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if (ssl) 2768b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt SSL_clear_chain_certs(ssl); 2769b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt else 2770b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt SSL_CTX_clear_chain_certs(data->ssl); 2771d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt while ((cert = sk_X509_pop(certs)) != NULL) { 2772d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt X509_NAME_oneline(X509_get_subject_name(cert), buf, 2773d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt sizeof(buf)); 2774d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: additional certificate" 2775d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt " from PKCS12: subject='%s'", buf); 2776b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if ((ssl && SSL_add1_chain_cert(ssl, cert) != 1) || 2777b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt (!ssl && SSL_CTX_add1_chain_cert(data->ssl, 2778b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt cert) != 1)) { 2779d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt tls_show_errors(MSG_DEBUG, __func__, 2780d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "Failed to add additional certificate"); 2781d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt res = -1; 278257c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt X509_free(cert); 2783d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt break; 2784d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 278557c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt X509_free(cert); 2786d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 2787d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!res) { 2788d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt /* Try to continue anyway */ 2789d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 279057c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt sk_X509_pop_free(certs, X509_free); 2791d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#ifndef OPENSSL_IS_BORINGSSL 2792b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if (ssl) 2793b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt res = SSL_build_cert_chain( 2794b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt ssl, 2795b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt SSL_BUILD_CHAIN_FLAG_CHECK | 2796b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR); 2797b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt else 2798b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt res = SSL_CTX_build_cert_chain( 2799b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt data->ssl, 2800b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt SSL_BUILD_CHAIN_FLAG_CHECK | 2801b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR); 2802d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!res) { 2803d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt tls_show_errors(MSG_DEBUG, __func__, 2804d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "Failed to build certificate chain"); 2805d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } else if (res == 2) { 2806d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_DEBUG, 2807d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "TLS: Ignore certificate chain verification error when building chain with PKCS#12 extra certificates"); 2808d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 2809d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* OPENSSL_IS_BORINGSSL */ 2810d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt /* 2811d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * Try to continue regardless of result since it is possible for 2812d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * the extra certificates not to be required. 2813d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt */ 2814d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt res = 0; 2815d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#else /* OPENSSL_VERSION_NUMBER >= 0x10002000L */ 2816d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX_clear_extra_chain_certs(data->ssl); 28178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while ((cert = sk_X509_pop(certs)) != NULL) { 28188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_NAME_oneline(X509_get_subject_name(cert), buf, 28198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(buf)); 28208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: additional certificate" 28218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " from PKCS12: subject='%s'", buf); 28228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 28238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * There is no SSL equivalent for the chain cert - so 28248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * always add it to the context... 28258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2826d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (SSL_CTX_add_extra_chain_cert(data->ssl, cert) != 1) 2827d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt { 282857c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt X509_free(cert); 28298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 28308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 28318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 283357c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt sk_X509_pop_free(certs, X509_free); 2834d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* OPENSSL_VERSION_NUMBER >= 0x10002000L */ 28358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PKCS12_free(p12); 28388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) 2840d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt tls_get_errors(data); 28418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 28438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* PKCS12_FUNCS */ 28458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2847d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int tls_read_pkcs12(struct tls_data *data, SSL *ssl, 2848d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const char *private_key, const char *passwd) 28498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef PKCS12_FUNCS 28518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FILE *f; 28528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PKCS12 *p12; 28538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt f = fopen(private_key, "rb"); 28558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (f == NULL) 28568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 28578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p12 = d2i_PKCS12_fp(f, NULL); 28598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fclose(f); 28608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p12 == NULL) { 28628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 28638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to use PKCS#12 file"); 28648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 28658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2867d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return tls_parse_pkcs12(data, ssl, p12, passwd); 28688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* PKCS12_FUNCS */ 28708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: PKCS12 support disabled - cannot read " 28718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "p12/pfx files"); 28728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 28738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* PKCS12_FUNCS */ 28748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2877d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int tls_read_pkcs12_blob(struct tls_data *data, SSL *ssl, 28788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *blob, size_t len, const char *passwd) 28798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef PKCS12_FUNCS 28818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PKCS12 *p12; 28828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2883216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p12 = d2i_PKCS12(NULL, (const unsigned char **) &blob, len); 28848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p12 == NULL) { 28858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 28868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to use PKCS#12 blob"); 28878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 28888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2890d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return tls_parse_pkcs12(data, ssl, p12, passwd); 28918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* PKCS12_FUNCS */ 28938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: PKCS12 support disabled - cannot parse " 28948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "p12/pfx blobs"); 28958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 28968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* PKCS12_FUNCS */ 28978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_ENGINE 29018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_engine_get_cert(struct tls_connection *conn, 29028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *cert_id, 29038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 **cert) 29048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* this runs after the private key is loaded so no PIN is required */ 29068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct { 29078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *cert_id; 29088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *cert; 29098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } params; 29108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.cert_id = cert_id; 29118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.cert = NULL; 29128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ENGINE_ctrl_cmd(conn->engine, "LOAD_CERT_CTRL", 29148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0, ¶ms, NULL, 1)) { 29151d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt unsigned long err = ERR_get_error(); 29161d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt 29178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "ENGINE: cannot load client cert with id" 29188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " '%s' [%s]", cert_id, 29191d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt ERR_error_string(err, NULL)); 29201d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt if (tls_is_pin_error(err)) 29211d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt return TLS_SET_PARAMS_ENGINE_PRV_BAD_PIN; 29228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED; 29238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!params.cert) { 29258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "ENGINE: did not properly cert with id" 29268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " '%s'", cert_id); 29278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED; 29288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *cert = params.cert; 29308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 29318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 29338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_connection_engine_client_cert(struct tls_connection *conn, 29368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *cert_id) 29378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_ENGINE 29398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *cert; 29408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_engine_get_cert(conn, cert_id, &cert)) 29428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 29438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!SSL_use_certificate(conn->ssl, cert)) { 29458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_ERROR, __func__, 29468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SSL_use_certificate failed"); 29478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 29488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 29498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 29518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: SSL_use_certificate --> " 29528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "OK"); 29538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 29548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_ENGINE */ 29568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 29578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 29588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2961d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int tls_connection_engine_ca_cert(struct tls_data *data, 29628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn, 29638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *ca_cert_id) 29648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_ENGINE 29668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *cert; 2967d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX *ssl_ctx = data->ssl; 2968216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt X509_STORE *store; 29698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_engine_get_cert(conn, ca_cert_id, &cert)) 29718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 29728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* start off the same as tls_connection_ca_cert */ 2974216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt store = X509_STORE_new(); 2975216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (store == NULL) { 29768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - failed to allocate new " 29778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate store", __func__); 29788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 29798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 29808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2981216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt SSL_CTX_set_cert_store(ssl_ctx, store); 2982216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!X509_STORE_add_cert(store, cert)) { 29838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned long err = ERR_peek_error(); 29848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_WARNING, __func__, 29858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to add CA certificate from engine " 29868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "to certificate store"); 29878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ERR_GET_LIB(err) == ERR_LIB_X509 && 29888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_GET_REASON(err) == X509_R_CERT_ALREADY_IN_HASH_TABLE) { 29898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - ignoring cert" 29908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " already in hash table error", 29918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__); 29928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 29938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 29948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 29958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 29988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - added CA certificate from engine " 29998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "to certificate store", __func__); 30008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb); 300161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt conn->ca_cert_verify = 1; 300261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 30038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 30048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_ENGINE */ 30068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 30078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 30088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_connection_engine_private_key(struct tls_connection *conn) 30128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 30131eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley#if defined(ANDROID) || !defined(OPENSSL_NO_ENGINE) 30148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_PrivateKey(conn->ssl, conn->private_key) != 1) { 30158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_ERROR, __func__, 30168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ENGINE: cannot use private key for TLS"); 30178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 30188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!SSL_check_private_key(conn->ssl)) { 30208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 30218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Private key failed verification"); 30228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 30238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 30258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_ENGINE */ 30268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "SSL: Configuration uses engine, but " 30278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "engine support was not compiled in"); 30288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 30298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 30308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3033d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidtstatic void tls_clear_default_passwd_cb(SSL_CTX *ssl_ctx, SSL *ssl) 3034d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt{ 3035d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) && !defined(OPENSSL_IS_BORINGSSL) 3036d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (ssl) { 3037d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt SSL_set_default_passwd_cb(ssl, NULL); 3038d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt SSL_set_default_passwd_cb_userdata(ssl, NULL); 3039d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt } 3040d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt#endif /* >= 1.1.0f && !LibreSSL && !BoringSSL */ 3041d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt SSL_CTX_set_default_passwd_cb(ssl_ctx, NULL); 3042d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, NULL); 3043d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt} 3044d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 3045d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 3046d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int tls_connection_private_key(struct tls_data *data, 30478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn, 30488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *private_key, 30498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *private_key_passwd, 30508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *private_key_blob, 30518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t private_key_blob_len) 30528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3053d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX *ssl_ctx = data->ssl; 30548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *passwd; 30558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ok; 30568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (private_key == NULL && private_key_blob == NULL) 30588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 30598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (private_key_passwd) { 30618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt passwd = os_strdup(private_key_passwd); 30628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (passwd == NULL) 30638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 30648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 30658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt passwd = NULL; 30668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3067d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) && !defined(OPENSSL_IS_BORINGSSL) 3068d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt /* 3069d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt * In OpenSSL >= 1.1.0f SSL_use_PrivateKey_file() uses the callback 3070d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt * from the SSL object. See OpenSSL commit d61461a75253. 3071d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt */ 3072d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt SSL_set_default_passwd_cb(conn->ssl, tls_passwd_cb); 3073d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt SSL_set_default_passwd_cb_userdata(conn->ssl, passwd); 3074d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt#endif /* >= 1.1.0f && !LibreSSL && !BoringSSL */ 3075d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt /* Keep these for OpenSSL < 1.1.0f */ 30768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_set_default_passwd_cb(ssl_ctx, tls_passwd_cb); 30778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, passwd); 30788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 0; 30808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (private_key_blob) { 30818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_PrivateKey_ASN1(EVP_PKEY_RSA, conn->ssl, 30828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) private_key_blob, 30838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt private_key_blob_len) == 1) { 30848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_PrivateKey_" 30858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ASN1(EVP_PKEY_RSA) --> OK"); 30868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 1; 30878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_PrivateKey_ASN1(EVP_PKEY_DSA, conn->ssl, 30918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) private_key_blob, 30928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt private_key_blob_len) == 1) { 30938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_PrivateKey_" 30948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ASN1(EVP_PKEY_DSA) --> OK"); 30958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 1; 30968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_RSAPrivateKey_ASN1(conn->ssl, 31008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) private_key_blob, 31018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt private_key_blob_len) == 1) { 31028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: " 31038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SSL_use_RSAPrivateKey_ASN1 --> OK"); 31048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 1; 31058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3108d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (tls_read_pkcs12_blob(data, conn->ssl, private_key_blob, 31098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt private_key_blob_len, passwd) == 0) { 31108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: PKCS#12 as blob --> " 31118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "OK"); 31128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 1; 31138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (!ok && private_key) { 31208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_STDIO 31218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_PrivateKey_file(conn->ssl, private_key, 31228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_FILETYPE_ASN1) == 1) { 31238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: " 31248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SSL_use_PrivateKey_File (DER) --> OK"); 31258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 1; 31268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_PrivateKey_file(conn->ssl, private_key, 31308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_FILETYPE_PEM) == 1) { 31318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: " 31328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SSL_use_PrivateKey_File (PEM) --> OK"); 31338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 1; 31348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_STDIO */ 31378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", 31388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__); 31398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_STDIO */ 31408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3141d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (tls_read_pkcs12(data, conn->ssl, private_key, passwd) 31428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt == 0) { 31438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Reading PKCS#12 file " 31448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "--> OK"); 31458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 1; 31468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_cryptoapi_cert(conn->ssl, private_key) == 0) { 31508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Using CryptoAPI to " 31518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "access certificate store --> OK"); 31528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 1; 31538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ok) { 31608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 31618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to load private key"); 3162d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt tls_clear_default_passwd_cb(ssl_ctx, conn->ssl); 31638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(passwd); 31648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 31658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_clear_error(); 3167d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt tls_clear_default_passwd_cb(ssl_ctx, conn->ssl); 31688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(passwd); 316961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 31708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!SSL_check_private_key(conn->ssl)) { 31718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, "Private key failed " 31728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "verification"); 31738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 31748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Private key loaded successfully"); 31778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 31788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3181d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int tls_global_private_key(struct tls_data *data, 3182d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const char *private_key, 31838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *private_key_passwd) 31848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3185d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX *ssl_ctx = data->ssl; 31868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *passwd; 31878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (private_key == NULL) 31898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 31908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (private_key_passwd) { 31928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt passwd = os_strdup(private_key_passwd); 31938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (passwd == NULL) 31948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 31958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 31968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt passwd = NULL; 31978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_set_default_passwd_cb(ssl_ctx, tls_passwd_cb); 31998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, passwd); 32008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ( 32018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_STDIO 32028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_use_PrivateKey_file(ssl_ctx, private_key, 32038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_FILETYPE_ASN1) != 1 && 32048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_use_PrivateKey_file(ssl_ctx, private_key, 32058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_FILETYPE_PEM) != 1 && 32068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_STDIO */ 3207d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt tls_read_pkcs12(data, NULL, private_key, passwd)) { 32088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 32098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to load private key"); 3210d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt tls_clear_default_passwd_cb(ssl_ctx, NULL); 32118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(passwd); 32128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_clear_error(); 32138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 32148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3215d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt tls_clear_default_passwd_cb(ssl_ctx, NULL); 32168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(passwd); 32178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_clear_error(); 321861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 32198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!SSL_CTX_check_private_key(ssl_ctx)) { 32208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 32218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Private key failed verification"); 32228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 32238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 32268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 32278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_connection_dh(struct tls_connection *conn, const char *dh_file) 32308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 32318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef OPENSSL_NO_DH 32328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dh_file == NULL) 32338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 32348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "TLS: openssl does not include DH support, but " 32358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dh_file specified"); 32368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 32378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_DH */ 32388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DH *dh; 32398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO *bio; 32408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: add support for dh_blob */ 32428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dh_file == NULL) 32438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 32448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 32458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 32468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bio = BIO_new_file(dh_file, "r"); 32488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bio == NULL) { 32498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to open DH file '%s': %s", 32508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dh_file, ERR_error_string(ERR_get_error(), NULL)); 32518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 32528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); 32548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO_free(bio); 32558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_DSA 32568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (dh == NULL) { 32578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DSA *dsa; 32588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Failed to parse DH file '%s': %s -" 32598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " trying to parse as DSA params", dh_file, 32608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 32618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bio = BIO_new_file(dh_file, "r"); 32628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bio == NULL) 32638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 32648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dsa = PEM_read_bio_DSAparams(bio, NULL, NULL, NULL); 32658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO_free(bio); 32668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!dsa) { 32678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Failed to parse DSA file " 32688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s': %s", dh_file, 32698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 32708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 32718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: DH file in DSA param format"); 32748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dh = DSA_dup_DH(dsa); 32758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DSA_free(dsa); 32768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dh == NULL) { 32778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to convert DSA " 32788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "params into DH params"); 32798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 32808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 32828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* !OPENSSL_NO_DSA */ 32848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dh == NULL) { 32858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to read/parse DH/DSA file " 32868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s'", dh_file); 32878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 32888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_set_tmp_dh(conn->ssl, dh) != 1) { 32918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to set DH params from '%s': " 32928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%s", dh_file, 32938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 32948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DH_free(dh); 32958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 32968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DH_free(dh); 32988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 32998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_DH */ 33008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 33018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3303d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int tls_global_dh(struct tls_data *data, const char *dh_file) 33048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 33058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef OPENSSL_NO_DH 33068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dh_file == NULL) 33078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 33088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "TLS: openssl does not include DH support, but " 33098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dh_file specified"); 33108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 33118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_DH */ 3312d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX *ssl_ctx = data->ssl; 33138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DH *dh; 33148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO *bio; 33158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: add support for dh_blob */ 33178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dh_file == NULL) 33188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 33198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssl_ctx == NULL) 33208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 33218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bio = BIO_new_file(dh_file, "r"); 33238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bio == NULL) { 33248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to open DH file '%s': %s", 33258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dh_file, ERR_error_string(ERR_get_error(), NULL)); 33268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 33278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); 33298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO_free(bio); 33308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_DSA 33318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (dh == NULL) { 33328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DSA *dsa; 33338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Failed to parse DH file '%s': %s -" 33348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " trying to parse as DSA params", dh_file, 33358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 33368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bio = BIO_new_file(dh_file, "r"); 33378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bio == NULL) 33388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 33398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dsa = PEM_read_bio_DSAparams(bio, NULL, NULL, NULL); 33408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO_free(bio); 33418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!dsa) { 33428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Failed to parse DSA file " 33438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s': %s", dh_file, 33448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 33458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 33468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: DH file in DSA param format"); 33498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dh = DSA_dup_DH(dsa); 33508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DSA_free(dsa); 33518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dh == NULL) { 33528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to convert DSA " 33538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "params into DH params"); 33548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 33558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 33578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* !OPENSSL_NO_DSA */ 33598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dh == NULL) { 33608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to read/parse DH/DSA file " 33618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s'", dh_file); 33628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 33638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_CTX_set_tmp_dh(ssl_ctx, dh) != 1) { 33668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to set DH params from '%s': " 33678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%s", dh_file, 33688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 33698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DH_free(dh); 33708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 33718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DH_free(dh); 33738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 33748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_DH */ 33758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 33768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3378d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtint tls_connection_get_random(void *ssl_ctx, struct tls_connection *conn, 3379d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct tls_random *keys) 33808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 33818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL *ssl; 33828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL || keys == NULL) 33848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 33858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssl = conn->ssl; 3386d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (ssl == NULL) 3387d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return -1; 3388d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3389d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt os_memset(keys, 0, sizeof(*keys)); 3390d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt keys->client_random = conn->client_random; 3391d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt keys->client_random_len = SSL_get_client_random( 3392d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ssl, conn->client_random, sizeof(conn->client_random)); 3393d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt keys->server_random = conn->server_random; 3394d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt keys->server_random_len = SSL_get_server_random( 3395d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ssl, conn->server_random, sizeof(conn->server_random)); 33968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 33988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 33998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3401849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt#ifdef OPENSSL_NEED_EAP_FAST_PRF 3402af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidtstatic int openssl_get_keyblock_size(SSL *ssl) 3403af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt{ 3404d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) 3405af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt const EVP_CIPHER *c; 3406af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt const EVP_MD *h; 3407af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt int md_size; 3408af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt 3409af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt if (ssl->enc_read_ctx == NULL || ssl->enc_read_ctx->cipher == NULL || 3410af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt ssl->read_hash == NULL) 3411af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt return -1; 3412af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt 3413af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt c = ssl->enc_read_ctx->cipher; 3414af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt h = EVP_MD_CTX_md(ssl->read_hash); 3415af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt if (h) 3416af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt md_size = EVP_MD_size(h); 3417af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt else if (ssl->s3) 3418af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt md_size = ssl->s3->tmp.new_mac_secret_size; 3419af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt else 3420af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt return -1; 3421af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt 3422af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: keyblock size: key_len=%d MD_size=%d " 3423af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt "IV_len=%d", EVP_CIPHER_key_length(c), md_size, 3424af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt EVP_CIPHER_iv_length(c)); 3425af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt return 2 * (EVP_CIPHER_key_length(c) + 3426af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt md_size + 3427af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt EVP_CIPHER_iv_length(c)); 3428d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#else 3429d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const SSL_CIPHER *ssl_cipher; 3430d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt int cipher, digest; 3431d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const EVP_CIPHER *c; 3432d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const EVP_MD *h; 3433d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3434d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ssl_cipher = SSL_get_current_cipher(ssl); 3435d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!ssl_cipher) 3436d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return -1; 3437d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt cipher = SSL_CIPHER_get_cipher_nid(ssl_cipher); 3438d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt digest = SSL_CIPHER_get_digest_nid(ssl_cipher); 3439d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: cipher nid %d digest nid %d", 3440d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt cipher, digest); 3441d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (cipher < 0 || digest < 0) 3442d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return -1; 3443d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt c = EVP_get_cipherbynid(cipher); 3444d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt h = EVP_get_digestbynid(digest); 3445d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!c || !h) 3446d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return -1; 3447d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3448d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_DEBUG, 3449d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "OpenSSL: keyblock size: key_len=%d MD_size=%d IV_len=%d", 3450d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt EVP_CIPHER_key_length(c), EVP_MD_size(h), 3451d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt EVP_CIPHER_iv_length(c)); 3452d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return 2 * (EVP_CIPHER_key_length(c) + EVP_MD_size(h) + 3453d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt EVP_CIPHER_iv_length(c)); 3454d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif 3455af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt} 3456849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt#endif /* OPENSSL_NEED_EAP_FAST_PRF */ 3457af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt 3458af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt 3459849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidtint tls_connection_export_key(void *tls_ctx, struct tls_connection *conn, 3460849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt const char *label, u8 *out, size_t out_len) 3461af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt{ 3462849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt if (!conn || 3463849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt SSL_export_keying_material(conn->ssl, out, out_len, label, 3464849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt os_strlen(label), NULL, 0, 0) != 1) 3465849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt return -1; 3466849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt return 0; 3467849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt} 3468849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt 3469849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt 3470849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidtint tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn, 3471849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt u8 *out, size_t out_len) 3472849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt{ 3473849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt#ifdef OPENSSL_NEED_EAP_FAST_PRF 3474d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL *ssl; 3475d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_SESSION *sess; 3476d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt u8 *rnd; 3477d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt int ret = -1; 3478d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt int skip = 0; 3479d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt u8 *tmp_out = NULL; 3480d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt u8 *_out = out; 3481d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt unsigned char client_random[SSL3_RANDOM_SIZE]; 3482d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt unsigned char server_random[SSL3_RANDOM_SIZE]; 3483d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt unsigned char master_key[64]; 3484d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt size_t master_key_len; 3485d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const char *ver; 3486d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3487d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt /* 3488849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt * TLS library did not support EAP-FAST key generation, so get the 3489849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt * needed TLS session parameters and use an internal implementation of 3490849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt * TLS PRF to derive the key. 3491d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt */ 3492d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3493d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (conn == NULL) 3494d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return -1; 3495d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ssl = conn->ssl; 3496d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (ssl == NULL) 3497d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return -1; 3498d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ver = SSL_get_version(ssl); 3499d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt sess = SSL_get_session(ssl); 3500d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!ver || !sess) 3501d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return -1; 3502d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3503849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt skip = openssl_get_keyblock_size(ssl); 3504849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt if (skip < 0) 3505849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt return -1; 3506849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt tmp_out = os_malloc(skip + out_len); 3507849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt if (!tmp_out) 3508849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt return -1; 3509849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt _out = tmp_out; 3510d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3511d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt rnd = os_malloc(2 * SSL3_RANDOM_SIZE); 3512d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!rnd) { 3513d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt os_free(tmp_out); 3514d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return -1; 3515d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 3516d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3517d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_get_client_random(ssl, client_random, sizeof(client_random)); 3518d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_get_server_random(ssl, server_random, sizeof(server_random)); 3519d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt master_key_len = SSL_SESSION_get_master_key(sess, master_key, 3520d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt sizeof(master_key)); 3521d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3522849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt os_memcpy(rnd, server_random, SSL3_RANDOM_SIZE); 3523849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt os_memcpy(rnd + SSL3_RANDOM_SIZE, client_random, SSL3_RANDOM_SIZE); 3524d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3525d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (os_strcmp(ver, "TLSv1.2") == 0) { 3526d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt tls_prf_sha256(master_key, master_key_len, 3527849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt "key expansion", rnd, 2 * SSL3_RANDOM_SIZE, 3528d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt _out, skip + out_len); 3529af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt ret = 0; 3530d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } else if (tls_prf_sha1_md5(master_key, master_key_len, 3531849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt "key expansion", rnd, 2 * SSL3_RANDOM_SIZE, 3532d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt _out, skip + out_len) == 0) { 3533d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ret = 0; 3534d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 3535d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt os_memset(master_key, 0, sizeof(master_key)); 3536af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt os_free(rnd); 3537849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt if (ret == 0) 3538af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt os_memcpy(out, _out + skip, out_len); 3539af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt bin_clear_free(tmp_out, skip); 3540af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt 3541af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt return ret; 3542849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt#else /* OPENSSL_NEED_EAP_FAST_PRF */ 3543849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt wpa_printf(MSG_ERROR, 3544849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt "OpenSSL: EAP-FAST keys cannot be exported in FIPS mode"); 3545849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt return -1; 3546849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt#endif /* OPENSSL_NEED_EAP_FAST_PRF */ 35478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 35488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * 35518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtopenssl_handshake(struct tls_connection *conn, const struct wpabuf *in_data, 35528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int server) 35538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 35548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 35558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *out_data; 35568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 35588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Give TLS handshake data from the server (if available) to OpenSSL 35598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * for processing. 35608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3561d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (in_data && wpabuf_len(in_data) > 0 && 35628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO_write(conn->ssl_in, wpabuf_head(in_data), wpabuf_len(in_data)) 35638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt < 0) { 35648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 35658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Handshake failed - BIO_write"); 35668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 35678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 35688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Initiate TLS handshake or continue the existing handshake */ 35708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (server) 35718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = SSL_accept(conn->ssl); 35728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 35738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = SSL_connect(conn->ssl); 35748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res != 1) { 35758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int err = SSL_get_error(conn->ssl, res); 35768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (err == SSL_ERROR_WANT_READ) 35778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: SSL_connect - want " 35788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "more data"); 35798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (err == SSL_ERROR_WANT_WRITE) 35808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: SSL_connect - want to " 35818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "write"); 35828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 35838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, "SSL_connect"); 35848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->failed++; 35858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 35868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 35878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3588d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt#ifdef CONFIG_SUITEB 3589d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if ((conn->flags & TLS_CONN_SUITEB) && !server && 3590d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt os_strncmp(SSL_get_cipher(conn->ssl), "DHE-", 4) == 0 && 3591d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt conn->server_dh_prime_len < 3072) { 3592d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt struct tls_context *context = conn->context; 3593d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 3594d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt /* 3595d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt * This should not be reached since earlier cert_cb should have 3596d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt * terminated the handshake. Keep this check here for extra 3597d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt * protection if anything goes wrong with the more low-level 3598d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt * checks based on having to parse the TLS handshake messages. 3599d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt */ 3600d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt wpa_printf(MSG_DEBUG, 3601d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt "OpenSSL: Server DH prime length: %d bits", 3602d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt conn->server_dh_prime_len); 3603d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 3604d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (context->event_cb) { 3605d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt union tls_event_data ev; 3606d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 3607d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt os_memset(&ev, 0, sizeof(ev)); 3608d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt ev.alert.is_local = 1; 3609d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt ev.alert.type = "fatal"; 3610d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt ev.alert.description = "insufficient security"; 3611d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt context->event_cb(context->cb_ctx, TLS_ALERT, &ev); 3612d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt } 3613d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt /* 3614d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt * Could send a TLS Alert to the server, but for now, simply 3615d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt * terminate handshake. 3616d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt */ 3617d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt conn->failed++; 3618d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt conn->write_alerts++; 3619d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt return NULL; 3620d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt } 3621d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt#endif /* CONFIG_SUITEB */ 3622d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 36238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Get the TLS handshake data to be sent to the server */ 36248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = BIO_ctrl_pending(conn->ssl_out); 36258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: %d bytes pending from ssl_out", res); 36268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out_data = wpabuf_alloc(res); 36278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (out_data == NULL) { 36288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Failed to allocate memory for " 36298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "handshake output (%d bytes)", res); 36308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (BIO_reset(conn->ssl_out) < 0) { 36318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 36328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "BIO_reset failed"); 36338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 36348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 36358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 36368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = res == 0 ? 0 : BIO_read(conn->ssl_out, wpabuf_mhead(out_data), 36378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res); 36388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 36398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 36408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Handshake failed - BIO_read"); 36418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (BIO_reset(conn->ssl_out) < 0) { 36428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 36438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "BIO_reset failed"); 36448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 36458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(out_data); 36468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 36478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 36488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put(out_data, res); 36498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return out_data; 36518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 36528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * 36558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtopenssl_get_appl_data(struct tls_connection *conn, size_t max_len) 36568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 36578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *appl_data; 36588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 36598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt appl_data = wpabuf_alloc(max_len + 100); 36618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (appl_data == NULL) 36628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 36638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = SSL_read(conn->ssl, wpabuf_mhead(appl_data), 36658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_size(appl_data)); 36668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 36678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int err = SSL_get_error(conn->ssl, res); 36688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (err == SSL_ERROR_WANT_READ || 36698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err == SSL_ERROR_WANT_WRITE) { 36708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: No Application Data " 36718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "included"); 36728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 36738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 36748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to read possible " 36758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Application Data"); 36768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 36778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(appl_data); 36788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 36798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 36808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put(appl_data, res); 36828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_buf_key(MSG_MSGDUMP, "SSL: Application Data in Finished " 36838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "message", appl_data); 36848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return appl_data; 36868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 36878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * 36908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtopenssl_connection_handshake(struct tls_connection *conn, 36918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *in_data, 36928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf **appl_data, int server) 36938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 36948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *out_data; 36958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (appl_data) 36978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *appl_data = NULL; 36988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out_data = openssl_handshake(conn, in_data, server); 37008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (out_data == NULL) 37018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 370226af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen if (conn->invalid_hb_used) { 370326af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen wpa_printf(MSG_INFO, "TLS: Heartbeat attack detected - do not send response"); 370426af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen wpabuf_free(out_data); 370526af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen return NULL; 370626af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen } 37078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3708d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (SSL_is_init_finished(conn->ssl)) { 3709d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_DEBUG, 3710d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "OpenSSL: Handshake finished - resumed=%d", 3711d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt tls_connection_resumed(conn->ssl_ctx, conn)); 3712d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (appl_data && in_data) 3713d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt *appl_data = openssl_get_appl_data(conn, 3714d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpabuf_len(in_data)); 3715d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 37168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 371726af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen if (conn->invalid_hb_used) { 371826af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen wpa_printf(MSG_INFO, "TLS: Heartbeat attack detected - do not send response"); 371926af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen if (appl_data) { 372026af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen wpabuf_free(*appl_data); 372126af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen *appl_data = NULL; 372226af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen } 372326af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen wpabuf_free(out_data); 372426af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen return NULL; 372526af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen } 372626af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen 37278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return out_data; 37288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 37298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * 37328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttls_connection_handshake(void *ssl_ctx, struct tls_connection *conn, 37338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *in_data, 37348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf **appl_data) 37358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 37368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return openssl_connection_handshake(conn, in_data, appl_data, 0); 37378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 37388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * tls_connection_server_handshake(void *tls_ctx, 37418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn, 37428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *in_data, 37438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf **appl_data) 37448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 37458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return openssl_connection_handshake(conn, in_data, appl_data, 1); 37468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 37478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * tls_connection_encrypt(void *tls_ctx, 37508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn, 37518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *in_data) 37528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 37538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 37548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 37558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 37578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 37588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Give plaintext data for OpenSSL to encrypt into the TLS tunnel. */ 37608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((res = BIO_reset(conn->ssl_in)) < 0 || 37618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (res = BIO_reset(conn->ssl_out)) < 0) { 37628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, "BIO_reset failed"); 37638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 37648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = SSL_write(conn->ssl, wpabuf_head(in_data), wpabuf_len(in_data)); 37668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 37678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 37688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Encryption failed - SSL_write"); 37698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 37708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Read encrypted data to be sent to the server */ 37738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = wpabuf_alloc(wpabuf_len(in_data) + 300); 37748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 37758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 37768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = BIO_read(conn->ssl_out, wpabuf_mhead(buf), wpabuf_size(buf)); 37778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 37788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 37798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Encryption failed - BIO_read"); 37808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(buf); 37818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 37828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put(buf, res); 37848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 37868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 37878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * tls_connection_decrypt(void *tls_ctx, 37908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn, 37918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *in_data) 37928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 37938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 37948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 37958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Give encrypted data from TLS tunnel for OpenSSL to decrypt. */ 37978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = BIO_write(conn->ssl_in, wpabuf_head(in_data), 37988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_len(in_data)); 37998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 38008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 38018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Decryption failed - BIO_write"); 38028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 38038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (BIO_reset(conn->ssl_out) < 0) { 38058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, "BIO_reset failed"); 38068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 38078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Read decrypted data for further processing */ 38108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 38118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Even though we try to disable TLS compression, it is possible that 38128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * this cannot be done with all TLS libraries. Add extra buffer space 38138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to handle the possibility of the decrypted data being longer than 38148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * input data. 38158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 38168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3); 38178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 38188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 38198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = SSL_read(conn->ssl, wpabuf_mhead(buf), wpabuf_size(buf)); 38208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 38218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 38228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Decryption failed - SSL_read"); 38238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(buf); 38248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 38258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put(buf, res); 38278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 382826af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen if (conn->invalid_hb_used) { 382926af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen wpa_printf(MSG_INFO, "TLS: Heartbeat attack detected - do not send response"); 383026af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen wpabuf_free(buf); 383126af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen return NULL; 383226af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen } 383326af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen 38348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 38358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 38368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_resumed(void *ssl_ctx, struct tls_connection *conn) 38398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3840216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return conn ? SSL_cache_hit(conn->ssl) : 0; 38418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 38428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn, 38458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *ciphers) 38468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3847de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt char buf[500], *pos, *end; 38488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *c; 38498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 38508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL || conn->ssl == NULL || ciphers == NULL) 38528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 38538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[0] = '\0'; 38558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = buf; 38568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + sizeof(buf); 38578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt c = ciphers; 38598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (*c != TLS_CIPHER_NONE) { 38608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *suite; 38618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (*c) { 38638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TLS_CIPHER_RC4_SHA: 38648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suite = "RC4-SHA"; 38658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 38668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TLS_CIPHER_AES128_SHA: 38678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suite = "AES128-SHA"; 38688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 38698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TLS_CIPHER_RSA_DHE_AES128_SHA: 38708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suite = "DHE-RSA-AES128-SHA"; 38718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 38728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TLS_CIPHER_ANON_DH_AES128_SHA: 38738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suite = "ADH-AES128-SHA"; 38748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3875de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt case TLS_CIPHER_RSA_DHE_AES256_SHA: 3876de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt suite = "DHE-RSA-AES256-SHA"; 3877de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt break; 3878de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt case TLS_CIPHER_AES256_SHA: 3879de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt suite = "AES256-SHA"; 3880de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt break; 38818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 38828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Unsupported " 38838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "cipher selection: %d", *c); 38848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 38858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, ":%s", suite); 38876c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(end - pos, ret)) 38888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 38898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 38908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt c++; 38928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 38938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: cipher suites: %s", buf + 1); 38958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3896d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) 3897d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) 3898d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (os_strstr(buf, ":ADH-")) { 3899d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt /* 3900d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * Need to drop to security level 0 to allow anonymous 3901d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * cipher suites for EAP-FAST. 3902d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt */ 3903d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_set_security_level(conn->ssl, 0); 3904d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } else if (SSL_get_security_level(conn->ssl) == 0) { 3905d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt /* Force at least security level 1 */ 3906d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_set_security_level(conn->ssl, 1); 3907d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 3908d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */ 3909d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif 3910d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 39118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_set_cipher_list(conn->ssl, buf + 1) != 1) { 39128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 39138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Cipher suite configuration failed"); 39148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 39158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 39168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 39188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 39198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3921d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtint tls_get_version(void *ssl_ctx, struct tls_connection *conn, 3922d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt char *buf, size_t buflen) 3923d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 3924d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const char *name; 3925d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (conn == NULL || conn->ssl == NULL) 3926d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return -1; 3927d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3928d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt name = SSL_get_version(conn->ssl); 3929d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (name == NULL) 3930d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return -1; 3931d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3932d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt os_strlcpy(buf, name, buflen); 3933d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return 0; 3934d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 3935d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3936d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 39378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_get_cipher(void *ssl_ctx, struct tls_connection *conn, 39388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *buf, size_t buflen) 39398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 39408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *name; 39418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL || conn->ssl == NULL) 39428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 39438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name = SSL_get_cipher(conn->ssl); 39458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (name == NULL) 39468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 39478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(buf, name, buflen); 39498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 39508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 39518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_enable_workaround(void *ssl_ctx, 39548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn) 39558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 39568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_options(conn->ssl, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS); 39578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 39598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 39608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) 39638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* ClientHello TLS extensions require a patch to openssl, so this function is 39648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * commented out unless explicitly needed for EAP-FAST in order to be able to 39658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * build this file with unmodified openssl. */ 39668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_client_hello_ext(void *ssl_ctx, struct tls_connection *conn, 39678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ext_type, const u8 *data, 39688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t data_len) 39698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 39708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL || conn->ssl == NULL || ext_type != 35) 39718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 39728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_set_session_ticket_ext(conn->ssl, (void *) data, 39748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data_len) != 1) 39758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 39768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 39788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 39798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */ 39808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_get_failed(void *ssl_ctx, struct tls_connection *conn) 39838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 39848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 39858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 39868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return conn->failed; 39878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 39888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_get_read_alerts(void *ssl_ctx, struct tls_connection *conn) 39918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 39928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 39938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 39948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return conn->read_alerts; 39958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 39968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_get_write_alerts(void *ssl_ctx, struct tls_connection *conn) 39998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 40008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 40018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 40028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return conn->write_alerts; 40038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 40048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 400634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#ifdef HAVE_OCSP 400734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 400834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidtstatic void ocsp_debug_print_resp(OCSP_RESPONSE *rsp) 400934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt{ 401034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#ifndef CONFIG_NO_STDOUT_DEBUG 401134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt BIO *out; 401234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt size_t rlen; 401334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt char *txt; 401434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt int res; 401534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 401634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (wpa_debug_level > MSG_DEBUG) 401734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return; 401834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 401934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt out = BIO_new(BIO_s_mem()); 402034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (!out) 402134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return; 402234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 402334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_RESPONSE_print(out, rsp, 0); 402434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt rlen = BIO_ctrl_pending(out); 402534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt txt = os_malloc(rlen + 1); 402634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (!txt) { 402734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt BIO_free(out); 402834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return; 402934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 403034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 403134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt res = BIO_read(out, txt, rlen); 403234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (res > 0) { 403334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt txt[res] = '\0'; 403434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: OCSP Response\n%s", txt); 403534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 403634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt os_free(txt); 403734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt BIO_free(out); 403834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#endif /* CONFIG_NO_STDOUT_DEBUG */ 403934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt} 404034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 404134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 4042717574375e969e8272c6d1a26137286eac158abbDmitry Shmidtstatic void debug_print_cert(X509 *cert, const char *title) 4043717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt{ 4044717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt#ifndef CONFIG_NO_STDOUT_DEBUG 4045717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt BIO *out; 4046717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt size_t rlen; 4047717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt char *txt; 4048717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt int res; 4049717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt 4050717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt if (wpa_debug_level > MSG_DEBUG) 4051717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt return; 4052717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt 4053717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt out = BIO_new(BIO_s_mem()); 4054717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt if (!out) 4055717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt return; 4056717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt 4057717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt X509_print(out, cert); 4058717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt rlen = BIO_ctrl_pending(out); 4059717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt txt = os_malloc(rlen + 1); 4060717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt if (!txt) { 4061717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt BIO_free(out); 4062717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt return; 4063717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt } 4064717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt 4065717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt res = BIO_read(out, txt, rlen); 4066717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt if (res > 0) { 4067717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt txt[res] = '\0'; 4068717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s\n%s", title, txt); 4069717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt } 4070717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt os_free(txt); 4071717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt 4072717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt BIO_free(out); 4073717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt#endif /* CONFIG_NO_STDOUT_DEBUG */ 4074717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt} 4075717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt 4076717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt 407734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidtstatic int ocsp_resp_cb(SSL *s, void *arg) 407834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt{ 407934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt struct tls_connection *conn = arg; 408034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt const unsigned char *p; 4081d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt int len, status, reason, res; 408234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_RESPONSE *rsp; 408334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_BASICRESP *basic; 408434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_CERTID *id; 408534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt ASN1_GENERALIZEDTIME *produced_at, *this_update, *next_update; 4086fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt X509_STORE *store; 4087fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt STACK_OF(X509) *certs = NULL; 408834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 408934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt len = SSL_get_tlsext_status_ocsp_resp(s, &p); 409034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (!p) { 409134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: No OCSP response received"); 409234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return (conn->flags & TLS_CONN_REQUIRE_OCSP) ? 0 : 1; 409334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 409434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 409534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "OpenSSL: OCSP response", p, len); 409634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 409734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt rsp = d2i_OCSP_RESPONSE(NULL, &p, len); 409834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (!rsp) { 409934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_INFO, "OpenSSL: Failed to parse OCSP response"); 410034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return 0; 410134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 410234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 410334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt ocsp_debug_print_resp(rsp); 410434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 410534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt status = OCSP_response_status(rsp); 410634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) { 410734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_INFO, "OpenSSL: OCSP responder error %d (%s)", 410834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt status, OCSP_response_status_str(status)); 410934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return 0; 411034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 411134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 411234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt basic = OCSP_response_get1_basic(rsp); 411334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (!basic) { 411434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_INFO, "OpenSSL: Could not find BasicOCSPResponse"); 411534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return 0; 411634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 411734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 4118216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt store = SSL_CTX_get_cert_store(conn->ssl_ctx); 4119fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (conn->peer_issuer) { 4120717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt debug_print_cert(conn->peer_issuer, "Add OCSP issuer"); 4121fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 4122fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (X509_STORE_add_cert(store, conn->peer_issuer) != 1) { 4123fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 41247f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt "OpenSSL: Could not add issuer to certificate store"); 4125fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 4126fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt certs = sk_X509_new_null(); 4127fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (certs) { 4128fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt X509 *cert; 4129fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt cert = X509_dup(conn->peer_issuer); 4130fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (cert && !sk_X509_push(certs, cert)) { 4131fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt tls_show_errors( 4132fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt MSG_INFO, __func__, 41337f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt "OpenSSL: Could not add issuer to OCSP responder trust store"); 4134fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt X509_free(cert); 4135fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt sk_X509_free(certs); 4136fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt certs = NULL; 4137fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 41387f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt if (certs && conn->peer_issuer_issuer) { 4139fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt cert = X509_dup(conn->peer_issuer_issuer); 4140fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (cert && !sk_X509_push(certs, cert)) { 4141fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt tls_show_errors( 4142fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt MSG_INFO, __func__, 41437f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt "OpenSSL: Could not add issuer's issuer to OCSP responder trust store"); 4144fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt X509_free(cert); 4145fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 4146fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 4147fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 4148fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 4149fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 4150fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt status = OCSP_basic_verify(basic, certs, store, OCSP_TRUSTOTHER); 4151fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt sk_X509_pop_free(certs, X509_free); 415234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (status <= 0) { 415334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 415434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt "OpenSSL: OCSP response failed verification"); 415534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_BASICRESP_free(basic); 415634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_RESPONSE_free(rsp); 415734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return 0; 415834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 415934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 416034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: OCSP response verification succeeded"); 416134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 41625605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (!conn->peer_cert) { 41635605286c30e1701491bd3af974ae423727750eddDmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Peer certificate not available for OCSP status check"); 41645605286c30e1701491bd3af974ae423727750eddDmitry Shmidt OCSP_BASICRESP_free(basic); 41655605286c30e1701491bd3af974ae423727750eddDmitry Shmidt OCSP_RESPONSE_free(rsp); 41665605286c30e1701491bd3af974ae423727750eddDmitry Shmidt return 0; 41675605286c30e1701491bd3af974ae423727750eddDmitry Shmidt } 41685605286c30e1701491bd3af974ae423727750eddDmitry Shmidt 41695605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (!conn->peer_issuer) { 41705605286c30e1701491bd3af974ae423727750eddDmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Peer issuer certificate not available for OCSP status check"); 417134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_BASICRESP_free(basic); 417234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_RESPONSE_free(rsp); 417334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return 0; 417434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 417534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 4176d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt id = OCSP_cert_to_id(EVP_sha256(), conn->peer_cert, conn->peer_issuer); 417734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (!id) { 4178d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt wpa_printf(MSG_DEBUG, 4179d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt "OpenSSL: Could not create OCSP certificate identifier (SHA256)"); 418034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_BASICRESP_free(basic); 418134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_RESPONSE_free(rsp); 418234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return 0; 418334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 418434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 4185d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt res = OCSP_resp_find_status(basic, id, &status, &reason, &produced_at, 4186d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt &this_update, &next_update); 4187d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (!res) { 4188d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt id = OCSP_cert_to_id(NULL, conn->peer_cert, conn->peer_issuer); 4189d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (!id) { 4190d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt wpa_printf(MSG_DEBUG, 4191d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt "OpenSSL: Could not create OCSP certificate identifier (SHA1)"); 4192d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt OCSP_BASICRESP_free(basic); 4193d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt OCSP_RESPONSE_free(rsp); 4194d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt return 0; 4195d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt } 4196d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 4197d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt res = OCSP_resp_find_status(basic, id, &status, &reason, 4198d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt &produced_at, &this_update, 4199d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt &next_update); 4200d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt } 4201d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 4202d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (!res) { 420334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_INFO, "OpenSSL: Could not find current server certificate from OCSP response%s", 420434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt (conn->flags & TLS_CONN_REQUIRE_OCSP) ? "" : 420534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt " (OCSP not required)"); 420657c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt OCSP_CERTID_free(id); 420734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_BASICRESP_free(basic); 420834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_RESPONSE_free(rsp); 420934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return (conn->flags & TLS_CONN_REQUIRE_OCSP) ? 0 : 1; 421034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 421157c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt OCSP_CERTID_free(id); 421234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 421334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (!OCSP_check_validity(this_update, next_update, 5 * 60, -1)) { 421434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 421534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt "OpenSSL: OCSP status times invalid"); 421634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_BASICRESP_free(basic); 421734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_RESPONSE_free(rsp); 421834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return 0; 421934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 422034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 422134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_BASICRESP_free(basic); 422234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_RESPONSE_free(rsp); 422334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 422434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status for server certificate: %s", 422534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_cert_status_str(status)); 422634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 422734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (status == V_OCSP_CERTSTATUS_GOOD) 422834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return 1; 422934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (status == V_OCSP_CERTSTATUS_REVOKED) 423034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return 0; 423134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (conn->flags & TLS_CONN_REQUIRE_OCSP) { 423234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status unknown, but OCSP required"); 423334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return 0; 423434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 4235051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status unknown, but OCSP was not required, so allow connection to continue"); 423634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return 1; 423734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt} 423834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 423934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 424034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidtstatic int ocsp_status_cb(SSL *s, void *arg) 424134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt{ 424234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt char *tmp; 424334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt char *resp; 424434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt size_t len; 424534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 424634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (tls_global->ocsp_stapling_response == NULL) { 424734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status callback - no response configured"); 424834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return SSL_TLSEXT_ERR_OK; 424934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 425034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 425134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt resp = os_readfile(tls_global->ocsp_stapling_response, &len); 425234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (resp == NULL) { 425334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status callback - could not read response file"); 425434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt /* TODO: Build OCSPResponse with responseStatus = internalError 425534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt */ 425634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return SSL_TLSEXT_ERR_OK; 425734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 425834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status callback - send cached response"); 425934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt tmp = OPENSSL_malloc(len); 426034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (tmp == NULL) { 426134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt os_free(resp); 426234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return SSL_TLSEXT_ERR_ALERT_FATAL; 426334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 426434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 426534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt os_memcpy(tmp, resp, len); 426634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt os_free(resp); 426734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt SSL_set_tlsext_status_ocsp_resp(s, tmp, len); 426834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 426934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return SSL_TLSEXT_ERR_OK; 427034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt} 427134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 427234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#endif /* HAVE_OCSP */ 427334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 427434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 42758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_set_params(void *tls_ctx, struct tls_connection *conn, 42768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct tls_connection_params *params) 42778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4278d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct tls_data *data = tls_ctx; 42798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 42808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned long err; 42816c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt int can_pkcs11 = 0; 42826c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt const char *key_id = params->key_id; 42836c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt const char *cert_id = params->cert_id; 42846c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt const char *ca_cert_id = params->ca_cert_id; 42856c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt const char *engine_id = params->engine ? params->engine_id : NULL; 42868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 42888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 42898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4290014a3ff83915745d57480e99b47e281a82143c79Dmitry Shmidt if (params->flags & TLS_CONN_REQUIRE_OCSP_ALL) { 4291014a3ff83915745d57480e99b47e281a82143c79Dmitry Shmidt wpa_printf(MSG_INFO, 4292014a3ff83915745d57480e99b47e281a82143c79Dmitry Shmidt "OpenSSL: ocsp=3 not supported"); 4293014a3ff83915745d57480e99b47e281a82143c79Dmitry Shmidt return -1; 4294014a3ff83915745d57480e99b47e281a82143c79Dmitry Shmidt } 4295014a3ff83915745d57480e99b47e281a82143c79Dmitry Shmidt 42966c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* 42976c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * If the engine isn't explicitly configured, and any of the 42986c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * cert/key fields are actually PKCS#11 URIs, then automatically 42996c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * use the PKCS#11 ENGINE. 43006c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt */ 43016c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!engine_id || os_strcmp(engine_id, "pkcs11") == 0) 43026c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt can_pkcs11 = 1; 43036c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 43046c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!key_id && params->private_key && can_pkcs11 && 43056c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_strncmp(params->private_key, "pkcs11:", 7) == 0) { 43066c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt can_pkcs11 = 2; 43076c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt key_id = params->private_key; 43086c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 43096c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 43106c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!cert_id && params->client_cert && can_pkcs11 && 43116c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_strncmp(params->client_cert, "pkcs11:", 7) == 0) { 43126c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt can_pkcs11 = 2; 43136c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt cert_id = params->client_cert; 43146c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 43156c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 43166c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!ca_cert_id && params->ca_cert && can_pkcs11 && 43176c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_strncmp(params->ca_cert, "pkcs11:", 7) == 0) { 43186c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt can_pkcs11 = 2; 43196c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ca_cert_id = params->ca_cert; 43206c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 43216c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 43226c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* If we need to automatically enable the PKCS#11 ENGINE, do so. */ 43236c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (can_pkcs11 == 2 && !engine_id) 43246c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt engine_id = "pkcs11"; 43256c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 4326d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) 43279839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) 43286c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (params->flags & TLS_CONN_EAP_FAST) { 43296c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, 43306c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "OpenSSL: Use TLSv1_method() for EAP-FAST"); 43316c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (SSL_set_ssl_method(conn->ssl, TLSv1_method()) != 1) { 43326c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt tls_show_errors(MSG_INFO, __func__, 43336c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "Failed to set TLSv1_method() for EAP-FAST"); 43346c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return -1; 43356c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 43366c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 4337d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif 4338d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */ 43396c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 43408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while ((err = ERR_get_error())) { 43418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "%s: Clearing pending SSL error: %s", 43428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__, ERR_error_string(err, NULL)); 43438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 43448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43456c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (engine_id) { 43468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Initializing TLS engine"); 43476c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ret = tls_engine_init(conn, engine_id, params->pin, 43486c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt key_id, cert_id, ca_cert_id); 43498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret) 43508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 43518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 43528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_connection_set_subject_match(conn, 43538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->subject_match, 4354051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt params->altsubject_match, 43552f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt params->suffix_match, 43562f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt params->domain_match)) 43578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 43588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43596c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (engine_id && ca_cert_id) { 4360d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (tls_connection_engine_ca_cert(data, conn, ca_cert_id)) 43618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED; 4362d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } else if (tls_connection_ca_cert(data, conn, params->ca_cert, 43638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->ca_cert_blob, 43648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->ca_cert_blob_len, 43658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->ca_path)) 43668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 43678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (engine_id && cert_id) { 43696c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (tls_connection_engine_client_cert(conn, cert_id)) 43708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED; 43718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (tls_connection_client_cert(conn, params->client_cert, 43728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->client_cert_blob, 43738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->client_cert_blob_len)) 43748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 43758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43766c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (engine_id && key_id) { 43778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Using private key from engine"); 43788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_connection_engine_private_key(conn)) 43798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED; 4380d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } else if (tls_connection_private_key(data, conn, 43818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->private_key, 43828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->private_key_passwd, 43838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->private_key_blob, 43848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->private_key_blob_len)) { 43858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to load private key '%s'", 43868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->private_key); 43878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 43888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 43898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_connection_dh(conn, params->dh_file)) { 43918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to load DH file '%s'", 43928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->dh_file); 43938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 43948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 43958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43966c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (params->openssl_ciphers && 43976c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt SSL_set_cipher_list(conn->ssl, params->openssl_ciphers) != 1) { 43986c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_INFO, 43996c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "OpenSSL: Failed to set cipher string '%s'", 44006c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt params->openssl_ciphers); 44016c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return -1; 44026c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 44036c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 4404d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (tls_set_conn_flags(conn, params->flags) < 0) 4405d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt return -1; 440613ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt 4407d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#ifdef OPENSSL_IS_BORINGSSL 4408d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (params->flags & TLS_CONN_REQUEST_OCSP) { 4409d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_enable_ocsp_stapling(conn->ssl); 4410d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 4411d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#else /* OPENSSL_IS_BORINGSSL */ 441234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#ifdef HAVE_OCSP 441334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (params->flags & TLS_CONN_REQUEST_OCSP) { 4414d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX *ssl_ctx = data->ssl; 441534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt SSL_set_tlsext_status_type(conn->ssl, TLSEXT_STATUSTYPE_ocsp); 441634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt SSL_CTX_set_tlsext_status_cb(ssl_ctx, ocsp_resp_cb); 441734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt SSL_CTX_set_tlsext_status_arg(ssl_ctx, conn); 441834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 4419d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#else /* HAVE_OCSP */ 4420d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (params->flags & TLS_CONN_REQUIRE_OCSP) { 4421d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_INFO, 4422d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "OpenSSL: No OCSP support included - reject configuration"); 4423d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return -1; 4424d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 4425d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (params->flags & TLS_CONN_REQUEST_OCSP) { 4426d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_DEBUG, 4427d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "OpenSSL: No OCSP support included - allow optional OCSP case to continue"); 4428d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 442934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#endif /* HAVE_OCSP */ 4430d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* OPENSSL_IS_BORINGSSL */ 443134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 4432c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt conn->flags = params->flags; 4433c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt 4434d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt tls_get_errors(data); 44358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 44378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 44388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_global_set_params(void *tls_ctx, 44418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct tls_connection_params *params) 44428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4443d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct tls_data *data = tls_ctx; 4444d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_CTX *ssl_ctx = data->ssl; 44458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned long err; 44468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while ((err = ERR_get_error())) { 44488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "%s: Clearing pending SSL error: %s", 44498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__, ERR_error_string(err, NULL)); 44508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 44518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4452d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (tls_global_ca_cert(data, params->ca_cert) || 4453d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt tls_global_client_cert(data, params->client_cert) || 4454d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt tls_global_private_key(data, params->private_key, 4455d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt params->private_key_passwd) || 4456d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt tls_global_dh(data, params->dh_file)) { 4457d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to set global parameters"); 44588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 44598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 44608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44616c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (params->openssl_ciphers && 44626c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt SSL_CTX_set_cipher_list(ssl_ctx, params->openssl_ciphers) != 1) { 44636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_INFO, 44646c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "OpenSSL: Failed to set cipher string '%s'", 44656c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt params->openssl_ciphers); 44666c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return -1; 44676c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 44686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 446961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef SSL_OP_NO_TICKET 447061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (params->flags & TLS_CONN_DISABLE_SESSION_TICKET) 447161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TICKET); 447261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt else 447361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt SSL_CTX_clear_options(ssl_ctx, SSL_OP_NO_TICKET); 447461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* SSL_OP_NO_TICKET */ 447561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 447634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#ifdef HAVE_OCSP 447734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt SSL_CTX_set_tlsext_status_cb(ssl_ctx, ocsp_status_cb); 447834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt SSL_CTX_set_tlsext_status_arg(ssl_ctx, ssl_ctx); 447934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt os_free(tls_global->ocsp_stapling_response); 448034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (params->ocsp_stapling_response) 448134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt tls_global->ocsp_stapling_response = 448234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt os_strdup(params->ocsp_stapling_response); 448334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt else 448434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt tls_global->ocsp_stapling_response = NULL; 448534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#endif /* HAVE_OCSP */ 448634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 44878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 44888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 44898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) 44928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Pre-shared secred requires a patch to openssl, so this function is 44938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * commented out unless explicitly needed for EAP-FAST in order to be able to 44948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * build this file with unmodified openssl. */ 44958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44961d6bf427f4769edb60865a3999d01eeb8f8fcb19Dmitry Shmidt#if (defined(OPENSSL_IS_BORINGSSL) || OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER) 44979ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidtstatic int tls_sess_sec_cb(SSL *s, void *secret, int *secret_len, 44989ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt STACK_OF(SSL_CIPHER) *peer_ciphers, 44999ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt const SSL_CIPHER **cipher, void *arg) 45009ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt#else /* OPENSSL_IS_BORINGSSL */ 45018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_sess_sec_cb(SSL *s, void *secret, int *secret_len, 45028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt STACK_OF(SSL_CIPHER) *peer_ciphers, 45038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CIPHER **cipher, void *arg) 45049ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt#endif /* OPENSSL_IS_BORINGSSL */ 45058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 45068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn = arg; 45078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 45088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4509d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) 45108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL || conn->session_ticket_cb == NULL) 45118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 45128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = conn->session_ticket_cb(conn->session_ticket_cb_ctx, 45148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket, 45158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket_len, 45168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->s3->client_random, 45178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->s3->server_random, secret); 4518d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#else 4519d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt unsigned char client_random[SSL3_RANDOM_SIZE]; 4520d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt unsigned char server_random[SSL3_RANDOM_SIZE]; 4521d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 4522d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (conn == NULL || conn->session_ticket_cb == NULL) 4523d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return 0; 4524d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 4525d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_get_client_random(s, client_random, sizeof(client_random)); 4526d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_get_server_random(s, server_random, sizeof(server_random)); 4527d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 4528d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ret = conn->session_ticket_cb(conn->session_ticket_cb_ctx, 4529d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt conn->session_ticket, 4530d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt conn->session_ticket_len, 4531d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt client_random, 4532d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt server_random, secret); 4533d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif 4534d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 45358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->session_ticket); 45368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket = NULL; 45378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret <= 0) 45398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 45408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *secret_len = SSL_MAX_MASTER_KEY_LENGTH; 45428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 45438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 45448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_session_ticket_ext_cb(SSL *s, const unsigned char *data, 45478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len, void *arg) 45488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 45498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn = arg; 45508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL || conn->session_ticket_cb == NULL) 45528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 45538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s: length=%d", __func__, len); 45558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->session_ticket); 45578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket = NULL; 45588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "OpenSSL: ClientHello SessionTicket " 45608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "extension", data, len); 45618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4562d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt conn->session_ticket = os_memdup(data, len); 45638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->session_ticket == NULL) 45648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 45658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket_len = len; 45678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 45698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 45708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */ 45718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_set_session_ticket_cb(void *tls_ctx, 45748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn, 45758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_session_ticket_cb cb, 45768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *ctx) 45778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 45788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) 45798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket_cb = cb; 45808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket_cb_ctx = ctx; 45818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cb) { 45838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_set_session_secret_cb(conn->ssl, tls_sess_sec_cb, 45848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn) != 1) 45858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 45868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_session_ticket_ext_cb(conn->ssl, 45878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_session_ticket_ext_cb, conn); 45888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 45898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_set_session_secret_cb(conn->ssl, NULL, NULL) != 1) 45908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 45918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_session_ticket_ext_cb(conn->ssl, NULL, NULL); 45928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 45938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 45958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */ 45968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 45978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */ 45988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4599ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 4600ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 4601ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidtint tls_get_library_version(char *buf, size_t buf_len) 4602ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt{ 46031d6bf427f4769edb60865a3999d01eeb8f8fcb19Dmitry Shmidt#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) 4604d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt return os_snprintf(buf, buf_len, "OpenSSL build=%s run=%s", 4605d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt OPENSSL_VERSION_TEXT, 4606d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt OpenSSL_version(OPENSSL_VERSION)); 4607d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt#else 4608ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return os_snprintf(buf, buf_len, "OpenSSL build=%s run=%s", 4609ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt OPENSSL_VERSION_TEXT, 4610ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt SSLeay_version(SSLEAY_VERSION)); 4611d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt#endif 4612ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt} 4613d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 4614d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 4615d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtvoid tls_connection_set_success_data(struct tls_connection *conn, 4616d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct wpabuf *data) 4617d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 4618d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_SESSION *sess; 4619d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct wpabuf *old; 4620d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 4621d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (tls_ex_idx_session < 0) 4622d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt goto fail; 4623d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt sess = SSL_get_session(conn->ssl); 4624d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!sess) 4625d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt goto fail; 4626d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt old = SSL_SESSION_get_ex_data(sess, tls_ex_idx_session); 4627d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (old) { 4628d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Replacing old success data %p", 4629d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt old); 4630d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpabuf_free(old); 4631d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 4632d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (SSL_SESSION_set_ex_data(sess, tls_ex_idx_session, data) != 1) 4633d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt goto fail; 4634d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 4635d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Stored success data %p", data); 4636d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt conn->success_data = 1; 4637d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return; 4638d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 4639d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtfail: 4640d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_INFO, "OpenSSL: Failed to store success data"); 4641d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpabuf_free(data); 4642d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 4643d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 4644d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 4645d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtvoid tls_connection_set_success_data_resumed(struct tls_connection *conn) 4646d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 4647d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_DEBUG, 4648d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "OpenSSL: Success data accepted for resumed session"); 4649d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt conn->success_data = 1; 4650d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 4651d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 4652d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 4653d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtconst struct wpabuf * 4654d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidttls_connection_get_success_data(struct tls_connection *conn) 4655d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 4656d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_SESSION *sess; 4657d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 4658d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (tls_ex_idx_session < 0 || 4659d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt !(sess = SSL_get_session(conn->ssl))) 4660d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return NULL; 4661d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return SSL_SESSION_get_ex_data(sess, tls_ex_idx_session); 4662d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 4663d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 4664d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 4665d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtvoid tls_connection_remove_session(struct tls_connection *conn) 4666d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 4667d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt SSL_SESSION *sess; 4668d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 4669d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt sess = SSL_get_session(conn->ssl); 4670d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!sess) 4671d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return; 4672d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 4673d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (SSL_CTX_remove_session(conn->ssl_ctx, sess) != 1) 4674d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_DEBUG, 4675d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "OpenSSL: Session was not cached"); 4676d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt else 4677d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_DEBUG, 4678d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "OpenSSL: Removed cached session to disable session resumption"); 4679d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 4680