aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/wpa_ctrl.h2
-rw-r--r--src/crypto/tls.h5
-rw-r--r--src/crypto/tls_openssl.c49
-rw-r--r--src/eap_peer/eap.c2
-rw-r--r--src/eap_peer/eap.h3
-rw-r--r--src/eapol_supp/eapol_supp_sm.c7
-rw-r--r--src/eapol_supp/eapol_supp_sm.h3
7 files changed, 68 insertions, 3 deletions
diff --git a/src/common/wpa_ctrl.h b/src/common/wpa_ctrl.h
index 82fad4b..bc5dd7c 100644
--- a/src/common/wpa_ctrl.h
+++ b/src/common/wpa_ctrl.h
@@ -42,6 +42,8 @@ extern "C" {
#define WPA_EVENT_EAP_METHOD "CTRL-EVENT-EAP-METHOD "
/** EAP peer certificate from TLS */
#define WPA_EVENT_EAP_PEER_CERT "CTRL-EVENT-EAP-PEER-CERT "
+/** EAP peer certificate alternative subject name component from TLS */
+#define WPA_EVENT_EAP_PEER_ALT "CTRL-EVENT-EAP-PEER-ALT "
/** EAP TLS certificate chain validation error */
#define WPA_EVENT_EAP_TLS_CERT_ERROR "CTRL-EVENT-EAP-TLS-CERT-ERROR "
/** EAP status */
diff --git a/src/crypto/tls.h b/src/crypto/tls.h
index a4f954c..202ada8 100644
--- a/src/crypto/tls.h
+++ b/src/crypto/tls.h
@@ -44,6 +44,9 @@ enum tls_fail_reason {
TLS_FAIL_DOMAIN_SUFFIX_MISMATCH = 9
};
+
+#define TLS_MAX_ALT_SUBJECT 10
+
union tls_event_data {
struct {
int depth;
@@ -59,6 +62,8 @@ union tls_event_data {
const struct wpabuf *cert;
const u8 *hash;
size_t hash_len;
+ const char *altsubject[TLS_MAX_ALT_SUBJECT];
+ int num_altsubject;
} peer_cert;
struct {
diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c
index 5433ebb..e52fd39 100644
--- a/src/crypto/tls_openssl.c
+++ b/src/crypto/tls_openssl.c
@@ -1377,6 +1377,11 @@ static void openssl_tls_cert_event(struct tls_connection *conn,
struct wpabuf *cert = NULL;
union tls_event_data ev;
struct tls_context *context = conn->context;
+ char *altsubject[TLS_MAX_ALT_SUBJECT];
+ int alt, num_altsubject = 0;
+ GENERAL_NAME *gen;
+ void *ext;
+ stack_index_t i;
#ifdef CONFIG_SHA256
u8 hash[32];
#endif /* CONFIG_SHA256 */
@@ -1403,8 +1408,52 @@ static void openssl_tls_cert_event(struct tls_connection *conn,
#endif /* CONFIG_SHA256 */
ev.peer_cert.depth = depth;
ev.peer_cert.subject = subject;
+
+ ext = X509_get_ext_d2i(err_cert, NID_subject_alt_name, NULL, NULL);
+ for (i = 0; ext && i < sk_GENERAL_NAME_num(ext); i++) {
+ char *pos;
+
+ if (num_altsubject == TLS_MAX_ALT_SUBJECT)
+ break;
+ gen = sk_GENERAL_NAME_value(ext, i);
+ if (gen->type != GEN_EMAIL &&
+ gen->type != GEN_DNS &&
+ gen->type != GEN_URI)
+ continue;
+
+ pos = os_malloc(10 + gen->d.ia5->length + 1);
+ if (pos == NULL)
+ break;
+ altsubject[num_altsubject++] = pos;
+
+ switch (gen->type) {
+ case GEN_EMAIL:
+ os_memcpy(pos, "EMAIL:", 6);
+ pos += 6;
+ break;
+ case GEN_DNS:
+ os_memcpy(pos, "DNS:", 4);
+ pos += 4;
+ break;
+ case GEN_URI:
+ os_memcpy(pos, "URI:", 4);
+ pos += 4;
+ break;
+ }
+
+ os_memcpy(pos, gen->d.ia5->data, gen->d.ia5->length);
+ pos += gen->d.ia5->length;
+ *pos = '\0';
+ }
+
+ for (alt = 0; alt < num_altsubject; alt++)
+ ev.peer_cert.altsubject[alt] = altsubject[alt];
+ ev.peer_cert.num_altsubject = num_altsubject;
+
context->event_cb(context->cb_ctx, TLS_PEER_CERTIFICATE, &ev);
wpabuf_free(cert);
+ for (alt = 0; alt < num_altsubject; alt++)
+ os_free(altsubject[alt]);
}
diff --git a/src/eap_peer/eap.c b/src/eap_peer/eap.c
index 31c1a29..62cd4a1 100644
--- a/src/eap_peer/eap.c
+++ b/src/eap_peer/eap.c
@@ -1858,6 +1858,8 @@ static void eap_peer_sm_tls_event(void *ctx, enum tls_event ev,
sm->eapol_cb->notify_cert(sm->eapol_ctx,
data->peer_cert.depth,
data->peer_cert.subject,
+ data->peer_cert.altsubject,
+ data->peer_cert.num_altsubject,
hash_hex, data->peer_cert.cert);
break;
case TLS_ALERT:
diff --git a/src/eap_peer/eap.h b/src/eap_peer/eap.h
index bc207e7..8c4a42f 100644
--- a/src/eap_peer/eap.h
+++ b/src/eap_peer/eap.h
@@ -228,10 +228,13 @@ struct eapol_callbacks {
* @ctx: eapol_ctx from eap_peer_sm_init() call
* @depth: Depth in certificate chain (0 = server)
* @subject: Subject of the peer certificate
+ * @altsubject: Select fields from AltSubject of the peer certificate
+ * @num_altsubject: Number of altsubject values
* @cert_hash: SHA-256 hash of the certificate
* @cert: Peer certificate
*/
void (*notify_cert)(void *ctx, int depth, const char *subject,
+ const char *altsubject[], int num_altsubject,
const char *cert_hash, const struct wpabuf *cert);
/**
diff --git a/src/eapol_supp/eapol_supp_sm.c b/src/eapol_supp/eapol_supp_sm.c
index 941a269..621318e 100644
--- a/src/eapol_supp/eapol_supp_sm.c
+++ b/src/eapol_supp/eapol_supp_sm.c
@@ -1962,13 +1962,14 @@ static void eapol_sm_eap_param_needed(void *ctx, enum wpa_ctrl_req_type field,
#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
static void eapol_sm_notify_cert(void *ctx, int depth, const char *subject,
- const char *cert_hash,
+ const char *altsubject[],
+ int num_altsubject, const char *cert_hash,
const struct wpabuf *cert)
{
struct eapol_sm *sm = ctx;
if (sm->ctx->cert_cb)
- sm->ctx->cert_cb(sm->ctx->ctx, depth, subject,
- cert_hash, cert);
+ sm->ctx->cert_cb(sm->ctx->ctx, depth, subject, altsubject,
+ num_altsubject, cert_hash, cert);
}
diff --git a/src/eapol_supp/eapol_supp_sm.h b/src/eapol_supp/eapol_supp_sm.h
index e089e88..d8ae9d4 100644
--- a/src/eapol_supp/eapol_supp_sm.h
+++ b/src/eapol_supp/eapol_supp_sm.h
@@ -248,10 +248,13 @@ struct eapol_ctx {
* @ctx: Callback context (ctx)
* @depth: Depth in certificate chain (0 = server)
* @subject: Subject of the peer certificate
+ * @altsubject: Select fields from AltSubject of the peer certificate
+ * @num_altsubject: Number of altsubject values
* @cert_hash: SHA-256 hash of the certificate
* @cert: Peer certificate
*/
void (*cert_cb)(void *ctx, int depth, const char *subject,
+ const char *altsubject[], int num_altsubject,
const char *cert_hash, const struct wpabuf *cert);
/**