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.
This commit is contained in:
Tobias Brunner 2023-10-30 17:34:51 +01:00
parent 3197523bd5
commit dab7c893a6
7 changed files with 214 additions and 8 deletions

View File

@ -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 \

View File

@ -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 \

View File

@ -22,10 +22,10 @@
#ifndef OCSP_RESPONDER_H_
#define OCSP_RESPONDER_H_
#include <credentials/certificates/crl.h>
typedef struct ocsp_responder_t ocsp_responder_t;
#include <credentials/certificates/crl.h>
/**
* 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

View File

@ -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 <http://www.fsf.org/copyleft/gpl.txt>.
*
* 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 <collections/linked_list.h>
#include <threading/rwlock.h>
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, &current))
{
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;
}

View File

@ -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 <http://www.fsf.org/copyleft/gpl.txt>.
*
* 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 <credentials/certificates/ocsp_responder.h>
/**
* 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_ @}*/

View File

@ -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();

View File

@ -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
*/