From ae06cfad36d56d4529e3a395662cfc5d9eead438 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Thu, 31 Oct 2019 09:27:49 +0100 Subject: [PATCH] ike-cert-post: Generate URL for hash-and-URL here This avoids having to register certificates with authority/ca backends beforehand, which is tricky for intermediate CA certificates loaded themselves via authority/ca sections. On the other hand, the form of these URLs can't be determined by config backends anymore (not an issue for the two current implementations, no idea if custom implementations ever made use of that possibility). If that became necessary, we could perhaps pass the certificate to the CDP enumerator or add a new method to the credential_set_t interface. --- src/libcharon/plugins/stroke/stroke_ca.c | 24 ++---- src/libcharon/plugins/vici/vici_authority.c | 24 ++---- src/libcharon/sa/ikev2/tasks/ike_cert_post.c | 87 +++++++++++--------- 3 files changed, 60 insertions(+), 75 deletions(-) diff --git a/src/libcharon/plugins/stroke/stroke_ca.c b/src/libcharon/plugins/stroke/stroke_ca.c index 2c0df8fb2..f728284d9 100644 --- a/src/libcharon/plugins/stroke/stroke_ca.c +++ b/src/libcharon/plugins/stroke/stroke_ca.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2015 Tobias Brunner + * Copyright (C) 2008-2019 Tobias Brunner * Copyright (C) 2008 Martin Willi * HSR Hochschule fuer Technik Rapperswil * @@ -308,32 +308,18 @@ static enumerator_t *create_inner_cdp(ca_section_t *section, cdp_data_t *data) */ static enumerator_t *create_inner_cdp_hashandurl(ca_section_t *section, cdp_data_t *data) { - enumerator_t *enumerator = NULL, *hash_enum; - identification_t *current; + enumerator_t *enumerator = NULL; if (!data->id || !section->certuribase) { return NULL; } - hash_enum = section->hashes->create_enumerator(section->hashes); - while (hash_enum->enumerate(hash_enum, ¤t)) + if (section->cert->has_subject(section->cert, data->id) != ID_MATCH_NONE) { - if (current->matches(current, data->id)) - { - char *url, *hash; - - url = malloc(strlen(section->certuribase) + 40 + 1); - strcpy(url, section->certuribase); - hash = chunk_to_hex(current->get_encoding(current), NULL, FALSE).ptr; - strncat(url, hash, 40); - free(hash); - - enumerator = enumerator_create_single(url, free); - break; - } + enumerator = enumerator_create_single(strdup(section->certuribase), + free); } - hash_enum->destroy(hash_enum); return enumerator; } diff --git a/src/libcharon/plugins/vici/vici_authority.c b/src/libcharon/plugins/vici/vici_authority.c index 0fa158b32..bac3eb388 100644 --- a/src/libcharon/plugins/vici/vici_authority.c +++ b/src/libcharon/plugins/vici/vici_authority.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Tobias Brunner + * Copyright (C) 2016-2019 Tobias Brunner * Copyright (C) 2015 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * @@ -694,32 +694,18 @@ static enumerator_t *create_inner_cdp(authority_t *authority, cdp_data_t *data) static enumerator_t *create_inner_cdp_hashandurl(authority_t *authority, cdp_data_t *data) { - enumerator_t *enumerator = NULL, *hash_enum; - identification_t *current; + enumerator_t *enumerator = NULL; if (!data->id || !authority->cert_uri_base) { return NULL; } - hash_enum = authority->hashes->create_enumerator(authority->hashes); - while (hash_enum->enumerate(hash_enum, ¤t)) + if (authority->cert->has_subject(authority->cert, data->id) != ID_MATCH_NONE) { - if (current->matches(current, data->id)) - { - char *url, *hash; - - url = malloc(strlen(authority->cert_uri_base) + 40 + 1); - strcpy(url, authority->cert_uri_base); - hash = chunk_to_hex(current->get_encoding(current), NULL, FALSE).ptr; - strncat(url, hash, 40); - free(hash); - - enumerator = enumerator_create_single(url, free); - break; - } + enumerator = enumerator_create_single(strdup(authority->cert_uri_base), + free); } - hash_enum->destroy(hash_enum); return enumerator; } diff --git a/src/libcharon/sa/ikev2/tasks/ike_cert_post.c b/src/libcharon/sa/ikev2/tasks/ike_cert_post.c index 68af6e35b..265500333 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_cert_post.c +++ b/src/libcharon/sa/ikev2/tasks/ike_cert_post.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Tobias Brunner + * Copyright (C) 2008-2019 Tobias Brunner * Copyright (C) 2006-2009 Martin Willi * HSR Hochschule fuer Technik Rapperswil * @@ -48,17 +48,58 @@ struct private_ike_cert_post_t { bool initiator; }; +/** + * Generate the payload for a hash-and-URL encoded certificate + */ +static bool build_hash_url_payload(char *base, certificate_t *cert, + cert_payload_t **payload) +{ + hasher_t *hasher; + chunk_t hash, encoded; + char *url, *hex_hash; + + hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); + if (!hasher) + { + DBG1(DBG_IKE, "unable to use hash-and-url: SHA-1 not supported"); + return FALSE; + } + + if (!cert->get_encoding(cert, CERT_ASN1_DER, &encoded)) + { + hasher->destroy(hasher); + return FALSE; + } + if (!hasher->allocate_hash(hasher, encoded, &hash)) + { + hasher->destroy(hasher); + chunk_free(&encoded); + return FALSE; + } + chunk_free(&encoded); + hasher->destroy(hasher); + + url = malloc(strlen(base) + 40 + 1); + strcpy(url, base); + hex_hash = chunk_to_hex(hash, NULL, FALSE).ptr; + strncat(url, hex_hash, 40); + free(hex_hash); + + DBG1(DBG_IKE, "sending hash-and-url \"%s\"", url); + *payload = cert_payload_create_from_hash_and_url(hash, url); + chunk_free(&hash); + free(url); + return TRUE; +} + /** * Generates the cert payload, if possible with "Hash and URL" */ static cert_payload_t *build_cert_payload(private_ike_cert_post_t *this, certificate_t *cert) { - hasher_t *hasher; - identification_t *id; - chunk_t hash, encoded ; enumerator_t *enumerator; - char *url; + char *base; cert_payload_t *payload = NULL; if (!this->ike_sa->supports_extension(this->ike_sa, EXT_HASH_AND_URL)) @@ -66,42 +107,14 @@ static cert_payload_t *build_cert_payload(private_ike_cert_post_t *this, return cert_payload_create_from_cert(PLV2_CERTIFICATE, cert); } - hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); - if (!hasher) - { - DBG1(DBG_IKE, "unable to use hash-and-url: sha1 not supported"); - return cert_payload_create_from_cert(PLV2_CERTIFICATE, cert); - } - - if (!cert->get_encoding(cert, CERT_ASN1_DER, &encoded)) - { - DBG1(DBG_IKE, "encoding certificate for cert payload failed"); - hasher->destroy(hasher); - return NULL; - } - if (!hasher->allocate_hash(hasher, encoded, &hash)) - { - hasher->destroy(hasher); - chunk_free(&encoded); - return cert_payload_create_from_cert(PLV2_CERTIFICATE, cert); - } - chunk_free(&encoded); - hasher->destroy(hasher); - id = identification_create_from_encoding(ID_KEY_ID, hash); - - enumerator = lib->credmgr->create_cdp_enumerator(lib->credmgr, CERT_X509, id); - if (enumerator->enumerate(enumerator, &url)) - { - payload = cert_payload_create_from_hash_and_url(hash, url); - DBG1(DBG_IKE, "sending hash-and-url \"%s\"", url); - } - else + enumerator = lib->credmgr->create_cdp_enumerator(lib->credmgr, CERT_X509, + cert->get_issuer(cert)); + if (!enumerator->enumerate(enumerator, &base) || + !build_hash_url_payload(base, cert, &payload)) { payload = cert_payload_create_from_cert(PLV2_CERTIFICATE, cert); } enumerator->destroy(enumerator); - chunk_free(&hash); - id->destroy(id); return payload; }