An OpenSSL::OCSP::BasicResponse
contains the status of a certificate check which is created from an OpenSSL::OCSP::Request
. A BasicResponse
is more detailed than a Response
.
static VALUE
ossl_ocspbres_initialize(int argc, VALUE *argv, VALUE self)
{
return self;
}
Creates a new BasicResponse
and ignores all arguments.
static VALUE
ossl_ocspbres_add_nonce(int argc, VALUE *argv, VALUE self)
{
OCSP_BASICRESP *bs;
VALUE val;
int ret;
rb_scan_args(argc, argv, "01", &val);
if(NIL_P(val)) {
GetOCSPBasicRes(self, bs);
ret = OCSP_basic_add1_nonce(bs, NULL, -1);
}
else{
StringValue(val);
GetOCSPBasicRes(self, bs);
ret = OCSP_basic_add1_nonce(bs, (unsigned char *)RSTRING_PTR(val), RSTRING_LENINT(val));
}
if(!ret) ossl_raise(eOCSPError, NULL);
return self;
}
Adds nonce
to this response. If no nonce was provided a random nonce will be added.
static VALUE
ossl_ocspbres_add_status(VALUE self, VALUE cid, VALUE status,
VALUE reason, VALUE revtime,
VALUE thisupd, VALUE nextupd, VALUE ext)
{
OCSP_BASICRESP *bs;
OCSP_SINGLERESP *single;
OCSP_CERTID *id;
ASN1_TIME *ths, *nxt, *rev;
int st, rsn, error, rstatus = 0;
long i;
VALUE tmp;
st = NUM2INT(status);
rsn = NIL_P(status) ? 0 : NUM2INT(reason);
if(!NIL_P(ext)){
/* All ary's members should be X509Extension */
Check_Type(ext, T_ARRAY);
for (i = 0; i < RARRAY_LEN(ext); i++)
OSSL_Check_Kind(RARRAY_AREF(ext, i), cX509Ext);
}
error = 0;
ths = nxt = rev = NULL;
if(!NIL_P(revtime)){
tmp = rb_protect(rb_Integer, revtime, &rstatus);
if(rstatus) goto err;
rev = X509_gmtime_adj(NULL, NUM2INT(tmp));
}
tmp = rb_protect(rb_Integer, thisupd, &rstatus);
if(rstatus) goto err;
ths = X509_gmtime_adj(NULL, NUM2INT(tmp));
tmp = rb_protect(rb_Integer, nextupd, &rstatus);
if(rstatus) goto err;
nxt = X509_gmtime_adj(NULL, NUM2INT(tmp));
GetOCSPBasicRes(self, bs);
SafeGetOCSPCertId(cid, id);
if(!(single = OCSP_basic_add1_status(bs, id, st, rsn, rev, ths, nxt))){
error = 1;
goto err;
}
if(!NIL_P(ext)){
X509_EXTENSION *x509ext;
sk_X509_EXTENSION_pop_free(single->singleExtensions, X509_EXTENSION_free);
single->singleExtensions = NULL;
for(i = 0; i < RARRAY_LEN(ext); i++){
x509ext = DupX509ExtPtr(RARRAY_AREF(ext, i));
if(!OCSP_SINGLERESP_add_ext(single, x509ext, -1)){
X509_EXTENSION_free(x509ext);
error = 1;
goto err;
}
X509_EXTENSION_free(x509ext);
}
}
err:
ASN1_TIME_free(ths);
ASN1_TIME_free(nxt);
ASN1_TIME_free(rev);
if(error) ossl_raise(eOCSPError, NULL);
if(rstatus) rb_jump_tag(rstatus);
return self;
}
Adds a validation status
(0 for good, 1 for revoked, 2 for unknown) to this response for certificate_id
. reason
describes the reason for the revocation, if any.
The revocation_time
, this_update
and next_update
are times for the certificate’s revocation time, the time of this status and the next update time for a new status, respectively.
extensions
may be an Array of OpenSSL::X509::Extension
that will be added to this response or nil.
static VALUE
ossl_ocspbres_copy_nonce(VALUE self, VALUE request)
{
OCSP_BASICRESP *bs;
OCSP_REQUEST *req;
int ret;
GetOCSPBasicRes(self, bs);
SafeGetOCSPReq(request, req);
ret = OCSP_copy_nonce(bs, req);
return INT2NUM(ret);
}
Copies the nonce from request
into this response. Returns 1 on success and 0 on failure.
static VALUE
ossl_ocspbres_sign(int argc, VALUE *argv, VALUE self)
{
VALUE signer_cert, signer_key, certs, flags;
OCSP_BASICRESP *bs;
X509 *signer;
EVP_PKEY *key;
STACK_OF(X509) *x509s;
unsigned long flg;
int ret;
rb_scan_args(argc, argv, "22", &signer_cert, &signer_key, &certs, &flags);
signer = GetX509CertPtr(signer_cert);
key = GetPrivPKeyPtr(signer_key);
flg = NIL_P(flags) ? 0 : NUM2INT(flags);
if(NIL_P(certs)){
x509s = sk_X509_new_null();
flg |= OCSP_NOCERTS;
}
else{
x509s = ossl_x509_ary2sk(certs);
}
GetOCSPBasicRes(self, bs);
ret = OCSP_basic_sign(bs, signer, key, EVP_sha1(), x509s, flg);
sk_X509_pop_free(x509s, X509_free);
if(!ret) ossl_raise(eOCSPError, NULL);
return self;
}
Signs this response using the signer_cert
and signer_key
. Additional certificates
may be added to the signature along with a set of flags
.
static VALUE
ossl_ocspbres_get_status(VALUE self)
{
OCSP_BASICRESP *bs;
OCSP_SINGLERESP *single;
OCSP_CERTID *cid;
ASN1_TIME *revtime, *thisupd, *nextupd;
int status, reason;
X509_EXTENSION *x509ext;
VALUE ret, ary, ext;
int count, ext_count, i, j;
GetOCSPBasicRes(self, bs);
ret = rb_ary_new();
count = OCSP_resp_count(bs);
for(i = 0; i < count; i++){
single = OCSP_resp_get0(bs, i);
if(!single) continue;
revtime = thisupd = nextupd = NULL;
status = OCSP_single_get0_status(single, &reason, &revtime,
&thisupd, &nextupd);
if(status < 0) continue;
if(!(cid = OCSP_CERTID_dup(single->certId)))
ossl_raise(eOCSPError, NULL);
ary = rb_ary_new();
rb_ary_push(ary, ossl_ocspcertid_new(cid));
rb_ary_push(ary, INT2NUM(status));
rb_ary_push(ary, INT2NUM(reason));
rb_ary_push(ary, revtime ? asn1time_to_time(revtime) : Qnil);
rb_ary_push(ary, thisupd ? asn1time_to_time(thisupd) : Qnil);
rb_ary_push(ary, nextupd ? asn1time_to_time(nextupd) : Qnil);
ext = rb_ary_new();
ext_count = OCSP_SINGLERESP_get_ext_count(single);
for(j = 0; j < ext_count; j++){
x509ext = OCSP_SINGLERESP_get_ext(single, j);
rb_ary_push(ext, ossl_x509ext_new(x509ext));
}
rb_ary_push(ary, ext);
rb_ary_push(ret, ary);
}
return ret;
}
Returns an Array of statuses for this response. Each status contains a CertificateId
, the status (0 for good, 1 for revoked, 2 for unknown), the reason for the status, the revocation time, the time of this update, the time for the next update and a list of OpenSSL::X509::Extensions.
static VALUE
ossl_ocspbres_verify(int argc, VALUE *argv, VALUE self)
{
VALUE certs, store, flags, result;
OCSP_BASICRESP *bs;
STACK_OF(X509) *x509s;
X509_STORE *x509st;
int flg;
rb_scan_args(argc, argv, "21", &certs, &store, &flags);
x509st = GetX509StorePtr(store);
flg = NIL_P(flags) ? 0 : NUM2INT(flags);
x509s = ossl_x509_ary2sk(certs);
GetOCSPBasicRes(self, bs);
result = OCSP_basic_verify(bs, x509s, x509st, flg) > 0 ? Qtrue : Qfalse;
sk_X509_pop_free(x509s, X509_free);
if(!result) rb_warn("%s", ERR_error_string(ERR_peek_error(), NULL));
return result;
}
Verifies the signature of the response using the given certificates
, store
and flags
.