18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SSL/TLS interface functions for OpenSSL 334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt * Copyright (c) 2004-2013, 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> 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <openssl/pkcs12.h> 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <openssl/x509v3.h> 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_ENGINE 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <openssl/engine.h> 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto.h" 29af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt#include "sha1.h" 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "tls.h" 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 329ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt#if OPENSSL_VERSION_NUMBER < 0x10000000L 339ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt/* ERR_remove_thread_state replaces ERR_remove_state and the latter is 349ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt * deprecated. However, OpenSSL 0.9.8 doesn't include 359ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt * ERR_remove_thread_state. */ 369ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt#define ERR_remove_thread_state(tid) ERR_remove_state(0) 379ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt#endif 389ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt 399ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt#if defined(OPENSSL_IS_BORINGSSL) 409ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt/* stack_index_t is the return type of OpenSSL's sk_XXX_num() functions. */ 419ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidttypedef size_t stack_index_t; 429ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt#else 439ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidttypedef int stack_index_t; 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46ff07917b8921a2a178ed9188a63b166af144ae53Dmitry Shmidt#ifdef SSL_set_tlsext_status_type 47ff07917b8921a2a178ed9188a63b166af144ae53Dmitry Shmidt#ifndef OPENSSL_NO_TLSEXT 48ff07917b8921a2a178ed9188a63b166af144ae53Dmitry Shmidt#define HAVE_OCSP 49ff07917b8921a2a178ed9188a63b166af144ae53Dmitry Shmidt#include <openssl/ocsp.h> 50ff07917b8921a2a178ed9188a63b166af144ae53Dmitry Shmidt#endif /* OPENSSL_NO_TLSEXT */ 51ff07917b8921a2a178ed9188a63b166af144ae53Dmitry Shmidt#endif /* SSL_set_tlsext_status_type */ 52ff07917b8921a2a178ed9188a63b166af144ae53Dmitry Shmidt 533f3ca3bb849b192d41b99aae775f6fc52f67118dKenny Root#ifdef ANDROID 543f3ca3bb849b192d41b99aae775f6fc52f67118dKenny Root#include <openssl/pem.h> 553f3ca3bb849b192d41b99aae775f6fc52f67118dKenny Root#include <keystore/keystore_get.h> 563f3ca3bb849b192d41b99aae775f6fc52f67118dKenny Root 573f3ca3bb849b192d41b99aae775f6fc52f67118dKenny Rootstatic BIO * BIO_from_keystore(const char *key) 583f3ca3bb849b192d41b99aae775f6fc52f67118dKenny Root{ 59ff07917b8921a2a178ed9188a63b166af144ae53Dmitry Shmidt BIO *bio = NULL; 60ff07917b8921a2a178ed9188a63b166af144ae53Dmitry Shmidt uint8_t *value = NULL; 61ff07917b8921a2a178ed9188a63b166af144ae53Dmitry Shmidt int length = keystore_get(key, strlen(key), &value); 62ff07917b8921a2a178ed9188a63b166af144ae53Dmitry Shmidt if (length != -1 && (bio = BIO_new(BIO_s_mem())) != NULL) 63ff07917b8921a2a178ed9188a63b166af144ae53Dmitry Shmidt BIO_write(bio, value, length); 64ff07917b8921a2a178ed9188a63b166af144ae53Dmitry Shmidt free(value); 65ff07917b8921a2a178ed9188a63b166af144ae53Dmitry Shmidt return bio; 663f3ca3bb849b192d41b99aae775f6fc52f67118dKenny Root} 671eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley 683f3ca3bb849b192d41b99aae775f6fc52f67118dKenny Root#endif /* ANDROID */ 693f3ca3bb849b192d41b99aae775f6fc52f67118dKenny Root 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_openssl_ref_count = 0; 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 72ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidtstruct tls_context { 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void (*event_cb)(void *ctx, enum tls_event ev, 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union tls_event_data *data); 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *cb_ctx; 761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int cert_in_cb; 7734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt char *ocsp_stapling_response; 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 80ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidtstatic struct tls_context *tls_global = NULL; 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct tls_connection { 84ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt struct tls_context *context; 85216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt SSL_CTX *ssl_ctx; 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL *ssl; 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO *ssl_in, *ssl_out; 881eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley#if defined(ANDROID) || !defined(OPENSSL_NO_ENGINE) 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE *engine; /* functional reference to the engine */ 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EVP_PKEY *private_key; /* the private key if using engine */ 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 922f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt char *subject_match, *altsubject_match, *suffix_match, *domain_match; 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int read_alerts, write_alerts, failed; 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_session_ticket_cb session_ticket_cb; 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *session_ticket_cb_ctx; 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* SessionTicket received from OpenSSL hello_extension_cb (server) */ 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *session_ticket; 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t session_ticket_len; 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int ca_cert_verify:1; 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int cert_probe:1; 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int server_cert_only:1; 10526af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen unsigned int invalid_hb_used:1; 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 srv_cert_hash[32]; 108c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt 109c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt unsigned int flags; 11034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 11134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt X509 *peer_cert; 11234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt X509 *peer_issuer; 113fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt X509 *peer_issuer_issuer; 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 117ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidtstatic struct tls_context * tls_context_new(const struct tls_config *conf) 118ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt{ 119ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt struct tls_context *context = os_zalloc(sizeof(*context)); 120ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt if (context == NULL) 121ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt return NULL; 122ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt if (conf) { 123ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt context->event_cb = conf->event_cb; 124ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt context->cb_ctx = conf->cb_ctx; 125ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt context->cert_in_cb = conf->cert_in_cb; 126ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt } 127ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt return context; 128ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt} 129ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt 130ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_NO_STDOUT_DEBUG 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void _tls_show_errors(void) 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned long err; 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while ((err = ERR_get_error())) { 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Just ignore the errors, since stdout is disabled */ 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define tls_show_errors(l, f, t) _tls_show_errors() 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_NO_STDOUT_DEBUG */ 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void tls_show_errors(int level, const char *func, const char *txt) 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned long err; 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(level, "OpenSSL: %s - %s %s", 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt func, txt, ERR_error_string(ERR_get_error(), NULL)); 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while ((err = ERR_get_error())) { 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "OpenSSL: pending error: %s", 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(err, NULL)); 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_STDOUT_DEBUG */ 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_NATIVE_WINDOWS 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Windows CryptoAPI and access to certificate stores */ 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <wincrypt.h> 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef __MINGW32_VERSION 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * MinGW does not yet include all the needed definitions for CryptoAPI, so 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * define here whatever extra is needed. 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define CERT_SYSTEM_STORE_CURRENT_USER (1 << 16) 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define CERT_STORE_READONLY_FLAG 0x00008000 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define CERT_STORE_OPEN_EXISTING_FLAG 0x00004000 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* __MINGW32_VERSION */ 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct cryptoapi_rsa_data { 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const CERT_CONTEXT *cert; 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HCRYPTPROV crypt_prov; 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD key_spec; 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BOOL free_crypt_prov; 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void cryptoapi_error(const char *msg) 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "CryptoAPI: %s; err=%u", 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg, (unsigned int) GetLastError()); 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int cryptoapi_rsa_pub_enc(int flen, const unsigned char *from, 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char *to, RSA *rsa, int padding) 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s - not implemented", __func__); 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int cryptoapi_rsa_pub_dec(int flen, const unsigned char *from, 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char *to, RSA *rsa, int padding) 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s - not implemented", __func__); 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int cryptoapi_rsa_priv_enc(int flen, const unsigned char *from, 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char *to, RSA *rsa, int padding) 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct cryptoapi_rsa_data *priv = 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (struct cryptoapi_rsa_data *) rsa->meth->app_data; 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HCRYPTHASH hash; 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD hash_size, len, i; 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char *buf = NULL; 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = 0; 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (priv == NULL) { 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_R_PASSED_NULL_PARAMETER); 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (padding != RSA_PKCS1_PADDING) { 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSA_R_UNKNOWN_PADDING_TYPE); 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (flen != 16 /* MD5 */ + 20 /* SHA-1 */) { 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "%s - only MD5-SHA1 hash supported", 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__); 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSA_R_INVALID_MESSAGE_LENGTH); 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptCreateHash(priv->crypt_prov, CALG_SSL3_SHAMD5, 0, 0, &hash)) 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_error("CryptCreateHash failed"); 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = sizeof(hash_size); 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptGetHashParam(hash, HP_HASHSIZE, (BYTE *) &hash_size, &len, 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0)) { 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_error("CryptGetHashParam failed"); 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((int) hash_size != flen) { 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "CryptoAPI: Invalid hash size (%u != %d)", 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned) hash_size, flen); 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSA_R_INVALID_MESSAGE_LENGTH); 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptSetHashParam(hash, HP_HASHVAL, (BYTE * ) from, 0)) { 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_error("CryptSetHashParam failed"); 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = RSA_size(rsa); 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = os_malloc(len); 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) { 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE); 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptSignHash(hash, priv->key_spec, NULL, 0, buf, &len)) { 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_error("CryptSignHash failed"); 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < len; i++) 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt to[i] = buf[len - i - 1]; 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = len; 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidterr: 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CryptDestroyHash(hash); 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int cryptoapi_rsa_priv_dec(int flen, const unsigned char *from, 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char *to, RSA *rsa, int padding) 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s - not implemented", __func__); 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void cryptoapi_free_data(struct cryptoapi_rsa_data *priv) 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (priv == NULL) 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (priv->crypt_prov && priv->free_crypt_prov) 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CryptReleaseContext(priv->crypt_prov, 0); 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (priv->cert) 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CertFreeCertificateContext(priv->cert); 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(priv); 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int cryptoapi_finish(RSA *rsa) 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_free_data((struct cryptoapi_rsa_data *) rsa->meth->app_data); 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free((void *) rsa->meth); 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa->meth = NULL; 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const CERT_CONTEXT * cryptoapi_find_cert(const char *name, DWORD store) 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HCERTSTORE cs; 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const CERT_CONTEXT *ret = NULL; 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cs = CertOpenStore((LPCSTR) CERT_STORE_PROV_SYSTEM, 0, 0, 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt store | CERT_STORE_OPEN_EXISTING_FLAG | 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CERT_STORE_READONLY_FLAG, L"MY"); 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cs == NULL) { 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_error("Failed to open 'My system store'"); 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (strncmp(name, "cert://", 7) == 0) { 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned short wbuf[255]; 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MultiByteToWideChar(CP_ACP, 0, name + 7, -1, wbuf, 255); 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = CertFindCertificateInStore(cs, X509_ASN_ENCODING | 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PKCS_7_ASN_ENCODING, 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0, CERT_FIND_SUBJECT_STR, 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wbuf, NULL); 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (strncmp(name, "hash://", 7) == 0) { 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CRYPT_HASH_BLOB blob; 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len; 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *hash = name + 7; 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char *buf; 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = os_strlen(hash) / 2; 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = os_malloc(len); 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf && hexstr2bin(hash, buf, len) == 0) { 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt blob.cbData = len; 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt blob.pbData = buf; 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = CertFindCertificateInStore(cs, 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_ASN_ENCODING | 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PKCS_7_ASN_ENCODING, 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0, CERT_FIND_HASH, 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &blob, NULL); 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CertCloseStore(cs, 0); 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_cryptoapi_cert(SSL *ssl, const char *name) 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *cert = NULL; 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSA *rsa = NULL, *pub_rsa; 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct cryptoapi_rsa_data *priv; 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSA_METHOD *rsa_meth; 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (name == NULL || 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (strncmp(name, "cert://", 7) != 0 && 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt strncmp(name, "hash://", 7) != 0)) 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priv = os_zalloc(sizeof(*priv)); 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_meth = os_zalloc(sizeof(*rsa_meth)); 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (priv == NULL || rsa_meth == NULL) { 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "CryptoAPI: Failed to allocate memory " 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for CryptoAPI RSA method"); 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(priv); 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(rsa_meth); 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priv->cert = cryptoapi_find_cert(name, CERT_SYSTEM_STORE_CURRENT_USER); 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (priv->cert == NULL) { 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priv->cert = cryptoapi_find_cert( 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name, CERT_SYSTEM_STORE_LOCAL_MACHINE); 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (priv->cert == NULL) { 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "CryptoAPI: Could not find certificate " 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s'", name); 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 396216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt cert = d2i_X509(NULL, 397216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt (const unsigned char **) &priv->cert->pbCertEncoded, 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priv->cert->cbCertEncoded); 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert == NULL) { 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "CryptoAPI: Could not process X509 DER " 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "encoding"); 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptAcquireCertificatePrivateKey(priv->cert, 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CRYPT_ACQUIRE_COMPARE_KEY_FLAG, 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, &priv->crypt_prov, 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &priv->key_spec, 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &priv->free_crypt_prov)) { 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_error("Failed to acquire a private key for the " 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate"); 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_meth->name = "Microsoft CryptoAPI RSA Method"; 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_meth->rsa_pub_enc = cryptoapi_rsa_pub_enc; 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_meth->rsa_pub_dec = cryptoapi_rsa_pub_dec; 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_meth->rsa_priv_enc = cryptoapi_rsa_priv_enc; 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_meth->rsa_priv_dec = cryptoapi_rsa_priv_dec; 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_meth->finish = cryptoapi_finish; 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_meth->flags = RSA_METHOD_FLAG_NO_CHECK; 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_meth->app_data = (char *) priv; 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa = RSA_new(); 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rsa == NULL) { 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_R_MALLOC_FAILURE); 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!SSL_use_certificate(ssl, cert)) { 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSA_free(rsa); 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa = NULL; 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pub_rsa = cert->cert_info->key->pkey->pkey.rsa; 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert = NULL; 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa->n = BN_dup(pub_rsa->n); 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa->e = BN_dup(pub_rsa->e); 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!RSA_set_method(rsa, rsa_meth)) 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!SSL_use_RSAPrivateKey(ssl, rsa)) 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSA_free(rsa); 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidterr: 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert) 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rsa) 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSA_free(rsa); 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(rsa_meth); 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_free_data(priv); 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_cryptoapi_ca_cert(SSL_CTX *ssl_ctx, SSL *ssl, const char *name) 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HCERTSTORE cs; 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PCCERT_CONTEXT ctx = NULL; 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *cert; 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char buf[128]; 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *store; 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef UNICODE 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WCHAR *wstore; 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* UNICODE */ 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (name == NULL || strncmp(name, "cert_store://", 13) != 0) 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt store = name + 13; 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef UNICODE 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wstore = os_malloc((os_strlen(store) + 1) * sizeof(WCHAR)); 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wstore == NULL) 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wsprintf(wstore, L"%S", store); 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cs = CertOpenSystemStore(0, wstore); 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(wstore); 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* UNICODE */ 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cs = CertOpenSystemStore(0, store); 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* UNICODE */ 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cs == NULL) { 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: failed to open system cert store " 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s': error=%d", __func__, store, 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) GetLastError()); 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while ((ctx = CertEnumCertificatesInStore(cs, ctx))) { 497216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt cert = d2i_X509(NULL, 498216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt (const unsigned char **) &ctx->pbCertEncoded, 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->cbCertEncoded); 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert == NULL) { 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "CryptoAPI: Could not process " 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "X509 DER encoding for CA cert"); 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_NAME_oneline(X509_get_subject_name(cert), buf, 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(buf)); 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Loaded CA certificate for " 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "system certificate store: subject='%s'", buf); 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!X509_STORE_add_cert(ssl_ctx->cert_store, cert)) { 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_WARNING, __func__, 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to add ca_cert to OpenSSL " 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate store"); 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CertCloseStore(cs, 0)) { 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: failed to close system cert store " 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s': error=%d", __func__, name + 13, 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) GetLastError()); 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_NATIVE_WINDOWS */ 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_cryptoapi_cert(SSL *ssl, const char *name) 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void ssl_info_cb(const SSL *ssl, int where, int ret) 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *str; 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int w; 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: (where=0x%x ret=0x%x)", where, ret); 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt w = where & ~SSL_ST_MASK; 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (w & SSL_ST_CONNECT) 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt str = "SSL_connect"; 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (w & SSL_ST_ACCEPT) 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt str = "SSL_accept"; 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt str = "undefined"; 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (where & SSL_CB_LOOP) { 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: %s:%s", 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt str, SSL_state_string_long(ssl)); 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (where & SSL_CB_ALERT) { 558ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt struct tls_connection *conn = SSL_get_app_data((SSL *) ssl); 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "SSL: SSL3 alert: %s:%s:%s", 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt where & SSL_CB_READ ? 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "read (remote end reported an error)" : 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "write (local SSL3 detected an error)", 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_alert_type_string_long(ret), 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_alert_desc_string_long(ret)); 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((ret >> 8) == SSL3_AL_FATAL) { 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (where & SSL_CB_READ) 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->read_alerts++; 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->write_alerts++; 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 571ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt if (conn->context->event_cb != NULL) { 57204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt union tls_event_data ev; 573ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt struct tls_context *context = conn->context; 57404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memset(&ev, 0, sizeof(ev)); 57504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ev.alert.is_local = !(where & SSL_CB_READ); 57604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ev.alert.type = SSL_alert_type_string_long(ret); 57704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ev.alert.description = SSL_alert_desc_string_long(ret); 578ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt context->event_cb(context->cb_ctx, TLS_ALERT, &ev); 57904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (where & SSL_CB_EXIT && ret <= 0) { 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: %s:%s in %s", 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt str, ret == 0 ? "failed" : "error", 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_state_string_long(ssl)); 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_ENGINE 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tls_engine_load_dynamic_generic - load any openssl engine 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @pre: an array of commands and values that load an engine initialized 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * in the engine specific function 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @post: an array of commands and values that initialize an already loaded 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * engine (or %NULL if not required) 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @id: the engine id of the engine to load (only required if post is not %NULL 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is a generic function that loads any openssl engine. 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_engine_load_dynamic_generic(const char *pre[], 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *post[], const char *id) 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE *engine; 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *dynamic_id = "dynamic"; 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt engine = ENGINE_by_id(id); 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (engine) { 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE_free(engine); 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: engine '%s' is already " 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "available", id); 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_clear_error(); 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt engine = ENGINE_by_id(dynamic_id); 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (engine == NULL) { 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "ENGINE: Can't find engine %s [%s]", 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dynamic_id, 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Perform the pre commands. This will load the engine. */ 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pre && pre[0]) { 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: '%s' '%s'", pre[0], pre[1]); 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ENGINE_ctrl_cmd_string(engine, pre[0], pre[1], 0) == 0) { 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "ENGINE: ctrl cmd_string failed: " 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%s %s [%s]", pre[0], pre[1], 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE_free(engine); 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pre += 2; 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Free the reference to the "dynamic" engine. The loaded engine can 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * now be looked up using ENGINE_by_id(). 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE_free(engine); 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt engine = ENGINE_by_id(id); 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (engine == NULL) { 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "ENGINE: Can't find engine %s [%s]", 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt id, ERR_error_string(ERR_get_error(), NULL)); 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (post && post[0]) { 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: '%s' '%s'", post[0], post[1]); 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ENGINE_ctrl_cmd_string(engine, post[0], post[1], 0) == 0) { 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: ctrl cmd_string failed:" 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " %s %s [%s]", post[0], post[1], 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE_remove(engine); 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE_free(engine); 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt post += 2; 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE_free(engine); 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tls_engine_load_dynamic_pkcs11 - load the pkcs11 engine provided by opensc 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @pkcs11_so_path: pksc11_so_path from the configuration 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @pcks11_module_path: pkcs11_module_path from the configuration 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_engine_load_dynamic_pkcs11(const char *pkcs11_so_path, 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *pkcs11_module_path) 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *engine_id = "pkcs11"; 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *pre_cmd[] = { 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SO_PATH", NULL /* pkcs11_so_path */, 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ID", NULL /* engine_id */, 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "LIST_ADD", "1", 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* "NO_VCHECK", "1", */ 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "LOAD", NULL, 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, NULL 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt }; 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *post_cmd[] = { 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "MODULE_PATH", NULL /* pkcs11_module_path */, 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, NULL 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt }; 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6906c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!pkcs11_so_path) 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pre_cmd[1] = pkcs11_so_path; 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pre_cmd[3] = engine_id; 6956c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (pkcs11_module_path) 6966c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt post_cmd[1] = pkcs11_module_path; 6976c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt else 6986c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt post_cmd[0] = NULL; 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: Loading pkcs11 Engine from %s", 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pkcs11_so_path); 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_engine_load_dynamic_generic(pre_cmd, post_cmd, engine_id); 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tls_engine_load_dynamic_opensc - load the opensc engine provided by opensc 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @opensc_so_path: opensc_so_path from the configuration 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_engine_load_dynamic_opensc(const char *opensc_so_path) 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *engine_id = "opensc"; 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *pre_cmd[] = { 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SO_PATH", NULL /* opensc_so_path */, 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ID", NULL /* engine_id */, 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "LIST_ADD", "1", 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "LOAD", NULL, 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, NULL 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt }; 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!opensc_so_path) 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pre_cmd[1] = opensc_so_path; 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pre_cmd[3] = engine_id; 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: Loading OpenSC Engine from %s", 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt opensc_so_path); 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_engine_load_dynamic_generic(pre_cmd, NULL, engine_id); 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid * tls_init(const struct tls_config *conf) 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX *ssl; 739ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt struct tls_context *context; 7406c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt const char *ciphers; 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_openssl_ref_count == 0) { 743ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt tls_global = context = tls_context_new(conf); 744ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt if (context == NULL) 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_FIPS 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef OPENSSL_FIPS 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf && conf->fips_mode) { 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!FIPS_mode_set(1)) { 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to enable FIPS " 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "mode"); 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_load_crypto_strings(); 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_print_errors_fp(stderr); 75461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(tls_global); 75561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt tls_global = NULL; 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "Running in FIPS mode"); 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_FIPS */ 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf && conf->fips_mode) { 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "FIPS mode requested, but not " 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "supported"); 76461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(tls_global); 76561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt tls_global = NULL; 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_FIPS */ 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_FIPS */ 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_load_error_strings(); 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_library_init(); 772216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt#ifndef OPENSSL_NO_SHA256 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EVP_add_digest(EVP_sha256()); 7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_SHA256 */ 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: if /dev/urandom is available, PRNG is seeded 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * automatically. If this is not the case, random data should 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * be added here. */ 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef PKCS12_FUNCS 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_RC2 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 40-bit RC2 is commonly used in PKCS#12 files, so enable it. 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This is enabled by PKCS12_PBE_add() in OpenSSL 0.9.8 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * versions, but it looks like OpenSSL 1.0.0 does not do that 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * anymore. 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EVP_add_cipher(EVP_rc2_40_cbc()); 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_RC2 */ 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PKCS12_PBE_add(); 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* PKCS12_FUNCS */ 791ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt } else { 792ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt context = tls_context_new(conf); 793ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt if (context == NULL) 794ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt return NULL; 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_openssl_ref_count++; 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7986c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ssl = SSL_CTX_new(SSLv23_method()); 799ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt if (ssl == NULL) { 800ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt tls_openssl_ref_count--; 80168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (context != tls_global) 80268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt os_free(context); 803ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt if (tls_openssl_ref_count == 0) { 804ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt os_free(tls_global); 805ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt tls_global = NULL; 806ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt } 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 808ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt } 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8106c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt SSL_CTX_set_options(ssl, SSL_OP_NO_SSLv2); 8116c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt SSL_CTX_set_options(ssl, SSL_OP_NO_SSLv3); 8126c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_set_info_callback(ssl, ssl_info_cb); 814ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt SSL_CTX_set_app_data(ssl, context); 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_ENGINE 8176c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: Loading dynamic engine"); 8186c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ERR_load_ENGINE_strings(); 8196c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ENGINE_load_dynamic(); 8206c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf && 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (conf->opensc_engine_path || conf->pkcs11_engine_path || 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->pkcs11_module_path)) { 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_engine_load_dynamic_opensc(conf->opensc_engine_path) || 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_engine_load_dynamic_pkcs11(conf->pkcs11_engine_path, 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->pkcs11_module_path)) { 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_deinit(ssl); 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8336c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (conf && conf->openssl_ciphers) 8346c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ciphers = conf->openssl_ciphers; 8356c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt else 8366c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ciphers = "DEFAULT:!EXP:!LOW"; 8376c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (SSL_CTX_set_cipher_list(ssl, ciphers) != 1) { 8386c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_ERROR, 8396c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "OpenSSL: Failed to set cipher string '%s'", 8406c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ciphers); 8416c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt tls_deinit(ssl); 8426c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return NULL; 8436c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 8446c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ssl; 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid tls_deinit(void *ssl_ctx) 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX *ssl = ssl_ctx; 852ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt struct tls_context *context = SSL_CTX_get_app_data(ssl); 853ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt if (context != tls_global) 854ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt os_free(context); 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_free(ssl); 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_openssl_ref_count--; 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_openssl_ref_count == 0) { 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_ENGINE 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE_cleanup(); 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CRYPTO_cleanup_all_ex_data(); 8639ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt ERR_remove_thread_state(NULL); 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_free_strings(); 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EVP_cleanup(); 86634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt os_free(tls_global->ocsp_stapling_response); 86734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt tls_global->ocsp_stapling_response = NULL; 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(tls_global); 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_global = NULL; 8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8731eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley#ifdef ANDROID 8741eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley/* EVP_PKEY_from_keystore comes from system/security/keystore-engine. */ 8751eb02edb319d462031f0c2f1f3548498558e95a5Adam LangleyEVP_PKEY* EVP_PKEY_from_keystore(const char* key_id); 8761eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley#endif 8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8781d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt#ifndef OPENSSL_NO_ENGINE 8791d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt 8801d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt/* Cryptoki return values */ 8811d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt#define CKR_PIN_INCORRECT 0x000000a0 8821d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt#define CKR_PIN_INVALID 0x000000a1 8831d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt#define CKR_PIN_LEN_RANGE 0x000000a2 8841d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt 8851d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt/* libp11 */ 8861d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt#define ERR_LIB_PKCS11 ERR_LIB_USER 8871d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt 8881d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidtstatic int tls_is_pin_error(unsigned int err) 8891d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt{ 8901d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt return ERR_GET_LIB(err) == ERR_LIB_PKCS11 && 8911d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt (ERR_GET_REASON(err) == CKR_PIN_INCORRECT || 8921d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt ERR_GET_REASON(err) == CKR_PIN_INVALID || 8931d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt ERR_GET_REASON(err) == CKR_PIN_LEN_RANGE); 8941d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt} 8951d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt 8961d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 8971d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt 8981d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_engine_init(struct tls_connection *conn, const char *engine_id, 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *pin, const char *key_id, 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *cert_id, const char *ca_cert_id) 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9031eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley#if defined(ANDROID) && defined(OPENSSL_IS_BORINGSSL) 9041eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley#if !defined(OPENSSL_NO_ENGINE) 9051eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley#error "This code depends on OPENSSL_NO_ENGINE being defined by BoringSSL." 9061eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley#endif 9071eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley 9081eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley conn->engine = NULL; 9091eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley conn->private_key = EVP_PKEY_from_keystore(key_id); 9101eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley if (!conn->private_key) { 9111eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley wpa_printf(MSG_ERROR, 9121eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley "ENGINE: cannot load private key with id '%s' [%s]", 9131eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley key_id, 9141eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley ERR_error_string(ERR_get_error(), NULL)); 9151eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley return TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED; 9161eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley } 9171eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley#endif 9181eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_ENGINE 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = -1; 9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (engine_id == NULL) { 9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "ENGINE: Engine ID not set"); 9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_clear_error(); 927db3c5a43353099fd4771f3b7a13efae905878ce9Kenny Root#ifdef ANDROID 928db3c5a43353099fd4771f3b7a13efae905878ce9Kenny Root ENGINE_load_dynamic(); 929db3c5a43353099fd4771f3b7a13efae905878ce9Kenny Root#endif 9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->engine = ENGINE_by_id(engine_id); 9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!conn->engine) { 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "ENGINE: engine %s not available [%s]", 9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt engine_id, ERR_error_string(ERR_get_error(), NULL)); 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ENGINE_init(conn->engine) != 1) { 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "ENGINE: engine init failed " 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(engine: %s) [%s]", engine_id, 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: engine initialized"); 9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 944db3c5a43353099fd4771f3b7a13efae905878ce9Kenny Root#ifndef ANDROID 9456c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (pin && ENGINE_ctrl_cmd_string(conn->engine, "PIN", pin, 0) == 0) { 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "ENGINE: cannot set pin [%s]", 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 950db3c5a43353099fd4771f3b7a13efae905878ce9Kenny Root#endif 9516c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (key_id) { 9526c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* 9536c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * Ensure that the ENGINE does not attempt to use the OpenSSL 9546c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * UI system to obtain a PIN, if we didn't provide one. 9556c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt */ 9566c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct { 9576c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt const void *password; 9586c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt const char *prompt_info; 9596c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } key_cb = { "", NULL }; 9606c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 9616c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* load private key first in-case PIN is required for cert */ 9626c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt conn->private_key = ENGINE_load_private_key(conn->engine, 9636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt key_id, NULL, 9646c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt &key_cb); 9656c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!conn->private_key) { 9661d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt unsigned long err = ERR_get_error(); 9671d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt 9686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_ERROR, 9696c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "ENGINE: cannot load private key with id '%s' [%s]", 9706c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt key_id, 9711d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt ERR_error_string(err, NULL)); 9721d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt if (tls_is_pin_error(err)) 9731d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt ret = TLS_SET_PARAMS_ENGINE_PRV_BAD_PIN; 9741d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt else 9751d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt ret = TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED; 9766c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt goto err; 9776c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* handle a certificate and/or CA certificate */ 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert_id || ca_cert_id) { 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *cmd_name = "LOAD_CERT_CTRL"; 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* test if the engine supports a LOAD_CERT_CTRL */ 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ENGINE_ctrl(conn->engine, ENGINE_CTRL_GET_CMD_FROM_NAME, 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0, (void *)cmd_name, NULL)) { 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "ENGINE: engine does not support" 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " loading certificates"); 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED; 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidterr: 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->engine) { 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE_free(conn->engine); 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->engine = NULL; 10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->private_key) { 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EVP_PKEY_free(conn->private_key); 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->private_key = NULL; 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_ENGINE */ 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void tls_engine_deinit(struct tls_connection *conn) 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10161eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley#if defined(ANDROID) || !defined(OPENSSL_NO_ENGINE) 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: engine deinit"); 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->private_key) { 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EVP_PKEY_free(conn->private_key); 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->private_key = NULL; 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->engine) { 10231eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley#if !defined(OPENSSL_IS_BORINGSSL) 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE_finish(conn->engine); 10251eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley#endif 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->engine = NULL; 10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_get_errors(void *ssl_ctx) 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int count = 0; 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned long err; 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while ((err = ERR_get_error())) { 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS - SSL error: %s", 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(err, NULL)); 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count++; 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return count; 10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 104626af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen 104726af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinenstatic void tls_msg_cb(int write_p, int version, int content_type, 104826af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen const void *buf, size_t len, SSL *ssl, void *arg) 104926af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen{ 105026af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen struct tls_connection *conn = arg; 105126af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen const u8 *pos = buf; 105226af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen 105326af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen wpa_printf(MSG_DEBUG, "OpenSSL: %s ver=0x%x content_type=%d", 105426af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen write_p ? "TX" : "RX", version, content_type); 105526af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen wpa_hexdump_key(MSG_MSGDUMP, "OpenSSL: Message", buf, len); 105626af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen if (content_type == 24 && len >= 3 && pos[0] == 1) { 105726af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen size_t payload_len = WPA_GET_BE16(pos + 1); 105826af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen if (payload_len + 3 > len) { 105926af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen wpa_printf(MSG_ERROR, "OpenSSL: Heartbeat attack detected"); 106026af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen conn->invalid_hb_used = 1; 106126af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen } 106226af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen } 106326af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen} 106426af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen 106526af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct tls_connection * tls_connection_init(void *ssl_ctx) 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX *ssl = ssl_ctx; 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn; 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt long options; 10717d5c8f257a74ac0d12828962a492e8b84ef83923Dmitry Shmidt struct tls_context *context = SSL_CTX_get_app_data(ssl); 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn = os_zalloc(sizeof(*conn)); 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1076216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt conn->ssl_ctx = ssl_ctx; 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ssl = SSL_new(ssl); 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->ssl == NULL) { 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to initialize new SSL connection"); 10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn); 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1085ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt conn->context = context; 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_app_data(conn->ssl, conn); 108726af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen SSL_set_msg_callback(conn->ssl, tls_msg_cb); 108826af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen SSL_set_msg_callback_arg(conn->ssl, conn); 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_OP_SINGLE_DH_USE; 10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef SSL_OP_NO_COMPRESSION 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt options |= SSL_OP_NO_COMPRESSION; 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* SSL_OP_NO_COMPRESSION */ 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_options(conn->ssl, options); 10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ssl_in = BIO_new(BIO_s_mem()); 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!conn->ssl_in) { 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to create a new BIO for ssl_in"); 11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_free(conn->ssl); 11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn); 11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ssl_out = BIO_new(BIO_s_mem()); 11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!conn->ssl_out) { 11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to create a new BIO for ssl_out"); 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_free(conn->ssl); 11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO_free(conn->ssl_in); 11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn); 11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_bio(conn->ssl, conn->ssl_in, conn->ssl_out); 11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return conn; 11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid tls_connection_deinit(void *ssl_ctx, struct tls_connection *conn) 11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_free(conn->ssl); 11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_engine_deinit(conn); 11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->subject_match); 11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->altsubject_match); 1129051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt os_free(conn->suffix_match); 11302f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt os_free(conn->domain_match); 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->session_ticket); 11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn); 11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_established(void *ssl_ctx, struct tls_connection *conn) 11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return conn ? SSL_is_init_finished(conn->ssl) : 0; 11398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_shutdown(void *ssl_ctx, struct tls_connection *conn) 11438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 11458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Shutdown previous TLS connection without notifying the peer 11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * because the connection was already terminated in practice 11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * and "close notify" shutdown alert would confuse AS. */ 11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_quiet_shutdown(conn->ssl, 1); 11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_shutdown(conn->ssl); 1152f291c682d490cef0b520b68e694a2bf97126b441Jouni Malinen return SSL_clear(conn->ssl) == 1 ? 0 : -1; 11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_match_altsubject_component(X509 *cert, int type, 11578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *value, size_t len) 11588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt GENERAL_NAME *gen; 11608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *ext; 11619ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt int found = 0; 11629ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt stack_index_t i; 11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ext = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL); 11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; ext && i < sk_GENERAL_NAME_num(ext); i++) { 11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gen = sk_GENERAL_NAME_value(ext, i); 11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (gen->type != type) 11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strlen((char *) gen->d.ia5->data) == len && 11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(value, gen->d.ia5->data, len) == 0) 11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt found++; 11738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return found; 11768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_match_altsubject(X509 *cert, const char *match) 11808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int type; 11828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *pos, *end; 11838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len; 11848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = match; 11868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt do { 11878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strncmp(pos, "EMAIL:", 6) == 0) { 11888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = GEN_EMAIL; 11898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 6; 11908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (os_strncmp(pos, "DNS:", 4) == 0) { 11918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = GEN_DNS; 11928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 4; 11938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (os_strncmp(pos, "URI:", 4) == 0) { 11948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = GEN_URI; 11958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 4; 11968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 11978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Invalid altSubjectName " 11988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "match '%s'", pos); 11998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 12008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = os_strchr(pos, ';'); 12028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (end) { 12038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strncmp(end + 1, "EMAIL:", 6) == 0 || 12048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strncmp(end + 1, "DNS:", 4) == 0 || 12058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strncmp(end + 1, "URI:", 4) == 0) 12068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = os_strchr(end + 1, ';'); 12088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end) 12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = end - pos; 12118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 12128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = os_strlen(pos); 12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_match_altsubject_component(cert, type, pos, len) > 0) 12148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 12158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = end + 1; 12168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } while (end); 12178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 12198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1222fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt#ifndef CONFIG_NATIVE_WINDOWS 12232f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidtstatic int domain_suffix_match(const u8 *val, size_t len, const char *match, 12242f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt int full) 1225051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt{ 1226051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt size_t i, match_len; 1227051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1228051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt /* Check for embedded nuls that could mess up suffix matching */ 1229051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt for (i = 0; i < len; i++) { 1230051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (val[i] == '\0') { 1231051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Embedded null in a string - reject"); 1232051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return 0; 1233051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } 1234051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } 1235051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1236051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt match_len = os_strlen(match); 12372f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (match_len > len || (full && match_len != len)) 1238051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return 0; 1239051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1240051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (os_strncasecmp((const char *) val + len - match_len, match, 1241051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt match_len) != 0) 1242051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return 0; /* no match */ 1243051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1244051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (match_len == len) 1245051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return 1; /* exact match */ 1246051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1247051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (val[len - match_len - 1] == '.') 1248051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return 1; /* full label match completes suffix match */ 1249051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1250051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Reject due to incomplete label match"); 1251051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return 0; 1252051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt} 1253fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 1254051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1255051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 12562f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidtstatic int tls_match_suffix(X509 *cert, const char *match, int full) 1257051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt{ 1258fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt#ifdef CONFIG_NATIVE_WINDOWS 1259fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt /* wincrypt.h has conflicting X509_NAME definition */ 1260fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt return -1; 1261fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt#else /* CONFIG_NATIVE_WINDOWS */ 1262051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt GENERAL_NAME *gen; 1263051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt void *ext; 1264051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt int i; 12659ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt stack_index_t j; 1266051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt int dns_name = 0; 1267051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt X509_NAME *name; 1268051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 12692f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Match domain against %s%s", 12702f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt full ? "": "suffix ", match); 1271051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1272051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt ext = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL); 1273051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 12749ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt for (j = 0; ext && j < sk_GENERAL_NAME_num(ext); j++) { 12759ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt gen = sk_GENERAL_NAME_value(ext, j); 1276051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (gen->type != GEN_DNS) 1277051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt continue; 1278051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt dns_name++; 1279051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "TLS: Certificate dNSName", 1280051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt gen->d.dNSName->data, 1281051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt gen->d.dNSName->length); 1282051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (domain_suffix_match(gen->d.dNSName->data, 12832f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt gen->d.dNSName->length, match, full) == 12842f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 1) { 12852f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: %s in dNSName found", 12862f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt full ? "Match" : "Suffix match"); 1287051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return 1; 1288051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } 1289051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } 1290051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1291051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (dns_name) { 1292051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: None of the dNSName(s) matched"); 1293051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return 0; 1294051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } 1295051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1296051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt name = X509_get_subject_name(cert); 1297051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt i = -1; 1298051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt for (;;) { 1299051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt X509_NAME_ENTRY *e; 1300051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt ASN1_STRING *cn; 1301051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1302051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt i = X509_NAME_get_index_by_NID(name, NID_commonName, i); 1303051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (i == -1) 1304051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt break; 1305051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt e = X509_NAME_get_entry(name, i); 1306051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (e == NULL) 1307051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt continue; 1308051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt cn = X509_NAME_ENTRY_get_data(e); 1309051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (cn == NULL) 1310051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt continue; 1311051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "TLS: Certificate commonName", 1312051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt cn->data, cn->length); 13132f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (domain_suffix_match(cn->data, cn->length, match, full) == 1) 13142f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt { 13152f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: %s in commonName found", 13162f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt full ? "Match" : "Suffix match"); 1317051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return 1; 1318051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } 1319051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } 1320051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 13212f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: No CommonName %smatch found", 13222f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt full ? "": "suffix "); 1323051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return 0; 1324fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 1325051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt} 1326051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1327051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 13288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic enum tls_fail_reason openssl_tls_fail_reason(int err) 13298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (err) { 13318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_CERT_REVOKED: 13328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_FAIL_REVOKED; 13338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_CERT_NOT_YET_VALID: 13348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_CRL_NOT_YET_VALID: 13358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_FAIL_NOT_YET_VALID; 13368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_CERT_HAS_EXPIRED: 13378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_CRL_HAS_EXPIRED: 13388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_FAIL_EXPIRED; 13398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: 13408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_UNABLE_TO_GET_CRL: 13418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER: 13428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: 13438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: 13448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: 13458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: 13468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_CERT_CHAIN_TOO_LONG: 13478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_PATH_LENGTH_EXCEEDED: 13488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_INVALID_CA: 13498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_FAIL_UNTRUSTED; 13508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: 13518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: 13528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: 13538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: 13548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: 13558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: 13568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: 13578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_CERT_UNTRUSTED: 13588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_CERT_REJECTED: 13598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_FAIL_BAD_CERTIFICATE; 13608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 13618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_FAIL_UNSPECIFIED; 13628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * get_x509_cert(X509 *cert) 13678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 13698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *tmp; 13708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int cert_len = i2d_X509(cert, NULL); 13728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert_len <= 0) 13738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 13748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = wpabuf_alloc(cert_len); 13768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 13778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 13788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = wpabuf_put(buf, cert_len); 13808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i2d_X509(cert, &tmp); 13818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 13828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void openssl_tls_fail_event(struct tls_connection *conn, 13868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *err_cert, int err, int depth, 13878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *subject, const char *err_str, 13888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum tls_fail_reason reason) 13898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union tls_event_data ev; 13918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *cert = NULL; 1392ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt struct tls_context *context = conn->context; 13938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1394ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt if (context->event_cb == NULL) 13958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 13968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert = get_x509_cert(err_cert); 13988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&ev, 0, sizeof(ev)); 13998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.cert_fail.reason = reason != TLS_FAIL_UNSPECIFIED ? 14008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reason : openssl_tls_fail_reason(err); 14018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.cert_fail.depth = depth; 14028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.cert_fail.subject = subject; 14038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.cert_fail.reason_txt = err_str; 14048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.cert_fail.cert = cert; 1405ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt context->event_cb(context->cb_ctx, TLS_CERT_CHAIN_FAILURE, &ev); 14068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(cert); 14078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void openssl_tls_cert_event(struct tls_connection *conn, 14118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *err_cert, int depth, 14128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *subject) 14138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *cert = NULL; 14158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union tls_event_data ev; 1416ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt struct tls_context *context = conn->context; 14172f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt char *altsubject[TLS_MAX_ALT_SUBJECT]; 14182f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt int alt, num_altsubject = 0; 14192f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt GENERAL_NAME *gen; 14202f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt void *ext; 14212f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt stack_index_t i; 14228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_SHA256 14238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 hash[32]; 14248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_SHA256 */ 14258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1426ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt if (context->event_cb == NULL) 14278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 14288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&ev, 0, sizeof(ev)); 1430ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt if (conn->cert_probe || context->cert_in_cb) { 14318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert = get_x509_cert(err_cert); 14328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.peer_cert.cert = cert; 14338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_SHA256 14358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert) { 14368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr[1]; 14378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len[1]; 14388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr[0] = wpabuf_head(cert); 14398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len[0] = wpabuf_len(cert); 14408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sha256_vector(1, addr, len, hash) == 0) { 14418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.peer_cert.hash = hash; 14428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.peer_cert.hash_len = sizeof(hash); 14438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_SHA256 */ 14468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.peer_cert.depth = depth; 14478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.peer_cert.subject = subject; 14482f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 14492f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt ext = X509_get_ext_d2i(err_cert, NID_subject_alt_name, NULL, NULL); 14502f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt for (i = 0; ext && i < sk_GENERAL_NAME_num(ext); i++) { 14512f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt char *pos; 14522f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 14532f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (num_altsubject == TLS_MAX_ALT_SUBJECT) 14542f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt break; 14552f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt gen = sk_GENERAL_NAME_value(ext, i); 14562f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (gen->type != GEN_EMAIL && 14572f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt gen->type != GEN_DNS && 14582f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt gen->type != GEN_URI) 14592f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt continue; 14602f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 14612f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt pos = os_malloc(10 + gen->d.ia5->length + 1); 14622f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (pos == NULL) 14632f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt break; 14642f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt altsubject[num_altsubject++] = pos; 14652f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 14662f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt switch (gen->type) { 14672f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt case GEN_EMAIL: 14682f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt os_memcpy(pos, "EMAIL:", 6); 14692f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt pos += 6; 14702f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt break; 14712f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt case GEN_DNS: 14722f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt os_memcpy(pos, "DNS:", 4); 14732f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt pos += 4; 14742f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt break; 14752f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt case GEN_URI: 14762f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt os_memcpy(pos, "URI:", 4); 14772f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt pos += 4; 14782f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt break; 14792f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 14802f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 14812f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt os_memcpy(pos, gen->d.ia5->data, gen->d.ia5->length); 14822f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt pos += gen->d.ia5->length; 14832f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt *pos = '\0'; 14842f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 14852f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 14862f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt for (alt = 0; alt < num_altsubject; alt++) 14872f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt ev.peer_cert.altsubject[alt] = altsubject[alt]; 14882f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt ev.peer_cert.num_altsubject = num_altsubject; 14892f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 1490ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt context->event_cb(context->cb_ctx, TLS_PEER_CERTIFICATE, &ev); 14918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(cert); 14922f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt for (alt = 0; alt < num_altsubject; alt++) 14932f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt os_free(altsubject[alt]); 14948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx) 14988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char buf[256]; 15008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *err_cert; 15018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int err, depth; 15028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL *ssl; 15038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn; 1504ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt struct tls_context *context; 15052f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt char *match, *altmatch, *suffix_match, *domain_match; 15068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *err_str; 15078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err_cert = X509_STORE_CTX_get_current_cert(x509_ctx); 150996be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt if (!err_cert) 151096be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt return 0; 151196be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt 15128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err = X509_STORE_CTX_get_error(x509_ctx); 15138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt depth = X509_STORE_CTX_get_error_depth(x509_ctx); 15148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssl = X509_STORE_CTX_get_ex_data(x509_ctx, 15158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_get_ex_data_X509_STORE_CTX_idx()); 15168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof(buf)); 15178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn = SSL_get_app_data(ssl); 15198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 15208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 152134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 152234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (depth == 0) 152334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt conn->peer_cert = err_cert; 152434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt else if (depth == 1) 152534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt conn->peer_issuer = err_cert; 1526fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt else if (depth == 2) 1527fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt conn->peer_issuer_issuer = err_cert; 152834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 1529ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt context = conn->context; 15308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt match = conn->subject_match; 15318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt altmatch = conn->altsubject_match; 1532051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt suffix_match = conn->suffix_match; 15332f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt domain_match = conn->domain_match; 15348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!preverify_ok && !conn->ca_cert_verify) 15368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt preverify_ok = 1; 15378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!preverify_ok && depth > 0 && conn->server_cert_only) 15388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt preverify_ok = 1; 1539c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt if (!preverify_ok && (conn->flags & TLS_CONN_DISABLE_TIME_CHECKS) && 1540c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt (err == X509_V_ERR_CERT_HAS_EXPIRED || 1541c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt err == X509_V_ERR_CERT_NOT_YET_VALID)) { 1542c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Ignore certificate validity " 1543c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt "time mismatch"); 1544c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt preverify_ok = 1; 1545c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt } 15468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err_str = X509_verify_cert_error_string(err); 15488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_SHA256 15504dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt /* 15514dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt * Do not require preverify_ok so we can explicity allow otherwise 15524dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt * invalid pinned server certificates. 15534dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt */ 15544dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt if (depth == 0 && conn->server_cert_only) { 15558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *cert; 15568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert = get_x509_cert(err_cert); 15578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!cert) { 15588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Could not fetch " 15598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "server certificate data"); 15608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt preverify_ok = 0; 15618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 15628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 hash[32]; 15638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr[1]; 15648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len[1]; 15658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr[0] = wpabuf_head(cert); 15668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len[0] = wpabuf_len(cert); 15678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sha256_vector(1, addr, len, hash) < 0 || 15688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(conn->srv_cert_hash, hash, 32) != 0) { 15698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err_str = "Server certificate mismatch"; 15708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN; 15718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt preverify_ok = 0; 15724dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt } else if (!preverify_ok) { 15734dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt /* 15744dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt * Certificate matches pinned certificate, allow 15754dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt * regardless of other problems. 15764dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt */ 15774dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt wpa_printf(MSG_DEBUG, 15784dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt "OpenSSL: Ignore validation issues for a pinned server certificate"); 15794dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt preverify_ok = 1; 15808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(cert); 15828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_SHA256 */ 15858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!preverify_ok) { 15878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "TLS: Certificate verification failed," 15888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " error %d (%s) depth %d for '%s'", err, err_str, 15898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt depth, buf); 15908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt openssl_tls_fail_event(conn, err_cert, err, depth, buf, 15918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err_str, TLS_FAIL_UNSPECIFIED); 15928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return preverify_ok; 15938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: tls_verify_cb - preverify_ok=%d " 15968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "err=%d (%s) ca_cert_verify=%d depth=%d buf='%s'", 15978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt preverify_ok, err, err_str, 15988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ca_cert_verify, depth, buf); 15998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (depth == 0 && match && os_strstr(buf, match) == NULL) { 16008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "TLS: Subject '%s' did not " 16018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "match with '%s'", buf, match); 16028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt preverify_ok = 0; 16038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt openssl_tls_fail_event(conn, err_cert, err, depth, buf, 16048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Subject mismatch", 16058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_FAIL_SUBJECT_MISMATCH); 16068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (depth == 0 && altmatch && 16078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !tls_match_altsubject(err_cert, altmatch)) { 16088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "TLS: altSubjectName match " 16098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s' not found", altmatch); 16108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt preverify_ok = 0; 16118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt openssl_tls_fail_event(conn, err_cert, err, depth, buf, 16128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "AltSubject mismatch", 16138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_FAIL_ALTSUBJECT_MISMATCH); 1614051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } else if (depth == 0 && suffix_match && 16152f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt !tls_match_suffix(err_cert, suffix_match, 0)) { 1616051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt wpa_printf(MSG_WARNING, "TLS: Domain suffix match '%s' not found", 1617051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt suffix_match); 1618051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt preverify_ok = 0; 1619051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt openssl_tls_fail_event(conn, err_cert, err, depth, buf, 1620051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt "Domain suffix mismatch", 1621051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt TLS_FAIL_DOMAIN_SUFFIX_MISMATCH); 16222f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } else if (depth == 0 && domain_match && 16232f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt !tls_match_suffix(err_cert, domain_match, 1)) { 16242f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_WARNING, "TLS: Domain match '%s' not found", 16252f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt domain_match); 16262f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt preverify_ok = 0; 16272f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt openssl_tls_fail_event(conn, err_cert, err, depth, buf, 16282f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt "Domain mismatch", 16292f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt TLS_FAIL_DOMAIN_MISMATCH); 16308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 16318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt openssl_tls_cert_event(conn, err_cert, depth, buf); 16328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->cert_probe && preverify_ok && depth == 0) { 16348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Reject server certificate " 16358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "on probe-only run"); 16368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt preverify_ok = 0; 16378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt openssl_tls_fail_event(conn, err_cert, err, depth, buf, 16388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Server certificate chain probe", 16398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_FAIL_SERVER_CHAIN_PROBE); 16408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1642ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt if (preverify_ok && context->event_cb != NULL) 1643ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt context->event_cb(context->cb_ctx, 1644ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt TLS_CERT_CHAIN_SUCCESS, NULL); 164504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 16468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return preverify_ok; 16478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_STDIO 16518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_load_ca_der(void *_ssl_ctx, const char *ca_cert) 16528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX *ssl_ctx = _ssl_ctx; 16548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_LOOKUP *lookup; 16558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = 0; 16568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1657216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt lookup = X509_STORE_add_lookup(SSL_CTX_get_cert_store(ssl_ctx), 16588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_LOOKUP_file()); 16598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (lookup == NULL) { 16608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_WARNING, __func__, 16618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed add lookup for X509 store"); 16628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 16638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!X509_LOOKUP_load_file(lookup, ca_cert, X509_FILETYPE_ASN1)) { 16668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned long err = ERR_peek_error(); 16678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_WARNING, __func__, 16688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed load CA in DER format"); 16698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ERR_GET_LIB(err) == ERR_LIB_X509 && 16708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_GET_REASON(err) == X509_R_CERT_ALREADY_IN_HASH_TABLE) { 16718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - ignoring " 16728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "cert already in hash table error", 16738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__); 16748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 16758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 16768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 16798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_STDIO */ 16818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_connection_ca_cert(void *_ssl_ctx, struct tls_connection *conn, 16848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *ca_cert, const u8 *ca_cert_blob, 16858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t ca_cert_blob_len, const char *ca_path) 16868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX *ssl_ctx = _ssl_ctx; 1688216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt X509_STORE *store; 16898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 16918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Remove previously configured trusted CA certificates before adding 16928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * new ones. 16938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1694216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt store = X509_STORE_new(); 1695216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (store == NULL) { 16968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - failed to allocate new " 16978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate store", __func__); 16988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 16998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1700216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt SSL_CTX_set_cert_store(ssl_ctx, store); 17018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb); 17038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ca_cert_verify = 1; 17048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ca_cert && os_strncmp(ca_cert, "probe://", 8) == 0) { 17068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Probe for server certificate " 17078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "chain"); 17088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->cert_probe = 1; 17098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ca_cert_verify = 0; 17108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 17118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ca_cert && os_strncmp(ca_cert, "hash://", 7) == 0) { 17148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_SHA256 17158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *pos = ca_cert + 7; 17168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strncmp(pos, "server/sha256/", 14) != 0) { 17178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Unsupported ca_cert " 17188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "hash value '%s'", ca_cert); 17198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 17208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 14; 17228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strlen(pos) != 32 * 2) { 17238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Unexpected SHA256 " 17248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "hash length in ca_cert '%s'", ca_cert); 17258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 17268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hexstr2bin(pos, conn->srv_cert_hash, 32) < 0) { 17288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Invalid SHA256 hash " 17298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "value in ca_cert '%s'", ca_cert); 17308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 17318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->server_cert_only = 1; 17338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Checking only server " 17348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate match"); 17358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 17368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_SHA256 */ 17378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "No SHA256 included in the build - " 17388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "cannot validate server certificate hash"); 17398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 17408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_SHA256 */ 17418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ca_cert_blob) { 1744216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt X509 *cert = d2i_X509(NULL, 1745216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt (const unsigned char **) &ca_cert_blob, 17468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ca_cert_blob_len); 17478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert == NULL) { 17488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_WARNING, __func__, 17498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to parse ca_cert_blob"); 17508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 17518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1753216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!X509_STORE_add_cert(SSL_CTX_get_cert_store(ssl_ctx), 1754216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt cert)) { 17558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned long err = ERR_peek_error(); 17568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_WARNING, __func__, 17578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to add ca_cert_blob to " 17588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate store"); 17598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ERR_GET_LIB(err) == ERR_LIB_X509 && 17608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_GET_REASON(err) == 17618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_R_CERT_ALREADY_IN_HASH_TABLE) { 17628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - ignoring " 17638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "cert already in hash table error", 17648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__); 17658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 17668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 17678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 17688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 17718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - added ca_cert_blob " 17728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "to certificate store", __func__); 17738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 17748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef ANDROID 17778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ca_cert && os_strncmp("keystore://", ca_cert, 11) == 0) { 17788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO *bio = BIO_from_keystore(&ca_cert[11]); 17798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt STACK_OF(X509_INFO) *stack = NULL; 17809ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt stack_index_t i; 17818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bio) { 17838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt stack = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL); 17848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO_free(bio); 17858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!stack) 17878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 17888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < sk_X509_INFO_num(stack); ++i) { 17908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_INFO *info = sk_X509_INFO_value(stack, i); 17918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (info->x509) { 17928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_STORE_add_cert(ssl_ctx->cert_store, 17938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt info->x509); 17948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (info->crl) { 17968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_STORE_add_crl(ssl_ctx->cert_store, 17978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt info->crl); 17988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sk_X509_INFO_pop_free(stack, X509_INFO_free); 18018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb); 18028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 18038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* ANDROID */ 18058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_NATIVE_WINDOWS 18078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ca_cert && tls_cryptoapi_ca_cert(ssl_ctx, conn->ssl, ca_cert) == 18088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) { 18098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Added CA certificates from " 18108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "system certificate store"); 18118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 18128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 18148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ca_cert || ca_path) { 18168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_STDIO 18178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_CTX_load_verify_locations(ssl_ctx, ca_cert, ca_path) != 18188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1) { 18198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_WARNING, __func__, 18208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to load root certificates"); 18218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ca_cert && 18228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_load_ca_der(ssl_ctx, ca_cert) == 0) { 18238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - loaded " 18248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "DER format CA certificate", 18258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__); 18268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 18278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 18288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 18298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Trusted root " 18308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate(s) loaded"); 18318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_get_errors(ssl_ctx); 18328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_STDIO */ 18348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", 18358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__); 18368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 18378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_STDIO */ 18388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 18398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* No ca_cert configured - do not try to verify server 18408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * certificate */ 18418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ca_cert_verify = 0; 18428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 18458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_global_ca_cert(SSL_CTX *ssl_ctx, const char *ca_cert) 18498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ca_cert) { 18518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_CTX_load_verify_locations(ssl_ctx, ca_cert, NULL) != 1) 18528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 18538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_WARNING, __func__, 18548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to load root certificates"); 18558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 18568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Trusted root " 18598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate(s) loaded"); 18608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_STDIO 18628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Add the same CAs to the client certificate requests */ 18638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_set_client_CA_list(ssl_ctx, 18648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_load_client_CA_file(ca_cert)); 18658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_STDIO */ 18668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 18698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_global_set_verify(void *ssl_ctx, int check_crl) 18738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int flags; 18758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (check_crl) { 18778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_STORE *cs = SSL_CTX_get_cert_store(ssl_ctx); 18788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cs == NULL) { 18798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, "Failed to get " 18808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate store when enabling " 18818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "check_crl"); 18828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 18838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt flags = X509_V_FLAG_CRL_CHECK; 18858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (check_crl == 2) 18868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt flags |= X509_V_FLAG_CRL_CHECK_ALL; 18878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_STORE_set_flags(cs, flags); 18888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 18908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_connection_set_subject_match(struct tls_connection *conn, 18948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *subject_match, 1895051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt const char *altsubject_match, 18962f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt const char *suffix_match, 18972f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt const char *domain_match) 18988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->subject_match); 19008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->subject_match = NULL; 19018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (subject_match) { 19028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->subject_match = os_strdup(subject_match); 19038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->subject_match == NULL) 19048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 19058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->altsubject_match); 19088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->altsubject_match = NULL; 19098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (altsubject_match) { 19108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->altsubject_match = os_strdup(altsubject_match); 19118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->altsubject_match == NULL) 19128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 19138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1915051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt os_free(conn->suffix_match); 1916051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt conn->suffix_match = NULL; 1917051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (suffix_match) { 1918051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt conn->suffix_match = os_strdup(suffix_match); 1919051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (conn->suffix_match == NULL) 1920051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return -1; 1921051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } 1922051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 19232f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt os_free(conn->domain_match); 19242f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt conn->domain_match = NULL; 19252f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (domain_match) { 19262f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt conn->domain_match = os_strdup(domain_match); 19272f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (conn->domain_match == NULL) 19282f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt return -1; 19292f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 19302f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 19318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 19328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn, 19368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int verify_peer) 19378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt static int counter = 0; 19398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 19418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 19428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (verify_peer) { 19448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ca_cert_verify = 1; 19458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_verify(conn->ssl, SSL_VERIFY_PEER | 19468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_VERIFY_FAIL_IF_NO_PEER_CERT | 19478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_VERIFY_CLIENT_ONCE, tls_verify_cb); 19488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 19498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ca_cert_verify = 0; 19508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_verify(conn->ssl, SSL_VERIFY_NONE, NULL); 19518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_accept_state(conn->ssl); 19548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 19568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Set session id context in order to avoid fatal errors when client 19578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tries to resume a session. However, set the context to a unique 19588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * value in order to effectively disable session resumption for now 19598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * since not all areas of the server code are ready for it (e.g., 19608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP-TTLS needs special handling for Phase 2 after abbreviated TLS 19618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * handshake). 19628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 19638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt counter++; 19648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_session_id_context(conn->ssl, 19658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (const unsigned char *) &counter, 19668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(counter)); 19678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 19698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_connection_client_cert(struct tls_connection *conn, 19738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *client_cert, 19748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *client_cert_blob, 19758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t client_cert_blob_len) 19768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (client_cert == NULL && client_cert_blob == NULL) 19788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 19798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (client_cert_blob && 19818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_use_certificate_ASN1(conn->ssl, (u8 *) client_cert_blob, 19828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client_cert_blob_len) == 1) { 19838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_ASN1 --> " 19848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "OK"); 19858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 19868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (client_cert_blob) { 19878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_DEBUG, __func__, 19888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SSL_use_certificate_ASN1 failed"); 19898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (client_cert == NULL) 19928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 19938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef ANDROID 19958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strncmp("keystore://", client_cert, 11) == 0) { 19968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO *bio = BIO_from_keystore(&client_cert[11]); 19978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *x509 = NULL; 19988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = -1; 19998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bio) { 20008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL); 20018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO_free(bio); 20028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (x509) { 20048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_certificate(conn->ssl, x509) == 1) 20058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = 0; 20068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(x509); 20078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 20098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* ANDROID */ 20118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_STDIO 20138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_certificate_file(conn->ssl, client_cert, 20148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_FILETYPE_ASN1) == 1) { 20158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_file (DER)" 20168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " --> OK"); 20178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 20188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_certificate_file(conn->ssl, client_cert, 20218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_FILETYPE_PEM) == 1) { 20228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_clear_error(); 20238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_file (PEM)" 20248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " --> OK"); 20258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 20268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_DEBUG, __func__, 20298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SSL_use_certificate_file failed"); 20308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_STDIO */ 20318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", __func__); 20328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_STDIO */ 20338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 20358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_global_client_cert(SSL_CTX *ssl_ctx, const char *client_cert) 20398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_STDIO 20418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (client_cert == NULL) 20428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 20438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_CTX_use_certificate_file(ssl_ctx, client_cert, 20458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_FILETYPE_ASN1) != 1 && 20461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt SSL_CTX_use_certificate_chain_file(ssl_ctx, client_cert) != 1 && 20478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_use_certificate_file(ssl_ctx, client_cert, 20488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_FILETYPE_PEM) != 1) { 20498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 20508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to load client certificate"); 20518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 20528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 20548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_STDIO */ 20558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (client_cert == NULL) 20568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 20578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", __func__); 20588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 20598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_STDIO */ 20608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_passwd_cb(char *buf, int size, int rwflag, void *password) 20648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (password == NULL) { 20668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 20678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(buf, (char *) password, size); 20698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return os_strlen(buf); 20708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef PKCS12_FUNCS 20748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_parse_pkcs12(SSL_CTX *ssl_ctx, SSL *ssl, PKCS12 *p12, 20758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *passwd) 20768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EVP_PKEY *pkey; 20788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *cert; 20798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt STACK_OF(X509) *certs; 20808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res = 0; 20818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char buf[256]; 20828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pkey = NULL; 20848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert = NULL; 20858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt certs = NULL; 20868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!PKCS12_parse(p12, passwd, &pkey, &cert, &certs)) { 20878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_DEBUG, __func__, 20888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to parse PKCS12 file"); 20898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PKCS12_free(p12); 20908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 20918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Successfully parsed PKCS12 data"); 20938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert) { 20958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_NAME_oneline(X509_get_subject_name(cert), buf, 20968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(buf)); 20978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Got certificate from PKCS12: " 20988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "subject='%s'", buf); 20998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssl) { 21008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_certificate(ssl, cert) != 1) 21018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 21028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 21038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_CTX_use_certificate(ssl_ctx, cert) != 1) 21048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 21058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 21078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pkey) { 21108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Got private key from PKCS12"); 21118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssl) { 21128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_PrivateKey(ssl, pkey) != 1) 21138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 21148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 21158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_CTX_use_PrivateKey(ssl_ctx, pkey) != 1) 21168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 21178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EVP_PKEY_free(pkey); 21198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (certs) { 21228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while ((cert = sk_X509_pop(certs)) != NULL) { 21238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_NAME_oneline(X509_get_subject_name(cert), buf, 21248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(buf)); 21258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: additional certificate" 21268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " from PKCS12: subject='%s'", buf); 21278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 21288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * There is no SSL equivalent for the chain cert - so 21298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * always add it to the context... 21308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 21318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_CTX_add_extra_chain_cert(ssl_ctx, cert) != 1) { 21328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 21338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 21348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sk_X509_free(certs); 21378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PKCS12_free(p12); 21408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) 21428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_get_errors(ssl_ctx); 21438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 21458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* PKCS12_FUNCS */ 21478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_read_pkcs12(SSL_CTX *ssl_ctx, SSL *ssl, const char *private_key, 21508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *passwd) 21518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef PKCS12_FUNCS 21538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FILE *f; 21548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PKCS12 *p12; 21558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt f = fopen(private_key, "rb"); 21578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (f == NULL) 21588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 21598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p12 = d2i_PKCS12_fp(f, NULL); 21618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fclose(f); 21628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p12 == NULL) { 21648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 21658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to use PKCS#12 file"); 21668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 21678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_parse_pkcs12(ssl_ctx, ssl, p12, passwd); 21708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* PKCS12_FUNCS */ 21728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: PKCS12 support disabled - cannot read " 21738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "p12/pfx files"); 21748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 21758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* PKCS12_FUNCS */ 21768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_read_pkcs12_blob(SSL_CTX *ssl_ctx, SSL *ssl, 21808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *blob, size_t len, const char *passwd) 21818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef PKCS12_FUNCS 21838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PKCS12 *p12; 21848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2185216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p12 = d2i_PKCS12(NULL, (const unsigned char **) &blob, len); 21868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p12 == NULL) { 21878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 21888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to use PKCS#12 blob"); 21898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 21908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_parse_pkcs12(ssl_ctx, ssl, p12, passwd); 21938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* PKCS12_FUNCS */ 21958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: PKCS12 support disabled - cannot parse " 21968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "p12/pfx blobs"); 21978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 21988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* PKCS12_FUNCS */ 21998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_ENGINE 22038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_engine_get_cert(struct tls_connection *conn, 22048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *cert_id, 22058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 **cert) 22068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* this runs after the private key is loaded so no PIN is required */ 22088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct { 22098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *cert_id; 22108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *cert; 22118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } params; 22128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.cert_id = cert_id; 22138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.cert = NULL; 22148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ENGINE_ctrl_cmd(conn->engine, "LOAD_CERT_CTRL", 22168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0, ¶ms, NULL, 1)) { 22171d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt unsigned long err = ERR_get_error(); 22181d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt 22198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "ENGINE: cannot load client cert with id" 22208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " '%s' [%s]", cert_id, 22211d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt ERR_error_string(err, NULL)); 22221d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt if (tls_is_pin_error(err)) 22231d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt return TLS_SET_PARAMS_ENGINE_PRV_BAD_PIN; 22248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED; 22258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!params.cert) { 22278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "ENGINE: did not properly cert with id" 22288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " '%s'", cert_id); 22298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED; 22308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *cert = params.cert; 22328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 22338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 22358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_connection_engine_client_cert(struct tls_connection *conn, 22388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *cert_id) 22398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_ENGINE 22418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *cert; 22428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_engine_get_cert(conn, cert_id, &cert)) 22448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!SSL_use_certificate(conn->ssl, cert)) { 22478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_ERROR, __func__, 22488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SSL_use_certificate failed"); 22498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 22508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 22538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: SSL_use_certificate --> " 22548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "OK"); 22558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 22568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_ENGINE */ 22588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 22608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_connection_engine_ca_cert(void *_ssl_ctx, 22648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn, 22658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *ca_cert_id) 22668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_ENGINE 22688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *cert; 22698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX *ssl_ctx = _ssl_ctx; 2270216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt X509_STORE *store; 22718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_engine_get_cert(conn, ca_cert_id, &cert)) 22738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* start off the same as tls_connection_ca_cert */ 2276216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt store = X509_STORE_new(); 2277216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (store == NULL) { 22788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - failed to allocate new " 22798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate store", __func__); 22808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 22818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2283216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt SSL_CTX_set_cert_store(ssl_ctx, store); 2284216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!X509_STORE_add_cert(store, cert)) { 22858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned long err = ERR_peek_error(); 22868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_WARNING, __func__, 22878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to add CA certificate from engine " 22888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "to certificate store"); 22898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ERR_GET_LIB(err) == ERR_LIB_X509 && 22908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_GET_REASON(err) == X509_R_CERT_ALREADY_IN_HASH_TABLE) { 22918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - ignoring cert" 22928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " already in hash table error", 22938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__); 22948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 22958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 22968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 23008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - added CA certificate from engine " 23018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "to certificate store", __func__); 23028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb); 230361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt conn->ca_cert_verify = 1; 230461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 23058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 23068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_ENGINE */ 23088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 23098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 23108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_connection_engine_private_key(struct tls_connection *conn) 23148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23151eb02edb319d462031f0c2f1f3548498558e95a5Adam Langley#if defined(ANDROID) || !defined(OPENSSL_NO_ENGINE) 23168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_PrivateKey(conn->ssl, conn->private_key) != 1) { 23178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_ERROR, __func__, 23188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ENGINE: cannot use private key for TLS"); 23198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 23208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!SSL_check_private_key(conn->ssl)) { 23228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 23238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Private key failed verification"); 23248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 23258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 23278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_ENGINE */ 23288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "SSL: Configuration uses engine, but " 23298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "engine support was not compiled in"); 23308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 23318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 23328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_connection_private_key(void *_ssl_ctx, 23368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn, 23378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *private_key, 23388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *private_key_passwd, 23398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *private_key_blob, 23408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t private_key_blob_len) 23418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX *ssl_ctx = _ssl_ctx; 23438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *passwd; 23448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ok; 23458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (private_key == NULL && private_key_blob == NULL) 23478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 23488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (private_key_passwd) { 23508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt passwd = os_strdup(private_key_passwd); 23518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (passwd == NULL) 23528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 23538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 23548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt passwd = NULL; 23558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_set_default_passwd_cb(ssl_ctx, tls_passwd_cb); 23578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, passwd); 23588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 0; 23608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (private_key_blob) { 23618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_PrivateKey_ASN1(EVP_PKEY_RSA, conn->ssl, 23628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) private_key_blob, 23638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt private_key_blob_len) == 1) { 23648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_PrivateKey_" 23658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ASN1(EVP_PKEY_RSA) --> OK"); 23668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 1; 23678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 23688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_PrivateKey_ASN1(EVP_PKEY_DSA, conn->ssl, 23718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) private_key_blob, 23728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt private_key_blob_len) == 1) { 23738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_PrivateKey_" 23748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ASN1(EVP_PKEY_DSA) --> OK"); 23758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 1; 23768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 23778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_RSAPrivateKey_ASN1(conn->ssl, 23808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) private_key_blob, 23818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt private_key_blob_len) == 1) { 23828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: " 23838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SSL_use_RSAPrivateKey_ASN1 --> OK"); 23848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 1; 23858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 23868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_read_pkcs12_blob(ssl_ctx, conn->ssl, private_key_blob, 23898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt private_key_blob_len, passwd) == 0) { 23908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: PKCS#12 as blob --> " 23918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "OK"); 23928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 1; 23938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 23948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 23978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (!ok && private_key) { 24008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_STDIO 24018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_PrivateKey_file(conn->ssl, private_key, 24028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_FILETYPE_ASN1) == 1) { 24038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: " 24048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SSL_use_PrivateKey_File (DER) --> OK"); 24058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 1; 24068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 24078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_PrivateKey_file(conn->ssl, private_key, 24108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_FILETYPE_PEM) == 1) { 24118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: " 24128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SSL_use_PrivateKey_File (PEM) --> OK"); 24138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 1; 24148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 24158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_STDIO */ 24178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", 24188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__); 24198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_STDIO */ 24208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_read_pkcs12(ssl_ctx, conn->ssl, private_key, passwd) 24228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt == 0) { 24238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Reading PKCS#12 file " 24248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "--> OK"); 24258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 1; 24268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 24278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_cryptoapi_cert(conn->ssl, private_key) == 0) { 24308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Using CryptoAPI to " 24318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "access certificate store --> OK"); 24328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 1; 24338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 24348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 24378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ok) { 24408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 24418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to load private key"); 24428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(passwd); 24438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 24448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_clear_error(); 24468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_set_default_passwd_cb(ssl_ctx, NULL); 24478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(passwd); 244861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 24498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!SSL_check_private_key(conn->ssl)) { 24508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, "Private key failed " 24518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "verification"); 24528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 24538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Private key loaded successfully"); 24568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 24578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_global_private_key(SSL_CTX *ssl_ctx, const char *private_key, 24618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *private_key_passwd) 24628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *passwd; 24648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (private_key == NULL) 24668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 24678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (private_key_passwd) { 24698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt passwd = os_strdup(private_key_passwd); 24708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (passwd == NULL) 24718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 24728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 24738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt passwd = NULL; 24748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_set_default_passwd_cb(ssl_ctx, tls_passwd_cb); 24768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, passwd); 24778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ( 24788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_STDIO 24798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_use_PrivateKey_file(ssl_ctx, private_key, 24808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_FILETYPE_ASN1) != 1 && 24818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_use_PrivateKey_file(ssl_ctx, private_key, 24828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_FILETYPE_PEM) != 1 && 24838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_STDIO */ 24848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_read_pkcs12(ssl_ctx, NULL, private_key, passwd)) { 24858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 24868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to load private key"); 24878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(passwd); 24888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_clear_error(); 24898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 24908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(passwd); 24928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_clear_error(); 24938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_set_default_passwd_cb(ssl_ctx, NULL); 249461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 24958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!SSL_CTX_check_private_key(ssl_ctx)) { 24968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 24978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Private key failed verification"); 24988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 24998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 25028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_connection_dh(struct tls_connection *conn, const char *dh_file) 25068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef OPENSSL_NO_DH 25088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dh_file == NULL) 25098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 25108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "TLS: openssl does not include DH support, but " 25118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dh_file specified"); 25128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 25138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_DH */ 25148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DH *dh; 25158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO *bio; 25168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: add support for dh_blob */ 25188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dh_file == NULL) 25198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 25208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 25218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 25228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bio = BIO_new_file(dh_file, "r"); 25248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bio == NULL) { 25258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to open DH file '%s': %s", 25268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dh_file, ERR_error_string(ERR_get_error(), NULL)); 25278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 25288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); 25308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO_free(bio); 25318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_DSA 25328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (dh == NULL) { 25338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DSA *dsa; 25348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Failed to parse DH file '%s': %s -" 25358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " trying to parse as DSA params", dh_file, 25368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 25378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bio = BIO_new_file(dh_file, "r"); 25388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bio == NULL) 25398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 25408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dsa = PEM_read_bio_DSAparams(bio, NULL, NULL, NULL); 25418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO_free(bio); 25428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!dsa) { 25438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Failed to parse DSA file " 25448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s': %s", dh_file, 25458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 25468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 25478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: DH file in DSA param format"); 25508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dh = DSA_dup_DH(dsa); 25518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DSA_free(dsa); 25528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dh == NULL) { 25538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to convert DSA " 25548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "params into DH params"); 25558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 25568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 25588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* !OPENSSL_NO_DSA */ 25608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dh == NULL) { 25618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to read/parse DH/DSA file " 25628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s'", dh_file); 25638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 25648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_set_tmp_dh(conn->ssl, dh) != 1) { 25678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to set DH params from '%s': " 25688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%s", dh_file, 25698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 25708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DH_free(dh); 25718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 25728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DH_free(dh); 25748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 25758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_DH */ 25768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_global_dh(SSL_CTX *ssl_ctx, const char *dh_file) 25808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef OPENSSL_NO_DH 25828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dh_file == NULL) 25838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 25848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "TLS: openssl does not include DH support, but " 25858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dh_file specified"); 25868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 25878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_DH */ 25888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DH *dh; 25898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO *bio; 25908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: add support for dh_blob */ 25928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dh_file == NULL) 25938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 25948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssl_ctx == NULL) 25958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 25968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bio = BIO_new_file(dh_file, "r"); 25988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bio == NULL) { 25998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to open DH file '%s': %s", 26008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dh_file, ERR_error_string(ERR_get_error(), NULL)); 26018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); 26048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO_free(bio); 26058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_DSA 26068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (dh == NULL) { 26078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DSA *dsa; 26088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Failed to parse DH file '%s': %s -" 26098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " trying to parse as DSA params", dh_file, 26108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 26118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bio = BIO_new_file(dh_file, "r"); 26128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bio == NULL) 26138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 26148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dsa = PEM_read_bio_DSAparams(bio, NULL, NULL, NULL); 26158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO_free(bio); 26168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!dsa) { 26178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Failed to parse DSA file " 26188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s': %s", dh_file, 26198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 26208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 26218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: DH file in DSA param format"); 26248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dh = DSA_dup_DH(dsa); 26258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DSA_free(dsa); 26268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dh == NULL) { 26278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to convert DSA " 26288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "params into DH params"); 26298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 26308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 26328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* !OPENSSL_NO_DSA */ 26348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dh == NULL) { 26358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to read/parse DH/DSA file " 26368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s'", dh_file); 26378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_CTX_set_tmp_dh(ssl_ctx, dh) != 1) { 26418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to set DH params from '%s': " 26428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%s", dh_file, 26438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 26448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DH_free(dh); 26458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DH_free(dh); 26488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_DH */ 26508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_get_keys(void *ssl_ctx, struct tls_connection *conn, 26548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_keys *keys) 26558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 265661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_FIPS 265761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "OpenSSL: TLS keys cannot be exported in FIPS " 265861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "mode"); 265961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 266061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#else /* CONFIG_FIPS */ 26618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL *ssl; 26628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL || keys == NULL) 26648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssl = conn->ssl; 26668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssl == NULL || ssl->s3 == NULL || ssl->session == NULL) 26678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(keys, 0, sizeof(*keys)); 26708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keys->client_random = ssl->s3->client_random; 26718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keys->client_random_len = SSL3_RANDOM_SIZE; 26728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keys->server_random = ssl->s3->server_random; 26738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keys->server_random_len = SSL3_RANDOM_SIZE; 26748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 267661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_FIPS */ 26778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2680af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidtstatic int openssl_get_keyblock_size(SSL *ssl) 2681af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt{ 2682af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt const EVP_CIPHER *c; 2683af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt const EVP_MD *h; 2684af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt int md_size; 2685af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt 2686af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt if (ssl->enc_read_ctx == NULL || ssl->enc_read_ctx->cipher == NULL || 2687af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt ssl->read_hash == NULL) 2688af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt return -1; 2689af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt 2690af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt c = ssl->enc_read_ctx->cipher; 2691af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt#if OPENSSL_VERSION_NUMBER >= 0x00909000L 2692af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt h = EVP_MD_CTX_md(ssl->read_hash); 2693af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt#else 26947a53dbb56693ee9f55c0cab1a8297436511e8613Dmitry Shmidt h = ssl->read_hash; 2695af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt#endif 2696af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt if (h) 2697af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt md_size = EVP_MD_size(h); 2698af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt#if OPENSSL_VERSION_NUMBER >= 0x10000000L 2699af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt else if (ssl->s3) 2700af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt md_size = ssl->s3->tmp.new_mac_secret_size; 2701af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt#endif 2702af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt else 2703af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt return -1; 2704af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt 2705af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: keyblock size: key_len=%d MD_size=%d " 2706af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt "IV_len=%d", EVP_CIPHER_key_length(c), md_size, 2707af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt EVP_CIPHER_iv_length(c)); 2708af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt return 2 * (EVP_CIPHER_key_length(c) + 2709af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt md_size + 2710af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt EVP_CIPHER_iv_length(c)); 2711af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt} 2712af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt 2713af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt 2714af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidtstatic int openssl_tls_prf(void *tls_ctx, struct tls_connection *conn, 2715af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt const char *label, int server_random_first, 2716af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt int skip_keyblock, u8 *out, size_t out_len) 2717af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt{ 2718af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt#ifdef CONFIG_FIPS 2719af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt wpa_printf(MSG_ERROR, "OpenSSL: TLS keys cannot be exported in FIPS " 2720af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt "mode"); 2721af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt return -1; 2722af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt#else /* CONFIG_FIPS */ 2723af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt SSL *ssl; 2724af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt u8 *rnd; 2725af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt int ret = -1; 2726af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt int skip = 0; 2727af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt u8 *tmp_out = NULL; 2728af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt u8 *_out = out; 2729af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt 2730af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt /* 2731af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt * TLS library did not support key generation, so get the needed TLS 2732af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt * session parameters and use an internal implementation of TLS PRF to 2733af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt * derive the key. 2734af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt */ 2735af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt 2736af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt if (conn == NULL) 2737af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt return -1; 2738af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt ssl = conn->ssl; 2739af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt if (ssl == NULL || ssl->s3 == NULL || ssl->session == NULL || 27409d9e60286e05ae45025b672636490bd12586138dDmitry Shmidt ssl->session->master_key_length <= 0) 2741af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt return -1; 2742af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt 2743af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt if (skip_keyblock) { 2744af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt skip = openssl_get_keyblock_size(ssl); 2745af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt if (skip < 0) 2746af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt return -1; 2747af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt tmp_out = os_malloc(skip + out_len); 2748af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt if (!tmp_out) 2749af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt return -1; 2750af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt _out = tmp_out; 2751af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt } 2752af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt 2753af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt rnd = os_malloc(2 * SSL3_RANDOM_SIZE); 2754a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt if (!rnd) { 2755a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt os_free(tmp_out); 2756af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt return -1; 2757a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt } 2758a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt 2759af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt if (server_random_first) { 2760af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt os_memcpy(rnd, ssl->s3->server_random, SSL3_RANDOM_SIZE); 2761af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt os_memcpy(rnd + SSL3_RANDOM_SIZE, ssl->s3->client_random, 2762af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt SSL3_RANDOM_SIZE); 2763af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt } else { 2764af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt os_memcpy(rnd, ssl->s3->client_random, SSL3_RANDOM_SIZE); 2765af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt os_memcpy(rnd + SSL3_RANDOM_SIZE, ssl->s3->server_random, 2766af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt SSL3_RANDOM_SIZE); 2767af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt } 2768af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt 2769af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt /* TODO: TLSv1.2 may need another PRF. This could use something closer 2770af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt * to SSL_export_keying_material() design. */ 2771af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt if (tls_prf_sha1_md5(ssl->session->master_key, 2772af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt ssl->session->master_key_length, 2773af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt label, rnd, 2 * SSL3_RANDOM_SIZE, 2774af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt _out, skip + out_len) == 0) 2775af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt ret = 0; 2776af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt os_free(rnd); 2777af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt if (ret == 0 && skip_keyblock) 2778af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt os_memcpy(out, _out + skip, out_len); 2779af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt bin_clear_free(tmp_out, skip); 2780af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt 2781af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt return ret; 2782af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt#endif /* CONFIG_FIPS */ 2783af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt} 2784af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt 2785af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt 27868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_prf(void *tls_ctx, struct tls_connection *conn, 27878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *label, int server_random_first, 2788af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt int skip_keyblock, u8 *out, size_t out_len) 27898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 279061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#if OPENSSL_VERSION_NUMBER >= 0x10001000L 279161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt SSL *ssl; 279261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (conn == NULL) 279361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 2794af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt if (server_random_first || skip_keyblock) 2795af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt return openssl_tls_prf(tls_ctx, conn, label, 2796af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt server_random_first, skip_keyblock, 2797af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt out, out_len); 279861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ssl = conn->ssl; 279961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (SSL_export_keying_material(ssl, out, out_len, label, 280061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_strlen(label), NULL, 0, 0) == 1) { 280161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Using internal PRF"); 280261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 280361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 280461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif 2805af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt return openssl_tls_prf(tls_ctx, conn, label, server_random_first, 2806af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt skip_keyblock, out, out_len); 28078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * 28118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtopenssl_handshake(struct tls_connection *conn, const struct wpabuf *in_data, 28128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int server) 28138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 28158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *out_data; 28168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 28188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Give TLS handshake data from the server (if available) to OpenSSL 28198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * for processing. 28208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 28218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (in_data && 28228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO_write(conn->ssl_in, wpabuf_head(in_data), wpabuf_len(in_data)) 28238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt < 0) { 28248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 28258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Handshake failed - BIO_write"); 28268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 28278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Initiate TLS handshake or continue the existing handshake */ 28308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (server) 28318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = SSL_accept(conn->ssl); 28328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 28338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = SSL_connect(conn->ssl); 28348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res != 1) { 28358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int err = SSL_get_error(conn->ssl, res); 28368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (err == SSL_ERROR_WANT_READ) 28378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: SSL_connect - want " 28388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "more data"); 28398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (err == SSL_ERROR_WANT_WRITE) 28408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: SSL_connect - want to " 28418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "write"); 28428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 28438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, "SSL_connect"); 28448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->failed++; 28458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Get the TLS handshake data to be sent to the server */ 28498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = BIO_ctrl_pending(conn->ssl_out); 28508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: %d bytes pending from ssl_out", res); 28518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out_data = wpabuf_alloc(res); 28528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (out_data == NULL) { 28538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Failed to allocate memory for " 28548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "handshake output (%d bytes)", res); 28558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (BIO_reset(conn->ssl_out) < 0) { 28568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 28578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "BIO_reset failed"); 28588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 28608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = res == 0 ? 0 : BIO_read(conn->ssl_out, wpabuf_mhead(out_data), 28628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res); 28638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 28648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 28658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Handshake failed - BIO_read"); 28668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (BIO_reset(conn->ssl_out) < 0) { 28678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 28688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "BIO_reset failed"); 28698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(out_data); 28718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 28728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put(out_data, res); 28748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return out_data; 28768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * 28808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtopenssl_get_appl_data(struct tls_connection *conn, size_t max_len) 28818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *appl_data; 28838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 28848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt appl_data = wpabuf_alloc(max_len + 100); 28868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (appl_data == NULL) 28878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 28888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = SSL_read(conn->ssl, wpabuf_mhead(appl_data), 28908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_size(appl_data)); 28918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 28928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int err = SSL_get_error(conn->ssl, res); 28938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (err == SSL_ERROR_WANT_READ || 28948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err == SSL_ERROR_WANT_WRITE) { 28958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: No Application Data " 28968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "included"); 28978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 28988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 28998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to read possible " 29008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Application Data"); 29018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(appl_data); 29038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 29048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put(appl_data, res); 29078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_buf_key(MSG_MSGDUMP, "SSL: Application Data in Finished " 29088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "message", appl_data); 29098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return appl_data; 29118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * 29158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtopenssl_connection_handshake(struct tls_connection *conn, 29168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *in_data, 29178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf **appl_data, int server) 29188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *out_data; 29208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (appl_data) 29228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *appl_data = NULL; 29238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out_data = openssl_handshake(conn, in_data, server); 29258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (out_data == NULL) 29268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 292726af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen if (conn->invalid_hb_used) { 292826af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen wpa_printf(MSG_INFO, "TLS: Heartbeat attack detected - do not send response"); 292926af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen wpabuf_free(out_data); 293026af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen return NULL; 293126af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen } 29328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_is_init_finished(conn->ssl) && appl_data && in_data) 29348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *appl_data = openssl_get_appl_data(conn, wpabuf_len(in_data)); 29358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 293626af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen if (conn->invalid_hb_used) { 293726af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen wpa_printf(MSG_INFO, "TLS: Heartbeat attack detected - do not send response"); 293826af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen if (appl_data) { 293926af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen wpabuf_free(*appl_data); 294026af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen *appl_data = NULL; 294126af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen } 294226af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen wpabuf_free(out_data); 294326af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen return NULL; 294426af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen } 294526af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen 29468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return out_data; 29478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * 29518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttls_connection_handshake(void *ssl_ctx, struct tls_connection *conn, 29528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *in_data, 29538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf **appl_data) 29548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return openssl_connection_handshake(conn, in_data, appl_data, 0); 29568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * tls_connection_server_handshake(void *tls_ctx, 29608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn, 29618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *in_data, 29628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf **appl_data) 29638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return openssl_connection_handshake(conn, in_data, appl_data, 1); 29658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * tls_connection_encrypt(void *tls_ctx, 29698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn, 29708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *in_data) 29718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 29738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 29748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 29768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 29778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Give plaintext data for OpenSSL to encrypt into the TLS tunnel. */ 29798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((res = BIO_reset(conn->ssl_in)) < 0 || 29808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (res = BIO_reset(conn->ssl_out)) < 0) { 29818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, "BIO_reset failed"); 29828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 29838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = SSL_write(conn->ssl, wpabuf_head(in_data), wpabuf_len(in_data)); 29858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 29868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 29878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Encryption failed - SSL_write"); 29888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 29898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Read encrypted data to be sent to the server */ 29928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = wpabuf_alloc(wpabuf_len(in_data) + 300); 29938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 29948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 29958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = BIO_read(conn->ssl_out, wpabuf_mhead(buf), wpabuf_size(buf)); 29968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 29978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 29988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Encryption failed - BIO_read"); 29998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(buf); 30008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 30018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put(buf, res); 30038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 30058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * tls_connection_decrypt(void *tls_ctx, 30098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn, 30108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *in_data) 30118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 30128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 30138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 30148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Give encrypted data from TLS tunnel for OpenSSL to decrypt. */ 30168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = BIO_write(conn->ssl_in, wpabuf_head(in_data), 30178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_len(in_data)); 30188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 30198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 30208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Decryption failed - BIO_write"); 30218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 30228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (BIO_reset(conn->ssl_out) < 0) { 30248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, "BIO_reset failed"); 30258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 30268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Read decrypted data for further processing */ 30298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 30308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Even though we try to disable TLS compression, it is possible that 30318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * this cannot be done with all TLS libraries. Add extra buffer space 30328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to handle the possibility of the decrypted data being longer than 30338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * input data. 30348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 30358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3); 30368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 30378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 30388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = SSL_read(conn->ssl, wpabuf_mhead(buf), wpabuf_size(buf)); 30398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 30408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 30418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Decryption failed - SSL_read"); 30428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(buf); 30438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 30448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put(buf, res); 30468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 304726af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen if (conn->invalid_hb_used) { 304826af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen wpa_printf(MSG_INFO, "TLS: Heartbeat attack detected - do not send response"); 304926af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen wpabuf_free(buf); 305026af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen return NULL; 305126af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen } 305226af48b2fcdee1b88e4092a9078cb7c9bf79da6eJouni Malinen 30538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 30548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_resumed(void *ssl_ctx, struct tls_connection *conn) 30588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3059216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt#if OPENSSL_VERSION_NUMBER >= 0x10001000L 3060216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return conn ? SSL_cache_hit(conn->ssl) : 0; 3061216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt#else 30628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return conn ? conn->ssl->hit : 0; 3063216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt#endif 30648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn, 30688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *ciphers) 30698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 30708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char buf[100], *pos, *end; 30718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *c; 30728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 30738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL || conn->ssl == NULL || ciphers == NULL) 30758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 30768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[0] = '\0'; 30788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = buf; 30798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + sizeof(buf); 30808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt c = ciphers; 30828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (*c != TLS_CIPHER_NONE) { 30838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *suite; 30848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (*c) { 30868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TLS_CIPHER_RC4_SHA: 30878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suite = "RC4-SHA"; 30888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TLS_CIPHER_AES128_SHA: 30908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suite = "AES128-SHA"; 30918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TLS_CIPHER_RSA_DHE_AES128_SHA: 30938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suite = "DHE-RSA-AES128-SHA"; 30948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TLS_CIPHER_ANON_DH_AES128_SHA: 30968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suite = "ADH-AES128-SHA"; 30978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 30998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Unsupported " 31008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "cipher selection: %d", *c); 31018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 31028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, ":%s", suite); 31046c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(end - pos, ret)) 31058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 31078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt c++; 31098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: cipher suites: %s", buf + 1); 31128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_set_cipher_list(conn->ssl, buf + 1) != 1) { 31148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 31158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Cipher suite configuration failed"); 31168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 31178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 31208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_get_cipher(void *ssl_ctx, struct tls_connection *conn, 31248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *buf, size_t buflen) 31258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 31268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *name; 31278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL || conn->ssl == NULL) 31288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 31298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name = SSL_get_cipher(conn->ssl); 31318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (name == NULL) 31328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 31338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(buf, name, buflen); 31358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 31368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_enable_workaround(void *ssl_ctx, 31408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn) 31418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 31428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_options(conn->ssl, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS); 31438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 31458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) 31498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* ClientHello TLS extensions require a patch to openssl, so this function is 31508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * commented out unless explicitly needed for EAP-FAST in order to be able to 31518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * build this file with unmodified openssl. */ 31528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_client_hello_ext(void *ssl_ctx, struct tls_connection *conn, 31538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ext_type, const u8 *data, 31548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t data_len) 31558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 31568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL || conn->ssl == NULL || ext_type != 35) 31578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 31588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_set_session_ticket_ext(conn->ssl, (void *) data, 31608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data_len) != 1) 31618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 31628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 31648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */ 31668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_get_failed(void *ssl_ctx, struct tls_connection *conn) 31698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 31708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 31718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 31728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return conn->failed; 31738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_get_read_alerts(void *ssl_ctx, struct tls_connection *conn) 31778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 31788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 31798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 31808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return conn->read_alerts; 31818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_get_write_alerts(void *ssl_ctx, struct tls_connection *conn) 31858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 31868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 31878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 31888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return conn->write_alerts; 31898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 319234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#ifdef HAVE_OCSP 319334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 319434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidtstatic void ocsp_debug_print_resp(OCSP_RESPONSE *rsp) 319534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt{ 319634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#ifndef CONFIG_NO_STDOUT_DEBUG 319734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt BIO *out; 319834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt size_t rlen; 319934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt char *txt; 320034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt int res; 320134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 320234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (wpa_debug_level > MSG_DEBUG) 320334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return; 320434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 320534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt out = BIO_new(BIO_s_mem()); 320634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (!out) 320734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return; 320834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 320934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_RESPONSE_print(out, rsp, 0); 321034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt rlen = BIO_ctrl_pending(out); 321134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt txt = os_malloc(rlen + 1); 321234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (!txt) { 321334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt BIO_free(out); 321434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return; 321534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 321634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 321734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt res = BIO_read(out, txt, rlen); 321834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (res > 0) { 321934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt txt[res] = '\0'; 322034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: OCSP Response\n%s", txt); 322134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 322234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt os_free(txt); 322334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt BIO_free(out); 322434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#endif /* CONFIG_NO_STDOUT_DEBUG */ 322534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt} 322634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 322734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 3228717574375e969e8272c6d1a26137286eac158abbDmitry Shmidtstatic void debug_print_cert(X509 *cert, const char *title) 3229717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt{ 3230717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt#ifndef CONFIG_NO_STDOUT_DEBUG 3231717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt BIO *out; 3232717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt size_t rlen; 3233717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt char *txt; 3234717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt int res; 3235717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt 3236717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt if (wpa_debug_level > MSG_DEBUG) 3237717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt return; 3238717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt 3239717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt out = BIO_new(BIO_s_mem()); 3240717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt if (!out) 3241717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt return; 3242717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt 3243717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt X509_print(out, cert); 3244717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt rlen = BIO_ctrl_pending(out); 3245717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt txt = os_malloc(rlen + 1); 3246717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt if (!txt) { 3247717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt BIO_free(out); 3248717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt return; 3249717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt } 3250717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt 3251717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt res = BIO_read(out, txt, rlen); 3252717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt if (res > 0) { 3253717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt txt[res] = '\0'; 3254717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s\n%s", title, txt); 3255717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt } 3256717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt os_free(txt); 3257717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt 3258717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt BIO_free(out); 3259717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt#endif /* CONFIG_NO_STDOUT_DEBUG */ 3260717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt} 3261717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt 3262717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt 326334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidtstatic int ocsp_resp_cb(SSL *s, void *arg) 326434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt{ 326534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt struct tls_connection *conn = arg; 326634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt const unsigned char *p; 326734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt int len, status, reason; 326834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_RESPONSE *rsp; 326934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_BASICRESP *basic; 327034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_CERTID *id; 327134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt ASN1_GENERALIZEDTIME *produced_at, *this_update, *next_update; 3272fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt X509_STORE *store; 3273fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt STACK_OF(X509) *certs = NULL; 327434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 327534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt len = SSL_get_tlsext_status_ocsp_resp(s, &p); 327634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (!p) { 327734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: No OCSP response received"); 327834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return (conn->flags & TLS_CONN_REQUIRE_OCSP) ? 0 : 1; 327934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 328034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 328134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "OpenSSL: OCSP response", p, len); 328234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 328334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt rsp = d2i_OCSP_RESPONSE(NULL, &p, len); 328434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (!rsp) { 328534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_INFO, "OpenSSL: Failed to parse OCSP response"); 328634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return 0; 328734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 328834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 328934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt ocsp_debug_print_resp(rsp); 329034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 329134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt status = OCSP_response_status(rsp); 329234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) { 329334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_INFO, "OpenSSL: OCSP responder error %d (%s)", 329434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt status, OCSP_response_status_str(status)); 329534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return 0; 329634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 329734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 329834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt basic = OCSP_response_get1_basic(rsp); 329934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (!basic) { 330034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_INFO, "OpenSSL: Could not find BasicOCSPResponse"); 330134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return 0; 330234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 330334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 3304216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt store = SSL_CTX_get_cert_store(conn->ssl_ctx); 3305fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (conn->peer_issuer) { 3306717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt debug_print_cert(conn->peer_issuer, "Add OCSP issuer"); 3307fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 3308fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (X509_STORE_add_cert(store, conn->peer_issuer) != 1) { 3309fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 33107f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt "OpenSSL: Could not add issuer to certificate store"); 3311fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 3312fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt certs = sk_X509_new_null(); 3313fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (certs) { 3314fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt X509 *cert; 3315fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt cert = X509_dup(conn->peer_issuer); 3316fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (cert && !sk_X509_push(certs, cert)) { 3317fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt tls_show_errors( 3318fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt MSG_INFO, __func__, 33197f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt "OpenSSL: Could not add issuer to OCSP responder trust store"); 3320fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt X509_free(cert); 3321fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt sk_X509_free(certs); 3322fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt certs = NULL; 3323fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 33247f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt if (certs && conn->peer_issuer_issuer) { 3325fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt cert = X509_dup(conn->peer_issuer_issuer); 3326fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (cert && !sk_X509_push(certs, cert)) { 3327fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt tls_show_errors( 3328fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt MSG_INFO, __func__, 33297f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt "OpenSSL: Could not add issuer's issuer to OCSP responder trust store"); 3330fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt X509_free(cert); 3331fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 3332fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 3333fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 3334fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 3335fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 3336fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt status = OCSP_basic_verify(basic, certs, store, OCSP_TRUSTOTHER); 3337fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt sk_X509_pop_free(certs, X509_free); 333834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (status <= 0) { 333934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 334034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt "OpenSSL: OCSP response failed verification"); 334134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_BASICRESP_free(basic); 334234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_RESPONSE_free(rsp); 334334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return 0; 334434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 334534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 334634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: OCSP response verification succeeded"); 334734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 33485605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (!conn->peer_cert) { 33495605286c30e1701491bd3af974ae423727750eddDmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Peer certificate not available for OCSP status check"); 33505605286c30e1701491bd3af974ae423727750eddDmitry Shmidt OCSP_BASICRESP_free(basic); 33515605286c30e1701491bd3af974ae423727750eddDmitry Shmidt OCSP_RESPONSE_free(rsp); 33525605286c30e1701491bd3af974ae423727750eddDmitry Shmidt return 0; 33535605286c30e1701491bd3af974ae423727750eddDmitry Shmidt } 33545605286c30e1701491bd3af974ae423727750eddDmitry Shmidt 33555605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (!conn->peer_issuer) { 33565605286c30e1701491bd3af974ae423727750eddDmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Peer issuer certificate not available for OCSP status check"); 335734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_BASICRESP_free(basic); 335834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_RESPONSE_free(rsp); 335934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return 0; 336034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 336134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 336234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt id = OCSP_cert_to_id(NULL, conn->peer_cert, conn->peer_issuer); 336334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (!id) { 336434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Could not create OCSP certificate identifier"); 336534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_BASICRESP_free(basic); 336634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_RESPONSE_free(rsp); 336734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return 0; 336834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 336934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 337034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (!OCSP_resp_find_status(basic, id, &status, &reason, &produced_at, 337134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt &this_update, &next_update)) { 337234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_INFO, "OpenSSL: Could not find current server certificate from OCSP response%s", 337334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt (conn->flags & TLS_CONN_REQUIRE_OCSP) ? "" : 337434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt " (OCSP not required)"); 337534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_BASICRESP_free(basic); 337634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_RESPONSE_free(rsp); 337734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return (conn->flags & TLS_CONN_REQUIRE_OCSP) ? 0 : 1; 337834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 337934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 338034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (!OCSP_check_validity(this_update, next_update, 5 * 60, -1)) { 338134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 338234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt "OpenSSL: OCSP status times invalid"); 338334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_BASICRESP_free(basic); 338434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_RESPONSE_free(rsp); 338534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return 0; 338634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 338734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 338834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_BASICRESP_free(basic); 338934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_RESPONSE_free(rsp); 339034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 339134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status for server certificate: %s", 339234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt OCSP_cert_status_str(status)); 339334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 339434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (status == V_OCSP_CERTSTATUS_GOOD) 339534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return 1; 339634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (status == V_OCSP_CERTSTATUS_REVOKED) 339734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return 0; 339834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (conn->flags & TLS_CONN_REQUIRE_OCSP) { 339934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status unknown, but OCSP required"); 340034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return 0; 340134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 3402051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status unknown, but OCSP was not required, so allow connection to continue"); 340334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return 1; 340434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt} 340534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 340634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 340734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidtstatic int ocsp_status_cb(SSL *s, void *arg) 340834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt{ 340934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt char *tmp; 341034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt char *resp; 341134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt size_t len; 341234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 341334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (tls_global->ocsp_stapling_response == NULL) { 341434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status callback - no response configured"); 341534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return SSL_TLSEXT_ERR_OK; 341634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 341734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 341834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt resp = os_readfile(tls_global->ocsp_stapling_response, &len); 341934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (resp == NULL) { 342034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status callback - could not read response file"); 342134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt /* TODO: Build OCSPResponse with responseStatus = internalError 342234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt */ 342334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return SSL_TLSEXT_ERR_OK; 342434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 342534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status callback - send cached response"); 342634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt tmp = OPENSSL_malloc(len); 342734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (tmp == NULL) { 342834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt os_free(resp); 342934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return SSL_TLSEXT_ERR_ALERT_FATAL; 343034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 343134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 343234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt os_memcpy(tmp, resp, len); 343334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt os_free(resp); 343434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt SSL_set_tlsext_status_ocsp_resp(s, tmp, len); 343534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 343634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return SSL_TLSEXT_ERR_OK; 343734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt} 343834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 343934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#endif /* HAVE_OCSP */ 344034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 344134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 34428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_set_params(void *tls_ctx, struct tls_connection *conn, 34438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct tls_connection_params *params) 34448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 34458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 34468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned long err; 34476c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt int can_pkcs11 = 0; 34486c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt const char *key_id = params->key_id; 34496c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt const char *cert_id = params->cert_id; 34506c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt const char *ca_cert_id = params->ca_cert_id; 34516c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt const char *engine_id = params->engine ? params->engine_id : NULL; 34528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 34548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 34558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34566c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* 34576c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * If the engine isn't explicitly configured, and any of the 34586c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * cert/key fields are actually PKCS#11 URIs, then automatically 34596c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * use the PKCS#11 ENGINE. 34606c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt */ 34616c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!engine_id || os_strcmp(engine_id, "pkcs11") == 0) 34626c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt can_pkcs11 = 1; 34636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 34646c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!key_id && params->private_key && can_pkcs11 && 34656c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_strncmp(params->private_key, "pkcs11:", 7) == 0) { 34666c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt can_pkcs11 = 2; 34676c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt key_id = params->private_key; 34686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 34696c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 34706c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!cert_id && params->client_cert && can_pkcs11 && 34716c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_strncmp(params->client_cert, "pkcs11:", 7) == 0) { 34726c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt can_pkcs11 = 2; 34736c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt cert_id = params->client_cert; 34746c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 34756c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 34766c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!ca_cert_id && params->ca_cert && can_pkcs11 && 34776c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_strncmp(params->ca_cert, "pkcs11:", 7) == 0) { 34786c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt can_pkcs11 = 2; 34796c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ca_cert_id = params->ca_cert; 34806c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 34816c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 34826c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* If we need to automatically enable the PKCS#11 ENGINE, do so. */ 34836c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (can_pkcs11 == 2 && !engine_id) 34846c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt engine_id = "pkcs11"; 34856c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 34866c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (params->flags & TLS_CONN_EAP_FAST) { 34876c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, 34886c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "OpenSSL: Use TLSv1_method() for EAP-FAST"); 34896c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (SSL_set_ssl_method(conn->ssl, TLSv1_method()) != 1) { 34906c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt tls_show_errors(MSG_INFO, __func__, 34916c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "Failed to set TLSv1_method() for EAP-FAST"); 34926c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return -1; 34936c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 34946c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 34956c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 34968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while ((err = ERR_get_error())) { 34978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "%s: Clearing pending SSL error: %s", 34988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__, ERR_error_string(err, NULL)); 34998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 35008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35016c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (engine_id) { 35028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Initializing TLS engine"); 35036c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ret = tls_engine_init(conn, engine_id, params->pin, 35046c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt key_id, cert_id, ca_cert_id); 35058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret) 35068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 35078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 35088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_connection_set_subject_match(conn, 35098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->subject_match, 3510051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt params->altsubject_match, 35112f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt params->suffix_match, 35122f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt params->domain_match)) 35138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 35148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35156c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (engine_id && ca_cert_id) { 35168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_connection_engine_ca_cert(tls_ctx, conn, 35176c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ca_cert_id)) 35188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED; 35198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (tls_connection_ca_cert(tls_ctx, conn, params->ca_cert, 35208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->ca_cert_blob, 35218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->ca_cert_blob_len, 35228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->ca_path)) 35238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 35248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35256c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (engine_id && cert_id) { 35266c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (tls_connection_engine_client_cert(conn, cert_id)) 35278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED; 35288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (tls_connection_client_cert(conn, params->client_cert, 35298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->client_cert_blob, 35308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->client_cert_blob_len)) 35318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 35328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35336c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (engine_id && key_id) { 35348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Using private key from engine"); 35358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_connection_engine_private_key(conn)) 35368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED; 35378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (tls_connection_private_key(tls_ctx, conn, 35388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->private_key, 35398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->private_key_passwd, 35408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->private_key_blob, 35418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->private_key_blob_len)) { 35428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to load private key '%s'", 35438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->private_key); 35448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 35458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 35468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_connection_dh(conn, params->dh_file)) { 35488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to load DH file '%s'", 35498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->dh_file); 35508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 35518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 35528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35536c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (params->openssl_ciphers && 35546c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt SSL_set_cipher_list(conn->ssl, params->openssl_ciphers) != 1) { 35556c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_INFO, 35566c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "OpenSSL: Failed to set cipher string '%s'", 35576c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt params->openssl_ciphers); 35586c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return -1; 35596c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 35606c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 356161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef SSL_OP_NO_TICKET 356261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (params->flags & TLS_CONN_DISABLE_SESSION_TICKET) 356361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt SSL_set_options(conn->ssl, SSL_OP_NO_TICKET); 356434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#ifdef SSL_clear_options 356561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt else 356661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt SSL_clear_options(conn->ssl, SSL_OP_NO_TICKET); 356734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#endif /* SSL_clear_options */ 356861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* SSL_OP_NO_TICKET */ 356961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 357013ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt#ifdef SSL_OP_NO_TLSv1_1 357113ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt if (params->flags & TLS_CONN_DISABLE_TLSv1_1) 357213ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt SSL_set_options(conn->ssl, SSL_OP_NO_TLSv1_1); 357313ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt else 357413ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt SSL_clear_options(conn->ssl, SSL_OP_NO_TLSv1_1); 357513ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt#endif /* SSL_OP_NO_TLSv1_1 */ 357613ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt#ifdef SSL_OP_NO_TLSv1_2 357713ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt if (params->flags & TLS_CONN_DISABLE_TLSv1_2) 357813ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt SSL_set_options(conn->ssl, SSL_OP_NO_TLSv1_2); 357913ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt else 358013ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt SSL_clear_options(conn->ssl, SSL_OP_NO_TLSv1_2); 358113ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt#endif /* SSL_OP_NO_TLSv1_2 */ 358213ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt 358334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#ifdef HAVE_OCSP 358434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (params->flags & TLS_CONN_REQUEST_OCSP) { 3585fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt SSL_CTX *ssl_ctx = tls_ctx; 358634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt SSL_set_tlsext_status_type(conn->ssl, TLSEXT_STATUSTYPE_ocsp); 358734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt SSL_CTX_set_tlsext_status_cb(ssl_ctx, ocsp_resp_cb); 358834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt SSL_CTX_set_tlsext_status_arg(ssl_ctx, conn); 358934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 359034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#endif /* HAVE_OCSP */ 359134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 3592c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt conn->flags = params->flags; 3593c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt 35948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_get_errors(tls_ctx); 35958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 35978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 35988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_global_set_params(void *tls_ctx, 36018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct tls_connection_params *params) 36028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 36038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX *ssl_ctx = tls_ctx; 36048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned long err; 36058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while ((err = ERR_get_error())) { 36078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "%s: Clearing pending SSL error: %s", 36088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__, ERR_error_string(err, NULL)); 36098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 36108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_global_ca_cert(ssl_ctx, params->ca_cert)) 36128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 36138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_global_client_cert(ssl_ctx, params->client_cert)) 36158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 36168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_global_private_key(ssl_ctx, params->private_key, 36188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->private_key_passwd)) 36198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 36208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_global_dh(ssl_ctx, params->dh_file)) { 36228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to load DH file '%s'", 36238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->dh_file); 36248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 36258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 36268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36276c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (params->openssl_ciphers && 36286c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt SSL_CTX_set_cipher_list(ssl_ctx, params->openssl_ciphers) != 1) { 36296c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_INFO, 36306c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "OpenSSL: Failed to set cipher string '%s'", 36316c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt params->openssl_ciphers); 36326c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return -1; 36336c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 36346c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 363561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef SSL_OP_NO_TICKET 363661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (params->flags & TLS_CONN_DISABLE_SESSION_TICKET) 363761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TICKET); 363834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#ifdef SSL_CTX_clear_options 363961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt else 364061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt SSL_CTX_clear_options(ssl_ctx, SSL_OP_NO_TICKET); 364134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#endif /* SSL_clear_options */ 364261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* SSL_OP_NO_TICKET */ 364361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 364434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#ifdef HAVE_OCSP 364534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt SSL_CTX_set_tlsext_status_cb(ssl_ctx, ocsp_status_cb); 364634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt SSL_CTX_set_tlsext_status_arg(ssl_ctx, ssl_ctx); 364734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt os_free(tls_global->ocsp_stapling_response); 364834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (params->ocsp_stapling_response) 364934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt tls_global->ocsp_stapling_response = 365034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt os_strdup(params->ocsp_stapling_response); 365134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt else 365234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt tls_global->ocsp_stapling_response = NULL; 365334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#endif /* HAVE_OCSP */ 365434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 36558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 36568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 36578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtunsigned int tls_capabilities(void *tls_ctx) 36608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 36618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 36628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 36638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) 36668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Pre-shared secred requires a patch to openssl, so this function is 36678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * commented out unless explicitly needed for EAP-FAST in order to be able to 36688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * build this file with unmodified openssl. */ 36698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36709ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt#ifdef OPENSSL_IS_BORINGSSL 36719ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidtstatic int tls_sess_sec_cb(SSL *s, void *secret, int *secret_len, 36729ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt STACK_OF(SSL_CIPHER) *peer_ciphers, 36739ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt const SSL_CIPHER **cipher, void *arg) 36749ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt#else /* OPENSSL_IS_BORINGSSL */ 36758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_sess_sec_cb(SSL *s, void *secret, int *secret_len, 36768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt STACK_OF(SSL_CIPHER) *peer_ciphers, 36778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CIPHER **cipher, void *arg) 36789ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt#endif /* OPENSSL_IS_BORINGSSL */ 36798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 36808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn = arg; 36818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 36828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL || conn->session_ticket_cb == NULL) 36848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 36858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = conn->session_ticket_cb(conn->session_ticket_cb_ctx, 36878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket, 36888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket_len, 36898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->s3->client_random, 36908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->s3->server_random, secret); 36918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->session_ticket); 36928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket = NULL; 36938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret <= 0) 36958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 36968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *secret_len = SSL_MAX_MASTER_KEY_LENGTH; 36988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 36998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 37008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_session_ticket_ext_cb(SSL *s, const unsigned char *data, 37038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len, void *arg) 37048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 37058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn = arg; 37068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL || conn->session_ticket_cb == NULL) 37088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 37098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s: length=%d", __func__, len); 37118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->session_ticket); 37138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket = NULL; 37148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "OpenSSL: ClientHello SessionTicket " 37168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "extension", data, len); 37178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket = os_malloc(len); 37198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->session_ticket == NULL) 37208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 37218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(conn->session_ticket, data, len); 37238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket_len = len; 37248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 37268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 37278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */ 37288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_set_session_ticket_cb(void *tls_ctx, 37318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn, 37328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_session_ticket_cb cb, 37338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *ctx) 37348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 37358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) 37368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket_cb = cb; 37378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket_cb_ctx = ctx; 37388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cb) { 37408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_set_session_secret_cb(conn->ssl, tls_sess_sec_cb, 37418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn) != 1) 37428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 37438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_session_ticket_ext_cb(conn->ssl, 37448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_session_ticket_ext_cb, conn); 37458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 37468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_set_session_secret_cb(conn->ssl, NULL, NULL) != 1) 37478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 37488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_session_ticket_ext_cb(conn->ssl, NULL, NULL); 37498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 37528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */ 37538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 37548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */ 37558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3756ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 3757ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 3758ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidtint tls_get_library_version(char *buf, size_t buf_len) 3759ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt{ 3760ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return os_snprintf(buf, buf_len, "OpenSSL build=%s run=%s", 3761ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt OPENSSL_VERSION_TEXT, 3762ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt SSLeay_version(SSLEAY_VERSION)); 3763ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt} 3764