Ruby 1.9.2p136(2010-12-25revision30365)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

# ext/openssl/ossl_x509crl.c

Go to the documentation of this file.

    00001 /*
    00002  * $Id: ossl_x509crl.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 WrapX509CRL(klass, obj, crl) do { \
    00014     if (!crl) { \
    00015         ossl_raise(rb_eRuntimeError, "CRL wasn't initialized!"); \
    00016     } \
    00017     obj = Data_Wrap_Struct(klass, 0, X509_CRL_free, crl); \
    00018 } while (0)
    00019 #define GetX509CRL(obj, crl) do { \
    00020     Data_Get_Struct(obj, X509_CRL, crl); \
    00021     if (!crl) { \
    00022         ossl_raise(rb_eRuntimeError, "CRL wasn't initialized!"); \
    00023     } \
    00024 } while (0)
    00025 #define SafeGetX509CRL(obj, crl) do { \
    00026     OSSL_Check_Kind(obj, cX509CRL); \
    00027     GetX509CRL(obj, crl); \
    00028 } while (0)
    00029
    00030 /*
    00031  * Classes
    00032  */
    00033 VALUE cX509CRL;
    00034 VALUE eX509CRLError;
    00035
    00036 /*
    00037  * PUBLIC
    00038  */
    00039 X509_CRL *
    00040 GetX509CRLPtr(VALUE obj)
    00041 {
    00042     X509_CRL *crl;
    00043
    00044     SafeGetX509CRL(obj, crl);
    00045
    00046     return crl;
    00047 }
    00048
    00049 X509_CRL *
    00050 DupX509CRLPtr(VALUE obj)
    00051 {
    00052     X509_CRL *crl;
    00053
    00054     SafeGetX509CRL(obj, crl);
    00055     CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509_CRL);
    00056
    00057     return crl;
    00058 }
    00059
    00060 VALUE
    00061 ossl_x509crl_new(X509_CRL *crl)
    00062 {
    00063     X509_CRL *tmp;
    00064     VALUE obj;
    00065
    00066     tmp = crl ? X509_CRL_dup(crl) : X509_CRL_new();
    00067     if(!tmp) ossl_raise(eX509CRLError, NULL);
    00068     WrapX509CRL(cX509CRL, obj, tmp);
    00069
    00070     return obj;
    00071 }
    00072
    00073 /*
    00074  * PRIVATE
    00075  */
    00076 static VALUE
    00077 ossl_x509crl_alloc(VALUE klass)
    00078 {
    00079     X509_CRL *crl;
    00080     VALUE obj;
    00081
    00082     if (!(crl = X509_CRL_new())) {
    00083         ossl_raise(eX509CRLError, NULL);
    00084     }
    00085     WrapX509CRL(klass, obj, crl);
    00086
    00087     return obj;
    00088 }
    00089
    00090 static VALUE
    00091 ossl_x509crl_initialize(int argc, VALUE *argv, VALUE self)
    00092 {
    00093     BIO *in;
    00094     X509_CRL *crl, *x = DATA_PTR(self);
    00095     VALUE arg;
    00096
    00097     if (rb_scan_args(argc, argv, "01", &arg) == 0) {
    00098         return self;
    00099     }
    00100     arg = ossl_to_der_if_possible(arg);
    00101     in = ossl_obj2bio(arg);
    00102     crl = PEM_read_bio_X509_CRL(in, &x, NULL, NULL);
    00103     DATA_PTR(self) = x;
    00104     if (!crl) {
    00105         (void)BIO_reset(in);
    00106         crl = d2i_X509_CRL_bio(in, &x);
    00107         DATA_PTR(self) = x;
    00108     }
    00109     BIO_free(in);
    00110     if (!crl) ossl_raise(eX509CRLError, NULL);
    00111
    00112     return self;
    00113 }
    00114
    00115 static VALUE
    00116 ossl_x509crl_copy(VALUE self, VALUE other)
    00117 {
    00118     X509_CRL *a, *b, *crl;
    00119
    00120     rb_check_frozen(self);
    00121     if (self == other) return self;
    00122     GetX509CRL(self, a);
    00123     SafeGetX509CRL(other, b);
    00124     if (!(crl = X509_CRL_dup(b))) {
    00125         ossl_raise(eX509CRLError, NULL);
    00126     }
    00127     X509_CRL_free(a);
    00128     DATA_PTR(self) = crl;
    00129
    00130     return self;
    00131 }
    00132
    00133 static VALUE
    00134 ossl_x509crl_get_version(VALUE self)
    00135 {
    00136     X509_CRL *crl;
    00137     long ver;
    00138
    00139     GetX509CRL(self, crl);
    00140     ver = X509_CRL_get_version(crl);
    00141
    00142     return LONG2NUM(ver);
    00143 }
    00144
    00145 static VALUE
    00146 ossl_x509crl_set_version(VALUE self, VALUE version)
    00147 {
    00148     X509_CRL *crl;
    00149     long ver;
    00150
    00151     if ((ver = NUM2LONG(version)) < 0) {
    00152         ossl_raise(eX509CRLError, "version must be >= 0!");
    00153     }
    00154     GetX509CRL(self, crl);
    00155     if (!X509_CRL_set_version(crl, ver)) {
    00156         ossl_raise(eX509CRLError, NULL);
    00157     }
    00158
    00159     return version;
    00160 }
    00161
    00162 static VALUE
    00163 ossl_x509crl_get_signature_algorithm(VALUE self)
    00164 {
    00165     X509_CRL *crl;
    00166     BIO *out;
    00167     BUF_MEM *buf;
    00168     VALUE str;
    00169
    00170     GetX509CRL(self, crl);
    00171     if (!(out = BIO_new(BIO_s_mem()))) {
    00172         ossl_raise(eX509CRLError, NULL);
    00173     }
    00174     if (!i2a_ASN1_OBJECT(out, crl->sig_alg->algorithm)) {
    00175         BIO_free(out);
    00176         ossl_raise(eX509CRLError, NULL);
    00177     }
    00178     BIO_get_mem_ptr(out, &buf);
    00179     str = rb_str_new(buf->data, buf->length);
    00180     BIO_free(out);
    00181     return str;
    00182 }
    00183
    00184 static VALUE
    00185 ossl_x509crl_get_issuer(VALUE self)
    00186 {
    00187     X509_CRL *crl;
    00188
    00189     GetX509CRL(self, crl);
    00190
    00191     return ossl_x509name_new(X509_CRL_get_issuer(crl)); /* NO DUP - don't free */
    00192 }
    00193
    00194 static VALUE
    00195 ossl_x509crl_set_issuer(VALUE self, VALUE issuer)
    00196 {
    00197     X509_CRL *crl;
    00198
    00199     GetX509CRL(self, crl);
    00200
    00201     if (!X509_CRL_set_issuer_name(crl, GetX509NamePtr(issuer))) { /* DUPs name */
    00202         ossl_raise(eX509CRLError, NULL);
    00203     }
    00204     return issuer;
    00205 }
    00206
    00207 static VALUE
    00208 ossl_x509crl_get_last_update(VALUE self)
    00209 {
    00210     X509_CRL *crl;
    00211
    00212     GetX509CRL(self, crl);
    00213
    00214     return asn1time_to_time(X509_CRL_get_lastUpdate(crl));
    00215 }
    00216
    00217 static VALUE
    00218 ossl_x509crl_set_last_update(VALUE self, VALUE time)
    00219 {
    00220     X509_CRL *crl;
    00221     time_t sec;
    00222
    00223     sec = time_to_time_t(time);
    00224     GetX509CRL(self, crl);
    00225     if (!X509_time_adj(crl->crl->lastUpdate, 0, &sec)) {
    00226         ossl_raise(eX509CRLError, NULL);
    00227     }
    00228
    00229     return time;
    00230 }
    00231
    00232 static VALUE
    00233 ossl_x509crl_get_next_update(VALUE self)
    00234 {
    00235     X509_CRL *crl;
    00236
    00237     GetX509CRL(self, crl);
    00238
    00239     return asn1time_to_time(X509_CRL_get_nextUpdate(crl));
    00240 }
    00241
    00242 static VALUE
    00243 ossl_x509crl_set_next_update(VALUE self, VALUE time)
    00244 {
    00245     X509_CRL *crl;
    00246     time_t sec;
    00247
    00248     sec = time_to_time_t(time);
    00249     GetX509CRL(self, crl);
    00250     /* This must be some thinko in OpenSSL */
    00251     if (!(crl->crl->nextUpdate = X509_time_adj(crl->crl->nextUpdate, 0, &sec))){
    00252         ossl_raise(eX509CRLError, NULL);
    00253     }
    00254
    00255     return time;
    00256 }
    00257
    00258 static VALUE
    00259 ossl_x509crl_get_revoked(VALUE self)
    00260 {
    00261     X509_CRL *crl;
    00262     int i, num;
    00263     X509_REVOKED *rev;
    00264     VALUE ary, revoked;
    00265
    00266     GetX509CRL(self, crl);
    00267     num = sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl));
    00268     if (num < 0) {
    00269         OSSL_Debug("num < 0???");
    00270         return rb_ary_new();
    00271     }
    00272     ary = rb_ary_new2(num);
    00273     for(i=0; i<num; i++) {
    00274         /* NO DUP - don't free! */
    00275         rev = sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i);
    00276         revoked = ossl_x509revoked_new(rev);
    00277         rb_ary_push(ary, revoked);
    00278     }
    00279
    00280     return ary;
    00281 }
    00282
    00283 static VALUE
    00284 ossl_x509crl_set_revoked(VALUE self, VALUE ary)
    00285 {
    00286     X509_CRL *crl;
    00287     X509_REVOKED *rev;
    00288     int i;
    00289
    00290     Check_Type(ary, T_ARRAY);
    00291     /* All ary members should be X509 Revoked */
    00292     for (i=0; i<RARRAY_LEN(ary); i++) {
    00293         OSSL_Check_Kind(RARRAY_PTR(ary)[i], cX509Rev);
    00294     }
    00295     GetX509CRL(self, crl);
    00296     sk_X509_REVOKED_pop_free(crl->crl->revoked, X509_REVOKED_free);
    00297     crl->crl->revoked = NULL;
    00298     for (i=0; i<RARRAY_LEN(ary); i++) {
    00299         rev = DupX509RevokedPtr(RARRAY_PTR(ary)[i]);
    00300         if (!X509_CRL_add0_revoked(crl, rev)) { /* NO DUP - don't free! */
    00301             ossl_raise(eX509CRLError, NULL);
    00302         }
    00303     }
    00304     X509_CRL_sort(crl);
    00305
    00306     return ary;
    00307 }
    00308
    00309 static VALUE
    00310 ossl_x509crl_add_revoked(VALUE self, VALUE revoked)
    00311 {
    00312     X509_CRL *crl;
    00313     X509_REVOKED *rev;
    00314
    00315     GetX509CRL(self, crl);
    00316     rev = DupX509RevokedPtr(revoked);
    00317     if (!X509_CRL_add0_revoked(crl, rev)) { /* NO DUP - don't free! */
    00318         ossl_raise(eX509CRLError, NULL);
    00319     }
    00320     X509_CRL_sort(crl);
    00321
    00322     return revoked;
    00323 }
    00324
    00325 static VALUE
    00326 ossl_x509crl_sign(VALUE self, VALUE key, VALUE digest)
    00327 {
    00328     X509_CRL *crl;
    00329     EVP_PKEY *pkey;
    00330     const EVP_MD *md;
    00331
    00332     GetX509CRL(self, crl);
    00333     pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */
    00334     md = GetDigestPtr(digest);
    00335     if (!X509_CRL_sign(crl, pkey, md)) {
    00336         ossl_raise(eX509CRLError, NULL);
    00337     }
    00338
    00339     return self;
    00340 }
    00341
    00342 static VALUE
    00343 ossl_x509crl_verify(VALUE self, VALUE key)
    00344 {
    00345     X509_CRL *crl;
    00346     int ret;
    00347
    00348     GetX509CRL(self, crl);
    00349     if ((ret = X509_CRL_verify(crl, GetPKeyPtr(key))) < 0) {
    00350         ossl_raise(eX509CRLError, NULL);
    00351     }
    00352     if (ret == 1) {
    00353         return Qtrue;
    00354     }
    00355
    00356     return Qfalse;
    00357 }
    00358
    00359 static VALUE
    00360 ossl_x509crl_to_der(VALUE self)
    00361 {
    00362     X509_CRL *crl;
    00363     BIO *out;
    00364     BUF_MEM *buf;
    00365     VALUE str;
    00366
    00367     GetX509CRL(self, crl);
    00368     if (!(out = BIO_new(BIO_s_mem()))) {
    00369         ossl_raise(eX509CRLError, NULL);
    00370     }
    00371     if (!i2d_X509_CRL_bio(out, crl)) {
    00372         BIO_free(out);
    00373         ossl_raise(eX509CRLError, NULL);
    00374     }
    00375     BIO_get_mem_ptr(out, &buf);
    00376     str = rb_str_new(buf->data, buf->length);
    00377     BIO_free(out);
    00378
    00379     return str;
    00380 }
    00381
    00382 static VALUE
    00383 ossl_x509crl_to_pem(VALUE self)
    00384 {
    00385     X509_CRL *crl;
    00386     BIO *out;
    00387     BUF_MEM *buf;
    00388     VALUE str;
    00389
    00390     GetX509CRL(self, crl);
    00391     if (!(out = BIO_new(BIO_s_mem()))) {
    00392         ossl_raise(eX509CRLError, NULL);
    00393     }
    00394     if (!PEM_write_bio_X509_CRL(out, crl)) {
    00395         BIO_free(out);
    00396         ossl_raise(eX509CRLError, NULL);
    00397     }
    00398     BIO_get_mem_ptr(out, &buf);
    00399     str = rb_str_new(buf->data, buf->length);
    00400     BIO_free(out);
    00401
    00402     return str;
    00403 }
    00404
    00405 static VALUE
    00406 ossl_x509crl_to_text(VALUE self)
    00407 {
    00408     X509_CRL *crl;
    00409     BIO *out;
    00410     BUF_MEM *buf;
    00411     VALUE str;
    00412
    00413     GetX509CRL(self, crl);
    00414     if (!(out = BIO_new(BIO_s_mem()))) {
    00415         ossl_raise(eX509CRLError, NULL);
    00416     }
    00417     if (!X509_CRL_print(out, crl)) {
    00418         BIO_free(out);
    00419         ossl_raise(eX509CRLError, NULL);
    00420     }
    00421     BIO_get_mem_ptr(out, &buf);
    00422     str = rb_str_new(buf->data, buf->length);
    00423     BIO_free(out);
    00424
    00425     return str;
    00426 }
    00427
    00428 /*
    00429  * Gets X509v3 extensions as array of X509Ext objects
    00430  */
    00431 static VALUE
    00432 ossl_x509crl_get_extensions(VALUE self)
    00433 {
    00434     X509_CRL *crl;
    00435     int count, i;
    00436     X509_EXTENSION *ext;
    00437     VALUE ary;
    00438
    00439     GetX509CRL(self, crl);
    00440     count = X509_CRL_get_ext_count(crl);
    00441     if (count < 0) {
    00442         OSSL_Debug("count < 0???");
    00443         return rb_ary_new();
    00444     }
    00445     ary = rb_ary_new2(count);
    00446     for (i=0; i<count; i++) {
    00447         ext = X509_CRL_get_ext(crl, i); /* NO DUP - don't free! */
    00448         rb_ary_push(ary, ossl_x509ext_new(ext));
    00449     }
    00450
    00451     return ary;
    00452 }
    00453
    00454 /*
    00455  * Sets X509_EXTENSIONs
    00456  */
    00457 static VALUE
    00458 ossl_x509crl_set_extensions(VALUE self, VALUE ary)
    00459 {
    00460     X509_CRL *crl;
    00461     X509_EXTENSION *ext;
    00462     int i;
    00463
    00464     Check_Type(ary, T_ARRAY);
    00465     /* All ary members should be X509 Extensions */
    00466     for (i=0; i<RARRAY_LEN(ary); i++) {
    00467         OSSL_Check_Kind(RARRAY_PTR(ary)[i], cX509Ext);
    00468     }
    00469     GetX509CRL(self, crl);
    00470     sk_X509_EXTENSION_pop_free(crl->crl->extensions, X509_EXTENSION_free);
    00471     crl->crl->extensions = NULL;
    00472     for (i=0; i<RARRAY_LEN(ary); i++) {
    00473         ext = DupX509ExtPtr(RARRAY_PTR(ary)[i]);
    00474         if(!X509_CRL_add_ext(crl, ext, -1)) { /* DUPs ext - FREE it */
    00475             X509_EXTENSION_free(ext);
    00476             ossl_raise(eX509CRLError, NULL);
    00477         }
    00478         X509_EXTENSION_free(ext);
    00479     }
    00480
    00481     return ary;
    00482 }
    00483
    00484 static VALUE
    00485 ossl_x509crl_add_extension(VALUE self, VALUE extension)
    00486 {
    00487     X509_CRL *crl;
    00488     X509_EXTENSION *ext;
    00489
    00490     GetX509CRL(self, crl);
    00491     ext = DupX509ExtPtr(extension);
    00492     if (!X509_CRL_add_ext(crl, ext, -1)) { /* DUPs ext - FREE it */
    00493         X509_EXTENSION_free(ext);
    00494         ossl_raise(eX509CRLError, NULL);
    00495     }
    00496     X509_EXTENSION_free(ext);
    00497
    00498     return extension;
    00499 }
    00500
    00501 /*
    00502  * INIT
    00503  */
    00504 void
    00505 Init_ossl_x509crl()
    00506 {
    00507     eX509CRLError = rb_define_class_under(mX509, "CRLError", eOSSLError);
    00508
    00509     cX509CRL = rb_define_class_under(mX509, "CRL", rb_cObject);
    00510
    00511     rb_define_alloc_func(cX509CRL, ossl_x509crl_alloc);
    00512     rb_define_method(cX509CRL, "initialize", ossl_x509crl_initialize, -1);
    00513     rb_define_copy_func(cX509CRL, ossl_x509crl_copy);
    00514
    00515     rb_define_method(cX509CRL, "version", ossl_x509crl_get_version, 0);
    00516     rb_define_method(cX509CRL, "version=", ossl_x509crl_set_version, 1);
    00517     rb_define_method(cX509CRL, "signature_algorithm", ossl_x509crl_get_signature_algorithm, 0);
    00518     rb_define_method(cX509CRL, "issuer", ossl_x509crl_get_issuer, 0);
    00519     rb_define_method(cX509CRL, "issuer=", ossl_x509crl_set_issuer, 1);
    00520     rb_define_method(cX509CRL, "last_update", ossl_x509crl_get_last_update, 0);
    00521     rb_define_method(cX509CRL, "last_update=", ossl_x509crl_set_last_update, 1);
    00522     rb_define_method(cX509CRL, "next_update", ossl_x509crl_get_next_update, 0);
    00523     rb_define_method(cX509CRL, "next_update=", ossl_x509crl_set_next_update, 1);
    00524     rb_define_method(cX509CRL, "revoked", ossl_x509crl_get_revoked, 0);
    00525     rb_define_method(cX509CRL, "revoked=", ossl_x509crl_set_revoked, 1);
    00526     rb_define_method(cX509CRL, "add_revoked", ossl_x509crl_add_revoked, 1);
    00527     rb_define_method(cX509CRL, "sign", ossl_x509crl_sign, 2);
    00528     rb_define_method(cX509CRL, "verify", ossl_x509crl_verify, 1);
    00529     rb_define_method(cX509CRL, "to_der", ossl_x509crl_to_der, 0);
    00530     rb_define_method(cX509CRL, "to_pem", ossl_x509crl_to_pem, 0);
    00531     rb_define_alias(cX509CRL, "to_s", "to_pem");
    00532     rb_define_method(cX509CRL, "to_text", ossl_x509crl_to_text, 0);
    00533     rb_define_method(cX509CRL, "extensions", ossl_x509crl_get_extensions, 0);
    00534     rb_define_method(cX509CRL, "extensions=", ossl_x509crl_set_extensions, 1);
    00535     rb_define_method(cX509CRL, "add_extension", ossl_x509crl_add_extension, 1);
    00536 }
    00537
    00538