diff --git a/src/libcharon/plugins/stroke/stroke_ca.c b/src/libcharon/plugins/stroke/stroke_ca.c index bfaa9a9d9..0dbe70745 100644 --- a/src/libcharon/plugins/stroke/stroke_ca.c +++ b/src/libcharon/plugins/stroke/stroke_ca.c @@ -175,46 +175,15 @@ CALLBACK(certs_filter, bool, cert_data_t *data, enumerator_t *orig, va_list args) { ca_cert_t *cacert; - public_key_t *public; certificate_t **out; VA_ARGS_VGET(args, out); while (orig->enumerate(orig, &cacert)) { - certificate_t *cert = cacert->cert; - - if (data->cert != CERT_ANY && data->cert != cert->get_type(cert)) + if (certificate_matches(cacert->cert, data->cert, data->key, data->id)) { - continue; - } - public = cert->get_public_key(cert); - if (public) - { - if (data->key == KEY_ANY || data->key == public->get_type(public)) - { - if (data->id && public->has_fingerprint(public, - data->id->get_encoding(data->id))) - { - public->destroy(public); - *out = cert; - return TRUE; - } - } - else - { - public->destroy(public); - continue; - } - public->destroy(public); - } - else if (data->key != KEY_ANY) - { - continue; - } - if (!data->id || cert->has_subject(cert, data->id)) - { - *out = cert; + *out = cacert->cert; return TRUE; } } diff --git a/src/libstrongswan/credentials/certificates/certificate.c b/src/libstrongswan/credentials/certificates/certificate.c index 761082986..d8e2223b7 100644 --- a/src/libstrongswan/credentials/certificates/certificate.c +++ b/src/libstrongswan/credentials/certificates/certificate.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2020 Tobias Brunner * Copyright (C) 2007 Martin Willi * Copyright (C) 2015 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil @@ -61,3 +62,40 @@ bool certificate_is_newer(certificate_t *this, certificate_t *other) type, &that_update, FALSE, newer ? "replaced" : "retained"); return newer; } + +/* + * Described in header + */ +bool certificate_matches(certificate_t *cert, certificate_type_t type, + key_type_t key, identification_t *id) +{ + public_key_t *public; + + if (type != CERT_ANY && type != cert->get_type(cert)) + { + return FALSE; + } + public = cert->get_public_key(cert); + if (public) + { + if (key == KEY_ANY || key == public->get_type(public)) + { + if (id && public->has_fingerprint(public, id->get_encoding(id))) + { + public->destroy(public); + return TRUE; + } + } + else + { + public->destroy(public); + return FALSE; + } + public->destroy(public); + } + else if (key != KEY_ANY) + { + return FALSE; + } + return !id || cert->has_subject(cert, id); +} diff --git a/src/libstrongswan/credentials/certificates/certificate.h b/src/libstrongswan/credentials/certificates/certificate.h index 71620aa91..cf2f2ae69 100644 --- a/src/libstrongswan/credentials/certificates/certificate.h +++ b/src/libstrongswan/credentials/certificates/certificate.h @@ -1,4 +1,5 @@ /* + * Copyright (C) 2020 Tobias Brunner * Copyright (C) 2007-2008 Martin Willi * HSR Hochschule fuer Technik Rapperswil * @@ -204,4 +205,18 @@ struct certificate_t { */ bool certificate_is_newer(certificate_t *cert, certificate_t *other); +/** + * Check if the given certificate matches the given type, key type and identity, + * all of which are optional. + * + * Note that the identity may also be a public key fingerprint. + * + * @param cert certificate + * @param type certificate type to match, or CERT_ANY + * @param key key type to match, or KEY_ANY + * @param id identity to match, or NULL + */ +bool certificate_matches(certificate_t *cert, certificate_type_t type, + key_type_t key, identification_t *id); + #endif /** CERTIFICATE_H_ @}*/ diff --git a/src/libstrongswan/credentials/sets/mem_cred.c b/src/libstrongswan/credentials/sets/mem_cred.c index 86b232a3e..0a4d512d2 100644 --- a/src/libstrongswan/credentials/sets/mem_cred.c +++ b/src/libstrongswan/credentials/sets/mem_cred.c @@ -84,42 +84,13 @@ CALLBACK(cert_data_destroy, void, CALLBACK(certs_filter, bool, cert_data_t *data, enumerator_t *orig, va_list args) { - public_key_t *public; certificate_t *cert, **out; VA_ARGS_VGET(args, out); while (orig->enumerate(orig, &cert)) { - if (data->cert != CERT_ANY && data->cert != cert->get_type(cert)) - { - continue; - } - public = cert->get_public_key(cert); - if (public) - { - if (data->key == KEY_ANY || data->key == public->get_type(public)) - { - if (data->id && public->has_fingerprint(public, - data->id->get_encoding(data->id))) - { - public->destroy(public); - *out = cert; - return TRUE; - } - } - else - { - public->destroy(public); - continue; - } - public->destroy(public); - } - else if (data->key != KEY_ANY) - { - continue; - } - if (!data->id || cert->has_subject(cert, data->id)) + if (certificate_matches(cert, data->cert, data->key, data->id)) { *out = cert; return TRUE;