Hi, so far, even if we look for our own cert, we only match the id against the first subjectAltName. This means we cannot use certificates where we actually need a different one. This diff changes the behaviour so that we check all subjectAltNames of a given certificate.
ok? Patrick diff --git a/sbin/iked/ca.c b/sbin/iked/ca.c index a8034411e77..543bd0b8725 100644 --- a/sbin/iked/ca.c +++ b/sbin/iked/ca.c @@ -65,7 +65,7 @@ int ca_privkey_to_method(struct iked_id *); struct ibuf * ca_x509_serialize(X509 *); int ca_x509_subjectaltname_cmp(X509 *, struct iked_static_id *); -int ca_x509_subjectaltname(X509 *cert, struct iked_id *); +int ca_x509_subjectaltname(X509 *cert, struct iked_id *, int); int ca_dispatch_parent(int, struct privsep_proc *, struct imsg *); int ca_dispatch_ikev2(int, struct privsep_proc *, struct imsg *); @@ -1400,34 +1400,31 @@ ca_x509_subjectaltname_cmp(X509 *cert, struct iked_static_id *id) { struct iked_id sanid; char idstr[IKED_ID_SIZE]; - int ret = -1; - - bzero(&sanid, sizeof(sanid)); - - if (ca_x509_subjectaltname(cert, &sanid) != 0) - return (-1); - - ikev2_print_id(&sanid, idstr, sizeof(idstr)); - - /* Compare id types, length and data */ - if ((id->id_type != sanid.id_type) || - ((ssize_t)ibuf_size(sanid.id_buf) != - (id->id_length - id->id_offset)) || - (memcmp(id->id_data + id->id_offset, - ibuf_data(sanid.id_buf), - ibuf_size(sanid.id_buf)) != 0)) { + int ret = -1, lastpos = -1; + + while (ca_x509_subjectaltname(cert, &sanid, lastpos++) == 0) { + ikev2_print_id(&sanid, idstr, sizeof(idstr)); + + /* Compare id types, length and data */ + if ((id->id_type == sanid.id_type) && + ((ssize_t)ibuf_size(sanid.id_buf) == + (id->id_length - id->id_offset)) && + (memcmp(id->id_data + id->id_offset, + ibuf_data(sanid.id_buf), + ibuf_size(sanid.id_buf)) == 0)) { + ret = 0; + break; + } log_debug("%s: %s mismatched", __func__, idstr); - goto done; + bzero(&sanid, sizeof(sanid)); } - ret = 0; - done: ibuf_release(sanid.id_buf); return (ret); } int -ca_x509_subjectaltname(X509 *cert, struct iked_id *id) +ca_x509_subjectaltname(X509 *cert, struct iked_id *id, int lastpos) { X509_EXTENSION *san; uint8_t sanhdr[4], *data; @@ -1435,7 +1432,7 @@ ca_x509_subjectaltname(X509 *cert, struct iked_id *id) char idstr[IKED_ID_SIZE]; if ((ext = X509_get_ext_by_NID(cert, - NID_subject_alt_name, -1)) == -1 || + NID_subject_alt_name, lastpos)) == -1 || ((san = X509_get_ext(cert, ext)) == NULL)) { log_debug("%s: did not find subjectAltName in certificate", __func__);