constraints: Properly validate name constraints according to RFC 5280

The previous code was in a way too simple which resulted in it being too
strict.  For instance, it enforced that intermediate CA certificates
inherited the name constraints of their parents.  That's not required by
RFC 5280 and prevented e.g. adding constraints in an intermediate CA
certificate that's followed by another that doesn't contain any
name constraints.  That's perfectly fine as the set of constraints
specified by the parent continue to apply to that CA certificate and
the children it issues.

Name constraints were previously also applied to all identities of a
matching type, which is way too strict except for some very simple
cases.  It basically prevented multiple constraints of the same type
as e.g. an intermediate CA certificate that has permitted name constraints
for example.org and example.com couldn't issue acceptable certificates
because any SAN with one domain would get rejected by the other
constraint.  According to RFC 5280 matching one constraint is enough.

Also fixed is an issue with name constraints for IP addresses which were
previously only supported for a single level.
This commit is contained in:
Tobias Brunner
2024-03-12 09:14:44 +01:00
parent ea6a6344d3
commit b29be6029e
2 changed files with 816 additions and 203 deletions
+404 -81
View File
@@ -68,15 +68,15 @@ static char keydata[] = {
/**
* Issue a certificate with permitted/excluded name constraints
*/
static certificate_t* create_cert(certificate_t *ca, char *subject, char *san,
x509_flag_t flags, identification_t *permitted,
identification_t *excluded)
static certificate_t* create_cert_lists(certificate_t *ca, char *subject,
linked_list_t *sans, x509_flag_t flags,
linked_list_t *permitted,
linked_list_t *excluded)
{
private_key_t *privkey;
public_key_t *pubkey;
certificate_t *cert;
identification_t *id;
linked_list_t *plist, *elist, *sans;
privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
BUILD_BLOB_ASN1_DER, chunk_from_thing(keydata),
@@ -84,6 +84,39 @@ static certificate_t* create_cert(certificate_t *ca, char *subject, char *san,
ck_assert(privkey);
pubkey = privkey->get_public_key(privkey);
ck_assert(pubkey);
id = identification_create_from_string(subject);
cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
BUILD_SIGNING_KEY, privkey,
BUILD_PUBLIC_KEY, pubkey,
BUILD_SUBJECT, id,
BUILD_X509_FLAG, flags,
BUILD_SIGNING_CERT, ca,
BUILD_SUBJECT_ALTNAMES, sans,
BUILD_PERMITTED_NAME_CONSTRAINTS, permitted,
BUILD_EXCLUDED_NAME_CONSTRAINTS, excluded,
BUILD_END);
ck_assert(cert);
id->destroy(id);
sans->destroy_offset(sans, offsetof(identification_t, destroy));
permitted->destroy_offset(permitted, offsetof(identification_t, destroy));
excluded->destroy_offset(excluded, offsetof(identification_t, destroy));
privkey->destroy(privkey);
pubkey->destroy(pubkey);
return cert;
}
/**
* Issue a certificate with single values
*/
static certificate_t* create_cert(certificate_t *ca, char *subject, char *san,
x509_flag_t flags, identification_t *permitted,
identification_t *excluded)
{
linked_list_t *plist, *elist, *sans;
identification_t *id;
plist = linked_list_create();
if (permitted)
{
@@ -100,26 +133,7 @@ static certificate_t* create_cert(certificate_t *ca, char *subject, char *san,
id = identification_create_from_string(san);
sans->insert_last(sans, id);
}
id = identification_create_from_string(subject);
cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
BUILD_SIGNING_KEY, privkey,
BUILD_PUBLIC_KEY, pubkey,
BUILD_SUBJECT, id,
BUILD_X509_FLAG, flags,
BUILD_SIGNING_CERT, ca,
BUILD_SUBJECT_ALTNAMES, sans,
BUILD_PERMITTED_NAME_CONSTRAINTS, plist,
BUILD_EXCLUDED_NAME_CONSTRAINTS, elist,
BUILD_END);
ck_assert(cert);
id->destroy(id);
sans->destroy_offset(sans, offsetof(identification_t, destroy));
plist->destroy_offset(plist, offsetof(identification_t, destroy));
elist->destroy_offset(elist, offsetof(identification_t, destroy));
privkey->destroy(privkey);
pubkey->destroy(pubkey);
return cert;
return create_cert_lists(ca, subject, sans, flags, plist, elist);
}
/**
@@ -188,26 +202,29 @@ START_TEST(test_permitted_dn)
END_TEST
static struct {
id_type_t ctype;
char *cdata;
char *subject;
bool good;
} permitted_san[] = {
{ ID_FQDN, ".strongswan.org", "test.strongswan.org", TRUE },
{ ID_FQDN, "strongswan.org", "test.strongswan.org", TRUE },
{ ID_FQDN, "a.b.c.strongswan.org", "d.a.b.c.strongswan.org", TRUE },
{ ID_FQDN, "a.b.c.strongswan.org", "a.b.c.d.strongswan.org", FALSE },
{ ID_FQDN, "strongswan.org", "strongswan.org.com", FALSE },
{ ID_FQDN, ".strongswan.org", "strongswan.org", FALSE },
{ ID_FQDN, "strongswan.org", "nostrongswan.org", FALSE },
{ ID_FQDN, "strongswan.org", "swan.org", FALSE },
{ ID_FQDN, "strongswan.org", "swan.org", FALSE },
{ ID_RFC822_ADDR, "[email protected]", "[email protected]", TRUE },
{ ID_RFC822_ADDR, "[email protected]", "[email protected]", FALSE },
{ ID_RFC822_ADDR, "strongswan.org", "[email protected]", TRUE },
{ ID_RFC822_ADDR, "strongswan.org", "[email protected]", FALSE },
{ ID_RFC822_ADDR, ".strongswan.org", "[email protected]", TRUE },
{ ID_RFC822_ADDR, ".strongswan.org", "[email protected]", FALSE },
{ ".strongswan.org", "test.strongswan.org", TRUE },
{ "strongswan.org", "test.strongswan.org", TRUE },
{ "a.b.c.strongswan.org", "d.a.b.c.strongswan.org", TRUE },
{ "a.b.c.strongswan.org", "a.b.c.d.strongswan.org", FALSE },
{ "strongswan.org", "strongswan.org.com", FALSE },
{ ".strongswan.org", "strongswan.org", FALSE },
{ "strongswan.org", "nostrongswan.org", FALSE },
{ "strongswan.org", "swan.org", FALSE },
{ "strongswan.org", "swan.org", FALSE },
{ "[email protected]", "[email protected]", TRUE },
{ "[email protected]", "[email protected]", FALSE },
{ "email:strongswan.org", "[email protected]", TRUE },
{ "email:strongswan.org", "[email protected]", FALSE },
{ "email:.strongswan.org", "[email protected]", TRUE },
{ "email:.strongswan.org", "[email protected]", FALSE },
{ "192.168.1.0/24", "192.168.1.10", TRUE },
{ "192.168.1.0/24", "192.168.2.10", FALSE },
{ "fec0::/64", "fec0::10", TRUE },
{ "fec0::/64", "fec1::10", FALSE },
};
START_TEST(test_permitted_san)
@@ -215,8 +232,7 @@ START_TEST(test_permitted_san)
certificate_t *ca, *sj;
identification_t *id;
id = identification_create_from_encoding(permitted_san[_i].ctype,
chunk_from_str(permitted_san[_i].cdata));
id = identification_create_from_string(permitted_san[_i].cdata);
ca = create_cert(NULL, "CN=CA", NULL, X509_CA, id, NULL);
sj = create_cert(ca, "CN=SJ", permitted_san[_i].subject, 0, NULL, NULL);
@@ -259,26 +275,29 @@ START_TEST(test_excluded_dn)
END_TEST
static struct {
id_type_t ctype;
char *cdata;
char *subject;
bool good;
} excluded_san[] = {
{ ID_FQDN, ".strongswan.org", "test.strongswan.org", FALSE },
{ ID_FQDN, "strongswan.org", "test.strongswan.org", FALSE },
{ ID_FQDN, "a.b.c.strongswan.org", "d.a.b.c.strongswan.org", FALSE },
{ ID_FQDN, "a.b.c.strongswan.org", "a.b.c.d.strongswan.org", TRUE },
{ ID_FQDN, "strongswan.org", "strongswan.org.com", TRUE },
{ ID_FQDN, ".strongswan.org", "strongswan.org", TRUE },
{ ID_FQDN, "strongswan.org", "nostrongswan.org", TRUE },
{ ID_FQDN, "strongswan.org", "swan.org", TRUE },
{ ID_FQDN, "strongswan.org", "swan.org", TRUE },
{ ID_RFC822_ADDR, "[email protected]", "[email protected]", FALSE },
{ ID_RFC822_ADDR, "[email protected]", "[email protected]", TRUE },
{ ID_RFC822_ADDR, "strongswan.org", "[email protected]", FALSE },
{ ID_RFC822_ADDR, "strongswan.org", "[email protected]", TRUE },
{ ID_RFC822_ADDR, ".strongswan.org", "[email protected]", FALSE },
{ ID_RFC822_ADDR, ".strongswan.org", "[email protected]", TRUE },
{ ".strongswan.org", "test.strongswan.org", FALSE },
{ "strongswan.org", "test.strongswan.org", FALSE },
{ "a.b.c.strongswan.org", "d.a.b.c.strongswan.org", FALSE },
{ "a.b.c.strongswan.org", "a.b.c.d.strongswan.org", TRUE },
{ "strongswan.org", "strongswan.org.com", TRUE },
{ ".strongswan.org", "strongswan.org", TRUE },
{ "strongswan.org", "nostrongswan.org", TRUE },
{ "strongswan.org", "swan.org", TRUE },
{ "strongswan.org", "swan.org", TRUE },
{ "[email protected]", "[email protected]", FALSE },
{ "[email protected]", "[email protected]", TRUE },
{ "email:strongswan.org", "[email protected]", FALSE },
{ "email:strongswan.org", "[email protected]", TRUE },
{ "email:.strongswan.org", "[email protected]", FALSE },
{ "email:.strongswan.org", "[email protected]", TRUE },
{ "192.168.1.0/24", "192.168.1.10", FALSE },
{ "192.168.1.0/24", "192.168.2.10", TRUE },
{ "fec0::/64", "fec0::10", FALSE },
{ "fec0::/64", "fec1::10", TRUE },
};
START_TEST(test_excluded_san)
@@ -286,8 +305,7 @@ START_TEST(test_excluded_san)
certificate_t *ca, *sj;
identification_t *id;
id = identification_create_from_encoding(excluded_san[_i].ctype,
chunk_from_str(excluded_san[_i].cdata));
id = identification_create_from_string(excluded_san[_i].cdata);
ca = create_cert(NULL, "CN=CA", NULL, X509_CA, NULL, id);
sj = create_cert(ca, "CN=SJ", excluded_san[_i].subject, 0, NULL, NULL);
@@ -298,33 +316,45 @@ START_TEST(test_excluded_san)
}
END_TEST
/**
* Create an identity if the given string is not NULL
*/
static identification_t *create_test_id(char *id)
{
return id ? identification_create_from_string(id) : NULL;
}
static struct {
char *caconst;
char *imconst;
char *subject;
bool good;
} permitted_dninh[] = {
} permitted_dn_levels[] = {
{ "C=CH", "C=CH, O=strongSwan", "C=CH, O=strongSwan, CN=tester", TRUE },
{ "C=CH", NULL, "C=CH, O=strongSwan, CN=tester", TRUE },
{ NULL, "C=CH, O=strongSwan", "C=CH, O=strongSwan, CN=tester", TRUE },
{ "C=CH", "C=DE, O=strongSwan", "C=CH, O=strongSwan, CN=tester", FALSE },
{ "C=CH", "C=DE", "C=DE, O=strongSwan, CN=tester", FALSE },
{ "C=CH, O=strongSwan", "C=CH", "C=CH", FALSE },
{ "C=CH, O=strongSwan, CN=Intermediate", NULL, "C=CH", FALSE },
};
START_TEST(test_permitted_dninh)
START_TEST(test_permitted_dn_levels)
{
certificate_t *ca, *im, *sj;
identification_t *id;
id = identification_create_from_string(permitted_dninh[_i].caconst);
id = create_test_id(permitted_dn_levels[_i].caconst);
ca = create_cert(NULL, "C=CH, O=strongSwan, CN=CA", NULL, X509_CA, id, NULL);
id = identification_create_from_string(permitted_dninh[_i].imconst);
id = create_test_id(permitted_dn_levels[_i].imconst);
im = create_cert(ca, "C=CH, O=strongSwan, CN=IM", NULL, X509_CA, id, NULL);
sj = create_cert(im, permitted_dninh[_i].subject, NULL, 0, NULL, NULL);
sj = create_cert(im, permitted_dn_levels[_i].subject, NULL, 0, NULL, NULL);
creds->add_cert(creds, TRUE, ca);
creds->add_cert(creds, FALSE, im);
creds->add_cert(creds, FALSE, sj);
ck_assert(check_trust(sj->get_subject(sj)) == permitted_dninh[_i].good);
ck_assert(check_trust(sj->get_subject(sj)) == permitted_dn_levels[_i].good);
}
END_TEST
@@ -333,28 +363,301 @@ static struct {
char *imconst;
char *subject;
bool good;
} excluded_dninh[] = {
{ "C=CH, O=strongSwan", "C=CH", "C=DE", TRUE },
{ "C=CH, O=strongSwan", "C=DE", "C=CH", FALSE },
{ "C=CH", "C=CH, O=strongSwan", "C=CH, O=strongSwan, CN=tester", FALSE },
} permitted_san_levels[] = {
{ "strongswan.org", NULL, "strongswan.org", TRUE },
{ "strongswan.org", NULL, "vpn.strongswan.org", TRUE },
{ "strongswan.org", NULL, "strongswan.com", FALSE },
{ NULL, "strongswan.org", "strongswan.org", TRUE },
{ NULL, "strongswan.org", "strongswan.com", FALSE },
{ "strongswan.org", "strongswan.org", "strongswan.org", TRUE },
{ "strongswan.org", "strongswan.com", "strongswan.com", FALSE },
{ "strongswan.org", "vpn.strongswan.org", "strongswan.org", FALSE },
{ "strongswan.org", "vpn.strongswan.org", "vpn.strongswan.org", TRUE },
{ "strongswan.org", "vpn.strongswan.org", "a.vpn.strongswan.org", TRUE },
{ "strongswan.org", NULL, "[email protected]", TRUE },
{ "[email protected]", NULL, "[email protected]", TRUE },
{ "email:strongswan.org", NULL, "[email protected]", TRUE },
{ "email:strongswan.org", NULL, "[email protected]", FALSE },
{ "email:strongswan.org", "[email protected]", "[email protected]", TRUE },
{ "email:strongswan.org", "[email protected]", "[email protected]", FALSE },
{ "email:strongswan.org", "strongswan.org", "vpn.strongswan.org", TRUE },
{ "192.168.1.0/24", NULL, "192.168.1.10", TRUE },
{ "192.168.1.0/24", NULL, "192.168.2.10", FALSE },
{ "192.168.1.0/24", "192.168.2.0/24", "192.168.1.10", FALSE },
{ "192.168.1.0/24", "192.168.1.0/28", "192.168.1.10", TRUE },
{ "192.168.1.0/24", "192.168.1.16/28", "192.168.1.10", FALSE },
{ "fec0::/64", NULL, "fec0::10", TRUE },
{ "fec0::/64", NULL, "fec1::10", FALSE },
{ "fec0::/64", "fec1::/64", "fec1::10", FALSE },
{ "fec0::/64", "fec0::/123", "fec0::10", TRUE },
{ "fec0::/64", "fec0::20/123", "fec0::10", FALSE },
};
START_TEST(test_excluded_dninh)
START_TEST(test_permitted_san_levels)
{
certificate_t *ca, *im, *sj;
identification_t *id;
id = identification_create_from_string(excluded_dninh[_i].caconst);
ca = create_cert(NULL, "C=CH, O=strongSwan, CN=CA", NULL, X509_CA, NULL, id);
id = identification_create_from_string(excluded_dninh[_i].imconst);
im = create_cert(ca, "C=DE, CN=IM", NULL, X509_CA, NULL, id);
sj = create_cert(im, excluded_dninh[_i].subject, NULL, 0, NULL, NULL);
id = create_test_id(permitted_san_levels[_i].caconst);
ca = create_cert(NULL, "CN=CA", NULL, X509_CA, id, NULL);
id = create_test_id(permitted_san_levels[_i].imconst);
im = create_cert(ca, "CN=IM", NULL, X509_CA, id, NULL);
sj = create_cert(im, "CN=EE", permitted_san_levels[_i].subject, 0, NULL, NULL);
creds->add_cert(creds, TRUE, ca);
creds->add_cert(creds, FALSE, im);
creds->add_cert(creds, FALSE, sj);
ck_assert(check_trust(sj->get_subject(sj)) == excluded_dninh[_i].good);
ck_assert(check_trust(sj->get_subject(sj)) == permitted_san_levels[_i].good);
}
END_TEST
static struct {
char *caconst;
char *imconst;
char *subject;
bool good;
} excluded_dn_levels[] = {
{ "C=CH, O=strongSwan", "C=CH", "C=DE", TRUE },
{ "C=CH, O=strongSwan", "C=CH", "C=CH", FALSE },
{ "C=CH, O=strongSwan", "C=DE", "C=CH", TRUE },
{ "C=CH, O=strongSwan", "C=DE", "C=DE", FALSE },
{ "C=CH, O=strongSwan", "C=DE", "C=CH, O=strongSwan", FALSE },
{ NULL, "C=CH", "C=CH, O=strongSwan", FALSE },
{ "C=CH", NULL, "C=CH, O=strongSwan", FALSE },
{ "C=CH", "C=CH, O=strongSwan", "C=CH, O=strongSwan, CN=tester", FALSE },
{ "C=DE", NULL, "C=CH, O=strongSwan, CN=tester", FALSE },
};
START_TEST(test_excluded_dn_levels)
{
certificate_t *ca, *im, *sj;
identification_t *id;
id = create_test_id(excluded_dn_levels[_i].caconst);
ca = create_cert(NULL, "C=CH, O=strongSwan, CN=CA", NULL, X509_CA, NULL, id);
id = create_test_id(excluded_dn_levels[_i].imconst);
im = create_cert(ca, "C=DE, CN=IM", NULL, X509_CA, NULL, id);
sj = create_cert(im, excluded_dn_levels[_i].subject, NULL, 0, NULL, NULL);
creds->add_cert(creds, TRUE, ca);
creds->add_cert(creds, FALSE, im);
creds->add_cert(creds, FALSE, sj);
ck_assert(check_trust(sj->get_subject(sj)) == excluded_dn_levels[_i].good);
}
END_TEST
static struct {
char *caconst;
char *imconst;
char *subject;
bool good;
} excluded_san_levels[] = {
{ "strongswan.org", NULL, "strongswan.org", FALSE },
{ "strongswan.org", NULL, "strongswan.com", TRUE },
{ NULL, "strongswan.org", "strongswan.org", FALSE },
{ NULL, "strongswan.org", "strongswan.com", TRUE },
{ "strongswan.org", NULL, "test.strongswan.org", FALSE },
{ "test.strongswan.org", NULL, "test.strongswan.org", FALSE },
{ "test.strongswan.org", NULL, "strongswan.org", TRUE },
{ "test.strongswan.org", "strongswan.org", "strongswan.org", FALSE },
{ "test.strongswan.org", "strongswan.org", "test.strongswan.org", FALSE },
{ "test.strongswan.org", "test.strongswan.org", "test.strongswan.org", FALSE },
{ "strongswan.org", NULL, "[email protected]", TRUE },
{ "[email protected]", NULL, "[email protected]", FALSE },
{ "[email protected]", NULL, "[email protected]", TRUE },
{ "email:strongswan.org", NULL, "[email protected]", FALSE },
{ "email:strongswan.org", NULL, "[email protected]", TRUE },
{ "email:strongswan.org", "email:strongswan.com", "[email protected]", FALSE },
{ "email:strongswan.org", "email:strongswan.com", "[email protected]", FALSE },
{ "strongswan.org", "email:strongswan.com", "[email protected]", FALSE },
{ "192.168.1.0/24", NULL, "192.168.1.10", FALSE },
{ "192.168.1.0/24", NULL, "192.168.2.10", TRUE },
{ "192.168.1.0/24", "192.168.0.0/16", "192.168.2.10", FALSE },
{ "fec0::/64", NULL, "fec0::10", FALSE },
{ "fec0::/64", NULL, "fec1::10", TRUE },
{ "fec0::/64", "fec1::/12", "fec1::10", FALSE },
};
START_TEST(test_excluded_san_levels)
{
certificate_t *ca, *im, *sj;
identification_t *id;
id = create_test_id(excluded_san_levels[_i].caconst);
ca = create_cert(NULL, "CN=CA", NULL, X509_CA, NULL, id);
id = create_test_id(excluded_san_levels[_i].imconst);
im = create_cert(ca, "CN=IM", NULL, X509_CA, NULL, id);
sj = create_cert(im, "CN=EE", excluded_san_levels[_i].subject, 0, NULL, NULL);
creds->add_cert(creds, TRUE, ca);
creds->add_cert(creds, FALSE, im);
creds->add_cert(creds, FALSE, sj);
ck_assert(check_trust(sj->get_subject(sj)) == excluded_san_levels[_i].good);
}
END_TEST
/**
* Add an identity to the given list if not NULL
*/
static void add_identity_to_list(linked_list_t *list, char *idstr)
{
identification_t *id;
if (idstr)
{
id = identification_create_from_string(idstr);
list->insert_last(list, id);
}
}
/**
* Create a certificate with potentially multiple constraints/SANs
*/
static certificate_t *create_cert_multi(certificate_t *ca, char *subject,
x509_flag_t flags,
char *san1, char *san2,
char *pconst1, char *pconst2,
char *econst1, char *econst2)
{
linked_list_t *sans, *permitted, *excluded;
sans = linked_list_create();
add_identity_to_list(sans, san1);
add_identity_to_list(sans, san2);
permitted = linked_list_create();
add_identity_to_list(permitted, pconst1);
add_identity_to_list(permitted, pconst2);
excluded = linked_list_create();
add_identity_to_list(excluded, econst1);
add_identity_to_list(excluded, econst2);
return create_cert_lists(ca, subject, sans, flags, permitted, excluded);
}
static struct {
char *caconst1;
char *caconst2;
char *imconst1;
char *imconst2;
char *san1;
char *san2;
bool good;
} permitted_san_multi[] = {
{ "strongswan.org", "strongswan.com", NULL, NULL, "vpn.strongswan.org", NULL, TRUE },
{ "strongswan.org", "strongswan.com", NULL, NULL, "vpn.strongswan.com", NULL, TRUE },
{ "strongswan.org", "strongswan.com", NULL, NULL, "vpn.strongswan.org", "vpn.strongswan.com", TRUE },
{ NULL, NULL, "strongswan.org", "strongswan.com", "vpn.strongswan.org", NULL, TRUE },
{ NULL, NULL, "strongswan.org", "strongswan.com", "vpn.strongswan.com", NULL, TRUE },
{ NULL, NULL, "strongswan.org", "strongswan.com", "vpn.strongswan.org", "vpn.strongswan.com", TRUE },
{ "strongswan.org", "strongswan.com", "strongswan.org", NULL, "vpn.strongswan.org", NULL, TRUE },
{ "strongswan.org", "strongswan.com", "vpn.strongswan.org", NULL, "vpn.strongswan.org", NULL, TRUE },
{ "strongswan.org", "strongswan.com", "vpn.strongswan.org", NULL, "vpn.strongswan.org", NULL, TRUE },
{ "strongswan.org", "strongswan.com", "vpn.strongswan.org", NULL, "vpn.strongswan.org", "vpn.strongswan.com", FALSE },
{ "strongswan.org", "strongswan.com", "strongswan.com", NULL, "vpn.strongswan.org", "vpn.strongswan.com", FALSE },
{ "strongswan.org", "strongswan.com", "strongswan.org", NULL, "vpn.strongswan.com", NULL, FALSE },
{ "strongswan.org", "strongswan.com", "strongswan.com", NULL, "vpn.strongswan.org", NULL, FALSE },
{ "strongswan.org", "strongswan.com", "strongswan.com", NULL, "vpn.strongswan.com", NULL, TRUE },
{ "strongswan.org", "strongswan.com", "strongswan.net", NULL, "vpn.strongswan.com", NULL, FALSE },
{ "strongswan.org", "strongswan.com", "strongswan.net", NULL, "vpn.strongswan.org", NULL, FALSE },
{ "strongswan.org", "strongswan.com", "strongswan.net", NULL, "vpn.strongswan.net", NULL, FALSE },
{ "strongswan.org", "email:strongswan.org", NULL, NULL, "vpn.strongswan.org", NULL, TRUE },
{ "strongswan.org", "email:strongswan.org", NULL, NULL, "[email protected]", NULL, TRUE },
{ "strongswan.org", "email:strongswan.org", NULL, NULL, "vpn.strongswan.org", "[email protected]", TRUE },
{ "strongswan.org", "email:strongswan.org", "strongswan.org", NULL, "vpn.strongswan.org", NULL, TRUE },
{ "strongswan.org", "email:strongswan.org", "strongswan.org", NULL, "[email protected]", NULL, TRUE },
{ "strongswan.org", "email:strongswan.org", "strongswan.org", NULL, "vpn.strongswan.org", "[email protected]", TRUE },
{ "strongswan.org", "email:strongswan.org", "strongswan.org", "email:strongswan.com", "vpn.strongswan.org", NULL, TRUE },
{ "strongswan.org", "email:strongswan.org", "strongswan.org", "email:strongswan.com", "[email protected]", NULL, FALSE },
{ "strongswan.org", "email:strongswan.org", "strongswan.org", "email:strongswan.com", "vpn.strongswan.org", "[email protected]", FALSE },
{ "strongswan.org", "email:strongswan.org", "email:strongswan.org", NULL, "vpn.strongswan.org", NULL, TRUE },
{ "strongswan.org", "email:strongswan.org", "email:strongswan.org", NULL, "[email protected]", NULL, TRUE },
{ "strongswan.org", "email:strongswan.org", "email:strongswan.org", NULL, "vpn.strongswan.org", "[email protected]", TRUE },
{ "strongswan.org", "email:strongswan.org", "email:strongswan.org", "strongswan.com", "vpn.strongswan.org", NULL, FALSE },
{ "strongswan.org", "email:strongswan.org", "email:strongswan.org", "strongswan.com", "[email protected]", NULL, TRUE },
{ "strongswan.org", "email:strongswan.org", "email:strongswan.org", "strongswan.com", "vpn.strongswan.org", "[email protected]", FALSE },
};
START_TEST(test_permitted_san_multi)
{
certificate_t *ca, *im, *sj;
ca = create_cert_multi(NULL, "CN=CA", X509_CA, NULL, NULL,
permitted_san_multi[_i].caconst1,
permitted_san_multi[_i].caconst2, NULL, NULL);
im = create_cert_multi(ca, "CN=IM", X509_CA, NULL, NULL,
permitted_san_multi[_i].imconst1,
permitted_san_multi[_i].imconst2, NULL, NULL);
sj = create_cert_multi(im, "CN=EE", 0,
permitted_san_multi[_i].san1,
permitted_san_multi[_i].san2, NULL, NULL, NULL, NULL);
creds->add_cert(creds, TRUE, ca);
creds->add_cert(creds, FALSE, im);
creds->add_cert(creds, FALSE, sj);
ck_assert(check_trust(sj->get_subject(sj)) == permitted_san_multi[_i].good);
}
END_TEST
static struct {
char *caconst1;
char *caconst2;
char *imconst1;
char *imconst2;
char *san1;
char *san2;
bool good;
} excluded_san_multi[] = {
{ "strongswan.org", "strongswan.com", NULL, NULL, "vpn.strongswan.org", NULL, FALSE },
{ "strongswan.org", "strongswan.com", NULL, NULL, "[email protected]", NULL, TRUE },
{ "strongswan.org", "strongswan.com", NULL, NULL, "vpn.strongswan.com", NULL, FALSE },
{ "strongswan.org", "strongswan.com", NULL, NULL, "vpn.strongswan.net", NULL, TRUE },
{ "strongswan.org", "strongswan.com", NULL, NULL, "vpn.strongswan.org", "vpn.strongswan.com", FALSE },
{ "strongswan.org", "strongswan.com", NULL, NULL, "vpn.strongswan.org", "vpn.strongswan.net", FALSE },
{ "strongswan.org", NULL, NULL, NULL, "vpn.strongswan.org", "vpn.strongswan.com", FALSE },
{ "strongswan.org", NULL, NULL, NULL, "vpn.strongswan.com", "vpn.strongswan.org", FALSE },
{ NULL, NULL, "strongswan.org", "strongswan.com", "vpn.strongswan.org", NULL, FALSE },
{ NULL, NULL, "strongswan.org", "strongswan.com", "vpn.strongswan.com", NULL, FALSE },
{ NULL, NULL, "strongswan.org", "strongswan.com", "vpn.strongswan.net", NULL, TRUE },
{ NULL, NULL, "strongswan.org", "strongswan.com", "vpn.strongswan.org", "vpn.strongswan.com", FALSE },
{ "strongswan.org", "strongswan.com", "strongswan.net", NULL, "vpn.strongswan.net", NULL, FALSE },
{ "strongswan.net", NULL, "strongswan.org", "strongswan.com", "vpn.strongswan.net", NULL, FALSE },
{ "strongswan.net", NULL, "strongswan.org", "strongswan.com", "vpn.strongswan.org", NULL, FALSE },
{ "strongswan.net", NULL, "strongswan.org", "strongswan.com", "vpn.strongswan.com", NULL, FALSE },
{ "vpn.strongswan.org", "vpn.strongswan.com", "strongswan.org", NULL, "a.strongswan.org", NULL, FALSE },
{ "vpn.strongswan.org", "vpn.strongswan.com", "strongswan.org", NULL, "vpn.strongswan.com", NULL, FALSE },
{ "vpn.strongswan.org", "vpn.strongswan.com", "strongswan.org", NULL, "a.strongswan.com", NULL, TRUE },
{ "vpn.strongswan.org", "vpn.strongswan.com", "strongswan.org", "strongswan.com", "a.strongswan.com", NULL, FALSE },
{ "strongswan.org", "email:strongswan.org", NULL, NULL, "vpn.strongswan.org", NULL, FALSE },
{ "strongswan.org", "email:strongswan.org", NULL, NULL, "[email protected]", NULL, FALSE },
};
START_TEST(test_excluded_san_multi)
{
certificate_t *ca, *im, *sj;
ca = create_cert_multi(NULL, "CN=CA", X509_CA, NULL, NULL, NULL, NULL,
excluded_san_multi[_i].caconst1,
excluded_san_multi[_i].caconst2);
im = create_cert_multi(ca, "CN=IM", X509_CA, NULL, NULL, NULL, NULL,
excluded_san_multi[_i].imconst1,
excluded_san_multi[_i].imconst2);
sj = create_cert_multi(im, "CN=EE", 0,
excluded_san_multi[_i].san1,
excluded_san_multi[_i].san2, NULL, NULL, NULL, NULL);
creds->add_cert(creds, TRUE, ca);
creds->add_cert(creds, FALSE, im);
creds->add_cert(creds, FALSE, sj);
ck_assert(check_trust(sj->get_subject(sj)) == excluded_san_multi[_i].good);
}
END_TEST
@@ -385,14 +688,34 @@ Suite *certnames_suite_create()
tcase_add_loop_test(tc, test_excluded_san, 0, countof(excluded_san));
suite_add_tcase(s, tc);
tc = tcase_create("permitted DN name constraint inherit");
tc = tcase_create("permitted DN name constraints multilevel");
tcase_add_checked_fixture(tc, setup, teardown);
tcase_add_loop_test(tc, test_permitted_dninh, 0, countof(permitted_dninh));
tcase_add_loop_test(tc, test_permitted_dn_levels, 0, countof(permitted_dn_levels));
suite_add_tcase(s, tc);
tc = tcase_create("excluded DN name constraint inherit");
tc = tcase_create("permitted subjectAltName constraints multilevel");
tcase_add_checked_fixture(tc, setup, teardown);
tcase_add_loop_test(tc, test_excluded_dninh, 0, countof(excluded_dninh));
tcase_add_loop_test(tc, test_permitted_san_levels, 0, countof(permitted_san_levels));
suite_add_tcase(s, tc);
tc = tcase_create("excluded DN name constraints multilevel");
tcase_add_checked_fixture(tc, setup, teardown);
tcase_add_loop_test(tc, test_excluded_dn_levels, 0, countof(excluded_dn_levels));
suite_add_tcase(s, tc);
tc = tcase_create("excluded subjectAltName constraints multilevel");
tcase_add_checked_fixture(tc, setup, teardown);
tcase_add_loop_test(tc, test_excluded_san_levels, 0, countof(excluded_san_levels));
suite_add_tcase(s, tc);
tc = tcase_create("permitted subjectAltName constraints multivalue");
tcase_add_checked_fixture(tc, setup, teardown);
tcase_add_loop_test(tc, test_permitted_san_multi, 0, countof(permitted_san_multi));
suite_add_tcase(s, tc);
tc = tcase_create("excluded subjectAltName constraints multivalue");
tcase_add_checked_fixture(tc, setup, teardown);
tcase_add_loop_test(tc, test_excluded_san_multi, 0, countof(excluded_san_multi));
suite_add_tcase(s, tc);
return s;