class OpenSSL::OCSP::Request - RDoc Documentation

# class OpenSSL::OCSP::Request

An `OpenSSL::OCSP::Request` contains the certificate information for determining if a certificate has been revoked or not. A `Request` can be created for a certificate or from a DER-encoded request created elsewhere.

### Public Class Methods

OpenSSL::OCSP::Request.new → request click to toggle source
OpenSSL::OCSP::Request.new(request_der) → request

Creates a new `OpenSSL::OCSP::Request`. The request may be created empty or from a request_der string.

    static VALUE
    ossl_ocspreq_initialize(int argc, VALUE *argv, VALUE self)
    {
        VALUE arg;
        OCSP_REQUEST *req, *req_new;
        const unsigned char *p;

        rb_scan_args(argc, argv, "01", &arg);
        if(!NIL_P(arg)){
            GetOCSPReq(self, req);
            arg = ossl_to_der_if_possible(arg);
            StringValue(arg);
            p = (unsigned char *)RSTRING_PTR(arg);
            req_new = d2i_OCSP_REQUEST(NULL, &p, RSTRING_LEN(arg));
            if (!req_new)
                ossl_raise(eOCSPError, "d2i_OCSP_REQUEST");
            SetOCSPReq(self, req_new);
            OCSP_REQUEST_free(req);
        }

        return self;
    }

### Public Instance Methods

add_certid(certificate_id) → request click to toggle source

Adds certificate_id to the request.

    static VALUE
    ossl_ocspreq_add_certid(VALUE self, VALUE certid)
    {
        OCSP_REQUEST *req;
        OCSP_CERTID *id, *id_new;

        GetOCSPReq(self, req);
        GetOCSPCertId(certid, id);

        if (!(id_new = OCSP_CERTID_dup(id)))
            ossl_raise(eOCSPError, "OCSP_CERTID_dup");
        if (!OCSP_request_add0_id(req, id_new)) {
            OCSP_CERTID_free(id_new);
            ossl_raise(eOCSPError, "OCSP_request_add0_id");
        }

        return self;
    }

add_nonce(nonce = nil) → request click to toggle source

Adds a nonce to the `OCSP` request. If no nonce is given a random one will be generated.

The nonce is used to prevent replay attacks but some servers do not support it.

    static VALUE
    ossl_ocspreq_add_nonce(int argc, VALUE *argv, VALUE self)
    {
        OCSP_REQUEST *req;
        VALUE val;
        int ret;

        rb_scan_args(argc, argv, "01", &val);
        if(NIL_P(val)) {
            GetOCSPReq(self, req);
            ret = OCSP_request_add1_nonce(req, NULL, -1);
        }
        else{
            StringValue(val);
            GetOCSPReq(self, req);
            ret = OCSP_request_add1_nonce(req, (unsigned char *)RSTRING_PTR(val), RSTRING_LENINT(val));
        }
        if(!ret) ossl_raise(eOCSPError, NULL);

        return self;
    }

certid → [certificate_id, ...] click to toggle source

Returns all certificate IDs in this request.

    static VALUE
    ossl_ocspreq_get_certid(VALUE self)
    {
        OCSP_REQUEST *req;
        OCSP_ONEREQ *one;
        OCSP_CERTID *id;
        VALUE ary, tmp;
        int i, count;

        GetOCSPReq(self, req);
        count = OCSP_request_onereq_count(req);
        ary = (count > 0) ? rb_ary_new() : Qnil;
        for(i = 0; i < count; i++){
            one = OCSP_request_onereq_get0(req, i);
            tmp = NewOCSPCertId(cOCSPCertId);
            if(!(id = OCSP_CERTID_dup(OCSP_onereq_get0_id(one))))
                ossl_raise(eOCSPError, NULL);
            SetOCSPCertId(tmp, id);
            rb_ary_push(ary, tmp);
        }

        return ary;
    }

check_nonce(response) → result click to toggle source

Checks the nonce validity for this request and response.

The return value is one of the following:

-1

  nonce in request only.

0

  nonces both present and not equal.

1

  nonces present and equal.

2

  nonces both absent.

3

  nonce present in response only.

For most responses, clients can check result > 0. If a responder doesn't handle nonces `result.nonzero?` may be necessary. A result of `0` is always an error.

    static VALUE
    ossl_ocspreq_check_nonce(VALUE self, VALUE basic_resp)
    {
        OCSP_REQUEST *req;
        OCSP_BASICRESP *bs;
        int res;

        GetOCSPReq(self, req);
        GetOCSPBasicRes(basic_resp, bs);
        res = OCSP_check_nonce(req, bs);

        return INT2NUM(res);
    }

