diff options
| author | Dmitry Shmidt <dimitrysh@google.com> | 2013-10-22 13:52:46 -0700 |
|---|---|---|
| committer | Dmitry Shmidt <dimitrysh@google.com> | 2013-10-22 13:52:46 -0700 |
| commit | 051af73b8f8014eff33330aead0f36944b3403e6 (patch) | |
| tree | 8e1d198bba44a3f1037eb4e58c81d75a66f0711e /src/crypto | |
| parent | 3b7e16d414e38c8856c4712f3a0768c89689cbc3 (diff) | |
| download | android_external_wpa_supplicant_8-051af73b8f8014eff33330aead0f36944b3403e6.tar.gz android_external_wpa_supplicant_8-051af73b8f8014eff33330aead0f36944b3403e6.tar.bz2 android_external_wpa_supplicant_8-051af73b8f8014eff33330aead0f36944b3403e6.zip | |
Cumulative patch from commit 538922a628d4f5403b9a96b171a59235bcb3d921
538922a dbus: Add boolean AllowRoam option to Scan() method options dictionary
c6f5dec Don't start second scan when changing scan interval
cd3b070 nl80211: Fix DFS radar event parsing
2b72df6 nl80211: Free BSS structure even if netdev does not exists
41cc50d nl80211: Update send_action_cookie on AP-offchannel-TX path
313424d GAS: Add support for multiple pending queries for the same destination
cbc5484 GAS: Do not start new scan operation during an ongoing GAS query
c377514 GAS: Delay GAS query Tx while scanning/connecting
24c694b GAS: Delay GAS query Tx while another query is in progress
7255983 WPS: Clear after_wps from number of new locations
73b54d6 P2P: Fix Operating Channel in Invitation Request for operating group
dc46fd6 P2P: Cancel offchannel TX wait on Invitation Response RX
0c92963 D-Bus: Clean up debug print for P2P invitation result
8d82c21 P2P: Fix PD retry channel on join-a-group case
d285888 P2P: Add GO BSS entry details to debug log on join-a-group
512629a P2P: Accept Invitation Response non-success without Channel List
e241b1b eap_proxy: Fix IMSI fetch for home vs. visited network determination
db13605 EAP-AKA/AKA' peer: Allow external USIM processing to be used
569ccf7 EAP-SIM peer: Allow external SIM processing to be used
84dc137 hlr_auc_gw: Add GSM-AUTH-REQ command
a5d44ac EAP peer: Add framework for external SIM/USIM processing
7e8bc7d eapol_test: Initialize BSS lists
bceb843 Send CTRL-RSP command response before processing EAPOL update
b607796 eapol_test: Fix external EAP request mechanism
94de082 eapol_test: Initialize wpa_s->global to fix ctrl_iface
f07bba3 Android: Add dfs.c into build
0cf0af2 WNM: Set Disassoc Imminent flag in ESS Disassoc Imminent frame
f47c145 Interworking: Add required_roaming_consortium parameter for credentials
a83e574 GAS: Update timeout from TX status handler
e88060e HTTP server: Allow TCP socket to be reused
9bc3386 Add test option for specifying hardcoded BSS Load element
9c7e43a Define BSS Load element id
56f5af4 Interworking: Add support for QoS Mapping functionality for the STA
850e1c2 atheros: Add support for QoS Mapping configuration
c551700 Interworking: Add support for QoS Mapping functionality for the AP
ac1bc54 Interworking: Add domain_suffix_match for credentials
463c8ff Interworking: Add support for multiple home FQDNs
01f809c Add AAA server domain name suffix matching constraint
be7963b OpenSSL: Fix code indentation in OCSP processing
899cc14 hostapd: Add support for DFS with 160 MHz channel width
6de0e0c Mark DFS functions static and rename them
58b73e3 hostapd: DFS with 40/80 MHz channel width support
846de15 DFS: Add more parameters to radar events
04e8003 nl80211: Use struct hostapd_freq_params with start_dfs_cac
72c753d hostapd: Split hostapd_set_freq to helper function
e76da50 hostapd: Add AP DFS support
Change-Id: Ie9ed4662ba6d81e6d8b14bccb29ffa192becf0f2
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
Diffstat (limited to 'src/crypto')
| -rw-r--r-- | src/crypto/tls.h | 6 | ||||
| -rw-r--r-- | src/crypto/tls_openssl.c | 121 |
2 files changed, 121 insertions, 6 deletions
diff --git a/src/crypto/tls.h b/src/crypto/tls.h index 2fdaa026..feba13ff 100644 --- a/src/crypto/tls.h +++ b/src/crypto/tls.h @@ -40,7 +40,8 @@ enum tls_fail_reason { TLS_FAIL_SUBJECT_MISMATCH = 5, TLS_FAIL_ALTSUBJECT_MISMATCH = 6, TLS_FAIL_BAD_CERTIFICATE = 7, - TLS_FAIL_SERVER_CHAIN_PROBE = 8 + TLS_FAIL_SERVER_CHAIN_PROBE = 8, + TLS_FAIL_DOMAIN_SUFFIX_MISMATCH = 9 }; union tls_event_data { @@ -96,6 +97,8 @@ struct tls_config { * %NULL to allow all subjects * @altsubject_match: String to match in the alternative subject of the peer * certificate or %NULL to allow all alternative subjects + * @suffix_match: String to suffix match in the dNSName or CN of the peer + * certificate or %NULL to allow all domain names * @client_cert: File or reference name for client X.509 certificate in PEM or * DER format * @client_cert_blob: client_cert as inlined data or %NULL if not used @@ -137,6 +140,7 @@ struct tls_connection_params { const char *ca_path; const char *subject_match; const char *altsubject_match; + const char *suffix_match; const char *client_cert; const u8 *client_cert_blob; size_t client_cert_blob_len; diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c index 18e0e789..48c48760 100644 --- a/src/crypto/tls_openssl.c +++ b/src/crypto/tls_openssl.c @@ -93,7 +93,7 @@ struct tls_connection { ENGINE *engine; /* functional reference to the engine */ EVP_PKEY *private_key; /* the private key if using engine */ #endif /* OPENSSL_NO_ENGINE */ - char *subject_match, *altsubject_match; + char *subject_match, *altsubject_match, *suffix_match; int read_alerts, write_alerts, failed; tls_session_ticket_cb session_ticket_cb; @@ -1049,6 +1049,7 @@ void tls_connection_deinit(void *ssl_ctx, struct tls_connection *conn) tls_engine_deinit(conn); os_free(conn->subject_match); os_free(conn->altsubject_match); + os_free(conn->suffix_match); os_free(conn->session_ticket); os_free(conn); } @@ -1139,6 +1140,97 @@ static int tls_match_altsubject(X509 *cert, const char *match) } +static int domain_suffix_match(const u8 *val, size_t len, const char *match) +{ + size_t i, match_len; + + /* Check for embedded nuls that could mess up suffix matching */ + for (i = 0; i < len; i++) { + if (val[i] == '\0') { + wpa_printf(MSG_DEBUG, "TLS: Embedded null in a string - reject"); + return 0; + } + } + + match_len = os_strlen(match); + if (match_len > len) + return 0; + + if (os_strncasecmp((const char *) val + len - match_len, match, + match_len) != 0) + return 0; /* no match */ + + if (match_len == len) + return 1; /* exact match */ + + if (val[len - match_len - 1] == '.') + return 1; /* full label match completes suffix match */ + + wpa_printf(MSG_DEBUG, "TLS: Reject due to incomplete label match"); + return 0; +} + + +static int tls_match_suffix(X509 *cert, const char *match) +{ + GENERAL_NAME *gen; + void *ext; + int i; + int dns_name = 0; + X509_NAME *name; + + wpa_printf(MSG_DEBUG, "TLS: Match domain against suffix %s", match); + + ext = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL); + + for (i = 0; ext && i < sk_GENERAL_NAME_num(ext); i++) { + gen = sk_GENERAL_NAME_value(ext, i); + if (gen->type != GEN_DNS) + continue; + dns_name++; + wpa_hexdump_ascii(MSG_DEBUG, "TLS: Certificate dNSName", + gen->d.dNSName->data, + gen->d.dNSName->length); + if (domain_suffix_match(gen->d.dNSName->data, + gen->d.dNSName->length, match) == 1) { + wpa_printf(MSG_DEBUG, "TLS: Suffix match in dNSName found"); + return 1; + } + } + + if (dns_name) { + wpa_printf(MSG_DEBUG, "TLS: None of the dNSName(s) matched"); + return 0; + } + + name = X509_get_subject_name(cert); + i = -1; + for (;;) { + X509_NAME_ENTRY *e; + ASN1_STRING *cn; + + i = X509_NAME_get_index_by_NID(name, NID_commonName, i); + if (i == -1) + break; + e = X509_NAME_get_entry(name, i); + if (e == NULL) + continue; + cn = X509_NAME_ENTRY_get_data(e); + if (cn == NULL) + continue; + wpa_hexdump_ascii(MSG_DEBUG, "TLS: Certificate commonName", + cn->data, cn->length); + if (domain_suffix_match(cn->data, cn->length, match) == 1) { + wpa_printf(MSG_DEBUG, "TLS: Suffix match in commonName found"); + return 1; + } + } + + wpa_printf(MSG_DEBUG, "TLS: No CommonName suffix match found"); + return 0; +} + + static enum tls_fail_reason openssl_tls_fail_reason(int err) { switch (err) { @@ -1267,7 +1359,7 @@ static int tls_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx) SSL *ssl; struct tls_connection *conn; struct tls_context *context; - char *match, *altmatch; + char *match, *altmatch, *suffix_match; const char *err_str; err_cert = X509_STORE_CTX_get_current_cert(x509_ctx); @@ -1289,6 +1381,7 @@ static int tls_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx) context = conn->context; match = conn->subject_match; altmatch = conn->altsubject_match; + suffix_match = conn->suffix_match; if (!preverify_ok && !conn->ca_cert_verify) preverify_ok = 1; @@ -1357,6 +1450,14 @@ static int tls_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx) openssl_tls_fail_event(conn, err_cert, err, depth, buf, "AltSubject mismatch", TLS_FAIL_ALTSUBJECT_MISMATCH); + } else if (depth == 0 && suffix_match && + !tls_match_suffix(err_cert, suffix_match)) { + wpa_printf(MSG_WARNING, "TLS: Domain suffix match '%s' not found", + suffix_match); + preverify_ok = 0; + openssl_tls_fail_event(conn, err_cert, err, depth, buf, + "Domain suffix mismatch", + TLS_FAIL_DOMAIN_SUFFIX_MISMATCH); } else openssl_tls_cert_event(conn, err_cert, depth, buf); @@ -1619,7 +1720,8 @@ int tls_global_set_verify(void *ssl_ctx, int check_crl) static int tls_connection_set_subject_match(struct tls_connection *conn, const char *subject_match, - const char *altsubject_match) + const char *altsubject_match, + const char *suffix_match) { os_free(conn->subject_match); conn->subject_match = NULL; @@ -1637,6 +1739,14 @@ static int tls_connection_set_subject_match(struct tls_connection *conn, return -1; } + os_free(conn->suffix_match); + conn->suffix_match = NULL; + if (suffix_match) { + conn->suffix_match = os_strdup(suffix_match); + if (conn->suffix_match == NULL) + return -1; + } + return 0; } @@ -2909,7 +3019,7 @@ static int ocsp_resp_cb(SSL *s, void *arg) wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status unknown, but OCSP required"); return 0; } - wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status unknown, but OCSP was not required, so allow connection to continue"); + wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status unknown, but OCSP was not required, so allow connection to continue"); return 1; } @@ -2974,7 +3084,8 @@ int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn, } if (tls_connection_set_subject_match(conn, params->subject_match, - params->altsubject_match)) + params->altsubject_match, + params->suffix_match)) return -1; if (params->engine && params->ca_cert_id) { |
