Replace call into Wifi Keystore with a
call into the new get_certificate method.

Bug: 205764502
Test: Manual test - connect to a WPA Enterprise network.
      Tests that KS2 path is still working.

      Manual test - store a key-value pair to
      legacy Keystore. Check that we can retrieve
      the value in supplicant. Tests the legacy
      keystore path.

      Manual test - try to retrieve a non-existing
      value from legacy keystore. Check that the
      get_certificate method returns -1

Change-Id: I5b595b6592ca9298a2cb667bc38edd4bd2d1e8e6
diff --git a/src/crypto/tls.h b/src/crypto/tls.h
index 7a2ee32..e215762 100644
--- a/src/crypto/tls.h
+++ b/src/crypto/tls.h
@@ -682,4 +682,13 @@
  */
 bool tls_connection_get_own_cert_used(struct tls_connection *conn);
 
+/**
+ * tls_register_cert_callback - Register a callback to retrieve certificates
+ * @cb: Callback object to register
+ */
+typedef ssize_t (*tls_get_certificate_cb)
+(void* ctx, const char* alias, uint8_t** value);
+
+void tls_register_cert_callback(tls_get_certificate_cb cb);
+
 #endif /* TLS_H */
diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c
index dc8a1b4..ab82e3d 100644
--- a/src/crypto/tls_openssl.c
+++ b/src/crypto/tls_openssl.c
@@ -126,9 +126,28 @@
 }
 #endif
 
+static int tls_openssl_ref_count = 0;
+static int tls_ex_idx_session = -1;
+
+struct tls_session_data {
+	struct dl_list list;
+	struct wpabuf *buf;
+};
+
+struct tls_context {
+	void (*event_cb)(void *ctx, enum tls_event ev,
+			 union tls_event_data *data);
+	void *cb_ctx;
+	int cert_in_cb;
+	char *ocsp_stapling_response;
+	struct dl_list sessions; /* struct tls_session_data */
+};
+
+static struct tls_context *tls_global = NULL;
+static tls_get_certificate_cb certificate_callback_global = NULL;
+
 #ifdef ANDROID
 #include <openssl/pem.h>
-#include <keystore/keystore_get.h>
 
 #include <log/log.h>
 #include <log/log_event_list.h>
@@ -152,9 +171,11 @@
 {
 	BIO *bio = NULL;
 	uint8_t *value = NULL;
-	int length = keystore_get(alias, strlen(alias), &value);
-	if (length != -1 && (bio = BIO_new(BIO_s_mem())) != NULL)
-		BIO_write(bio, value, length);
+	if (tls_global != NULL && certificate_callback_global != NULL) {
+		int length = (*certificate_callback_global)(tls_global->cb_ctx, alias, &value);
+		if (length != -1 && (bio = BIO_new(BIO_s_mem())) != NULL)
+			BIO_write(bio, value, length);
+	}
 	free(value);
 	return bio;
 }
@@ -229,26 +250,6 @@
 
 #endif /* ANDROID */
 
-static int tls_openssl_ref_count = 0;
-static int tls_ex_idx_session = -1;
-
-struct tls_session_data {
-	struct dl_list list;
-	struct wpabuf *buf;
-};
-
-struct tls_context {
-	void (*event_cb)(void *ctx, enum tls_event ev,
-			 union tls_event_data *data);
-	void *cb_ctx;
-	int cert_in_cb;
-	char *ocsp_stapling_response;
-	struct dl_list sessions; /* struct tls_session_data */
-};
-
-static struct tls_context *tls_global = NULL;
-
-
 struct tls_data {
 	SSL_CTX *ssl;
 	unsigned int tls_session_lifetime;
@@ -6025,3 +6026,8 @@
 		return SSL_get_certificate(conn->ssl) != NULL;
 	return false;
 }
+
+void tls_register_cert_callback(tls_get_certificate_cb cb)
+{
+	certificate_callback_global = cb;
+}
diff --git a/src/eap_peer/eap.c b/src/eap_peer/eap.c
index a7dee37..15664df 100644
--- a/src/eap_peer/eap.c
+++ b/src/eap_peer/eap.c
@@ -2196,6 +2196,14 @@
 	os_free(hash_hex);
 }
 
+ssize_t tls_certificate_callback(void* ctx, const char* alias, uint8_t** value) {
+	if (alias == NULL || ctx == NULL || value == NULL) return -1;
+	struct eap_sm *sm = (struct eap_sm*) ctx;
+	if (sm->eapol_cb && sm->eapol_cb->get_certificate) {
+		return sm->eapol_cb->get_certificate(sm->eapol_ctx, alias, value);
+	}
+	return -1;
+}
 
 /**
  * eap_peer_sm_init - Allocate and initialize EAP peer state machine
@@ -2239,6 +2247,7 @@
 	tlsconf.event_cb = eap_peer_sm_tls_event;
 	tlsconf.cb_ctx = sm;
 	tlsconf.cert_in_cb = conf->cert_in_cb;
+	tls_register_cert_callback(&tls_certificate_callback);
 	sm->ssl_ctx = tls_init(&tlsconf);
 	if (sm->ssl_ctx == NULL) {
 		wpa_printf(MSG_WARNING, "SSL: Failed to initialize TLS "