From f781b9d326c5e735eff1a542d470ceec67880d2a Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 17 Oct 2023 10:21:28 +0200 Subject: [PATCH] openssl: Add support for nameConstraints X.509 extension Closes strongswan/strongswan#1990 --- .../plugins/openssl/openssl_x509.c | 77 ++++++++++++++++++- 1 file changed, 75 insertions(+), 2 deletions(-) diff --git a/src/libstrongswan/plugins/openssl/openssl_x509.c b/src/libstrongswan/plugins/openssl/openssl_x509.c index 832cec4b47..f7bef0d031 100644 --- a/src/libstrongswan/plugins/openssl/openssl_x509.c +++ b/src/libstrongswan/plugins/openssl/openssl_x509.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2017 Tobias Brunner + * Copyright (C) 2011-2023 Tobias Brunner * Copyright (C) 2010 Martin Willi * * Copyright (C) secunet Security Networks AG @@ -181,6 +181,15 @@ struct private_openssl_x509_t { */ linked_list_t *ipAddrBlocks; + /** + * List of permitted name constraints + */ + linked_list_t *permitted_names; + + /** + * List of excluded name constraints + */ + linked_list_t *excluded_names; /** * References to this cert @@ -312,6 +321,16 @@ METHOD(x509_t, create_ipAddrBlock_enumerator, enumerator_t*, return this->ipAddrBlocks->create_enumerator(this->ipAddrBlocks); } +METHOD(x509_t, create_name_constraint_enumerator, enumerator_t*, + private_openssl_x509_t *this, bool perm) +{ + if (perm) + { + return this->permitted_names->create_enumerator(this->permitted_names); + } + return this->excluded_names->create_enumerator(this->excluded_names); +} + METHOD(certificate_t, get_type, certificate_type_t, private_openssl_x509_t *this) { @@ -564,6 +583,10 @@ METHOD(certificate_t, destroy, void, this->ocsp_uris->destroy_function(this->ocsp_uris, free); this->ipAddrBlocks->destroy_offset(this->ipAddrBlocks, offsetof(traffic_selector_t, destroy)); + this->permitted_names->destroy_offset(this->permitted_names, + offsetof(identification_t, destroy)); + this->excluded_names->destroy_offset(this->excluded_names, + offsetof(identification_t, destroy)); free(this); } } @@ -601,7 +624,7 @@ static private_openssl_x509_t *create_empty() .create_crl_uri_enumerator = _create_crl_uri_enumerator, .create_ocsp_uri_enumerator = _create_ocsp_uri_enumerator, .create_ipAddrBlock_enumerator = _create_ipAddrBlock_enumerator, - .create_name_constraint_enumerator = (void*)enumerator_create_empty, + .create_name_constraint_enumerator = _create_name_constraint_enumerator, .create_cert_policy_enumerator = (void*)enumerator_create_empty, .create_policy_mapping_enumerator = (void*)enumerator_create_empty, }, @@ -611,6 +634,8 @@ static private_openssl_x509_t *create_empty() .crl_uris = linked_list_create(), .ocsp_uris = linked_list_create(), .ipAddrBlocks = linked_list_create(), + .permitted_names = linked_list_create(), + .excluded_names = linked_list_create(), .pathlen = X509_NO_CONSTRAINT, .ref = 1, ); @@ -964,6 +989,51 @@ static bool parse_ipAddrBlock_ext(private_openssl_x509_t *this, } #endif /* !OPENSSL_NO_RFC3779 */ +/** + * Parse a "generalSubtree" structure (sequence of generalNames) + */ +static bool parse_generalSubtrees(linked_list_t *list, + STACK_OF(GENERAL_SUBTREE) *subtrees) +{ + GENERAL_SUBTREE *subtree; + identification_t *id; + int i; + + for (i = 0; i < sk_GENERAL_SUBTREE_num(subtrees); i++) + { + subtree = sk_GENERAL_SUBTREE_value(subtrees, i); + id = general_name2id(subtree->base); + if (id) + { + list->insert_last(list, id); + } + else + { + return FALSE; + } + } + return TRUE; +} + +/** + * Parse permitted/excluded nameConstraints + */ +static bool parse_nameConstraints_ext(private_openssl_x509_t *this, + X509_EXTENSION *ext) +{ + NAME_CONSTRAINTS *nc; + bool ok = FALSE; + + nc = (NAME_CONSTRAINTS*)X509V3_EXT_d2i(ext); + if (nc) + { + ok = parse_generalSubtrees(this->permitted_names, nc->permittedSubtrees) && + parse_generalSubtrees(this->excluded_names, nc->excludedSubtrees); + NAME_CONSTRAINTS_free(nc); + } + return ok; +} + /** * Parse authorityKeyIdentifier extension */ @@ -1059,6 +1129,9 @@ static bool parse_extensions(private_openssl_x509_t *this) ok = parse_ipAddrBlock_ext(this, ext); break; #endif /* !OPENSSL_NO_RFC3779 */ + case NID_name_constraints: + ok = parse_nameConstraints_ext(this, ext); + break; default: ok = X509_EXTENSION_get_critical(ext) == 0 || !lib->settings->get_bool(lib->settings, -- 2.47.2