Revert previous patch.
(hx509_ocsp_verify): new function that returns the expiration of certificate in ocsp data-blob git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@17376 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
@@ -193,22 +193,15 @@ out:
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
load_ocsp(hx509_context context, struct revoke_ocsp *ocsp)
|
parse_ocsp_basic(const void *data, size_t length, OCSPBasicOCSPResponse *basic)
|
||||||
{
|
{
|
||||||
OCSPResponse resp;
|
OCSPResponse resp;
|
||||||
OCSPBasicOCSPResponse basic;
|
size_t size;
|
||||||
hx509_certs certs = NULL;
|
|
||||||
size_t length, size;
|
|
||||||
struct stat sb;
|
|
||||||
void *data;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = _hx509_map_file(ocsp->path, &data, &length, &sb);
|
memset(basic, 0, sizeof(*basic));
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
ret = decode_OCSPResponse(data, length, &resp, &size);
|
ret = decode_OCSPResponse(data, length, &resp, &size);
|
||||||
_hx509_unmap_file(data, length);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
if (length != size) {
|
if (length != size) {
|
||||||
@@ -229,8 +222,7 @@ load_ocsp(hx509_context context, struct revoke_ocsp *ocsp)
|
|||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = heim_oid_cmp(&resp.responseBytes->responseType,
|
ret = heim_oid_cmp(&resp.responseBytes->responseType, oid_id_pkix_ocsp_basic());
|
||||||
oid_id_pkix_ocsp_basic());
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
free_OCSPResponse(&resp);
|
free_OCSPResponse(&resp);
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
@@ -238,7 +230,7 @@ load_ocsp(hx509_context context, struct revoke_ocsp *ocsp)
|
|||||||
|
|
||||||
ret = decode_OCSPBasicOCSPResponse(resp.responseBytes->response.data,
|
ret = decode_OCSPBasicOCSPResponse(resp.responseBytes->response.data,
|
||||||
resp.responseBytes->response.length,
|
resp.responseBytes->response.length,
|
||||||
&basic,
|
basic,
|
||||||
&size);
|
&size);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
free_OCSPResponse(&resp);
|
free_OCSPResponse(&resp);
|
||||||
@@ -246,11 +238,37 @@ load_ocsp(hx509_context context, struct revoke_ocsp *ocsp)
|
|||||||
}
|
}
|
||||||
if (size != resp.responseBytes->response.length) {
|
if (size != resp.responseBytes->response.length) {
|
||||||
free_OCSPResponse(&resp);
|
free_OCSPResponse(&resp);
|
||||||
free_OCSPBasicOCSPResponse(&basic);
|
free_OCSPBasicOCSPResponse(basic);
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
free_OCSPResponse(&resp);
|
free_OCSPResponse(&resp);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int
|
||||||
|
load_ocsp(hx509_context context, struct revoke_ocsp *ocsp)
|
||||||
|
{
|
||||||
|
OCSPBasicOCSPResponse basic;
|
||||||
|
hx509_certs certs = NULL;
|
||||||
|
size_t length;
|
||||||
|
struct stat sb;
|
||||||
|
void *data;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = _hx509_map_file(ocsp->path, &data, &length, &sb);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = parse_ocsp_basic(data, length, &basic);
|
||||||
|
_hx509_unmap_file(data, length);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
if (basic.certs) {
|
if (basic.certs) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@@ -482,7 +500,6 @@ hx509_revoke_verify(hx509_context context,
|
|||||||
hx509_revoke_ctx revoke,
|
hx509_revoke_ctx revoke,
|
||||||
hx509_certs certs,
|
hx509_certs certs,
|
||||||
time_t now,
|
time_t now,
|
||||||
time_t *expiration,
|
|
||||||
hx509_cert cert,
|
hx509_cert cert,
|
||||||
hx509_cert parent_cert)
|
hx509_cert parent_cert)
|
||||||
{
|
{
|
||||||
@@ -491,9 +508,6 @@ hx509_revoke_verify(hx509_context context,
|
|||||||
unsigned long i, j, k;
|
unsigned long i, j, k;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (expiration)
|
|
||||||
*expiration = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < revoke->ocsps.len; i++) {
|
for (i = 0; i < revoke->ocsps.len; i++) {
|
||||||
struct revoke_ocsp *ocsp = &revoke->ocsps.val[i];
|
struct revoke_ocsp *ocsp = &revoke->ocsps.val[i];
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
@@ -561,13 +575,6 @@ hx509_revoke_verify(hx509_context context,
|
|||||||
} else
|
} else
|
||||||
/* Should force a refetch, but can we ? */;
|
/* Should force a refetch, but can we ? */;
|
||||||
|
|
||||||
if (expiration) {
|
|
||||||
if (*ocsp->ocsp.tbsResponseData.responses.val[i].nextUpdate)
|
|
||||||
*expiration = *ocsp->ocsp.tbsResponseData.responses.val[i].nextUpdate;
|
|
||||||
else
|
|
||||||
*expiration = now + context->ocsp_time_diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -631,9 +638,6 @@ hx509_revoke_verify(hx509_context context,
|
|||||||
return HX509_CRL_CERT_REVOKED;
|
return HX509_CRL_CERT_REVOKED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expiration)
|
|
||||||
*expiration = _hx509_Time2time_t(crl->crl.tbsCertList.nextUpdate);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -904,3 +908,66 @@ hx509_revoke_ocsp_print(hx509_context context, const char *path, FILE *out)
|
|||||||
free_ocsp(&ocsp);
|
free_ocsp(&ocsp);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
hx509_ocsp_verify(hx509_context context,
|
||||||
|
time_t now,
|
||||||
|
hx509_cert cert,
|
||||||
|
int flags,
|
||||||
|
const void *data, size_t length,
|
||||||
|
time_t *expiration)
|
||||||
|
{
|
||||||
|
const Certificate *c = _hx509_get_cert(cert);
|
||||||
|
OCSPBasicOCSPResponse basic;
|
||||||
|
int ret, i;
|
||||||
|
|
||||||
|
*expiration = 0;
|
||||||
|
|
||||||
|
ret = parse_ocsp_basic(data, length, &basic);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
|
||||||
|
for (i = 0; i < basic.tbsResponseData.responses.len; i++) {
|
||||||
|
|
||||||
|
ret = heim_integer_cmp(&basic.tbsResponseData.responses.val[i].certID.serialNumber,
|
||||||
|
&c->tbsCertificate.serialNumber);
|
||||||
|
if (ret != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* verify issuer hashes hash */
|
||||||
|
ret = _hx509_verify_signature(NULL,
|
||||||
|
&basic.tbsResponseData.responses.val[i].certID.hashAlgorithm,
|
||||||
|
&c->tbsCertificate.issuer._save,
|
||||||
|
&basic.tbsResponseData.responses.val[i].certID.issuerNameHash);
|
||||||
|
if (ret != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch (basic.tbsResponseData.responses.val[i].certStatus.element) {
|
||||||
|
case choice_OCSPCertStatus_good:
|
||||||
|
break;
|
||||||
|
case choice_OCSPCertStatus_revoked:
|
||||||
|
case choice_OCSPCertStatus_unknown:
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* don't allow the update to be in the future */
|
||||||
|
if (basic.tbsResponseData.responses.val[i].thisUpdate >
|
||||||
|
now + context->ocsp_time_diff)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* don't allow the next updte to be in the past */
|
||||||
|
if (basic.tbsResponseData.responses.val[i].nextUpdate) {
|
||||||
|
if (*basic.tbsResponseData.responses.val[i].nextUpdate < now)
|
||||||
|
continue;
|
||||||
|
} else
|
||||||
|
continue;
|
||||||
|
|
||||||
|
*expiration = *basic.tbsResponseData.responses.val[i].nextUpdate;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
free_OCSPBasicOCSPResponse(&basic);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user