wpa_supplicant_8: fix keystore-backed keys
The switch to BoringSSL broke keystore backed keys because I didn't
realise that wpa_supplicant was using the dynamic ENGINE loading to load
the keystore module.
The ENGINE-like functionality in BoringSSL is much simplier and this
change should enable it. However, I don't have a suitable AP to test
against.
BUG=20460625
Change-Id: I798deb29264484788c6222385bcc104a34245e2b
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c
index d3e9eb9..cbd35c4 100644
--- a/src/crypto/tls_openssl.c
+++ b/src/crypto/tls_openssl.c
@@ -68,6 +68,7 @@
free(value);
return bio;
}
+
#endif /* ANDROID */
static int tls_openssl_ref_count = 0;
@@ -88,7 +89,7 @@
SSL_CTX *ssl_ctx;
SSL *ssl;
BIO *ssl_in, *ssl_out;
-#ifndef OPENSSL_NO_ENGINE
+#if defined(ANDROID) || !defined(OPENSSL_NO_ENGINE)
ENGINE *engine; /* functional reference to the engine */
EVP_PKEY *private_key; /* the private key if using engine */
#endif /* OPENSSL_NO_ENGINE */
@@ -884,11 +885,31 @@
}
}
+#ifdef ANDROID
+/* EVP_PKEY_from_keystore comes from system/security/keystore-engine. */
+EVP_PKEY* EVP_PKEY_from_keystore(const char* key_id);
+#endif
static int tls_engine_init(struct tls_connection *conn, const char *engine_id,
const char *pin, const char *key_id,
const char *cert_id, const char *ca_cert_id)
{
+#if defined(ANDROID) && defined(OPENSSL_IS_BORINGSSL)
+#if !defined(OPENSSL_NO_ENGINE)
+#error "This code depends on OPENSSL_NO_ENGINE being defined by BoringSSL."
+#endif
+
+ conn->engine = NULL;
+ conn->private_key = EVP_PKEY_from_keystore(key_id);
+ if (!conn->private_key) {
+ wpa_printf(MSG_ERROR,
+ "ENGINE: cannot load private key with id '%s' [%s]",
+ key_id,
+ ERR_error_string(ERR_get_error(), NULL));
+ return TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED;
+ }
+#endif
+
#ifndef OPENSSL_NO_ENGINE
int ret = -1;
if (engine_id == NULL) {
@@ -981,14 +1002,16 @@
static void tls_engine_deinit(struct tls_connection *conn)
{
-#ifndef OPENSSL_NO_ENGINE
+#if defined(ANDROID) || !defined(OPENSSL_NO_ENGINE)
wpa_printf(MSG_DEBUG, "ENGINE: engine deinit");
if (conn->private_key) {
EVP_PKEY_free(conn->private_key);
conn->private_key = NULL;
}
if (conn->engine) {
+#if !defined(OPENSSL_IS_BORINGSSL)
ENGINE_finish(conn->engine);
+#endif
conn->engine = NULL;
}
#endif /* OPENSSL_NO_ENGINE */
@@ -2278,7 +2301,7 @@
static int tls_connection_engine_private_key(struct tls_connection *conn)
{
-#ifndef OPENSSL_NO_ENGINE
+#if defined(ANDROID) || !defined(OPENSSL_NO_ENGINE)
if (SSL_use_PrivateKey(conn->ssl, conn->private_key) != 1) {
tls_show_errors(MSG_ERROR, __func__,
"ENGINE: cannot use private key for TLS");
diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk
index 657784b..847c590 100644
--- a/wpa_supplicant/Android.mk
+++ b/wpa_supplicant/Android.mk
@@ -1565,6 +1565,13 @@
ifeq ($(CONFIG_TLS), openssl)
LOCAL_SHARED_LIBRARIES += libcrypto libssl libkeystore_binder
endif
+
+# With BoringSSL we need libkeystore-engine in order to provide access to
+# keystore keys.
+ifneq (,$(wildcard external/boringssl/flavor.mk))
+LOCAL_SHARED_LIBRARIES += libkeystore-engine
+endif
+
ifdef CONFIG_DRIVER_NL80211
ifneq ($(wildcard external/libnl),)
LOCAL_SHARED_LIBRARIES += libnl