aboutsummaryrefslogtreecommitdiff
path: root/tls_openssl.c
diff options
context:
space:
mode:
authorChia-chi Yeh <chiachi@android.com>2009-10-02 00:40:48 +0800
committerChia-chi Yeh <chiachi@android.com>2009-10-02 00:40:48 +0800
commit3630a058cb0c57d0f6da9568098471163535d4cf (patch)
treeaec1230821eaa45a4055d87c8fc384992ed0ff30 /tls_openssl.c
parent4866d77cee4db6487f8df017059c74df93b2568a (diff)
downloadwpa_supplicant-3630a058cb0c57d0f6da9568098471163535d4cf.tar.gz
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.
Diffstat (limited to 'tls_openssl.c')
-rw-r--r--tls_openssl.c114
1 files changed, 79 insertions, 35 deletions
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 <openssl/pem.h>
+#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,