Cumulative patch from commit c06c9099f0d0827feae5622097bd8ac946eca5ea
c06c909 Use stronger PRNG for MS-MPPE-Send/Recv-Key salt
9e1f1bd eloop: Clean up coding style for eloop debug prints
f9982b3 Implement kqueue(2) support via CONFIG_ELOOP_KQUEUE
2e69bdd eloop: Add eloop_sock_requeue()
70f4f05 wpa_ctrl: Retry select() on EINTR
df9e2c2 D-Bus: Don't do <deny send_interface="..." /> in dbus service file
9684c75 mesh: Fix peer link counting when a mesh peer reconnects
83fe38b P2P: Fall back to no VHT when starting AP/P2P GO
360a9d5 P2P: Reduce off channel wait time for some P2P Action frames
1fc63fe RADIUS: Share a single function for generating session IDs
2cbc6ff RADIUS: Redesign Request Authenticator generation
b71a64a Send an Acct-Multi-Session-Id attribute in Access-Request packets
4260e1a Add Acct-Session-Id to Accounting-On/Off
d72a005 RADIUS: Use more likely unique accounting Acct-{,Multi-}Session-Id
d689317 EAPOL auth: Move radius_cui/identity freeing to eapol_auth_free()
0ae86f9 wpa_supplicant: Fix couple of C++ compiler errors with header files
9b6177a Add Event-Timestamp to all Accounting-Request packets
d179089 GAS: Calculate response buffer length of ANQP elements
dda091c OpenSSL: Fix server side PKCS#12 processing with extra certificates
443c8e1 OpenSSL: Fix possible null pointer dereference on an OCSP error path
a3cc64f Remove -w support from wpa_supplicant README
e265838 EAP-FAST: Fix an error path in PAC binary format parsing
f91e11f D-Bus: Fix p2p interface capability message
479f46c Do not send Acct-Authentic in Accounting-On/Off
696544e RADIUS: Do not include Acct-Terminate-Cause in Accounting-On/Off
236053e Make fallback from HT40 to HT20 work
cb22e3b BSD: Zero ifindex on interface removal
a8ef133 Android: Support multiple CA certs when connecting to EAP network
80ce804 WNM: Workaround for broken AP operating class behavior
af06093 BSD: Disable interface on down
dc0ad60 BSD: Use correct ifindex from route messages
5f17b2c BSD: __FUNCTION__ -> __func__
2088ecb OSU: Add debug printing of more LogotypeExtn fields
0b905c8 Add the selector suite into wpa_parse_wpa_ie_rsn() "invalid group cipher"
03a72ea VHT: Add an interoperability workaround for 80+80 and 160 MHz channels
Change-Id: Ief9174bdec380e81025e1467c47bf1656eb39cd9
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c
index b16b519..e34a3d0 100644
--- a/src/crypto/tls_openssl.c
+++ b/src/crypto/tls_openssl.c
@@ -105,6 +105,66 @@
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);
+ unsigned char *decoded_alias;
+
+ if (len & 1) {
+ wpa_printf(MSG_WARNING, "Invalid hex-encoded alias: %s",
+ encoded_key_alias);
+ return rc;
+ }
+
+ decoded_alias = os_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, (const char *) decoded_alias);
+ }
+ os_free(decoded_alias);
+ }
+
+ return rc;
+}
+
#endif /* ANDROID */
static int tls_openssl_ref_count = 0;
@@ -1989,30 +2049,40 @@
}
#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]) < 0)
return -1;
+ SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb);
+ return 0;
+ }
- 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 */
+ if (ca_cert && os_strncmp("keystores://", ca_cert, 12) == 0) {
+ char *aliases = os_strdup(&ca_cert[12]);
+ const char *delim = " ";
+ int rc = 0;
+ char *savedptr;
+ char *alias;
+
+ if (!aliases)
+ return -1;
+ alias = strtok_r(aliases, delim, &savedptr);
+ for (; alias; alias = strtok_r(NULL, delim, &savedptr)) {
+ if (tls_add_ca_from_keystore_encoded(
+ ssl_ctx->cert_store, alias)) {
+ wpa_printf(MSG_WARNING,
+ "OpenSSL: %s - Failed to add ca_cert %s from keystore",
+ __func__, alias);
+ rc = -1;
+ break;
}
}
- sk_X509_INFO_pop_free(stack, X509_INFO_free);
+ os_free(aliases);
+ if (rc)
+ return rc;
+
SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb);
return 0;
}
@@ -2393,13 +2463,18 @@
if (certs) {
#if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(LIBRESSL_VERSION_NUMBER)
- SSL_clear_chain_certs(ssl);
+ if (ssl)
+ SSL_clear_chain_certs(ssl);
+ else
+ SSL_CTX_clear_chain_certs(data->ssl);
while ((cert = sk_X509_pop(certs)) != NULL) {
X509_NAME_oneline(X509_get_subject_name(cert), buf,
sizeof(buf));
wpa_printf(MSG_DEBUG, "TLS: additional certificate"
" from PKCS12: subject='%s'", buf);
- if (SSL_add1_chain_cert(ssl, cert) != 1) {
+ if ((ssl && SSL_add1_chain_cert(ssl, cert) != 1) ||
+ (!ssl && SSL_CTX_add1_chain_cert(data->ssl,
+ cert) != 1)) {
tls_show_errors(MSG_DEBUG, __func__,
"Failed to add additional certificate");
res = -1;
@@ -2411,9 +2486,16 @@
}
sk_X509_free(certs);
#ifndef OPENSSL_IS_BORINGSSL
- res = SSL_build_cert_chain(ssl,
- SSL_BUILD_CHAIN_FLAG_CHECK |
- SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR);
+ if (ssl)
+ res = SSL_build_cert_chain(
+ ssl,
+ SSL_BUILD_CHAIN_FLAG_CHECK |
+ SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR);
+ else
+ res = SSL_CTX_build_cert_chain(
+ data->ssl,
+ SSL_BUILD_CHAIN_FLAG_CHECK |
+ SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR);
if (!res) {
tls_show_errors(MSG_DEBUG, __func__,
"Failed to build certificate chain");