results from the single responses is stored in the corresponding certinfo_t structs

This commit is contained in:
Andreas Steffen
2007-03-12 13:42:31 +00:00
parent 7c1b9ab784
commit db0f828413
4 changed files with 94 additions and 61 deletions
@@ -645,7 +645,7 @@ static bool verify(private_local_credential_store_t *this, x509_t *cert, bool *f
certinfo->destroy(certinfo);
return FALSE;
}
DBG2(DBG_CFG, "certificate is good");
DBG1(DBG_CFG, "certificate is good");
/* with strict crl policy the public key must have the same
* lifetime as the validity of the ocsp status or crl lifetime
@@ -684,7 +684,7 @@ static bool verify(private_local_credential_store_t *this, x509_t *cert, bool *f
case CERT_UNKNOWN:
case CERT_UNDEFINED:
default:
DBG2(DBG_CFG, "certificate status unknown");
DBG1(DBG_CFG, "certificate status unknown");
if (this->strict)
{
/* update status of end certificate in the credential store */
+19
View File
@@ -125,6 +125,22 @@ static cert_status_t get_status(const private_certinfo_t *this)
return this->status;
}
/**
* Implements certinfo_t.set_thisUpdate
*/
static void set_thisUpdate(private_certinfo_t *this, time_t thisUpdate)
{
this->thisUpdate = thisUpdate;
}
/**
* Implements certinfo_t.get_thisUpdate
*/
static time_t get_thisUpdate(const private_certinfo_t *this)
{
return this->thisUpdate;
}
/**
* Implements certinfo_t.set_nextUpdate
*/
@@ -192,6 +208,7 @@ certinfo_t *certinfo_create(chunk_t serial)
/* initialize */
this->serialNumber = chunk_clone(serial);
this->status = CERT_UNDEFINED;
this->thisUpdate = UNDEFINED_TIME;
this->nextUpdate = UNDEFINED_TIME;
this->revocationTime = UNDEFINED_TIME;
this->revocationReason = REASON_UNSPECIFIED;
@@ -201,6 +218,8 @@ certinfo_t *certinfo_create(chunk_t serial)
this->public.get_serialNumber = (chunk_t (*) (const certinfo_t*))get_serialNumber;
this->public.set_status = (void (*) (certinfo_t*,cert_status_t))set_status;
this->public.get_status = (cert_status_t (*) (const certinfo_t*))get_status;
this->public.set_thisUpdate = (void (*) (certinfo_t*,time_t))set_thisUpdate;
this->public.get_thisUpdate = (time_t (*) (const certinfo_t*))get_thisUpdate;
this->public.set_nextUpdate = (void (*) (certinfo_t*,time_t))set_nextUpdate;
this->public.get_nextUpdate = (time_t (*) (const certinfo_t*))get_nextUpdate;
this->public.set_revocationTime = (void (*) (certinfo_t*,time_t))set_revocationTime;
+17 -1
View File
@@ -99,11 +99,27 @@ struct certinfo_t {
*/
cert_status_t (*get_status) (const certinfo_t *this);
/**
* @brief Set thisUpdate.
*
* @param this calling object
* @param thisUpdate thisUpdate
*/
void (*set_thisUpdate) (certinfo_t *this, time_t thisUpdate);
/**
* @brief Get thisUpdate.
*
* @param this calling object
* @return thisUpdate
*/
time_t (*get_thisUpdate) (const certinfo_t *this);
/**
* @brief Set nextUpdate.
*
* @param this calling object
* @return nextUpdate
* @param nextUpdate
*/
void (*set_nextUpdate) (certinfo_t *this, time_t nextUpdate);
+56 -58
View File
@@ -85,6 +85,11 @@ struct private_ocsp_t {
* SHA-1 hash over issuer distinguished name
*/
chunk_t authNameID;
/**
* SHA-1 hash over issuer public key
*/
chunk_t authKeyID;
};
ENUM(response_status_names, STATUS_SUCCESSFUL, STATUS_UNAUTHORIZED,
@@ -153,35 +158,6 @@ static response_t* response_create_from_chunk(chunk_t chunk)
return this;
}
/* single response container */
typedef struct single_response single_response_t;
struct single_response {
single_response_t *next;
int hash_algorithm;
chunk_t issuer_name_hash;
chunk_t issuer_key_hash;
chunk_t serialNumber;
cert_status_t status;
time_t revocationTime;
crl_reason_t revocationReason;
time_t thisUpdate;
time_t nextUpdate;
};
const single_response_t empty_single_response = {
NULL , /* *next */
OID_UNKNOWN , /* hash_algorithm */
{ NULL, 0 } , /* issuer_name_hash */
{ NULL, 0 } , /* issuer_key_hash */
{ NULL, 0 } , /* serial_number */
CERT_UNDEFINED , /* status */
UNDEFINED_TIME , /* revocationTime */
REASON_UNSPECIFIED, /* revocationReason */
UNDEFINED_TIME , /* this_update */
UNDEFINED_TIME /* next_update */
};
/* some OCSP specific prefabricated ASN.1 constants */
static u_char ASN1_nonce_oid_str[] = {
@@ -346,13 +322,12 @@ static chunk_t build_requestor_name(private_ocsp_t *this)
*/
static chunk_t build_request(private_ocsp_t *this, certinfo_t *certinfo)
{
chunk_t authKeyID = this->cacert->get_subjectKeyID(this->cacert);
chunk_t serialNumber = certinfo->get_serialNumber(certinfo);
chunk_t reqCert = asn1_wrap(ASN1_SEQUENCE, "cmmm",
ASN1_sha1_id,
asn1_simple_object(ASN1_OCTET_STRING, this->authNameID),
asn1_simple_object(ASN1_OCTET_STRING, authKeyID),
asn1_simple_object(ASN1_OCTET_STRING, this->authKeyID),
asn1_simple_object(ASN1_INTEGER, serialNumber));
return asn1_wrap(ASN1_SEQUENCE, "m", reqCert);
@@ -660,7 +635,7 @@ static bool ocsp_valid_response(response_t *res, x509_t *ocsp_cert)
/**
* parse a single OCSP response
*/
static bool ocsp_parse_single_response(chunk_t blob, int level0, single_response_t *sres)
static bool ocsp_parse_single_response(private_ocsp_t *this, chunk_t blob, int level0)
{
u_int level, extn_oid;
asn1_ctx_t ctx;
@@ -668,6 +643,8 @@ static bool ocsp_parse_single_response(chunk_t blob, int level0, single_response
chunk_t object;
int objectID = 0;
certinfo_t *certinfo = NULL;
asn1_init(&ctx, blob, level0, FALSE, FALSE);
while (objectID < SINGLE_RESPONSE_ROOF)
@@ -680,38 +657,70 @@ static bool ocsp_parse_single_response(chunk_t blob, int level0, single_response
switch (objectID)
{
case SINGLE_RESPONSE_ALGORITHM:
sres->hash_algorithm = parse_algorithmIdentifier(object, level+1, NULL);
if (parse_algorithmIdentifier(object, level+1, NULL) != OID_SHA1)
{
DBG1("only sha-1 hash supported in ocsp single response");
return FALSE;
}
break;
case SINGLE_RESPONSE_ISSUER_NAME_HASH:
sres->issuer_name_hash = object;
if (!chunk_equals(object, this->authNameID))
{
DBG1("ocsp single response has wrong issuer name hash");
return FALSE;
}
break;
case SINGLE_RESPONSE_ISSUER_KEY_HASH:
sres->issuer_key_hash = object;
if (!chunk_equals(object, this->authKeyID))
{
DBG1("ocsp single response has wrong issuer key hash");
return FALSE;
}
break;
case SINGLE_RESPONSE_SERIAL_NUMBER:
sres->serialNumber = object;
{
iterator_t *iterator = this->certinfos->create_iterator(this->certinfos, TRUE);
certinfo_t *current_certinfo;
while (iterator->iterate(iterator, (void**)&current_certinfo))
{
if (chunk_equals(object, current_certinfo->get_serialNumber(current_certinfo)))
{
certinfo = current_certinfo;
}
}
iterator->destroy(iterator);
if (certinfo == NULL)
{
DBG1("unrequested serial number in ocsp single response");
return FALSE;
}
}
break;
case SINGLE_RESPONSE_CERT_STATUS_GOOD:
sres->status = CERT_GOOD;
certinfo->set_status(certinfo, CERT_GOOD);
break;
case SINGLE_RESPONSE_CERT_STATUS_REVOKED:
sres->status = CERT_REVOKED;
certinfo->set_status(certinfo, CERT_REVOKED);
break;
case SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME:
sres->revocationTime = asn1totime(&object, ASN1_GENERALIZEDTIME);
certinfo->set_revocationTime(certinfo,
asn1totime(&object, ASN1_GENERALIZEDTIME));
break;
case SINGLE_RESPONSE_CERT_STATUS_CRL_REASON:
sres->revocationReason = (object.len == 1)
? *object.ptr : REASON_UNSPECIFIED;
certinfo->set_revocationReason(certinfo,
(object.len == 1) ? *object.ptr : REASON_UNSPECIFIED);
break;
case SINGLE_RESPONSE_CERT_STATUS_UNKNOWN:
sres->status = CERT_UNKNOWN;
certinfo->set_status(certinfo, CERT_UNKNOWN);
break;
case SINGLE_RESPONSE_THIS_UPDATE:
sres->thisUpdate = asn1totime(&object, ASN1_GENERALIZEDTIME);
certinfo->set_thisUpdate(certinfo,
asn1totime(&object, ASN1_GENERALIZEDTIME));
break;
case SINGLE_RESPONSE_NEXT_UPDATE:
sres->nextUpdate = asn1totime(&object, ASN1_GENERALIZEDTIME);
certinfo->set_nextUpdate(certinfo,
asn1totime(&object, ASN1_GENERALIZEDTIME));
break;
case SINGLE_RESPONSE_EXT_ID:
extn_oid = known_oid(object);
@@ -727,14 +736,6 @@ static bool ocsp_parse_single_response(chunk_t blob, int level0, single_response
return TRUE;
}
/**
* process received ocsp single response and add it to ocsp cache
*/
static void process_single_response(private_ocsp_t *this, single_response_t *sres)
{
/* TODO */
}
/**
* verify and process ocsp response and update the ocsp cache
*/
@@ -825,12 +826,7 @@ static void ocsp_process_response(private_ocsp_t *this, response_t *res, credent
}
if (objectID == RESPONSES_SINGLE_RESPONSE)
{
single_response_t sres = empty_single_response;
if (ocsp_parse_single_response(object, level+1, &sres))
{
process_single_response(this, &sres);
}
ocsp_parse_single_response(this, object, level+1);
}
objectID++;
}
@@ -911,6 +907,8 @@ ocsp_t *ocsp_create(x509_t *cacert, linked_list_t *uris)
this->uris = uris;
this->certinfos = linked_list_create();
this->nonce = chunk_empty;
this->authKeyID = cacert->get_subjectKeyID(cacert);
/* TODO compute authKeyID in case subjectKeyID does not exist */
{
hasher_t *hasher = hasher_create(HASH_SHA1);
identification_t *issuer = cacert->get_subject(cacert);