Object
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.
Creates a new BasicResponse and ignores all arguments.
static VALUE
ossl_ocspbres_initialize(int argc, VALUE *argv, VALUE self)
{
return self;
}
Adds nonce to this response. If no nonce was provided a
random nonce will be added.
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 a validation status (0 for revoked, 1 for success) 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_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;
int st, rsn;
ASN1_TIME *ths, *nxt, *rev;
int error, i, rstatus = 0;
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_PTR(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_PTR(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;
}
Copies the nonce from request into this response. Returns 1
on success and 0 on failure.
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);
}
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_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;
}
Returns an Array of statuses for this response. Each status contains a CertificateId, the status (0 for success, 1 for revoked), 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_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;
}
Verifies the signature of the response using the given
certificates, store and flags.
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;
}
Commenting is here to help enhance the documentation. For example, code samples, or clarification of the documentation.
If you have questions about Ruby or the documentation, please post to one of the Ruby mailing lists. You will get better, faster, help that way.
If you wish to post a correction of the docs, please do so, but also file bug report so that it can be corrected for the next release. Thank you.
If you want to help improve the Ruby documentation, please visit Documenting-ruby.org.