From 3630a058cb0c57d0f6da9568098471163535d4cf Mon Sep 17 00:00:00 2001 From: Chia-chi Yeh Date: Fri, 2 Oct 2009 00:40:48 +0800 Subject: wpa_supplicant: push keystore access to tls_openssl.c. Since we support certificate chain, doing it in eap_tls_common.c becomes too complicated. To make things simpler, push the logic to tls_openssl.c and use keystore namespace instead. --- tls_openssl.c | 114 ++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 79 insertions(+), 35 deletions(-) (limited to 'tls_openssl.c') diff --git a/tls_openssl.c b/tls_openssl.c index 2bbffea..b7dd4db 100644 --- a/tls_openssl.c +++ b/tls_openssl.c @@ -37,6 +37,22 @@ #define OPENSSL_d2i_TYPE unsigned char ** #endif +#ifdef ANDROID +#include +#include "keystore_get.h" + +static BIO *BIO_from_keystore(const char *key) +{ + BIO *bio = NULL; + char value[KEYSTORE_MESSAGE_SIZE]; + int length = keystore_get(key, value); + if (length != -1 && (bio = BIO_new(BIO_s_mem())) != NULL) { + BIO_write(bio, value, length); + } + return bio; +} +#endif + static int tls_openssl_ref_count = 0; struct tls_connection { @@ -1092,35 +1108,6 @@ static int tls_load_ca_der(void *_ssl_ctx, const char *ca_cert) } #endif /* OPENSSL_NO_STDIO */ -#ifdef ANDROID -static int add_cert_chain_from_blob(X509_STORE *store, char *value, int size) -{ - int i, ret = -1; - BIO *bio = NULL; - STACK_OF(X509_INFO) *stack = NULL; - - bio = BIO_new(BIO_s_mem()); - if (bio == NULL) goto end; - BIO_write(bio, value, size); - stack = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL); - if (stack == NULL) goto end; - 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(store, info->x509); - } - if (info->crl) { - X509_STORE_add_crl(store, info->crl); - } - } - sk_X509_INFO_pop_free(stack, X509_INFO_free); - ret = 0; -end: - if (bio != NULL) BIO_free(bio); - return ret; -} -#endif - static int tls_connection_ca_cert(void *_ssl_ctx, struct tls_connection *conn, const char *ca_cert, const u8 *ca_cert_blob, size_t ca_cert_blob_len, const char *ca_path) @@ -1138,12 +1125,8 @@ static int tls_connection_ca_cert(void *_ssl_ctx, struct tls_connection *conn, "certificate store", __func__); return -1; } + if (ca_cert_blob) { -#ifdef ANDROID - return add_cert_chain_from_blob(ssl_ctx->cert_store, - (char*)ca_cert_blob, - (int)ca_cert_blob_len); -#else X509 *cert = d2i_X509(NULL, (OPENSSL_d2i_TYPE) &ca_cert_blob, ca_cert_blob_len); if (cert == NULL) { @@ -1173,9 +1156,34 @@ static int tls_connection_ca_cert(void *_ssl_ctx, struct tls_connection *conn, "to certificate store", __func__); SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb); return 0; -#endif } +#ifdef ANDROID + if (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) == @@ -1332,6 +1340,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) { @@ -1621,6 +1648,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, -- cgit v1.2.3