Ruby
2.0.0p247(2013-06-27revision41674)
|
00001 /* 00002 * $Id: ossl_x509crl.c 32199 2011-06-22 08:41:08Z emboss $ 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 OSSL_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