[PATCH] Add access to Android certificates

Dmitry Shmidt dimitrysh at google.com
Fri Feb 25 14:11:12 EST 2011


Change-Id: I42c2a9dc8ea37ba63a042f22fd4333a8b8d2d5bf
Signed-off-by: Dmitry Shmidt <dimitrysh at google.com>
---
 src/crypto/tls_openssl.c |   80 +++++++++++++++++++++++++++++++
 1 files changed, 80 insertions(+), 0 deletions(-)

diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c
index 24bf328..a916e86 100644
--- a/src/crypto/tls_openssl.c
+++ b/src/crypto/tls_openssl.c
@@ -31,6 +31,10 @@
 #include "common.h"
 #include "crypto.h"
 #include "tls.h"
+#ifdef ANDROID
+#include <openssl/pem.h>
+#include "keystore_get.h"
+#endif

 #if OPENSSL_VERSION_NUMBER >= 0x0090800fL
 #define OPENSSL_d2i_TYPE const unsigned char **
@@ -1289,6 +1293,19 @@ static int tls_load_ca_der(void *_ssl_ctx,
const char *ca_cert)
 }
 #endif /* OPENSSL_NO_STDIO */

+#ifdef ANDROID
+static BIO *BIO_from_keystore(const char *key)
+{
+	BIO *bio = NULL;
+	char value[KEYSTORE_MESSAGE_SIZE];
+	int length = keystore_get(key, strlen(key), value);
+	if (length != -1 && (bio = BIO_new(BIO_s_mem())) != NULL) {
+		BIO_write(bio, value, length);
+	}
+	return bio;
+}
+#endif
+

 static int tls_connection_ca_cert(void *_ssl_ctx, struct tls_connection *conn,
 				  const char *ca_cert, const u8 *ca_cert_blob,
@@ -1380,6 +1397,33 @@ static int tls_connection_ca_cert(void
*_ssl_ctx, struct tls_connection *conn,
 		return 0;
 	}

+#ifdef ANDROID
+	if (ca_cert && strncmp("keystore://", ca_cert, 11) == 0) {
+		BIO *bio = BIO_from_keystore(&ca_cert[11]);
+		STACK_OF(X509_INFO) *stack = NULL;
+		int i;
+		if (bio) {
+			stack = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL);
+			BIO_free(bio);
+		}
+		if (!stack) {
+			return -1;
+		}
+		for (i = 0; i < sk_X509_INFO_num(stack); ++i) {
+			X509_INFO *info = sk_X509_INFO_value(stack, i);
+			if (info->x509) {
+				X509_STORE_add_cert(ssl_ctx->cert_store, info->x509);
+			}
+			if (info->crl) {
+				X509_STORE_add_crl(ssl_ctx->cert_store, info->crl);
+			}
+		}
+		sk_X509_INFO_pop_free(stack, X509_INFO_free);
+		SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb);
+		return 0;
+	}
+#endif
+
 #ifdef CONFIG_NATIVE_WINDOWS
 	if (ca_cert && tls_cryptoapi_ca_cert(ssl_ctx, conn->ssl, ca_cert) ==
 	    0) {
@@ -1550,6 +1594,25 @@ static int tls_connection_client_cert(struct
tls_connection *conn,
 	if (client_cert == NULL)
 		return -1;

+#ifdef ANDROID
+	if (strncmp("keystore://", client_cert, 11) == 0) {
+		BIO *bio = BIO_from_keystore(&client_cert[11]);
+		X509 *x509 = NULL;
+		int ret = -1;
+		if (bio) {
+			x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
+			BIO_free(bio);
+		}
+		if (x509) {
+			if (SSL_use_certificate(conn->ssl, x509) == 1) {
+				ret = 0;
+			}
+			X509_free(x509);
+		}
+		return ret;
+	}
+#endif
+
 #ifndef OPENSSL_NO_STDIO
 	if (SSL_use_certificate_file(conn->ssl, client_cert,
 				     SSL_FILETYPE_ASN1) == 1) {
@@ -1929,6 +1992,23 @@ static int tls_connection_private_key(void *_ssl_ctx,
 		break;
 	}

+#ifdef ANDROID
+	if (!ok && private_key && strncmp("keystore://", private_key, 11) == 0) {
+		BIO *bio = BIO_from_keystore(&private_key[11]);
+		EVP_PKEY *pkey = NULL;
+		if (bio) {
+			pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
+			BIO_free(bio);
+		}
+		if (pkey) {
+			if (SSL_use_PrivateKey(conn->ssl, pkey) == 1) {
+				ok = 1;
+			}
+			EVP_PKEY_free(pkey);
+		}
+	}
+#endif
+
 	while (!ok && private_key) {
 #ifndef OPENSSL_NO_STDIO
 		if (SSL_use_PrivateKey_file(conn->ssl, private_key,
-- 
1.7.3.1


More information about the HostAP mailing list