Ruby 2.0.0p247(2013-06-27revision41674)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

ossl_x509crl.c
Go to the documentation of this file.
1 /*
2 * $Id: ossl_x509crl.c 32199 2011-06-22 08:41:08Z emboss $
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'.)
10 */
11 #include "ossl.h"
12
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)
29
30 /*
31 * Classes
32 */
33 VALUE cX509CRL;
34 VALUE eX509CRLError;
35
36 /*
37 * PUBLIC
38 */
39 X509_CRL *
40 GetX509CRLPtr(VALUE obj)
41 {
42 X509_CRL *crl;
43
44 SafeGetX509CRL(obj, crl);
45
46 return crl;
47 }
48
49 X509_CRL *
50 DupX509CRLPtr(VALUE obj)
51 {
52 X509_CRL *crl;
53
54 SafeGetX509CRL(obj, crl);
55 CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509_CRL);
56
57 return crl;
58 }
59
60 VALUE
61 ossl_x509crl_new(X509_CRL *crl)
62 {
63 X509_CRL *tmp;
64 VALUE obj;
65
66 tmp = crl ? X509_CRL_dup(crl) : X509_CRL_new();
67 if(!tmp) ossl_raise(eX509CRLError, NULL);
68 WrapX509CRL(cX509CRL, obj, tmp);
69
70 return obj;
71 }
72
73 /*
74 * PRIVATE
75 */
76 static VALUE
77 ossl_x509crl_alloc(VALUE klass)
78 {
79 X509_CRL *crl;
80 VALUE obj;
81
82 if (!(crl = X509_CRL_new())) {
83 ossl_raise(eX509CRLError, NULL);
84 }
85 WrapX509CRL(klass, obj, crl);
86
87 return obj;
88 }
89
90 static VALUE
91 ossl_x509crl_initialize(int argc, VALUE *argv, VALUE self)
92 {
93 BIO *in;
94 X509_CRL *crl, *x = DATA_PTR(self);
95 VALUE arg;
96
97 if (rb_scan_args(argc, argv, "01", &arg) == 0) {
98 return self;
99 }
100 arg = ossl_to_der_if_possible(arg);
101 in = ossl_obj2bio(arg);
102 crl = PEM_read_bio_X509_CRL(in, &x, NULL, NULL);
103 DATA_PTR(self) = x;
104 if (!crl) {
105 OSSL_BIO_reset(in);
106 crl = d2i_X509_CRL_bio(in, &x);
107 DATA_PTR(self) = x;
108 }
109 BIO_free(in);
110 if (!crl) ossl_raise(eX509CRLError, NULL);
111
112 return self;
113 }
114
115 static VALUE
116 ossl_x509crl_copy(VALUE self, VALUE other)
117 {
118 X509_CRL *a, *b, *crl;
119
120 rb_check_frozen(self);
121 if (self == other) return self;
122 GetX509CRL(self, a);
123 SafeGetX509CRL(other, b);
124 if (!(crl = X509_CRL_dup(b))) {
125 ossl_raise(eX509CRLError, NULL);
126 }
127 X509_CRL_free(a);
128 DATA_PTR(self) = crl;
129
130 return self;
131 }
132
133 static VALUE
134 ossl_x509crl_get_version(VALUE self)
135 {
136 X509_CRL *crl;
137 long ver;
138
139 GetX509CRL(self, crl);
140 ver = X509_CRL_get_version(crl);
141
142 return LONG2NUM(ver);
143 }
144
145 static VALUE
146 ossl_x509crl_set_version(VALUE self, VALUE version)
147 {
148 X509_CRL *crl;
149 long ver;
150
151 if ((ver = NUM2LONG(version)) < 0) {
152 ossl_raise(eX509CRLError, "version must be >= 0!");
153 }
154 GetX509CRL(self, crl);
155 if (!X509_CRL_set_version(crl, ver)) {
156 ossl_raise(eX509CRLError, NULL);
157 }
158
159 return version;
160 }
161
162 static VALUE
163 ossl_x509crl_get_signature_algorithm(VALUE self)
164 {
165 X509_CRL *crl;
166 BIO *out;
167 BUF_MEM *buf;
168 VALUE str;
169
170 GetX509CRL(self, crl);
171 if (!(out = BIO_new(BIO_s_mem()))) {
172 ossl_raise(eX509CRLError, NULL);
173 }
174 if (!i2a_ASN1_OBJECT(out, crl->sig_alg->algorithm)) {
175 BIO_free(out);
176 ossl_raise(eX509CRLError, NULL);
177 }
178 BIO_get_mem_ptr(out, &buf);
179 str = rb_str_new(buf->data, buf->length);
180 BIO_free(out);
181 return str;
182 }
183
184 static VALUE
185 ossl_x509crl_get_issuer(VALUE self)
186 {
187 X509_CRL *crl;
188
189 GetX509CRL(self, crl);
190
191 return ossl_x509name_new(X509_CRL_get_issuer(crl)); /* NO DUP - don't free */
192 }
193
194 static VALUE
195 ossl_x509crl_set_issuer(VALUE self, VALUE issuer)
196 {
197 X509_CRL *crl;
198
199 GetX509CRL(self, crl);
200
201 if (!X509_CRL_set_issuer_name(crl, GetX509NamePtr(issuer))) { /* DUPs name */
202 ossl_raise(eX509CRLError, NULL);
203 }
204 return issuer;
205 }
206
207 static VALUE
208 ossl_x509crl_get_last_update(VALUE self)
209 {
210 X509_CRL *crl;
211
212 GetX509CRL(self, crl);
213
214 return asn1time_to_time(X509_CRL_get_lastUpdate(crl));
215 }
216
217 static VALUE
218 ossl_x509crl_set_last_update(VALUE self, VALUE time)
219 {
220 X509_CRL *crl;
221 time_t sec;
222
223 sec = time_to_time_t(time);
224 GetX509CRL(self, crl);
225 if (!X509_time_adj(crl->crl->lastUpdate, 0, &sec)) {
226 ossl_raise(eX509CRLError, NULL);
227 }
228
229 return time;
230 }
231
232 static VALUE
233 ossl_x509crl_get_next_update(VALUE self)
234 {
235 X509_CRL *crl;
236
237 GetX509CRL(self, crl);
238
239 return asn1time_to_time(X509_CRL_get_nextUpdate(crl));
240 }
241
242 static VALUE
243 ossl_x509crl_set_next_update(VALUE self, VALUE time)
244 {
245 X509_CRL *crl;
246 time_t sec;
247
248 sec = time_to_time_t(time);
249 GetX509CRL(self, crl);
250 /* This must be some thinko in OpenSSL */
251 if (!(crl->crl->nextUpdate = X509_time_adj(crl->crl->nextUpdate, 0, &sec))){
252 ossl_raise(eX509CRLError, NULL);
253 }
254
255 return time;
256 }
257
258 static VALUE
259 ossl_x509crl_get_revoked(VALUE self)
260 {
261 X509_CRL *crl;
262 int i, num;
263 X509_REVOKED *rev;
264 VALUE ary, revoked;
265
266 GetX509CRL(self, crl);
267 num = sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl));
268 if (num < 0) {
269 OSSL_Debug("num < 0???");
270 return rb_ary_new();
271 }
272 ary = rb_ary_new2(num);
273 for(i=0; i<num; i++) {
274 /* NO DUP - don't free! */
275 rev = sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i);
276 revoked = ossl_x509revoked_new(rev);
277 rb_ary_push(ary, revoked);
278 }
279
280 return ary;
281 }
282
283 static VALUE
284 ossl_x509crl_set_revoked(VALUE self, VALUE ary)
285 {
286 X509_CRL *crl;
287 X509_REVOKED *rev;
288 int i;
289
290 Check_Type(ary, T_ARRAY);
291 /* All ary members should be X509 Revoked */
292 for (i=0; i<RARRAY_LEN(ary); i++) {
293 OSSL_Check_Kind(RARRAY_PTR(ary)[i], cX509Rev);
294 }
295 GetX509CRL(self, crl);
296 sk_X509_REVOKED_pop_free(crl->crl->revoked, X509_REVOKED_free);
297 crl->crl->revoked = NULL;
298 for (i=0; i<RARRAY_LEN(ary); i++) {
299 rev = DupX509RevokedPtr(RARRAY_PTR(ary)[i]);
300 if (!X509_CRL_add0_revoked(crl, rev)) { /* NO DUP - don't free! */
301 ossl_raise(eX509CRLError, NULL);
302 }
303 }
304 X509_CRL_sort(crl);
305
306 return ary;
307 }
308
309 static VALUE
310 ossl_x509crl_add_revoked(VALUE self, VALUE revoked)
311 {
312 X509_CRL *crl;
313 X509_REVOKED *rev;
314
315 GetX509CRL(self, crl);
316 rev = DupX509RevokedPtr(revoked);
317 if (!X509_CRL_add0_revoked(crl, rev)) { /* NO DUP - don't free! */
318 ossl_raise(eX509CRLError, NULL);
319 }
320 X509_CRL_sort(crl);
321
322 return revoked;
323 }
324
325 static VALUE
326 ossl_x509crl_sign(VALUE self, VALUE key, VALUE digest)
327 {
328 X509_CRL *crl;
329 EVP_PKEY *pkey;
330 const EVP_MD *md;
331
332 GetX509CRL(self, crl);
333 pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */
334 md = GetDigestPtr(digest);
335 if (!X509_CRL_sign(crl, pkey, md)) {
336 ossl_raise(eX509CRLError, NULL);
337 }
338
339 return self;
340 }
341
342 static VALUE
343 ossl_x509crl_verify(VALUE self, VALUE key)
344 {
345 X509_CRL *crl;
346 int ret;
347
348 GetX509CRL(self, crl);
349 if ((ret = X509_CRL_verify(crl, GetPKeyPtr(key))) < 0) {
350 ossl_raise(eX509CRLError, NULL);
351 }
352 if (ret == 1) {
353 return Qtrue;
354 }
355
356 return Qfalse;
357 }
358
359 static VALUE
360 ossl_x509crl_to_der(VALUE self)
361 {
362 X509_CRL *crl;
363 BIO *out;
364 BUF_MEM *buf;
365 VALUE str;
366
367 GetX509CRL(self, crl);
368 if (!(out = BIO_new(BIO_s_mem()))) {
369 ossl_raise(eX509CRLError, NULL);
370 }
371 if (!i2d_X509_CRL_bio(out, crl)) {
372 BIO_free(out);
373 ossl_raise(eX509CRLError, NULL);
374 }
375 BIO_get_mem_ptr(out, &buf);
376 str = rb_str_new(buf->data, buf->length);
377 BIO_free(out);
378
379 return str;
380 }
381
382 static VALUE
383 ossl_x509crl_to_pem(VALUE self)
384 {
385 X509_CRL *crl;
386 BIO *out;
387 BUF_MEM *buf;
388 VALUE str;
389
390 GetX509CRL(self, crl);
391 if (!(out = BIO_new(BIO_s_mem()))) {
392 ossl_raise(eX509CRLError, NULL);
393 }
394 if (!PEM_write_bio_X509_CRL(out, crl)) {
395 BIO_free(out);
396 ossl_raise(eX509CRLError, NULL);
397 }
398 BIO_get_mem_ptr(out, &buf);
399 str = rb_str_new(buf->data, buf->length);
400 BIO_free(out);
401
402 return str;
403 }
404
405 static VALUE
406 ossl_x509crl_to_text(VALUE self)
407 {
408 X509_CRL *crl;
409 BIO *out;
410 BUF_MEM *buf;
411 VALUE str;
412
413 GetX509CRL(self, crl);
414 if (!(out = BIO_new(BIO_s_mem()))) {
415 ossl_raise(eX509CRLError, NULL);
416 }
417 if (!X509_CRL_print(out, crl)) {
418 BIO_free(out);
419 ossl_raise(eX509CRLError, NULL);
420 }
421 BIO_get_mem_ptr(out, &buf);
422 str = rb_str_new(buf->data, buf->length);
423 BIO_free(out);
424
425 return str;
426 }
427
428 /*
429 * Gets X509v3 extensions as array of X509Ext objects
430 */
431 static VALUE
432 ossl_x509crl_get_extensions(VALUE self)
433 {
434 X509_CRL *crl;
435 int count, i;
436 X509_EXTENSION *ext;
437 VALUE ary;
438
439 GetX509CRL(self, crl);
440 count = X509_CRL_get_ext_count(crl);
441 if (count < 0) {
442 OSSL_Debug("count < 0???");
443 return rb_ary_new();
444 }
445 ary = rb_ary_new2(count);
446 for (i=0; i<count; i++) {
447 ext = X509_CRL_get_ext(crl, i); /* NO DUP - don't free! */
448 rb_ary_push(ary, ossl_x509ext_new(ext));
449 }
450
451 return ary;
452 }
453
454 /*
455 * Sets X509_EXTENSIONs
456 */
457 static VALUE
458 ossl_x509crl_set_extensions(VALUE self, VALUE ary)
459 {
460 X509_CRL *crl;
461 X509_EXTENSION *ext;
462 int i;
463
464 Check_Type(ary, T_ARRAY);
465 /* All ary members should be X509 Extensions */
466 for (i=0; i<RARRAY_LEN(ary); i++) {
467 OSSL_Check_Kind(RARRAY_PTR(ary)[i], cX509Ext);
468 }
469 GetX509CRL(self, crl);
470 sk_X509_EXTENSION_pop_free(crl->crl->extensions, X509_EXTENSION_free);
471 crl->crl->extensions = NULL;
472 for (i=0; i<RARRAY_LEN(ary); i++) {
473 ext = DupX509ExtPtr(RARRAY_PTR(ary)[i]);
474 if(!X509_CRL_add_ext(crl, ext, -1)) { /* DUPs ext - FREE it */
475 X509_EXTENSION_free(ext);
476 ossl_raise(eX509CRLError, NULL);
477 }
478 X509_EXTENSION_free(ext);
479 }
480
481 return ary;
482 }
483
484 static VALUE
485 ossl_x509crl_add_extension(VALUE self, VALUE extension)
486 {
487 X509_CRL *crl;
488 X509_EXTENSION *ext;
489
490 GetX509CRL(self, crl);
491 ext = DupX509ExtPtr(extension);
492 if (!X509_CRL_add_ext(crl, ext, -1)) { /* DUPs ext - FREE it */
493 X509_EXTENSION_free(ext);
494 ossl_raise(eX509CRLError, NULL);
495 }
496 X509_EXTENSION_free(ext);
497
498 return extension;
499 }
500
501 /*
502 * INIT
503 */
504 void
505 Init_ossl_x509crl()
506 {
507 eX509CRLError = rb_define_class_under(mX509, "CRLError", eOSSLError);
508
509 cX509CRL = rb_define_class_under(mX509, "CRL", rb_cObject);
510
511 rb_define_alloc_func(cX509CRL, ossl_x509crl_alloc);
512 rb_define_method(cX509CRL, "initialize", ossl_x509crl_initialize, -1);
513 rb_define_copy_func(cX509CRL, ossl_x509crl_copy);
514
515 rb_define_method(cX509CRL, "version", ossl_x509crl_get_version, 0);
516 rb_define_method(cX509CRL, "version=", ossl_x509crl_set_version, 1);
517 rb_define_method(cX509CRL, "signature_algorithm", ossl_x509crl_get_signature_algorithm, 0);
518 rb_define_method(cX509CRL, "issuer", ossl_x509crl_get_issuer, 0);
519 rb_define_method(cX509CRL, "issuer=", ossl_x509crl_set_issuer, 1);
520 rb_define_method(cX509CRL, "last_update", ossl_x509crl_get_last_update, 0);
521 rb_define_method(cX509CRL, "last_update=", ossl_x509crl_set_last_update, 1);
522 rb_define_method(cX509CRL, "next_update", ossl_x509crl_get_next_update, 0);
523 rb_define_method(cX509CRL, "next_update=", ossl_x509crl_set_next_update, 1);
524 rb_define_method(cX509CRL, "revoked", ossl_x509crl_get_revoked, 0);
525 rb_define_method(cX509CRL, "revoked=", ossl_x509crl_set_revoked, 1);
526 rb_define_method(cX509CRL, "add_revoked", ossl_x509crl_add_revoked, 1);
527 rb_define_method(cX509CRL, "sign", ossl_x509crl_sign, 2);
528 rb_define_method(cX509CRL, "verify", ossl_x509crl_verify, 1);
529 rb_define_method(cX509CRL, "to_der", ossl_x509crl_to_der, 0);
530 rb_define_method(cX509CRL, "to_pem", ossl_x509crl_to_pem, 0);
531 rb_define_alias(cX509CRL, "to_s", "to_pem");
532 rb_define_method(cX509CRL, "to_text", ossl_x509crl_to_text, 0);
533 rb_define_method(cX509CRL, "extensions", ossl_x509crl_get_extensions, 0);
534 rb_define_method(cX509CRL, "extensions=", ossl_x509crl_set_extensions, 1);
535 rb_define_method(cX509CRL, "add_extension", ossl_x509crl_add_extension, 1);
536 }
537
538