• Main Page
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

ext/openssl/ossl_x509cert.c

Go to the documentation of this file.
00001 /*
00002  * $Id: ossl_x509cert.c 27440 2010-04-22 08:21:01Z nobu $
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 WrapX509(klass, obj, x509) do { \
00014     if (!x509) { \
00015         ossl_raise(rb_eRuntimeError, "CERT wasn't initialized!"); \
00016     } \
00017     obj = Data_Wrap_Struct(klass, 0, X509_free, x509); \
00018 } while (0)
00019 #define GetX509(obj, x509) do { \
00020     Data_Get_Struct(obj, X509, x509); \
00021     if (!x509) { \
00022         ossl_raise(rb_eRuntimeError, "CERT wasn't initialized!"); \
00023     } \
00024 } while (0)
00025 #define SafeGetX509(obj, x509) do { \
00026     OSSL_Check_Kind(obj, cX509Cert); \
00027     GetX509(obj, x509); \
00028 } while (0)
00029 
00030 /*
00031  * Classes
00032  */
00033 VALUE cX509Cert;
00034 VALUE eX509CertError;
00035 
00036 /*
00037  * Public
00038  */
00039 VALUE
00040 ossl_x509_new(X509 *x509)
00041 {
00042     X509 *new;
00043     VALUE obj;
00044 
00045     if (!x509) {
00046         new = X509_new();
00047     } else {
00048         new = X509_dup(x509);
00049     }
00050     if (!new) {
00051         ossl_raise(eX509CertError, NULL);
00052     }
00053     WrapX509(cX509Cert, obj, new);
00054 
00055     return obj;
00056 }
00057 
00058 VALUE
00059 ossl_x509_new_from_file(VALUE filename)
00060 {
00061     X509 *x509;
00062     FILE *fp;
00063     VALUE obj;
00064 
00065     SafeStringValue(filename);
00066     if (!(fp = fopen(RSTRING_PTR(filename), "r"))) {
00067         ossl_raise(eX509CertError, "%s", strerror(errno));
00068     }
00069     x509 = PEM_read_X509(fp, NULL, NULL, NULL);
00070     /*
00071      * prepare for DER...
00072 #if !defined(OPENSSL_NO_FP_API)
00073     if (!x509) {
00074         rewind(fp);
00075 
00076         x509 = d2i_X509_fp(fp, NULL);
00077     }
00078 #endif
00079     */
00080     fclose(fp);
00081     if (!x509) {
00082         ossl_raise(eX509CertError, NULL);
00083     }
00084     WrapX509(cX509Cert, obj, x509);
00085 
00086     return obj;
00087 }
00088 
00089 X509 *
00090 GetX509CertPtr(VALUE obj)
00091 {
00092     X509 *x509;
00093 
00094     SafeGetX509(obj, x509);
00095 
00096     return x509;
00097 }
00098 
00099 X509 *
00100 DupX509CertPtr(VALUE obj)
00101 {
00102     X509 *x509;
00103 
00104     SafeGetX509(obj, x509);
00105 
00106     CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509);
00107 
00108     return x509;
00109 }
00110 
00111 /*
00112  * Private
00113  */
00114 static VALUE
00115 ossl_x509_alloc(VALUE klass)
00116 {
00117     X509 *x509;
00118     VALUE obj;
00119 
00120     x509 = X509_new();
00121     if (!x509) ossl_raise(eX509CertError, NULL);
00122 
00123     WrapX509(klass, obj, x509);
00124 
00125     return obj;
00126 }
00127 
00128 /*
00129  * call-seq:
00130  *    Certificate.new => cert
00131  *    Certificate.new(string) => cert
00132  */
00133 static VALUE
00134 ossl_x509_initialize(int argc, VALUE *argv, VALUE self)
00135 {
00136     BIO *in;
00137     X509 *x509, *x = DATA_PTR(self);
00138     VALUE arg;
00139 
00140     if (rb_scan_args(argc, argv, "01", &arg) == 0) {
00141         /* create just empty X509Cert */
00142         return self;
00143     }
00144     arg = ossl_to_der_if_possible(arg);
00145     in = ossl_obj2bio(arg);
00146     x509 = PEM_read_bio_X509(in, &x, NULL, NULL);
00147     DATA_PTR(self) = x;
00148     if (!x509) {
00149         (void)BIO_reset(in);
00150         x509 = d2i_X509_bio(in, &x);
00151         DATA_PTR(self) = x;
00152     }
00153     BIO_free(in);
00154     if (!x509) ossl_raise(eX509CertError, NULL);
00155 
00156     return self;
00157 }
00158 
00159 static VALUE
00160 ossl_x509_copy(VALUE self, VALUE other)
00161 {
00162     X509 *a, *b, *x509;
00163 
00164     rb_check_frozen(self);
00165     if (self == other) return self;
00166 
00167     GetX509(self, a);
00168     SafeGetX509(other, b);
00169 
00170     x509 = X509_dup(b);
00171     if (!x509) ossl_raise(eX509CertError, NULL);
00172 
00173     DATA_PTR(self) = x509;
00174     X509_free(a);
00175 
00176     return self;
00177 }
00178 
00179 /*
00180  * call-seq:
00181  *    cert.to_der => string
00182  */
00183 static VALUE
00184 ossl_x509_to_der(VALUE self)
00185 {
00186     X509 *x509;
00187     VALUE str;
00188     long len;
00189     unsigned char *p;
00190 
00191     GetX509(self, x509);
00192     if ((len = i2d_X509(x509, NULL)) <= 0)
00193         ossl_raise(eX509CertError, NULL);
00194     str = rb_str_new(0, len);
00195     p = (unsigned char *)RSTRING_PTR(str);
00196     if (i2d_X509(x509, &p) <= 0)
00197         ossl_raise(eX509CertError, NULL);
00198     ossl_str_adjust(str, p);
00199 
00200     return str;
00201 }
00202 
00203 /*
00204  * call-seq:
00205  *    cert.to_pem => string
00206  */
00207 static VALUE
00208 ossl_x509_to_pem(VALUE self)
00209 {
00210     X509 *x509;
00211     BIO *out;
00212     VALUE str;
00213 
00214     GetX509(self, x509);
00215     out = BIO_new(BIO_s_mem());
00216     if (!out) ossl_raise(eX509CertError, NULL);
00217 
00218     if (!PEM_write_bio_X509(out, x509)) {
00219         BIO_free(out);
00220         ossl_raise(eX509CertError, NULL);
00221     }
00222     str = ossl_membio2str(out);
00223 
00224     return str;
00225 }
00226 
00227 /*
00228  * call-seq:
00229  *    cert.to_text => string
00230  */
00231 static VALUE
00232 ossl_x509_to_text(VALUE self)
00233 {
00234     X509 *x509;
00235     BIO *out;
00236     VALUE str;
00237 
00238     GetX509(self, x509);
00239 
00240     out = BIO_new(BIO_s_mem());
00241     if (!out) ossl_raise(eX509CertError, NULL);
00242 
00243     if (!X509_print(out, x509)) {
00244         BIO_free(out);
00245         ossl_raise(eX509CertError, NULL);
00246     }
00247     str = ossl_membio2str(out);
00248 
00249     return str;
00250 }
00251 
00252 #if 0
00253 /*
00254  * Makes from X509 X509_REQuest
00255  */
00256 static VALUE
00257 ossl_x509_to_req(VALUE self)
00258 {
00259     X509 *x509;
00260     X509_REQ *req;
00261     VALUE obj;
00262 
00263     GetX509(self, x509);
00264     if (!(req = X509_to_X509_REQ(x509, NULL, EVP_md5()))) {
00265         ossl_raise(eX509CertError, NULL);
00266     }
00267     obj = ossl_x509req_new(req);
00268     X509_REQ_free(req);
00269 
00270     return obj;
00271 }
00272 #endif
00273 
00274 /*
00275  * call-seq:
00276  *    cert.version => integer
00277  */
00278 static VALUE
00279 ossl_x509_get_version(VALUE self)
00280 {
00281     X509 *x509;
00282 
00283     GetX509(self, x509);
00284 
00285     return LONG2NUM(X509_get_version(x509));
00286 }
00287 
00288 /*
00289  * call-seq:
00290  *    cert.version = integer => integer
00291  */
00292 static VALUE
00293 ossl_x509_set_version(VALUE self, VALUE version)
00294 {
00295     X509 *x509;
00296     long ver;
00297 
00298     if ((ver = NUM2LONG(version)) < 0) {
00299         ossl_raise(eX509CertError, "version must be >= 0!");
00300     }
00301     GetX509(self, x509);
00302     if (!X509_set_version(x509, ver)) {
00303         ossl_raise(eX509CertError, NULL);
00304     }
00305 
00306     return version;
00307 }
00308 
00309 /*
00310  * call-seq:
00311  *    cert.serial => integer
00312  */
00313 static VALUE
00314 ossl_x509_get_serial(VALUE self)
00315 {
00316     X509 *x509;
00317 
00318     GetX509(self, x509);
00319 
00320     return asn1integer_to_num(X509_get_serialNumber(x509));
00321 }
00322 
00323 /*
00324  * call-seq:
00325  *    cert.serial = integer => integer
00326  */
00327 static VALUE
00328 ossl_x509_set_serial(VALUE self, VALUE num)
00329 {
00330     X509 *x509;
00331 
00332     GetX509(self, x509);
00333 
00334     x509->cert_info->serialNumber =
00335         num_to_asn1integer(num, X509_get_serialNumber(x509));
00336 
00337     return num;
00338 }
00339 
00340 /*
00341  * call-seq:
00342  *    cert.signature_algorithm => string
00343  */
00344 static VALUE
00345 ossl_x509_get_signature_algorithm(VALUE self)
00346 {
00347     X509 *x509;
00348     BIO *out;
00349     VALUE str;
00350 
00351     GetX509(self, x509);
00352     out = BIO_new(BIO_s_mem());
00353     if (!out) ossl_raise(eX509CertError, NULL);
00354 
00355     if (!i2a_ASN1_OBJECT(out, x509->cert_info->signature->algorithm)) {
00356         BIO_free(out);
00357         ossl_raise(eX509CertError, NULL);
00358     }
00359     str = ossl_membio2str(out);
00360 
00361     return str;
00362 }
00363 
00364 /*
00365  * call-seq:
00366  *    cert.subject => name
00367  */
00368 static VALUE
00369 ossl_x509_get_subject(VALUE self)
00370 {
00371     X509 *x509;
00372     X509_NAME *name;
00373 
00374     GetX509(self, x509);
00375     if (!(name = X509_get_subject_name(x509))) { /* NO DUP - don't free! */
00376         ossl_raise(eX509CertError, NULL);
00377     }
00378 
00379     return ossl_x509name_new(name);
00380 }
00381 
00382 /*
00383  * call-seq:
00384  *    cert.subject = name => name
00385  */
00386 static VALUE
00387 ossl_x509_set_subject(VALUE self, VALUE subject)
00388 {
00389     X509 *x509;
00390 
00391     GetX509(self, x509);
00392     if (!X509_set_subject_name(x509, GetX509NamePtr(subject))) { /* DUPs name */
00393         ossl_raise(eX509CertError, NULL);
00394     }
00395 
00396     return subject;
00397 }
00398 
00399 /*
00400  * call-seq:
00401  *    cert.issuer => name
00402  */
00403 static VALUE
00404 ossl_x509_get_issuer(VALUE self)
00405 {
00406     X509 *x509;
00407     X509_NAME *name;
00408 
00409     GetX509(self, x509);
00410     if(!(name = X509_get_issuer_name(x509))) { /* NO DUP - don't free! */
00411         ossl_raise(eX509CertError, NULL);
00412     }
00413 
00414     return ossl_x509name_new(name);
00415 }
00416 
00417 /*
00418  * call-seq:
00419  *    cert.issuer = name => name
00420  */
00421 static VALUE
00422 ossl_x509_set_issuer(VALUE self, VALUE issuer)
00423 {
00424     X509 *x509;
00425 
00426     GetX509(self, x509);
00427     if (!X509_set_issuer_name(x509, GetX509NamePtr(issuer))) { /* DUPs name */
00428         ossl_raise(eX509CertError, NULL);
00429     }
00430 
00431     return issuer;
00432 }
00433 
00434 /*
00435  * call-seq:
00436  *    cert.not_before => time
00437  */
00438 static VALUE
00439 ossl_x509_get_not_before(VALUE self)
00440 {
00441     X509 *x509;
00442     ASN1_UTCTIME *asn1time;
00443 
00444     GetX509(self, x509);
00445     if (!(asn1time = X509_get_notBefore(x509))) { /* NO DUP - don't free! */
00446         ossl_raise(eX509CertError, NULL);
00447     }
00448 
00449     return asn1time_to_time(asn1time);
00450 }
00451 
00452 /*
00453  * call-seq:
00454  *    cert.not_before = time => time
00455  */
00456 static VALUE
00457 ossl_x509_set_not_before(VALUE self, VALUE time)
00458 {
00459     X509 *x509;
00460     time_t sec;
00461 
00462     sec = time_to_time_t(time);
00463     GetX509(self, x509);
00464     if (!X509_time_adj(X509_get_notBefore(x509), 0, &sec)) {
00465         ossl_raise(eX509CertError, NULL);
00466     }
00467 
00468     return time;
00469 }
00470 
00471 /*
00472  * call-seq:
00473  *    cert.not_after => time
00474  */
00475 static VALUE
00476 ossl_x509_get_not_after(VALUE self)
00477 {
00478     X509 *x509;
00479     ASN1_TIME *asn1time;
00480 
00481     GetX509(self, x509);
00482     if (!(asn1time = X509_get_notAfter(x509))) { /* NO DUP - don't free! */
00483         ossl_raise(eX509CertError, NULL);
00484     }
00485 
00486     return asn1time_to_time(asn1time);
00487 }
00488 
00489 /*
00490  * call-seq:
00491  *    cert.not_before = time => time
00492  */
00493 static VALUE
00494 ossl_x509_set_not_after(VALUE self, VALUE time)
00495 {
00496     X509 *x509;
00497     time_t sec;
00498 
00499     sec = time_to_time_t(time);
00500     GetX509(self, x509);
00501     if (!X509_time_adj(X509_get_notAfter(x509), 0, &sec)) {
00502         ossl_raise(eX509CertError, NULL);
00503     }
00504 
00505     return time;
00506 }
00507 
00508 /*
00509  * call-seq:
00510  *    cert.public_key => key
00511  */
00512 static VALUE
00513 ossl_x509_get_public_key(VALUE self)
00514 {
00515     X509 *x509;
00516     EVP_PKEY *pkey;
00517 
00518     GetX509(self, x509);
00519     if (!(pkey = X509_get_pubkey(x509))) { /* adds an reference */
00520         ossl_raise(eX509CertError, NULL);
00521     }
00522 
00523     return ossl_pkey_new(pkey); /* NO DUP - OK */
00524 }
00525 
00526 /*
00527  * call-seq:
00528  *    cert.public_key = key => key
00529  */
00530 static VALUE
00531 ossl_x509_set_public_key(VALUE self, VALUE key)
00532 {
00533     X509 *x509;
00534 
00535     GetX509(self, x509);
00536     if (!X509_set_pubkey(x509, GetPKeyPtr(key))) { /* DUPs pkey */
00537         ossl_raise(eX509CertError, NULL);
00538     }
00539 
00540     return key;
00541 }
00542 
00543 /*
00544  * call-seq:
00545  *    cert.sign(key, digest) => self
00546  */
00547 static VALUE
00548 ossl_x509_sign(VALUE self, VALUE key, VALUE digest)
00549 {
00550     X509 *x509;
00551     EVP_PKEY *pkey;
00552     const EVP_MD *md;
00553 
00554     pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */
00555     md = GetDigestPtr(digest);
00556     GetX509(self, x509);
00557     if (!X509_sign(x509, pkey, md)) {
00558         ossl_raise(eX509CertError, NULL);
00559     }
00560 
00561     return self;
00562 }
00563 
00564 /*
00565  * call-seq:
00566  *    cert.verify(key) => true | false
00567  *
00568  * Checks that cert signature is made with PRIVversion of this PUBLIC 'key'
00569  */
00570 static VALUE
00571 ossl_x509_verify(VALUE self, VALUE key)
00572 {
00573     X509 *x509;
00574     EVP_PKEY *pkey;
00575     int i;
00576 
00577     pkey = GetPKeyPtr(key); /* NO NEED TO DUP */
00578     GetX509(self, x509);
00579     if ((i = X509_verify(x509, pkey)) < 0) {
00580         ossl_raise(eX509CertError, NULL);
00581     }
00582     if (i > 0) {
00583         return Qtrue;
00584     }
00585 
00586     return Qfalse;
00587 }
00588 
00589 /*
00590  * call-seq:
00591  *    cert.check_private_key(key)
00592  *
00593  * Checks if 'key' is PRIV key for this cert
00594  */
00595 static VALUE
00596 ossl_x509_check_private_key(VALUE self, VALUE key)
00597 {
00598     X509 *x509;
00599     EVP_PKEY *pkey;
00600 
00601     /* not needed private key, but should be */
00602     pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */
00603     GetX509(self, x509);
00604     if (!X509_check_private_key(x509, pkey)) {
00605         OSSL_Warning("Check private key:%s", OSSL_ErrMsg());
00606         return Qfalse;
00607     }
00608 
00609     return Qtrue;
00610 }
00611 
00612 /*
00613  * call-seq:
00614  *    cert.extensions => [extension...]
00615  */
00616 static VALUE
00617 ossl_x509_get_extensions(VALUE self)
00618 {
00619     X509 *x509;
00620     int count, i;
00621     X509_EXTENSION *ext;
00622     VALUE ary;
00623 
00624     GetX509(self, x509);
00625     count = X509_get_ext_count(x509);
00626     if (count < 0) {
00627         return rb_ary_new();
00628     }
00629     ary = rb_ary_new2(count);
00630     for (i=0; i<count; i++) {
00631         ext = X509_get_ext(x509, i); /* NO DUP - don't free! */
00632         rb_ary_push(ary, ossl_x509ext_new(ext));
00633     }
00634 
00635     return ary;
00636 }
00637 
00638 /*
00639  * call-seq:
00640  *    cert.extensions = [ext...] => [ext...]
00641  */
00642 static VALUE
00643 ossl_x509_set_extensions(VALUE self, VALUE ary)
00644 {
00645     X509 *x509;
00646     X509_EXTENSION *ext;
00647     int i;
00648 
00649     Check_Type(ary, T_ARRAY);
00650     /* All ary's members should be X509Extension */
00651     for (i=0; i<RARRAY_LEN(ary); i++) {
00652         OSSL_Check_Kind(RARRAY_PTR(ary)[i], cX509Ext);
00653     }
00654     GetX509(self, x509);
00655     sk_X509_EXTENSION_pop_free(x509->cert_info->extensions, X509_EXTENSION_free);
00656     x509->cert_info->extensions = NULL;
00657     for (i=0; i<RARRAY_LEN(ary); i++) {
00658         ext = DupX509ExtPtr(RARRAY_PTR(ary)[i]);
00659 
00660         if (!X509_add_ext(x509, ext, -1)) { /* DUPs ext - FREE it */
00661             X509_EXTENSION_free(ext);
00662             ossl_raise(eX509CertError, NULL);
00663         }
00664         X509_EXTENSION_free(ext);
00665     }
00666 
00667     return ary;
00668 }
00669 
00670 /*
00671  * call-seq:
00672  *    cert.add_extension(extension) => extension
00673  */
00674 static VALUE
00675 ossl_x509_add_extension(VALUE self, VALUE extension)
00676 {
00677     X509 *x509;
00678     X509_EXTENSION *ext;
00679 
00680     GetX509(self, x509);
00681     ext = DupX509ExtPtr(extension);
00682     if (!X509_add_ext(x509, ext, -1)) { /* DUPs ext - FREE it */
00683         X509_EXTENSION_free(ext);
00684         ossl_raise(eX509CertError, NULL);
00685     }
00686     X509_EXTENSION_free(ext);
00687 
00688     return extension;
00689 }
00690 
00691 static VALUE
00692 ossl_x509_inspect(VALUE self)
00693 {
00694     VALUE str;
00695     const char *cname = rb_class2name(rb_obj_class(self));
00696 
00697     str = rb_str_new2("#<");
00698     rb_str_cat2(str, cname);
00699     rb_str_cat2(str, " ");
00700 
00701     rb_str_cat2(str, "subject=");
00702     rb_str_append(str, rb_inspect(ossl_x509_get_subject(self)));
00703     rb_str_cat2(str, ", ");
00704 
00705     rb_str_cat2(str, "issuer=");
00706     rb_str_append(str, rb_inspect(ossl_x509_get_issuer(self)));
00707     rb_str_cat2(str, ", ");
00708 
00709     rb_str_cat2(str, "serial=");
00710     rb_str_append(str, rb_inspect(ossl_x509_get_serial(self)));
00711     rb_str_cat2(str, ", ");
00712 
00713     rb_str_cat2(str, "not_before=");
00714     rb_str_append(str, rb_inspect(ossl_x509_get_not_before(self)));
00715     rb_str_cat2(str, ", ");
00716 
00717     rb_str_cat2(str, "not_after=");
00718     rb_str_append(str, rb_inspect(ossl_x509_get_not_after(self)));
00719 
00720     str = rb_str_cat2(str, ">");
00721 
00722     return str;
00723 }
00724 
00725 /*
00726  * INIT
00727  */
00728 void
00729 Init_ossl_x509cert()
00730 {
00731     eX509CertError = rb_define_class_under(mX509, "CertificateError", eOSSLError);
00732 
00733     cX509Cert = rb_define_class_under(mX509, "Certificate", rb_cObject);
00734 
00735     rb_define_alloc_func(cX509Cert, ossl_x509_alloc);
00736     rb_define_method(cX509Cert, "initialize", ossl_x509_initialize, -1);
00737     rb_define_copy_func(cX509Cert, ossl_x509_copy);
00738 
00739     rb_define_method(cX509Cert, "to_der", ossl_x509_to_der, 0);
00740     rb_define_method(cX509Cert, "to_pem", ossl_x509_to_pem, 0);
00741     rb_define_alias(cX509Cert, "to_s", "to_pem");
00742     rb_define_method(cX509Cert, "to_text", ossl_x509_to_text, 0);
00743     rb_define_method(cX509Cert, "version", ossl_x509_get_version, 0);
00744     rb_define_method(cX509Cert, "version=", ossl_x509_set_version, 1);
00745     rb_define_method(cX509Cert, "signature_algorithm", ossl_x509_get_signature_algorithm, 0);
00746     rb_define_method(cX509Cert, "serial", ossl_x509_get_serial, 0);
00747     rb_define_method(cX509Cert, "serial=", ossl_x509_set_serial, 1);
00748     rb_define_method(cX509Cert, "subject", ossl_x509_get_subject, 0);
00749     rb_define_method(cX509Cert, "subject=", ossl_x509_set_subject, 1);
00750     rb_define_method(cX509Cert, "issuer", ossl_x509_get_issuer, 0);
00751     rb_define_method(cX509Cert, "issuer=", ossl_x509_set_issuer, 1);
00752     rb_define_method(cX509Cert, "not_before", ossl_x509_get_not_before, 0);
00753     rb_define_method(cX509Cert, "not_before=", ossl_x509_set_not_before, 1);
00754     rb_define_method(cX509Cert, "not_after", ossl_x509_get_not_after, 0);
00755     rb_define_method(cX509Cert, "not_after=", ossl_x509_set_not_after, 1);
00756     rb_define_method(cX509Cert, "public_key", ossl_x509_get_public_key, 0);
00757     rb_define_method(cX509Cert, "public_key=", ossl_x509_set_public_key, 1);
00758     rb_define_method(cX509Cert, "sign", ossl_x509_sign, 2);
00759     rb_define_method(cX509Cert, "verify", ossl_x509_verify, 1);
00760     rb_define_method(cX509Cert, "check_private_key", ossl_x509_check_private_key, 1);
00761     rb_define_method(cX509Cert, "extensions", ossl_x509_get_extensions, 0);
00762     rb_define_method(cX509Cert, "extensions=", ossl_x509_set_extensions, 1);
00763     rb_define_method(cX509Cert, "add_extension", ossl_x509_add_extension, 1);
00764     rb_define_method(cX509Cert, "inspect", ossl_x509_inspect, 0);
00765 }
00766 
00767 

Generated on Thu Sep 8 2011 03:50:36 for Ruby by  doxygen 1.7.1