2 #include "wvsslhacks.h"
4 static const int OCSP_MAX_VALIDITY_PERIOD = (5 * 60);
7 WvOCSPReq::WvOCSPReq(
const WvX509 &cert,
const WvX509 &issuer)
11 req = OCSP_REQUEST_new();
16 id = OCSP_cert_to_id(NULL, cert.cert, issuer.cert);
17 OCSP_request_add0_id(req,
id);
22 WvOCSPReq::~WvOCSPReq()
25 OCSP_REQUEST_free(req);
31 void WvOCSPReq::encode(
WvBuf &buf)
33 BIO *bufbio = BIO_new(BIO_s_mem());
38 assert(wv_i2d_OCSP_REQUEST_bio(bufbio, req) > 0);
40 BIO_get_mem_ptr(bufbio, &bm);
41 buf.put(bm->data, bm->length);
46 WvOCSPResp::WvOCSPResp() :
49 log(
"OCSP Response",
WvLog::Debug5)
55 WvOCSPResp::~WvOCSPResp()
58 OCSP_BASICRESP_free(bs);
61 OCSP_RESPONSE_free(resp);
67 void WvOCSPResp::decode(
WvBuf &encoded)
69 BIO *membuf = BIO_new(BIO_s_mem());
70 BIO_write(membuf, encoded.
get(encoded.
used()), encoded.
used());
72 resp = d2i_OCSP_RESPONSE_bio(membuf, NULL);
75 bs = OCSP_response_get1_basic(resp);
77 log(
"Failed to decode response.\n");
83 bool WvOCSPResp::isok()
const
88 int i = OCSP_response_status(resp);
89 if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL)
91 log(
"Status not successful: %s\n", wvssl_errstr());
99 bool WvOCSPResp::check_nonce(
const WvOCSPReq &req)
const
105 if ((i = OCSP_check_nonce(req.req, bs)) <= 0)
108 log(
"No nonce in response\n");
110 log(
"Nonce verify error\n");
119 bool WvOCSPResp::signedbycert(
const WvX509 &cert)
const
121 EVP_PKEY *skey = X509_get_pubkey(cert.cert);
122 int i = OCSP_BASICRESP_verify(bs, skey, 0);
132 WvX509 WvOCSPResp::get_signing_cert()
const
134 if (!bs || !sk_X509_num(bs->certs))
141 OCSP_RESPID *
id = bs->tbsResponseData->responderId;
143 if (id->type == V_OCSP_RESPID_NAME)
145 X509 *x = X509_find_by_subject(bs->certs, id->value.byName);
147 return WvX509(X509_dup(x));
150 if (id->value.byKey->length != SHA_DIGEST_LENGTH)
return NULL;
151 unsigned char tmphash[SHA_DIGEST_LENGTH];
152 unsigned char *keyhash =
id->value.byKey->data;
153 for (
int i = 0; i < sk_X509_num(bs->certs); i++)
155 X509 *x = sk_X509_value(bs->certs, i);
156 X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL);
157 if(!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH))
158 return WvX509(X509_dup(x));
165 WvOCSPResp::Status WvOCSPResp::get_status(
const WvX509 &cert,
166 const WvX509 &issuer)
const
175 ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
177 OCSP_CERTID *
id = OCSP_cert_to_id(NULL, cert.cert, issuer.cert);
180 if(!OCSP_resp_find_status(bs,
id, &status, &reason,
181 &rev, &thisupd, &nextupd))
183 log(
"OCSP Find Status Error: %s\n", wvssl_errstr());
184 OCSP_CERTID_free(
id);
187 OCSP_CERTID_free(
id);
189 if (!OCSP_check_validity(thisupd, nextupd, OCSP_MAX_VALIDITY_PERIOD, -1))
191 log(
"Error checking for OCSP validity: %s\n", wvssl_errstr());
195 if (status == V_OCSP_CERTSTATUS_GOOD)
197 else if (status == V_OCSP_CERTSTATUS_REVOKED)
200 log(
"OCSP cert status is %s, marking as 'Unknown'.\n",
201 OCSP_cert_status_str(status));
206 WvString WvOCSPResp::status_str(WvOCSPResp::Status status)
210 else if (status == Error)
212 else if (status == Revoked)