diff options
author | Andreas Steffen <andreas.steffen@strongswan.org> | 2009-11-04 23:37:15 +0100 |
---|---|---|
committer | Andreas Steffen <andreas.steffen@strongswan.org> | 2009-11-04 23:37:15 +0100 |
commit | 4c68a85a75f23a33623687847dcc5dcd2d761ff5 (patch) | |
tree | b32fe600a59d87bd70aed24fe0b87309d679ae77 /src | |
parent | fef3b0b7fde0dc2e67c1ff790e3e968d721f2412 (diff) | |
download | strongswan-4c68a85a75f23a33623687847dcc5dcd2d761ff5.tar.bz2 strongswan-4c68a85a75f23a33623687847dcc5dcd2d761ff5.tar.xz |
implemented path length constraint checkinf for IKEv2
Diffstat (limited to 'src')
-rw-r--r-- | src/charon/credentials/credential_manager.c | 36 | ||||
-rw-r--r-- | src/charon/plugins/stroke/stroke_list.c | 2 | ||||
-rw-r--r-- | src/libstrongswan/credentials/certificates/x509.h | 3 | ||||
-rw-r--r-- | src/libstrongswan/plugins/x509/x509_cert.c | 2 | ||||
-rw-r--r-- | src/pluto/ca.c | 17 | ||||
-rw-r--r-- | src/pluto/ca.h | 2 | ||||
-rw-r--r-- | src/pluto/connections.c | 10 | ||||
-rw-r--r-- | src/pluto/ocsp.c | 19 | ||||
-rw-r--r-- | src/pluto/x509.c | 8 |
9 files changed, 63 insertions, 36 deletions
diff --git a/src/charon/credentials/credential_manager.c b/src/charon/credentials/credential_manager.c index 7bd724a66..875b62d80 100644 --- a/src/charon/credentials/credential_manager.c +++ b/src/charon/credentials/credential_manager.c @@ -28,8 +28,6 @@ #include <credentials/certificates/ocsp_request.h> #include <credentials/certificates/ocsp_response.h> -#define MAX_CA_LEVELS 6 - typedef struct private_credential_manager_t private_credential_manager_t; /** @@ -1067,12 +1065,14 @@ static bool verify_trust_chain(private_credential_manager_t *this, bool trusted, bool crl, bool ocsp) { certificate_t *current, *issuer; + x509_t *x509; auth_cfg_t *auth; - u_int level = 0; + int pathlen, pathlen_constraint; auth = auth_cfg_create(); current = subject->get_ref(subject); - while (level++ < MAX_CA_LEVELS) + + for (pathlen = 0; pathlen <= X509_MAX_PATH_LEN; pathlen++) { issuer = get_issuer_cert(this, current, TRUE); if (issuer) @@ -1082,7 +1082,7 @@ static bool verify_trust_chain(private_credential_manager_t *this, { auth->add(auth, AUTH_RULE_CA_CERT, issuer->get_ref(issuer)); DBG1(DBG_CFG, " using trusted ca certificate \"%Y\"", - issuer->get_subject(issuer)); + issuer->get_subject(issuer)); trusted = TRUE; } else @@ -1122,17 +1122,32 @@ static bool verify_trust_chain(private_credential_manager_t *this, issuer->destroy(issuer); break; } + + /* check path length constraint */ + x509 = (x509_t*)issuer; + pathlen_constraint = x509->get_pathLenConstraint(x509); + if (pathlen_constraint != X509_NO_PATH_LEN_CONSTRAINT && + pathlen > pathlen_constraint) + { + DBG1(DBG_CFG, "path length of %d violates constraint of %d", + pathlen, pathlen_constraint); + trusted = FALSE; + issuer->destroy(issuer); + break; + } current->destroy(current); current = issuer; if (trusted) { + DBG1(DBG_CFG, " reached self-signed root ca with a path length of %d", + pathlen); break; } } current->destroy(current); - if (level > MAX_CA_LEVELS) + if (pathlen > X509_MAX_PATH_LEN) { - DBG1(DBG_CFG, "maximum ca path length of %d levels reached", level); + DBG1(DBG_CFG, "maximum path length of %d exceeded", X509_MAX_PATH_LEN); } if (trusted) { @@ -1377,7 +1392,7 @@ static auth_cfg_t *build_trustchain(private_credential_manager_t *this, { certificate_t *issuer, *current; auth_cfg_t *trustchain; - u_int level = 0; + int pathlen = 0; trustchain = auth_cfg_create(); @@ -1406,13 +1421,14 @@ static auth_cfg_t *build_trustchain(private_credential_manager_t *this, trustchain->add(trustchain, AUTH_RULE_IM_CERT, current); } issuer = get_issuer_cert(this, current, FALSE); - if (!issuer || issuer->equals(issuer, current) || level > MAX_CA_LEVELS) + if (!issuer || issuer->equals(issuer, current) || + pathlen > X509_MAX_PATH_LEN) { DESTROY_IF(issuer); break; } current = issuer; - level++; + pathlen++; } trustchain->destroy(trustchain); return NULL; diff --git a/src/charon/plugins/stroke/stroke_list.c b/src/charon/plugins/stroke/stroke_list.c index 5cffa4298..93942441f 100644 --- a/src/charon/plugins/stroke/stroke_list.c +++ b/src/charon/plugins/stroke/stroke_list.c @@ -746,7 +746,7 @@ static void stroke_list_certs(linked_list_t *list, char *label, /* list optional pathLenConstraint */ pathlen = x509->get_pathLenConstraint(x509); - if (pathlen != NO_PATH_LEN_CONSTRAINT) + if (pathlen != X509_NO_PATH_LEN_CONSTRAINT) { fprintf(out, " pathlen: %d\n", pathlen); } diff --git a/src/libstrongswan/credentials/certificates/x509.h b/src/libstrongswan/credentials/certificates/x509.h index 6d3419546..a671ce220 100644 --- a/src/libstrongswan/credentials/certificates/x509.h +++ b/src/libstrongswan/credentials/certificates/x509.h @@ -24,7 +24,8 @@ #include <utils/enumerator.h> #include <credentials/certificates/certificate.h> -#define NO_PATH_LEN_CONSTRAINT -1 +#define X509_NO_PATH_LEN_CONSTRAINT -1 +#define X509_MAX_PATH_LEN 7 typedef struct x509_t x509_t; typedef enum x509_flag_t x509_flag_t; diff --git a/src/libstrongswan/plugins/x509/x509_cert.c b/src/libstrongswan/plugins/x509/x509_cert.c index 0147e78c6..bc1afad33 100644 --- a/src/libstrongswan/plugins/x509/x509_cert.c +++ b/src/libstrongswan/plugins/x509/x509_cert.c @@ -1238,7 +1238,7 @@ static private_x509_cert_t* create_empty(void) this->subjectKeyIdentifier = chunk_empty; this->authKeyIdentifier = chunk_empty; this->authKeySerialNumber = chunk_empty; - this->pathLenConstraint = NO_PATH_LEN_CONSTRAINT; + this->pathLenConstraint = X509_NO_PATH_LEN_CONSTRAINT; this->algorithm = 0; this->signature = chunk_empty; this->flags = 0; diff --git a/src/pluto/ca.c b/src/pluto/ca.c index 2f59a9014..583ef8b90 100644 --- a/src/pluto/ca.c +++ b/src/pluto/ca.c @@ -21,6 +21,7 @@ #include <debug.h> #include <utils/enumerator.h> +#include <credentials/certificates/x509.h> #include <freeswan.h> @@ -52,14 +53,14 @@ bool trusted_ca(identification_t *a, identification_t *b, int *pathlen) /* no CA b specified -> any CA a is accepted */ if (b == NULL) { - *pathlen = (a == NULL) ? 0 : MAX_CA_PATH_LEN; + *pathlen = (a == NULL) ? 0 : X509_MAX_PATH_LEN; return TRUE; } /* no CA a specified -> trust cannot be established */ if (a == NULL) { - *pathlen = MAX_CA_PATH_LEN; + *pathlen = X509_MAX_PATH_LEN; return FALSE; } @@ -74,7 +75,7 @@ bool trusted_ca(identification_t *a, identification_t *b, int *pathlen) /* CA a might be a subordinate CA of b */ lock_authcert_list("trusted_ca"); - while ((*pathlen)++ < MAX_CA_PATH_LEN) + while ((*pathlen)++ < X509_MAX_PATH_LEN) { certificate_t *certificate; identification_t *issuer; @@ -130,7 +131,7 @@ bool match_requested_ca(linked_list_t *requested_ca, identification_t *our_ca, return TRUE; } - *our_pathlen = MAX_CA_PATH_LEN + 1; + *our_pathlen = X509_MAX_PATH_LEN + 1; enumerator = requested_ca->create_enumerator(requested_ca); while (enumerator->enumerate(enumerator, &ca)) @@ -144,9 +145,9 @@ bool match_requested_ca(linked_list_t *requested_ca, identification_t *our_ca, } enumerator->destroy(enumerator); - if (*our_pathlen > MAX_CA_PATH_LEN) + if (*our_pathlen > X509_MAX_PATH_LEN) { - *our_pathlen = MAX_CA_PATH_LEN; + *our_pathlen = X509_MAX_PATH_LEN; return FALSE; } else @@ -374,7 +375,7 @@ bool trust_authcert_candidate(const x509cert_t *cert, const x509cert_t *alt_chai lock_authcert_list("trust_authcert_candidate"); - for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++) + for (pathlen = 0; pathlen < X509_MAX_PATH_LEN; pathlen++) { certificate_t *certificate = cert->cert; x509_t *x509 = (x509_t*)certificate; @@ -443,7 +444,7 @@ bool trust_authcert_candidate(const x509cert_t *cert, const x509cert_t *alt_chai /* go up one step in the trust chain */ cert = authcert; } - plog("maximum ca path length of %d levels exceeded", MAX_CA_PATH_LEN); + plog("maximum ca path length of %d levels exceeded", X509_MAX_PATH_LEN); unlock_authcert_list("trust_authcert_candidate"); return FALSE; } diff --git a/src/pluto/ca.h b/src/pluto/ca.h index 77dfe3327..7b016f943 100644 --- a/src/pluto/ca.h +++ b/src/pluto/ca.h @@ -21,8 +21,6 @@ #include "x509.h" #include "whack.h" -#define MAX_CA_PATH_LEN 7 - /* CA info structures */ typedef struct ca_info ca_info_t; diff --git a/src/pluto/connections.c b/src/pluto/connections.c index 528e40897..45d88a350 100644 --- a/src/pluto/connections.c +++ b/src/pluto/connections.c @@ -3391,8 +3391,8 @@ connection_t *refine_host_connection(const struct state *st, int prio = (ID_MATCH_PERFECT) * !matching_request + ID_MATCH_PERFECT - match_level; - prio = (MAX_CA_PATH_LEN + 1) * prio + peer_pathlen; - prio = (MAX_CA_PATH_LEN + 1) * prio + our_pathlen; + prio = (X509_MAX_PATH_LEN + 1) * prio + peer_pathlen; + prio = (X509_MAX_PATH_LEN + 1) * prio + our_pathlen; DBG(DBG_CONTROLMORE, DBG_log("%s: %s match (id: %s, auth: %s, trust: %s, request: %s, prio: %4d)" @@ -3560,7 +3560,7 @@ static bool is_virtual_net_used(const ip_subnet *peer_net, */ #define PATH_WEIGHT 1 -#define WILD_WEIGHT (MAX_CA_PATH_LEN+1) +#define WILD_WEIGHT (X509_MAX_PATH_LEN+1) #define PRIO_WEIGHT (ID_MATCH_PERFECT+1) * WILD_WEIGHT /* fc_try: a helper function for find_client_connection */ @@ -3691,7 +3691,7 @@ static connection_t *fc_try(const connection_t *c, struct host_pair *hp, */ prio = PRIO_WEIGHT * routed(sr->routing) + WILD_WEIGHT * match_level - + PATH_WEIGHT * (MAX_CA_PATH_LEN - pathlen) + + PATH_WEIGHT * (X509_MAX_PATH_LEN - pathlen) + 1; if (prio > best_prio) { @@ -3797,7 +3797,7 @@ static connection_t *fc_try_oppo(const connection_t *c, */ prio = PRIO_WEIGHT * (d->prio + routed(sr->routing)) + WILD_WEIGHT * match_level - + PATH_WEIGHT * (MAX_CA_PATH_LEN - pathlen); + + PATH_WEIGHT * (X509_MAX_PATH_LEN - pathlen); if (prio > best_prio) { best = d; diff --git a/src/pluto/ocsp.c b/src/pluto/ocsp.c index 10ebcda14..2674aa2ab 100644 --- a/src/pluto/ocsp.c +++ b/src/pluto/ocsp.c @@ -961,7 +961,7 @@ chunk_t build_ocsp_request(ocsp_location_t *location) */ static bool valid_ocsp_response(response_t *res) { - int pathlen; + int pathlen, pathlen_constraint; x509cert_t *authcert; lock_authcert_list("valid_ocsp_response"); @@ -990,7 +990,7 @@ static bool valid_ocsp_response(response_t *res) ) - for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++) + for (pathlen = -1; pathlen <= X509_MAX_PATH_LEN; pathlen++) { x509cert_t *cert = authcert; certificate_t *certificate = cert->cert; @@ -1038,17 +1038,28 @@ static bool valid_ocsp_response(response_t *res) DBG_log("certificate signature is valid") ) + /* check path length constraint */ + pathlen_constraint = x509->get_pathLenConstraint(x509); + if (pathlen_constraint != X509_NO_PATH_LEN_CONSTRAINT && + pathlen > pathlen_constraint) + { + plog("path length of %d violates constraint of %d", + pathlen, pathlen_constraint); + return FALSE; + } + /* check if cert is self-signed */ if (x509->get_flags(x509) & X509_SELF_SIGNED) { DBG(DBG_CONTROL, - DBG_log("reached self-signed root ca") + DBG_log("reached self-signed root ca with a path length of %d", + pathlen) ) unlock_authcert_list("valid_ocsp_response"); return TRUE; } } - plog("maximum ca path length of %d levels exceeded", MAX_CA_PATH_LEN); + plog("maximum path length of %d exceeded", X509_MAX_PATH_LEN); unlock_authcert_list("valid_ocsp_response"); return FALSE; } diff --git a/src/pluto/x509.c b/src/pluto/x509.c index 37d0b016a..a612a70ed 100644 --- a/src/pluto/x509.c +++ b/src/pluto/x509.c @@ -348,7 +348,7 @@ bool verify_x509cert(const x509cert_t *cert, bool strict, time_t *until) *until = 0; - for (pathlen = -1; pathlen < MAX_CA_PATH_LEN; pathlen++) + for (pathlen = -1; pathlen <= X509_MAX_PATH_LEN; pathlen++) { certificate_t *certificate = cert->cert; identification_t *subject = certificate->get_subject(certificate); @@ -409,7 +409,7 @@ bool verify_x509cert(const x509cert_t *cert, bool strict, time_t *until) /* check path length constraint */ pathlen_constraint = x509->get_pathLenConstraint(x509); - if (pathlen_constraint != NO_PATH_LEN_CONSTRAINT && + if (pathlen_constraint != X509_NO_PATH_LEN_CONSTRAINT && pathlen > pathlen_constraint) { plog("path length of %d violates constraint of %d", @@ -490,7 +490,7 @@ bool verify_x509cert(const x509cert_t *cert, bool strict, time_t *until) /* go up one step in the trust chain */ cert = issuer_cert; } - plog("maximum path length of %d exceeded", MAX_CA_PATH_LEN); + plog("maximum path length of %d exceeded", X509_MAX_PATH_LEN); return FALSE; } @@ -603,7 +603,7 @@ void list_x509cert_chain(const char *caption, x509cert_t* cert, /* list optional pathLenConstraint */ pathlen = x509->get_pathLenConstraint(x509); - if (pathlen != NO_PATH_LEN_CONSTRAINT) + if (pathlen != X509_NO_PATH_LEN_CONSTRAINT) { whack_log(RC_COMMENT, " pathlen: %d", pathlen); } |