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:
@@ -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
|
||||
|
||||
@@ -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, ¤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;
|
||||
}
|
||||
@@ -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_ @}*/
|
||||
Reference in New Issue
Block a user