Ruby 1.9.2p136(2010-12-25revision30365)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

# ext/openssl/ossl_ocsp.c

Go to the documentation of this file.

    00001 /*
    00002  * $Id: ossl_ocsp.c 27437 2010-04-22 08:04:13Z nobu $
    00003  * 'OpenSSL for Ruby' project
    00004  * Copyright (C) 2003  Michal Rokos <m.rokos@sh.cvut.cz>
    00005  * Copyright (C) 2003  GOTOU Yuuzou <gotoyuzo@notwork.org>
    00006  * All rights reserved.
    00007  */
    00008 /*
    00009  * This program is licenced under the same licence as Ruby.
    00010  * (See the file 'LICENCE'.)
    00011  */
    00012 #include "ossl.h"
    00013
    00014 #if defined(OSSL_OCSP_ENABLED)
    00015
    00016 #define WrapOCSPReq(klass, obj, req) do { \
    00017     if(!req) ossl_raise(rb_eRuntimeError, "Request wasn't initialized!"); \
    00018     obj = Data_Wrap_Struct(klass, 0, OCSP_REQUEST_free, req); \
    00019 } while (0)
    00020 #define GetOCSPReq(obj, req) do { \
    00021     Data_Get_Struct(obj, OCSP_REQUEST, req); \
    00022     if(!req) ossl_raise(rb_eRuntimeError, "Request wasn't initialized!"); \
    00023 } while (0)
    00024 #define SafeGetOCSPReq(obj, req) do { \
    00025     OSSL_Check_Kind(obj, cOCSPReq); \
    00026     GetOCSPReq(obj, req); \
    00027 } while (0)
    00028
    00029 #define WrapOCSPRes(klass, obj, res) do { \
    00030     if(!res) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \
    00031     obj = Data_Wrap_Struct(klass, 0, OCSP_RESPONSE_free, res); \
    00032 } while (0)
    00033 #define GetOCSPRes(obj, res) do { \
    00034     Data_Get_Struct(obj, OCSP_RESPONSE, res); \
    00035     if(!res) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \
    00036 } while (0)
    00037 #define SafeGetOCSPRes(obj, res) do { \
    00038     OSSL_Check_Kind(obj, cOCSPRes); \
    00039     GetOCSPRes(obj, res); \
    00040 } while (0)
    00041
    00042 #define WrapOCSPBasicRes(klass, obj, res) do { \
    00043     if(!res) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \
    00044     obj = Data_Wrap_Struct(klass, 0, OCSP_BASICRESP_free, res); \
    00045 } while (0)
    00046 #define GetOCSPBasicRes(obj, res) do { \
    00047     Data_Get_Struct(obj, OCSP_BASICRESP, res); \
    00048     if(!res) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \
    00049 } while (0)
    00050 #define SafeGetOCSPBasicRes(obj, res) do { \
    00051     OSSL_Check_Kind(obj, cOCSPBasicRes); \
    00052     GetOCSPBasicRes(obj, res); \
    00053 } while (0)
    00054
    00055 #define WrapOCSPCertId(klass, obj, cid) do { \
    00056     if(!cid) ossl_raise(rb_eRuntimeError, "Cert ID wasn't initialized!"); \
    00057     obj = Data_Wrap_Struct(klass, 0, OCSP_CERTID_free, cid); \
    00058 } while (0)
    00059 #define GetOCSPCertId(obj, cid) do { \
    00060     Data_Get_Struct(obj, OCSP_CERTID, cid); \
    00061     if(!cid) ossl_raise(rb_eRuntimeError, "Cert ID wasn't initialized!"); \
    00062 } while (0)
    00063 #define SafeGetOCSPCertId(obj, cid) do { \
    00064     OSSL_Check_Kind(obj, cOCSPCertId); \
    00065     GetOCSPCertId(obj, cid); \
    00066 } while (0)
    00067
    00068 VALUE mOCSP;
    00069 VALUE eOCSPError;
    00070 VALUE cOCSPReq;
    00071 VALUE cOCSPRes;
    00072 VALUE cOCSPBasicRes;
    00073 VALUE cOCSPCertId;
    00074
    00075 /*
    00076  * Public
    00077  */
    00078 static VALUE
    00079 ossl_ocspcertid_new(OCSP_CERTID *cid)
    00080 {
    00081     VALUE obj;
    00082     WrapOCSPCertId(cOCSPCertId, obj, cid);
    00083     return obj;
    00084 }
    00085
    00086 /*
    00087  * OCSP::Resquest
    00088  */
    00089 static VALUE
    00090 ossl_ocspreq_alloc(VALUE klass)
    00091 {
    00092     OCSP_REQUEST *req;
    00093     VALUE obj;
    00094
    00095     if (!(req = OCSP_REQUEST_new()))
    00096         ossl_raise(eOCSPError, NULL);
    00097     WrapOCSPReq(klass, obj, req);
    00098
    00099     return obj;
    00100 }
    00101
    00102 static VALUE
    00103 ossl_ocspreq_initialize(int argc, VALUE *argv, VALUE self)
    00104 {
    00105     VALUE arg;
    00106     const unsigned char *p;
    00107
    00108     rb_scan_args(argc, argv, "01", &arg);
    00109     if(!NIL_P(arg)){
    00110         OCSP_REQUEST *req = DATA_PTR(self), *x;
    00111         arg = ossl_to_der_if_possible(arg);
    00112         StringValue(arg);
    00113         p = (unsigned char*)RSTRING_PTR(arg);
    00114         x = d2i_OCSP_REQUEST(&req, &p, RSTRING_LEN(arg));
    00115         DATA_PTR(self) = req;
    00116         if(!x){
    00117             ossl_raise(eOCSPError, "cannot load DER encoded request");
    00118         }
    00119     }
    00120
    00121     return self;
    00122 }
    00123
    00124 static VALUE
    00125 ossl_ocspreq_add_nonce(int argc, VALUE *argv, VALUE self)
    00126 {
    00127     OCSP_REQUEST *req;
    00128     VALUE val;
    00129     int ret;
    00130
    00131     rb_scan_args(argc, argv, "01", &val);
    00132     if(NIL_P(val)) {
    00133         GetOCSPReq(self, req);
    00134         ret = OCSP_request_add1_nonce(req, NULL, -1);
    00135     }
    00136     else{
    00137         StringValue(val);
    00138         GetOCSPReq(self, req);
    00139         ret = OCSP_request_add1_nonce(req, (unsigned char *)RSTRING_PTR(val), RSTRING_LEN(val));
    00140     }
    00141     if(!ret) ossl_raise(eOCSPError, NULL);
    00142
    00143     return self;
    00144 }
    00145
    00146 /* Check nonce validity in a request and response.
    00147  * Return value reflects result:
    00148  *  1: nonces present and equal.
    00149  *  2: nonces both absent.
    00150  *  3: nonce present in response only.
    00151  *  0: nonces both present and not equal.
    00152  * -1: nonce in request only.
    00153  *
    00154  *  For most responders clients can check return > 0.
    00155  *  If responder doesn't handle nonces return != 0 may be
    00156  *  necessary. return == 0 is always an error.
    00157  */
    00158 static VALUE
    00159 ossl_ocspreq_check_nonce(VALUE self, VALUE basic_resp)
    00160 {
    00161     OCSP_REQUEST *req;
    00162     OCSP_BASICRESP *bs;
    00163     int res;
    00164
    00165     GetOCSPReq(self, req);
    00166     SafeGetOCSPBasicRes(basic_resp, bs);
    00167     res = OCSP_check_nonce(req, bs);
    00168
    00169     return INT2NUM(res);
    00170 }
    00171
    00172 static VALUE
    00173 ossl_ocspreq_add_certid(VALUE self, VALUE certid)
    00174 {
    00175     OCSP_REQUEST *req;
    00176     OCSP_CERTID *id;
    00177
    00178     GetOCSPReq(self, req);
    00179     GetOCSPCertId(certid, id);
    00180     if(!OCSP_request_add0_id(req, OCSP_CERTID_dup(id)))
    00181         ossl_raise(eOCSPError, NULL);
    00182
    00183     return self;
    00184 }
    00185
    00186 static VALUE
    00187 ossl_ocspreq_get_certid(VALUE self)
    00188 {
    00189     OCSP_REQUEST *req;
    00190     OCSP_ONEREQ *one;
    00191     OCSP_CERTID *id;
    00192     VALUE ary, tmp;
    00193     int i, count;
    00194
    00195     GetOCSPReq(self, req);
    00196     count = OCSP_request_onereq_count(req);
    00197     ary = (count > 0) ? rb_ary_new() : Qnil;
    00198     for(i = 0; i < count; i++){
    00199         one = OCSP_request_onereq_get0(req, i);
    00200         if(!(id = OCSP_CERTID_dup(OCSP_onereq_get0_id(one))))
    00201             ossl_raise(eOCSPError, NULL);
    00202         WrapOCSPCertId(cOCSPCertId, tmp, id);
    00203         rb_ary_push(ary, tmp);
    00204     }
    00205
    00206     return ary;
    00207 }
    00208
    00209 static VALUE
    00210 ossl_ocspreq_sign(int argc, VALUE *argv, VALUE self)
    00211 {
    00212     VALUE signer_cert, signer_key, certs, flags;
    00213     OCSP_REQUEST *req;
    00214     X509 *signer;
    00215     EVP_PKEY *key;
    00216     STACK_OF(X509) *x509s;
    00217     unsigned long flg;
    00218     int ret;
    00219
    00220     rb_scan_args(argc, argv, "22", &signer_cert, &signer_key, &certs, &flags);
    00221     signer = GetX509CertPtr(signer_cert);
    00222     key = GetPrivPKeyPtr(signer_key);
    00223     flg = NIL_P(flags) ? 0 : NUM2INT(flags);
    00224     if(NIL_P(certs)){
    00225         x509s = sk_X509_new_null();
    00226         flags |= OCSP_NOCERTS;
    00227     }
    00228     else x509s = ossl_x509_ary2sk(certs);
    00229     GetOCSPReq(self, req);
    00230     ret = OCSP_request_sign(req, signer, key, EVP_sha1(), x509s, flg);
    00231     sk_X509_pop_free(x509s, X509_free);
    00232     if(!ret) ossl_raise(eOCSPError, NULL);
    00233
    00234     return self;
    00235 }
    00236
    00237 static VALUE
    00238 ossl_ocspreq_verify(int argc, VALUE *argv, VALUE self)
    00239 {
    00240     VALUE certs, store, flags;
    00241     OCSP_REQUEST *req;
    00242     STACK_OF(X509) *x509s;
    00243     X509_STORE *x509st;
    00244     int flg, result;
    00245
    00246     rb_scan_args(argc, argv, "21", &certs, &store, &flags);
    00247     x509st = GetX509StorePtr(store);
    00248     flg = NIL_P(flags) ? 0 : INT2NUM(flags);
    00249     x509s = ossl_x509_ary2sk(certs);
    00250     GetOCSPReq(self, req);
    00251     result = OCSP_request_verify(req, x509s, x509st, flg);
    00252     sk_X509_pop_free(x509s, X509_free);
    00253     if(!result) rb_warn("%s", ERR_error_string(ERR_peek_error(), NULL));
    00254
    00255     return result ? Qtrue : Qfalse;
    00256 }
    00257
    00258 static VALUE
    00259 ossl_ocspreq_to_der(VALUE self)
    00260 {
    00261     OCSP_REQUEST *req;
    00262     VALUE str;
    00263     unsigned char *p;
    00264     long len;
    00265
    00266     GetOCSPReq(self, req);
    00267     if((len = i2d_OCSP_REQUEST(req, NULL)) <= 0)
    00268         ossl_raise(eOCSPError, NULL);
    00269     str = rb_str_new(0, len);
    00270     p = (unsigned char *)RSTRING_PTR(str);
    00271     if(i2d_OCSP_REQUEST(req, &p) <= 0)
    00272         ossl_raise(eOCSPError, NULL);
    00273     ossl_str_adjust(str, p);
    00274
    00275     return str;
    00276 }
    00277
    00278 /*
    00279  * OCSP::Response
    00280  */
    00281 static VALUE
    00282 ossl_ocspres_s_create(VALUE klass, VALUE status, VALUE basic_resp)
    00283 {
    00284     OCSP_BASICRESP *bs;
    00285     OCSP_RESPONSE *res;
    00286     VALUE obj;
    00287     int st = NUM2INT(status);
    00288
    00289     if(NIL_P(basic_resp)) bs = NULL;
    00290     else GetOCSPBasicRes(basic_resp, bs); /* NO NEED TO DUP */
    00291     if(!(res = OCSP_response_create(st, bs)))
    00292         ossl_raise(eOCSPError, NULL);
    00293     WrapOCSPRes(klass, obj, res);
    00294
    00295     return obj;
    00296 }
    00297
    00298 static VALUE
    00299 ossl_ocspres_alloc(VALUE klass)
    00300 {
    00301     OCSP_RESPONSE *res;
    00302     VALUE obj;
    00303
    00304     if(!(res = OCSP_RESPONSE_new()))
    00305         ossl_raise(eOCSPError, NULL);
    00306     WrapOCSPRes(klass, obj, res);
    00307
    00308     return obj;
    00309 }
    00310
    00311 static VALUE
    00312 ossl_ocspres_initialize(int argc, VALUE *argv, VALUE self)
    00313 {
    00314     VALUE arg;
    00315     const unsigned char *p;
    00316
    00317     rb_scan_args(argc, argv, "01", &arg);
    00318     if(!NIL_P(arg)){
    00319         OCSP_RESPONSE *res = DATA_PTR(self), *x;
    00320         arg = ossl_to_der_if_possible(arg);
    00321         StringValue(arg);
    00322         p = (unsigned char *)RSTRING_PTR(arg);
    00323         x = d2i_OCSP_RESPONSE(&res, &p, RSTRING_LEN(arg));
    00324         DATA_PTR(self) = res;
    00325         if(!x){
    00326             ossl_raise(eOCSPError, "cannot load DER encoded response");
    00327         }
    00328     }
    00329
    00330     return self;
    00331 }
    00332
    00333 static VALUE
    00334 ossl_ocspres_status(VALUE self)
    00335 {
    00336     OCSP_RESPONSE *res;
    00337     int st;
    00338
    00339     GetOCSPRes(self, res);
    00340     st = OCSP_response_status(res);
    00341
    00342     return INT2NUM(st);
    00343 }
    00344
    00345 static VALUE
    00346 ossl_ocspres_status_string(VALUE self)
    00347 {
    00348     OCSP_RESPONSE *res;
    00349     int st;
    00350
    00351     GetOCSPRes(self, res);
    00352     st = OCSP_response_status(res);
    00353
    00354     return rb_str_new2(OCSP_response_status_str(st));
    00355 }
    00356
    00357 static VALUE
    00358 ossl_ocspres_get_basic(VALUE self)
    00359 {
    00360     OCSP_RESPONSE *res;
    00361     OCSP_BASICRESP *bs;
    00362     VALUE ret;
    00363
    00364     GetOCSPRes(self, res);
    00365     if(!(bs = OCSP_response_get1_basic(res)))
    00366         return Qnil;
    00367     WrapOCSPBasicRes(cOCSPBasicRes, ret, bs);
    00368
    00369     return ret;
    00370 }
    00371
    00372 static VALUE
    00373 ossl_ocspres_to_der(VALUE self)
    00374 {
    00375     OCSP_RESPONSE *res;
    00376     VALUE str;
    00377     long len;
    00378     unsigned char *p;
    00379
    00380     GetOCSPRes(self, res);
    00381     if((len = i2d_OCSP_RESPONSE(res, NULL)) <= 0)
    00382         ossl_raise(eOCSPError, NULL);
    00383     str = rb_str_new(0, len);
    00384     p = (unsigned char *)RSTRING_PTR(str);
    00385     if(i2d_OCSP_RESPONSE(res, &p) <= 0)
    00386         ossl_raise(eOCSPError, NULL);
    00387     ossl_str_adjust(str, p);
    00388
    00389     return str;
    00390 }
    00391
    00392 /*
    00393  * OCSP::BasicResponse
    00394  */
    00395 static VALUE
    00396 ossl_ocspbres_alloc(VALUE klass)
    00397 {
    00398     OCSP_BASICRESP *bs;
    00399     VALUE obj;
    00400
    00401     if(!(bs = OCSP_BASICRESP_new()))
    00402         ossl_raise(eOCSPError, NULL);
    00403     WrapOCSPBasicRes(klass, obj, bs);
    00404
    00405     return obj;
    00406 }
    00407
    00408 static VALUE
    00409 ossl_ocspbres_initialize(int argc, VALUE *argv, VALUE self)
    00410 {
    00411     return self;
    00412 }
    00413
    00414 static VALUE
    00415 ossl_ocspbres_copy_nonce(VALUE self, VALUE request)
    00416 {
    00417     OCSP_BASICRESP *bs;
    00418     OCSP_REQUEST *req;
    00419     int ret;
    00420
    00421     GetOCSPBasicRes(self, bs);
    00422     SafeGetOCSPReq(request, req);
    00423     ret = OCSP_copy_nonce(bs, req);
    00424
    00425     return INT2NUM(ret);
    00426 }
    00427
    00428 static VALUE
    00429 ossl_ocspbres_add_nonce(int argc, VALUE *argv, VALUE self)
    00430 {
    00431     OCSP_BASICRESP *bs;
    00432     VALUE val;
    00433     int ret;
    00434
    00435     rb_scan_args(argc, argv, "01", &val);
    00436     if(NIL_P(val)) {
    00437         GetOCSPBasicRes(self, bs);
    00438         ret = OCSP_basic_add1_nonce(bs, NULL, -1);
    00439     }
    00440     else{
    00441         StringValue(val);
    00442         GetOCSPBasicRes(self, bs);
    00443         ret = OCSP_basic_add1_nonce(bs, (unsigned char *)RSTRING_PTR(val), RSTRING_LEN(val));
    00444     }
    00445     if(!ret) ossl_raise(eOCSPError, NULL);
    00446
    00447     return self;
    00448 }
    00449
    00450 static VALUE
    00451 ossl_ocspbres_add_status(VALUE self, VALUE cid, VALUE status,
    00452                          VALUE reason, VALUE revtime,
    00453                          VALUE thisupd, VALUE nextupd, VALUE ext)
    00454 {
    00455     OCSP_BASICRESP *bs;
    00456     OCSP_SINGLERESP *single;
    00457     OCSP_CERTID *id;
    00458     int st, rsn;
    00459     ASN1_TIME *ths, *nxt, *rev;
    00460     int error, i, rstatus = 0;
    00461     VALUE tmp;
    00462
    00463     st = NUM2INT(status);
    00464     rsn = NIL_P(status) ? 0 : NUM2INT(reason);
    00465     if(!NIL_P(ext)){
    00466         /* All ary's members should be X509Extension */
    00467         Check_Type(ext, T_ARRAY);
    00468         for (i = 0; i < RARRAY_LEN(ext); i++)
    00469             OSSL_Check_Kind(RARRAY_PTR(ext)[i], cX509Ext);
    00470     }
    00471
    00472     error = 0;
    00473     ths = nxt = rev = NULL;
    00474     if(!NIL_P(revtime)){
    00475         tmp = rb_protect(rb_Integer, revtime, &rstatus);
    00476         if(rstatus) goto err;
    00477         rev = X509_gmtime_adj(NULL, NUM2INT(tmp));
    00478     }
    00479     tmp = rb_protect(rb_Integer, thisupd, &rstatus);
    00480     if(rstatus) goto err;
    00481     ths = X509_gmtime_adj(NULL, NUM2INT(tmp));
    00482     tmp = rb_protect(rb_Integer, nextupd, &rstatus);
    00483     if(rstatus) goto err;
    00484     nxt = X509_gmtime_adj(NULL, NUM2INT(tmp));
    00485
    00486     GetOCSPBasicRes(self, bs);
    00487     SafeGetOCSPCertId(cid, id);
    00488     if(!(single = OCSP_basic_add1_status(bs, id, st, rsn, rev, ths, nxt))){
    00489         error = 1;
    00490         goto err;
    00491     }
    00492
    00493     if(!NIL_P(ext)){
    00494         X509_EXTENSION *x509ext;
    00495         sk_X509_EXTENSION_pop_free(single->singleExtensions, X509_EXTENSION_free);
    00496         single->singleExtensions = NULL;
    00497         for(i = 0; i < RARRAY_LEN(ext); i++){
    00498             x509ext = DupX509ExtPtr(RARRAY_PTR(ext)[i]);
    00499             if(!OCSP_SINGLERESP_add_ext(single, x509ext, -1)){
    00500                 X509_EXTENSION_free(x509ext);
    00501                 error = 1;
    00502                 goto err;
    00503             }
    00504             X509_EXTENSION_free(x509ext);
    00505         }
    00506     }
    00507
    00508  err:
    00509     ASN1_TIME_free(ths);
    00510     ASN1_TIME_free(nxt);
    00511     ASN1_TIME_free(rev);
    00512     if(error) ossl_raise(eOCSPError, NULL);
    00513     if(rstatus) rb_jump_tag(rstatus);
    00514
    00515     return self;
    00516 }
    00517
    00518 static VALUE
    00519 ossl_ocspbres_get_status(VALUE self)
    00520 {
    00521     OCSP_BASICRESP *bs;
    00522     OCSP_SINGLERESP *single;
    00523     OCSP_CERTID *cid;
    00524     ASN1_TIME *revtime, *thisupd, *nextupd;
    00525     int status, reason;
    00526     X509_EXTENSION *x509ext;
    00527     VALUE ret, ary, ext;
    00528     int count, ext_count, i, j;
    00529
    00530     GetOCSPBasicRes(self, bs);
    00531     ret = rb_ary_new();
    00532     count = OCSP_resp_count(bs);
    00533     for(i = 0; i < count; i++){
    00534         single = OCSP_resp_get0(bs, i);
    00535         if(!single) continue;
    00536
    00537         revtime = thisupd = nextupd = NULL;
    00538         status = OCSP_single_get0_status(single, &reason, &revtime,
    00539                                          &thisupd, &nextupd);
    00540         if(status < 0) continue;
    00541         if(!(cid = OCSP_CERTID_dup(single->certId)))
    00542             ossl_raise(eOCSPError, NULL);
    00543         ary = rb_ary_new();
    00544         rb_ary_push(ary, ossl_ocspcertid_new(cid));
    00545         rb_ary_push(ary, INT2NUM(status));
    00546         rb_ary_push(ary, INT2NUM(reason));
    00547         rb_ary_push(ary, revtime ? asn1time_to_time(revtime) : Qnil);
    00548         rb_ary_push(ary, thisupd ? asn1time_to_time(thisupd) : Qnil);
    00549         rb_ary_push(ary, nextupd ? asn1time_to_time(nextupd) : Qnil);
    00550         ext = rb_ary_new();
    00551         ext_count = OCSP_SINGLERESP_get_ext_count(single);
    00552         for(j = 0; j < ext_count; j++){
    00553             x509ext = OCSP_SINGLERESP_get_ext(single, j);
    00554             rb_ary_push(ext, ossl_x509ext_new(x509ext));
    00555         }
    00556         rb_ary_push(ary, ext);
    00557         rb_ary_push(ret, ary);
    00558     }
    00559
    00560     return ret;
    00561 }
    00562
    00563 static VALUE
    00564 ossl_ocspbres_sign(int argc, VALUE *argv, VALUE self)
    00565 {
    00566     VALUE signer_cert, signer_key, certs, flags;
    00567     OCSP_BASICRESP *bs;
    00568     X509 *signer;
    00569     EVP_PKEY *key;
    00570     STACK_OF(X509) *x509s;
    00571     unsigned long flg;
    00572     int ret;
    00573
    00574     rb_scan_args(argc, argv, "22", &signer_cert, &signer_key, &certs, &flags);
    00575     signer = GetX509CertPtr(signer_cert);
    00576     key = GetPrivPKeyPtr(signer_key);
    00577     flg = NIL_P(flags) ? 0 : NUM2INT(flags);
    00578     if(NIL_P(certs)){
    00579         x509s = sk_X509_new_null();
    00580         flg |= OCSP_NOCERTS;
    00581     }
    00582     else{
    00583         x509s = ossl_x509_ary2sk(certs);
    00584     }
    00585     GetOCSPBasicRes(self, bs);
    00586     ret = OCSP_basic_sign(bs, signer, key, EVP_sha1(), x509s, flg);
    00587     sk_X509_pop_free(x509s, X509_free);
    00588     if(!ret) ossl_raise(eOCSPError, NULL);
    00589
    00590     return self;
    00591 }
    00592
    00593 static VALUE
    00594 ossl_ocspbres_verify(int argc, VALUE *argv, VALUE self)
    00595 {
    00596     VALUE certs, store, flags, result;
    00597     OCSP_BASICRESP *bs;
    00598     STACK_OF(X509) *x509s;
    00599     X509_STORE *x509st;
    00600     int flg;
    00601
    00602     rb_scan_args(argc, argv, "21", &certs, &store, &flags);
    00603     x509st = GetX509StorePtr(store);
    00604     flg = NIL_P(flags) ? 0 : INT2NUM(flags);
    00605     x509s = ossl_x509_ary2sk(certs);
    00606     GetOCSPBasicRes(self, bs);
    00607     result = OCSP_basic_verify(bs, x509s, x509st, flg) > 0 ? Qtrue : Qfalse;
    00608     sk_X509_pop_free(x509s, X509_free);
    00609     if(!result) rb_warn("%s", ERR_error_string(ERR_peek_error(), NULL));
    00610
    00611     return result;
    00612 }
    00613
    00614 /*
    00615  * OCSP::CertificateId
    00616  */
    00617 static VALUE
    00618 ossl_ocspcid_alloc(VALUE klass)
    00619 {
    00620     OCSP_CERTID *id;
    00621     VALUE obj;
    00622
    00623     if(!(id = OCSP_CERTID_new()))
    00624         ossl_raise(eOCSPError, NULL);
    00625     WrapOCSPCertId(klass, obj, id);
    00626
    00627     return obj;
    00628 }
    00629
    00630 static VALUE
    00631 ossl_ocspcid_initialize(VALUE self, VALUE subject, VALUE issuer)
    00632 {
    00633     OCSP_CERTID *id, *newid;
    00634     X509 *x509s, *x509i;
    00635
    00636     x509s = GetX509CertPtr(subject); /* NO NEED TO DUP */
    00637     x509i = GetX509CertPtr(issuer); /* NO NEED TO DUP */
    00638     if(!(newid = OCSP_cert_to_id(NULL, x509s, x509i)))
    00639         ossl_raise(eOCSPError, NULL);
    00640     GetOCSPCertId(self, id);
    00641     OCSP_CERTID_free(id);
    00642     RDATA(self)->data = newid;
    00643
    00644     return self;
    00645 }
    00646
    00647 static VALUE
    00648 ossl_ocspcid_cmp(VALUE self, VALUE other)
    00649 {
    00650     OCSP_CERTID *id, *id2;
    00651     int result;
    00652
    00653     GetOCSPCertId(self, id);
    00654     SafeGetOCSPCertId(other, id2);
    00655     result = OCSP_id_cmp(id, id2);
    00656
    00657     return (result == 0) ? Qtrue : Qfalse;
    00658 }
    00659
    00660 static VALUE
    00661 ossl_ocspcid_cmp_issuer(VALUE self, VALUE other)
    00662 {
    00663     OCSP_CERTID *id, *id2;
    00664     int result;
    00665
    00666     GetOCSPCertId(self, id);
    00667     SafeGetOCSPCertId(other, id2);
    00668     result = OCSP_id_issuer_cmp(id, id2);
    00669
    00670     return (result == 0) ? Qtrue : Qfalse;
    00671 }
    00672
    00673 static VALUE
    00674 ossl_ocspcid_get_serial(VALUE self)
    00675 {
    00676     OCSP_CERTID *id;
    00677
    00678     GetOCSPCertId(self, id);
    00679
    00680     return asn1integer_to_num(id->serialNumber);
    00681 }
    00682
    00683 void
    00684 Init_ossl_ocsp()
    00685 {
    00686     mOCSP = rb_define_module_under(mOSSL, "OCSP");
    00687
    00688     eOCSPError = rb_define_class_under(mOCSP, "OCSPError", eOSSLError);
    00689
    00690     cOCSPReq = rb_define_class_under(mOCSP, "Request", rb_cObject);
    00691     rb_define_alloc_func(cOCSPReq, ossl_ocspreq_alloc);
    00692     rb_define_method(cOCSPReq, "initialize", ossl_ocspreq_initialize, -1);
    00693     rb_define_method(cOCSPReq, "add_nonce", ossl_ocspreq_add_nonce, -1);
    00694     rb_define_method(cOCSPReq, "check_nonce", ossl_ocspreq_check_nonce, 1);
    00695     rb_define_method(cOCSPReq, "add_certid", ossl_ocspreq_add_certid, 1);
    00696     rb_define_method(cOCSPReq, "certid", ossl_ocspreq_get_certid, 0);
    00697     rb_define_method(cOCSPReq, "sign", ossl_ocspreq_sign, -1);
    00698     rb_define_method(cOCSPReq, "verify", ossl_ocspreq_verify, -1);
    00699     rb_define_method(cOCSPReq, "to_der", ossl_ocspreq_to_der, 0);
    00700
    00701     cOCSPRes = rb_define_class_under(mOCSP, "Response", rb_cObject);
    00702     rb_define_singleton_method(cOCSPRes, "create", ossl_ocspres_s_create, 2);
    00703     rb_define_alloc_func(cOCSPRes, ossl_ocspres_alloc);
    00704     rb_define_method(cOCSPRes, "initialize", ossl_ocspres_initialize, -1);
    00705     rb_define_method(cOCSPRes, "status", ossl_ocspres_status, 0);
    00706     rb_define_method(cOCSPRes, "status_string", ossl_ocspres_status_string, 0);
    00707     rb_define_method(cOCSPRes, "basic", ossl_ocspres_get_basic, 0);
    00708     rb_define_method(cOCSPRes, "to_der", ossl_ocspres_to_der, 0);
    00709
    00710     cOCSPBasicRes = rb_define_class_under(mOCSP, "BasicResponse", rb_cObject);
    00711     rb_define_alloc_func(cOCSPBasicRes, ossl_ocspbres_alloc);
    00712     rb_define_method(cOCSPBasicRes, "initialize", ossl_ocspbres_initialize, -1);
    00713     rb_define_method(cOCSPBasicRes, "copy_nonce", ossl_ocspbres_copy_nonce, 1);
    00714     rb_define_method(cOCSPBasicRes, "add_nonce", ossl_ocspbres_add_nonce, -1);
    00715     rb_define_method(cOCSPBasicRes, "add_status", ossl_ocspbres_add_status, 7);
    00716     rb_define_method(cOCSPBasicRes, "status", ossl_ocspbres_get_status, 0);
    00717     rb_define_method(cOCSPBasicRes, "sign", ossl_ocspbres_sign, -1);
    00718     rb_define_method(cOCSPBasicRes, "verify", ossl_ocspbres_verify, -1);
    00719
    00720     cOCSPCertId = rb_define_class_under(mOCSP, "CertificateId", rb_cObject);
    00721     rb_define_alloc_func(cOCSPCertId, ossl_ocspcid_alloc);
    00722     rb_define_method(cOCSPCertId, "initialize", ossl_ocspcid_initialize, 2);
    00723     rb_define_method(cOCSPCertId, "cmp", ossl_ocspcid_cmp, 1);
    00724     rb_define_method(cOCSPCertId, "cmp_issuer", ossl_ocspcid_cmp_issuer, 1);
    00725     rb_define_method(cOCSPCertId, "serial", ossl_ocspcid_get_serial, 0);
    00726
    00727 #define DefOCSPConst(x) rb_define_const(mOCSP, #x, INT2NUM(OCSP_##x))
    00728
    00729     DefOCSPConst(RESPONSE_STATUS_SUCCESSFUL);
    00730     DefOCSPConst(RESPONSE_STATUS_MALFORMEDREQUEST);
    00731     DefOCSPConst(RESPONSE_STATUS_INTERNALERROR);
    00732     DefOCSPConst(RESPONSE_STATUS_TRYLATER);
    00733     DefOCSPConst(RESPONSE_STATUS_SIGREQUIRED);
    00734     DefOCSPConst(RESPONSE_STATUS_UNAUTHORIZED);
    00735
    00736     DefOCSPConst(REVOKED_STATUS_NOSTATUS);
    00737     DefOCSPConst(REVOKED_STATUS_UNSPECIFIED);
    00738     DefOCSPConst(REVOKED_STATUS_KEYCOMPROMISE);
    00739     DefOCSPConst(REVOKED_STATUS_CACOMPROMISE);
    00740     DefOCSPConst(REVOKED_STATUS_AFFILIATIONCHANGED);
    00741     DefOCSPConst(REVOKED_STATUS_SUPERSEDED);
    00742     DefOCSPConst(REVOKED_STATUS_CESSATIONOFOPERATION);
    00743     DefOCSPConst(REVOKED_STATUS_CERTIFICATEHOLD);
    00744     DefOCSPConst(REVOKED_STATUS_REMOVEFROMCRL);
    00745
    00746     DefOCSPConst(NOCERTS);
    00747     DefOCSPConst(NOINTERN);
    00748     DefOCSPConst(NOSIGS);
    00749     DefOCSPConst(NOCHAIN);
    00750     DefOCSPConst(NOVERIFY);
    00751     DefOCSPConst(NOEXPLICIT);
    00752     DefOCSPConst(NOCASIGN);
    00753     DefOCSPConst(NODELEGATED);
    00754     DefOCSPConst(NOCHECKS);
    00755     DefOCSPConst(TRUSTOTHER);
    00756     DefOCSPConst(RESPID_KEY);
    00757     DefOCSPConst(NOTIME);
    00758
    00759 #define DefOCSPVConst(x) rb_define_const(mOCSP, "V_" #x, INT2NUM(V_OCSP_##x))
    00760
    00761     DefOCSPVConst(CERTSTATUS_GOOD);
    00762     DefOCSPVConst(CERTSTATUS_REVOKED);
    00763     DefOCSPVConst(CERTSTATUS_UNKNOWN);
    00764     DefOCSPVConst(RESPID_NAME);
    00765     DefOCSPVConst(RESPID_KEY);
    00766 }
    00767
    00768 #else /* ! OSSL_OCSP_ENABLED */
    00769 void
    00770 Init_ossl_ocsp()
    00771 {
    00772 }
    00773 #endif
    00774