caching of ocsp responses (experimental), no crl caching yet
This commit is contained in:
@@ -714,8 +714,7 @@ static id_match_t has_issuer(private_x509_ac_t *this, identification_t *issuer)
|
||||
/**
|
||||
* Implementation of certificate_t.issued_by
|
||||
*/
|
||||
static bool issued_by(private_x509_ac_t *this, certificate_t *issuer,
|
||||
bool sigcheck)
|
||||
static bool issued_by(private_x509_ac_t *this, certificate_t *issuer)
|
||||
{
|
||||
public_key_t *key;
|
||||
signature_scheme_t scheme;
|
||||
@@ -753,11 +752,6 @@ static bool issued_by(private_x509_ac_t *this, certificate_t *issuer,
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sigcheck)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
/* TODO: generic OID to scheme mapper? */
|
||||
switch (this->algorithm)
|
||||
{
|
||||
@@ -912,7 +906,7 @@ static private_x509_ac_t *create_empty(void)
|
||||
this->public.interface.certificate.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
|
||||
this->public.interface.certificate.has_subject = (id_match_t(*)(certificate_t*, identification_t *subject))has_subject;
|
||||
this->public.interface.certificate.has_issuer = (id_match_t(*)(certificate_t*, identification_t *issuer))has_issuer;
|
||||
this->public.interface.certificate.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer,bool))issued_by;
|
||||
this->public.interface.certificate.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer))issued_by;
|
||||
this->public.interface.certificate.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
|
||||
this->public.interface.certificate.get_validity = (bool(*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
|
||||
this->public.interface.certificate.is_newer = (bool (*)(certificate_t*,certificate_t*))is_newer;
|
||||
|
||||
@@ -932,8 +932,7 @@ static id_match_t has_issuer(private_x509_cert_t *this, identification_t *issuer
|
||||
/**
|
||||
* Implementation of certificate_t.issued_by
|
||||
*/
|
||||
static bool issued_by(private_x509_cert_t *this, certificate_t *issuer,
|
||||
bool sigcheck)
|
||||
static bool issued_by(private_x509_cert_t *this, certificate_t *issuer)
|
||||
{
|
||||
public_key_t *key;
|
||||
signature_scheme_t scheme;
|
||||
@@ -962,10 +961,6 @@ static bool issued_by(private_x509_cert_t *this, certificate_t *issuer,
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (!sigcheck)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
/* TODO: generic OID to scheme mapper? */
|
||||
switch (this->algorithm)
|
||||
{
|
||||
@@ -1174,7 +1169,7 @@ static private_x509_cert_t* create_empty(void)
|
||||
this->public.interface.interface.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
|
||||
this->public.interface.interface.has_subject = (id_match_t (*)(certificate_t*, identification_t *subject))has_subject;
|
||||
this->public.interface.interface.has_issuer = (id_match_t (*)(certificate_t*, identification_t *issuer))has_issuer;
|
||||
this->public.interface.interface.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer,bool))issued_by;
|
||||
this->public.interface.interface.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer))issued_by;
|
||||
this->public.interface.interface.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
|
||||
this->public.interface.interface.get_validity = (bool (*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
|
||||
this->public.interface.interface.is_newer = (bool (*)(certificate_t*,certificate_t*))is_newer;
|
||||
@@ -1220,7 +1215,7 @@ static private_x509_cert_t *create_from_chunk(chunk_t chunk)
|
||||
}
|
||||
|
||||
/* check if the certificate is self-signed */
|
||||
if (issued_by(this, &this->public.interface.interface, TRUE))
|
||||
if (issued_by(this, &this->public.interface.interface))
|
||||
{
|
||||
this->flags |= X509_SELF_SIGNED;
|
||||
}
|
||||
|
||||
@@ -362,15 +362,7 @@ static certificate_type_t get_type(private_x509_crl_t *this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of certificate_t.get_subject
|
||||
*/
|
||||
static identification_t* get_subject(private_x509_crl_t *this)
|
||||
{
|
||||
return this->issuer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of certificate_t.get_issuer
|
||||
* Implementation of certificate_t.get_issuer and get_subject
|
||||
*/
|
||||
static identification_t* get_issuer(private_x509_crl_t *this)
|
||||
{
|
||||
@@ -378,15 +370,7 @@ static identification_t* get_issuer(private_x509_crl_t *this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of certificate_t.has_subject.
|
||||
*/
|
||||
static id_match_t has_subject(private_x509_crl_t *this, identification_t *subject)
|
||||
{
|
||||
return ID_MATCH_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of certificate_t.has_issuer.
|
||||
* Implementation of certificate_t.has_subject and has_issuer.
|
||||
*/
|
||||
static id_match_t has_issuer(private_x509_crl_t *this, identification_t *issuer)
|
||||
{
|
||||
@@ -413,8 +397,7 @@ static id_match_t has_issuer(private_x509_crl_t *this, identification_t *issuer)
|
||||
/**
|
||||
* Implementation of certificate_t.issued_by
|
||||
*/
|
||||
static bool issued_by(private_x509_crl_t *this, certificate_t *issuer,
|
||||
bool sigcheck)
|
||||
static bool issued_by(private_x509_crl_t *this, certificate_t *issuer)
|
||||
{
|
||||
public_key_t *key;
|
||||
signature_scheme_t scheme;
|
||||
@@ -452,11 +435,6 @@ static bool issued_by(private_x509_crl_t *this, certificate_t *issuer,
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sigcheck)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
/* TODO: generic OID to scheme mapper? */
|
||||
switch (this->algorithm)
|
||||
{
|
||||
@@ -616,11 +594,11 @@ static private_x509_crl_t* create_empty(void)
|
||||
this->public.crl.get_authKeyIdentifier = (identification_t* (*)(crl_t*))get_authKeyIdentifier;
|
||||
this->public.crl.create_enumerator = (enumerator_t* (*)(crl_t*))create_enumerator;
|
||||
this->public.crl.certificate.get_type = (certificate_type_t (*)(certificate_t *this))get_type;
|
||||
this->public.crl.certificate.get_subject = (identification_t* (*)(certificate_t *this))get_subject;
|
||||
this->public.crl.certificate.get_subject = (identification_t* (*)(certificate_t *this))get_issuer;
|
||||
this->public.crl.certificate.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
|
||||
this->public.crl.certificate.has_subject = (id_match_t (*)(certificate_t*, identification_t *subject))has_subject;
|
||||
this->public.crl.certificate.has_subject = (id_match_t (*)(certificate_t*, identification_t *subject))has_issuer;
|
||||
this->public.crl.certificate.has_issuer = (id_match_t (*)(certificate_t*, identification_t *issuer))has_issuer;
|
||||
this->public.crl.certificate.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer,bool))issued_by;
|
||||
this->public.crl.certificate.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer))issued_by;
|
||||
this->public.crl.certificate.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
|
||||
this->public.crl.certificate.get_validity = (bool (*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
|
||||
this->public.crl.certificate.is_newer = (bool (*)(certificate_t*,certificate_t*))is_newer;
|
||||
|
||||
@@ -378,8 +378,7 @@ static id_match_t has_issuer(private_x509_ocsp_request_t *this,
|
||||
/**
|
||||
* Implementation of certificate_t.issued_by
|
||||
*/
|
||||
static bool issued_by(private_x509_ocsp_request_t *this, certificate_t *issuer,
|
||||
bool sigcheck)
|
||||
static bool issued_by(private_x509_ocsp_request_t *this, certificate_t *issuer)
|
||||
{
|
||||
DBG1("OCSP request validation not implemented!");
|
||||
return FALSE;
|
||||
@@ -482,7 +481,7 @@ static private_x509_ocsp_request_t *create_empty()
|
||||
this->public.interface.interface.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
|
||||
this->public.interface.interface.has_subject = (id_match_t(*)(certificate_t*, identification_t *subject))has_subject;
|
||||
this->public.interface.interface.has_issuer = (id_match_t(*)(certificate_t*, identification_t *issuer))has_issuer;
|
||||
this->public.interface.interface.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer,bool))issued_by;
|
||||
this->public.interface.interface.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer))issued_by;
|
||||
this->public.interface.interface.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
|
||||
this->public.interface.interface.get_validity = (bool(*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
|
||||
this->public.interface.interface.get_encoding = (chunk_t(*)(certificate_t*))get_encoding;
|
||||
|
||||
@@ -31,6 +31,11 @@
|
||||
#include <credentials/certificates/x509.h>
|
||||
#include <credentials/certificates/crl.h>
|
||||
|
||||
/**
|
||||
* how long do we use an OCSP response without a nextUpdate
|
||||
*/
|
||||
#define OCSP_DEFAULT_LIFETIME 30
|
||||
|
||||
typedef struct private_x509_ocsp_response_t private_x509_ocsp_response_t;
|
||||
|
||||
/**
|
||||
@@ -58,10 +63,7 @@ struct private_x509_ocsp_response_t {
|
||||
int signatureAlgorithm;
|
||||
|
||||
/**
|
||||
* signature enumerator = this->responses->create_enumerator(this->responses);
|
||||
while (enumerator->enumerate(enumerator, &response))
|
||||
{
|
||||
value
|
||||
* signature
|
||||
*/
|
||||
chunk_t signature;
|
||||
|
||||
@@ -75,6 +77,11 @@ struct private_x509_ocsp_response_t {
|
||||
*/
|
||||
time_t producedAt;
|
||||
|
||||
/**
|
||||
* latest nextUpdate in this OCSP response
|
||||
*/
|
||||
time_t usableUntil;
|
||||
|
||||
/**
|
||||
* list of included certificates
|
||||
*/
|
||||
@@ -382,8 +389,9 @@ static bool parse_singleResponse(private_x509_ocsp_response_t *this,
|
||||
response->status = VALIDATION_FAILED;
|
||||
response->revocationTime = 0;
|
||||
response->revocationReason = CRL_UNSPECIFIED;
|
||||
response->thisUpdate = 0;
|
||||
response->nextUpdate = 0;
|
||||
response->thisUpdate = UNDEFINED_TIME;
|
||||
/* if nextUpdate is missing, we give it a short lifetime */
|
||||
response->nextUpdate = this->producedAt + OCSP_DEFAULT_LIFETIME;
|
||||
|
||||
asn1_init(&ctx, blob, level0, FALSE, FALSE);
|
||||
while (objectID < SINGLE_RESPONSE_ROOF)
|
||||
@@ -423,17 +431,25 @@ static bool parse_singleResponse(private_x509_ocsp_response_t *this,
|
||||
}
|
||||
break;
|
||||
case SINGLE_RESPONSE_CERT_STATUS_UNKNOWN:
|
||||
response->status = VALIDATION_UNKNOWN;
|
||||
response->status = VALIDATION_FAILED;
|
||||
break;
|
||||
case SINGLE_RESPONSE_THIS_UPDATE:
|
||||
response->thisUpdate = asn1totime(&object, ASN1_GENERALIZEDTIME);
|
||||
break;
|
||||
case SINGLE_RESPONSE_NEXT_UPDATE:
|
||||
response->nextUpdate = asn1totime(&object, ASN1_GENERALIZEDTIME);
|
||||
if (response->nextUpdate > this->usableUntil)
|
||||
{
|
||||
this->usableUntil = response->nextUpdate;
|
||||
}
|
||||
break;
|
||||
}
|
||||
objectID++;
|
||||
}
|
||||
if (this->usableUntil == UNDEFINED_TIME)
|
||||
{
|
||||
this->usableUntil = this->producedAt + OCSP_DEFAULT_LIFETIME;
|
||||
}
|
||||
this->responses->insert_last(this->responses, response);
|
||||
return TRUE;
|
||||
}
|
||||
@@ -643,8 +659,7 @@ static id_match_t has_issuer(private_x509_ocsp_response_t *this,
|
||||
/**
|
||||
* Implementation of certificate_t.issued_by
|
||||
*/
|
||||
static bool issued_by(private_x509_ocsp_response_t *this, certificate_t *issuer,
|
||||
bool sigcheck)
|
||||
static bool issued_by(private_x509_ocsp_response_t *this, certificate_t *issuer)
|
||||
{
|
||||
public_key_t *key;
|
||||
signature_scheme_t scheme;
|
||||
@@ -685,10 +700,6 @@ static bool issued_by(private_x509_ocsp_response_t *this, certificate_t *issuer,
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (!sigcheck)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
/* TODO: generic OID to scheme mapper? */
|
||||
switch (this->signatureAlgorithm)
|
||||
{
|
||||
@@ -734,19 +745,7 @@ static public_key_t* get_public_key(private_x509_ocsp_response_t *this)
|
||||
static bool get_validity(private_x509_ocsp_response_t *this, time_t *when,
|
||||
time_t *not_before, time_t *not_after)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
single_response_t *response;
|
||||
time_t thisUpdate = this->producedAt;
|
||||
time_t nextUpdate = 0;
|
||||
time_t t;
|
||||
|
||||
enumerator = this->responses->create_enumerator(this->responses);
|
||||
if (enumerator->enumerate(enumerator, &response))
|
||||
{
|
||||
thisUpdate = response->thisUpdate;
|
||||
nextUpdate = response->nextUpdate;
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
if (when == NULL)
|
||||
{
|
||||
@@ -758,13 +757,13 @@ static bool get_validity(private_x509_ocsp_response_t *this, time_t *when,
|
||||
}
|
||||
if (not_before)
|
||||
{
|
||||
*not_before = thisUpdate;
|
||||
*not_before = this->producedAt;
|
||||
}
|
||||
if (not_after)
|
||||
{
|
||||
*not_after = nextUpdate;
|
||||
*not_after = this->usableUntil;
|
||||
}
|
||||
return (t < nextUpdate);
|
||||
return (t < this->usableUntil);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -853,7 +852,7 @@ static x509_ocsp_response_t *load(chunk_t data)
|
||||
this->public.interface.certificate.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
|
||||
this->public.interface.certificate.has_subject = (id_match_t(*)(certificate_t*, identification_t *subject))has_issuer;
|
||||
this->public.interface.certificate.has_issuer = (id_match_t(*)(certificate_t*, identification_t *issuer))has_issuer;
|
||||
this->public.interface.certificate.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer,bool))issued_by;
|
||||
this->public.interface.certificate.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer))issued_by;
|
||||
this->public.interface.certificate.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
|
||||
this->public.interface.certificate.get_validity = (bool(*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
|
||||
this->public.interface.certificate.is_newer = (bool (*)(certificate_t*,certificate_t*))is_newer;
|
||||
@@ -869,6 +868,7 @@ static x509_ocsp_response_t *load(chunk_t data)
|
||||
this->tbsResponseData = chunk_empty;
|
||||
this->responderId = NULL;
|
||||
this->producedAt = UNDEFINED_TIME;
|
||||
this->usableUntil = UNDEFINED_TIME;
|
||||
this->responses = linked_list_create();
|
||||
this->nonce = chunk_empty;
|
||||
this->signatureAlgorithm = OID_UNKNOWN;
|
||||
|
||||
Reference in New Issue
Block a user