[PATCH] Android: Support multiple CA certs when connecting to EAP network
Rubin Xu
rubinxu at google.com
Tue Jan 26 13:03:54 PST 2016
From dd90559fa3bfa3d606b51f97a66afff2ab4758d2 Mon Sep 17 00:00:00 2001
From: Rubin Xu <rubinxu at google.com>
Date: Tue, 10 Nov 2015 17:14:51 +0000
Subject: [PATCH] Android: Support multiple CA certs when connecting to EAP
network
In the Android-specific case, Make ca_cert directive parse a space-separated
list of hex-encoded CA certificate aliases following the "keystores://"
prefix.
Server certificate validation should succeed as long as the chain ends with
one of them.
Bug: 22547958
Change-Id: I9c98f06f8ddf94ea1332f7ac291a14b7f1d96406
Signed-off-by: Rubin Xu <rubinxu at google.com>
---
src/crypto/tls_openssl.c | 98
+++++++++++++++++++++++++++++++++++++-----------
1 file changed, 76 insertions(+), 22 deletions(-)
diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c
index b16b519..087210d 100644
--- a/src/crypto/tls_openssl.c
+++ b/src/crypto/tls_openssl.c
@@ -105,6 +105,56 @@ static BIO * BIO_from_keystore(const char *key)
free(value);
return bio;
}
+
+static int tls_add_ca_from_keystore(X509_STORE *ctx, const char *key_alias)
+{
+ BIO *bio = BIO_from_keystore(key_alias);
+ STACK_OF(X509_INFO) *stack = NULL;
+ stack_index_t i;
+
+ if (bio) {
+ stack = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL);
+ BIO_free(bio);
+ }
+ if (!stack) {
+ wpa_printf(MSG_WARNING, "TLS: failed to parse certificate: %s",
key_alias);
+ 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(ctx,
+ info->x509);
+ }
+ if (info->crl) {
+ X509_STORE_add_crl(ctx,
+ info->crl);
+ }
+ }
+ sk_X509_INFO_pop_free(stack, X509_INFO_free);
+ return 0;
+}
+
+static int tls_add_ca_from_keystore_encoded(X509_STORE *ctx, const char
*encoded_key_alias)
+{
+ int rc = -1;
+ int len = os_strlen(encoded_key_alias);
+ if (len & 1) {
+ // Hex-encoded string should have an even number of characters.
+ wpa_printf(MSG_WARNING, "Invalid hex-encoded alias: %s",
encoded_key_alias);
+ return rc;
+ }
+ unsigned char* decoded_alias = malloc(len / 2 + 1);
+ if (decoded_alias) {
+ if (!hexstr2bin(encoded_key_alias, decoded_alias, len / 2)) {
+ decoded_alias[len / 2] = '\0';
+ rc = tls_add_ca_from_keystore(ctx, (char*) decoded_alias);
+ }
+ free(decoded_alias);
+ }
+ return rc;
+}
#endif /* ANDROID */
static int tls_openssl_ref_count = 0;
@@ -1989,32 +2039,36 @@ static int tls_connection_ca_cert(struct
tls_data *data,
}
#ifdef ANDROID
+ /* Single alias */
if (ca_cert && os_strncmp("keystore://", ca_cert, 11) == 0) {
- BIO *bio = BIO_from_keystore(&ca_cert[11]);
- STACK_OF(X509_INFO) *stack = NULL;
- stack_index_t i;
-
- if (bio) {
- stack = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL);
- BIO_free(bio);
- }
- if (!stack)
+ if (!tls_add_ca_from_keystore(ssl_ctx->cert_store, &ca_cert[11])) {
+ SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb);
+ return 0;
+ } else {
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);
+ }
+ /* Multiple aliases separated by space */
+ } else if (ca_cert && os_strncmp("keystores://", ca_cert, 12) == 0) {
+ char *aliases = strdup(&ca_cert[12]);
+ const char *DELIMITER = " ";
+ int rc = 0;
+ char *savedptr;
+ char *alias = strtok_r(aliases, DELIMITER, &savedptr);
+ for(; alias; alias = strtok_r(NULL, DELIMITER, &savedptr)) {
+ if (tls_add_ca_from_keystore_encoded(ssl_ctx->cert_store, alias)) {
+ wpa_printf(MSG_WARNING, "OpenSSL: %s - fail to add ca_cert"
+ " %s from keystore", __func__, alias);
+ rc = -1;
+ break;
}
}
- sk_X509_INFO_pop_free(stack, X509_INFO_free);
- SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb);
- return 0;
+ free(aliases);
+ if (!rc) {
+ SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb);
+ return 0;
+ } else {
+ return -1;
+ }
}
#endif /* ANDROID */
--
2.7.0.rc3.207.g0ac5344
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Android-Support-multiple-CA-certs-when-connecting-to.patch
Type: text/x-patch
Size: 4154 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/hostap/attachments/20160126/4f732c7a/attachment.bin>
More information about the Hostap
mailing list