非常教程

Ruby 2.4参考手册

OpenSSL

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_idstatus是地位,必须是其中的一个:

  • OpenSSL::OCSP::V_CERTSTATUS_GOOD
  • OpenSSL::OCSP::V_CERTSTATUS_REVOKED
  • OpenSSL::OCSP::V_CERTSTATUS_UNKNOWN

reasonrevocation_time只有在statusOpenSSL :: OCSP :: V_CERTSTATUS_REVOKED 时才能给出。reason描述了撤销的原因,并且必须是OpenSSL :: OCSP :: REVOKED_STATUS_ *常量之一。revocation_time是证书被撤销的时间。

this_updatenext_update指出该状态经过验证的时间是正确的,以及分别提供更新信息的时间。next_update是可选的。

extensions是一个包含在 SingleResponse 中的 OpenSSL :: X509 :: Extension 数组。这也是可选的。

需要注意的是时间,revocation_timethis_updatenext_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 响应certkey以及可选的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;
}

OpenSSL相关

1.OpenSSL::ASN1
2.OpenSSL::ASN1::ASN1Data
3.OpenSSL::ASN1::ASN1Error
4.OpenSSL::ASN1::Constructive
5.OpenSSL::ASN1::ObjectId
6.OpenSSL::ASN1::Primitive
7.OpenSSL::BN
8.OpenSSL::BNError
9.OpenSSL::Buffering
10.OpenSSL::Cipher
11.OpenSSL::Cipher::Cipher
12.OpenSSL::Config
13.OpenSSL::ConfigError
14.OpenSSL::Digest
15.OpenSSL::Digest::DigestError
16.OpenSSL::Engine
17.OpenSSL::Engine::EngineError
18.OpenSSL::ExtConfig
19.OpenSSL::HMAC
20.OpenSSL::HMACError
21.OpenSSL::Netscape
22.OpenSSL::Netscape::SPKI
23.OpenSSL::Netscape::SPKIError
24.OpenSSL::OCSP
25.OpenSSL::OCSP::CertificateId
26.OpenSSL::OCSP::OCSPError
27.OpenSSL::OCSP::Request
28.OpenSSL::OCSP::Response
29.OpenSSL::OCSP::SingleResponse
30.OpenSSL::OpenSSLError
31.OpenSSL::PKCS12
32.OpenSSL::PKCS5
33.OpenSSL::PKCS5::PKCS5Error
34.OpenSSL::PKCS7
35.OpenSSL::PKCS7::RecipientInfo
36.OpenSSL::PKCS7::SignerInfo
37.OpenSSL::PKey
38.OpenSSL::PKey::DH
39.OpenSSL::PKey::DHError
40.OpenSSL::PKey::DSA
41.OpenSSL::PKey::DSAError
42.OpenSSL::PKey::EC
43.OpenSSL::PKey::EC::Group
44.OpenSSL::PKey::EC::Point
45.OpenSSL::PKey::PKey
46.OpenSSL::PKey::PKeyError
47.OpenSSL::PKey::RSA
48.OpenSSL::PKey::RSAError
49.OpenSSL::Random
50.OpenSSL::SSL
51.OpenSSL::SSL::Session
52.OpenSSL::SSL::SocketForwarder
53.OpenSSL::SSL::SSLContext
54.OpenSSL::SSL::SSLError
55.OpenSSL::SSL::SSLServer
56.OpenSSL::SSL::SSLSocket
57.OpenSSL::X509::Attribute
58.OpenSSL::X509::Certificate
59.OpenSSL::X509::CRL
60.OpenSSL::X509::Extension
61.OpenSSL::X509::ExtensionFactory
62.OpenSSL::X509::Name
63.OpenSSL::X509::Name::RFC2253DN
64.OpenSSL::X509::Request
65.OpenSSL::X509::Revoked
66.OpenSSL::X509::Store
67.OpenSSL::X509::StoreContext
Ruby 2.4

Ruby 是一种面向对象、命令式、函数式、动态的通用编程语言,是世界上最优美而巧妙的语言。

主页 https://www.ruby-lang.org/
源码 https://github.com/ruby/ruby
版本 2.4
发布版本 2.4.1

Ruby 2.4目录

1.缩略 | Abbrev
2.ARGF
3.数组 | Array
4.Base64
5.基本对象 | BasicObject
6.基准测试 | Benchmark
7.BigDecimal
8.绑定 | Binding
9.CGI
10.类 | Class
11.比较 | Comparable
12.负责 | Complex
13.计算续体 | Continuation
14.覆盖 | Coverage
15.CSV
16.日期 | Date
17.日期时间 | DateTime
18.DBM
19.代理 | Delegator
20.摘要 | Digest
21.Dir
22.DRb
23.编码 | Encoding
24.枚举 | Enumerable
25.枚举 | Enumerator
26.ENV
27.ERB
28.错误 | Errors
29.Etc
30.期望值 | Exception
31.错误类 | FalseClass
32.Fiber
33.Fiddle
34.文件 | File
35.文件实用程序 | FileUtils
36.查找 | Find
37.浮点 | Float
38.Forwardable
39.GC
40.GDBM
41.GetoptLong
42.Hash
43.Integer
44.IO
45.IPAddr
46.JSON
47.Kernel
48.语言 | 3Language
49.记录 | Logger
50.编排 | Marshal
51.MatchData
52.数学 | Math
53.矩阵 | Matrix
54.方法 | Method
55.模型 | Module
56.监控 | Monitor
57. 互斥 | Mutex
58.Net
59.Net::FTP
60.Net::HTTP
61.Net::IMAP
62.Net::SMTP
63.NilClass
64.数字 | Numeric
65.对象 | Object
66.ObjectSpace
67.Observable
68.Open3
69.OpenSSL
70.OpenStruct
71.OpenURI
72.OptionParser
73.路径名 | Pathname
74.完整输出 | PrettyPrint
75.Prime
76.Proc
77.过程 | Process
78.PStore
79.PTY
80.队列 | Queue
81.随机 | Random
82.范围 | Range
83.合理的 | Rational
84.Readline
85.Regexp
86.Resolv
87.Ripper
88.RubyVM
89.Scanf
90.SDBM
91.SecureRandom
92.Set
93.Shell
94.信号 | Signal
95.Singleton
96.套接字 | Socket
97.字符串 | String
98.StringIO
99.StringScanner
100.结构 | Struct