aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndreas Steffen <andreas.steffen@strongswan.org>2009-11-04 23:37:15 +0100
committerAndreas Steffen <andreas.steffen@strongswan.org>2009-11-04 23:37:15 +0100
commit4c68a85a75f23a33623687847dcc5dcd2d761ff5 (patch)
treeb32fe600a59d87bd70aed24fe0b87309d679ae77 /src
parentfef3b0b7fde0dc2e67c1ff790e3e968d721f2412 (diff)
downloadstrongswan-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.c36
-rw-r--r--src/charon/plugins/stroke/stroke_list.c2
-rw-r--r--src/libstrongswan/credentials/certificates/x509.h3
-rw-r--r--src/libstrongswan/plugins/x509/x509_cert.c2
-rw-r--r--src/pluto/ca.c17
-rw-r--r--src/pluto/ca.h2
-rw-r--r--src/pluto/connections.c10
-rw-r--r--src/pluto/ocsp.c19
-rw-r--r--src/pluto/x509.c8
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);
}