tls_openssl.c revision 68d0e3ed07847339aedfac8e02f50db68c702e52
15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SSL/TLS interface functions for OpenSSL 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (c) 2004-2013, Jouni Malinen <j@w1.fi> 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This software may be distributed under the terms of the BSD license. 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * See README for more details. 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "includes.h" 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef CONFIG_SMARTCARD 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef OPENSSL_NO_ENGINE 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef ANDROID 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define OPENSSL_NO_ENGINE 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <openssl/ssl.h> 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <openssl/err.h> 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <openssl/pkcs12.h> 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <openssl/x509v3.h> 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef OPENSSL_NO_ENGINE 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <openssl/engine.h> 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif /* OPENSSL_NO_ENGINE */ 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "common.h" 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "crypto.h" 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "tls.h" 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if OPENSSL_VERSION_NUMBER >= 0x0090800fL 325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define OPENSSL_d2i_TYPE const unsigned char ** 33197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#else 34a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#define OPENSSL_d2i_TYPE unsigned char ** 355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 36a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch 375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if defined(SSL_CTX_get_app_data) && defined(SSL_CTX_set_app_data) 38197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#define OPENSSL_SUPPORTS_CTX_APP_DATA 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifdef SSL_F_SSL_SET_SESSION_TICKET_EXT 42a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#ifdef SSL_OP_NO_TICKET 43a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch/* 44a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch * Session ticket override patch was merged into OpenSSL 0.9.9 tree on 45a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch * 2008-11-15. This version uses a bit different API compared to the old patch. 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 47926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#define CONFIG_OPENSSL_TICKET_OVERRIDE 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 51926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#ifdef ANDROID 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <openssl/pem.h> 53926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#include <keystore/keystore_get.h> 54926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 55a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochstatic BIO * BIO_from_keystore(const char *key) 56926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 57926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) BIO *bio = NULL; 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint8_t *value = NULL; 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int length = keystore_get(key, strlen(key), &value); 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (length != -1 && (bio = BIO_new(BIO_s_mem())) != NULL) { 61a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) BIO_write(bio, value, length); 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 63926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) free(value); 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return bio; 65926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 66926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#endif /* ANDROID */ 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifdef SSL_set_tlsext_status_type 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef OPENSSL_NO_TLSEXT 70a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#define HAVE_OCSP 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <openssl/ocsp.h> 72926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#endif /* OPENSSL_NO_TLSEXT */ 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif /* SSL_set_tlsext_status_type */ 74926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 75926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)static int tls_openssl_ref_count = 0; 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)struct tls_context { 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void (*event_cb)(void *ctx, enum tls_event ev, 79926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) union tls_event_data *data); 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void *cb_ctx; 81926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) int cert_in_cb; 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) char *ocsp_stapling_response; 83926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}; 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 85926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)static struct tls_context *tls_global = NULL; 86926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 87926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)struct tls_connection { 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) struct tls_context *context; 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SSL *ssl; 91926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) BIO *ssl_in, *ssl_out; 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef OPENSSL_NO_ENGINE 93926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ENGINE *engine; /* functional reference to the engine */ 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EVP_PKEY *private_key; /* the private key if using engine */ 95926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#endif /* OPENSSL_NO_ENGINE */ 96926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) char *subject_match, *altsubject_match, *suffix_match; 97926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) int read_alerts, write_alerts, failed; 98926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) tls_session_ticket_cb session_ticket_cb; 100926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) void *session_ticket_cb_ctx; 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /* SessionTicket received from OpenSSL hello_extension_cb (server) */ 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) u8 *session_ticket; 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) size_t session_ticket_len; 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 106a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) unsigned int ca_cert_verify:1; 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned int cert_probe:1; 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned int server_cert_only:1; 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) u8 srv_cert_hash[32]; 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned int flags; 113a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) X509 *peer_cert; 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) X509 *peer_issuer; 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static struct tls_context * tls_context_new(const struct tls_config *conf) 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 121f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu struct tls_context *context = os_zalloc(sizeof(*context)); 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (context == NULL) 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return NULL; 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (conf) { 125a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch context->event_cb = conf->event_cb; 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) context->cb_ctx = conf->cb_ctx; 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) context->cert_in_cb = conf->cert_in_cb; 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 129a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) return context; 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifdef CONFIG_NO_STDOUT_DEBUG 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void _tls_show_errors(void) 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 137a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) unsigned long err; 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while ((err = ERR_get_error())) { 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /* Just ignore the errors, since stdout is disabled */ 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define tls_show_errors(l, f, t) _tls_show_errors() 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#else /* CONFIG_NO_STDOUT_DEBUG */ 146926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void tls_show_errors(int level, const char *func, const char *txt) 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned long err; 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) wpa_printf(level, "OpenSSL: %s - %s %s", 152a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) func, txt, ERR_error_string(ERR_get_error(), NULL)); 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 154a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) while ((err = ERR_get_error())) { 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) wpa_printf(MSG_INFO, "OpenSSL: pending error: %s", 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ERR_error_string(err, NULL)); 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif /* CONFIG_NO_STDOUT_DEBUG */ 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifdef CONFIG_NATIVE_WINDOWS 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* Windows CryptoAPI and access to certificate stores */ 166a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include <wincrypt.h> 167a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifdef __MINGW32_VERSION 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MinGW does not yet include all the needed definitions for CryptoAPI, so 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * define here whatever extra is needed. 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define CERT_SYSTEM_STORE_CURRENT_USER (1 << 16) 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define CERT_STORE_READONLY_FLAG 0x00008000 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define CERT_STORE_OPEN_EXISTING_FLAG 0x00004000 176a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif /* __MINGW32_VERSION */ 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)struct cryptoapi_rsa_data { 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const CERT_CONTEXT *cert; 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) HCRYPTPROV crypt_prov; 183a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) DWORD key_spec; 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) BOOL free_crypt_prov; 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void cryptoapi_error(const char *msg) 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) wpa_printf(MSG_INFO, "CryptoAPI: %s; err=%u", 191f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu msg, (unsigned int) GetLastError()); 1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 193a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static int cryptoapi_rsa_pub_enc(int flen, const unsigned char *from, 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned char *to, RSA *rsa, int padding) 1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) wpa_printf(MSG_DEBUG, "%s - not implemented", __func__); 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 200a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch} 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static int cryptoapi_rsa_pub_dec(int flen, const unsigned char *from, 204a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) unsigned char *to, RSA *rsa, int padding) 205a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles){ 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) wpa_printf(MSG_DEBUG, "%s - not implemented", __func__); 207a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) return 0; 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 211a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)static int cryptoapi_rsa_priv_enc(int flen, const unsigned char *from, 212a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) unsigned char *to, RSA *rsa, int padding) 213a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles){ 214a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) struct cryptoapi_rsa_data *priv = 215a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) (struct cryptoapi_rsa_data *) rsa->meth->app_data; 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) HCRYPTHASH hash; 2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DWORD hash_size, len, i; 2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned char *buf = NULL; 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int ret = 0; 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (priv == NULL) { 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, 2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ERR_R_PASSED_NULL_PARAMETER); 2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (padding != RSA_PKCS1_PADDING) { 228a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, 229a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) RSA_R_UNKNOWN_PADDING_TYPE); 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (flen != 16 /* MD5 */ + 20 /* SHA-1 */) { 2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) wpa_printf(MSG_INFO, "%s - only MD5-SHA1 hash supported", 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) __func__); 236a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, 2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RSA_R_INVALID_MESSAGE_LENGTH); 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!CryptCreateHash(priv->crypt_prov, CALG_SSL3_SHAMD5, 0, 0, &hash)) 2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cryptoapi_error("CryptCreateHash failed"); 244f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu return 0; 2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) len = sizeof(hash_size); 248a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch if (!CryptGetHashParam(hash, HP_HASHSIZE, (BYTE *) &hash_size, &len, 2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 0)) { 2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cryptoapi_error("CryptGetHashParam failed"); 2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) goto err; 252a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) } 2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if ((int) hash_size != flen) { 2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) wpa_printf(MSG_INFO, "CryptoAPI: Invalid hash size (%u != %d)", 2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) (unsigned) hash_size, flen); 2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, 2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RSA_R_INVALID_MESSAGE_LENGTH); 2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) goto err; 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!CryptSetHashParam(hash, HP_HASHVAL, (BYTE * ) from, 0)) { 2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cryptoapi_error("CryptSetHashParam failed"); 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) goto err; 2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) len = RSA_size(rsa); 2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) buf = os_malloc(len); 2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (buf == NULL) { 2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE); 2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) goto err; 2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!CryptSignHash(hash, priv->key_spec, NULL, 0, buf, &len)) { 2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cryptoapi_error("CryptSignHash failed"); 2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) goto err; 2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (i = 0; i < len; i++) 2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) to[i] = buf[len - i - 1]; 2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ret = len; 2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)err: 2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) os_free(buf); 2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CryptDestroyHash(hash); 2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return ret; 287f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu} 2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static int cryptoapi_rsa_priv_dec(int flen, const unsigned char *from, 2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned char *to, RSA *rsa, int padding) 292a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch{ 2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) wpa_printf(MSG_DEBUG, "%s - not implemented", __func__); 2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 295a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)} 2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void cryptoapi_free_data(struct cryptoapi_rsa_data *priv) 2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (priv == NULL) 3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (priv->crypt_prov && priv->free_crypt_prov) 3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CryptReleaseContext(priv->crypt_prov, 0); 3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (priv->cert) 3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CertFreeCertificateContext(priv->cert); 3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) os_free(priv); 3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static int cryptoapi_finish(RSA *rsa) 3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cryptoapi_free_data((struct cryptoapi_rsa_data *) rsa->meth->app_data); 3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) os_free((void *) rsa->meth); 3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rsa->meth = NULL; 3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 1; 3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const CERT_CONTEXT * cryptoapi_find_cert(const char *name, DWORD store) 3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) HCERTSTORE cs; 3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const CERT_CONTEXT *ret = NULL; 3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cs = CertOpenStore((LPCSTR) CERT_STORE_PROV_SYSTEM, 0, 0, 3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) store | CERT_STORE_OPEN_EXISTING_FLAG | 3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CERT_STORE_READONLY_FLAG, L"MY"); 3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (cs == NULL) { 3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cryptoapi_error("Failed to open 'My system store'"); 3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return NULL; 3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 331f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu 3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (strncmp(name, "cert://", 7) == 0) { 3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned short wbuf[255]; 3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MultiByteToWideChar(CP_ACP, 0, name + 7, -1, wbuf, 255); 3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ret = CertFindCertificateInStore(cs, X509_ASN_ENCODING | 336a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch PKCS_7_ASN_ENCODING, 3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 0, CERT_FIND_SUBJECT_STR, 3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) wbuf, NULL); 3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (strncmp(name, "hash://", 7) == 0) { 340a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) CRYPT_HASH_BLOB blob; 3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int len; 3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const char *hash = name + 7; 3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned char *buf; 3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) len = os_strlen(hash) / 2; 3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) buf = os_malloc(len); 3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (buf && hexstr2bin(hash, buf, len) == 0) { 3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) blob.cbData = len; 3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) blob.pbData = buf; 3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ret = CertFindCertificateInStore(cs, 3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) X509_ASN_ENCODING | 3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) PKCS_7_ASN_ENCODING, 3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 0, CERT_FIND_HASH, 3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) &blob, NULL); 355197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } 3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) os_free(buf); 3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CertCloseStore(cs, 0); 3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return ret; 3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static int tls_cryptoapi_cert(SSL *ssl, const char *name) 366a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles){ 3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) X509 *cert = NULL; 3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RSA *rsa = NULL, *pub_rsa; 369a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) struct cryptoapi_rsa_data *priv; 3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RSA_METHOD *rsa_meth; 3715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (name == NULL || 3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) (strncmp(name, "cert://", 7) != 0 && 3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) strncmp(name, "hash://", 7) != 0)) 3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return -1; 3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) priv = os_zalloc(sizeof(*priv)); 3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rsa_meth = os_zalloc(sizeof(*rsa_meth)); 3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (priv == NULL || rsa_meth == NULL) { 3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) wpa_printf(MSG_WARNING, "CryptoAPI: Failed to allocate memory " 3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) "for CryptoAPI RSA method"); 3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) os_free(priv); 3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) os_free(rsa_meth); 3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return -1; 3855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) priv->cert = cryptoapi_find_cert(name, CERT_SYSTEM_STORE_CURRENT_USER); 3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (priv->cert == NULL) { 3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) priv->cert = cryptoapi_find_cert( 3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) name, CERT_SYSTEM_STORE_LOCAL_MACHINE); 391a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) } 392a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) if (priv->cert == NULL) { 393a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) wpa_printf(MSG_INFO, "CryptoAPI: Could not find certificate " 3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) "'%s'", name); 3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) goto err; 3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cert = d2i_X509(NULL, (OPENSSL_d2i_TYPE) &priv->cert->pbCertEncoded, 3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) priv->cert->cbCertEncoded); 4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (cert == NULL) { 4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) wpa_printf(MSG_INFO, "CryptoAPI: Could not process X509 DER " 4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) "encoding"); 4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) goto err; 4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 406a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) if (!CryptAcquireCertificatePrivateKey(priv->cert, 407a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) CRYPT_ACQUIRE_COMPARE_KEY_FLAG, 4085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) NULL, &priv->crypt_prov, 4095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) &priv->key_spec, 4105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) &priv->free_crypt_prov)) { 4115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cryptoapi_error("Failed to acquire a private key for the " 4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) "certificate"); 4135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) goto err; 414926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 4155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rsa_meth->name = "Microsoft CryptoAPI RSA Method"; 4175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rsa_meth->rsa_pub_enc = cryptoapi_rsa_pub_enc; 4185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rsa_meth->rsa_pub_dec = cryptoapi_rsa_pub_dec; 419a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) rsa_meth->rsa_priv_enc = cryptoapi_rsa_priv_enc; 4205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rsa_meth->rsa_priv_dec = cryptoapi_rsa_priv_dec; 4215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rsa_meth->finish = cryptoapi_finish; 4225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rsa_meth->flags = RSA_METHOD_FLAG_NO_CHECK; 4235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rsa_meth->app_data = (char *) priv; 4245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rsa = RSA_new(); 4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (rsa == NULL) { 427a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, 4285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ERR_R_MALLOC_FAILURE); 4295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) goto err; 4305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!SSL_use_certificate(ssl, cert)) { 4335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RSA_free(rsa); 4345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rsa = NULL; 4355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) goto err; 4365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) pub_rsa = cert->cert_info->key->pkey->pkey.rsa; 4385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) X509_free(cert); 4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cert = NULL; 4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rsa->n = BN_dup(pub_rsa->n); 4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rsa->e = BN_dup(pub_rsa->e); 4435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!RSA_set_method(rsa, rsa_meth)) 4445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) goto err; 4455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!SSL_use_RSAPrivateKey(ssl, rsa)) 4475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) goto err; 4485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RSA_free(rsa); 4495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 4515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)err: 4535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (cert) 4545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) X509_free(cert); 4555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (rsa) 4565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RSA_free(rsa); 4575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else { 4585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) os_free(rsa_meth); 459a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) cryptoapi_free_data(priv); 4605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return -1; 4625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static int tls_cryptoapi_ca_cert(SSL_CTX *ssl_ctx, SSL *ssl, const char *name) 4665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) HCERTSTORE cs; 4685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) PCCERT_CONTEXT ctx = NULL; 4695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) X509 *cert; 4705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) char buf[128]; 4715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const char *store; 4725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifdef UNICODE 4735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) WCHAR *wstore; 4745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif /* UNICODE */ 4755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (name == NULL || strncmp(name, "cert_store://", 13) != 0) 4775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return -1; 478a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 479a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) store = name + 13; 480a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#ifdef UNICODE 4815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) wstore = os_malloc((os_strlen(store) + 1) * sizeof(WCHAR)); 4825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (wstore == NULL) 4835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return -1; 4845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) wsprintf(wstore, L"%S", store); 4855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cs = CertOpenSystemStore(0, wstore); 4865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) os_free(wstore); 4875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#else /* UNICODE */ 4885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cs = CertOpenSystemStore(0, store); 489a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#endif /* UNICODE */ 4905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (cs == NULL) { 4915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) wpa_printf(MSG_DEBUG, "%s: failed to open system cert store " 4925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) "'%s': error=%d", __func__, store, 4935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) (int) GetLastError()); 4945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return -1; 4955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while ((ctx = CertEnumCertificatesInStore(cs, ctx))) { 4985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cert = d2i_X509(NULL, (OPENSSL_d2i_TYPE) &ctx->pbCertEncoded, 4995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ctx->cbCertEncoded); 5005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (cert == NULL) { 5015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) wpa_printf(MSG_INFO, "CryptoAPI: Could not process " 502a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) "X509 DER encoding for CA cert"); 503a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) continue; 504a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) } 5055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) X509_NAME_oneline(X509_get_subject_name(cert), buf, 5075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) sizeof(buf)); 5085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) wpa_printf(MSG_DEBUG, "OpenSSL: Loaded CA certificate for " 5095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) "system certificate store: subject='%s'", buf); 5105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!X509_STORE_add_cert(ssl_ctx->cert_store, cert)) { 5125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) tls_show_errors(MSG_WARNING, __func__, 5135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) "Failed to add ca_cert to OpenSSL " 5145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) "certificate store"); 5155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) X509_free(cert); 5185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!CertCloseStore(cs, 0)) { 5215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) wpa_printf(MSG_DEBUG, "%s: failed to close system cert store " 5225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) "'%s': error=%d", __func__, name + 13, 5235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) (int) GetLastError()); 5245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 525a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 5265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 5275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#else /* CONFIG_NATIVE_WINDOWS */ 5315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static int tls_cryptoapi_cert(SSL *ssl, const char *name) 5335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return -1; 5355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif /* CONFIG_NATIVE_WINDOWS */ 5385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void ssl_info_cb(const SSL *ssl, int where, int ret) 5415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const char *str; 5435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int w; 5445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) wpa_printf(MSG_DEBUG, "SSL: (where=0x%x ret=0x%x)", where, ret); 5465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) w = where & ~SSL_ST_MASK; 5475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (w & SSL_ST_CONNECT) 5485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) str = "SSL_connect"; 5495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (w & SSL_ST_ACCEPT) 5505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) str = "SSL_accept"; 5515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 5525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) str = "undefined"; 5535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 554 if (where & SSL_CB_LOOP) { 555 wpa_printf(MSG_DEBUG, "SSL: %s:%s", 556 str, SSL_state_string_long(ssl)); 557 } else if (where & SSL_CB_ALERT) { 558 struct tls_connection *conn = SSL_get_app_data((SSL *) ssl); 559 wpa_printf(MSG_INFO, "SSL: SSL3 alert: %s:%s:%s", 560 where & SSL_CB_READ ? 561 "read (remote end reported an error)" : 562 "write (local SSL3 detected an error)", 563 SSL_alert_type_string_long(ret), 564 SSL_alert_desc_string_long(ret)); 565 if ((ret >> 8) == SSL3_AL_FATAL) { 566 if (where & SSL_CB_READ) 567 conn->read_alerts++; 568 else 569 conn->write_alerts++; 570 } 571 if (conn->context->event_cb != NULL) { 572 union tls_event_data ev; 573 struct tls_context *context = conn->context; 574 os_memset(&ev, 0, sizeof(ev)); 575 ev.alert.is_local = !(where & SSL_CB_READ); 576 ev.alert.type = SSL_alert_type_string_long(ret); 577 ev.alert.description = SSL_alert_desc_string_long(ret); 578 context->event_cb(context->cb_ctx, TLS_ALERT, &ev); 579 } 580 } else if (where & SSL_CB_EXIT && ret <= 0) { 581 wpa_printf(MSG_DEBUG, "SSL: %s:%s in %s", 582 str, ret == 0 ? "failed" : "error", 583 SSL_state_string_long(ssl)); 584 } 585} 586 587 588#ifndef OPENSSL_NO_ENGINE 589/** 590 * tls_engine_load_dynamic_generic - load any openssl engine 591 * @pre: an array of commands and values that load an engine initialized 592 * in the engine specific function 593 * @post: an array of commands and values that initialize an already loaded 594 * engine (or %NULL if not required) 595 * @id: the engine id of the engine to load (only required if post is not %NULL 596 * 597 * This function is a generic function that loads any openssl engine. 598 * 599 * Returns: 0 on success, -1 on failure 600 */ 601static int tls_engine_load_dynamic_generic(const char *pre[], 602 const char *post[], const char *id) 603{ 604 ENGINE *engine; 605 const char *dynamic_id = "dynamic"; 606 607 engine = ENGINE_by_id(id); 608 if (engine) { 609 ENGINE_free(engine); 610 wpa_printf(MSG_DEBUG, "ENGINE: engine '%s' is already " 611 "available", id); 612 return 0; 613 } 614 ERR_clear_error(); 615 616 engine = ENGINE_by_id(dynamic_id); 617 if (engine == NULL) { 618 wpa_printf(MSG_INFO, "ENGINE: Can't find engine %s [%s]", 619 dynamic_id, 620 ERR_error_string(ERR_get_error(), NULL)); 621 return -1; 622 } 623 624 /* Perform the pre commands. This will load the engine. */ 625 while (pre && pre[0]) { 626 wpa_printf(MSG_DEBUG, "ENGINE: '%s' '%s'", pre[0], pre[1]); 627 if (ENGINE_ctrl_cmd_string(engine, pre[0], pre[1], 0) == 0) { 628 wpa_printf(MSG_INFO, "ENGINE: ctrl cmd_string failed: " 629 "%s %s [%s]", pre[0], pre[1], 630 ERR_error_string(ERR_get_error(), NULL)); 631 ENGINE_free(engine); 632 return -1; 633 } 634 pre += 2; 635 } 636 637 /* 638 * Free the reference to the "dynamic" engine. The loaded engine can 639 * now be looked up using ENGINE_by_id(). 640 */ 641 ENGINE_free(engine); 642 643 engine = ENGINE_by_id(id); 644 if (engine == NULL) { 645 wpa_printf(MSG_INFO, "ENGINE: Can't find engine %s [%s]", 646 id, ERR_error_string(ERR_get_error(), NULL)); 647 return -1; 648 } 649 650 while (post && post[0]) { 651 wpa_printf(MSG_DEBUG, "ENGINE: '%s' '%s'", post[0], post[1]); 652 if (ENGINE_ctrl_cmd_string(engine, post[0], post[1], 0) == 0) { 653 wpa_printf(MSG_DEBUG, "ENGINE: ctrl cmd_string failed:" 654 " %s %s [%s]", post[0], post[1], 655 ERR_error_string(ERR_get_error(), NULL)); 656 ENGINE_remove(engine); 657 ENGINE_free(engine); 658 return -1; 659 } 660 post += 2; 661 } 662 ENGINE_free(engine); 663 664 return 0; 665} 666 667 668/** 669 * tls_engine_load_dynamic_pkcs11 - load the pkcs11 engine provided by opensc 670 * @pkcs11_so_path: pksc11_so_path from the configuration 671 * @pcks11_module_path: pkcs11_module_path from the configuration 672 */ 673static int tls_engine_load_dynamic_pkcs11(const char *pkcs11_so_path, 674 const char *pkcs11_module_path) 675{ 676 char *engine_id = "pkcs11"; 677 const char *pre_cmd[] = { 678 "SO_PATH", NULL /* pkcs11_so_path */, 679 "ID", NULL /* engine_id */, 680 "LIST_ADD", "1", 681 /* "NO_VCHECK", "1", */ 682 "LOAD", NULL, 683 NULL, NULL 684 }; 685 const char *post_cmd[] = { 686 "MODULE_PATH", NULL /* pkcs11_module_path */, 687 NULL, NULL 688 }; 689 690 if (!pkcs11_so_path || !pkcs11_module_path) 691 return 0; 692 693 pre_cmd[1] = pkcs11_so_path; 694 pre_cmd[3] = engine_id; 695 post_cmd[1] = pkcs11_module_path; 696 697 wpa_printf(MSG_DEBUG, "ENGINE: Loading pkcs11 Engine from %s", 698 pkcs11_so_path); 699 700 return tls_engine_load_dynamic_generic(pre_cmd, post_cmd, engine_id); 701} 702 703 704/** 705 * tls_engine_load_dynamic_opensc - load the opensc engine provided by opensc 706 * @opensc_so_path: opensc_so_path from the configuration 707 */ 708static int tls_engine_load_dynamic_opensc(const char *opensc_so_path) 709{ 710 char *engine_id = "opensc"; 711 const char *pre_cmd[] = { 712 "SO_PATH", NULL /* opensc_so_path */, 713 "ID", NULL /* engine_id */, 714 "LIST_ADD", "1", 715 "LOAD", NULL, 716 NULL, NULL 717 }; 718 719 if (!opensc_so_path) 720 return 0; 721 722 pre_cmd[1] = opensc_so_path; 723 pre_cmd[3] = engine_id; 724 725 wpa_printf(MSG_DEBUG, "ENGINE: Loading OpenSC Engine from %s", 726 opensc_so_path); 727 728 return tls_engine_load_dynamic_generic(pre_cmd, NULL, engine_id); 729} 730#endif /* OPENSSL_NO_ENGINE */ 731 732 733void * tls_init(const struct tls_config *conf) 734{ 735 SSL_CTX *ssl; 736 struct tls_context *context; 737 738 if (tls_openssl_ref_count == 0) { 739 tls_global = context = tls_context_new(conf); 740 if (context == NULL) 741 return NULL; 742#ifdef CONFIG_FIPS 743#ifdef OPENSSL_FIPS 744 if (conf && conf->fips_mode) { 745 if (!FIPS_mode_set(1)) { 746 wpa_printf(MSG_ERROR, "Failed to enable FIPS " 747 "mode"); 748 ERR_load_crypto_strings(); 749 ERR_print_errors_fp(stderr); 750 os_free(tls_global); 751 tls_global = NULL; 752 return NULL; 753 } else 754 wpa_printf(MSG_INFO, "Running in FIPS mode"); 755 } 756#else /* OPENSSL_FIPS */ 757 if (conf && conf->fips_mode) { 758 wpa_printf(MSG_ERROR, "FIPS mode requested, but not " 759 "supported"); 760 os_free(tls_global); 761 tls_global = NULL; 762 return NULL; 763 } 764#endif /* OPENSSL_FIPS */ 765#endif /* CONFIG_FIPS */ 766 SSL_load_error_strings(); 767 SSL_library_init(); 768#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL) && !defined(OPENSSL_NO_SHA256) 769 EVP_add_digest(EVP_sha256()); 770#endif /* OPENSSL_NO_SHA256 */ 771 /* TODO: if /dev/urandom is available, PRNG is seeded 772 * automatically. If this is not the case, random data should 773 * be added here. */ 774 775#ifdef PKCS12_FUNCS 776#ifndef OPENSSL_NO_RC2 777 /* 778 * 40-bit RC2 is commonly used in PKCS#12 files, so enable it. 779 * This is enabled by PKCS12_PBE_add() in OpenSSL 0.9.8 780 * versions, but it looks like OpenSSL 1.0.0 does not do that 781 * anymore. 782 */ 783 EVP_add_cipher(EVP_rc2_40_cbc()); 784#endif /* OPENSSL_NO_RC2 */ 785 PKCS12_PBE_add(); 786#endif /* PKCS12_FUNCS */ 787 } else { 788 context = tls_global; 789#ifdef OPENSSL_SUPPORTS_CTX_APP_DATA 790 /* Newer OpenSSL can store app-data per-SSL */ 791 context = tls_context_new(conf); 792 if (context == NULL) 793 return NULL; 794#endif /* OPENSSL_SUPPORTS_CTX_APP_DATA */ 795 } 796 tls_openssl_ref_count++; 797 798 ssl = SSL_CTX_new(TLSv1_method()); 799 if (ssl == NULL) { 800 tls_openssl_ref_count--; 801#ifdef OPENSSL_SUPPORTS_CTX_APP_DATA 802 if (context != tls_global) 803 os_free(context); 804#endif /* OPENSSL_SUPPORTS_CTX_APP_DATA */ 805 if (tls_openssl_ref_count == 0) { 806 os_free(tls_global); 807 tls_global = NULL; 808 } 809 return NULL; 810 } 811 812 SSL_CTX_set_info_callback(ssl, ssl_info_cb); 813#ifdef OPENSSL_SUPPORTS_CTX_APP_DATA 814 SSL_CTX_set_app_data(ssl, context); 815#endif /* OPENSSL_SUPPORTS_CTX_APP_DATA */ 816 817#ifndef OPENSSL_NO_ENGINE 818 if (conf && 819 (conf->opensc_engine_path || conf->pkcs11_engine_path || 820 conf->pkcs11_module_path)) { 821 wpa_printf(MSG_DEBUG, "ENGINE: Loading dynamic engine"); 822 ERR_load_ENGINE_strings(); 823 ENGINE_load_dynamic(); 824 825 if (tls_engine_load_dynamic_opensc(conf->opensc_engine_path) || 826 tls_engine_load_dynamic_pkcs11(conf->pkcs11_engine_path, 827 conf->pkcs11_module_path)) { 828 tls_deinit(ssl); 829 return NULL; 830 } 831 } 832#endif /* OPENSSL_NO_ENGINE */ 833 834 return ssl; 835} 836 837 838void tls_deinit(void *ssl_ctx) 839{ 840 SSL_CTX *ssl = ssl_ctx; 841#ifdef OPENSSL_SUPPORTS_CTX_APP_DATA 842 struct tls_context *context = SSL_CTX_get_app_data(ssl); 843 if (context != tls_global) 844 os_free(context); 845#endif /* OPENSSL_SUPPORTS_CTX_APP_DATA */ 846 SSL_CTX_free(ssl); 847 848 tls_openssl_ref_count--; 849 if (tls_openssl_ref_count == 0) { 850#ifndef OPENSSL_NO_ENGINE 851 ENGINE_cleanup(); 852#endif /* OPENSSL_NO_ENGINE */ 853 CRYPTO_cleanup_all_ex_data(); 854 ERR_remove_state(0); 855 ERR_free_strings(); 856 EVP_cleanup(); 857 os_free(tls_global->ocsp_stapling_response); 858 tls_global->ocsp_stapling_response = NULL; 859 os_free(tls_global); 860 tls_global = NULL; 861 } 862} 863 864 865static int tls_engine_init(struct tls_connection *conn, const char *engine_id, 866 const char *pin, const char *key_id, 867 const char *cert_id, const char *ca_cert_id) 868{ 869#ifndef OPENSSL_NO_ENGINE 870 int ret = -1; 871 if (engine_id == NULL) { 872 wpa_printf(MSG_ERROR, "ENGINE: Engine ID not set"); 873 return -1; 874 } 875#ifndef ANDROID 876 if (pin == NULL) { 877 wpa_printf(MSG_ERROR, "ENGINE: Smartcard PIN not set"); 878 return -1; 879 } 880#endif 881 if (key_id == NULL) { 882 wpa_printf(MSG_ERROR, "ENGINE: Key Id not set"); 883 return -1; 884 } 885 886 ERR_clear_error(); 887#ifdef ANDROID 888 ENGINE_load_dynamic(); 889#endif 890 conn->engine = ENGINE_by_id(engine_id); 891 if (!conn->engine) { 892 wpa_printf(MSG_ERROR, "ENGINE: engine %s not available [%s]", 893 engine_id, ERR_error_string(ERR_get_error(), NULL)); 894 goto err; 895 } 896 if (ENGINE_init(conn->engine) != 1) { 897 wpa_printf(MSG_ERROR, "ENGINE: engine init failed " 898 "(engine: %s) [%s]", engine_id, 899 ERR_error_string(ERR_get_error(), NULL)); 900 goto err; 901 } 902 wpa_printf(MSG_DEBUG, "ENGINE: engine initialized"); 903 904#ifndef ANDROID 905 if (ENGINE_ctrl_cmd_string(conn->engine, "PIN", pin, 0) == 0) { 906 wpa_printf(MSG_ERROR, "ENGINE: cannot set pin [%s]", 907 ERR_error_string(ERR_get_error(), NULL)); 908 goto err; 909 } 910#endif 911 /* load private key first in-case PIN is required for cert */ 912 conn->private_key = ENGINE_load_private_key(conn->engine, 913 key_id, NULL, NULL); 914 if (!conn->private_key) { 915 wpa_printf(MSG_ERROR, "ENGINE: cannot load private key with id" 916 " '%s' [%s]", key_id, 917 ERR_error_string(ERR_get_error(), NULL)); 918 ret = TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED; 919 goto err; 920 } 921 922 /* handle a certificate and/or CA certificate */ 923 if (cert_id || ca_cert_id) { 924 const char *cmd_name = "LOAD_CERT_CTRL"; 925 926 /* test if the engine supports a LOAD_CERT_CTRL */ 927 if (!ENGINE_ctrl(conn->engine, ENGINE_CTRL_GET_CMD_FROM_NAME, 928 0, (void *)cmd_name, NULL)) { 929 wpa_printf(MSG_ERROR, "ENGINE: engine does not support" 930 " loading certificates"); 931 ret = TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED; 932 goto err; 933 } 934 } 935 936 return 0; 937 938err: 939 if (conn->engine) { 940 ENGINE_free(conn->engine); 941 conn->engine = NULL; 942 } 943 944 if (conn->private_key) { 945 EVP_PKEY_free(conn->private_key); 946 conn->private_key = NULL; 947 } 948 949 return ret; 950#else /* OPENSSL_NO_ENGINE */ 951 return 0; 952#endif /* OPENSSL_NO_ENGINE */ 953} 954 955 956static void tls_engine_deinit(struct tls_connection *conn) 957{ 958#ifndef OPENSSL_NO_ENGINE 959 wpa_printf(MSG_DEBUG, "ENGINE: engine deinit"); 960 if (conn->private_key) { 961 EVP_PKEY_free(conn->private_key); 962 conn->private_key = NULL; 963 } 964 if (conn->engine) { 965 ENGINE_finish(conn->engine); 966 conn->engine = NULL; 967 } 968#endif /* OPENSSL_NO_ENGINE */ 969} 970 971 972int tls_get_errors(void *ssl_ctx) 973{ 974 int count = 0; 975 unsigned long err; 976 977 while ((err = ERR_get_error())) { 978 wpa_printf(MSG_INFO, "TLS - SSL error: %s", 979 ERR_error_string(err, NULL)); 980 count++; 981 } 982 983 return count; 984} 985 986struct tls_connection * tls_connection_init(void *ssl_ctx) 987{ 988 SSL_CTX *ssl = ssl_ctx; 989 struct tls_connection *conn; 990 long options; 991 struct tls_context *context = tls_global; 992#ifdef OPENSSL_SUPPORTS_CTX_APP_DATA 993 context = SSL_CTX_get_app_data(ssl); 994#endif /* OPENSSL_SUPPORTS_CTX_APP_DATA */ 995 996 conn = os_zalloc(sizeof(*conn)); 997 if (conn == NULL) 998 return NULL; 999 conn->ssl = SSL_new(ssl); 1000 if (conn->ssl == NULL) { 1001 tls_show_errors(MSG_INFO, __func__, 1002 "Failed to initialize new SSL connection"); 1003 os_free(conn); 1004 return NULL; 1005 } 1006 1007 conn->context = context; 1008 SSL_set_app_data(conn->ssl, conn); 1009 options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | 1010 SSL_OP_SINGLE_DH_USE; 1011#ifdef SSL_OP_NO_COMPRESSION 1012 options |= SSL_OP_NO_COMPRESSION; 1013#endif /* SSL_OP_NO_COMPRESSION */ 1014#ifdef ANDROID 1015 options |= SSL_OP_NO_TLSv1_1; 1016 options |= SSL_OP_NO_TLSv1_2; 1017 options |= SSL_OP_NO_TICKET; 1018#endif /* ANDROID */ 1019 SSL_set_options(conn->ssl, options); 1020 1021 conn->ssl_in = BIO_new(BIO_s_mem()); 1022 if (!conn->ssl_in) { 1023 tls_show_errors(MSG_INFO, __func__, 1024 "Failed to create a new BIO for ssl_in"); 1025 SSL_free(conn->ssl); 1026 os_free(conn); 1027 return NULL; 1028 } 1029 1030 conn->ssl_out = BIO_new(BIO_s_mem()); 1031 if (!conn->ssl_out) { 1032 tls_show_errors(MSG_INFO, __func__, 1033 "Failed to create a new BIO for ssl_out"); 1034 SSL_free(conn->ssl); 1035 BIO_free(conn->ssl_in); 1036 os_free(conn); 1037 return NULL; 1038 } 1039 1040 SSL_set_bio(conn->ssl, conn->ssl_in, conn->ssl_out); 1041 1042 return conn; 1043} 1044 1045 1046void tls_connection_deinit(void *ssl_ctx, struct tls_connection *conn) 1047{ 1048 if (conn == NULL) 1049 return; 1050 SSL_free(conn->ssl); 1051 tls_engine_deinit(conn); 1052 os_free(conn->subject_match); 1053 os_free(conn->altsubject_match); 1054 os_free(conn->suffix_match); 1055 os_free(conn->session_ticket); 1056 os_free(conn); 1057} 1058 1059 1060int tls_connection_established(void *ssl_ctx, struct tls_connection *conn) 1061{ 1062 return conn ? SSL_is_init_finished(conn->ssl) : 0; 1063} 1064 1065 1066int tls_connection_shutdown(void *ssl_ctx, struct tls_connection *conn) 1067{ 1068 if (conn == NULL) 1069 return -1; 1070 1071 /* Shutdown previous TLS connection without notifying the peer 1072 * because the connection was already terminated in practice 1073 * and "close notify" shutdown alert would confuse AS. */ 1074 SSL_set_quiet_shutdown(conn->ssl, 1); 1075 SSL_shutdown(conn->ssl); 1076 return 0; 1077} 1078 1079 1080static int tls_match_altsubject_component(X509 *cert, int type, 1081 const char *value, size_t len) 1082{ 1083 GENERAL_NAME *gen; 1084 void *ext; 1085 int i, found = 0; 1086 1087 ext = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL); 1088 1089 for (i = 0; ext && i < sk_GENERAL_NAME_num(ext); i++) { 1090 gen = sk_GENERAL_NAME_value(ext, i); 1091 if (gen->type != type) 1092 continue; 1093 if (os_strlen((char *) gen->d.ia5->data) == len && 1094 os_memcmp(value, gen->d.ia5->data, len) == 0) 1095 found++; 1096 } 1097 1098 return found; 1099} 1100 1101 1102static int tls_match_altsubject(X509 *cert, const char *match) 1103{ 1104 int type; 1105 const char *pos, *end; 1106 size_t len; 1107 1108 pos = match; 1109 do { 1110 if (os_strncmp(pos, "EMAIL:", 6) == 0) { 1111 type = GEN_EMAIL; 1112 pos += 6; 1113 } else if (os_strncmp(pos, "DNS:", 4) == 0) { 1114 type = GEN_DNS; 1115 pos += 4; 1116 } else if (os_strncmp(pos, "URI:", 4) == 0) { 1117 type = GEN_URI; 1118 pos += 4; 1119 } else { 1120 wpa_printf(MSG_INFO, "TLS: Invalid altSubjectName " 1121 "match '%s'", pos); 1122 return 0; 1123 } 1124 end = os_strchr(pos, ';'); 1125 while (end) { 1126 if (os_strncmp(end + 1, "EMAIL:", 6) == 0 || 1127 os_strncmp(end + 1, "DNS:", 4) == 0 || 1128 os_strncmp(end + 1, "URI:", 4) == 0) 1129 break; 1130 end = os_strchr(end + 1, ';'); 1131 } 1132 if (end) 1133 len = end - pos; 1134 else 1135 len = os_strlen(pos); 1136 if (tls_match_altsubject_component(cert, type, pos, len) > 0) 1137 return 1; 1138 pos = end + 1; 1139 } while (end); 1140 1141 return 0; 1142} 1143 1144 1145static int domain_suffix_match(const u8 *val, size_t len, const char *match) 1146{ 1147 size_t i, match_len; 1148 1149 /* Check for embedded nuls that could mess up suffix matching */ 1150 for (i = 0; i < len; i++) { 1151 if (val[i] == '\0') { 1152 wpa_printf(MSG_DEBUG, "TLS: Embedded null in a string - reject"); 1153 return 0; 1154 } 1155 } 1156 1157 match_len = os_strlen(match); 1158 if (match_len > len) 1159 return 0; 1160 1161 if (os_strncasecmp((const char *) val + len - match_len, match, 1162 match_len) != 0) 1163 return 0; /* no match */ 1164 1165 if (match_len == len) 1166 return 1; /* exact match */ 1167 1168 if (val[len - match_len - 1] == '.') 1169 return 1; /* full label match completes suffix match */ 1170 1171 wpa_printf(MSG_DEBUG, "TLS: Reject due to incomplete label match"); 1172 return 0; 1173} 1174 1175 1176static int tls_match_suffix(X509 *cert, const char *match) 1177{ 1178 GENERAL_NAME *gen; 1179 void *ext; 1180 int i; 1181 int dns_name = 0; 1182 X509_NAME *name; 1183 1184 wpa_printf(MSG_DEBUG, "TLS: Match domain against suffix %s", match); 1185 1186 ext = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL); 1187 1188 for (i = 0; ext && i < sk_GENERAL_NAME_num(ext); i++) { 1189 gen = sk_GENERAL_NAME_value(ext, i); 1190 if (gen->type != GEN_DNS) 1191 continue; 1192 dns_name++; 1193 wpa_hexdump_ascii(MSG_DEBUG, "TLS: Certificate dNSName", 1194 gen->d.dNSName->data, 1195 gen->d.dNSName->length); 1196 if (domain_suffix_match(gen->d.dNSName->data, 1197 gen->d.dNSName->length, match) == 1) { 1198 wpa_printf(MSG_DEBUG, "TLS: Suffix match in dNSName found"); 1199 return 1; 1200 } 1201 } 1202 1203 if (dns_name) { 1204 wpa_printf(MSG_DEBUG, "TLS: None of the dNSName(s) matched"); 1205 return 0; 1206 } 1207 1208 name = X509_get_subject_name(cert); 1209 i = -1; 1210 for (;;) { 1211 X509_NAME_ENTRY *e; 1212 ASN1_STRING *cn; 1213 1214 i = X509_NAME_get_index_by_NID(name, NID_commonName, i); 1215 if (i == -1) 1216 break; 1217 e = X509_NAME_get_entry(name, i); 1218 if (e == NULL) 1219 continue; 1220 cn = X509_NAME_ENTRY_get_data(e); 1221 if (cn == NULL) 1222 continue; 1223 wpa_hexdump_ascii(MSG_DEBUG, "TLS: Certificate commonName", 1224 cn->data, cn->length); 1225 if (domain_suffix_match(cn->data, cn->length, match) == 1) { 1226 wpa_printf(MSG_DEBUG, "TLS: Suffix match in commonName found"); 1227 return 1; 1228 } 1229 } 1230 1231 wpa_printf(MSG_DEBUG, "TLS: No CommonName suffix match found"); 1232 return 0; 1233} 1234 1235 1236static enum tls_fail_reason openssl_tls_fail_reason(int err) 1237{ 1238 switch (err) { 1239 case X509_V_ERR_CERT_REVOKED: 1240 return TLS_FAIL_REVOKED; 1241 case X509_V_ERR_CERT_NOT_YET_VALID: 1242 case X509_V_ERR_CRL_NOT_YET_VALID: 1243 return TLS_FAIL_NOT_YET_VALID; 1244 case X509_V_ERR_CERT_HAS_EXPIRED: 1245 case X509_V_ERR_CRL_HAS_EXPIRED: 1246 return TLS_FAIL_EXPIRED; 1247 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: 1248 case X509_V_ERR_UNABLE_TO_GET_CRL: 1249 case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER: 1250 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: 1251 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: 1252 case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: 1253 case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: 1254 case X509_V_ERR_CERT_CHAIN_TOO_LONG: 1255 case X509_V_ERR_PATH_LENGTH_EXCEEDED: 1256 case X509_V_ERR_INVALID_CA: 1257 return TLS_FAIL_UNTRUSTED; 1258 case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: 1259 case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: 1260 case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: 1261 case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: 1262 case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: 1263 case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: 1264 case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: 1265 case X509_V_ERR_CERT_UNTRUSTED: 1266 case X509_V_ERR_CERT_REJECTED: 1267 return TLS_FAIL_BAD_CERTIFICATE; 1268 default: 1269 return TLS_FAIL_UNSPECIFIED; 1270 } 1271} 1272 1273 1274static struct wpabuf * get_x509_cert(X509 *cert) 1275{ 1276 struct wpabuf *buf; 1277 u8 *tmp; 1278 1279 int cert_len = i2d_X509(cert, NULL); 1280 if (cert_len <= 0) 1281 return NULL; 1282 1283 buf = wpabuf_alloc(cert_len); 1284 if (buf == NULL) 1285 return NULL; 1286 1287 tmp = wpabuf_put(buf, cert_len); 1288 i2d_X509(cert, &tmp); 1289 return buf; 1290} 1291 1292 1293static void openssl_tls_fail_event(struct tls_connection *conn, 1294 X509 *err_cert, int err, int depth, 1295 const char *subject, const char *err_str, 1296 enum tls_fail_reason reason) 1297{ 1298 union tls_event_data ev; 1299 struct wpabuf *cert = NULL; 1300 struct tls_context *context = conn->context; 1301 1302 if (context->event_cb == NULL) 1303 return; 1304 1305 cert = get_x509_cert(err_cert); 1306 os_memset(&ev, 0, sizeof(ev)); 1307 ev.cert_fail.reason = reason != TLS_FAIL_UNSPECIFIED ? 1308 reason : openssl_tls_fail_reason(err); 1309 ev.cert_fail.depth = depth; 1310 ev.cert_fail.subject = subject; 1311 ev.cert_fail.reason_txt = err_str; 1312 ev.cert_fail.cert = cert; 1313 context->event_cb(context->cb_ctx, TLS_CERT_CHAIN_FAILURE, &ev); 1314 wpabuf_free(cert); 1315} 1316 1317 1318static void openssl_tls_cert_event(struct tls_connection *conn, 1319 X509 *err_cert, int depth, 1320 const char *subject) 1321{ 1322 struct wpabuf *cert = NULL; 1323 union tls_event_data ev; 1324 struct tls_context *context = conn->context; 1325#ifdef CONFIG_SHA256 1326 u8 hash[32]; 1327#endif /* CONFIG_SHA256 */ 1328 1329 if (context->event_cb == NULL) 1330 return; 1331 1332 os_memset(&ev, 0, sizeof(ev)); 1333 if (conn->cert_probe || context->cert_in_cb) { 1334 cert = get_x509_cert(err_cert); 1335 ev.peer_cert.cert = cert; 1336 } 1337#ifdef CONFIG_SHA256 1338 if (cert) { 1339 const u8 *addr[1]; 1340 size_t len[1]; 1341 addr[0] = wpabuf_head(cert); 1342 len[0] = wpabuf_len(cert); 1343 if (sha256_vector(1, addr, len, hash) == 0) { 1344 ev.peer_cert.hash = hash; 1345 ev.peer_cert.hash_len = sizeof(hash); 1346 } 1347 } 1348#endif /* CONFIG_SHA256 */ 1349 ev.peer_cert.depth = depth; 1350 ev.peer_cert.subject = subject; 1351 context->event_cb(context->cb_ctx, TLS_PEER_CERTIFICATE, &ev); 1352 wpabuf_free(cert); 1353} 1354 1355 1356static int tls_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx) 1357{ 1358 char buf[256]; 1359 X509 *err_cert; 1360 int err, depth; 1361 SSL *ssl; 1362 struct tls_connection *conn; 1363 struct tls_context *context; 1364 char *match, *altmatch, *suffix_match; 1365 const char *err_str; 1366 1367 err_cert = X509_STORE_CTX_get_current_cert(x509_ctx); 1368 err = X509_STORE_CTX_get_error(x509_ctx); 1369 depth = X509_STORE_CTX_get_error_depth(x509_ctx); 1370 ssl = X509_STORE_CTX_get_ex_data(x509_ctx, 1371 SSL_get_ex_data_X509_STORE_CTX_idx()); 1372 X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof(buf)); 1373 1374 conn = SSL_get_app_data(ssl); 1375 if (conn == NULL) 1376 return 0; 1377 1378 if (depth == 0) 1379 conn->peer_cert = err_cert; 1380 else if (depth == 1) 1381 conn->peer_issuer = err_cert; 1382 1383 context = conn->context; 1384 match = conn->subject_match; 1385 altmatch = conn->altsubject_match; 1386 suffix_match = conn->suffix_match; 1387 1388 if (!preverify_ok && !conn->ca_cert_verify) 1389 preverify_ok = 1; 1390 if (!preverify_ok && depth > 0 && conn->server_cert_only) 1391 preverify_ok = 1; 1392 if (!preverify_ok && (conn->flags & TLS_CONN_DISABLE_TIME_CHECKS) && 1393 (err == X509_V_ERR_CERT_HAS_EXPIRED || 1394 err == X509_V_ERR_CERT_NOT_YET_VALID)) { 1395 wpa_printf(MSG_DEBUG, "OpenSSL: Ignore certificate validity " 1396 "time mismatch"); 1397 preverify_ok = 1; 1398 } 1399 1400 err_str = X509_verify_cert_error_string(err); 1401 1402#ifdef CONFIG_SHA256 1403 if (preverify_ok && depth == 0 && conn->server_cert_only) { 1404 struct wpabuf *cert; 1405 cert = get_x509_cert(err_cert); 1406 if (!cert) { 1407 wpa_printf(MSG_DEBUG, "OpenSSL: Could not fetch " 1408 "server certificate data"); 1409 preverify_ok = 0; 1410 } else { 1411 u8 hash[32]; 1412 const u8 *addr[1]; 1413 size_t len[1]; 1414 addr[0] = wpabuf_head(cert); 1415 len[0] = wpabuf_len(cert); 1416 if (sha256_vector(1, addr, len, hash) < 0 || 1417 os_memcmp(conn->srv_cert_hash, hash, 32) != 0) { 1418 err_str = "Server certificate mismatch"; 1419 err = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN; 1420 preverify_ok = 0; 1421 } 1422 wpabuf_free(cert); 1423 } 1424 } 1425#endif /* CONFIG_SHA256 */ 1426 1427 if (!preverify_ok) { 1428 wpa_printf(MSG_WARNING, "TLS: Certificate verification failed," 1429 " error %d (%s) depth %d for '%s'", err, err_str, 1430 depth, buf); 1431 openssl_tls_fail_event(conn, err_cert, err, depth, buf, 1432 err_str, TLS_FAIL_UNSPECIFIED); 1433 return preverify_ok; 1434 } 1435 1436 wpa_printf(MSG_DEBUG, "TLS: tls_verify_cb - preverify_ok=%d " 1437 "err=%d (%s) ca_cert_verify=%d depth=%d buf='%s'", 1438 preverify_ok, err, err_str, 1439 conn->ca_cert_verify, depth, buf); 1440 if (depth == 0 && match && os_strstr(buf, match) == NULL) { 1441 wpa_printf(MSG_WARNING, "TLS: Subject '%s' did not " 1442 "match with '%s'", buf, match); 1443 preverify_ok = 0; 1444 openssl_tls_fail_event(conn, err_cert, err, depth, buf, 1445 "Subject mismatch", 1446 TLS_FAIL_SUBJECT_MISMATCH); 1447 } else if (depth == 0 && altmatch && 1448 !tls_match_altsubject(err_cert, altmatch)) { 1449 wpa_printf(MSG_WARNING, "TLS: altSubjectName match " 1450 "'%s' not found", altmatch); 1451 preverify_ok = 0; 1452 openssl_tls_fail_event(conn, err_cert, err, depth, buf, 1453 "AltSubject mismatch", 1454 TLS_FAIL_ALTSUBJECT_MISMATCH); 1455 } else if (depth == 0 && suffix_match && 1456 !tls_match_suffix(err_cert, suffix_match)) { 1457 wpa_printf(MSG_WARNING, "TLS: Domain suffix match '%s' not found", 1458 suffix_match); 1459 preverify_ok = 0; 1460 openssl_tls_fail_event(conn, err_cert, err, depth, buf, 1461 "Domain suffix mismatch", 1462 TLS_FAIL_DOMAIN_SUFFIX_MISMATCH); 1463 } else 1464 openssl_tls_cert_event(conn, err_cert, depth, buf); 1465 1466 if (conn->cert_probe && preverify_ok && depth == 0) { 1467 wpa_printf(MSG_DEBUG, "OpenSSL: Reject server certificate " 1468 "on probe-only run"); 1469 preverify_ok = 0; 1470 openssl_tls_fail_event(conn, err_cert, err, depth, buf, 1471 "Server certificate chain probe", 1472 TLS_FAIL_SERVER_CHAIN_PROBE); 1473 } 1474 1475 if (preverify_ok && context->event_cb != NULL) 1476 context->event_cb(context->cb_ctx, 1477 TLS_CERT_CHAIN_SUCCESS, NULL); 1478 1479 return preverify_ok; 1480} 1481 1482 1483#ifndef OPENSSL_NO_STDIO 1484static int tls_load_ca_der(void *_ssl_ctx, const char *ca_cert) 1485{ 1486 SSL_CTX *ssl_ctx = _ssl_ctx; 1487 X509_LOOKUP *lookup; 1488 int ret = 0; 1489 1490 lookup = X509_STORE_add_lookup(ssl_ctx->cert_store, 1491 X509_LOOKUP_file()); 1492 if (lookup == NULL) { 1493 tls_show_errors(MSG_WARNING, __func__, 1494 "Failed add lookup for X509 store"); 1495 return -1; 1496 } 1497 1498 if (!X509_LOOKUP_load_file(lookup, ca_cert, X509_FILETYPE_ASN1)) { 1499 unsigned long err = ERR_peek_error(); 1500 tls_show_errors(MSG_WARNING, __func__, 1501 "Failed load CA in DER format"); 1502 if (ERR_GET_LIB(err) == ERR_LIB_X509 && 1503 ERR_GET_REASON(err) == X509_R_CERT_ALREADY_IN_HASH_TABLE) { 1504 wpa_printf(MSG_DEBUG, "OpenSSL: %s - ignoring " 1505 "cert already in hash table error", 1506 __func__); 1507 } else 1508 ret = -1; 1509 } 1510 1511 return ret; 1512} 1513#endif /* OPENSSL_NO_STDIO */ 1514 1515 1516static int tls_connection_ca_cert(void *_ssl_ctx, struct tls_connection *conn, 1517 const char *ca_cert, const u8 *ca_cert_blob, 1518 size_t ca_cert_blob_len, const char *ca_path) 1519{ 1520 SSL_CTX *ssl_ctx = _ssl_ctx; 1521 1522 /* 1523 * Remove previously configured trusted CA certificates before adding 1524 * new ones. 1525 */ 1526 X509_STORE_free(ssl_ctx->cert_store); 1527 ssl_ctx->cert_store = X509_STORE_new(); 1528 if (ssl_ctx->cert_store == NULL) { 1529 wpa_printf(MSG_DEBUG, "OpenSSL: %s - failed to allocate new " 1530 "certificate store", __func__); 1531 return -1; 1532 } 1533 1534 SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb); 1535 conn->ca_cert_verify = 1; 1536 1537 if (ca_cert && os_strncmp(ca_cert, "probe://", 8) == 0) { 1538 wpa_printf(MSG_DEBUG, "OpenSSL: Probe for server certificate " 1539 "chain"); 1540 conn->cert_probe = 1; 1541 conn->ca_cert_verify = 0; 1542 return 0; 1543 } 1544 1545 if (ca_cert && os_strncmp(ca_cert, "hash://", 7) == 0) { 1546#ifdef CONFIG_SHA256 1547 const char *pos = ca_cert + 7; 1548 if (os_strncmp(pos, "server/sha256/", 14) != 0) { 1549 wpa_printf(MSG_DEBUG, "OpenSSL: Unsupported ca_cert " 1550 "hash value '%s'", ca_cert); 1551 return -1; 1552 } 1553 pos += 14; 1554 if (os_strlen(pos) != 32 * 2) { 1555 wpa_printf(MSG_DEBUG, "OpenSSL: Unexpected SHA256 " 1556 "hash length in ca_cert '%s'", ca_cert); 1557 return -1; 1558 } 1559 if (hexstr2bin(pos, conn->srv_cert_hash, 32) < 0) { 1560 wpa_printf(MSG_DEBUG, "OpenSSL: Invalid SHA256 hash " 1561 "value in ca_cert '%s'", ca_cert); 1562 return -1; 1563 } 1564 conn->server_cert_only = 1; 1565 wpa_printf(MSG_DEBUG, "OpenSSL: Checking only server " 1566 "certificate match"); 1567 return 0; 1568#else /* CONFIG_SHA256 */ 1569 wpa_printf(MSG_INFO, "No SHA256 included in the build - " 1570 "cannot validate server certificate hash"); 1571 return -1; 1572#endif /* CONFIG_SHA256 */ 1573 } 1574 1575 if (ca_cert_blob) { 1576 X509 *cert = d2i_X509(NULL, (OPENSSL_d2i_TYPE) &ca_cert_blob, 1577 ca_cert_blob_len); 1578 if (cert == NULL) { 1579 tls_show_errors(MSG_WARNING, __func__, 1580 "Failed to parse ca_cert_blob"); 1581 return -1; 1582 } 1583 1584 if (!X509_STORE_add_cert(ssl_ctx->cert_store, cert)) { 1585 unsigned long err = ERR_peek_error(); 1586 tls_show_errors(MSG_WARNING, __func__, 1587 "Failed to add ca_cert_blob to " 1588 "certificate store"); 1589 if (ERR_GET_LIB(err) == ERR_LIB_X509 && 1590 ERR_GET_REASON(err) == 1591 X509_R_CERT_ALREADY_IN_HASH_TABLE) { 1592 wpa_printf(MSG_DEBUG, "OpenSSL: %s - ignoring " 1593 "cert already in hash table error", 1594 __func__); 1595 } else { 1596 X509_free(cert); 1597 return -1; 1598 } 1599 } 1600 X509_free(cert); 1601 wpa_printf(MSG_DEBUG, "OpenSSL: %s - added ca_cert_blob " 1602 "to certificate store", __func__); 1603 return 0; 1604 } 1605 1606#ifdef ANDROID 1607 if (ca_cert && os_strncmp("keystore://", ca_cert, 11) == 0) { 1608 BIO *bio = BIO_from_keystore(&ca_cert[11]); 1609 STACK_OF(X509_INFO) *stack = NULL; 1610 int i; 1611 1612 if (bio) { 1613 stack = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL); 1614 BIO_free(bio); 1615 } 1616 if (!stack) 1617 return -1; 1618 1619 for (i = 0; i < sk_X509_INFO_num(stack); ++i) { 1620 X509_INFO *info = sk_X509_INFO_value(stack, i); 1621 if (info->x509) { 1622 X509_STORE_add_cert(ssl_ctx->cert_store, 1623 info->x509); 1624 } 1625 if (info->crl) { 1626 X509_STORE_add_crl(ssl_ctx->cert_store, 1627 info->crl); 1628 } 1629 } 1630 sk_X509_INFO_pop_free(stack, X509_INFO_free); 1631 SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb); 1632 return 0; 1633 } 1634#endif /* ANDROID */ 1635 1636#ifdef CONFIG_NATIVE_WINDOWS 1637 if (ca_cert && tls_cryptoapi_ca_cert(ssl_ctx, conn->ssl, ca_cert) == 1638 0) { 1639 wpa_printf(MSG_DEBUG, "OpenSSL: Added CA certificates from " 1640 "system certificate store"); 1641 return 0; 1642 } 1643#endif /* CONFIG_NATIVE_WINDOWS */ 1644 1645 if (ca_cert || ca_path) { 1646#ifndef OPENSSL_NO_STDIO 1647 if (SSL_CTX_load_verify_locations(ssl_ctx, ca_cert, ca_path) != 1648 1) { 1649 tls_show_errors(MSG_WARNING, __func__, 1650 "Failed to load root certificates"); 1651 if (ca_cert && 1652 tls_load_ca_der(ssl_ctx, ca_cert) == 0) { 1653 wpa_printf(MSG_DEBUG, "OpenSSL: %s - loaded " 1654 "DER format CA certificate", 1655 __func__); 1656 } else 1657 return -1; 1658 } else { 1659 wpa_printf(MSG_DEBUG, "TLS: Trusted root " 1660 "certificate(s) loaded"); 1661 tls_get_errors(ssl_ctx); 1662 } 1663#else /* OPENSSL_NO_STDIO */ 1664 wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", 1665 __func__); 1666 return -1; 1667#endif /* OPENSSL_NO_STDIO */ 1668 } else { 1669 /* No ca_cert configured - do not try to verify server 1670 * certificate */ 1671 conn->ca_cert_verify = 0; 1672 } 1673 1674 return 0; 1675} 1676 1677 1678static int tls_global_ca_cert(SSL_CTX *ssl_ctx, const char *ca_cert) 1679{ 1680 if (ca_cert) { 1681 if (SSL_CTX_load_verify_locations(ssl_ctx, ca_cert, NULL) != 1) 1682 { 1683 tls_show_errors(MSG_WARNING, __func__, 1684 "Failed to load root certificates"); 1685 return -1; 1686 } 1687 1688 wpa_printf(MSG_DEBUG, "TLS: Trusted root " 1689 "certificate(s) loaded"); 1690 1691#ifndef OPENSSL_NO_STDIO 1692 /* Add the same CAs to the client certificate requests */ 1693 SSL_CTX_set_client_CA_list(ssl_ctx, 1694 SSL_load_client_CA_file(ca_cert)); 1695#endif /* OPENSSL_NO_STDIO */ 1696 } 1697 1698 return 0; 1699} 1700 1701 1702int tls_global_set_verify(void *ssl_ctx, int check_crl) 1703{ 1704 int flags; 1705 1706 if (check_crl) { 1707 X509_STORE *cs = SSL_CTX_get_cert_store(ssl_ctx); 1708 if (cs == NULL) { 1709 tls_show_errors(MSG_INFO, __func__, "Failed to get " 1710 "certificate store when enabling " 1711 "check_crl"); 1712 return -1; 1713 } 1714 flags = X509_V_FLAG_CRL_CHECK; 1715 if (check_crl == 2) 1716 flags |= X509_V_FLAG_CRL_CHECK_ALL; 1717 X509_STORE_set_flags(cs, flags); 1718 } 1719 return 0; 1720} 1721 1722 1723static int tls_connection_set_subject_match(struct tls_connection *conn, 1724 const char *subject_match, 1725 const char *altsubject_match, 1726 const char *suffix_match) 1727{ 1728 os_free(conn->subject_match); 1729 conn->subject_match = NULL; 1730 if (subject_match) { 1731 conn->subject_match = os_strdup(subject_match); 1732 if (conn->subject_match == NULL) 1733 return -1; 1734 } 1735 1736 os_free(conn->altsubject_match); 1737 conn->altsubject_match = NULL; 1738 if (altsubject_match) { 1739 conn->altsubject_match = os_strdup(altsubject_match); 1740 if (conn->altsubject_match == NULL) 1741 return -1; 1742 } 1743 1744 os_free(conn->suffix_match); 1745 conn->suffix_match = NULL; 1746 if (suffix_match) { 1747 conn->suffix_match = os_strdup(suffix_match); 1748 if (conn->suffix_match == NULL) 1749 return -1; 1750 } 1751 1752 return 0; 1753} 1754 1755 1756int tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn, 1757 int verify_peer) 1758{ 1759 static int counter = 0; 1760 1761 if (conn == NULL) 1762 return -1; 1763 1764 if (verify_peer) { 1765 conn->ca_cert_verify = 1; 1766 SSL_set_verify(conn->ssl, SSL_VERIFY_PEER | 1767 SSL_VERIFY_FAIL_IF_NO_PEER_CERT | 1768 SSL_VERIFY_CLIENT_ONCE, tls_verify_cb); 1769 } else { 1770 conn->ca_cert_verify = 0; 1771 SSL_set_verify(conn->ssl, SSL_VERIFY_NONE, NULL); 1772 } 1773 1774 SSL_set_accept_state(conn->ssl); 1775 1776 /* 1777 * Set session id context in order to avoid fatal errors when client 1778 * tries to resume a session. However, set the context to a unique 1779 * value in order to effectively disable session resumption for now 1780 * since not all areas of the server code are ready for it (e.g., 1781 * EAP-TTLS needs special handling for Phase 2 after abbreviated TLS 1782 * handshake). 1783 */ 1784 counter++; 1785 SSL_set_session_id_context(conn->ssl, 1786 (const unsigned char *) &counter, 1787 sizeof(counter)); 1788 1789 return 0; 1790} 1791 1792 1793static int tls_connection_client_cert(struct tls_connection *conn, 1794 const char *client_cert, 1795 const u8 *client_cert_blob, 1796 size_t client_cert_blob_len) 1797{ 1798 if (client_cert == NULL && client_cert_blob == NULL) 1799 return 0; 1800 1801 if (client_cert_blob && 1802 SSL_use_certificate_ASN1(conn->ssl, (u8 *) client_cert_blob, 1803 client_cert_blob_len) == 1) { 1804 wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_ASN1 --> " 1805 "OK"); 1806 return 0; 1807 } else if (client_cert_blob) { 1808 tls_show_errors(MSG_DEBUG, __func__, 1809 "SSL_use_certificate_ASN1 failed"); 1810 } 1811 1812 if (client_cert == NULL) 1813 return -1; 1814 1815#ifdef ANDROID 1816 if (os_strncmp("keystore://", client_cert, 11) == 0) { 1817 BIO *bio = BIO_from_keystore(&client_cert[11]); 1818 X509 *x509 = NULL; 1819 int ret = -1; 1820 if (bio) { 1821 x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL); 1822 BIO_free(bio); 1823 } 1824 if (x509) { 1825 if (SSL_use_certificate(conn->ssl, x509) == 1) 1826 ret = 0; 1827 X509_free(x509); 1828 } 1829 return ret; 1830 } 1831#endif /* ANDROID */ 1832 1833#ifndef OPENSSL_NO_STDIO 1834 if (SSL_use_certificate_file(conn->ssl, client_cert, 1835 SSL_FILETYPE_ASN1) == 1) { 1836 wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_file (DER)" 1837 " --> OK"); 1838 return 0; 1839 } 1840 1841 if (SSL_use_certificate_file(conn->ssl, client_cert, 1842 SSL_FILETYPE_PEM) == 1) { 1843 ERR_clear_error(); 1844 wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_file (PEM)" 1845 " --> OK"); 1846 return 0; 1847 } 1848 1849 tls_show_errors(MSG_DEBUG, __func__, 1850 "SSL_use_certificate_file failed"); 1851#else /* OPENSSL_NO_STDIO */ 1852 wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", __func__); 1853#endif /* OPENSSL_NO_STDIO */ 1854 1855 return -1; 1856} 1857 1858 1859static int tls_global_client_cert(SSL_CTX *ssl_ctx, const char *client_cert) 1860{ 1861#ifndef OPENSSL_NO_STDIO 1862 if (client_cert == NULL) 1863 return 0; 1864 1865 if (SSL_CTX_use_certificate_file(ssl_ctx, client_cert, 1866 SSL_FILETYPE_ASN1) != 1 && 1867 SSL_CTX_use_certificate_chain_file(ssl_ctx, client_cert) != 1 && 1868 SSL_CTX_use_certificate_file(ssl_ctx, client_cert, 1869 SSL_FILETYPE_PEM) != 1) { 1870 tls_show_errors(MSG_INFO, __func__, 1871 "Failed to load client certificate"); 1872 return -1; 1873 } 1874 return 0; 1875#else /* OPENSSL_NO_STDIO */ 1876 if (client_cert == NULL) 1877 return 0; 1878 wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", __func__); 1879 return -1; 1880#endif /* OPENSSL_NO_STDIO */ 1881} 1882 1883 1884static int tls_passwd_cb(char *buf, int size, int rwflag, void *password) 1885{ 1886 if (password == NULL) { 1887 return 0; 1888 } 1889 os_strlcpy(buf, (char *) password, size); 1890 return os_strlen(buf); 1891} 1892 1893 1894#ifdef PKCS12_FUNCS 1895static int tls_parse_pkcs12(SSL_CTX *ssl_ctx, SSL *ssl, PKCS12 *p12, 1896 const char *passwd) 1897{ 1898 EVP_PKEY *pkey; 1899 X509 *cert; 1900 STACK_OF(X509) *certs; 1901 int res = 0; 1902 char buf[256]; 1903 1904 pkey = NULL; 1905 cert = NULL; 1906 certs = NULL; 1907 if (!PKCS12_parse(p12, passwd, &pkey, &cert, &certs)) { 1908 tls_show_errors(MSG_DEBUG, __func__, 1909 "Failed to parse PKCS12 file"); 1910 PKCS12_free(p12); 1911 return -1; 1912 } 1913 wpa_printf(MSG_DEBUG, "TLS: Successfully parsed PKCS12 data"); 1914 1915 if (cert) { 1916 X509_NAME_oneline(X509_get_subject_name(cert), buf, 1917 sizeof(buf)); 1918 wpa_printf(MSG_DEBUG, "TLS: Got certificate from PKCS12: " 1919 "subject='%s'", buf); 1920 if (ssl) { 1921 if (SSL_use_certificate(ssl, cert) != 1) 1922 res = -1; 1923 } else { 1924 if (SSL_CTX_use_certificate(ssl_ctx, cert) != 1) 1925 res = -1; 1926 } 1927 X509_free(cert); 1928 } 1929 1930 if (pkey) { 1931 wpa_printf(MSG_DEBUG, "TLS: Got private key from PKCS12"); 1932 if (ssl) { 1933 if (SSL_use_PrivateKey(ssl, pkey) != 1) 1934 res = -1; 1935 } else { 1936 if (SSL_CTX_use_PrivateKey(ssl_ctx, pkey) != 1) 1937 res = -1; 1938 } 1939 EVP_PKEY_free(pkey); 1940 } 1941 1942 if (certs) { 1943 while ((cert = sk_X509_pop(certs)) != NULL) { 1944 X509_NAME_oneline(X509_get_subject_name(cert), buf, 1945 sizeof(buf)); 1946 wpa_printf(MSG_DEBUG, "TLS: additional certificate" 1947 " from PKCS12: subject='%s'", buf); 1948 /* 1949 * There is no SSL equivalent for the chain cert - so 1950 * always add it to the context... 1951 */ 1952 if (SSL_CTX_add_extra_chain_cert(ssl_ctx, cert) != 1) { 1953 res = -1; 1954 break; 1955 } 1956 } 1957 sk_X509_free(certs); 1958 } 1959 1960 PKCS12_free(p12); 1961 1962 if (res < 0) 1963 tls_get_errors(ssl_ctx); 1964 1965 return res; 1966} 1967#endif /* PKCS12_FUNCS */ 1968 1969 1970static int tls_read_pkcs12(SSL_CTX *ssl_ctx, SSL *ssl, const char *private_key, 1971 const char *passwd) 1972{ 1973#ifdef PKCS12_FUNCS 1974 FILE *f; 1975 PKCS12 *p12; 1976 1977 f = fopen(private_key, "rb"); 1978 if (f == NULL) 1979 return -1; 1980 1981 p12 = d2i_PKCS12_fp(f, NULL); 1982 fclose(f); 1983 1984 if (p12 == NULL) { 1985 tls_show_errors(MSG_INFO, __func__, 1986 "Failed to use PKCS#12 file"); 1987 return -1; 1988 } 1989 1990 return tls_parse_pkcs12(ssl_ctx, ssl, p12, passwd); 1991 1992#else /* PKCS12_FUNCS */ 1993 wpa_printf(MSG_INFO, "TLS: PKCS12 support disabled - cannot read " 1994 "p12/pfx files"); 1995 return -1; 1996#endif /* PKCS12_FUNCS */ 1997} 1998 1999 2000static int tls_read_pkcs12_blob(SSL_CTX *ssl_ctx, SSL *ssl, 2001 const u8 *blob, size_t len, const char *passwd) 2002{ 2003#ifdef PKCS12_FUNCS 2004 PKCS12 *p12; 2005 2006 p12 = d2i_PKCS12(NULL, (OPENSSL_d2i_TYPE) &blob, len); 2007 if (p12 == NULL) { 2008 tls_show_errors(MSG_INFO, __func__, 2009 "Failed to use PKCS#12 blob"); 2010 return -1; 2011 } 2012 2013 return tls_parse_pkcs12(ssl_ctx, ssl, p12, passwd); 2014 2015#else /* PKCS12_FUNCS */ 2016 wpa_printf(MSG_INFO, "TLS: PKCS12 support disabled - cannot parse " 2017 "p12/pfx blobs"); 2018 return -1; 2019#endif /* PKCS12_FUNCS */ 2020} 2021 2022 2023#ifndef OPENSSL_NO_ENGINE 2024static int tls_engine_get_cert(struct tls_connection *conn, 2025 const char *cert_id, 2026 X509 **cert) 2027{ 2028 /* this runs after the private key is loaded so no PIN is required */ 2029 struct { 2030 const char *cert_id; 2031 X509 *cert; 2032 } params; 2033 params.cert_id = cert_id; 2034 params.cert = NULL; 2035 2036 if (!ENGINE_ctrl_cmd(conn->engine, "LOAD_CERT_CTRL", 2037 0, ¶ms, NULL, 1)) { 2038 wpa_printf(MSG_ERROR, "ENGINE: cannot load client cert with id" 2039 " '%s' [%s]", cert_id, 2040 ERR_error_string(ERR_get_error(), NULL)); 2041 return TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED; 2042 } 2043 if (!params.cert) { 2044 wpa_printf(MSG_ERROR, "ENGINE: did not properly cert with id" 2045 " '%s'", cert_id); 2046 return TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED; 2047 } 2048 *cert = params.cert; 2049 return 0; 2050} 2051#endif /* OPENSSL_NO_ENGINE */ 2052 2053 2054static int tls_connection_engine_client_cert(struct tls_connection *conn, 2055 const char *cert_id) 2056{ 2057#ifndef OPENSSL_NO_ENGINE 2058 X509 *cert; 2059 2060 if (tls_engine_get_cert(conn, cert_id, &cert)) 2061 return -1; 2062 2063 if (!SSL_use_certificate(conn->ssl, cert)) { 2064 tls_show_errors(MSG_ERROR, __func__, 2065 "SSL_use_certificate failed"); 2066 X509_free(cert); 2067 return -1; 2068 } 2069 X509_free(cert); 2070 wpa_printf(MSG_DEBUG, "ENGINE: SSL_use_certificate --> " 2071 "OK"); 2072 return 0; 2073 2074#else /* OPENSSL_NO_ENGINE */ 2075 return -1; 2076#endif /* OPENSSL_NO_ENGINE */ 2077} 2078 2079 2080static int tls_connection_engine_ca_cert(void *_ssl_ctx, 2081 struct tls_connection *conn, 2082 const char *ca_cert_id) 2083{ 2084#ifndef OPENSSL_NO_ENGINE 2085 X509 *cert; 2086 SSL_CTX *ssl_ctx = _ssl_ctx; 2087 2088 if (tls_engine_get_cert(conn, ca_cert_id, &cert)) 2089 return -1; 2090 2091 /* start off the same as tls_connection_ca_cert */ 2092 X509_STORE_free(ssl_ctx->cert_store); 2093 ssl_ctx->cert_store = X509_STORE_new(); 2094 if (ssl_ctx->cert_store == NULL) { 2095 wpa_printf(MSG_DEBUG, "OpenSSL: %s - failed to allocate new " 2096 "certificate store", __func__); 2097 X509_free(cert); 2098 return -1; 2099 } 2100 if (!X509_STORE_add_cert(ssl_ctx->cert_store, cert)) { 2101 unsigned long err = ERR_peek_error(); 2102 tls_show_errors(MSG_WARNING, __func__, 2103 "Failed to add CA certificate from engine " 2104 "to certificate store"); 2105 if (ERR_GET_LIB(err) == ERR_LIB_X509 && 2106 ERR_GET_REASON(err) == X509_R_CERT_ALREADY_IN_HASH_TABLE) { 2107 wpa_printf(MSG_DEBUG, "OpenSSL: %s - ignoring cert" 2108 " already in hash table error", 2109 __func__); 2110 } else { 2111 X509_free(cert); 2112 return -1; 2113 } 2114 } 2115 X509_free(cert); 2116 wpa_printf(MSG_DEBUG, "OpenSSL: %s - added CA certificate from engine " 2117 "to certificate store", __func__); 2118 SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb); 2119 conn->ca_cert_verify = 1; 2120 2121 return 0; 2122 2123#else /* OPENSSL_NO_ENGINE */ 2124 return -1; 2125#endif /* OPENSSL_NO_ENGINE */ 2126} 2127 2128 2129static int tls_connection_engine_private_key(struct tls_connection *conn) 2130{ 2131#ifndef OPENSSL_NO_ENGINE 2132 if (SSL_use_PrivateKey(conn->ssl, conn->private_key) != 1) { 2133 tls_show_errors(MSG_ERROR, __func__, 2134 "ENGINE: cannot use private key for TLS"); 2135 return -1; 2136 } 2137 if (!SSL_check_private_key(conn->ssl)) { 2138 tls_show_errors(MSG_INFO, __func__, 2139 "Private key failed verification"); 2140 return -1; 2141 } 2142 return 0; 2143#else /* OPENSSL_NO_ENGINE */ 2144 wpa_printf(MSG_ERROR, "SSL: Configuration uses engine, but " 2145 "engine support was not compiled in"); 2146 return -1; 2147#endif /* OPENSSL_NO_ENGINE */ 2148} 2149 2150 2151static int tls_connection_private_key(void *_ssl_ctx, 2152 struct tls_connection *conn, 2153 const char *private_key, 2154 const char *private_key_passwd, 2155 const u8 *private_key_blob, 2156 size_t private_key_blob_len) 2157{ 2158 SSL_CTX *ssl_ctx = _ssl_ctx; 2159 char *passwd; 2160 int ok; 2161 2162 if (private_key == NULL && private_key_blob == NULL) 2163 return 0; 2164 2165 if (private_key_passwd) { 2166 passwd = os_strdup(private_key_passwd); 2167 if (passwd == NULL) 2168 return -1; 2169 } else 2170 passwd = NULL; 2171 2172 SSL_CTX_set_default_passwd_cb(ssl_ctx, tls_passwd_cb); 2173 SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, passwd); 2174 2175 ok = 0; 2176 while (private_key_blob) { 2177 if (SSL_use_PrivateKey_ASN1(EVP_PKEY_RSA, conn->ssl, 2178 (u8 *) private_key_blob, 2179 private_key_blob_len) == 1) { 2180 wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_PrivateKey_" 2181 "ASN1(EVP_PKEY_RSA) --> OK"); 2182 ok = 1; 2183 break; 2184 } 2185 2186 if (SSL_use_PrivateKey_ASN1(EVP_PKEY_DSA, conn->ssl, 2187 (u8 *) private_key_blob, 2188 private_key_blob_len) == 1) { 2189 wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_PrivateKey_" 2190 "ASN1(EVP_PKEY_DSA) --> OK"); 2191 ok = 1; 2192 break; 2193 } 2194 2195 if (SSL_use_RSAPrivateKey_ASN1(conn->ssl, 2196 (u8 *) private_key_blob, 2197 private_key_blob_len) == 1) { 2198 wpa_printf(MSG_DEBUG, "OpenSSL: " 2199 "SSL_use_RSAPrivateKey_ASN1 --> OK"); 2200 ok = 1; 2201 break; 2202 } 2203 2204 if (tls_read_pkcs12_blob(ssl_ctx, conn->ssl, private_key_blob, 2205 private_key_blob_len, passwd) == 0) { 2206 wpa_printf(MSG_DEBUG, "OpenSSL: PKCS#12 as blob --> " 2207 "OK"); 2208 ok = 1; 2209 break; 2210 } 2211 2212 break; 2213 } 2214 2215 while (!ok && private_key) { 2216#ifndef OPENSSL_NO_STDIO 2217 if (SSL_use_PrivateKey_file(conn->ssl, private_key, 2218 SSL_FILETYPE_ASN1) == 1) { 2219 wpa_printf(MSG_DEBUG, "OpenSSL: " 2220 "SSL_use_PrivateKey_File (DER) --> OK"); 2221 ok = 1; 2222 break; 2223 } 2224 2225 if (SSL_use_PrivateKey_file(conn->ssl, private_key, 2226 SSL_FILETYPE_PEM) == 1) { 2227 wpa_printf(MSG_DEBUG, "OpenSSL: " 2228 "SSL_use_PrivateKey_File (PEM) --> OK"); 2229 ok = 1; 2230 break; 2231 } 2232#else /* OPENSSL_NO_STDIO */ 2233 wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", 2234 __func__); 2235#endif /* OPENSSL_NO_STDIO */ 2236 2237 if (tls_read_pkcs12(ssl_ctx, conn->ssl, private_key, passwd) 2238 == 0) { 2239 wpa_printf(MSG_DEBUG, "OpenSSL: Reading PKCS#12 file " 2240 "--> OK"); 2241 ok = 1; 2242 break; 2243 } 2244 2245 if (tls_cryptoapi_cert(conn->ssl, private_key) == 0) { 2246 wpa_printf(MSG_DEBUG, "OpenSSL: Using CryptoAPI to " 2247 "access certificate store --> OK"); 2248 ok = 1; 2249 break; 2250 } 2251 2252 break; 2253 } 2254 2255 if (!ok) { 2256 tls_show_errors(MSG_INFO, __func__, 2257 "Failed to load private key"); 2258 os_free(passwd); 2259 return -1; 2260 } 2261 ERR_clear_error(); 2262 SSL_CTX_set_default_passwd_cb(ssl_ctx, NULL); 2263 os_free(passwd); 2264 2265 if (!SSL_check_private_key(conn->ssl)) { 2266 tls_show_errors(MSG_INFO, __func__, "Private key failed " 2267 "verification"); 2268 return -1; 2269 } 2270 2271 wpa_printf(MSG_DEBUG, "SSL: Private key loaded successfully"); 2272 return 0; 2273} 2274 2275 2276static int tls_global_private_key(SSL_CTX *ssl_ctx, const char *private_key, 2277 const char *private_key_passwd) 2278{ 2279 char *passwd; 2280 2281 if (private_key == NULL) 2282 return 0; 2283 2284 if (private_key_passwd) { 2285 passwd = os_strdup(private_key_passwd); 2286 if (passwd == NULL) 2287 return -1; 2288 } else 2289 passwd = NULL; 2290 2291 SSL_CTX_set_default_passwd_cb(ssl_ctx, tls_passwd_cb); 2292 SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, passwd); 2293 if ( 2294#ifndef OPENSSL_NO_STDIO 2295 SSL_CTX_use_PrivateKey_file(ssl_ctx, private_key, 2296 SSL_FILETYPE_ASN1) != 1 && 2297 SSL_CTX_use_PrivateKey_file(ssl_ctx, private_key, 2298 SSL_FILETYPE_PEM) != 1 && 2299#endif /* OPENSSL_NO_STDIO */ 2300 tls_read_pkcs12(ssl_ctx, NULL, private_key, passwd)) { 2301 tls_show_errors(MSG_INFO, __func__, 2302 "Failed to load private key"); 2303 os_free(passwd); 2304 ERR_clear_error(); 2305 return -1; 2306 } 2307 os_free(passwd); 2308 ERR_clear_error(); 2309 SSL_CTX_set_default_passwd_cb(ssl_ctx, NULL); 2310 2311 if (!SSL_CTX_check_private_key(ssl_ctx)) { 2312 tls_show_errors(MSG_INFO, __func__, 2313 "Private key failed verification"); 2314 return -1; 2315 } 2316 2317 return 0; 2318} 2319 2320 2321static int tls_connection_dh(struct tls_connection *conn, const char *dh_file) 2322{ 2323#ifdef OPENSSL_NO_DH 2324 if (dh_file == NULL) 2325 return 0; 2326 wpa_printf(MSG_ERROR, "TLS: openssl does not include DH support, but " 2327 "dh_file specified"); 2328 return -1; 2329#else /* OPENSSL_NO_DH */ 2330 DH *dh; 2331 BIO *bio; 2332 2333 /* TODO: add support for dh_blob */ 2334 if (dh_file == NULL) 2335 return 0; 2336 if (conn == NULL) 2337 return -1; 2338 2339 bio = BIO_new_file(dh_file, "r"); 2340 if (bio == NULL) { 2341 wpa_printf(MSG_INFO, "TLS: Failed to open DH file '%s': %s", 2342 dh_file, ERR_error_string(ERR_get_error(), NULL)); 2343 return -1; 2344 } 2345 dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); 2346 BIO_free(bio); 2347#ifndef OPENSSL_NO_DSA 2348 while (dh == NULL) { 2349 DSA *dsa; 2350 wpa_printf(MSG_DEBUG, "TLS: Failed to parse DH file '%s': %s -" 2351 " trying to parse as DSA params", dh_file, 2352 ERR_error_string(ERR_get_error(), NULL)); 2353 bio = BIO_new_file(dh_file, "r"); 2354 if (bio == NULL) 2355 break; 2356 dsa = PEM_read_bio_DSAparams(bio, NULL, NULL, NULL); 2357 BIO_free(bio); 2358 if (!dsa) { 2359 wpa_printf(MSG_DEBUG, "TLS: Failed to parse DSA file " 2360 "'%s': %s", dh_file, 2361 ERR_error_string(ERR_get_error(), NULL)); 2362 break; 2363 } 2364 2365 wpa_printf(MSG_DEBUG, "TLS: DH file in DSA param format"); 2366 dh = DSA_dup_DH(dsa); 2367 DSA_free(dsa); 2368 if (dh == NULL) { 2369 wpa_printf(MSG_INFO, "TLS: Failed to convert DSA " 2370 "params into DH params"); 2371 break; 2372 } 2373 break; 2374 } 2375#endif /* !OPENSSL_NO_DSA */ 2376 if (dh == NULL) { 2377 wpa_printf(MSG_INFO, "TLS: Failed to read/parse DH/DSA file " 2378 "'%s'", dh_file); 2379 return -1; 2380 } 2381 2382 if (SSL_set_tmp_dh(conn->ssl, dh) != 1) { 2383 wpa_printf(MSG_INFO, "TLS: Failed to set DH params from '%s': " 2384 "%s", dh_file, 2385 ERR_error_string(ERR_get_error(), NULL)); 2386 DH_free(dh); 2387 return -1; 2388 } 2389 DH_free(dh); 2390 return 0; 2391#endif /* OPENSSL_NO_DH */ 2392} 2393 2394 2395static int tls_global_dh(SSL_CTX *ssl_ctx, const char *dh_file) 2396{ 2397#ifdef OPENSSL_NO_DH 2398 if (dh_file == NULL) 2399 return 0; 2400 wpa_printf(MSG_ERROR, "TLS: openssl does not include DH support, but " 2401 "dh_file specified"); 2402 return -1; 2403#else /* OPENSSL_NO_DH */ 2404 DH *dh; 2405 BIO *bio; 2406 2407 /* TODO: add support for dh_blob */ 2408 if (dh_file == NULL) 2409 return 0; 2410 if (ssl_ctx == NULL) 2411 return -1; 2412 2413 bio = BIO_new_file(dh_file, "r"); 2414 if (bio == NULL) { 2415 wpa_printf(MSG_INFO, "TLS: Failed to open DH file '%s': %s", 2416 dh_file, ERR_error_string(ERR_get_error(), NULL)); 2417 return -1; 2418 } 2419 dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); 2420 BIO_free(bio); 2421#ifndef OPENSSL_NO_DSA 2422 while (dh == NULL) { 2423 DSA *dsa; 2424 wpa_printf(MSG_DEBUG, "TLS: Failed to parse DH file '%s': %s -" 2425 " trying to parse as DSA params", dh_file, 2426 ERR_error_string(ERR_get_error(), NULL)); 2427 bio = BIO_new_file(dh_file, "r"); 2428 if (bio == NULL) 2429 break; 2430 dsa = PEM_read_bio_DSAparams(bio, NULL, NULL, NULL); 2431 BIO_free(bio); 2432 if (!dsa) { 2433 wpa_printf(MSG_DEBUG, "TLS: Failed to parse DSA file " 2434 "'%s': %s", dh_file, 2435 ERR_error_string(ERR_get_error(), NULL)); 2436 break; 2437 } 2438 2439 wpa_printf(MSG_DEBUG, "TLS: DH file in DSA param format"); 2440 dh = DSA_dup_DH(dsa); 2441 DSA_free(dsa); 2442 if (dh == NULL) { 2443 wpa_printf(MSG_INFO, "TLS: Failed to convert DSA " 2444 "params into DH params"); 2445 break; 2446 } 2447 break; 2448 } 2449#endif /* !OPENSSL_NO_DSA */ 2450 if (dh == NULL) { 2451 wpa_printf(MSG_INFO, "TLS: Failed to read/parse DH/DSA file " 2452 "'%s'", dh_file); 2453 return -1; 2454 } 2455 2456 if (SSL_CTX_set_tmp_dh(ssl_ctx, dh) != 1) { 2457 wpa_printf(MSG_INFO, "TLS: Failed to set DH params from '%s': " 2458 "%s", dh_file, 2459 ERR_error_string(ERR_get_error(), NULL)); 2460 DH_free(dh); 2461 return -1; 2462 } 2463 DH_free(dh); 2464 return 0; 2465#endif /* OPENSSL_NO_DH */ 2466} 2467 2468 2469int tls_connection_get_keys(void *ssl_ctx, struct tls_connection *conn, 2470 struct tls_keys *keys) 2471{ 2472#ifdef CONFIG_FIPS 2473 wpa_printf(MSG_ERROR, "OpenSSL: TLS keys cannot be exported in FIPS " 2474 "mode"); 2475 return -1; 2476#else /* CONFIG_FIPS */ 2477 SSL *ssl; 2478 2479 if (conn == NULL || keys == NULL) 2480 return -1; 2481 ssl = conn->ssl; 2482 if (ssl == NULL || ssl->s3 == NULL || ssl->session == NULL) 2483 return -1; 2484 2485 os_memset(keys, 0, sizeof(*keys)); 2486 keys->master_key = ssl->session->master_key; 2487 keys->master_key_len = ssl->session->master_key_length; 2488 keys->client_random = ssl->s3->client_random; 2489 keys->client_random_len = SSL3_RANDOM_SIZE; 2490 keys->server_random = ssl->s3->server_random; 2491 keys->server_random_len = SSL3_RANDOM_SIZE; 2492 2493 return 0; 2494#endif /* CONFIG_FIPS */ 2495} 2496 2497 2498int tls_connection_prf(void *tls_ctx, struct tls_connection *conn, 2499 const char *label, int server_random_first, 2500 u8 *out, size_t out_len) 2501{ 2502#if OPENSSL_VERSION_NUMBER >= 0x10001000L 2503 SSL *ssl; 2504 if (conn == NULL) 2505 return -1; 2506 if (server_random_first) 2507 return -1; 2508 ssl = conn->ssl; 2509 if (SSL_export_keying_material(ssl, out, out_len, label, 2510 os_strlen(label), NULL, 0, 0) == 1) { 2511 wpa_printf(MSG_DEBUG, "OpenSSL: Using internal PRF"); 2512 return 0; 2513 } 2514#endif 2515 return -1; 2516} 2517 2518 2519static struct wpabuf * 2520openssl_handshake(struct tls_connection *conn, const struct wpabuf *in_data, 2521 int server) 2522{ 2523 int res; 2524 struct wpabuf *out_data; 2525 2526 /* 2527 * Give TLS handshake data from the server (if available) to OpenSSL 2528 * for processing. 2529 */ 2530 if (in_data && 2531 BIO_write(conn->ssl_in, wpabuf_head(in_data), wpabuf_len(in_data)) 2532 < 0) { 2533 tls_show_errors(MSG_INFO, __func__, 2534 "Handshake failed - BIO_write"); 2535 return NULL; 2536 } 2537 2538 /* Initiate TLS handshake or continue the existing handshake */ 2539 if (server) 2540 res = SSL_accept(conn->ssl); 2541 else 2542 res = SSL_connect(conn->ssl); 2543 if (res != 1) { 2544 int err = SSL_get_error(conn->ssl, res); 2545 if (err == SSL_ERROR_WANT_READ) 2546 wpa_printf(MSG_DEBUG, "SSL: SSL_connect - want " 2547 "more data"); 2548 else if (err == SSL_ERROR_WANT_WRITE) 2549 wpa_printf(MSG_DEBUG, "SSL: SSL_connect - want to " 2550 "write"); 2551 else { 2552 tls_show_errors(MSG_INFO, __func__, "SSL_connect"); 2553 conn->failed++; 2554 } 2555 } 2556 2557 /* Get the TLS handshake data to be sent to the server */ 2558 res = BIO_ctrl_pending(conn->ssl_out); 2559 wpa_printf(MSG_DEBUG, "SSL: %d bytes pending from ssl_out", res); 2560 out_data = wpabuf_alloc(res); 2561 if (out_data == NULL) { 2562 wpa_printf(MSG_DEBUG, "SSL: Failed to allocate memory for " 2563 "handshake output (%d bytes)", res); 2564 if (BIO_reset(conn->ssl_out) < 0) { 2565 tls_show_errors(MSG_INFO, __func__, 2566 "BIO_reset failed"); 2567 } 2568 return NULL; 2569 } 2570 res = res == 0 ? 0 : BIO_read(conn->ssl_out, wpabuf_mhead(out_data), 2571 res); 2572 if (res < 0) { 2573 tls_show_errors(MSG_INFO, __func__, 2574 "Handshake failed - BIO_read"); 2575 if (BIO_reset(conn->ssl_out) < 0) { 2576 tls_show_errors(MSG_INFO, __func__, 2577 "BIO_reset failed"); 2578 } 2579 wpabuf_free(out_data); 2580 return NULL; 2581 } 2582 wpabuf_put(out_data, res); 2583 2584 return out_data; 2585} 2586 2587 2588static struct wpabuf * 2589openssl_get_appl_data(struct tls_connection *conn, size_t max_len) 2590{ 2591 struct wpabuf *appl_data; 2592 int res; 2593 2594 appl_data = wpabuf_alloc(max_len + 100); 2595 if (appl_data == NULL) 2596 return NULL; 2597 2598 res = SSL_read(conn->ssl, wpabuf_mhead(appl_data), 2599 wpabuf_size(appl_data)); 2600 if (res < 0) { 2601 int err = SSL_get_error(conn->ssl, res); 2602 if (err == SSL_ERROR_WANT_READ || 2603 err == SSL_ERROR_WANT_WRITE) { 2604 wpa_printf(MSG_DEBUG, "SSL: No Application Data " 2605 "included"); 2606 } else { 2607 tls_show_errors(MSG_INFO, __func__, 2608 "Failed to read possible " 2609 "Application Data"); 2610 } 2611 wpabuf_free(appl_data); 2612 return NULL; 2613 } 2614 2615 wpabuf_put(appl_data, res); 2616 wpa_hexdump_buf_key(MSG_MSGDUMP, "SSL: Application Data in Finished " 2617 "message", appl_data); 2618 2619 return appl_data; 2620} 2621 2622 2623static struct wpabuf * 2624openssl_connection_handshake(struct tls_connection *conn, 2625 const struct wpabuf *in_data, 2626 struct wpabuf **appl_data, int server) 2627{ 2628 struct wpabuf *out_data; 2629 2630 if (appl_data) 2631 *appl_data = NULL; 2632 2633 out_data = openssl_handshake(conn, in_data, server); 2634 if (out_data == NULL) 2635 return NULL; 2636 2637 if (SSL_is_init_finished(conn->ssl) && appl_data && in_data) 2638 *appl_data = openssl_get_appl_data(conn, wpabuf_len(in_data)); 2639 2640 return out_data; 2641} 2642 2643 2644struct wpabuf * 2645tls_connection_handshake(void *ssl_ctx, struct tls_connection *conn, 2646 const struct wpabuf *in_data, 2647 struct wpabuf **appl_data) 2648{ 2649 return openssl_connection_handshake(conn, in_data, appl_data, 0); 2650} 2651 2652 2653struct wpabuf * tls_connection_server_handshake(void *tls_ctx, 2654 struct tls_connection *conn, 2655 const struct wpabuf *in_data, 2656 struct wpabuf **appl_data) 2657{ 2658 return openssl_connection_handshake(conn, in_data, appl_data, 1); 2659} 2660 2661 2662struct wpabuf * tls_connection_encrypt(void *tls_ctx, 2663 struct tls_connection *conn, 2664 const struct wpabuf *in_data) 2665{ 2666 int res; 2667 struct wpabuf *buf; 2668 2669 if (conn == NULL) 2670 return NULL; 2671 2672 /* Give plaintext data for OpenSSL to encrypt into the TLS tunnel. */ 2673 if ((res = BIO_reset(conn->ssl_in)) < 0 || 2674 (res = BIO_reset(conn->ssl_out)) < 0) { 2675 tls_show_errors(MSG_INFO, __func__, "BIO_reset failed"); 2676 return NULL; 2677 } 2678 res = SSL_write(conn->ssl, wpabuf_head(in_data), wpabuf_len(in_data)); 2679 if (res < 0) { 2680 tls_show_errors(MSG_INFO, __func__, 2681 "Encryption failed - SSL_write"); 2682 return NULL; 2683 } 2684 2685 /* Read encrypted data to be sent to the server */ 2686 buf = wpabuf_alloc(wpabuf_len(in_data) + 300); 2687 if (buf == NULL) 2688 return NULL; 2689 res = BIO_read(conn->ssl_out, wpabuf_mhead(buf), wpabuf_size(buf)); 2690 if (res < 0) { 2691 tls_show_errors(MSG_INFO, __func__, 2692 "Encryption failed - BIO_read"); 2693 wpabuf_free(buf); 2694 return NULL; 2695 } 2696 wpabuf_put(buf, res); 2697 2698 return buf; 2699} 2700 2701 2702struct wpabuf * tls_connection_decrypt(void *tls_ctx, 2703 struct tls_connection *conn, 2704 const struct wpabuf *in_data) 2705{ 2706 int res; 2707 struct wpabuf *buf; 2708 2709 /* Give encrypted data from TLS tunnel for OpenSSL to decrypt. */ 2710 res = BIO_write(conn->ssl_in, wpabuf_head(in_data), 2711 wpabuf_len(in_data)); 2712 if (res < 0) { 2713 tls_show_errors(MSG_INFO, __func__, 2714 "Decryption failed - BIO_write"); 2715 return NULL; 2716 } 2717 if (BIO_reset(conn->ssl_out) < 0) { 2718 tls_show_errors(MSG_INFO, __func__, "BIO_reset failed"); 2719 return NULL; 2720 } 2721 2722 /* Read decrypted data for further processing */ 2723 /* 2724 * Even though we try to disable TLS compression, it is possible that 2725 * this cannot be done with all TLS libraries. Add extra buffer space 2726 * to handle the possibility of the decrypted data being longer than 2727 * input data. 2728 */ 2729 buf = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3); 2730 if (buf == NULL) 2731 return NULL; 2732 res = SSL_read(conn->ssl, wpabuf_mhead(buf), wpabuf_size(buf)); 2733 if (res < 0) { 2734 tls_show_errors(MSG_INFO, __func__, 2735 "Decryption failed - SSL_read"); 2736 wpabuf_free(buf); 2737 return NULL; 2738 } 2739 wpabuf_put(buf, res); 2740 2741 return buf; 2742} 2743 2744 2745int tls_connection_resumed(void *ssl_ctx, struct tls_connection *conn) 2746{ 2747 return conn ? conn->ssl->hit : 0; 2748} 2749 2750 2751int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn, 2752 u8 *ciphers) 2753{ 2754 char buf[100], *pos, *end; 2755 u8 *c; 2756 int ret; 2757 2758 if (conn == NULL || conn->ssl == NULL || ciphers == NULL) 2759 return -1; 2760 2761 buf[0] = '\0'; 2762 pos = buf; 2763 end = pos + sizeof(buf); 2764 2765 c = ciphers; 2766 while (*c != TLS_CIPHER_NONE) { 2767 const char *suite; 2768 2769 switch (*c) { 2770 case TLS_CIPHER_RC4_SHA: 2771 suite = "RC4-SHA"; 2772 break; 2773 case TLS_CIPHER_AES128_SHA: 2774 suite = "AES128-SHA"; 2775 break; 2776 case TLS_CIPHER_RSA_DHE_AES128_SHA: 2777 suite = "DHE-RSA-AES128-SHA"; 2778 break; 2779 case TLS_CIPHER_ANON_DH_AES128_SHA: 2780 suite = "ADH-AES128-SHA"; 2781 break; 2782 default: 2783 wpa_printf(MSG_DEBUG, "TLS: Unsupported " 2784 "cipher selection: %d", *c); 2785 return -1; 2786 } 2787 ret = os_snprintf(pos, end - pos, ":%s", suite); 2788 if (ret < 0 || ret >= end - pos) 2789 break; 2790 pos += ret; 2791 2792 c++; 2793 } 2794 2795 wpa_printf(MSG_DEBUG, "OpenSSL: cipher suites: %s", buf + 1); 2796 2797 if (SSL_set_cipher_list(conn->ssl, buf + 1) != 1) { 2798 tls_show_errors(MSG_INFO, __func__, 2799 "Cipher suite configuration failed"); 2800 return -1; 2801 } 2802 2803 return 0; 2804} 2805 2806 2807int tls_get_cipher(void *ssl_ctx, struct tls_connection *conn, 2808 char *buf, size_t buflen) 2809{ 2810 const char *name; 2811 if (conn == NULL || conn->ssl == NULL) 2812 return -1; 2813 2814 name = SSL_get_cipher(conn->ssl); 2815 if (name == NULL) 2816 return -1; 2817 2818 os_strlcpy(buf, name, buflen); 2819 return 0; 2820} 2821 2822 2823int tls_connection_enable_workaround(void *ssl_ctx, 2824 struct tls_connection *conn) 2825{ 2826 SSL_set_options(conn->ssl, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS); 2827 2828 return 0; 2829} 2830 2831 2832#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) 2833/* ClientHello TLS extensions require a patch to openssl, so this function is 2834 * commented out unless explicitly needed for EAP-FAST in order to be able to 2835 * build this file with unmodified openssl. */ 2836int tls_connection_client_hello_ext(void *ssl_ctx, struct tls_connection *conn, 2837 int ext_type, const u8 *data, 2838 size_t data_len) 2839{ 2840 if (conn == NULL || conn->ssl == NULL || ext_type != 35) 2841 return -1; 2842 2843#ifdef CONFIG_OPENSSL_TICKET_OVERRIDE 2844 if (SSL_set_session_ticket_ext(conn->ssl, (void *) data, 2845 data_len) != 1) 2846 return -1; 2847#else /* CONFIG_OPENSSL_TICKET_OVERRIDE */ 2848 if (SSL_set_hello_extension(conn->ssl, ext_type, (void *) data, 2849 data_len) != 1) 2850 return -1; 2851#endif /* CONFIG_OPENSSL_TICKET_OVERRIDE */ 2852 2853 return 0; 2854} 2855#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */ 2856 2857 2858int tls_connection_get_failed(void *ssl_ctx, struct tls_connection *conn) 2859{ 2860 if (conn == NULL) 2861 return -1; 2862 return conn->failed; 2863} 2864 2865 2866int tls_connection_get_read_alerts(void *ssl_ctx, struct tls_connection *conn) 2867{ 2868 if (conn == NULL) 2869 return -1; 2870 return conn->read_alerts; 2871} 2872 2873 2874int tls_connection_get_write_alerts(void *ssl_ctx, struct tls_connection *conn) 2875{ 2876 if (conn == NULL) 2877 return -1; 2878 return conn->write_alerts; 2879} 2880 2881 2882#ifdef HAVE_OCSP 2883 2884static void ocsp_debug_print_resp(OCSP_RESPONSE *rsp) 2885{ 2886#ifndef CONFIG_NO_STDOUT_DEBUG 2887 extern int wpa_debug_level; 2888 BIO *out; 2889 size_t rlen; 2890 char *txt; 2891 int res; 2892 2893 if (wpa_debug_level > MSG_DEBUG) 2894 return; 2895 2896 out = BIO_new(BIO_s_mem()); 2897 if (!out) 2898 return; 2899 2900 OCSP_RESPONSE_print(out, rsp, 0); 2901 rlen = BIO_ctrl_pending(out); 2902 txt = os_malloc(rlen + 1); 2903 if (!txt) { 2904 BIO_free(out); 2905 return; 2906 } 2907 2908 res = BIO_read(out, txt, rlen); 2909 if (res > 0) { 2910 txt[res] = '\0'; 2911 wpa_printf(MSG_DEBUG, "OpenSSL: OCSP Response\n%s", txt); 2912 } 2913 os_free(txt); 2914 BIO_free(out); 2915#endif /* CONFIG_NO_STDOUT_DEBUG */ 2916} 2917 2918 2919static int ocsp_resp_cb(SSL *s, void *arg) 2920{ 2921 struct tls_connection *conn = arg; 2922 const unsigned char *p; 2923 int len, status, reason; 2924 OCSP_RESPONSE *rsp; 2925 OCSP_BASICRESP *basic; 2926 OCSP_CERTID *id; 2927 ASN1_GENERALIZEDTIME *produced_at, *this_update, *next_update; 2928 2929 len = SSL_get_tlsext_status_ocsp_resp(s, &p); 2930 if (!p) { 2931 wpa_printf(MSG_DEBUG, "OpenSSL: No OCSP response received"); 2932 return (conn->flags & TLS_CONN_REQUIRE_OCSP) ? 0 : 1; 2933 } 2934 2935 wpa_hexdump(MSG_DEBUG, "OpenSSL: OCSP response", p, len); 2936 2937 rsp = d2i_OCSP_RESPONSE(NULL, &p, len); 2938 if (!rsp) { 2939 wpa_printf(MSG_INFO, "OpenSSL: Failed to parse OCSP response"); 2940 return 0; 2941 } 2942 2943 ocsp_debug_print_resp(rsp); 2944 2945 status = OCSP_response_status(rsp); 2946 if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) { 2947 wpa_printf(MSG_INFO, "OpenSSL: OCSP responder error %d (%s)", 2948 status, OCSP_response_status_str(status)); 2949 return 0; 2950 } 2951 2952 basic = OCSP_response_get1_basic(rsp); 2953 if (!basic) { 2954 wpa_printf(MSG_INFO, "OpenSSL: Could not find BasicOCSPResponse"); 2955 return 0; 2956 } 2957 2958 status = OCSP_basic_verify(basic, NULL, SSL_CTX_get_cert_store(s->ctx), 2959 0); 2960 if (status <= 0) { 2961 tls_show_errors(MSG_INFO, __func__, 2962 "OpenSSL: OCSP response failed verification"); 2963 OCSP_BASICRESP_free(basic); 2964 OCSP_RESPONSE_free(rsp); 2965 return 0; 2966 } 2967 2968 wpa_printf(MSG_DEBUG, "OpenSSL: OCSP response verification succeeded"); 2969 2970 if (!conn->peer_cert) { 2971 wpa_printf(MSG_DEBUG, "OpenSSL: Peer certificate not available for OCSP status check"); 2972 OCSP_BASICRESP_free(basic); 2973 OCSP_RESPONSE_free(rsp); 2974 return 0; 2975 } 2976 2977 if (!conn->peer_issuer) { 2978 wpa_printf(MSG_DEBUG, "OpenSSL: Peer issuer certificate not available for OCSP status check"); 2979 OCSP_BASICRESP_free(basic); 2980 OCSP_RESPONSE_free(rsp); 2981 return 0; 2982 } 2983 2984 id = OCSP_cert_to_id(NULL, conn->peer_cert, conn->peer_issuer); 2985 if (!id) { 2986 wpa_printf(MSG_DEBUG, "OpenSSL: Could not create OCSP certificate identifier"); 2987 OCSP_BASICRESP_free(basic); 2988 OCSP_RESPONSE_free(rsp); 2989 return 0; 2990 } 2991 2992 if (!OCSP_resp_find_status(basic, id, &status, &reason, &produced_at, 2993 &this_update, &next_update)) { 2994 wpa_printf(MSG_INFO, "OpenSSL: Could not find current server certificate from OCSP response%s", 2995 (conn->flags & TLS_CONN_REQUIRE_OCSP) ? "" : 2996 " (OCSP not required)"); 2997 OCSP_BASICRESP_free(basic); 2998 OCSP_RESPONSE_free(rsp); 2999 return (conn->flags & TLS_CONN_REQUIRE_OCSP) ? 0 : 1; 3000 } 3001 3002 if (!OCSP_check_validity(this_update, next_update, 5 * 60, -1)) { 3003 tls_show_errors(MSG_INFO, __func__, 3004 "OpenSSL: OCSP status times invalid"); 3005 OCSP_BASICRESP_free(basic); 3006 OCSP_RESPONSE_free(rsp); 3007 return 0; 3008 } 3009 3010 OCSP_BASICRESP_free(basic); 3011 OCSP_RESPONSE_free(rsp); 3012 3013 wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status for server certificate: %s", 3014 OCSP_cert_status_str(status)); 3015 3016 if (status == V_OCSP_CERTSTATUS_GOOD) 3017 return 1; 3018 if (status == V_OCSP_CERTSTATUS_REVOKED) 3019 return 0; 3020 if (conn->flags & TLS_CONN_REQUIRE_OCSP) { 3021 wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status unknown, but OCSP required"); 3022 return 0; 3023 } 3024 wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status unknown, but OCSP was not required, so allow connection to continue"); 3025 return 1; 3026} 3027 3028 3029static int ocsp_status_cb(SSL *s, void *arg) 3030{ 3031 char *tmp; 3032 char *resp; 3033 size_t len; 3034 3035 if (tls_global->ocsp_stapling_response == NULL) { 3036 wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status callback - no response configured"); 3037 return SSL_TLSEXT_ERR_OK; 3038 } 3039 3040 resp = os_readfile(tls_global->ocsp_stapling_response, &len); 3041 if (resp == NULL) { 3042 wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status callback - could not read response file"); 3043 /* TODO: Build OCSPResponse with responseStatus = internalError 3044 */ 3045 return SSL_TLSEXT_ERR_OK; 3046 } 3047 wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status callback - send cached response"); 3048 tmp = OPENSSL_malloc(len); 3049 if (tmp == NULL) { 3050 os_free(resp); 3051 return SSL_TLSEXT_ERR_ALERT_FATAL; 3052 } 3053 3054 os_memcpy(tmp, resp, len); 3055 os_free(resp); 3056 SSL_set_tlsext_status_ocsp_resp(s, tmp, len); 3057 3058 return SSL_TLSEXT_ERR_OK; 3059} 3060 3061#endif /* HAVE_OCSP */ 3062 3063 3064int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn, 3065 const struct tls_connection_params *params) 3066{ 3067 int ret; 3068 unsigned long err; 3069 SSL_CTX *ssl_ctx = tls_ctx; 3070 3071 if (conn == NULL) 3072 return -1; 3073 3074 while ((err = ERR_get_error())) { 3075 wpa_printf(MSG_INFO, "%s: Clearing pending SSL error: %s", 3076 __func__, ERR_error_string(err, NULL)); 3077 } 3078 3079 if (params->engine) { 3080 wpa_printf(MSG_DEBUG, "SSL: Initializing TLS engine"); 3081 ret = tls_engine_init(conn, params->engine_id, params->pin, 3082 params->key_id, params->cert_id, 3083 params->ca_cert_id); 3084 if (ret) 3085 return ret; 3086 } 3087 if (tls_connection_set_subject_match(conn, 3088 params->subject_match, 3089 params->altsubject_match, 3090 params->suffix_match)) 3091 return -1; 3092 3093 if (params->engine && params->ca_cert_id) { 3094 if (tls_connection_engine_ca_cert(tls_ctx, conn, 3095 params->ca_cert_id)) 3096 return TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED; 3097 } else if (tls_connection_ca_cert(tls_ctx, conn, params->ca_cert, 3098 params->ca_cert_blob, 3099 params->ca_cert_blob_len, 3100 params->ca_path)) 3101 return -1; 3102 3103 if (params->engine && params->cert_id) { 3104 if (tls_connection_engine_client_cert(conn, params->cert_id)) 3105 return TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED; 3106 } else if (tls_connection_client_cert(conn, params->client_cert, 3107 params->client_cert_blob, 3108 params->client_cert_blob_len)) 3109 return -1; 3110 3111 if (params->engine && params->key_id) { 3112 wpa_printf(MSG_DEBUG, "TLS: Using private key from engine"); 3113 if (tls_connection_engine_private_key(conn)) 3114 return TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED; 3115 } else if (tls_connection_private_key(tls_ctx, conn, 3116 params->private_key, 3117 params->private_key_passwd, 3118 params->private_key_blob, 3119 params->private_key_blob_len)) { 3120 wpa_printf(MSG_INFO, "TLS: Failed to load private key '%s'", 3121 params->private_key); 3122 return -1; 3123 } 3124 3125 if (tls_connection_dh(conn, params->dh_file)) { 3126 wpa_printf(MSG_INFO, "TLS: Failed to load DH file '%s'", 3127 params->dh_file); 3128 return -1; 3129 } 3130 3131#ifdef SSL_OP_NO_TICKET 3132 if (params->flags & TLS_CONN_DISABLE_SESSION_TICKET) 3133 SSL_set_options(conn->ssl, SSL_OP_NO_TICKET); 3134#ifdef SSL_clear_options 3135 else 3136 SSL_clear_options(conn->ssl, SSL_OP_NO_TICKET); 3137#endif /* SSL_clear_options */ 3138#endif /* SSL_OP_NO_TICKET */ 3139 3140#ifdef HAVE_OCSP 3141 if (params->flags & TLS_CONN_REQUEST_OCSP) { 3142 SSL_set_tlsext_status_type(conn->ssl, TLSEXT_STATUSTYPE_ocsp); 3143 SSL_CTX_set_tlsext_status_cb(ssl_ctx, ocsp_resp_cb); 3144 SSL_CTX_set_tlsext_status_arg(ssl_ctx, conn); 3145 } 3146#endif /* HAVE_OCSP */ 3147 3148 conn->flags = params->flags; 3149 3150 tls_get_errors(tls_ctx); 3151 3152 return 0; 3153} 3154 3155 3156int tls_global_set_params(void *tls_ctx, 3157 const struct tls_connection_params *params) 3158{ 3159 SSL_CTX *ssl_ctx = tls_ctx; 3160 unsigned long err; 3161 3162 while ((err = ERR_get_error())) { 3163 wpa_printf(MSG_INFO, "%s: Clearing pending SSL error: %s", 3164 __func__, ERR_error_string(err, NULL)); 3165 } 3166 3167 if (tls_global_ca_cert(ssl_ctx, params->ca_cert)) 3168 return -1; 3169 3170 if (tls_global_client_cert(ssl_ctx, params->client_cert)) 3171 return -1; 3172 3173 if (tls_global_private_key(ssl_ctx, params->private_key, 3174 params->private_key_passwd)) 3175 return -1; 3176 3177 if (tls_global_dh(ssl_ctx, params->dh_file)) { 3178 wpa_printf(MSG_INFO, "TLS: Failed to load DH file '%s'", 3179 params->dh_file); 3180 return -1; 3181 } 3182 3183#ifdef SSL_OP_NO_TICKET 3184 if (params->flags & TLS_CONN_DISABLE_SESSION_TICKET) 3185 SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TICKET); 3186#ifdef SSL_CTX_clear_options 3187 else 3188 SSL_CTX_clear_options(ssl_ctx, SSL_OP_NO_TICKET); 3189#endif /* SSL_clear_options */ 3190#endif /* SSL_OP_NO_TICKET */ 3191 3192#ifdef HAVE_OCSP 3193 SSL_CTX_set_tlsext_status_cb(ssl_ctx, ocsp_status_cb); 3194 SSL_CTX_set_tlsext_status_arg(ssl_ctx, ssl_ctx); 3195 os_free(tls_global->ocsp_stapling_response); 3196 if (params->ocsp_stapling_response) 3197 tls_global->ocsp_stapling_response = 3198 os_strdup(params->ocsp_stapling_response); 3199 else 3200 tls_global->ocsp_stapling_response = NULL; 3201#endif /* HAVE_OCSP */ 3202 3203 return 0; 3204} 3205 3206 3207int tls_connection_get_keyblock_size(void *tls_ctx, 3208 struct tls_connection *conn) 3209{ 3210 const EVP_CIPHER *c; 3211 const EVP_MD *h; 3212 int md_size; 3213 3214 if (conn == NULL || conn->ssl == NULL || 3215 conn->ssl->enc_read_ctx == NULL || 3216 conn->ssl->enc_read_ctx->cipher == NULL || 3217 conn->ssl->read_hash == NULL) 3218 return -1; 3219 3220 c = conn->ssl->enc_read_ctx->cipher; 3221#if OPENSSL_VERSION_NUMBER >= 0x00909000L 3222 h = EVP_MD_CTX_md(conn->ssl->read_hash); 3223#else 3224 h = conn->ssl->read_hash; 3225#endif 3226 if (h) 3227 md_size = EVP_MD_size(h); 3228#if OPENSSL_VERSION_NUMBER >= 0x10000000L 3229 else if (conn->ssl->s3) 3230 md_size = conn->ssl->s3->tmp.new_mac_secret_size; 3231#endif 3232 else 3233 return -1; 3234 3235 wpa_printf(MSG_DEBUG, "OpenSSL: keyblock size: key_len=%d MD_size=%d " 3236 "IV_len=%d", EVP_CIPHER_key_length(c), md_size, 3237 EVP_CIPHER_iv_length(c)); 3238 return 2 * (EVP_CIPHER_key_length(c) + 3239 md_size + 3240 EVP_CIPHER_iv_length(c)); 3241} 3242 3243 3244unsigned int tls_capabilities(void *tls_ctx) 3245{ 3246 return 0; 3247} 3248 3249 3250#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) 3251/* Pre-shared secred requires a patch to openssl, so this function is 3252 * commented out unless explicitly needed for EAP-FAST in order to be able to 3253 * build this file with unmodified openssl. */ 3254 3255static int tls_sess_sec_cb(SSL *s, void *secret, int *secret_len, 3256 STACK_OF(SSL_CIPHER) *peer_ciphers, 3257 SSL_CIPHER **cipher, void *arg) 3258{ 3259 struct tls_connection *conn = arg; 3260 int ret; 3261 3262 if (conn == NULL || conn->session_ticket_cb == NULL) 3263 return 0; 3264 3265 ret = conn->session_ticket_cb(conn->session_ticket_cb_ctx, 3266 conn->session_ticket, 3267 conn->session_ticket_len, 3268 s->s3->client_random, 3269 s->s3->server_random, secret); 3270 os_free(conn->session_ticket); 3271 conn->session_ticket = NULL; 3272 3273 if (ret <= 0) 3274 return 0; 3275 3276 *secret_len = SSL_MAX_MASTER_KEY_LENGTH; 3277 return 1; 3278} 3279 3280 3281#ifdef CONFIG_OPENSSL_TICKET_OVERRIDE 3282static int tls_session_ticket_ext_cb(SSL *s, const unsigned char *data, 3283 int len, void *arg) 3284{ 3285 struct tls_connection *conn = arg; 3286 3287 if (conn == NULL || conn->session_ticket_cb == NULL) 3288 return 0; 3289 3290 wpa_printf(MSG_DEBUG, "OpenSSL: %s: length=%d", __func__, len); 3291 3292 os_free(conn->session_ticket); 3293 conn->session_ticket = NULL; 3294 3295 wpa_hexdump(MSG_DEBUG, "OpenSSL: ClientHello SessionTicket " 3296 "extension", data, len); 3297 3298 conn->session_ticket = os_malloc(len); 3299 if (conn->session_ticket == NULL) 3300 return 0; 3301 3302 os_memcpy(conn->session_ticket, data, len); 3303 conn->session_ticket_len = len; 3304 3305 return 1; 3306} 3307#else /* CONFIG_OPENSSL_TICKET_OVERRIDE */ 3308#ifdef SSL_OP_NO_TICKET 3309static void tls_hello_ext_cb(SSL *s, int client_server, int type, 3310 unsigned char *data, int len, void *arg) 3311{ 3312 struct tls_connection *conn = arg; 3313 3314 if (conn == NULL || conn->session_ticket_cb == NULL) 3315 return; 3316 3317 wpa_printf(MSG_DEBUG, "OpenSSL: %s: type=%d length=%d", __func__, 3318 type, len); 3319 3320 if (type == TLSEXT_TYPE_session_ticket && !client_server) { 3321 os_free(conn->session_ticket); 3322 conn->session_ticket = NULL; 3323 3324 wpa_hexdump(MSG_DEBUG, "OpenSSL: ClientHello SessionTicket " 3325 "extension", data, len); 3326 conn->session_ticket = os_malloc(len); 3327 if (conn->session_ticket == NULL) 3328 return; 3329 3330 os_memcpy(conn->session_ticket, data, len); 3331 conn->session_ticket_len = len; 3332 } 3333} 3334#else /* SSL_OP_NO_TICKET */ 3335static int tls_hello_ext_cb(SSL *s, TLS_EXTENSION *ext, void *arg) 3336{ 3337 struct tls_connection *conn = arg; 3338 3339 if (conn == NULL || conn->session_ticket_cb == NULL) 3340 return 0; 3341 3342 wpa_printf(MSG_DEBUG, "OpenSSL: %s: type=%d length=%d", __func__, 3343 ext->type, ext->length); 3344 3345 os_free(conn->session_ticket); 3346 conn->session_ticket = NULL; 3347 3348 if (ext->type == 35) { 3349 wpa_hexdump(MSG_DEBUG, "OpenSSL: ClientHello SessionTicket " 3350 "extension", ext->data, ext->length); 3351 conn->session_ticket = os_malloc(ext->length); 3352 if (conn->session_ticket == NULL) 3353 return SSL_AD_INTERNAL_ERROR; 3354 3355 os_memcpy(conn->session_ticket, ext->data, ext->length); 3356 conn->session_ticket_len = ext->length; 3357 } 3358 3359 return 0; 3360} 3361#endif /* SSL_OP_NO_TICKET */ 3362#endif /* CONFIG_OPENSSL_TICKET_OVERRIDE */ 3363#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */ 3364 3365 3366int tls_connection_set_session_ticket_cb(void *tls_ctx, 3367 struct tls_connection *conn, 3368 tls_session_ticket_cb cb, 3369 void *ctx) 3370{ 3371#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) 3372 conn->session_ticket_cb = cb; 3373 conn->session_ticket_cb_ctx = ctx; 3374 3375 if (cb) { 3376 if (SSL_set_session_secret_cb(conn->ssl, tls_sess_sec_cb, 3377 conn) != 1) 3378 return -1; 3379#ifdef CONFIG_OPENSSL_TICKET_OVERRIDE 3380 SSL_set_session_ticket_ext_cb(conn->ssl, 3381 tls_session_ticket_ext_cb, conn); 3382#else /* CONFIG_OPENSSL_TICKET_OVERRIDE */ 3383#ifdef SSL_OP_NO_TICKET 3384 SSL_set_tlsext_debug_callback(conn->ssl, tls_hello_ext_cb); 3385 SSL_set_tlsext_debug_arg(conn->ssl, conn); 3386#else /* SSL_OP_NO_TICKET */ 3387 if (SSL_set_hello_extension_cb(conn->ssl, tls_hello_ext_cb, 3388 conn) != 1) 3389 return -1; 3390#endif /* SSL_OP_NO_TICKET */ 3391#endif /* CONFIG_OPENSSL_TICKET_OVERRIDE */ 3392 } else { 3393 if (SSL_set_session_secret_cb(conn->ssl, NULL, NULL) != 1) 3394 return -1; 3395#ifdef CONFIG_OPENSSL_TICKET_OVERRIDE 3396 SSL_set_session_ticket_ext_cb(conn->ssl, NULL, NULL); 3397#else /* CONFIG_OPENSSL_TICKET_OVERRIDE */ 3398#ifdef SSL_OP_NO_TICKET 3399 SSL_set_tlsext_debug_callback(conn->ssl, NULL); 3400 SSL_set_tlsext_debug_arg(conn->ssl, conn); 3401#else /* SSL_OP_NO_TICKET */ 3402 if (SSL_set_hello_extension_cb(conn->ssl, NULL, NULL) != 1) 3403 return -1; 3404#endif /* SSL_OP_NO_TICKET */ 3405#endif /* CONFIG_OPENSSL_TICKET_OVERRIDE */ 3406 } 3407 3408 return 0; 3409#else /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */ 3410 return -1; 3411#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */ 3412} 3413