diff options
author | Andreas Steffen <andreas.steffen@strongswan.org> | 2009-12-23 14:17:28 +0100 |
---|---|---|
committer | Andreas Steffen <andreas.steffen@strongswan.org> | 2009-12-23 14:21:31 +0100 |
commit | 32d8f44229ac1025046a984efc4a546fbe0a841c (patch) | |
tree | e2113aa2b09873b650bcde3bb65c2fe2abf06d6f /src | |
parent | f8f4f31a77444d05d7cc246adc22803baad98446 (diff) | |
download | strongswan-32d8f44229ac1025046a984efc4a546fbe0a841c.tar.bz2 strongswan-32d8f44229ac1025046a984efc4a546fbe0a841c.tar.xz |
verify RFC3779 IP address blocks along X.509 certificate trust chain
Diffstat (limited to 'src')
-rw-r--r-- | src/charon/credentials/credential_manager.c | 58 | ||||
-rw-r--r-- | src/charon/plugins/stroke/stroke_list.c | 41 |
2 files changed, 91 insertions, 8 deletions
diff --git a/src/charon/credentials/credential_manager.c b/src/charon/credentials/credential_manager.c index 875b62d80..1d20a1e1e 100644 --- a/src/charon/credentials/credential_manager.c +++ b/src/charon/credentials/credential_manager.c @@ -938,6 +938,60 @@ static cert_validation_t check_crl(private_credential_manager_t *this, } /** + * check a certificate for optional IP address block constraints + */ +static bool check_ip_addr_block_constraints(x509_t *subject, x509_t *issuer) +{ + bool subject_constraint = subject->get_flags(subject) & X509_IP_ADDR_BLOCKS; + bool issuer_constraint = issuer->get_flags(issuer) & X509_IP_ADDR_BLOCKS; + bool contained = TRUE; + + enumerator_t *subject_enumerator, *issuer_enumerator; + traffic_selector_t *subject_ts, *issuer_ts; + + if (!subject_constraint && !issuer_constraint) + { + return TRUE; + } + if (!subject_constraint) + { + DBG1(DBG_CFG, "subject certficate lacks ipAddrBlocks extension"); + return FALSE; + } + if (!issuer_constraint) + { + DBG1(DBG_CFG, "issuer certficate lacks ipAddrBlocks extension"); + return FALSE; + } + subject_enumerator = subject->create_ipAddrBlock_enumerator(subject); + while (subject_enumerator->enumerate(subject_enumerator, &subject_ts)) + { + contained = FALSE; + + issuer_enumerator = issuer->create_ipAddrBlock_enumerator(issuer); + while (issuer_enumerator->enumerate(issuer_enumerator, &issuer_ts)) + { + if (subject_ts->is_contained_in(subject_ts, issuer_ts)) + { + DBG2(DBG_CFG, " subject address block %R is contained in " + "issuer address block %R", subject_ts, issuer_ts); + contained = TRUE; + break; + } + } + issuer_enumerator->destroy(issuer_enumerator); + if (!contained) + { + DBG1(DBG_CFG, "subject address block %R is not contained in any " + "issuer address block", subject_ts); + break; + } + } + subject_enumerator->destroy(subject_enumerator); + return contained; +} + +/** * check a certificate for its lifetime */ static bool check_certificate(private_credential_manager_t *this, @@ -961,6 +1015,10 @@ static bool check_certificate(private_credential_manager_t *this, if (issuer->get_type(issuer) == CERT_X509 && subject->get_type(subject) == CERT_X509) { + if (!check_ip_addr_block_constraints((x509_t*)subject, (x509_t*)issuer)) + { + return FALSE; + } if (ocsp || crl) { DBG1(DBG_CFG, "checking certificate status of \"%Y\"", diff --git a/src/charon/plugins/stroke/stroke_list.c b/src/charon/plugins/stroke/stroke_list.c index 2b7a7df03..470f8e900 100644 --- a/src/charon/plugins/stroke/stroke_list.c +++ b/src/charon/plugins/stroke/stroke_list.c @@ -694,19 +694,21 @@ static void stroke_list_certs(linked_list_t *list, char *label, { bool first = TRUE; time_t now = time(NULL); - enumerator_t *enumerator = list->create_enumerator(list); + enumerator_t *enumerator; certificate_t *cert; + x509_flag_t flag_mask; + /* mask all auxiliary flags */ + flag_mask = ~(X509_SELF_SIGNED | X509_SERVER_AUTH | X509_IP_ADDR_BLOCKS ); + + enumerator = list->create_enumerator(list); while (enumerator->enumerate(enumerator, (void**)&cert)) { x509_t *x509 = (x509_t*)cert; - x509_flag_t x509_flags = x509->get_flags(x509); + x509_flag_t x509_flags = x509->get_flags(x509) & flag_mask; - /* list only if flag is set, - * or flags == 0 (ignoring self-signed and serverAuth) - */ - if ((x509_flags & flags) || - (flags == (x509_flags & ~(X509_SELF_SIGNED | X509_SERVER_AUTH)))) + /* list only if flag is set or flag == 0 */ + if ((x509_flags & flags) || (x509_flags == flags)) { enumerator_t *enumerator; identification_t *altName; @@ -797,6 +799,29 @@ static void stroke_list_certs(linked_list_t *list, char *label, fprintf(out, " pathlen: %d\n", pathlen); } + /* list optional ipAddrBlocks */ + if (x509->get_flags(x509) & X509_IP_ADDR_BLOCKS) + { + traffic_selector_t *ipAddrBlock; + bool first_ipAddrBlock = TRUE; + + fprintf(out, " addresses: "); + enumerator = x509->create_ipAddrBlock_enumerator(x509); + while (enumerator->enumerate(enumerator, &ipAddrBlock)) + { + if (first_ipAddrBlock) + { + first_ipAddrBlock = FALSE; + } + else + { + fprintf(out, ", "); + } + fprintf(out, "%R", ipAddrBlock); + } + enumerator->destroy(enumerator); + fprintf(out, "\n"); + } } } enumerator->destroy(enumerator); @@ -1058,7 +1083,7 @@ static void list(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out) if (msg->list.flags & LIST_CERTS) { stroke_list_certs(cert_list, "X.509 End Entity Certificates", - 0, msg->list.utc, out); + X509_NONE, msg->list.utc, out); } if (msg->list.flags & LIST_CACERTS) { |