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)
X509 Class to handle certificates and their related functions.
virtual bool isok() const
Is the certificate object valid?
Specialization of WvBufBase for unsigned char type buffers intended for use with raw memory buffers...
size_t used() const
Returns the number of elements in the buffer currently available for reading.
WvString is an implementation of a simple and efficient printable-string class.
const T * get(size_t count)
Reads exactly the specified number of elements and returns a pointer to a storage location owned by t...
A WvLog stream accepts log messages from applications and forwards them to all registered WvLogRcv's...