tls_openssl.c revision 04949598a23f501be6eec21697465fd46a28840a
18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SSL/TLS interface functions for OpenSSL 3c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt * Copyright (c) 2004-2011, 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#ifdef ANDROID 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <openssl/pem.h> 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "keystore_get.h" 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* ANDROID */ 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto.h" 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "tls.h" 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if OPENSSL_VERSION_NUMBER >= 0x0090800fL 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define OPENSSL_d2i_TYPE const unsigned char ** 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define OPENSSL_d2i_TYPE unsigned char ** 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef SSL_F_SSL_SET_SESSION_TICKET_EXT 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef SSL_OP_NO_TICKET 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Session ticket override patch was merged into OpenSSL 0.9.9 tree on 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 2008-11-15. This version uses a bit different API compared to the old patch. 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define CONFIG_OPENSSL_TICKET_OVERRIDE 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_openssl_ref_count = 0; 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct tls_global { 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void (*event_cb)(void *ctx, enum tls_event ev, 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union tls_event_data *data); 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *cb_ctx; 581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int cert_in_cb; 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct tls_global *tls_global = NULL; 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct tls_connection { 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL *ssl; 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO *ssl_in, *ssl_out; 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_ENGINE 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE *engine; /* functional reference to the engine */ 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EVP_PKEY *private_key; /* the private key if using engine */ 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *subject_match, *altsubject_match; 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int read_alerts, write_alerts, failed; 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_session_ticket_cb session_ticket_cb; 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *session_ticket_cb_ctx; 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* SessionTicket received from OpenSSL hello_extension_cb (server) */ 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *session_ticket; 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t session_ticket_len; 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int ca_cert_verify:1; 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int cert_probe:1; 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int server_cert_only:1; 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 srv_cert_hash[32]; 86c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt 87c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt unsigned int flags; 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_NO_STDOUT_DEBUG 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void _tls_show_errors(void) 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned long err; 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while ((err = ERR_get_error())) { 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Just ignore the errors, since stdout is disabled */ 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define tls_show_errors(l, f, t) _tls_show_errors() 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_NO_STDOUT_DEBUG */ 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void tls_show_errors(int level, const char *func, const char *txt) 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned long err; 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(level, "OpenSSL: %s - %s %s", 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt func, txt, ERR_error_string(ERR_get_error(), NULL)); 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while ((err = ERR_get_error())) { 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "OpenSSL: pending error: %s", 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(err, NULL)); 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_STDOUT_DEBUG */ 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_NATIVE_WINDOWS 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Windows CryptoAPI and access to certificate stores */ 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <wincrypt.h> 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef __MINGW32_VERSION 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * MinGW does not yet include all the needed definitions for CryptoAPI, so 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * define here whatever extra is needed. 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define CERT_SYSTEM_STORE_CURRENT_USER (1 << 16) 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define CERT_STORE_READONLY_FLAG 0x00008000 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define CERT_STORE_OPEN_EXISTING_FLAG 0x00004000 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* __MINGW32_VERSION */ 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct cryptoapi_rsa_data { 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const CERT_CONTEXT *cert; 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HCRYPTPROV crypt_prov; 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD key_spec; 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BOOL free_crypt_prov; 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void cryptoapi_error(const char *msg) 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "CryptoAPI: %s; err=%u", 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg, (unsigned int) GetLastError()); 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int cryptoapi_rsa_pub_enc(int flen, const unsigned char *from, 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char *to, RSA *rsa, int padding) 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s - not implemented", __func__); 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int cryptoapi_rsa_pub_dec(int flen, const unsigned char *from, 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char *to, RSA *rsa, int padding) 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s - not implemented", __func__); 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int cryptoapi_rsa_priv_enc(int flen, const unsigned char *from, 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char *to, RSA *rsa, int padding) 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct cryptoapi_rsa_data *priv = 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (struct cryptoapi_rsa_data *) rsa->meth->app_data; 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HCRYPTHASH hash; 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD hash_size, len, i; 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char *buf = NULL; 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = 0; 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (priv == NULL) { 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_R_PASSED_NULL_PARAMETER); 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (padding != RSA_PKCS1_PADDING) { 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSA_R_UNKNOWN_PADDING_TYPE); 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (flen != 16 /* MD5 */ + 20 /* SHA-1 */) { 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "%s - only MD5-SHA1 hash supported", 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__); 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSA_R_INVALID_MESSAGE_LENGTH); 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptCreateHash(priv->crypt_prov, CALG_SSL3_SHAMD5, 0, 0, &hash)) 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_error("CryptCreateHash failed"); 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = sizeof(hash_size); 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptGetHashParam(hash, HP_HASHSIZE, (BYTE *) &hash_size, &len, 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0)) { 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_error("CryptGetHashParam failed"); 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((int) hash_size != flen) { 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "CryptoAPI: Invalid hash size (%u != %d)", 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned) hash_size, flen); 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSA_R_INVALID_MESSAGE_LENGTH); 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptSetHashParam(hash, HP_HASHVAL, (BYTE * ) from, 0)) { 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_error("CryptSetHashParam failed"); 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = RSA_size(rsa); 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = os_malloc(len); 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) { 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE); 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptSignHash(hash, priv->key_spec, NULL, 0, buf, &len)) { 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_error("CryptSignHash failed"); 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < len; i++) 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt to[i] = buf[len - i - 1]; 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = len; 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidterr: 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CryptDestroyHash(hash); 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int cryptoapi_rsa_priv_dec(int flen, const unsigned char *from, 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char *to, RSA *rsa, int padding) 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s - not implemented", __func__); 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void cryptoapi_free_data(struct cryptoapi_rsa_data *priv) 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (priv == NULL) 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (priv->crypt_prov && priv->free_crypt_prov) 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CryptReleaseContext(priv->crypt_prov, 0); 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (priv->cert) 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CertFreeCertificateContext(priv->cert); 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(priv); 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int cryptoapi_finish(RSA *rsa) 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_free_data((struct cryptoapi_rsa_data *) rsa->meth->app_data); 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free((void *) rsa->meth); 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa->meth = NULL; 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const CERT_CONTEXT * cryptoapi_find_cert(const char *name, DWORD store) 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HCERTSTORE cs; 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const CERT_CONTEXT *ret = NULL; 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cs = CertOpenStore((LPCSTR) CERT_STORE_PROV_SYSTEM, 0, 0, 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt store | CERT_STORE_OPEN_EXISTING_FLAG | 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CERT_STORE_READONLY_FLAG, L"MY"); 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cs == NULL) { 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_error("Failed to open 'My system store'"); 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (strncmp(name, "cert://", 7) == 0) { 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned short wbuf[255]; 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MultiByteToWideChar(CP_ACP, 0, name + 7, -1, wbuf, 255); 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = CertFindCertificateInStore(cs, X509_ASN_ENCODING | 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PKCS_7_ASN_ENCODING, 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0, CERT_FIND_SUBJECT_STR, 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wbuf, NULL); 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (strncmp(name, "hash://", 7) == 0) { 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CRYPT_HASH_BLOB blob; 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len; 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *hash = name + 7; 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char *buf; 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = os_strlen(hash) / 2; 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = os_malloc(len); 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf && hexstr2bin(hash, buf, len) == 0) { 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt blob.cbData = len; 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt blob.pbData = buf; 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = CertFindCertificateInStore(cs, 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_ASN_ENCODING | 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PKCS_7_ASN_ENCODING, 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0, CERT_FIND_HASH, 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &blob, NULL); 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CertCloseStore(cs, 0); 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_cryptoapi_cert(SSL *ssl, const char *name) 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *cert = NULL; 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSA *rsa = NULL, *pub_rsa; 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct cryptoapi_rsa_data *priv; 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSA_METHOD *rsa_meth; 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (name == NULL || 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (strncmp(name, "cert://", 7) != 0 && 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt strncmp(name, "hash://", 7) != 0)) 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priv = os_zalloc(sizeof(*priv)); 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_meth = os_zalloc(sizeof(*rsa_meth)); 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (priv == NULL || rsa_meth == NULL) { 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "CryptoAPI: Failed to allocate memory " 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for CryptoAPI RSA method"); 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(priv); 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(rsa_meth); 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priv->cert = cryptoapi_find_cert(name, CERT_SYSTEM_STORE_CURRENT_USER); 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (priv->cert == NULL) { 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priv->cert = cryptoapi_find_cert( 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name, CERT_SYSTEM_STORE_LOCAL_MACHINE); 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (priv->cert == NULL) { 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "CryptoAPI: Could not find certificate " 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s'", name); 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert = d2i_X509(NULL, (OPENSSL_d2i_TYPE) &priv->cert->pbCertEncoded, 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priv->cert->cbCertEncoded); 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert == NULL) { 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "CryptoAPI: Could not process X509 DER " 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "encoding"); 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CryptAcquireCertificatePrivateKey(priv->cert, 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CRYPT_ACQUIRE_COMPARE_KEY_FLAG, 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, &priv->crypt_prov, 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &priv->key_spec, 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &priv->free_crypt_prov)) { 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_error("Failed to acquire a private key for the " 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate"); 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_meth->name = "Microsoft CryptoAPI RSA Method"; 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_meth->rsa_pub_enc = cryptoapi_rsa_pub_enc; 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_meth->rsa_pub_dec = cryptoapi_rsa_pub_dec; 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_meth->rsa_priv_enc = cryptoapi_rsa_priv_enc; 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_meth->rsa_priv_dec = cryptoapi_rsa_priv_dec; 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_meth->finish = cryptoapi_finish; 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_meth->flags = RSA_METHOD_FLAG_NO_CHECK; 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_meth->app_data = (char *) priv; 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa = RSA_new(); 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rsa == NULL) { 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_R_MALLOC_FAILURE); 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!SSL_use_certificate(ssl, cert)) { 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSA_free(rsa); 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa = NULL; 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pub_rsa = cert->cert_info->key->pkey->pkey.rsa; 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert = NULL; 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa->n = BN_dup(pub_rsa->n); 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa->e = BN_dup(pub_rsa->e); 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!RSA_set_method(rsa, rsa_meth)) 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!SSL_use_RSAPrivateKey(ssl, rsa)) 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSA_free(rsa); 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidterr: 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert) 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rsa) 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RSA_free(rsa); 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(rsa_meth); 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cryptoapi_free_data(priv); 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_cryptoapi_ca_cert(SSL_CTX *ssl_ctx, SSL *ssl, const char *name) 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HCERTSTORE cs; 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PCCERT_CONTEXT ctx = NULL; 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *cert; 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char buf[128]; 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *store; 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef UNICODE 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WCHAR *wstore; 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* UNICODE */ 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (name == NULL || strncmp(name, "cert_store://", 13) != 0) 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt store = name + 13; 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef UNICODE 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wstore = os_malloc((os_strlen(store) + 1) * sizeof(WCHAR)); 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wstore == NULL) 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wsprintf(wstore, L"%S", store); 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cs = CertOpenSystemStore(0, wstore); 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(wstore); 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* UNICODE */ 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cs = CertOpenSystemStore(0, store); 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* UNICODE */ 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cs == NULL) { 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: failed to open system cert store " 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s': error=%d", __func__, store, 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) GetLastError()); 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while ((ctx = CertEnumCertificatesInStore(cs, ctx))) { 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert = d2i_X509(NULL, (OPENSSL_d2i_TYPE) &ctx->pbCertEncoded, 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->cbCertEncoded); 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert == NULL) { 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "CryptoAPI: Could not process " 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "X509 DER encoding for CA cert"); 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_NAME_oneline(X509_get_subject_name(cert), buf, 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(buf)); 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Loaded CA certificate for " 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "system certificate store: subject='%s'", buf); 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!X509_STORE_add_cert(ssl_ctx->cert_store, cert)) { 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_WARNING, __func__, 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to add ca_cert to OpenSSL " 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate store"); 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CertCloseStore(cs, 0)) { 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: failed to close system cert store " 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s': error=%d", __func__, name + 13, 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) GetLastError()); 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_NATIVE_WINDOWS */ 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_cryptoapi_cert(SSL *ssl, const char *name) 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void ssl_info_cb(const SSL *ssl, int where, int ret) 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *str; 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int w; 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: (where=0x%x ret=0x%x)", where, ret); 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt w = where & ~SSL_ST_MASK; 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (w & SSL_ST_CONNECT) 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt str = "SSL_connect"; 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (w & SSL_ST_ACCEPT) 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt str = "SSL_accept"; 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt str = "undefined"; 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (where & SSL_CB_LOOP) { 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: %s:%s", 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt str, SSL_state_string_long(ssl)); 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (where & SSL_CB_ALERT) { 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "SSL: SSL3 alert: %s:%s:%s", 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt where & SSL_CB_READ ? 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "read (remote end reported an error)" : 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "write (local SSL3 detected an error)", 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_alert_type_string_long(ret), 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_alert_desc_string_long(ret)); 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((ret >> 8) == SSL3_AL_FATAL) { 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn = 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_get_app_data((SSL *) ssl); 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (where & SSL_CB_READ) 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->read_alerts++; 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->write_alerts++; 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 53004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (tls_global->event_cb != NULL) { 53104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt union tls_event_data ev; 53204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memset(&ev, 0, sizeof(ev)); 53304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ev.alert.is_local = !(where & SSL_CB_READ); 53404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ev.alert.type = SSL_alert_type_string_long(ret); 53504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ev.alert.description = SSL_alert_desc_string_long(ret); 53604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt tls_global->event_cb(tls_global->cb_ctx, TLS_ALERT, 53704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt &ev); 53804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (where & SSL_CB_EXIT && ret <= 0) { 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: %s:%s in %s", 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt str, ret == 0 ? "failed" : "error", 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_state_string_long(ssl)); 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_ENGINE 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tls_engine_load_dynamic_generic - load any openssl engine 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @pre: an array of commands and values that load an engine initialized 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * in the engine specific function 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @post: an array of commands and values that initialize an already loaded 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * engine (or %NULL if not required) 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @id: the engine id of the engine to load (only required if post is not %NULL 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is a generic function that loads any openssl engine. 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_engine_load_dynamic_generic(const char *pre[], 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *post[], const char *id) 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE *engine; 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *dynamic_id = "dynamic"; 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt engine = ENGINE_by_id(id); 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (engine) { 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE_free(engine); 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: engine '%s' is already " 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "available", id); 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_clear_error(); 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt engine = ENGINE_by_id(dynamic_id); 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (engine == NULL) { 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "ENGINE: Can't find engine %s [%s]", 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dynamic_id, 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Perform the pre commands. This will load the engine. */ 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pre && pre[0]) { 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: '%s' '%s'", pre[0], pre[1]); 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ENGINE_ctrl_cmd_string(engine, pre[0], pre[1], 0) == 0) { 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "ENGINE: ctrl cmd_string failed: " 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%s %s [%s]", pre[0], pre[1], 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE_free(engine); 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pre += 2; 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Free the reference to the "dynamic" engine. The loaded engine can 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * now be looked up using ENGINE_by_id(). 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE_free(engine); 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt engine = ENGINE_by_id(id); 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (engine == NULL) { 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "ENGINE: Can't find engine %s [%s]", 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt id, ERR_error_string(ERR_get_error(), NULL)); 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (post && post[0]) { 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: '%s' '%s'", post[0], post[1]); 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ENGINE_ctrl_cmd_string(engine, post[0], post[1], 0) == 0) { 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: ctrl cmd_string failed:" 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " %s %s [%s]", post[0], post[1], 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE_remove(engine); 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE_free(engine); 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt post += 2; 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE_free(engine); 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tls_engine_load_dynamic_pkcs11 - load the pkcs11 engine provided by opensc 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @pkcs11_so_path: pksc11_so_path from the configuration 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @pcks11_module_path: pkcs11_module_path from the configuration 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_engine_load_dynamic_pkcs11(const char *pkcs11_so_path, 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *pkcs11_module_path) 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *engine_id = "pkcs11"; 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *pre_cmd[] = { 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SO_PATH", NULL /* pkcs11_so_path */, 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ID", NULL /* engine_id */, 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "LIST_ADD", "1", 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* "NO_VCHECK", "1", */ 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "LOAD", NULL, 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, NULL 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt }; 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *post_cmd[] = { 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "MODULE_PATH", NULL /* pkcs11_module_path */, 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, NULL 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt }; 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!pkcs11_so_path || !pkcs11_module_path) 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pre_cmd[1] = pkcs11_so_path; 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pre_cmd[3] = engine_id; 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt post_cmd[1] = pkcs11_module_path; 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: Loading pkcs11 Engine from %s", 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pkcs11_so_path); 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_engine_load_dynamic_generic(pre_cmd, post_cmd, engine_id); 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tls_engine_load_dynamic_opensc - load the opensc engine provided by opensc 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @opensc_so_path: opensc_so_path from the configuration 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_engine_load_dynamic_opensc(const char *opensc_so_path) 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *engine_id = "opensc"; 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *pre_cmd[] = { 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SO_PATH", NULL /* opensc_so_path */, 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ID", NULL /* engine_id */, 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "LIST_ADD", "1", 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "LOAD", NULL, 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, NULL 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt }; 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!opensc_so_path) 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pre_cmd[1] = opensc_so_path; 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pre_cmd[3] = engine_id; 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: Loading OpenSC Engine from %s", 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt opensc_so_path); 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_engine_load_dynamic_generic(pre_cmd, NULL, engine_id); 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid * tls_init(const struct tls_config *conf) 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX *ssl; 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_openssl_ref_count == 0) { 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_global = os_zalloc(sizeof(*tls_global)); 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_global == NULL) 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf) { 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_global->event_cb = conf->event_cb; 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_global->cb_ctx = conf->cb_ctx; 7031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt tls_global->cert_in_cb = conf->cert_in_cb; 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_FIPS 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef OPENSSL_FIPS 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf && conf->fips_mode) { 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!FIPS_mode_set(1)) { 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to enable FIPS " 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "mode"); 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_load_crypto_strings(); 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_print_errors_fp(stderr); 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "Running in FIPS mode"); 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_FIPS */ 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf && conf->fips_mode) { 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "FIPS mode requested, but not " 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "supported"); 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_FIPS */ 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_FIPS */ 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_load_error_strings(); 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_library_init(); 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL) && !defined(OPENSSL_NO_SHA256) 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EVP_add_digest(EVP_sha256()); 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_SHA256 */ 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: if /dev/urandom is available, PRNG is seeded 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * automatically. If this is not the case, random data should 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * be added here. */ 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef PKCS12_FUNCS 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_RC2 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 40-bit RC2 is commonly used in PKCS#12 files, so enable it. 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This is enabled by PKCS12_PBE_add() in OpenSSL 0.9.8 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * versions, but it looks like OpenSSL 1.0.0 does not do that 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * anymore. 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EVP_add_cipher(EVP_rc2_40_cbc()); 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_RC2 */ 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PKCS12_PBE_add(); 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* PKCS12_FUNCS */ 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_openssl_ref_count++; 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssl = SSL_CTX_new(TLSv1_method()); 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssl == NULL) 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_set_info_callback(ssl, ssl_info_cb); 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_ENGINE 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf && 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (conf->opensc_engine_path || conf->pkcs11_engine_path || 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->pkcs11_module_path)) { 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: Loading dynamic engine"); 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_load_ENGINE_strings(); 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE_load_dynamic(); 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_engine_load_dynamic_opensc(conf->opensc_engine_path) || 7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_engine_load_dynamic_pkcs11(conf->pkcs11_engine_path, 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->pkcs11_module_path)) { 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_deinit(ssl); 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ssl; 7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid tls_deinit(void *ssl_ctx) 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX *ssl = ssl_ctx; 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_free(ssl); 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_openssl_ref_count--; 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_openssl_ref_count == 0) { 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_ENGINE 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE_cleanup(); 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CRYPTO_cleanup_all_ex_data(); 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_remove_state(0); 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_free_strings(); 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EVP_cleanup(); 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(tls_global); 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_global = NULL; 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_engine_init(struct tls_connection *conn, const char *engine_id, 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *pin, const char *key_id, 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *cert_id, const char *ca_cert_id) 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_ENGINE 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = -1; 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (engine_id == NULL) { 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "ENGINE: Engine ID not set"); 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 807db3c5a43353099fd4771f3b7a13efae905878ce9Kenny Root#ifndef ANDROID 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pin == NULL) { 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "ENGINE: Smartcard PIN not set"); 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 812db3c5a43353099fd4771f3b7a13efae905878ce9Kenny Root#endif 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key_id == NULL) { 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "ENGINE: Key Id not set"); 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_clear_error(); 819db3c5a43353099fd4771f3b7a13efae905878ce9Kenny Root#ifdef ANDROID 820db3c5a43353099fd4771f3b7a13efae905878ce9Kenny Root ENGINE_load_dynamic(); 821db3c5a43353099fd4771f3b7a13efae905878ce9Kenny Root#endif 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->engine = ENGINE_by_id(engine_id); 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!conn->engine) { 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "ENGINE: engine %s not available [%s]", 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt engine_id, ERR_error_string(ERR_get_error(), NULL)); 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ENGINE_init(conn->engine) != 1) { 8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "ENGINE: engine init failed " 8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(engine: %s) [%s]", engine_id, 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: engine initialized"); 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 836db3c5a43353099fd4771f3b7a13efae905878ce9Kenny Root#ifndef ANDROID 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ENGINE_ctrl_cmd_string(conn->engine, "PIN", pin, 0) == 0) { 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "ENGINE: cannot set pin [%s]", 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 842db3c5a43353099fd4771f3b7a13efae905878ce9Kenny Root#endif 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* load private key first in-case PIN is required for cert */ 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->private_key = ENGINE_load_private_key(conn->engine, 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_id, NULL, NULL); 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!conn->private_key) { 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "ENGINE: cannot load private key with id" 8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " '%s' [%s]", key_id, 8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED; 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* handle a certificate and/or CA certificate */ 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert_id || ca_cert_id) { 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *cmd_name = "LOAD_CERT_CTRL"; 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* test if the engine supports a LOAD_CERT_CTRL */ 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ENGINE_ctrl(conn->engine, ENGINE_CTRL_GET_CMD_FROM_NAME, 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0, (void *)cmd_name, NULL)) { 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "ENGINE: engine does not support" 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " loading certificates"); 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED; 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto err; 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidterr: 8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->engine) { 8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE_free(conn->engine); 8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->engine = NULL; 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->private_key) { 8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EVP_PKEY_free(conn->private_key); 8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->private_key = NULL; 8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_ENGINE */ 8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void tls_engine_deinit(struct tls_connection *conn) 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_ENGINE 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: engine deinit"); 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->private_key) { 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EVP_PKEY_free(conn->private_key); 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->private_key = NULL; 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->engine) { 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ENGINE_finish(conn->engine); 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->engine = NULL; 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_get_errors(void *ssl_ctx) 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int count = 0; 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned long err; 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while ((err = ERR_get_error())) { 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS - SSL error: %s", 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(err, NULL)); 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count++; 9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return count; 9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct tls_connection * tls_connection_init(void *ssl_ctx) 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX *ssl = ssl_ctx; 9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn; 9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt long options; 9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn = os_zalloc(sizeof(*conn)); 9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ssl = SSL_new(ssl); 9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->ssl == NULL) { 9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to initialize new SSL connection"); 9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn); 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_app_data(conn->ssl, conn); 9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_OP_SINGLE_DH_USE; 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef SSL_OP_NO_COMPRESSION 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt options |= SSL_OP_NO_COMPRESSION; 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* SSL_OP_NO_COMPRESSION */ 9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_options(conn->ssl, options); 9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ssl_in = BIO_new(BIO_s_mem()); 9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!conn->ssl_in) { 9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to create a new BIO for ssl_in"); 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_free(conn->ssl); 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn); 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ssl_out = BIO_new(BIO_s_mem()); 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!conn->ssl_out) { 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to create a new BIO for ssl_out"); 9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_free(conn->ssl); 9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO_free(conn->ssl_in); 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn); 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_bio(conn->ssl, conn->ssl_in, conn->ssl_out); 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return conn; 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid tls_connection_deinit(void *ssl_ctx, struct tls_connection *conn) 9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_free(conn->ssl); 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_engine_deinit(conn); 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->subject_match); 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->altsubject_match); 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->session_ticket); 9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn); 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_established(void *ssl_ctx, struct tls_connection *conn) 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return conn ? SSL_is_init_finished(conn->ssl) : 0; 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_shutdown(void *ssl_ctx, struct tls_connection *conn) 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Shutdown previous TLS connection without notifying the peer 9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * because the connection was already terminated in practice 9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * and "close notify" shutdown alert would confuse AS. */ 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_quiet_shutdown(conn->ssl, 1); 9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_shutdown(conn->ssl); 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_match_altsubject_component(X509 *cert, int type, 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *value, size_t len) 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt GENERAL_NAME *gen; 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *ext; 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i, found = 0; 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ext = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL); 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; ext && i < sk_GENERAL_NAME_num(ext); i++) { 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gen = sk_GENERAL_NAME_value(ext, i); 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (gen->type != type) 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strlen((char *) gen->d.ia5->data) == len && 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(value, gen->d.ia5->data, len) == 0) 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt found++; 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return found; 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_match_altsubject(X509 *cert, const char *match) 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int type; 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *pos, *end; 10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len; 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = match; 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt do { 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strncmp(pos, "EMAIL:", 6) == 0) { 10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = GEN_EMAIL; 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 6; 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (os_strncmp(pos, "DNS:", 4) == 0) { 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = GEN_DNS; 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 4; 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (os_strncmp(pos, "URI:", 4) == 0) { 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type = GEN_URI; 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 4; 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Invalid altSubjectName " 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "match '%s'", pos); 10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = os_strchr(pos, ';'); 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (end) { 10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strncmp(end + 1, "EMAIL:", 6) == 0 || 10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strncmp(end + 1, "DNS:", 4) == 0 || 10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strncmp(end + 1, "URI:", 4) == 0) 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = os_strchr(end + 1, ';'); 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end) 10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = end - pos; 10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = os_strlen(pos); 10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_match_altsubject_component(cert, type, pos, len) > 0) 10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = end + 1; 10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } while (end); 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic enum tls_fail_reason openssl_tls_fail_reason(int err) 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (err) { 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_CERT_REVOKED: 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_FAIL_REVOKED; 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_CERT_NOT_YET_VALID: 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_CRL_NOT_YET_VALID: 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_FAIL_NOT_YET_VALID; 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_CERT_HAS_EXPIRED: 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_CRL_HAS_EXPIRED: 10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_FAIL_EXPIRED; 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_UNABLE_TO_GET_CRL: 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER: 10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: 10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_CERT_CHAIN_TOO_LONG: 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_PATH_LENGTH_EXCEEDED: 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_INVALID_CA: 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_FAIL_UNTRUSTED; 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: 10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: 10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_CERT_UNTRUSTED: 10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case X509_V_ERR_CERT_REJECTED: 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_FAIL_BAD_CERTIFICATE; 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_FAIL_UNSPECIFIED; 11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * get_x509_cert(X509 *cert) 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *tmp; 11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int cert_len = i2d_X509(cert, NULL); 11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert_len <= 0) 11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = wpabuf_alloc(cert_len); 11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = wpabuf_put(buf, cert_len); 11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i2d_X509(cert, &tmp); 11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void openssl_tls_fail_event(struct tls_connection *conn, 11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *err_cert, int err, int depth, 11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *subject, const char *err_str, 11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum tls_fail_reason reason) 11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union tls_event_data ev; 11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *cert = NULL; 11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_global->event_cb == NULL) 11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert = get_x509_cert(err_cert); 11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&ev, 0, sizeof(ev)); 11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.cert_fail.reason = reason != TLS_FAIL_UNSPECIFIED ? 11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reason : openssl_tls_fail_reason(err); 11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.cert_fail.depth = depth; 11398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.cert_fail.subject = subject; 11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.cert_fail.reason_txt = err_str; 11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.cert_fail.cert = cert; 11428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_global->event_cb(tls_global->cb_ctx, TLS_CERT_CHAIN_FAILURE, &ev); 11438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(cert); 11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void openssl_tls_cert_event(struct tls_connection *conn, 11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *err_cert, int depth, 11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *subject) 11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *cert = NULL; 11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union tls_event_data ev; 11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_SHA256 11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 hash[32]; 11558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_SHA256 */ 11568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_global->event_cb == NULL) 11588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 11598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&ev, 0, sizeof(ev)); 11611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (conn->cert_probe || tls_global->cert_in_cb) { 11628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert = get_x509_cert(err_cert); 11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.peer_cert.cert = cert; 11648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_SHA256 11668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert) { 11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr[1]; 11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len[1]; 11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr[0] = wpabuf_head(cert); 11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len[0] = wpabuf_len(cert); 11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sha256_vector(1, addr, len, hash) == 0) { 11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.peer_cert.hash = hash; 11738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.peer_cert.hash_len = sizeof(hash); 11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_SHA256 */ 11778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.peer_cert.depth = depth; 11788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ev.peer_cert.subject = subject; 11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_global->event_cb(tls_global->cb_ctx, TLS_PEER_CERTIFICATE, &ev); 11808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(cert); 11818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx) 11858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char buf[256]; 11878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *err_cert; 11888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int err, depth; 11898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL *ssl; 11908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn; 11918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *match, *altmatch; 11928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *err_str; 11938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err_cert = X509_STORE_CTX_get_current_cert(x509_ctx); 11958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err = X509_STORE_CTX_get_error(x509_ctx); 11968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt depth = X509_STORE_CTX_get_error_depth(x509_ctx); 11978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssl = X509_STORE_CTX_get_ex_data(x509_ctx, 11988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_get_ex_data_X509_STORE_CTX_idx()); 11998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof(buf)); 12008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn = SSL_get_app_data(ssl); 12028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 12038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 12048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt match = conn->subject_match; 12058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt altmatch = conn->altsubject_match; 12068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!preverify_ok && !conn->ca_cert_verify) 12088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt preverify_ok = 1; 12098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!preverify_ok && depth > 0 && conn->server_cert_only) 12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt preverify_ok = 1; 1211c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt if (!preverify_ok && (conn->flags & TLS_CONN_DISABLE_TIME_CHECKS) && 1212c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt (err == X509_V_ERR_CERT_HAS_EXPIRED || 1213c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt err == X509_V_ERR_CERT_NOT_YET_VALID)) { 1214c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Ignore certificate validity " 1215c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt "time mismatch"); 1216c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt preverify_ok = 1; 1217c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt } 12188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err_str = X509_verify_cert_error_string(err); 12208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_SHA256 12228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (preverify_ok && depth == 0 && conn->server_cert_only) { 12238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *cert; 12248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert = get_x509_cert(err_cert); 12258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!cert) { 12268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Could not fetch " 12278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "server certificate data"); 12288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt preverify_ok = 0; 12298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 12308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 hash[32]; 12318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr[1]; 12328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len[1]; 12338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr[0] = wpabuf_head(cert); 12348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len[0] = wpabuf_len(cert); 12358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sha256_vector(1, addr, len, hash) < 0 || 12368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(conn->srv_cert_hash, hash, 32) != 0) { 12378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err_str = "Server certificate mismatch"; 12388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN; 12398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt preverify_ok = 0; 12408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(cert); 12428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_SHA256 */ 12458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!preverify_ok) { 12478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "TLS: Certificate verification failed," 12488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " error %d (%s) depth %d for '%s'", err, err_str, 12498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt depth, buf); 12508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt openssl_tls_fail_event(conn, err_cert, err, depth, buf, 12518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err_str, TLS_FAIL_UNSPECIFIED); 12528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return preverify_ok; 12538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: tls_verify_cb - preverify_ok=%d " 12568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "err=%d (%s) ca_cert_verify=%d depth=%d buf='%s'", 12578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt preverify_ok, err, err_str, 12588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ca_cert_verify, depth, buf); 12598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (depth == 0 && match && os_strstr(buf, match) == NULL) { 12608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "TLS: Subject '%s' did not " 12618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "match with '%s'", buf, match); 12628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt preverify_ok = 0; 12638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt openssl_tls_fail_event(conn, err_cert, err, depth, buf, 12648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Subject mismatch", 12658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_FAIL_SUBJECT_MISMATCH); 12668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (depth == 0 && altmatch && 12678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !tls_match_altsubject(err_cert, altmatch)) { 12688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "TLS: altSubjectName match " 12698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s' not found", altmatch); 12708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt preverify_ok = 0; 12718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt openssl_tls_fail_event(conn, err_cert, err, depth, buf, 12728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "AltSubject mismatch", 12738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_FAIL_ALTSUBJECT_MISMATCH); 12748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 12758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt openssl_tls_cert_event(conn, err_cert, depth, buf); 12768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->cert_probe && preverify_ok && depth == 0) { 12788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Reject server certificate " 12798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "on probe-only run"); 12808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt preverify_ok = 0; 12818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt openssl_tls_fail_event(conn, err_cert, err, depth, buf, 12828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Server certificate chain probe", 12838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_FAIL_SERVER_CHAIN_PROBE); 12848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 128604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (preverify_ok && tls_global->event_cb != NULL) 128704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt tls_global->event_cb(tls_global->cb_ctx, 128804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt TLS_CERT_CHAIN_SUCCESS, NULL); 128904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 12908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return preverify_ok; 12918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_STDIO 12958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_load_ca_der(void *_ssl_ctx, const char *ca_cert) 12968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX *ssl_ctx = _ssl_ctx; 12988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_LOOKUP *lookup; 12998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = 0; 13008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt lookup = X509_STORE_add_lookup(ssl_ctx->cert_store, 13028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_LOOKUP_file()); 13038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (lookup == NULL) { 13048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_WARNING, __func__, 13058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed add lookup for X509 store"); 13068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!X509_LOOKUP_load_file(lookup, ca_cert, X509_FILETYPE_ASN1)) { 13108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned long err = ERR_peek_error(); 13118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_WARNING, __func__, 13128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed load CA in DER format"); 13138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ERR_GET_LIB(err) == ERR_LIB_X509 && 13148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_GET_REASON(err) == X509_R_CERT_ALREADY_IN_HASH_TABLE) { 13158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - ignoring " 13168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "cert already in hash table error", 13178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__); 13188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 13198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 13208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 13238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_STDIO */ 13258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef ANDROID 13288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic BIO * BIO_from_keystore(const char *key) 13298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO *bio = NULL; 13318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char value[KEYSTORE_MESSAGE_SIZE]; 13328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int length = keystore_get(key, strlen(key), value); 13338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (length != -1 && (bio = BIO_new(BIO_s_mem())) != NULL) 13348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO_write(bio, value, length); 13358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return bio; 13368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* ANDROID */ 13388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_connection_ca_cert(void *_ssl_ctx, struct tls_connection *conn, 13418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *ca_cert, const u8 *ca_cert_blob, 13428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t ca_cert_blob_len, const char *ca_path) 13438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX *ssl_ctx = _ssl_ctx; 13458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 13478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Remove previously configured trusted CA certificates before adding 13488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * new ones. 13498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 13508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_STORE_free(ssl_ctx->cert_store); 13518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssl_ctx->cert_store = X509_STORE_new(); 13528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssl_ctx->cert_store == NULL) { 13538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - failed to allocate new " 13548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate store", __func__); 13558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb); 13598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ca_cert_verify = 1; 13608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ca_cert && os_strncmp(ca_cert, "probe://", 8) == 0) { 13628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Probe for server certificate " 13638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "chain"); 13648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->cert_probe = 1; 13658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ca_cert_verify = 0; 13668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 13678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ca_cert && os_strncmp(ca_cert, "hash://", 7) == 0) { 13708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_SHA256 13718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *pos = ca_cert + 7; 13728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strncmp(pos, "server/sha256/", 14) != 0) { 13738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Unsupported ca_cert " 13748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "hash value '%s'", ca_cert); 13758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 14; 13788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strlen(pos) != 32 * 2) { 13798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Unexpected SHA256 " 13808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "hash length in ca_cert '%s'", ca_cert); 13818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hexstr2bin(pos, conn->srv_cert_hash, 32) < 0) { 13848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Invalid SHA256 hash " 13858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "value in ca_cert '%s'", ca_cert); 13868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->server_cert_only = 1; 13898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Checking only server " 13908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate match"); 13918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 13928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_SHA256 */ 13938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "No SHA256 included in the build - " 13948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "cannot validate server certificate hash"); 13958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_SHA256 */ 13978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ca_cert_blob) { 14008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *cert = d2i_X509(NULL, (OPENSSL_d2i_TYPE) &ca_cert_blob, 14018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ca_cert_blob_len); 14028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert == NULL) { 14038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_WARNING, __func__, 14048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to parse ca_cert_blob"); 14058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!X509_STORE_add_cert(ssl_ctx->cert_store, cert)) { 14098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned long err = ERR_peek_error(); 14108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_WARNING, __func__, 14118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to add ca_cert_blob to " 14128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate store"); 14138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ERR_GET_LIB(err) == ERR_LIB_X509 && 14148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_GET_REASON(err) == 14158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_R_CERT_ALREADY_IN_HASH_TABLE) { 14168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - ignoring " 14178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "cert already in hash table error", 14188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__); 14198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 14208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 14218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 14258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - added ca_cert_blob " 14268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "to certificate store", __func__); 14278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 14288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef ANDROID 14318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ca_cert && os_strncmp("keystore://", ca_cert, 11) == 0) { 14328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO *bio = BIO_from_keystore(&ca_cert[11]); 14338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt STACK_OF(X509_INFO) *stack = NULL; 14348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 14358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bio) { 14378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt stack = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL); 14388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO_free(bio); 14398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!stack) 14418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < sk_X509_INFO_num(stack); ++i) { 14448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_INFO *info = sk_X509_INFO_value(stack, i); 14458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (info->x509) { 14468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_STORE_add_cert(ssl_ctx->cert_store, 14478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt info->x509); 14488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (info->crl) { 14508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_STORE_add_crl(ssl_ctx->cert_store, 14518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt info->crl); 14528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sk_X509_INFO_pop_free(stack, X509_INFO_free); 14558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb); 14568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 14578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* ANDROID */ 14598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_NATIVE_WINDOWS 14618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ca_cert && tls_cryptoapi_ca_cert(ssl_ctx, conn->ssl, ca_cert) == 14628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) { 14638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Added CA certificates from " 14648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "system certificate store"); 14658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 14668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 14688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ca_cert || ca_path) { 14708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_STDIO 14718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_CTX_load_verify_locations(ssl_ctx, ca_cert, ca_path) != 14728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1) { 14738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_WARNING, __func__, 14748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to load root certificates"); 14758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ca_cert && 14768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_load_ca_der(ssl_ctx, ca_cert) == 0) { 14778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - loaded " 14788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "DER format CA certificate", 14798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__); 14808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 14818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 14838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Trusted root " 14848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate(s) loaded"); 14858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_get_errors(ssl_ctx); 14868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_STDIO */ 14888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", 14898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__); 14908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_STDIO */ 14928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 14938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* No ca_cert configured - do not try to verify server 14948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * certificate */ 14958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ca_cert_verify = 0; 14968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 14998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_global_ca_cert(SSL_CTX *ssl_ctx, const char *ca_cert) 15038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ca_cert) { 15058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_CTX_load_verify_locations(ssl_ctx, ca_cert, NULL) != 1) 15068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 15078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_WARNING, __func__, 15088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to load root certificates"); 15098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 15108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Trusted root " 15138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate(s) loaded"); 15148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_STDIO 15168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Add the same CAs to the client certificate requests */ 15178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_set_client_CA_list(ssl_ctx, 15188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_load_client_CA_file(ca_cert)); 15198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_STDIO */ 15208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 15238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_global_set_verify(void *ssl_ctx, int check_crl) 15278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int flags; 15298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (check_crl) { 15318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_STORE *cs = SSL_CTX_get_cert_store(ssl_ctx); 15328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cs == NULL) { 15338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, "Failed to get " 15348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate store when enabling " 15358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "check_crl"); 15368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 15378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt flags = X509_V_FLAG_CRL_CHECK; 15398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (check_crl == 2) 15408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt flags |= X509_V_FLAG_CRL_CHECK_ALL; 15418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_STORE_set_flags(cs, flags); 15428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 15448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_connection_set_subject_match(struct tls_connection *conn, 15488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *subject_match, 15498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *altsubject_match) 15508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->subject_match); 15528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->subject_match = NULL; 15538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (subject_match) { 15548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->subject_match = os_strdup(subject_match); 15558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->subject_match == NULL) 15568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 15578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->altsubject_match); 15608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->altsubject_match = NULL; 15618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (altsubject_match) { 15628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->altsubject_match = os_strdup(altsubject_match); 15638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->altsubject_match == NULL) 15648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 15658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 15688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn, 15728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int verify_peer) 15738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt static int counter = 0; 15758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 15778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 15788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (verify_peer) { 15808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ca_cert_verify = 1; 15818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_verify(conn->ssl, SSL_VERIFY_PEER | 15828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_VERIFY_FAIL_IF_NO_PEER_CERT | 15838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_VERIFY_CLIENT_ONCE, tls_verify_cb); 15848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 15858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ca_cert_verify = 0; 15868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_verify(conn->ssl, SSL_VERIFY_NONE, NULL); 15878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_accept_state(conn->ssl); 15908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 15928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Set session id context in order to avoid fatal errors when client 15938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tries to resume a session. However, set the context to a unique 15948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * value in order to effectively disable session resumption for now 15958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * since not all areas of the server code are ready for it (e.g., 15968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP-TTLS needs special handling for Phase 2 after abbreviated TLS 15978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * handshake). 15988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 15998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt counter++; 16008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_session_id_context(conn->ssl, 16018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (const unsigned char *) &counter, 16028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(counter)); 16038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 16058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_connection_client_cert(struct tls_connection *conn, 16098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *client_cert, 16108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *client_cert_blob, 16118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t client_cert_blob_len) 16128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (client_cert == NULL && client_cert_blob == NULL) 16148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 16158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (client_cert_blob && 16178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_use_certificate_ASN1(conn->ssl, (u8 *) client_cert_blob, 16188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt client_cert_blob_len) == 1) { 16198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_ASN1 --> " 16208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "OK"); 16218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 16228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (client_cert_blob) { 16238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_DEBUG, __func__, 16248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SSL_use_certificate_ASN1 failed"); 16258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (client_cert == NULL) 16288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 16298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef ANDROID 16318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strncmp("keystore://", client_cert, 11) == 0) { 16328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO *bio = BIO_from_keystore(&client_cert[11]); 16338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *x509 = NULL; 16348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = -1; 16358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bio) { 16368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL); 16378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO_free(bio); 16388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (x509) { 16408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_certificate(conn->ssl, x509) == 1) 16418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = 0; 16428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(x509); 16438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 16458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* ANDROID */ 16478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_STDIO 16498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_certificate_file(conn->ssl, client_cert, 16508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_FILETYPE_ASN1) == 1) { 16518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_file (DER)" 16528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " --> OK"); 16538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 16548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_certificate_file(conn->ssl, client_cert, 16578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_FILETYPE_PEM) == 1) { 16588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_clear_error(); 16598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_file (PEM)" 16608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " --> OK"); 16618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 16628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_DEBUG, __func__, 16658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SSL_use_certificate_file failed"); 16668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_STDIO */ 16678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", __func__); 16688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_STDIO */ 16698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 16718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_global_client_cert(SSL_CTX *ssl_ctx, const char *client_cert) 16758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_STDIO 16778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (client_cert == NULL) 16788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 16798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_CTX_use_certificate_file(ssl_ctx, client_cert, 16818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_FILETYPE_ASN1) != 1 && 16821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt SSL_CTX_use_certificate_chain_file(ssl_ctx, client_cert) != 1 && 16838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_use_certificate_file(ssl_ctx, client_cert, 16848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_FILETYPE_PEM) != 1) { 16858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 16868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to load client certificate"); 16878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 16888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 16908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_STDIO */ 16918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (client_cert == NULL) 16928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 16938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", __func__); 16948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 16958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_STDIO */ 16968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_passwd_cb(char *buf, int size, int rwflag, void *password) 17008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (password == NULL) { 17028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 17038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(buf, (char *) password, size); 17058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return os_strlen(buf); 17068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef PKCS12_FUNCS 17108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_parse_pkcs12(SSL_CTX *ssl_ctx, SSL *ssl, PKCS12 *p12, 17118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *passwd) 17128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EVP_PKEY *pkey; 17148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *cert; 17158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt STACK_OF(X509) *certs; 17168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res = 0; 17178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char buf[256]; 17188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pkey = NULL; 17208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cert = NULL; 17218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt certs = NULL; 17228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!PKCS12_parse(p12, passwd, &pkey, &cert, &certs)) { 17238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_DEBUG, __func__, 17248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to parse PKCS12 file"); 17258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PKCS12_free(p12); 17268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 17278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Successfully parsed PKCS12 data"); 17298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cert) { 17318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_NAME_oneline(X509_get_subject_name(cert), buf, 17328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(buf)); 17338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Got certificate from PKCS12: " 17348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "subject='%s'", buf); 17358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssl) { 17368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_certificate(ssl, cert) != 1) 17378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 17388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 17398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_CTX_use_certificate(ssl_ctx, cert) != 1) 17408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 17418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 17438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pkey) { 17468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Got private key from PKCS12"); 17478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssl) { 17488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_PrivateKey(ssl, pkey) != 1) 17498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 17508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 17518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_CTX_use_PrivateKey(ssl_ctx, pkey) != 1) 17528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 17538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EVP_PKEY_free(pkey); 17558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (certs) { 17588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while ((cert = sk_X509_pop(certs)) != NULL) { 17598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_NAME_oneline(X509_get_subject_name(cert), buf, 17608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(buf)); 17618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: additional certificate" 17628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " from PKCS12: subject='%s'", buf); 17638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 17648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * There is no SSL equivalent for the chain cert - so 17658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * always add it to the context... 17668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 17678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_CTX_add_extra_chain_cert(ssl_ctx, cert) != 1) { 17688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 17698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sk_X509_free(certs); 17738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PKCS12_free(p12); 17768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) 17788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_get_errors(ssl_ctx); 17798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 17818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* PKCS12_FUNCS */ 17838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_read_pkcs12(SSL_CTX *ssl_ctx, SSL *ssl, const char *private_key, 17868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *passwd) 17878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef PKCS12_FUNCS 17898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FILE *f; 17908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PKCS12 *p12; 17918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt f = fopen(private_key, "rb"); 17938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (f == NULL) 17948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 17958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p12 = d2i_PKCS12_fp(f, NULL); 17978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fclose(f); 17988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p12 == NULL) { 18008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 18018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to use PKCS#12 file"); 18028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 18038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_parse_pkcs12(ssl_ctx, ssl, p12, passwd); 18068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* PKCS12_FUNCS */ 18088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: PKCS12 support disabled - cannot read " 18098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "p12/pfx files"); 18108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 18118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* PKCS12_FUNCS */ 18128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_read_pkcs12_blob(SSL_CTX *ssl_ctx, SSL *ssl, 18168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *blob, size_t len, const char *passwd) 18178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef PKCS12_FUNCS 18198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PKCS12 *p12; 18208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p12 = d2i_PKCS12(NULL, (OPENSSL_d2i_TYPE) &blob, len); 18228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p12 == NULL) { 18238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 18248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to use PKCS#12 blob"); 18258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 18268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_parse_pkcs12(ssl_ctx, ssl, p12, passwd); 18298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* PKCS12_FUNCS */ 18318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: PKCS12 support disabled - cannot parse " 18328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "p12/pfx blobs"); 18338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 18348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* PKCS12_FUNCS */ 18358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_ENGINE 18398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_engine_get_cert(struct tls_connection *conn, 18408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *cert_id, 18418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 **cert) 18428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* this runs after the private key is loaded so no PIN is required */ 18448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct { 18458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *cert_id; 18468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *cert; 18478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } params; 18488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.cert_id = cert_id; 18498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.cert = NULL; 18508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ENGINE_ctrl_cmd(conn->engine, "LOAD_CERT_CTRL", 18528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0, ¶ms, NULL, 1)) { 18538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "ENGINE: cannot load client cert with id" 18548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " '%s' [%s]", cert_id, 18558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 18568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED; 18578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!params.cert) { 18598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "ENGINE: did not properly cert with id" 18608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " '%s'", cert_id); 18618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED; 18628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *cert = params.cert; 18648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 18658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 18678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_connection_engine_client_cert(struct tls_connection *conn, 18708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *cert_id) 18718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_ENGINE 18738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *cert; 18748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_engine_get_cert(conn, cert_id, &cert)) 18768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 18778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!SSL_use_certificate(conn->ssl, cert)) { 18798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_ERROR, __func__, 18808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SSL_use_certificate failed"); 18818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 18828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 18838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 18858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ENGINE: SSL_use_certificate --> " 18868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "OK"); 18878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 18888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_ENGINE */ 18908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 18918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 18928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_connection_engine_ca_cert(void *_ssl_ctx, 18968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn, 18978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *ca_cert_id) 18988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_ENGINE 19008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509 *cert; 19018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX *ssl_ctx = _ssl_ctx; 19028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_engine_get_cert(conn, ca_cert_id, &cert)) 19048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 19058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* start off the same as tls_connection_ca_cert */ 19078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_STORE_free(ssl_ctx->cert_store); 19088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssl_ctx->cert_store = X509_STORE_new(); 19098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssl_ctx->cert_store == NULL) { 19108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - failed to allocate new " 19118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate store", __func__); 19128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 19138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 19148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!X509_STORE_add_cert(ssl_ctx->cert_store, cert)) { 19168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned long err = ERR_peek_error(); 19178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_WARNING, __func__, 19188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to add CA certificate from engine " 19198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "to certificate store"); 19208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ERR_GET_LIB(err) == ERR_LIB_X509 && 19218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_GET_REASON(err) == X509_R_CERT_ALREADY_IN_HASH_TABLE) { 19228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - ignoring cert" 19238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " already in hash table error", 19248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__); 19258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 19268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 19278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 19288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt X509_free(cert); 19318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - added CA certificate from engine " 19328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "to certificate store", __func__); 19338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb); 19348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 19358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_ENGINE */ 19378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 19388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 19398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_connection_engine_private_key(struct tls_connection *conn) 19438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_ENGINE 19458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_PrivateKey(conn->ssl, conn->private_key) != 1) { 19468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_ERROR, __func__, 19478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ENGINE: cannot use private key for TLS"); 19488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 19498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!SSL_check_private_key(conn->ssl)) { 19518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 19528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Private key failed verification"); 19538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 19548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 19568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_ENGINE */ 19578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "SSL: Configuration uses engine, but " 19588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "engine support was not compiled in"); 19598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 19608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_ENGINE */ 19618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_connection_private_key(void *_ssl_ctx, 19658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn, 19668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *private_key, 19678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *private_key_passwd, 19688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *private_key_blob, 19698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t private_key_blob_len) 19708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX *ssl_ctx = _ssl_ctx; 19728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *passwd; 19738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ok; 19748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (private_key == NULL && private_key_blob == NULL) 19768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 19778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (private_key_passwd) { 19798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt passwd = os_strdup(private_key_passwd); 19808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (passwd == NULL) 19818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 19828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 19838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt passwd = NULL; 19848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_set_default_passwd_cb(ssl_ctx, tls_passwd_cb); 19868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, passwd); 19878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 0; 19898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (private_key_blob) { 19908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_PrivateKey_ASN1(EVP_PKEY_RSA, conn->ssl, 19918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) private_key_blob, 19928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt private_key_blob_len) == 1) { 19938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_PrivateKey_" 19948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ASN1(EVP_PKEY_RSA) --> OK"); 19958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 1; 19968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 19978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_PrivateKey_ASN1(EVP_PKEY_DSA, conn->ssl, 20008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) private_key_blob, 20018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt private_key_blob_len) == 1) { 20028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_PrivateKey_" 20038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ASN1(EVP_PKEY_DSA) --> OK"); 20048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 1; 20058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 20068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_RSAPrivateKey_ASN1(conn->ssl, 20098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) private_key_blob, 20108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt private_key_blob_len) == 1) { 20118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: " 20128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SSL_use_RSAPrivateKey_ASN1 --> OK"); 20138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 1; 20148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 20158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_read_pkcs12_blob(ssl_ctx, conn->ssl, private_key_blob, 20188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt private_key_blob_len, passwd) == 0) { 20198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: PKCS#12 as blob --> " 20208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "OK"); 20218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 1; 20228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 20238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 20268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef ANDROID 20298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ok && private_key && 20308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strncmp("keystore://", private_key, 11) == 0) { 20318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO *bio = BIO_from_keystore(&private_key[11]); 20328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EVP_PKEY *pkey = NULL; 20338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bio) { 20348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL); 20358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO_free(bio); 20368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pkey) { 20388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_PrivateKey(conn->ssl, pkey) == 1) { 20398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Private key " 20408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "from keystore"); 20418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 1; 20428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EVP_PKEY_free(pkey); 20448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* ANDROID */ 20478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (!ok && private_key) { 20498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_STDIO 20508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_PrivateKey_file(conn->ssl, private_key, 20518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_FILETYPE_ASN1) == 1) { 20528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: " 20538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SSL_use_PrivateKey_File (DER) --> OK"); 20548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 1; 20558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 20568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_use_PrivateKey_file(conn->ssl, private_key, 20598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_FILETYPE_PEM) == 1) { 20608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: " 20618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SSL_use_PrivateKey_File (PEM) --> OK"); 20628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 1; 20638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 20648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_STDIO */ 20668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", 20678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__); 20688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_STDIO */ 20698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_read_pkcs12(ssl_ctx, conn->ssl, private_key, passwd) 20718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt == 0) { 20728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Reading PKCS#12 file " 20738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "--> OK"); 20748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 1; 20758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 20768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_cryptoapi_cert(conn->ssl, private_key) == 0) { 20798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: Using CryptoAPI to " 20808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "access certificate store --> OK"); 20818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ok = 1; 20828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 20838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 20868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ok) { 20898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 20908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to load private key"); 20918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(passwd); 20928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 20938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_clear_error(); 20958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_set_default_passwd_cb(ssl_ctx, NULL); 20968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(passwd); 20978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!SSL_check_private_key(conn->ssl)) { 20998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, "Private key failed " 21008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "verification"); 21018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 21028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Private key loaded successfully"); 21058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 21068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_global_private_key(SSL_CTX *ssl_ctx, const char *private_key, 21108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *private_key_passwd) 21118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *passwd; 21138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (private_key == NULL) 21158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 21168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (private_key_passwd) { 21188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt passwd = os_strdup(private_key_passwd); 21198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (passwd == NULL) 21208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 21218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 21228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt passwd = NULL; 21238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_set_default_passwd_cb(ssl_ctx, tls_passwd_cb); 21258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, passwd); 21268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ( 21278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_STDIO 21288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_use_PrivateKey_file(ssl_ctx, private_key, 21298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_FILETYPE_ASN1) != 1 && 21308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_use_PrivateKey_file(ssl_ctx, private_key, 21318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_FILETYPE_PEM) != 1 && 21328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_STDIO */ 21338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_read_pkcs12(ssl_ctx, NULL, private_key, passwd)) { 21348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 21358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to load private key"); 21368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(passwd); 21378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_clear_error(); 21388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 21398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(passwd); 21418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_clear_error(); 21428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX_set_default_passwd_cb(ssl_ctx, NULL); 21438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!SSL_CTX_check_private_key(ssl_ctx)) { 21458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 21468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Private key failed verification"); 21478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 21488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 21518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_connection_dh(struct tls_connection *conn, const char *dh_file) 21558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef OPENSSL_NO_DH 21578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dh_file == NULL) 21588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 21598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "TLS: openssl does not include DH support, but " 21608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dh_file specified"); 21618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 21628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_DH */ 21638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DH *dh; 21648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO *bio; 21658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: add support for dh_blob */ 21678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dh_file == NULL) 21688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 21698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 21708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 21718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bio = BIO_new_file(dh_file, "r"); 21738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bio == NULL) { 21748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to open DH file '%s': %s", 21758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dh_file, ERR_error_string(ERR_get_error(), NULL)); 21768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 21778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); 21798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO_free(bio); 21808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_DSA 21818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (dh == NULL) { 21828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DSA *dsa; 21838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Failed to parse DH file '%s': %s -" 21848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " trying to parse as DSA params", dh_file, 21858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 21868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bio = BIO_new_file(dh_file, "r"); 21878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bio == NULL) 21888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 21898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dsa = PEM_read_bio_DSAparams(bio, NULL, NULL, NULL); 21908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO_free(bio); 21918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!dsa) { 21928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Failed to parse DSA file " 21938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s': %s", dh_file, 21948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 21958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 21968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: DH file in DSA param format"); 21998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dh = DSA_dup_DH(dsa); 22008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DSA_free(dsa); 22018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dh == NULL) { 22028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to convert DSA " 22038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "params into DH params"); 22048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 22058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 22078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* !OPENSSL_NO_DSA */ 22098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dh == NULL) { 22108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to read/parse DH/DSA file " 22118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s'", dh_file); 22128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_set_tmp_dh(conn->ssl, dh) != 1) { 22168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to set DH params from '%s': " 22178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%s", dh_file, 22188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 22198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DH_free(dh); 22208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DH_free(dh); 22238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 22248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_DH */ 22258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_global_dh(SSL_CTX *ssl_ctx, const char *dh_file) 22298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef OPENSSL_NO_DH 22318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dh_file == NULL) 22328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 22338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "TLS: openssl does not include DH support, but " 22348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dh_file specified"); 22358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* OPENSSL_NO_DH */ 22378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DH *dh; 22388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO *bio; 22398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: add support for dh_blob */ 22418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dh_file == NULL) 22428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 22438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssl_ctx == NULL) 22448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bio = BIO_new_file(dh_file, "r"); 22478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bio == NULL) { 22488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to open DH file '%s': %s", 22498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dh_file, ERR_error_string(ERR_get_error(), NULL)); 22508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); 22538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO_free(bio); 22548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OPENSSL_NO_DSA 22558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (dh == NULL) { 22568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DSA *dsa; 22578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Failed to parse DH file '%s': %s -" 22588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " trying to parse as DSA params", dh_file, 22598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 22608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bio = BIO_new_file(dh_file, "r"); 22618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bio == NULL) 22628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 22638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dsa = PEM_read_bio_DSAparams(bio, NULL, NULL, NULL); 22648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO_free(bio); 22658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!dsa) { 22668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Failed to parse DSA file " 22678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s': %s", dh_file, 22688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 22698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 22708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: DH file in DSA param format"); 22738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dh = DSA_dup_DH(dsa); 22748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DSA_free(dsa); 22758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dh == NULL) { 22768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to convert DSA " 22778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "params into DH params"); 22788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 22798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 22818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* !OPENSSL_NO_DSA */ 22838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dh == NULL) { 22848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to read/parse DH/DSA file " 22858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s'", dh_file); 22868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_CTX_set_tmp_dh(ssl_ctx, dh) != 1) { 22908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to set DH params from '%s': " 22918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%s", dh_file, 22928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERR_error_string(ERR_get_error(), NULL)); 22938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DH_free(dh); 22948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DH_free(dh); 22978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 22988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OPENSSL_NO_DH */ 22998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_get_keys(void *ssl_ctx, struct tls_connection *conn, 23038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_keys *keys) 23048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL *ssl; 23068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL || keys == NULL) 23088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 23098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssl = conn->ssl; 23108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssl == NULL || ssl->s3 == NULL || ssl->session == NULL) 23118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 23128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(keys, 0, sizeof(*keys)); 23148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keys->master_key = ssl->session->master_key; 23158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keys->master_key_len = ssl->session->master_key_length; 23168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keys->client_random = ssl->s3->client_random; 23178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keys->client_random_len = SSL3_RANDOM_SIZE; 23188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keys->server_random = ssl->s3->server_random; 23198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keys->server_random_len = SSL3_RANDOM_SIZE; 23208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 23228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_prf(void *tls_ctx, struct tls_connection *conn, 23268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *label, int server_random_first, 23278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *out, size_t out_len) 23288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 23308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * 23348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtopenssl_handshake(struct tls_connection *conn, const struct wpabuf *in_data, 23358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int server) 23368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 23388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *out_data; 23398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 23418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Give TLS handshake data from the server (if available) to OpenSSL 23428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * for processing. 23438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 23448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (in_data && 23458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BIO_write(conn->ssl_in, wpabuf_head(in_data), wpabuf_len(in_data)) 23468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt < 0) { 23478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 23488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Handshake failed - BIO_write"); 23498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 23508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Initiate TLS handshake or continue the existing handshake */ 23538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (server) 23548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = SSL_accept(conn->ssl); 23558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 23568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = SSL_connect(conn->ssl); 23578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res != 1) { 23588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int err = SSL_get_error(conn->ssl, res); 23598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (err == SSL_ERROR_WANT_READ) 23608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: SSL_connect - want " 23618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "more data"); 23628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (err == SSL_ERROR_WANT_WRITE) 23638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: SSL_connect - want to " 23648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "write"); 23658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 23668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, "SSL_connect"); 23678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->failed++; 23688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Get the TLS handshake data to be sent to the server */ 23728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = BIO_ctrl_pending(conn->ssl_out); 23738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: %d bytes pending from ssl_out", res); 23748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out_data = wpabuf_alloc(res); 23758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (out_data == NULL) { 23768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Failed to allocate memory for " 23778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "handshake output (%d bytes)", res); 23788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (BIO_reset(conn->ssl_out) < 0) { 23798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 23808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "BIO_reset failed"); 23818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 23838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = res == 0 ? 0 : BIO_read(conn->ssl_out, wpabuf_mhead(out_data), 23858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res); 23868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 23878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 23888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Handshake failed - BIO_read"); 23898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (BIO_reset(conn->ssl_out) < 0) { 23908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 23918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "BIO_reset failed"); 23928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(out_data); 23948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 23958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put(out_data, res); 23978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return out_data; 23998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * 24038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtopenssl_get_appl_data(struct tls_connection *conn, size_t max_len) 24048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *appl_data; 24068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 24078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt appl_data = wpabuf_alloc(max_len + 100); 24098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (appl_data == NULL) 24108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 24118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = SSL_read(conn->ssl, wpabuf_mhead(appl_data), 24138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_size(appl_data)); 24148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 24158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int err = SSL_get_error(conn->ssl, res); 24168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (err == SSL_ERROR_WANT_READ || 24178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt err == SSL_ERROR_WANT_WRITE) { 24188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: No Application Data " 24198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "included"); 24208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 24218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 24228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to read possible " 24238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Application Data"); 24248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(appl_data); 24268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 24278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put(appl_data, res); 24308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_buf_key(MSG_MSGDUMP, "SSL: Application Data in Finished " 24318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "message", appl_data); 24328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return appl_data; 24348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * 24388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtopenssl_connection_handshake(struct tls_connection *conn, 24398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *in_data, 24408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf **appl_data, int server) 24418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *out_data; 24438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (appl_data) 24458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *appl_data = NULL; 24468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out_data = openssl_handshake(conn, in_data, server); 24488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (out_data == NULL) 24498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 24508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_is_init_finished(conn->ssl) && appl_data && in_data) 24528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *appl_data = openssl_get_appl_data(conn, wpabuf_len(in_data)); 24538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return out_data; 24558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * 24598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttls_connection_handshake(void *ssl_ctx, struct tls_connection *conn, 24608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *in_data, 24618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf **appl_data) 24628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return openssl_connection_handshake(conn, in_data, appl_data, 0); 24648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * tls_connection_server_handshake(void *tls_ctx, 24688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn, 24698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *in_data, 24708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf **appl_data) 24718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return openssl_connection_handshake(conn, in_data, appl_data, 1); 24738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * tls_connection_encrypt(void *tls_ctx, 24778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn, 24788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *in_data) 24798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 24818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 24828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 24848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 24858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Give plaintext data for OpenSSL to encrypt into the TLS tunnel. */ 24878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((res = BIO_reset(conn->ssl_in)) < 0 || 24888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (res = BIO_reset(conn->ssl_out)) < 0) { 24898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, "BIO_reset failed"); 24908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 24918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = SSL_write(conn->ssl, wpabuf_head(in_data), wpabuf_len(in_data)); 24938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 24948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 24958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Encryption failed - SSL_write"); 24968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 24978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Read encrypted data to be sent to the server */ 25008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = wpabuf_alloc(wpabuf_len(in_data) + 300); 25018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 25028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 25038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = BIO_read(conn->ssl_out, wpabuf_mhead(buf), wpabuf_size(buf)); 25048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 25058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 25068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Encryption failed - BIO_read"); 25078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(buf); 25088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 25098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put(buf, res); 25118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 25138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * tls_connection_decrypt(void *tls_ctx, 25178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn, 25188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *in_data) 25198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 25218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 25228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Give encrypted data from TLS tunnel for OpenSSL to decrypt. */ 25248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = BIO_write(conn->ssl_in, wpabuf_head(in_data), 25258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_len(in_data)); 25268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 25278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 25288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Decryption failed - BIO_write"); 25298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 25308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (BIO_reset(conn->ssl_out) < 0) { 25328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, "BIO_reset failed"); 25338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 25348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Read decrypted data for further processing */ 25378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 25388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Even though we try to disable TLS compression, it is possible that 25398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * this cannot be done with all TLS libraries. Add extra buffer space 25408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to handle the possibility of the decrypted data being longer than 25418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * input data. 25428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 25438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3); 25448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 25458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 25468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = SSL_read(conn->ssl, wpabuf_mhead(buf), wpabuf_size(buf)); 25478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 25488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 25498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Decryption failed - SSL_read"); 25508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(buf); 25518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 25528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put(buf, res); 25548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 25568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_resumed(void *ssl_ctx, struct tls_connection *conn) 25608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return conn ? conn->ssl->hit : 0; 25628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn, 25668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *ciphers) 25678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 25688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char buf[100], *pos, *end; 25698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *c; 25708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 25718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL || conn->ssl == NULL || ciphers == NULL) 25738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 25748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[0] = '\0'; 25768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = buf; 25778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + sizeof(buf); 25788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt c = ciphers; 25808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (*c != TLS_CIPHER_NONE) { 25818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *suite; 25828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (*c) { 25848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TLS_CIPHER_RC4_SHA: 25858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suite = "RC4-SHA"; 25868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 25878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TLS_CIPHER_AES128_SHA: 25888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suite = "AES128-SHA"; 25898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 25908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TLS_CIPHER_RSA_DHE_AES128_SHA: 25918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suite = "DHE-RSA-AES128-SHA"; 25928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 25938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TLS_CIPHER_ANON_DH_AES128_SHA: 25948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suite = "ADH-AES128-SHA"; 25958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 25968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 25978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Unsupported " 25988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "cipher selection: %d", *c); 25998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, ":%s", suite); 26028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 26038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 26048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 26058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt c++; 26078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: cipher suites: %s", buf + 1); 26108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_set_cipher_list(conn->ssl, buf + 1) != 1) { 26128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_show_errors(MSG_INFO, __func__, 26138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Cipher suite configuration failed"); 26148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_get_cipher(void *ssl_ctx, struct tls_connection *conn, 26228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *buf, size_t buflen) 26238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *name; 26258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL || conn->ssl == NULL) 26268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name = SSL_get_cipher(conn->ssl); 26298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (name == NULL) 26308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(buf, name, buflen); 26338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_enable_workaround(void *ssl_ctx, 26388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn) 26398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_options(conn->ssl, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS); 26418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) 26478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* ClientHello TLS extensions require a patch to openssl, so this function is 26488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * commented out unless explicitly needed for EAP-FAST in order to be able to 26498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * build this file with unmodified openssl. */ 26508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_client_hello_ext(void *ssl_ctx, struct tls_connection *conn, 26518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ext_type, const u8 *data, 26528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t data_len) 26538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL || conn->ssl == NULL || ext_type != 35) 26558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_OPENSSL_TICKET_OVERRIDE 26588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_set_session_ticket_ext(conn->ssl, (void *) data, 26598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data_len) != 1) 26608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_OPENSSL_TICKET_OVERRIDE */ 26628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_set_hello_extension(conn->ssl, ext_type, (void *) data, 26638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data_len) != 1) 26648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_OPENSSL_TICKET_OVERRIDE */ 26668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */ 26708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_get_failed(void *ssl_ctx, struct tls_connection *conn) 26738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 26758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return conn->failed; 26778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_get_read_alerts(void *ssl_ctx, struct tls_connection *conn) 26818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 26838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return conn->read_alerts; 26858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_get_write_alerts(void *ssl_ctx, struct tls_connection *conn) 26898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 26918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 26928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return conn->write_alerts; 26938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_set_params(void *tls_ctx, struct tls_connection *conn, 26978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct tls_connection_params *params) 26988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 27008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned long err; 27018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 27038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while ((err = ERR_get_error())) { 27068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "%s: Clearing pending SSL error: %s", 27078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__, ERR_error_string(err, NULL)); 27088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->engine) { 27118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Initializing TLS engine"); 27128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = tls_engine_init(conn, params->engine_id, params->pin, 27138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->key_id, params->cert_id, 27148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->ca_cert_id); 27158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret) 27168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 27178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_connection_set_subject_match(conn, 27198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->subject_match, 27208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->altsubject_match)) 27218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->engine && params->ca_cert_id) { 27248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_connection_engine_ca_cert(tls_ctx, conn, 27258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->ca_cert_id)) 27268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED; 27278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (tls_connection_ca_cert(tls_ctx, conn, params->ca_cert, 27288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->ca_cert_blob, 27298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->ca_cert_blob_len, 27308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->ca_path)) 27318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->engine && params->cert_id) { 27348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_connection_engine_client_cert(conn, params->cert_id)) 27358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED; 27368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (tls_connection_client_cert(conn, params->client_cert, 27378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->client_cert_blob, 27388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->client_cert_blob_len)) 27398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->engine && params->key_id) { 27428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Using private key from engine"); 27438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_connection_engine_private_key(conn)) 27448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED; 27458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (tls_connection_private_key(tls_ctx, conn, 27468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->private_key, 27478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->private_key_passwd, 27488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->private_key_blob, 27498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->private_key_blob_len)) { 27508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to load private key '%s'", 27518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->private_key); 27528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_connection_dh(conn, params->dh_file)) { 27568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to load DH file '%s'", 27578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->dh_file); 27588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2761c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt conn->flags = params->flags; 2762c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt 27638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_get_errors(tls_ctx); 27648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 27668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_global_set_params(void *tls_ctx, 27708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct tls_connection_params *params) 27718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CTX *ssl_ctx = tls_ctx; 27738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned long err; 27748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while ((err = ERR_get_error())) { 27768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "%s: Clearing pending SSL error: %s", 27778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__, ERR_error_string(err, NULL)); 27788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_global_ca_cert(ssl_ctx, params->ca_cert)) 27818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_global_client_cert(ssl_ctx, params->client_cert)) 27848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_global_private_key(ssl_ctx, params->private_key, 27878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->private_key_passwd)) 27888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_global_dh(ssl_ctx, params->dh_file)) { 27918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to load DH file '%s'", 27928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->dh_file); 27938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 27978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_get_keyblock_size(void *tls_ctx, 28018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn) 28028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const EVP_CIPHER *c; 28048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const EVP_MD *h; 28058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL || conn->ssl == NULL || 28078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ssl->enc_read_ctx == NULL || 28088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ssl->enc_read_ctx->cipher == NULL || 28098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->ssl->read_hash == NULL) 28108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 28118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt c = conn->ssl->enc_read_ctx->cipher; 28138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if OPENSSL_VERSION_NUMBER >= 0x00909000L 28148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt h = EVP_MD_CTX_md(conn->ssl->read_hash); 28158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else 28168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt h = conn->ssl->read_hash; 28178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 28188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 2 * (EVP_CIPHER_key_length(c) + 28208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EVP_MD_size(h) + 28218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EVP_CIPHER_iv_length(c)); 28228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtunsigned int tls_capabilities(void *tls_ctx) 28268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 28288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) 28328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Pre-shared secred requires a patch to openssl, so this function is 28338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * commented out unless explicitly needed for EAP-FAST in order to be able to 28348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * build this file with unmodified openssl. */ 28358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_sess_sec_cb(SSL *s, void *secret, int *secret_len, 28378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt STACK_OF(SSL_CIPHER) *peer_ciphers, 28388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_CIPHER **cipher, void *arg) 28398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn = arg; 28418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 28428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL || conn->session_ticket_cb == NULL) 28448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 28458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = conn->session_ticket_cb(conn->session_ticket_cb_ctx, 28478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket, 28488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket_len, 28498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->s3->client_random, 28508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s->s3->server_random, secret); 28518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->session_ticket); 28528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket = NULL; 28538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret <= 0) 28558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 28568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *secret_len = SSL_MAX_MASTER_KEY_LENGTH; 28588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 28598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_OPENSSL_TICKET_OVERRIDE 28638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_session_ticket_ext_cb(SSL *s, const unsigned char *data, 28648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len, void *arg) 28658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn = arg; 28678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL || conn->session_ticket_cb == NULL) 28698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 28708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s: length=%d", __func__, len); 28728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->session_ticket); 28748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket = NULL; 28758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "OpenSSL: ClientHello SessionTicket " 28778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "extension", data, len); 28788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket = os_malloc(len); 28808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->session_ticket == NULL) 28818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 28828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(conn->session_ticket, data, len); 28848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket_len = len; 28858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 28878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_OPENSSL_TICKET_OVERRIDE */ 28898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef SSL_OP_NO_TICKET 28908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void tls_hello_ext_cb(SSL *s, int client_server, int type, 28918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char *data, int len, void *arg) 28928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn = arg; 28948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL || conn->session_ticket_cb == NULL) 28968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 28978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s: type=%d length=%d", __func__, 28998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type, len); 29008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type == TLSEXT_TYPE_session_ticket && !client_server) { 29028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->session_ticket); 29038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket = NULL; 29048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "OpenSSL: ClientHello SessionTicket " 29068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "extension", data, len); 29078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket = os_malloc(len); 29088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->session_ticket == NULL) 29098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 29108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(conn->session_ticket, data, len); 29128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket_len = len; 29138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* SSL_OP_NO_TICKET */ 29168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_hello_ext_cb(SSL *s, TLS_EXTENSION *ext, void *arg) 29178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn = arg; 29198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL || conn->session_ticket_cb == NULL) 29218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 29228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "OpenSSL: %s: type=%d length=%d", __func__, 29248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ext->type, ext->length); 29258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->session_ticket); 29278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket = NULL; 29288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ext->type == 35) { 29308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "OpenSSL: ClientHello SessionTicket " 29318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "extension", ext->data, ext->length); 29328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket = os_malloc(ext->length); 29338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->session_ticket == NULL) 29348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return SSL_AD_INTERNAL_ERROR; 29358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(conn->session_ticket, ext->data, ext->length); 29378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket_len = ext->length; 29388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 29418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* SSL_OP_NO_TICKET */ 29438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_OPENSSL_TICKET_OVERRIDE */ 29448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */ 29458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_set_session_ticket_cb(void *tls_ctx, 29488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn, 29498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_session_ticket_cb cb, 29508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *ctx) 29518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) 29538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket_cb = cb; 29548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket_cb_ctx = ctx; 29558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cb) { 29578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_set_session_secret_cb(conn->ssl, tls_sess_sec_cb, 29588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn) != 1) 29598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 29608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_OPENSSL_TICKET_OVERRIDE 29618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_session_ticket_ext_cb(conn->ssl, 29628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_session_ticket_ext_cb, conn); 29638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_OPENSSL_TICKET_OVERRIDE */ 29648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef SSL_OP_NO_TICKET 29658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_tlsext_debug_callback(conn->ssl, tls_hello_ext_cb); 29668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_tlsext_debug_arg(conn->ssl, conn); 29678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* SSL_OP_NO_TICKET */ 29688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_set_hello_extension_cb(conn->ssl, tls_hello_ext_cb, 29698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn) != 1) 29708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 29718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* SSL_OP_NO_TICKET */ 29728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_OPENSSL_TICKET_OVERRIDE */ 29738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 29748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_set_session_secret_cb(conn->ssl, NULL, NULL) != 1) 29758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 29768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_OPENSSL_TICKET_OVERRIDE 29778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_session_ticket_ext_cb(conn->ssl, NULL, NULL); 29788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_OPENSSL_TICKET_OVERRIDE */ 29798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef SSL_OP_NO_TICKET 29808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_tlsext_debug_callback(conn->ssl, NULL); 29818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SSL_set_tlsext_debug_arg(conn->ssl, conn); 29828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* SSL_OP_NO_TICKET */ 29838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SSL_set_hello_extension_cb(conn->ssl, NULL, NULL) != 1) 29848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 29858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* SSL_OP_NO_TICKET */ 29868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_OPENSSL_TICKET_OVERRIDE */ 29878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 29908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */ 29918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 29928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */ 29938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2994