initialize_copy(p1) click to toggle source

    static VALUE
    ossl_ocspreq_initialize_copy(VALUE self, VALUE other)
    {
        OCSP_REQUEST *req, *req_old, *req_new;

        rb_check_frozen(self);
        GetOCSPReq(self, req_old);
        GetOCSPReq(other, req);

        req_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_REQUEST), req);
        if (!req_new)
            ossl_raise(eOCSPError, "ASN1_item_dup");

        SetOCSPReq(self, req_new);
        OCSP_REQUEST_free(req_old);

        return self;
    }

sign(cert, key, certs = nil, flags = 0, digest = nil) → self click to toggle source

Signs this `OCSP` request using cert, key and optional digest. If digest is not specified, SHA-1 is used. certs is an optional `Array` of additional certificates which are included in the request in addition to the signer certificate. Note that if certs is `nil` or not given, flag OpenSSL::OCSP::NOCERTS is enabled. Pass an empty array to include only the signer certificate.

flags is a bitwise OR of the following constants:

OpenSSL::OCSP::NOCERTS

  Don't include any certificates in the request. certs will be ignored.

    static VALUE
    ossl_ocspreq_sign(int argc, VALUE *argv, VALUE self)
    {
        VALUE signer_cert, signer_key, certs, flags, digest;
        OCSP_REQUEST *req;
        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);
        GetOCSPReq(self, req);
        signer = GetX509CertPtr(signer_cert);
        key = GetPrivPKeyPtr(signer_key);
        if (!NIL_P(flags))
            flg = NUM2INT(flags);
        if (NIL_P(digest))
            md = EVP_sha1();
        else
            md = ossl_evp_get_digestbyname(digest);
        if (NIL_P(certs))
            flg |= OCSP_NOCERTS;
        else
            x509s = ossl_x509_ary2sk(certs);

        ret = OCSP_request_sign(req, signer, key, md, x509s, flg);
        sk_X509_pop_free(x509s, X509_free);
        if (!ret) ossl_raise(eOCSPError, NULL);

        return self;
    }

signed? → true or false click to toggle source

Returns `true` if the request is signed, `false` otherwise. Note that the validity of the signature is not checked. Use `verify` to verify that.

    static VALUE
    ossl_ocspreq_signed_p(VALUE self)
    {
        OCSP_REQUEST *req;

        GetOCSPReq(self, req);
        return OCSP_request_is_signed(req) ? Qtrue : Qfalse;
    }

to_der() click to toggle source

Returns this request as a DER-encoded string

    static VALUE
    ossl_ocspreq_to_der(VALUE self)
    {
        OCSP_REQUEST *req;
        VALUE str;
        unsigned char *p;
        long len;

        GetOCSPReq(self, req);
        if((len = i2d_OCSP_REQUEST(req, NULL)) <= 0)
            ossl_raise(eOCSPError, NULL);
        str = rb_str_new(0, len);
        p = (unsigned char *)RSTRING_PTR(str);
        if(i2d_OCSP_REQUEST(req, &p) <= 0)
            ossl_raise(eOCSPError, NULL);
        ossl_str_adjust(str, p);

        return str;
    }

verify(certificates, store, flags = 0) → true or false click to toggle source

Verifies this request using the given certificates and store. certificates is an array of `OpenSSL::X509::Certificate`, store is an `OpenSSL::X509::Store`.

Note that `false` is returned if the request does not have a signature. Use `signed?` to check whether the request is signed or not.

    static VALUE
    ossl_ocspreq_verify(int argc, VALUE *argv, VALUE self)
    {
        VALUE certs, store, flags;
        OCSP_REQUEST *req;
        STACK_OF(X509) *x509s;
        X509_STORE *x509st;
        int flg, result;

        rb_scan_args(argc, argv, "21", &certs, &store, &flags);
        GetOCSPReq(self, req);
        x509st = GetX509StorePtr(store);
        flg = NIL_P(flags) ? 0 : NUM2INT(flags);
        x509s = ossl_x509_ary2sk(certs);
        result = OCSP_request_verify(req, x509s, x509st, flg);
        sk_X509_pop_free(x509s, X509_free);
        if (result <= 0)
            ossl_clear_error();

        return result > 0 ? Qtrue : Qfalse;
    }