From: Tobias Brunner Date: Mon, 30 Oct 2023 16:34:51 +0000 (+0100) Subject: library: Add manager for OCSP responders X-Git-Tag: 5.9.12rc1~2^2~9 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dab7c893a600cdb8526f852ee1d13108b4fc037d;p=thirdparty%2Fstrongswan.git library: Add manager for OCSP responders Registered OCSP responders should return VALIDATION_SKIPPED for issuer certificates they are not responsible for. However, VALIDATION_FAILED is currently treated the same way, so that's fine as well. --- diff --git a/src/libstrongswan/Android.mk b/src/libstrongswan/Android.mk index 3ce05d9319..1f2d0af521 100644 --- a/src/libstrongswan/Android.mk +++ b/src/libstrongswan/Android.mk @@ -28,7 +28,7 @@ credentials/certificates/ocsp_response.c credentials/certificates/x509.c \ credentials/certificates/ocsp_single_response.c \ credentials/certificates/certificate_printer.c \ credentials/containers/container.c credentials/containers/pkcs12.c \ -credentials/credential_manager.c \ +credentials/credential_manager.c credentials/ocsp_responders.c \ credentials/sets/auth_cfg_wrapper.c credentials/sets/ocsp_response_wrapper.c \ credentials/sets/cert_cache.c credentials/sets/mem_cred.c \ credentials/sets/callback_cred.c credentials/auth_cfg.c database/database.c \ diff --git a/src/libstrongswan/Makefile.am b/src/libstrongswan/Makefile.am index cc00d43f75..0597afad96 100644 --- a/src/libstrongswan/Makefile.am +++ b/src/libstrongswan/Makefile.am @@ -26,7 +26,7 @@ credentials/certificates/ocsp_response.c credentials/certificates/x509.c \ credentials/certificates/ocsp_single_response.c \ credentials/certificates/certificate_printer.c \ credentials/containers/container.c credentials/containers/pkcs12.c \ -credentials/credential_manager.c \ +credentials/credential_manager.c credentials/ocsp_responders.c \ credentials/sets/auth_cfg_wrapper.c credentials/sets/ocsp_response_wrapper.c \ credentials/sets/cert_cache.c credentials/sets/mem_cred.c \ credentials/sets/callback_cred.c credentials/auth_cfg.c database/database.c \ @@ -99,10 +99,11 @@ credentials/certificates/pgp_certificate.h \ credentials/certificates/certificate_printer.h \ credentials/containers/container.h credentials/containers/pkcs7.h \ credentials/containers/pkcs12.h \ -credentials/credential_manager.h credentials/sets/auth_cfg_wrapper.h \ -credentials/sets/ocsp_response_wrapper.h credentials/sets/cert_cache.h \ -credentials/sets/mem_cred.h credentials/sets/callback_cred.h \ -credentials/auth_cfg.h credentials/credential_set.h credentials/cert_validator.h \ +credentials/credential_manager.h credentials/ocsp_responders.h \ +credentials/sets/auth_cfg_wrapper.h credentials/sets/ocsp_response_wrapper.h \ +credentials/sets/cert_cache.h credentials/sets/mem_cred.h \ +credentials/sets/callback_cred.h credentials/auth_cfg.h \ +credentials/credential_set.h credentials/cert_validator.h \ database/database.h database/database_factory.h fetcher/fetcher.h \ fetcher/fetcher_manager.h eap/eap.h pen/pen.h ipsec/ipsec_types.h \ metadata/metadata.h metadata/metadata_factory.h metadata/metadata_int.h \ diff --git a/src/libstrongswan/credentials/certificates/ocsp_responder.h b/src/libstrongswan/credentials/certificates/ocsp_responder.h index e7644dda9e..57896ace1b 100644 --- a/src/libstrongswan/credentials/certificates/ocsp_responder.h +++ b/src/libstrongswan/credentials/certificates/ocsp_responder.h @@ -22,10 +22,10 @@ #ifndef OCSP_RESPONDER_H_ #define OCSP_RESPONDER_H_ -#include - typedef struct ocsp_responder_t ocsp_responder_t; +#include + /** * OCSP responder object. */ @@ -34,6 +34,8 @@ struct ocsp_responder_t { /** * Check the status of a certificate given by its serial number * + * @note Return VALIDATION_SKIPPED if not responsible for the given CA + * * @param cacert X.509 certificate of issuer CA * @param serial_number serial number of the certificate to be checked * @param revocation_time receives time of revocation, if revoked diff --git a/src/libstrongswan/credentials/ocsp_responders.c b/src/libstrongswan/credentials/ocsp_responders.c new file mode 100644 index 0000000000..8eca73c926 --- /dev/null +++ b/src/libstrongswan/credentials/ocsp_responders.c @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2023 Tobias Brunner + * + * Copyright (C) secunet Security Networks AG + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "ocsp_responders.h" + +#include +#include + +typedef struct private_ocsp_responders_t private_ocsp_responders_t; + +/** + * Private data + */ +struct private_ocsp_responders_t { + + /** + * Public interface + */ + ocsp_responders_t public; + + /** + * List of registered OCSP responders + */ + linked_list_t *responders; + + /** + * Lock to access responder list + */ + rwlock_t *lock; +}; + +METHOD(ocsp_responders_t, get_status, cert_validation_t, + private_ocsp_responders_t *this, certificate_t *cacert, + chunk_t serial_number, time_t *revocation_time, + crl_reason_t *revocation_reason) +{ + enumerator_t *enumerator; + ocsp_responder_t *current; + cert_validation_t validation = VALIDATION_SKIPPED; + + this->lock->read_lock(this->lock); + enumerator = this->responders->create_enumerator(this->responders); + while (enumerator->enumerate(enumerator, ¤t)) + { + validation = current->get_status(current, cacert, serial_number, + revocation_time, revocation_reason); + if (validation != VALIDATION_SKIPPED && + validation != VALIDATION_FAILED) + { + break; + } + } + enumerator->destroy(enumerator); + this->lock->unlock(this->lock); + + if (validation == VALIDATION_SKIPPED) + { + validation = VALIDATION_FAILED; + } + return validation; +} + +METHOD(ocsp_responders_t, add_responder, void, + private_ocsp_responders_t *this, ocsp_responder_t *responder) +{ + this->lock->write_lock(this->lock); + this->responders->insert_last(this->responders, responder); + this->lock->unlock(this->lock); +} + +METHOD(ocsp_responders_t, remove_responder, void, + private_ocsp_responders_t *this, ocsp_responder_t *responder) +{ + this->lock->write_lock(this->lock); + this->responders->remove(this->responders, responder, NULL); + this->lock->unlock(this->lock); +} + +METHOD(ocsp_responders_t, destroy, void, + private_ocsp_responders_t *this) +{ + this->responders->destroy(this->responders); + this->lock->destroy(this->lock); + free(this); +} + +/* + * Described in header + */ +ocsp_responders_t *ocsp_responders_create() +{ + private_ocsp_responders_t *this; + + INIT(this, + .public = { + .get_status = _get_status, + .add_responder = _add_responder, + .remove_responder = _remove_responder, + .destroy = _destroy, + }, + .responders = linked_list_create(), + .lock = rwlock_create(RWLOCK_TYPE_DEFAULT), + ); + + return &this->public; +} diff --git a/src/libstrongswan/credentials/ocsp_responders.h b/src/libstrongswan/credentials/ocsp_responders.h new file mode 100644 index 0000000000..d4ce331a67 --- /dev/null +++ b/src/libstrongswan/credentials/ocsp_responders.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2023 Tobias Brunner + * + * Copyright (C) secunet Security Networks AG + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup ocsp_responders ocsp_responders + * @{ @ingroup credentials + */ + +#ifndef OCSP_RESPONDERS_H_ +#define OCSP_RESPONDERS_H_ + +typedef struct ocsp_responders_t ocsp_responders_t; + +#include + +/** + * Manages OCSP responders. + */ +struct ocsp_responders_t { + + /** + * Check the status of a certificate given by its serial number + * + * @param cacert X.509 certificate of issuer CA + * @param serial_number serial number of the certificate to be checked + * @param revocation_time receives time of revocation, if revoked + * @param reason receives reason of revocation, if revoked + * @return certificate validation status + */ + cert_validation_t (*get_status)(ocsp_responders_t *this, + certificate_t *cacert, + chunk_t serial_number, + time_t *revocation_time, + crl_reason_t *revocation_reason); + + /** + * Register an OCSP responder with this manager. + * + * @param responder OCSP responder to register + */ + void (*add_responder)(ocsp_responders_t *this, + ocsp_responder_t *responder); + + /** + * Unregister an OCSP responder from this manager. + * + * @param responder OCSP responder to unregister + */ + void (*remove_responder)(ocsp_responders_t *this, + ocsp_responder_t *responder); + + /** + * Destroy a ocsp_responders_t instance. + */ + void (*destroy)(ocsp_responders_t *this); +}; + +/** + * Create a ocsp_responders_t instance. + */ +ocsp_responders_t *ocsp_responders_create(); + +#endif /** OCSP_RESPONDERS_H_ @}*/ diff --git a/src/libstrongswan/library.c b/src/libstrongswan/library.c index f2ece6ca98..c65b381547 100644 --- a/src/libstrongswan/library.c +++ b/src/libstrongswan/library.c @@ -171,6 +171,7 @@ void library_deinit() this->public.credmgr->destroy(this->public.credmgr); this->public.creds->destroy(this->public.creds); this->public.encoding->destroy(this->public.encoding); + this->public.ocsp->destroy(this->public.ocsp); this->public.metadata->destroy(this->public.metadata); this->public.crypto->destroy(this->public.crypto); this->public.caps->destroy(this->public.caps); @@ -401,6 +402,7 @@ bool library_init(char *settings, const char *namespace) this->public.creds = credential_factory_create(); this->public.credmgr = credential_manager_create(); this->public.encoding = cred_encoding_create(); + this->public.ocsp = ocsp_responders_create(); this->public.metadata = metadata_factory_create(); this->public.fetcher = fetcher_manager_create(); this->public.resolver = resolver_manager_create(); diff --git a/src/libstrongswan/library.h b/src/libstrongswan/library.h index 9b8a26c1c2..20c30bdac8 100644 --- a/src/libstrongswan/library.h +++ b/src/libstrongswan/library.h @@ -113,6 +113,7 @@ #include "credentials/credential_factory.h" #include "credentials/credential_manager.h" #include "credentials/cred_encoding.h" +#include "credentials/ocsp_responders.h" #include "metadata/metadata_factory.h" #include "utils/chunk.h" #include "utils/capabilities.h" @@ -191,6 +192,11 @@ struct library_t { */ cred_encoding_t *encoding; + /** + * Manager for OCSP responders + */ + ocsp_responders_t *ocsp; + /** * Registry and factory for metadata creation */