1 /*
2 * 'OpenSSL for Ruby' project
3 * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
4 * All rights reserved.
5 */
6 /*
7 * This program is licensed under the same licence as Ruby.
8 * (See the file 'LICENCE'.)
9 */
10 #include "ossl.h"
11
12 #define NewX509(klass) \
13 TypedData_Wrap_Struct((klass), &ossl_x509_type, 0)
14 #define SetX509(obj, x509) do { \
15 if (!(x509)) { \
16 ossl_raise(rb_eRuntimeError, "CERT wasn't initialized!"); \
17 } \
18 RTYPEDDATA_DATA(obj) = (x509); \
19 } while (0)
20 #define GetX509(obj, x509) do { \
21 TypedData_Get_Struct((obj), X509, &ossl_x509_type, (x509)); \
22 if (!(x509)) { \
23 ossl_raise(rb_eRuntimeError, "CERT wasn't initialized!"); \
24 } \
25 } while (0)
26
27 /*
28 * Classes
29 */
30 VALUE cX509Cert;
31 VALUE eX509CertError;
32
33 static void
ossl_x509_free(void * ptr)34 ossl_x509_free(void *ptr)
35 {
36 X509_free(ptr);
37 }
38
39 static const rb_data_type_t ossl_x509_type = {
40 "OpenSSL/X509",
41 {
42 0, ossl_x509_free,
43 },
44 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
45 };
46
47 /*
48 * Public
49 */
50 VALUE
ossl_x509_new(X509 * x509)51 ossl_x509_new(X509 *x509)
52 {
53 X509 *new;
54 VALUE obj;
55
56 obj = NewX509(cX509Cert);
57 if (!x509) {
58 new = X509_new();
59 } else {
60 new = X509_dup(x509);
61 }
62 if (!new) {
63 ossl_raise(eX509CertError, NULL);
64 }
65 SetX509(obj, new);
66
67 return obj;
68 }
69
70 X509 *
GetX509CertPtr(VALUE obj)71 GetX509CertPtr(VALUE obj)
72 {
73 X509 *x509;
74
75 GetX509(obj, x509);
76
77 return x509;
78 }
79
80 X509 *
DupX509CertPtr(VALUE obj)81 DupX509CertPtr(VALUE obj)
82 {
83 X509 *x509;
84
85 GetX509(obj, x509);
86
87 X509_up_ref(x509);
88
89 return x509;
90 }
91
92 /*
93 * Private
94 */
95 static VALUE
ossl_x509_alloc(VALUE klass)96 ossl_x509_alloc(VALUE klass)
97 {
98 X509 *x509;
99 VALUE obj;
100
101 obj = NewX509(klass);
102 x509 = X509_new();
103 if (!x509) ossl_raise(eX509CertError, NULL);
104 SetX509(obj, x509);
105
106 return obj;
107 }
108
109 /*
110 * call-seq:
111 * Certificate.new => cert
112 * Certificate.new(string) => cert
113 */
114 static VALUE
ossl_x509_initialize(int argc,VALUE * argv,VALUE self)115 ossl_x509_initialize(int argc, VALUE *argv, VALUE self)
116 {
117 BIO *in;
118 X509 *x509, *x = DATA_PTR(self);
119 VALUE arg;
120
121 if (rb_scan_args(argc, argv, "01", &arg) == 0) {
122 /* create just empty X509Cert */
123 return self;
124 }
125 arg = ossl_to_der_if_possible(arg);
126 in = ossl_obj2bio(&arg);
127 x509 = PEM_read_bio_X509(in, &x, NULL, NULL);
128 DATA_PTR(self) = x;
129 if (!x509) {
130 OSSL_BIO_reset(in);
131 x509 = d2i_X509_bio(in, &x);
132 DATA_PTR(self) = x;
133 }
134 BIO_free(in);
135 if (!x509) ossl_raise(eX509CertError, NULL);
136
137 return self;
138 }
139
140 static VALUE
ossl_x509_copy(VALUE self,VALUE other)141 ossl_x509_copy(VALUE self, VALUE other)
142 {
143 X509 *a, *b, *x509;
144
145 rb_check_frozen(self);
146 if (self == other) return self;
147
148 GetX509(self, a);
149 GetX509(other, b);
150
151 x509 = X509_dup(b);
152 if (!x509) ossl_raise(eX509CertError, NULL);
153
154 DATA_PTR(self) = x509;
155 X509_free(a);
156
157 return self;
158 }
159
160 /*
161 * call-seq:
162 * cert.to_der => string
163 */
164 static VALUE
ossl_x509_to_der(VALUE self)165 ossl_x509_to_der(VALUE self)
166 {
167 X509 *x509;
168 VALUE str;
169 long len;
170 unsigned char *p;
171
172 GetX509(self, x509);
173 if ((len = i2d_X509(x509, NULL)) <= 0)
174 ossl_raise(eX509CertError, NULL);
175 str = rb_str_new(0, len);
176 p = (unsigned char *)RSTRING_PTR(str);
177 if (i2d_X509(x509, &p) <= 0)
178 ossl_raise(eX509CertError, NULL);
179 ossl_str_adjust(str, p);
180
181 return str;
182 }
183
184 /*
185 * call-seq:
186 * cert.to_pem => string
187 */
188 static VALUE
ossl_x509_to_pem(VALUE self)189 ossl_x509_to_pem(VALUE self)
190 {
191 X509 *x509;
192 BIO *out;
193 VALUE str;
194
195 GetX509(self, x509);
196 out = BIO_new(BIO_s_mem());
197 if (!out) ossl_raise(eX509CertError, NULL);
198
199 if (!PEM_write_bio_X509(out, x509)) {
200 BIO_free(out);
201 ossl_raise(eX509CertError, NULL);
202 }
203 str = ossl_membio2str(out);
204
205 return str;
206 }
207
208 /*
209 * call-seq:
210 * cert.to_text => string
211 */
212 static VALUE
ossl_x509_to_text(VALUE self)213 ossl_x509_to_text(VALUE self)
214 {
215 X509 *x509;
216 BIO *out;
217 VALUE str;
218
219 GetX509(self, x509);
220
221 out = BIO_new(BIO_s_mem());
222 if (!out) ossl_raise(eX509CertError, NULL);
223
224 if (!X509_print(out, x509)) {
225 BIO_free(out);
226 ossl_raise(eX509CertError, NULL);
227 }
228 str = ossl_membio2str(out);
229
230 return str;
231 }
232
233 #if 0
234 /*
235 * Makes from X509 X509_REQuest
236 */
237 static VALUE
238 ossl_x509_to_req(VALUE self)
239 {
240 X509 *x509;
241 X509_REQ *req;
242 VALUE obj;
243
244 GetX509(self, x509);
245 if (!(req = X509_to_X509_REQ(x509, NULL, EVP_md5()))) {
246 ossl_raise(eX509CertError, NULL);
247 }
248 obj = ossl_x509req_new(req);
249 X509_REQ_free(req);
250
251 return obj;
252 }
253 #endif
254
255 /*
256 * call-seq:
257 * cert.version => integer
258 */
259 static VALUE
ossl_x509_get_version(VALUE self)260 ossl_x509_get_version(VALUE self)
261 {
262 X509 *x509;
263
264 GetX509(self, x509);
265
266 return LONG2NUM(X509_get_version(x509));
267 }
268
269 /*
270 * call-seq:
271 * cert.version = integer => integer
272 */
273 static VALUE
ossl_x509_set_version(VALUE self,VALUE version)274 ossl_x509_set_version(VALUE self, VALUE version)
275 {
276 X509 *x509;
277 long ver;
278
279 if ((ver = NUM2LONG(version)) < 0) {
280 ossl_raise(eX509CertError, "version must be >= 0!");
281 }
282 GetX509(self, x509);
283 if (!X509_set_version(x509, ver)) {
284 ossl_raise(eX509CertError, NULL);
285 }
286
287 return version;
288 }
289
290 /*
291 * call-seq:
292 * cert.serial => integer
293 */
294 static VALUE
ossl_x509_get_serial(VALUE self)295 ossl_x509_get_serial(VALUE self)
296 {
297 X509 *x509;
298
299 GetX509(self, x509);
300
301 return asn1integer_to_num(X509_get_serialNumber(x509));
302 }
303
304 /*
305 * call-seq:
306 * cert.serial = integer => integer
307 */
308 static VALUE
ossl_x509_set_serial(VALUE self,VALUE num)309 ossl_x509_set_serial(VALUE self, VALUE num)
310 {
311 X509 *x509;
312
313 GetX509(self, x509);
314 X509_set_serialNumber(x509, num_to_asn1integer(num, X509_get_serialNumber(x509)));
315
316 return num;
317 }
318
319 /*
320 * call-seq:
321 * cert.signature_algorithm => string
322 */
323 static VALUE
ossl_x509_get_signature_algorithm(VALUE self)324 ossl_x509_get_signature_algorithm(VALUE self)
325 {
326 X509 *x509;
327 BIO *out;
328 VALUE str;
329
330 GetX509(self, x509);
331 out = BIO_new(BIO_s_mem());
332 if (!out) ossl_raise(eX509CertError, NULL);
333
334 if (!i2a_ASN1_OBJECT(out, X509_get0_tbs_sigalg(x509)->algorithm)) {
335 BIO_free(out);
336 ossl_raise(eX509CertError, NULL);
337 }
338 str = ossl_membio2str(out);
339
340 return str;
341 }
342
343 /*
344 * call-seq:
345 * cert.subject => name
346 */
347 static VALUE
ossl_x509_get_subject(VALUE self)348 ossl_x509_get_subject(VALUE self)
349 {
350 X509 *x509;
351 X509_NAME *name;
352
353 GetX509(self, x509);
354 if (!(name = X509_get_subject_name(x509))) { /* NO DUP - don't free! */
355 ossl_raise(eX509CertError, NULL);
356 }
357
358 return ossl_x509name_new(name);
359 }
360
361 /*
362 * call-seq:
363 * cert.subject = name => name
364 */
365 static VALUE
ossl_x509_set_subject(VALUE self,VALUE subject)366 ossl_x509_set_subject(VALUE self, VALUE subject)
367 {
368 X509 *x509;
369
370 GetX509(self, x509);
371 if (!X509_set_subject_name(x509, GetX509NamePtr(subject))) { /* DUPs name */
372 ossl_raise(eX509CertError, NULL);
373 }
374
375 return subject;
376 }
377
378 /*
379 * call-seq:
380 * cert.issuer => name
381 */
382 static VALUE
ossl_x509_get_issuer(VALUE self)383 ossl_x509_get_issuer(VALUE self)
384 {
385 X509 *x509;
386 X509_NAME *name;
387
388 GetX509(self, x509);
389 if(!(name = X509_get_issuer_name(x509))) { /* NO DUP - don't free! */
390 ossl_raise(eX509CertError, NULL);
391 }
392
393 return ossl_x509name_new(name);
394 }
395
396 /*
397 * call-seq:
398 * cert.issuer = name => name
399 */
400 static VALUE
ossl_x509_set_issuer(VALUE self,VALUE issuer)401 ossl_x509_set_issuer(VALUE self, VALUE issuer)
402 {
403 X509 *x509;
404
405 GetX509(self, x509);
406 if (!X509_set_issuer_name(x509, GetX509NamePtr(issuer))) { /* DUPs name */
407 ossl_raise(eX509CertError, NULL);
408 }
409
410 return issuer;
411 }
412
413 /*
414 * call-seq:
415 * cert.not_before => time
416 */
417 static VALUE
ossl_x509_get_not_before(VALUE self)418 ossl_x509_get_not_before(VALUE self)
419 {
420 X509 *x509;
421 const ASN1_TIME *asn1time;
422
423 GetX509(self, x509);
424 if (!(asn1time = X509_get0_notBefore(x509))) {
425 ossl_raise(eX509CertError, NULL);
426 }
427
428 return asn1time_to_time(asn1time);
429 }
430
431 /*
432 * call-seq:
433 * cert.not_before = time => time
434 */
435 static VALUE
ossl_x509_set_not_before(VALUE self,VALUE time)436 ossl_x509_set_not_before(VALUE self, VALUE time)
437 {
438 X509 *x509;
439 ASN1_TIME *asn1time;
440
441 GetX509(self, x509);
442 asn1time = ossl_x509_time_adjust(NULL, time);
443 if (!X509_set1_notBefore(x509, asn1time)) {
444 ASN1_TIME_free(asn1time);
445 ossl_raise(eX509CertError, "X509_set_notBefore");
446 }
447 ASN1_TIME_free(asn1time);
448
449 return time;
450 }
451
452 /*
453 * call-seq:
454 * cert.not_after => time
455 */
456 static VALUE
ossl_x509_get_not_after(VALUE self)457 ossl_x509_get_not_after(VALUE self)
458 {
459 X509 *x509;
460 const ASN1_TIME *asn1time;
461
462 GetX509(self, x509);
463 if (!(asn1time = X509_get0_notAfter(x509))) {
464 ossl_raise(eX509CertError, NULL);
465 }
466
467 return asn1time_to_time(asn1time);
468 }
469
470 /*
471 * call-seq:
472 * cert.not_after = time => time
473 */
474 static VALUE
ossl_x509_set_not_after(VALUE self,VALUE time)475 ossl_x509_set_not_after(VALUE self, VALUE time)
476 {
477 X509 *x509;
478 ASN1_TIME *asn1time;
479
480 GetX509(self, x509);
481 asn1time = ossl_x509_time_adjust(NULL, time);
482 if (!X509_set1_notAfter(x509, asn1time)) {
483 ASN1_TIME_free(asn1time);
484 ossl_raise(eX509CertError, "X509_set_notAfter");
485 }
486 ASN1_TIME_free(asn1time);
487
488 return time;
489 }
490
491 /*
492 * call-seq:
493 * cert.public_key => key
494 */
495 static VALUE
ossl_x509_get_public_key(VALUE self)496 ossl_x509_get_public_key(VALUE self)
497 {
498 X509 *x509;
499 EVP_PKEY *pkey;
500
501 GetX509(self, x509);
502 if (!(pkey = X509_get_pubkey(x509))) { /* adds an reference */
503 ossl_raise(eX509CertError, NULL);
504 }
505
506 return ossl_pkey_new(pkey); /* NO DUP - OK */
507 }
508
509 /*
510 * call-seq:
511 * cert.public_key = key
512 */
513 static VALUE
ossl_x509_set_public_key(VALUE self,VALUE key)514 ossl_x509_set_public_key(VALUE self, VALUE key)
515 {
516 X509 *x509;
517 EVP_PKEY *pkey;
518
519 GetX509(self, x509);
520 pkey = GetPKeyPtr(key);
521 ossl_pkey_check_public_key(pkey);
522 if (!X509_set_pubkey(x509, pkey))
523 ossl_raise(eX509CertError, "X509_set_pubkey");
524 return key;
525 }
526
527 /*
528 * call-seq:
529 * cert.sign(key, digest) => self
530 */
531 static VALUE
ossl_x509_sign(VALUE self,VALUE key,VALUE digest)532 ossl_x509_sign(VALUE self, VALUE key, VALUE digest)
533 {
534 X509 *x509;
535 EVP_PKEY *pkey;
536 const EVP_MD *md;
537
538 pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */
539 md = ossl_evp_get_digestbyname(digest);
540 GetX509(self, x509);
541 if (!X509_sign(x509, pkey, md)) {
542 ossl_raise(eX509CertError, NULL);
543 }
544
545 return self;
546 }
547
548 /*
549 * call-seq:
550 * cert.verify(key) => true | false
551 *
552 * Verifies the signature of the certificate, with the public key _key_. _key_
553 * must be an instance of OpenSSL::PKey.
554 */
555 static VALUE
ossl_x509_verify(VALUE self,VALUE key)556 ossl_x509_verify(VALUE self, VALUE key)
557 {
558 X509 *x509;
559 EVP_PKEY *pkey;
560
561 GetX509(self, x509);
562 pkey = GetPKeyPtr(key);
563 ossl_pkey_check_public_key(pkey);
564 switch (X509_verify(x509, pkey)) {
565 case 1:
566 return Qtrue;
567 case 0:
568 ossl_clear_error();
569 return Qfalse;
570 default:
571 ossl_raise(eX509CertError, NULL);
572 }
573 }
574
575 /*
576 * call-seq:
577 * cert.check_private_key(key) -> true | false
578 *
579 * Returns +true+ if _key_ is the corresponding private key to the Subject
580 * Public Key Information, +false+ otherwise.
581 */
582 static VALUE
ossl_x509_check_private_key(VALUE self,VALUE key)583 ossl_x509_check_private_key(VALUE self, VALUE key)
584 {
585 X509 *x509;
586 EVP_PKEY *pkey;
587
588 /* not needed private key, but should be */
589 pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */
590 GetX509(self, x509);
591 if (!X509_check_private_key(x509, pkey)) {
592 ossl_clear_error();
593 return Qfalse;
594 }
595
596 return Qtrue;
597 }
598
599 /*
600 * call-seq:
601 * cert.extensions => [extension...]
602 */
603 static VALUE
ossl_x509_get_extensions(VALUE self)604 ossl_x509_get_extensions(VALUE self)
605 {
606 X509 *x509;
607 int count, i;
608 X509_EXTENSION *ext;
609 VALUE ary;
610
611 GetX509(self, x509);
612 count = X509_get_ext_count(x509);
613 if (count < 0) {
614 return rb_ary_new();
615 }
616 ary = rb_ary_new2(count);
617 for (i=0; i<count; i++) {
618 ext = X509_get_ext(x509, i); /* NO DUP - don't free! */
619 rb_ary_push(ary, ossl_x509ext_new(ext));
620 }
621
622 return ary;
623 }
624
625 /*
626 * call-seq:
627 * cert.extensions = [ext...] => [ext...]
628 */
629 static VALUE
ossl_x509_set_extensions(VALUE self,VALUE ary)630 ossl_x509_set_extensions(VALUE self, VALUE ary)
631 {
632 X509 *x509;
633 X509_EXTENSION *ext;
634 long i;
635
636 Check_Type(ary, T_ARRAY);
637 /* All ary's members should be X509Extension */
638 for (i=0; i<RARRAY_LEN(ary); i++) {
639 OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Ext);
640 }
641 GetX509(self, x509);
642 while ((ext = X509_delete_ext(x509, 0)))
643 X509_EXTENSION_free(ext);
644 for (i=0; i<RARRAY_LEN(ary); i++) {
645 ext = GetX509ExtPtr(RARRAY_AREF(ary, i));
646 if (!X509_add_ext(x509, ext, -1)) { /* DUPs ext */
647 ossl_raise(eX509CertError, NULL);
648 }
649 }
650
651 return ary;
652 }
653
654 /*
655 * call-seq:
656 * cert.add_extension(extension) => extension
657 */
658 static VALUE
ossl_x509_add_extension(VALUE self,VALUE extension)659 ossl_x509_add_extension(VALUE self, VALUE extension)
660 {
661 X509 *x509;
662 X509_EXTENSION *ext;
663
664 GetX509(self, x509);
665 ext = GetX509ExtPtr(extension);
666 if (!X509_add_ext(x509, ext, -1)) { /* DUPs ext - FREE it */
667 ossl_raise(eX509CertError, NULL);
668 }
669
670 return extension;
671 }
672
673 static VALUE
ossl_x509_inspect(VALUE self)674 ossl_x509_inspect(VALUE self)
675 {
676 return rb_sprintf("#<%"PRIsVALUE": subject=%+"PRIsVALUE", "
677 "issuer=%+"PRIsVALUE", serial=%+"PRIsVALUE", "
678 "not_before=%+"PRIsVALUE", not_after=%+"PRIsVALUE">",
679 rb_obj_class(self),
680 ossl_x509_get_subject(self),
681 ossl_x509_get_issuer(self),
682 ossl_x509_get_serial(self),
683 ossl_x509_get_not_before(self),
684 ossl_x509_get_not_after(self));
685 }
686
687 /*
688 * call-seq:
689 * cert1 == cert2 -> true | false
690 *
691 * Compares the two certificates. Note that this takes into account all fields,
692 * not just the issuer name and the serial number.
693 */
694 static VALUE
ossl_x509_eq(VALUE self,VALUE other)695 ossl_x509_eq(VALUE self, VALUE other)
696 {
697 X509 *a, *b;
698
699 GetX509(self, a);
700 if (!rb_obj_is_kind_of(other, cX509Cert))
701 return Qfalse;
702 GetX509(other, b);
703
704 return !X509_cmp(a, b) ? Qtrue : Qfalse;
705 }
706
707 /*
708 * INIT
709 */
710 void
Init_ossl_x509cert(void)711 Init_ossl_x509cert(void)
712 {
713 #if 0
714 mOSSL = rb_define_module("OpenSSL");
715 eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
716 mX509 = rb_define_module_under(mOSSL, "X509");
717 #endif
718
719 eX509CertError = rb_define_class_under(mX509, "CertificateError", eOSSLError);
720
721 /* Document-class: OpenSSL::X509::Certificate
722 *
723 * Implementation of an X.509 certificate as specified in RFC 5280.
724 * Provides access to a certificate's attributes and allows certificates
725 * to be read from a string, but also supports the creation of new
726 * certificates from scratch.
727 *
728 * === Reading a certificate from a file
729 *
730 * Certificate is capable of handling DER-encoded certificates and
731 * certificates encoded in OpenSSL's PEM format.
732 *
733 * raw = File.read "cert.cer" # DER- or PEM-encoded
734 * certificate = OpenSSL::X509::Certificate.new raw
735 *
736 * === Saving a certificate to a file
737 *
738 * A certificate may be encoded in DER format
739 *
740 * cert = ...
741 * File.open("cert.cer", "wb") { |f| f.print cert.to_der }
742 *
743 * or in PEM format
744 *
745 * cert = ...
746 * File.open("cert.pem", "wb") { |f| f.print cert.to_pem }
747 *
748 * X.509 certificates are associated with a private/public key pair,
749 * typically a RSA, DSA or ECC key (see also OpenSSL::PKey::RSA,
750 * OpenSSL::PKey::DSA and OpenSSL::PKey::EC), the public key itself is
751 * stored within the certificate and can be accessed in form of an
752 * OpenSSL::PKey. Certificates are typically used to be able to associate
753 * some form of identity with a key pair, for example web servers serving
754 * pages over HTTPs use certificates to authenticate themselves to the user.
755 *
756 * The public key infrastructure (PKI) model relies on trusted certificate
757 * authorities ("root CAs") that issue these certificates, so that end
758 * users need to base their trust just on a selected few authorities
759 * that themselves again vouch for subordinate CAs issuing their
760 * certificates to end users.
761 *
762 * The OpenSSL::X509 module provides the tools to set up an independent
763 * PKI, similar to scenarios where the 'openssl' command line tool is
764 * used for issuing certificates in a private PKI.
765 *
766 * === Creating a root CA certificate and an end-entity certificate
767 *
768 * First, we need to create a "self-signed" root certificate. To do so,
769 * we need to generate a key first. Please note that the choice of "1"
770 * as a serial number is considered a security flaw for real certificates.
771 * Secure choices are integers in the two-digit byte range and ideally
772 * not sequential but secure random numbers, steps omitted here to keep
773 * the example concise.
774 *
775 * root_key = OpenSSL::PKey::RSA.new 2048 # the CA's public/private key
776 * root_ca = OpenSSL::X509::Certificate.new
777 * root_ca.version = 2 # cf. RFC 5280 - to make it a "v3" certificate
778 * root_ca.serial = 1
779 * root_ca.subject = OpenSSL::X509::Name.parse "/DC=org/DC=ruby-lang/CN=Ruby CA"
780 * root_ca.issuer = root_ca.subject # root CA's are "self-signed"
781 * root_ca.public_key = root_key.public_key
782 * root_ca.not_before = Time.now
783 * root_ca.not_after = root_ca.not_before + 2 * 365 * 24 * 60 * 60 # 2 years validity
784 * ef = OpenSSL::X509::ExtensionFactory.new
785 * ef.subject_certificate = root_ca
786 * ef.issuer_certificate = root_ca
787 * root_ca.add_extension(ef.create_extension("basicConstraints","CA:TRUE",true))
788 * root_ca.add_extension(ef.create_extension("keyUsage","keyCertSign, cRLSign", true))
789 * root_ca.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false))
790 * root_ca.add_extension(ef.create_extension("authorityKeyIdentifier","keyid:always",false))
791 * root_ca.sign(root_key, OpenSSL::Digest::SHA256.new)
792 *
793 * The next step is to create the end-entity certificate using the root CA
794 * certificate.
795 *
796 * key = OpenSSL::PKey::RSA.new 2048
797 * cert = OpenSSL::X509::Certificate.new
798 * cert.version = 2
799 * cert.serial = 2
800 * cert.subject = OpenSSL::X509::Name.parse "/DC=org/DC=ruby-lang/CN=Ruby certificate"
801 * cert.issuer = root_ca.subject # root CA is the issuer
802 * cert.public_key = key.public_key
803 * cert.not_before = Time.now
804 * cert.not_after = cert.not_before + 1 * 365 * 24 * 60 * 60 # 1 years validity
805 * ef = OpenSSL::X509::ExtensionFactory.new
806 * ef.subject_certificate = cert
807 * ef.issuer_certificate = root_ca
808 * cert.add_extension(ef.create_extension("keyUsage","digitalSignature", true))
809 * cert.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false))
810 * cert.sign(root_key, OpenSSL::Digest::SHA256.new)
811 *
812 */
813 cX509Cert = rb_define_class_under(mX509, "Certificate", rb_cObject);
814
815 rb_define_alloc_func(cX509Cert, ossl_x509_alloc);
816 rb_define_method(cX509Cert, "initialize", ossl_x509_initialize, -1);
817 rb_define_method(cX509Cert, "initialize_copy", ossl_x509_copy, 1);
818
819 rb_define_method(cX509Cert, "to_der", ossl_x509_to_der, 0);
820 rb_define_method(cX509Cert, "to_pem", ossl_x509_to_pem, 0);
821 rb_define_alias(cX509Cert, "to_s", "to_pem");
822 rb_define_method(cX509Cert, "to_text", ossl_x509_to_text, 0);
823 rb_define_method(cX509Cert, "version", ossl_x509_get_version, 0);
824 rb_define_method(cX509Cert, "version=", ossl_x509_set_version, 1);
825 rb_define_method(cX509Cert, "signature_algorithm", ossl_x509_get_signature_algorithm, 0);
826 rb_define_method(cX509Cert, "serial", ossl_x509_get_serial, 0);
827 rb_define_method(cX509Cert, "serial=", ossl_x509_set_serial, 1);
828 rb_define_method(cX509Cert, "subject", ossl_x509_get_subject, 0);
829 rb_define_method(cX509Cert, "subject=", ossl_x509_set_subject, 1);
830 rb_define_method(cX509Cert, "issuer", ossl_x509_get_issuer, 0);
831 rb_define_method(cX509Cert, "issuer=", ossl_x509_set_issuer, 1);
832 rb_define_method(cX509Cert, "not_before", ossl_x509_get_not_before, 0);
833 rb_define_method(cX509Cert, "not_before=", ossl_x509_set_not_before, 1);
834 rb_define_method(cX509Cert, "not_after", ossl_x509_get_not_after, 0);
835 rb_define_method(cX509Cert, "not_after=", ossl_x509_set_not_after, 1);
836 rb_define_method(cX509Cert, "public_key", ossl_x509_get_public_key, 0);
837 rb_define_method(cX509Cert, "public_key=", ossl_x509_set_public_key, 1);
838 rb_define_method(cX509Cert, "sign", ossl_x509_sign, 2);
839 rb_define_method(cX509Cert, "verify", ossl_x509_verify, 1);
840 rb_define_method(cX509Cert, "check_private_key", ossl_x509_check_private_key, 1);
841 rb_define_method(cX509Cert, "extensions", ossl_x509_get_extensions, 0);
842 rb_define_method(cX509Cert, "extensions=", ossl_x509_set_extensions, 1);
843 rb_define_method(cX509Cert, "add_extension", ossl_x509_add_extension, 1);
844 rb_define_method(cX509Cert, "inspect", ossl_x509_inspect, 0);
845 rb_define_method(cX509Cert, "==", ossl_x509_eq, 1);
846 }
847