OpenSSL::OCSP::BasicResponse
类 OpenSSL :: OCSP :: BasicResponse
家长:对象 (Parent:Object)
OpenSSL :: OCSP :: BasicResponse 包含从 OpenSSL :: OCSP :: Request 创建的证书检查的状态。BasicResponse 比 Response 更详细。
公共类方法
OpenSSL :: OCSP :: BasicResponse.new(der_string = nil)→basic_response 显示源文件
创建一个新的 BasicResponse。如果der_string
给出,则解码der_string
为 DER。
static VALUE
ossl_ocspbres_initialize(int argc, VALUE *argv, VALUE self)
{
VALUE arg;
OCSP_BASICRESP *res, *res_new;
const unsigned char *p;
rb_scan_args(argc, argv, "01", &arg
if (!NIL_P(arg)) {
GetOCSPBasicRes(self, res
arg = ossl_to_der_if_possible(arg
StringValue(arg
p = (unsigned char *)RSTRING_PTR(arg
res_new = d2i_OCSP_BASICRESP(NULL, &p, RSTRING_LEN(arg)
if (!res_new)
ossl_raise(eOCSPError, "d2i_OCSP_BASICRESP"
SetOCSPBasicRes(self, res_new
OCSP_BASICRESP_free(res
}
return self;
}
公共实例方法
add_nonce(nonce = nil)显示源文件
添加nonce
到此响应。如果不提供随机数,则会添加随机数。
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;
}
add_status(certificate_id,status,reason,revocation_time,this_update,next_update,扩展)→basic_response显示源代码
添加证书状态certificate_id
。status
是地位,必须是其中的一个:
- OpenSSL::OCSP::V_CERTSTATUS_GOOD
- OpenSSL::OCSP::V_CERTSTATUS_REVOKED
- OpenSSL::OCSP::V_CERTSTATUS_UNKNOWN
reason
和revocation_time
只有在status
OpenSSL :: OCSP :: V_CERTSTATUS_REVOKED 时才能给出。reason
描述了撤销的原因,并且必须是OpenSSL :: OCSP :: REVOKED_STATUS_ *常量之一。revocation_time
是证书被撤销的时间。
this_update
和next_update
指出该状态经过验证的时间是正确的,以及分别提供更新信息的时间。next_update
是可选的。
extensions
是一个包含在 SingleResponse 中的 OpenSSL :: X509 :: Extension 数组。这也是可选的。
需要注意的是时间,revocation_time
,this_update
和next_update
可以在整数或Time对象的规定。如果它们是整型,则将其视为当前时间的相对秒数。
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 = NULL, *nxt = NULL, *rev = NULL;
int st, rsn = 0, error = 0, rstatus = 0;
long i;
VALUE tmp;
GetOCSPBasicRes(self, bs
SafeGetOCSPCertId(cid, id
st = NUM2INT(status
if (!NIL_P(ext)) { /* All ext's members must be X509::Extension */
ext = rb_check_array_type(ext
for (i = 0; i < RARRAY_LEN(ext i++)
OSSL_Check_Kind(RARRAY_AREF(ext, i), cX509Ext
}
if (st == V_OCSP_CERTSTATUS_REVOKED) {
rsn = NUM2INT(reason
tmp = rb_protect(add_status_convert_time, revtime, &rstatus
if (rstatus) goto err;
rev = (ASN1_TIME *)tmp;
}
tmp = rb_protect(add_status_convert_time, thisupd, &rstatus
if (rstatus) goto err;
ths = (ASN1_TIME *)tmp;
if (!NIL_P(nextupd)) {
tmp = rb_protect(add_status_convert_time, nextupd, &rstatus
if (rstatus) goto err;
nxt = (ASN1_TIME *)tmp;
}
if(!(single = OCSP_basic_add1_status(bs, id, st, rsn, rev, ths, nxt))){
error = 1;
goto err;
}
if(!NIL_P(ext)){
X509_EXTENSION *x509ext;
for(i = 0; i < RARRAY_LEN(ext i++){
x509ext = GetX509ExtPtr(RARRAY_AREF(ext, i)
if(!OCSP_SINGLERESP_add_ext(single, x509ext, -1)){
error = 1;
goto err;
}
}
}
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;
}
copy_nonce(请求)→整数显示源
将 nonce 复制request
到此响应中。成功时返回1,失败时返回0。
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
}
find_response(certificate_id) → SingleResponse | nil Show source
返回 CertId 匹配的 SingleResponse certificate_id
,如果此 BasicResponse 不包含它,则返回 nil。
static VALUE
ossl_ocspbres_find_response(VALUE self, VALUE target)
{
OCSP_BASICRESP *bs;
OCSP_SINGLERESP *sres, *sres_new;
OCSP_CERTID *id;
int n;
SafeGetOCSPCertId(target, id
GetOCSPBasicRes(self, bs
if ((n = OCSP_resp_find(bs, id, -1)) == -1)
return Qnil;
sres = OCSP_resp_get0(bs, n
sres_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_SINGLERESP), sres
if (!sres_new)
ossl_raise(eOCSPError, "ASN1_item_dup"
return ossl_ocspsres_new(sres_new
}
响应→SingleResponse 数组显示源
返回此 BasicResponse 的 SingleResponse 数组。
static VALUE
ossl_ocspbres_get_responses(VALUE self)
{
OCSP_BASICRESP *bs;
VALUE ret;
int count, i;
GetOCSPBasicRes(self, bs
count = OCSP_resp_count(bs
ret = rb_ary_new2(count
for (i = 0; i < count; i++) {
OCSP_SINGLERESP *sres, *sres_new;
sres = OCSP_resp_get0(bs, i
sres_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_SINGLERESP), sres
if (!sres_new)
ossl_raise(eOCSPError, "ASN1_item_dup"
rb_ary_push(ret, ossl_ocspsres_new(sres_new)
}
return ret;
}
sign(cert, key, certs = nil, flags = 0, digest = nil) → self 显示源
标志使用此 OCSP 响应cert
,key
以及可选的digest
。它的行为与 OpenSSL :: OCSP :: Request#标记类似。
flags
可以包括:
OpenSSL::OCSP::NOCERTS
不包括证书
OpenSSL::OCSP::NOTIME
不要设置生产
OpenSSL::OCSP::RESPID_KEY
使用签名者的公钥哈希作为 responderID
static VALUE
ossl_ocspbres_sign(int argc, VALUE *argv, VALUE self)
{
VALUE signer_cert, signer_key, certs, flags, digest;
OCSP_BASICRESP *bs;
X509 *signer;
EVP_PKEY *key;
STACK_OF(X509) *x509s = NULL;
unsigned long flg = 0;
const EVP_MD *md;
int ret;
rb_scan_args(argc, argv, "23", &signer_cert, &signer_key, &certs, &flags, &digest
GetOCSPBasicRes(self, bs
signer = GetX509CertPtr(signer_cert
key = GetPrivPKeyPtr(signer_key
if (!NIL_P(flags))
flg = NUM2INT(flags
if (NIL_P(digest))
md = EVP_sha1(
else
md = GetDigestPtr(digest
if (NIL_P(certs))
flg |= OCSP_NOCERTS;
else
x509s = ossl_x509_ary2sk(certs
ret = OCSP_basic_sign(bs, signer, key, md, x509s, flg
sk_X509_pop_free(x509s, X509_free
if (!ret) ossl_raise(eOCSPError, NULL
return self;
}
状态 status → statuses显示来源
返回此响应的状态数组。每个状态都包含 CertificateId,状态(0表示正确,1表示撤销,2表示未知),状态原因,撤销时间,此更新时间,下次更新时间以及OpenSSL列表: :X509 ::扩展。
这应该被返回 SingleResponse 的 #responses 和 find_response 所取代。
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((OCSP_CERTID *)OCSP_SINGLERESP_get0_id(single)))) /* FIXME */
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;
}
to_der →字符串显示源
将此基本响应编码为 DER 编码的字符串。
static VALUE
ossl_ocspbres_to_der(VALUE self)
{
OCSP_BASICRESP *res;
VALUE str;
long len;
unsigned char *p;
GetOCSPBasicRes(self, res
if ((len = i2d_OCSP_BASICRESP(res, NULL)) <= 0)
ossl_raise(eOCSPError, NULL
str = rb_str_new(0, len
p = (unsigned char *)RSTRING_PTR(str
if (i2d_OCSP_BASICRESP(res, &p) <= 0)
ossl_raise(eOCSPError, NULL
ossl_str_adjust(str, p
return str;
}
verify(certificates, store, flags = 0) →true或false显示源
验证使用给定certificates
和的响应的签名store
。这与 OpenSSL :: OCSP :: Request#verify 类似。
static VALUE
ossl_ocspbres_verify(int argc, VALUE *argv, VALUE self)
{
VALUE certs, store, flags;
OCSP_BASICRESP *bs;
STACK_OF(X509) *x509s;
X509_STORE *x509st;
int flg, result;
rb_scan_args(argc, argv, "21", &certs, &store, &flags
GetOCSPBasicRes(self, bs
x509st = GetX509StorePtr(store
flg = NIL_P(flags) ? 0 : NUM2INT(flags
x509s = ossl_x509_ary2sk(certs
#if (OPENSSL_VERSION_NUMBER < 0x1000202fL) || defined(LIBRESSL_VERSION_NUMBER)
/*
* OpenSSL had a bug that it doesn't use the certificates in x509s for
* verifying the chain. This can be a problem when the response is signed by
* a certificate issued by an intermediate CA.
*
* root_ca
* |
* intermediate_ca
* |-------------|
* end_entity ocsp_signer
*
* When the certificate hierarchy is like this, and the response contains
* only ocsp_signer certificate, the following code wrongly fails.
*
* store = OpenSSL::X509::Store.new; store.add_cert(root_ca)
* basic_response.verify([intermediate_ca], store)
*
* So add the certificates in x509s to the embedded certificates list first.
*
* This is fixed in OpenSSL 0.9.8zg, 1.0.0s, 1.0.1n, 1.0.2b. But it still
* exists in LibreSSL 2.1.10, 2.2.9, 2.3.6, 2.4.1.
*/
if (!(flg & (OCSP_NOCHAIN | OCSP_NOVERIFY)) &&
sk_X509_num(x509s) && sk_X509_num(bs->certs)) {
int i;
bs = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_BASICRESP), bs
if (!bs) {
sk_X509_pop_free(x509s, X509_free
ossl_raise(eOCSPError, "ASN1_item_dup"
}
for (i = 0; i < sk_X509_num(x509s i++) {
if (!OCSP_basic_add1_cert(bs, sk_X509_value(x509s, i))) {
sk_X509_pop_free(x509s, X509_free
OCSP_BASICRESP_free(bs
ossl_raise(eOCSPError, "OCSP_basic_add1_cert"
}
}
result = OCSP_basic_verify(bs, x509s, x509st, flg
OCSP_BASICRESP_free(bs
}
else {
result = OCSP_basic_verify(bs, x509s, x509st, flg
}
#else
result = OCSP_basic_verify(bs, x509s, x509st, flg
#endif
sk_X509_pop_free(x509s, X509_free
if (result <= 0)
ossl_clear_error(
return result > 0 ? Qtrue : Qfalse;
}