Class: OpenSSL::OCSP::BasicResponse

Inherits:
Object
  • Object
show all
Defined in:
ext/openssl/ossl_ocsp.c

Instance Method Summary collapse

Constructor Details

#OpenSSL::OCSP::BasicResponse.new(der_string = nil) ⇒ Object

Creates a new BasicResponse. If der_string is given, decodes der_string as DER.



702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
# File 'ext/openssl/ossl_ocsp.c', line 702

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;
}

Instance Method Details

#add_nonce(nonce = nil) ⇒ Object

Adds nonce to this response. If no nonce was provided a random nonce will be added.



755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
# File 'ext/openssl/ossl_ocsp.c', line 755

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, extensions) ⇒ Object

Adds a certificate status for certificate_id. status is the status, and must be one of these:

  • OpenSSL::OCSP::V_CERTSTATUS_GOOD

  • OpenSSL::OCSP::V_CERTSTATUS_REVOKED

  • OpenSSL::OCSP::V_CERTSTATUS_UNKNOWN

reason and revocation_time can be given only when status is OpenSSL::OCSP::V_CERTSTATUS_REVOKED. reason describes the reason for the revocation, and must be one of OpenSSL::OCSP::REVOKED_STATUS_* constants. revocation_time is the time when the certificate is revoked.

this_update and next_update indicate the time at which the status is verified to be correct and the time at or before which newer information will be available, respectively. next_update is optional.

extensions is an Array of OpenSSL::X509::Extension to be included in the SingleResponse. This is also optional.

Note that the times, revocation_time, this_update and next_update can be specified in either of Integer or Time object. If they are Integer, it is treated as the relative seconds from the current time.



820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
# File 'ext/openssl/ossl_ocsp.c', line 820

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);
    GetOCSPCertId(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(request) ⇒ Integer

Copies the nonce from request into this response. Returns 1 on success and 0 on failure.

Returns:



733
734
735
736
737
738
739
740
741
742
743
744
745
# File 'ext/openssl/ossl_ocsp.c', line 733

static VALUE
ossl_ocspbres_copy_nonce(VALUE self, VALUE request)
{
    OCSP_BASICRESP *bs;
    OCSP_REQUEST *req;
    int ret;

    GetOCSPBasicRes(self, bs);
    GetOCSPReq(request, req);
    ret = OCSP_copy_nonce(bs, req);

    return INT2NUM(ret);
}

#find_response(certificate_id) ⇒ SingleResponse | nil

Returns a SingleResponse whose CertId matches with certificate_id, or nil if this BasicResponse does not contain it.

Returns:



970
971
972
973
974
975
976
977
978
979
980
981
982
983
# File 'ext/openssl/ossl_ocsp.c', line 970

static VALUE
ossl_ocspbres_find_response(VALUE self, VALUE target)
{
    OCSP_BASICRESP *bs;
    OCSP_CERTID *id;
    int n;

    GetOCSPCertId(target, id);
    GetOCSPBasicRes(self, bs);

    if ((n = OCSP_resp_find(bs, id, -1)) == -1)
        return Qnil;
    return ossl_ocspsres_new(OCSP_resp_get0(bs, n));
}

#initialize_copy(other) ⇒ Object

:nodoc:



675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
# File 'ext/openssl/ossl_ocsp.c', line 675

static VALUE
ossl_ocspbres_initialize_copy(VALUE self, VALUE other)
{
    OCSP_BASICRESP *bs, *bs_old, *bs_new;

    rb_check_frozen(self);
    GetOCSPBasicRes(self, bs_old);
    GetOCSPBasicRes(other, bs);

    bs_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_BASICRESP), bs);
    if (!bs_new)
        ossl_raise(eOCSPError, "ASN1_item_dup");

    SetOCSPBasicRes(self, bs_new);
    OCSP_BASICRESP_free(bs_old);

    return self;
}

#responsesArray of SingleResponse

Returns an Array of SingleResponse for this BasicResponse.

Returns:



944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
# File 'ext/openssl/ossl_ocsp.c', line 944

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_new_capa(count);

    for (i = 0; i < count; i++) {
        rb_ary_push(ret, ossl_ocspsres_new(OCSP_resp_get0(bs, i)));
    }

    return ret;
}

#sign(cert, key, certs = nil, flags = 0, digest = nil) ⇒ self

Signs this OCSP response using the cert, key and optional digest. This behaves in the similar way as OpenSSL::OCSP::Request#sign.

flags can include:

OpenSSL::OCSP::NOCERTS

don’t include certificates

OpenSSL::OCSP::NOTIME

don’t set producedAt

OpenSSL::OCSP::RESPID_KEY

use signer’s public key hash as responderID

Returns:

  • (self)


998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
# File 'ext/openssl/ossl_ocsp.c', line 998

static VALUE
ossl_ocspbres_sign(int argc, VALUE *argv, VALUE self)
{
    VALUE signer_cert, signer_key, certs, flags, digest, md_holder;
    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);
    md = NIL_P(digest) ? NULL : ossl_evp_md_fetch(digest, &md_holder);
    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, "OCSP_basic_sign");

    return self;
}

#statusObject

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::Extension.

This should be superseded by BasicResponse#responses and #find_response that return SingleResponse.



898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
# File 'ext/openssl/ossl_ocsp.c', line 898

static VALUE
ossl_ocspbres_get_status(VALUE self)
{
    OCSP_BASICRESP *bs;

    GetOCSPBasicRes(self, bs);
    VALUE ret = rb_ary_new();
    int count = OCSP_resp_count(bs);
    for (int i = 0; i < count; i++) {
        OCSP_SINGLERESP *single = OCSP_resp_get0(bs, i);
        ASN1_TIME *revtime, *thisupd, *nextupd;
        int reason;

        int status = OCSP_single_get0_status(single, &reason, &revtime, &thisupd, &nextupd);
        if (status < 0)
            ossl_raise(eOCSPError, "OCSP_single_get0_status");

        VALUE ary = rb_ary_new();
        rb_ary_push(ary, ossl_ocspcid_new(OCSP_SINGLERESP_get0_id(single)));
        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);
        VALUE ext = rb_ary_new();
        int ext_count = OCSP_SINGLERESP_get_ext_count(single);
        for (int j = 0; j < ext_count; j++) {
            X509_EXTENSION *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_derString

Encodes this basic response into a DER-encoded string.

Returns:

  • (String)


1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
# File 'ext/openssl/ossl_ocsp.c', line 1065

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) ⇒ Boolean

Verifies the signature of the response using the given certificates and store. This works in the similar way as OpenSSL::OCSP::Request#verify.

Returns:

  • (Boolean)


1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
# File 'ext/openssl/ossl_ocsp.c', line 1037

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);
    result = OCSP_basic_verify(bs, x509s, x509st, flg);
    sk_X509_pop_free(x509s, X509_free);
    if (result <= 0)
        ossl_clear_error();

    return result > 0 ? Qtrue : Qfalse;
}