Change soft-fail to use the config, rather than env
[rbx.git] / stdlib / ext / openssl / ossl_x509crl.c
blob7c0be1a090585f5ad292171b35da9f64fa280389
1 /*
2 * $Id: ossl_x509crl.c 11708 2007-02-12 23:01:19Z shyouhei $
3 * 'OpenSSL for Ruby' project
4 * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
5 * All rights reserved.
6 */
7 /*
8 * This program is licenced under the same licence as Ruby.
9 * (See the file 'LICENCE'.)
11 #include "ossl.h"
13 #define WrapX509CRL(klass, obj, crl) do { \
14 if (!crl) { \
15 ossl_raise(rb_eRuntimeError, "CRL wasn't initialized!"); \
16 } \
17 obj = Data_Wrap_Struct(klass, 0, X509_CRL_free, crl); \
18 } while (0)
19 #define GetX509CRL(obj, crl) do { \
20 Data_Get_Struct(obj, X509_CRL, crl); \
21 if (!crl) { \
22 ossl_raise(rb_eRuntimeError, "CRL wasn't initialized!"); \
23 } \
24 } while (0)
25 #define SafeGetX509CRL(obj, crl) do { \
26 OSSL_Check_Kind(obj, cX509CRL); \
27 GetX509CRL(obj, crl); \
28 } while (0)
31 * Classes
33 VALUE cX509CRL;
34 VALUE eX509CRLError;
37 * PUBLIC
39 X509_CRL *
40 GetX509CRLPtr(VALUE obj)
42 X509_CRL *crl;
44 SafeGetX509CRL(obj, crl);
46 return crl;
49 X509_CRL *
50 DupX509CRLPtr(VALUE obj)
52 X509_CRL *crl;
54 SafeGetX509CRL(obj, crl);
55 CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509_CRL);
57 return crl;
60 VALUE
61 ossl_x509crl_new(X509_CRL *crl)
63 X509_CRL *tmp;
64 VALUE obj;
66 tmp = crl ? X509_CRL_dup(crl) : X509_CRL_new();
67 if(!tmp) ossl_raise(eX509CRLError, NULL);
68 WrapX509CRL(cX509CRL, obj, tmp);
70 return obj;
74 * PRIVATE
76 static VALUE
77 ossl_x509crl_alloc(VALUE klass)
79 X509_CRL *crl;
80 VALUE obj;
82 if (!(crl = X509_CRL_new())) {
83 ossl_raise(eX509CRLError, NULL);
85 WrapX509CRL(klass, obj, crl);
87 return obj;
90 static VALUE
91 ossl_x509crl_initialize(int argc, VALUE *argv, VALUE self)
93 BIO *in;
94 X509_CRL *crl;
95 VALUE arg;
97 if (rb_scan_args(argc, argv, "01", &arg) == 0) {
98 return self;
100 arg = ossl_to_der_if_possible(arg);
101 in = ossl_obj2bio(arg);
102 crl = PEM_read_bio_X509_CRL(in, (X509_CRL **)&DATA_PTR(self), NULL, NULL);
103 if (!crl) {
104 BIO_reset(in);
105 crl = d2i_X509_CRL_bio(in, (X509_CRL **)&DATA_PTR(self));
107 BIO_free(in);
108 if (!crl) ossl_raise(eX509CRLError, NULL);
110 return self;
113 static VALUE
114 ossl_x509crl_copy(VALUE self, VALUE other)
116 X509_CRL *a, *b, *crl;
118 rb_check_frozen(self);
119 if (self == other) return self;
120 GetX509CRL(self, a);
121 SafeGetX509CRL(other, b);
122 if (!(crl = X509_CRL_dup(b))) {
123 ossl_raise(eX509CRLError, NULL);
125 X509_CRL_free(a);
126 DATA_PTR(self) = crl;
128 return self;
131 static VALUE
132 ossl_x509crl_get_version(VALUE self)
134 X509_CRL *crl;
135 long ver;
137 GetX509CRL(self, crl);
138 ver = X509_CRL_get_version(crl);
140 return LONG2NUM(ver);
143 static VALUE
144 ossl_x509crl_set_version(VALUE self, VALUE version)
146 X509_CRL *crl;
147 long ver;
149 if ((ver = NUM2LONG(version)) < 0) {
150 ossl_raise(eX509CRLError, "version must be >= 0!");
152 GetX509CRL(self, crl);
153 if (!X509_CRL_set_version(crl, ver)) {
154 ossl_raise(eX509CRLError, NULL);
157 return version;
160 static VALUE
161 ossl_x509crl_get_signature_algorithm(VALUE self)
163 X509_CRL *crl;
164 BIO *out;
165 BUF_MEM *buf;
166 VALUE str;
168 GetX509CRL(self, crl);
169 if (!(out = BIO_new(BIO_s_mem()))) {
170 ossl_raise(eX509CRLError, NULL);
172 if (!i2a_ASN1_OBJECT(out, crl->sig_alg->algorithm)) {
173 BIO_free(out);
174 ossl_raise(eX509CRLError, NULL);
176 BIO_get_mem_ptr(out, &buf);
177 str = rb_str_new(buf->data, buf->length);
178 BIO_free(out);
179 return str;
182 static VALUE
183 ossl_x509crl_get_issuer(VALUE self)
185 X509_CRL *crl;
187 GetX509CRL(self, crl);
189 return ossl_x509name_new(X509_CRL_get_issuer(crl)); /* NO DUP - don't free */
192 static VALUE
193 ossl_x509crl_set_issuer(VALUE self, VALUE issuer)
195 X509_CRL *crl;
197 GetX509CRL(self, crl);
199 if (!X509_CRL_set_issuer_name(crl, GetX509NamePtr(issuer))) { /* DUPs name */
200 ossl_raise(eX509CRLError, NULL);
202 return issuer;
205 static VALUE
206 ossl_x509crl_get_last_update(VALUE self)
208 X509_CRL *crl;
210 GetX509CRL(self, crl);
212 return asn1time_to_time(X509_CRL_get_lastUpdate(crl));
215 static VALUE
216 ossl_x509crl_set_last_update(VALUE self, VALUE time)
218 X509_CRL *crl;
219 time_t sec;
221 sec = time_to_time_t(time);
222 GetX509CRL(self, crl);
223 if (!X509_time_adj(crl->crl->lastUpdate, 0, &sec)) {
224 ossl_raise(eX509CRLError, NULL);
227 return time;
230 static VALUE
231 ossl_x509crl_get_next_update(VALUE self)
233 X509_CRL *crl;
235 GetX509CRL(self, crl);
237 return asn1time_to_time(X509_CRL_get_nextUpdate(crl));
240 static VALUE
241 ossl_x509crl_set_next_update(VALUE self, VALUE time)
243 X509_CRL *crl;
244 time_t sec;
246 sec = time_to_time_t(time);
247 GetX509CRL(self, crl);
248 /* This must be some thinko in OpenSSL */
249 if (!(crl->crl->nextUpdate = X509_time_adj(crl->crl->nextUpdate, 0, &sec))){
250 ossl_raise(eX509CRLError, NULL);
253 return time;
256 static VALUE
257 ossl_x509crl_get_revoked(VALUE self)
259 X509_CRL *crl;
260 int i, num;
261 X509_REVOKED *rev;
262 VALUE ary, revoked;
264 GetX509CRL(self, crl);
265 num = sk_X509_CRL_num(X509_CRL_get_REVOKED(crl));
266 if (num < 0) {
267 OSSL_Debug("num < 0???");
268 return rb_ary_new();
270 ary = rb_ary_new2(num);
271 for(i=0; i<num; i++) {
272 /* NO DUP - don't free! */
273 rev = (X509_REVOKED *)sk_X509_CRL_value(X509_CRL_get_REVOKED(crl), i);
274 revoked = ossl_x509revoked_new(rev);
275 rb_ary_push(ary, revoked);
278 return ary;
281 static VALUE
282 ossl_x509crl_set_revoked(VALUE self, VALUE ary)
284 X509_CRL *crl;
285 X509_REVOKED *rev;
286 int i;
288 Check_Type(ary, T_ARRAY);
289 /* All ary members should be X509 Revoked */
290 for (i=0; i<RARRAY(ary)->len; i++) {
291 OSSL_Check_Kind(RARRAY(ary)->ptr[i], cX509Rev);
293 GetX509CRL(self, crl);
294 sk_X509_REVOKED_pop_free(crl->crl->revoked, X509_REVOKED_free);
295 crl->crl->revoked = NULL;
296 for (i=0; i<RARRAY(ary)->len; i++) {
297 rev = DupX509RevokedPtr(RARRAY(ary)->ptr[i]);
298 if (!X509_CRL_add0_revoked(crl, rev)) { /* NO DUP - don't free! */
299 ossl_raise(eX509CRLError, NULL);
302 X509_CRL_sort(crl);
304 return ary;
307 static VALUE
308 ossl_x509crl_add_revoked(VALUE self, VALUE revoked)
310 X509_CRL *crl;
311 X509_REVOKED *rev;
313 GetX509CRL(self, crl);
314 rev = DupX509RevokedPtr(revoked);
315 if (!X509_CRL_add0_revoked(crl, rev)) { /* NO DUP - don't free! */
316 ossl_raise(eX509CRLError, NULL);
318 X509_CRL_sort(crl);
320 return revoked;
323 static VALUE
324 ossl_x509crl_sign(VALUE self, VALUE key, VALUE digest)
326 X509_CRL *crl;
327 EVP_PKEY *pkey;
328 const EVP_MD *md;
330 GetX509CRL(self, crl);
331 pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */
332 md = GetDigestPtr(digest);
333 if (!X509_CRL_sign(crl, pkey, md)) {
334 ossl_raise(eX509CRLError, NULL);
337 return self;
340 static VALUE
341 ossl_x509crl_verify(VALUE self, VALUE key)
343 X509_CRL *crl;
344 int ret;
346 GetX509CRL(self, crl);
347 if ((ret = X509_CRL_verify(crl, GetPKeyPtr(key))) < 0) {
348 ossl_raise(eX509CRLError, NULL);
350 if (ret == 1) {
351 return Qtrue;
354 return Qfalse;
357 static VALUE
358 ossl_x509crl_to_der(VALUE self)
360 X509_CRL *crl;
361 BIO *out;
362 BUF_MEM *buf;
363 VALUE str;
365 GetX509CRL(self, crl);
366 if (!(out = BIO_new(BIO_s_mem()))) {
367 ossl_raise(eX509CRLError, NULL);
369 if (!i2d_X509_CRL_bio(out, crl)) {
370 BIO_free(out);
371 ossl_raise(eX509CRLError, NULL);
373 BIO_get_mem_ptr(out, &buf);
374 str = rb_str_new(buf->data, buf->length);
375 BIO_free(out);
377 return str;
380 static VALUE
381 ossl_x509crl_to_pem(VALUE self)
383 X509_CRL *crl;
384 BIO *out;
385 BUF_MEM *buf;
386 VALUE str;
388 GetX509CRL(self, crl);
389 if (!(out = BIO_new(BIO_s_mem()))) {
390 ossl_raise(eX509CRLError, NULL);
392 if (!PEM_write_bio_X509_CRL(out, crl)) {
393 BIO_free(out);
394 ossl_raise(eX509CRLError, NULL);
396 BIO_get_mem_ptr(out, &buf);
397 str = rb_str_new(buf->data, buf->length);
398 BIO_free(out);
400 return str;
403 static VALUE
404 ossl_x509crl_to_text(VALUE self)
406 X509_CRL *crl;
407 BIO *out;
408 BUF_MEM *buf;
409 VALUE str;
411 GetX509CRL(self, crl);
412 if (!(out = BIO_new(BIO_s_mem()))) {
413 ossl_raise(eX509CRLError, NULL);
415 if (!X509_CRL_print(out, crl)) {
416 BIO_free(out);
417 ossl_raise(eX509CRLError, NULL);
419 BIO_get_mem_ptr(out, &buf);
420 str = rb_str_new(buf->data, buf->length);
421 BIO_free(out);
423 return str;
427 * Gets X509v3 extensions as array of X509Ext objects
429 static VALUE
430 ossl_x509crl_get_extensions(VALUE self)
432 X509_CRL *crl;
433 int count, i;
434 X509_EXTENSION *ext;
435 VALUE ary;
437 GetX509CRL(self, crl);
438 count = X509_CRL_get_ext_count(crl);
439 if (count < 0) {
440 OSSL_Debug("count < 0???");
441 return rb_ary_new();
443 ary = rb_ary_new2(count);
444 for (i=0; i<count; i++) {
445 ext = X509_CRL_get_ext(crl, i); /* NO DUP - don't free! */
446 rb_ary_push(ary, ossl_x509ext_new(ext));
449 return ary;
453 * Sets X509_EXTENSIONs
455 static VALUE
456 ossl_x509crl_set_extensions(VALUE self, VALUE ary)
458 X509_CRL *crl;
459 X509_EXTENSION *ext;
460 int i;
462 Check_Type(ary, T_ARRAY);
463 /* All ary members should be X509 Extensions */
464 for (i=0; i<RARRAY(ary)->len; i++) {
465 OSSL_Check_Kind(RARRAY(ary)->ptr[i], cX509Ext);
467 GetX509CRL(self, crl);
468 sk_X509_EXTENSION_pop_free(crl->crl->extensions, X509_EXTENSION_free);
469 crl->crl->extensions = NULL;
470 for (i=0; i<RARRAY(ary)->len; i++) {
471 ext = DupX509ExtPtr(RARRAY(ary)->ptr[i]);
472 if(!X509_CRL_add_ext(crl, ext, -1)) { /* DUPs ext - FREE it */
473 X509_EXTENSION_free(ext);
474 ossl_raise(eX509CRLError, NULL);
476 X509_EXTENSION_free(ext);
479 return ary;
482 static VALUE
483 ossl_x509crl_add_extension(VALUE self, VALUE extension)
485 X509_CRL *crl;
486 X509_EXTENSION *ext;
488 GetX509CRL(self, crl);
489 ext = DupX509ExtPtr(extension);
490 if (!X509_CRL_add_ext(crl, ext, -1)) { /* DUPs ext - FREE it */
491 X509_EXTENSION_free(ext);
492 ossl_raise(eX509CRLError, NULL);
494 X509_EXTENSION_free(ext);
496 return extension;
500 * INIT
502 void
503 Init_ossl_x509crl()
505 eX509CRLError = rb_define_class_under(mX509, "CRLError", eOSSLError);
507 cX509CRL = rb_define_class_under(mX509, "CRL", rb_cObject);
509 rb_define_alloc_func(cX509CRL, ossl_x509crl_alloc);
510 rb_define_method(cX509CRL, "initialize", ossl_x509crl_initialize, -1);
511 rb_define_copy_func(cX509CRL, ossl_x509crl_copy);
513 rb_define_method(cX509CRL, "version", ossl_x509crl_get_version, 0);
514 rb_define_method(cX509CRL, "version=", ossl_x509crl_set_version, 1);
515 rb_define_method(cX509CRL, "signature_algorithm", ossl_x509crl_get_signature_algorithm, 0);
516 rb_define_method(cX509CRL, "issuer", ossl_x509crl_get_issuer, 0);
517 rb_define_method(cX509CRL, "issuer=", ossl_x509crl_set_issuer, 1);
518 rb_define_method(cX509CRL, "last_update", ossl_x509crl_get_last_update, 0);
519 rb_define_method(cX509CRL, "last_update=", ossl_x509crl_set_last_update, 1);
520 rb_define_method(cX509CRL, "next_update", ossl_x509crl_get_next_update, 0);
521 rb_define_method(cX509CRL, "next_update=", ossl_x509crl_set_next_update, 1);
522 rb_define_method(cX509CRL, "revoked", ossl_x509crl_get_revoked, 0);
523 rb_define_method(cX509CRL, "revoked=", ossl_x509crl_set_revoked, 1);
524 rb_define_method(cX509CRL, "add_revoked", ossl_x509crl_add_revoked, 1);
525 rb_define_method(cX509CRL, "sign", ossl_x509crl_sign, 2);
526 rb_define_method(cX509CRL, "verify", ossl_x509crl_verify, 1);
527 rb_define_method(cX509CRL, "to_der", ossl_x509crl_to_der, 0);
528 rb_define_method(cX509CRL, "to_pem", ossl_x509crl_to_pem, 0);
529 rb_define_alias(cX509CRL, "to_s", "to_pem");
530 rb_define_method(cX509CRL, "to_text", ossl_x509crl_to_text, 0);
531 rb_define_method(cX509CRL, "extensions", ossl_x509crl_get_extensions, 0);
532 rb_define_method(cX509CRL, "extensions=", ossl_x509crl_set_extensions, 1);
533 rb_define_method(cX509CRL, "add_extension", ossl_x509crl_add_extension, 1);