Ruby  2.0.0p247(2013-06-27revision41674)
ext/openssl/ossl_x509store.c
Go to the documentation of this file.
00001 /*
00002  * $Id: ossl_x509store.c 37070 2012-10-02 19:36:26Z drbrain $
00003  * 'OpenSSL for Ruby' project
00004  * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
00005  * All rights reserved.
00006  */
00007 /*
00008  * This program is licenced under the same licence as Ruby.
00009  * (See the file 'LICENCE'.)
00010  */
00011 #include "ossl.h"
00012 
00013 #define WrapX509Store(klass, obj, st) do { \
00014     if (!(st)) { \
00015         ossl_raise(rb_eRuntimeError, "STORE wasn't initialized!"); \
00016     } \
00017     (obj) = Data_Wrap_Struct((klass), 0, X509_STORE_free, (st)); \
00018 } while (0)
00019 #define GetX509Store(obj, st) do { \
00020     Data_Get_Struct((obj), X509_STORE, (st)); \
00021     if (!(st)) { \
00022         ossl_raise(rb_eRuntimeError, "STORE wasn't initialized!"); \
00023     } \
00024 } while (0)
00025 #define SafeGetX509Store(obj, st) do { \
00026     OSSL_Check_Kind((obj), cX509Store); \
00027     GetX509Store((obj), (st)); \
00028 } while (0)
00029 
00030 #define WrapX509StCtx(klass, obj, ctx) do { \
00031     if (!(ctx)) { \
00032         ossl_raise(rb_eRuntimeError, "STORE_CTX wasn't initialized!"); \
00033     } \
00034     (obj) = Data_Wrap_Struct((klass), 0, ossl_x509stctx_free, (ctx)); \
00035 } while (0)
00036 #define GetX509StCtx(obj, ctx) do { \
00037     Data_Get_Struct((obj), X509_STORE_CTX, (ctx)); \
00038     if (!(ctx)) { \
00039         ossl_raise(rb_eRuntimeError, "STORE_CTX is out of scope!"); \
00040     } \
00041 } while (0)
00042 #define SafeGetX509StCtx(obj, storep) do { \
00043     OSSL_Check_Kind((obj), cX509StoreContext); \
00044     GetX509Store((obj), (ctx)); \
00045 } while (0)
00046 
00047 /*
00048  * Classes
00049  */
00050 VALUE cX509Store;
00051 VALUE cX509StoreContext;
00052 VALUE eX509StoreError;
00053 
00054 /*
00055  * Public functions
00056  */
00057 VALUE
00058 ossl_x509store_new(X509_STORE *store)
00059 {
00060     VALUE obj;
00061 
00062     WrapX509Store(cX509Store, obj, store);
00063 
00064     return obj;
00065 }
00066 
00067 X509_STORE *
00068 GetX509StorePtr(VALUE obj)
00069 {
00070     X509_STORE *store;
00071 
00072     SafeGetX509Store(obj, store);
00073 
00074     return store;
00075 }
00076 
00077 X509_STORE *
00078 DupX509StorePtr(VALUE obj)
00079 {
00080     X509_STORE *store;
00081 
00082     SafeGetX509Store(obj, store);
00083     CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE);
00084 
00085     return store;
00086 }
00087 
00088 /*
00089  * Private functions
00090  */
00091 static VALUE
00092 ossl_x509store_alloc(VALUE klass)
00093 {
00094     X509_STORE *store;
00095     VALUE obj;
00096 
00097     if((store = X509_STORE_new()) == NULL){
00098         ossl_raise(eX509StoreError, NULL);
00099     }
00100     WrapX509Store(klass, obj, store);
00101 
00102     return obj;
00103 }
00104 
00105 /*
00106  * General callback for OpenSSL verify
00107  */
00108 static VALUE
00109 ossl_x509store_set_vfy_cb(VALUE self, VALUE cb)
00110 {
00111     X509_STORE *store;
00112 
00113     GetX509Store(self, store);
00114     X509_STORE_set_ex_data(store, ossl_verify_cb_idx, (void*)cb);
00115     rb_iv_set(self, "@verify_callback", cb);
00116 
00117     return cb;
00118 }
00119 
00120 
00121 /*
00122  * call-seq:
00123  *    X509::Store.new => store
00124  *
00125  */
00126 static VALUE
00127 ossl_x509store_initialize(int argc, VALUE *argv, VALUE self)
00128 {
00129     X509_STORE *store;
00130 
00131 /* BUG: This method takes any number of arguments but appears to ignore them. */
00132     GetX509Store(self, store);
00133     store->ex_data.sk = NULL;
00134     X509_STORE_set_verify_cb_func(store, ossl_verify_cb);
00135     ossl_x509store_set_vfy_cb(self, Qnil);
00136 
00137 #if (OPENSSL_VERSION_NUMBER < 0x00907000L)
00138     rb_iv_set(self, "@flags", INT2NUM(0));
00139     rb_iv_set(self, "@purpose", INT2NUM(0));
00140     rb_iv_set(self, "@trust", INT2NUM(0));
00141 #endif
00142 
00143     /* last verification status */
00144     rb_iv_set(self, "@error", Qnil);
00145     rb_iv_set(self, "@error_string", Qnil);
00146     rb_iv_set(self, "@chain", Qnil);
00147     rb_iv_set(self, "@time", Qnil);
00148 
00149     return self;
00150 }
00151 
00152 static VALUE
00153 ossl_x509store_set_flags(VALUE self, VALUE flags)
00154 {
00155 #if (OPENSSL_VERSION_NUMBER >= 0x00907000L)
00156     X509_STORE *store;
00157     long f = NUM2LONG(flags);
00158 
00159     GetX509Store(self, store);
00160     X509_STORE_set_flags(store, f);
00161 #else
00162     rb_iv_set(self, "@flags", flags);
00163 #endif
00164 
00165     return flags;
00166 }
00167 
00168 static VALUE
00169 ossl_x509store_set_purpose(VALUE self, VALUE purpose)
00170 {
00171 #if (OPENSSL_VERSION_NUMBER >= 0x00907000L)
00172     X509_STORE *store;
00173     int p = NUM2INT(purpose);
00174 
00175     GetX509Store(self, store);
00176     X509_STORE_set_purpose(store, p);
00177 #else
00178     rb_iv_set(self, "@purpose", purpose);
00179 #endif
00180 
00181     return purpose;
00182 }
00183 
00184 static VALUE
00185 ossl_x509store_set_trust(VALUE self, VALUE trust)
00186 {
00187 #if (OPENSSL_VERSION_NUMBER >= 0x00907000L)
00188     X509_STORE *store;
00189     int t = NUM2INT(trust);
00190 
00191     GetX509Store(self, store);
00192     X509_STORE_set_trust(store, t);
00193 #else
00194     rb_iv_set(self, "@trust", trust);
00195 #endif
00196 
00197     return trust;
00198 }
00199 
00200 static VALUE
00201 ossl_x509store_set_time(VALUE self, VALUE time)
00202 {
00203     rb_iv_set(self, "@time", time);
00204     return time;
00205 }
00206 
00207 /*
00208  * call-seq:
00209  *   store.add_file(file) -> store
00210  *
00211  *
00212  * Adds the certificates in +file+ to the certificate store.  The +file+ can
00213  * contain multiple PEM-encoded certificates.
00214  */
00215 
00216 static VALUE
00217 ossl_x509store_add_file(VALUE self, VALUE file)
00218 {
00219     X509_STORE *store;
00220     X509_LOOKUP *lookup;
00221     char *path = NULL;
00222 
00223     if(file != Qnil){
00224         SafeStringValue(file);
00225         path = RSTRING_PTR(file);
00226     }
00227     GetX509Store(self, store);
00228     lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
00229     if(lookup == NULL) ossl_raise(eX509StoreError, NULL);
00230     if(X509_LOOKUP_load_file(lookup, path, X509_FILETYPE_PEM) != 1){
00231         ossl_raise(eX509StoreError, NULL);
00232     }
00233 
00234     return self;
00235 }
00236 
00237 static VALUE
00238 ossl_x509store_add_path(VALUE self, VALUE dir)
00239 {
00240     X509_STORE *store;
00241     X509_LOOKUP *lookup;
00242     char *path = NULL;
00243 
00244     if(dir != Qnil){
00245         SafeStringValue(dir);
00246         path = RSTRING_PTR(dir);
00247     }
00248     GetX509Store(self, store);
00249     lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
00250     if(lookup == NULL) ossl_raise(eX509StoreError, NULL);
00251     if(X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM) != 1){
00252         ossl_raise(eX509StoreError, NULL);
00253     }
00254 
00255     return self;
00256 }
00257 
00258 /*
00259  * call-seq:
00260  *   store.set_default_path
00261  *
00262  * Adds the default certificates to the certificate store.  These certificates
00263  * are loaded from the default configuration directory which can usually be
00264  * determined by:
00265  *
00266  *   File.dirname OpenSSL::Config::DEFAULT_CONFIG_FILE
00267  */
00268 static VALUE
00269 ossl_x509store_set_default_paths(VALUE self)
00270 {
00271     X509_STORE *store;
00272 
00273     GetX509Store(self, store);
00274     if (X509_STORE_set_default_paths(store) != 1){
00275         ossl_raise(eX509StoreError, NULL);
00276     }
00277 
00278     return Qnil;
00279 }
00280 
00281 /*
00282  * call-seq:
00283  *   store.add_cert(cert)
00284  *
00285  * Adds the OpenSSL::X509::Certificate +cert+ to the certificate store.
00286  */
00287 
00288 static VALUE
00289 ossl_x509store_add_cert(VALUE self, VALUE arg)
00290 {
00291     X509_STORE *store;
00292     X509 *cert;
00293 
00294     cert = GetX509CertPtr(arg); /* NO NEED TO DUP */
00295     GetX509Store(self, store);
00296     if (X509_STORE_add_cert(store, cert) != 1){
00297         ossl_raise(eX509StoreError, NULL);
00298     }
00299 
00300     return self;
00301 }
00302 
00303 static VALUE
00304 ossl_x509store_add_crl(VALUE self, VALUE arg)
00305 {
00306     X509_STORE *store;
00307     X509_CRL *crl;
00308 
00309     crl = GetX509CRLPtr(arg); /* NO NEED TO DUP */
00310     GetX509Store(self, store);
00311     if (X509_STORE_add_crl(store, crl) != 1){
00312         ossl_raise(eX509StoreError, NULL);
00313     }
00314 
00315     return self;
00316 }
00317 
00318 static VALUE ossl_x509stctx_get_err(VALUE);
00319 static VALUE ossl_x509stctx_get_err_string(VALUE);
00320 static VALUE ossl_x509stctx_get_chain(VALUE);
00321 
00322 static VALUE
00323 ossl_x509store_verify(int argc, VALUE *argv, VALUE self)
00324 {
00325     VALUE cert, chain;
00326     VALUE ctx, proc, result;
00327 
00328     rb_scan_args(argc, argv, "11", &cert, &chain);
00329     ctx = rb_funcall(cX509StoreContext, rb_intern("new"), 3, self, cert, chain);
00330     proc = rb_block_given_p() ?  rb_block_proc() :
00331            rb_iv_get(self, "@verify_callback");
00332     rb_iv_set(ctx, "@verify_callback", proc);
00333     result = rb_funcall(ctx, rb_intern("verify"), 0);
00334 
00335     rb_iv_set(self, "@error", ossl_x509stctx_get_err(ctx));
00336     rb_iv_set(self, "@error_string", ossl_x509stctx_get_err_string(ctx));
00337     rb_iv_set(self, "@chain", ossl_x509stctx_get_chain(ctx));
00338 
00339     return result;
00340 }
00341 
00342 /*
00343  * Public Functions
00344  */
00345 static void ossl_x509stctx_free(X509_STORE_CTX*);
00346 
00347 VALUE
00348 ossl_x509stctx_new(X509_STORE_CTX *ctx)
00349 {
00350     VALUE obj;
00351 
00352     WrapX509StCtx(cX509StoreContext, obj, ctx);
00353 
00354     return obj;
00355 }
00356 
00357 VALUE
00358 ossl_x509stctx_clear_ptr(VALUE obj)
00359 {
00360     OSSL_Check_Kind(obj, cX509StoreContext);
00361     RDATA(obj)->data = NULL;
00362 
00363     return obj;
00364 }
00365 
00366 /*
00367  * Private functions
00368  */
00369 static void
00370 ossl_x509stctx_free(X509_STORE_CTX *ctx)
00371 {
00372     if(ctx->untrusted)
00373         sk_X509_pop_free(ctx->untrusted, X509_free);
00374     if(ctx->cert)
00375         X509_free(ctx->cert);
00376     X509_STORE_CTX_free(ctx);
00377 }
00378 
00379 static VALUE
00380 ossl_x509stctx_alloc(VALUE klass)
00381 {
00382     X509_STORE_CTX *ctx;
00383     VALUE obj;
00384 
00385     if((ctx = X509_STORE_CTX_new()) == NULL){
00386         ossl_raise(eX509StoreError, NULL);
00387     }
00388     WrapX509StCtx(klass, obj, ctx);
00389 
00390     return obj;
00391 }
00392 
00393 static VALUE ossl_x509stctx_set_flags(VALUE, VALUE);
00394 static VALUE ossl_x509stctx_set_purpose(VALUE, VALUE);
00395 static VALUE ossl_x509stctx_set_trust(VALUE, VALUE);
00396 static VALUE ossl_x509stctx_set_time(VALUE, VALUE);
00397 
00398 static VALUE
00399 ossl_x509stctx_initialize(int argc, VALUE *argv, VALUE self)
00400 {
00401     VALUE store, cert, chain, t;
00402     X509_STORE_CTX *ctx;
00403     X509_STORE *x509st;
00404     X509 *x509 = NULL;
00405     STACK_OF(X509) *x509s = NULL;
00406 
00407     rb_scan_args(argc, argv, "12", &store, &cert, &chain);
00408     GetX509StCtx(self, ctx);
00409     SafeGetX509Store(store, x509st);
00410     if(!NIL_P(cert)) x509 = DupX509CertPtr(cert); /* NEED TO DUP */
00411     if(!NIL_P(chain)) x509s = ossl_x509_ary2sk(chain);
00412 #if (OPENSSL_VERSION_NUMBER >= 0x00907000L)
00413     if(X509_STORE_CTX_init(ctx, x509st, x509, x509s) != 1){
00414         sk_X509_pop_free(x509s, X509_free);
00415         ossl_raise(eX509StoreError, NULL);
00416     }
00417 #else
00418     X509_STORE_CTX_init(ctx, x509st, x509, x509s);
00419     ossl_x509stctx_set_flags(self, rb_iv_get(store, "@flags"));
00420     ossl_x509stctx_set_purpose(self, rb_iv_get(store, "@purpose"));
00421     ossl_x509stctx_set_trust(self, rb_iv_get(store, "@trust"));
00422 #endif
00423     if (!NIL_P(t = rb_iv_get(store, "@time")))
00424         ossl_x509stctx_set_time(self, t);
00425     rb_iv_set(self, "@verify_callback", rb_iv_get(store, "@verify_callback"));
00426     rb_iv_set(self, "@cert", cert);
00427 
00428     return self;
00429 }
00430 
00431 static VALUE
00432 ossl_x509stctx_verify(VALUE self)
00433 {
00434     X509_STORE_CTX *ctx;
00435     int result;
00436 
00437     GetX509StCtx(self, ctx);
00438     X509_STORE_CTX_set_ex_data(ctx, ossl_verify_cb_idx,
00439                                (void*)rb_iv_get(self, "@verify_callback"));
00440     result = X509_verify_cert(ctx);
00441 
00442     return result ? Qtrue : Qfalse;
00443 }
00444 
00445 static VALUE
00446 ossl_x509stctx_get_chain(VALUE self)
00447 {
00448     X509_STORE_CTX *ctx;
00449     STACK_OF(X509) *chain;
00450     X509 *x509;
00451     int i, num;
00452     VALUE ary;
00453 
00454     GetX509StCtx(self, ctx);
00455     if((chain = X509_STORE_CTX_get_chain(ctx)) == NULL){
00456         return Qnil;
00457     }
00458     if((num = sk_X509_num(chain)) < 0){
00459         OSSL_Debug("certs in chain < 0???");
00460         return rb_ary_new();
00461     }
00462     ary = rb_ary_new2(num);
00463     for(i = 0; i < num; i++) {
00464         x509 = sk_X509_value(chain, i);
00465         rb_ary_push(ary, ossl_x509_new(x509));
00466     }
00467 
00468     return ary;
00469 }
00470 
00471 static VALUE
00472 ossl_x509stctx_get_err(VALUE self)
00473 {
00474     X509_STORE_CTX *ctx;
00475 
00476     GetX509StCtx(self, ctx);
00477 
00478     return INT2FIX(X509_STORE_CTX_get_error(ctx));
00479 }
00480 
00481 static VALUE
00482 ossl_x509stctx_set_error(VALUE self, VALUE err)
00483 {
00484     X509_STORE_CTX *ctx;
00485 
00486     GetX509StCtx(self, ctx);
00487     X509_STORE_CTX_set_error(ctx, NUM2INT(err));
00488 
00489     return err;
00490 }
00491 
00492 static VALUE
00493 ossl_x509stctx_get_err_string(VALUE self)
00494 {
00495     X509_STORE_CTX *ctx;
00496     long err;
00497 
00498     GetX509StCtx(self, ctx);
00499     err = X509_STORE_CTX_get_error(ctx);
00500 
00501     return rb_str_new2(X509_verify_cert_error_string(err));
00502 }
00503 
00504 static VALUE
00505 ossl_x509stctx_get_err_depth(VALUE self)
00506 {
00507     X509_STORE_CTX *ctx;
00508 
00509     GetX509StCtx(self, ctx);
00510 
00511     return INT2FIX(X509_STORE_CTX_get_error_depth(ctx));
00512 }
00513 
00514 static VALUE
00515 ossl_x509stctx_get_curr_cert(VALUE self)
00516 {
00517     X509_STORE_CTX *ctx;
00518 
00519     GetX509StCtx(self, ctx);
00520 
00521     return ossl_x509_new(X509_STORE_CTX_get_current_cert(ctx));
00522 }
00523 
00524 static VALUE
00525 ossl_x509stctx_get_curr_crl(VALUE self)
00526 {
00527 #if (OPENSSL_VERSION_NUMBER >= 0x00907000L)
00528     X509_STORE_CTX *ctx;
00529 
00530     GetX509StCtx(self, ctx);
00531     if(!ctx->current_crl) return Qnil;
00532 
00533     return ossl_x509crl_new(ctx->current_crl);
00534 #else
00535     return Qnil;
00536 #endif
00537 }
00538 
00539 static VALUE
00540 ossl_x509stctx_set_flags(VALUE self, VALUE flags)
00541 {
00542     X509_STORE_CTX *store;
00543     long f = NUM2LONG(flags);
00544 
00545     GetX509StCtx(self, store);
00546     X509_STORE_CTX_set_flags(store, f);
00547 
00548     return flags;
00549 }
00550 
00551 static VALUE
00552 ossl_x509stctx_set_purpose(VALUE self, VALUE purpose)
00553 {
00554     X509_STORE_CTX *store;
00555     int p = NUM2INT(purpose);
00556 
00557     GetX509StCtx(self, store);
00558     X509_STORE_CTX_set_purpose(store, p);
00559 
00560     return purpose;
00561 }
00562 
00563 static VALUE
00564 ossl_x509stctx_set_trust(VALUE self, VALUE trust)
00565 {
00566     X509_STORE_CTX *store;
00567     int t = NUM2INT(trust);
00568 
00569     GetX509StCtx(self, store);
00570     X509_STORE_CTX_set_trust(store, t);
00571 
00572     return trust;
00573 }
00574 
00575 /*
00576  * call-seq:
00577  *    storectx.time = time => time
00578  */
00579 static VALUE
00580 ossl_x509stctx_set_time(VALUE self, VALUE time)
00581 {
00582     X509_STORE_CTX *store;
00583     long t;
00584 
00585     t = NUM2LONG(rb_Integer(time));
00586     GetX509StCtx(self, store);
00587     X509_STORE_CTX_set_time(store, 0, t);
00588 
00589     return time;
00590 }
00591 
00592 /*
00593  * INIT
00594  */
00595 void
00596 Init_ossl_x509store()
00597 {
00598     VALUE x509stctx;
00599 
00600 #if 0
00601     mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */
00602     mX509 = rb_define_module_under(mOSSL, "X509");
00603 #endif
00604 
00605     eX509StoreError = rb_define_class_under(mX509, "StoreError", eOSSLError);
00606 
00607     /* Document-class: OpenSSL::X509::Store
00608      *
00609      * The X509 certificate store holds trusted CA certificates used to verify
00610      * peer certificates.
00611      *
00612      * The easiest way to create a useful certificate store is:
00613      *
00614      *   cert_store = OpenSSL::X509::Store.new
00615      *   cert_store.set_default_paths
00616      *
00617      * This will use your system's built-in certificates.
00618      *
00619      * If your system does not have a default set of certificates you can
00620      * obtain a set from Mozilla here: http://curl.haxx.se/docs/caextract.html
00621      * (Note that this set does not have an HTTPS download option so you may
00622      * wish to use the firefox-db2pem.sh script to extract the certificates
00623      * from a local install to avoid man-in-the-middle attacks.)
00624      *
00625      * After downloading or generating a cacert.pem from the above link you
00626      * can create a certificate store from the pem file like this:
00627      *
00628      *   cert_store = OpenSSL::X509::Store.new
00629      *   cert_store.add_file 'cacert.pem'
00630      *
00631      * The certificate store can be used with an SSLSocket like this:
00632      *
00633      *   ssl_context = OpenSSL::SSL::SSLContext.new
00634      *   ssl_context.cert_store = cert_store
00635      *
00636      *   tcp_socket = TCPSocket.open 'example.com', 443
00637      *
00638      *   ssl_socket = OpenSSL::SSL::SSLSocket.new tcp_socket, ssl_context
00639      */
00640 
00641     cX509Store = rb_define_class_under(mX509, "Store", rb_cObject);
00642     rb_attr(cX509Store, rb_intern("verify_callback"), 1, 0, Qfalse);
00643     rb_attr(cX509Store, rb_intern("error"), 1, 0, Qfalse);
00644     rb_attr(cX509Store, rb_intern("error_string"), 1, 0, Qfalse);
00645     rb_attr(cX509Store, rb_intern("chain"), 1, 0, Qfalse);
00646     rb_define_alloc_func(cX509Store, ossl_x509store_alloc);
00647     rb_define_method(cX509Store, "initialize",   ossl_x509store_initialize, -1);
00648     rb_define_method(cX509Store, "verify_callback=", ossl_x509store_set_vfy_cb, 1);
00649     rb_define_method(cX509Store, "flags=",       ossl_x509store_set_flags, 1);
00650     rb_define_method(cX509Store, "purpose=",     ossl_x509store_set_purpose, 1);
00651     rb_define_method(cX509Store, "trust=",       ossl_x509store_set_trust, 1);
00652     rb_define_method(cX509Store, "time=",        ossl_x509store_set_time, 1);
00653     rb_define_method(cX509Store, "add_path",     ossl_x509store_add_path, 1);
00654     rb_define_method(cX509Store, "add_file",     ossl_x509store_add_file, 1);
00655     rb_define_method(cX509Store, "set_default_paths", ossl_x509store_set_default_paths, 0);
00656     rb_define_method(cX509Store, "add_cert",     ossl_x509store_add_cert, 1);
00657     rb_define_method(cX509Store, "add_crl",      ossl_x509store_add_crl, 1);
00658     rb_define_method(cX509Store, "verify",       ossl_x509store_verify, -1);
00659 
00660     cX509StoreContext = rb_define_class_under(mX509,"StoreContext",rb_cObject);
00661     x509stctx = cX509StoreContext;
00662     rb_define_alloc_func(cX509StoreContext, ossl_x509stctx_alloc);
00663     rb_define_method(x509stctx,"initialize",  ossl_x509stctx_initialize, -1);
00664     rb_define_method(x509stctx,"verify",      ossl_x509stctx_verify, 0);
00665     rb_define_method(x509stctx,"chain",       ossl_x509stctx_get_chain,0);
00666     rb_define_method(x509stctx,"error",       ossl_x509stctx_get_err, 0);
00667     rb_define_method(x509stctx,"error=",      ossl_x509stctx_set_error, 1);
00668     rb_define_method(x509stctx,"error_string",ossl_x509stctx_get_err_string,0);
00669     rb_define_method(x509stctx,"error_depth", ossl_x509stctx_get_err_depth, 0);
00670     rb_define_method(x509stctx,"current_cert",ossl_x509stctx_get_curr_cert, 0);
00671     rb_define_method(x509stctx,"current_crl", ossl_x509stctx_get_curr_crl, 0);
00672     rb_define_method(x509stctx,"flags=",      ossl_x509stctx_set_flags, 1);
00673     rb_define_method(x509stctx,"purpose=",    ossl_x509stctx_set_purpose, 1);
00674     rb_define_method(x509stctx,"trust=",      ossl_x509stctx_set_trust, 1);
00675     rb_define_method(x509stctx,"time=",       ossl_x509stctx_set_time, 1);
00676 
00677 }
00678