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, &params, 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