00001
00002
00003
00004
00005
00006
00007
00008
00009
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
00032
00033 VALUE cX509CRL;
00034 VALUE eX509CRLError;
00035
00036
00037
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
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));
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))) {
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
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
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
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)) {
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)) {
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);
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
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);
00448 rb_ary_push(ary, ossl_x509ext_new(ext));
00449 }
00450
00451 return ary;
00452 }
00453
00454
00455
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
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)) {
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)) {
00493 X509_EXTENSION_free(ext);
00494 ossl_raise(eX509CRLError, NULL);
00495 }
00496 X509_EXTENSION_free(ext);
00497
00498 return extension;
00499 }
00500
00501
00502
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