Ruby
2.0.0p247(2013-06-27revision41674)
|
00001 /* 00002 * $Id: ossl_x509cert.c 35190 2012-03-31 03:07:53Z 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 WrapX509(klass, obj, x509) do { \ 00014 if (!(x509)) { \ 00015 ossl_raise(rb_eRuntimeError, "CERT wasn't initialized!"); \ 00016 } \ 00017 (obj) = Data_Wrap_Struct((klass), 0, X509_free, (x509)); \ 00018 } while (0) 00019 #define GetX509(obj, x509) do { \ 00020 Data_Get_Struct((obj), X509, (x509)); \ 00021 if (!(x509)) { \ 00022 ossl_raise(rb_eRuntimeError, "CERT wasn't initialized!"); \ 00023 } \ 00024 } while (0) 00025 #define SafeGetX509(obj, x509) do { \ 00026 OSSL_Check_Kind((obj), cX509Cert); \ 00027 GetX509((obj), (x509)); \ 00028 } while (0) 00029 00030 /* 00031 * Classes 00032 */ 00033 VALUE cX509Cert; 00034 VALUE eX509CertError; 00035 00036 /* 00037 * Public 00038 */ 00039 VALUE 00040 ossl_x509_new(X509 *x509) 00041 { 00042 X509 *new; 00043 VALUE obj; 00044 00045 if (!x509) { 00046 new = X509_new(); 00047 } else { 00048 new = X509_dup(x509); 00049 } 00050 if (!new) { 00051 ossl_raise(eX509CertError, NULL); 00052 } 00053 WrapX509(cX509Cert, obj, new); 00054 00055 return obj; 00056 } 00057 00058 VALUE 00059 ossl_x509_new_from_file(VALUE filename) 00060 { 00061 X509 *x509; 00062 FILE *fp; 00063 VALUE obj; 00064 00065 SafeStringValue(filename); 00066 if (!(fp = fopen(RSTRING_PTR(filename), "r"))) { 00067 ossl_raise(eX509CertError, "%s", strerror(errno)); 00068 } 00069 rb_fd_fix_cloexec(fileno(fp)); 00070 x509 = PEM_read_X509(fp, NULL, NULL, NULL); 00071 /* 00072 * prepare for DER... 00073 #if !defined(OPENSSL_NO_FP_API) 00074 if (!x509) { 00075 (void)ERR_get_error(); 00076 rewind(fp); 00077 00078 x509 = d2i_X509_fp(fp, NULL); 00079 } 00080 #endif 00081 */ 00082 fclose(fp); 00083 if (!x509) { 00084 ossl_raise(eX509CertError, NULL); 00085 } 00086 WrapX509(cX509Cert, obj, x509); 00087 00088 return obj; 00089 } 00090 00091 X509 * 00092 GetX509CertPtr(VALUE obj) 00093 { 00094 X509 *x509; 00095 00096 SafeGetX509(obj, x509); 00097 00098 return x509; 00099 } 00100 00101 X509 * 00102 DupX509CertPtr(VALUE obj) 00103 { 00104 X509 *x509; 00105 00106 SafeGetX509(obj, x509); 00107 00108 CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509); 00109 00110 return x509; 00111 } 00112 00113 /* 00114 * Private 00115 */ 00116 static VALUE 00117 ossl_x509_alloc(VALUE klass) 00118 { 00119 X509 *x509; 00120 VALUE obj; 00121 00122 x509 = X509_new(); 00123 if (!x509) ossl_raise(eX509CertError, NULL); 00124 00125 WrapX509(klass, obj, x509); 00126 00127 return obj; 00128 } 00129 00130 /* 00131 * call-seq: 00132 * Certificate.new => cert 00133 * Certificate.new(string) => cert 00134 */ 00135 static VALUE 00136 ossl_x509_initialize(int argc, VALUE *argv, VALUE self) 00137 { 00138 BIO *in; 00139 X509 *x509, *x = DATA_PTR(self); 00140 VALUE arg; 00141 00142 if (rb_scan_args(argc, argv, "01", &arg) == 0) { 00143 /* create just empty X509Cert */ 00144 return self; 00145 } 00146 arg = ossl_to_der_if_possible(arg); 00147 in = ossl_obj2bio(arg); 00148 x509 = PEM_read_bio_X509(in, &x, NULL, NULL); 00149 DATA_PTR(self) = x; 00150 if (!x509) { 00151 OSSL_BIO_reset(in); 00152 x509 = d2i_X509_bio(in, &x); 00153 DATA_PTR(self) = x; 00154 } 00155 BIO_free(in); 00156 if (!x509) ossl_raise(eX509CertError, NULL); 00157 00158 return self; 00159 } 00160 00161 static VALUE 00162 ossl_x509_copy(VALUE self, VALUE other) 00163 { 00164 X509 *a, *b, *x509; 00165 00166 rb_check_frozen(self); 00167 if (self == other) return self; 00168 00169 GetX509(self, a); 00170 SafeGetX509(other, b); 00171 00172 x509 = X509_dup(b); 00173 if (!x509) ossl_raise(eX509CertError, NULL); 00174 00175 DATA_PTR(self) = x509; 00176 X509_free(a); 00177 00178 return self; 00179 } 00180 00181 /* 00182 * call-seq: 00183 * cert.to_der => string 00184 */ 00185 static VALUE 00186 ossl_x509_to_der(VALUE self) 00187 { 00188 X509 *x509; 00189 VALUE str; 00190 long len; 00191 unsigned char *p; 00192 00193 GetX509(self, x509); 00194 if ((len = i2d_X509(x509, NULL)) <= 0) 00195 ossl_raise(eX509CertError, NULL); 00196 str = rb_str_new(0, len); 00197 p = (unsigned char *)RSTRING_PTR(str); 00198 if (i2d_X509(x509, &p) <= 0) 00199 ossl_raise(eX509CertError, NULL); 00200 ossl_str_adjust(str, p); 00201 00202 return str; 00203 } 00204 00205 /* 00206 * call-seq: 00207 * cert.to_pem => string 00208 */ 00209 static VALUE 00210 ossl_x509_to_pem(VALUE self) 00211 { 00212 X509 *x509; 00213 BIO *out; 00214 VALUE str; 00215 00216 GetX509(self, x509); 00217 out = BIO_new(BIO_s_mem()); 00218 if (!out) ossl_raise(eX509CertError, NULL); 00219 00220 if (!PEM_write_bio_X509(out, x509)) { 00221 BIO_free(out); 00222 ossl_raise(eX509CertError, NULL); 00223 } 00224 str = ossl_membio2str(out); 00225 00226 return str; 00227 } 00228 00229 /* 00230 * call-seq: 00231 * cert.to_text => string 00232 */ 00233 static VALUE 00234 ossl_x509_to_text(VALUE self) 00235 { 00236 X509 *x509; 00237 BIO *out; 00238 VALUE str; 00239 00240 GetX509(self, x509); 00241 00242 out = BIO_new(BIO_s_mem()); 00243 if (!out) ossl_raise(eX509CertError, NULL); 00244 00245 if (!X509_print(out, x509)) { 00246 BIO_free(out); 00247 ossl_raise(eX509CertError, NULL); 00248 } 00249 str = ossl_membio2str(out); 00250 00251 return str; 00252 } 00253 00254 #if 0 00255 /* 00256 * Makes from X509 X509_REQuest 00257 */ 00258 static VALUE 00259 ossl_x509_to_req(VALUE self) 00260 { 00261 X509 *x509; 00262 X509_REQ *req; 00263 VALUE obj; 00264 00265 GetX509(self, x509); 00266 if (!(req = X509_to_X509_REQ(x509, NULL, EVP_md5()))) { 00267 ossl_raise(eX509CertError, NULL); 00268 } 00269 obj = ossl_x509req_new(req); 00270 X509_REQ_free(req); 00271 00272 return obj; 00273 } 00274 #endif 00275 00276 /* 00277 * call-seq: 00278 * cert.version => integer 00279 */ 00280 static VALUE 00281 ossl_x509_get_version(VALUE self) 00282 { 00283 X509 *x509; 00284 00285 GetX509(self, x509); 00286 00287 return LONG2NUM(X509_get_version(x509)); 00288 } 00289 00290 /* 00291 * call-seq: 00292 * cert.version = integer => integer 00293 */ 00294 static VALUE 00295 ossl_x509_set_version(VALUE self, VALUE version) 00296 { 00297 X509 *x509; 00298 long ver; 00299 00300 if ((ver = NUM2LONG(version)) < 0) { 00301 ossl_raise(eX509CertError, "version must be >= 0!"); 00302 } 00303 GetX509(self, x509); 00304 if (!X509_set_version(x509, ver)) { 00305 ossl_raise(eX509CertError, NULL); 00306 } 00307 00308 return version; 00309 } 00310 00311 /* 00312 * call-seq: 00313 * cert.serial => integer 00314 */ 00315 static VALUE 00316 ossl_x509_get_serial(VALUE self) 00317 { 00318 X509 *x509; 00319 00320 GetX509(self, x509); 00321 00322 return asn1integer_to_num(X509_get_serialNumber(x509)); 00323 } 00324 00325 /* 00326 * call-seq: 00327 * cert.serial = integer => integer 00328 */ 00329 static VALUE 00330 ossl_x509_set_serial(VALUE self, VALUE num) 00331 { 00332 X509 *x509; 00333 00334 GetX509(self, x509); 00335 00336 x509->cert_info->serialNumber = 00337 num_to_asn1integer(num, X509_get_serialNumber(x509)); 00338 00339 return num; 00340 } 00341 00342 /* 00343 * call-seq: 00344 * cert.signature_algorithm => string 00345 */ 00346 static VALUE 00347 ossl_x509_get_signature_algorithm(VALUE self) 00348 { 00349 X509 *x509; 00350 BIO *out; 00351 VALUE str; 00352 00353 GetX509(self, x509); 00354 out = BIO_new(BIO_s_mem()); 00355 if (!out) ossl_raise(eX509CertError, NULL); 00356 00357 if (!i2a_ASN1_OBJECT(out, x509->cert_info->signature->algorithm)) { 00358 BIO_free(out); 00359 ossl_raise(eX509CertError, NULL); 00360 } 00361 str = ossl_membio2str(out); 00362 00363 return str; 00364 } 00365 00366 /* 00367 * call-seq: 00368 * cert.subject => name 00369 */ 00370 static VALUE 00371 ossl_x509_get_subject(VALUE self) 00372 { 00373 X509 *x509; 00374 X509_NAME *name; 00375 00376 GetX509(self, x509); 00377 if (!(name = X509_get_subject_name(x509))) { /* NO DUP - don't free! */ 00378 ossl_raise(eX509CertError, NULL); 00379 } 00380 00381 return ossl_x509name_new(name); 00382 } 00383 00384 /* 00385 * call-seq: 00386 * cert.subject = name => name 00387 */ 00388 static VALUE 00389 ossl_x509_set_subject(VALUE self, VALUE subject) 00390 { 00391 X509 *x509; 00392 00393 GetX509(self, x509); 00394 if (!X509_set_subject_name(x509, GetX509NamePtr(subject))) { /* DUPs name */ 00395 ossl_raise(eX509CertError, NULL); 00396 } 00397 00398 return subject; 00399 } 00400 00401 /* 00402 * call-seq: 00403 * cert.issuer => name 00404 */ 00405 static VALUE 00406 ossl_x509_get_issuer(VALUE self) 00407 { 00408 X509 *x509; 00409 X509_NAME *name; 00410 00411 GetX509(self, x509); 00412 if(!(name = X509_get_issuer_name(x509))) { /* NO DUP - don't free! */ 00413 ossl_raise(eX509CertError, NULL); 00414 } 00415 00416 return ossl_x509name_new(name); 00417 } 00418 00419 /* 00420 * call-seq: 00421 * cert.issuer = name => name 00422 */ 00423 static VALUE 00424 ossl_x509_set_issuer(VALUE self, VALUE issuer) 00425 { 00426 X509 *x509; 00427 00428 GetX509(self, x509); 00429 if (!X509_set_issuer_name(x509, GetX509NamePtr(issuer))) { /* DUPs name */ 00430 ossl_raise(eX509CertError, NULL); 00431 } 00432 00433 return issuer; 00434 } 00435 00436 /* 00437 * call-seq: 00438 * cert.not_before => time 00439 */ 00440 static VALUE 00441 ossl_x509_get_not_before(VALUE self) 00442 { 00443 X509 *x509; 00444 ASN1_UTCTIME *asn1time; 00445 00446 GetX509(self, x509); 00447 if (!(asn1time = X509_get_notBefore(x509))) { /* NO DUP - don't free! */ 00448 ossl_raise(eX509CertError, NULL); 00449 } 00450 00451 return asn1time_to_time(asn1time); 00452 } 00453 00454 /* 00455 * call-seq: 00456 * cert.not_before = time => time 00457 */ 00458 static VALUE 00459 ossl_x509_set_not_before(VALUE self, VALUE time) 00460 { 00461 X509 *x509; 00462 time_t sec; 00463 00464 sec = time_to_time_t(time); 00465 GetX509(self, x509); 00466 if (!X509_time_adj(X509_get_notBefore(x509), 0, &sec)) { 00467 ossl_raise(eX509CertError, NULL); 00468 } 00469 00470 return time; 00471 } 00472 00473 /* 00474 * call-seq: 00475 * cert.not_after => time 00476 */ 00477 static VALUE 00478 ossl_x509_get_not_after(VALUE self) 00479 { 00480 X509 *x509; 00481 ASN1_TIME *asn1time; 00482 00483 GetX509(self, x509); 00484 if (!(asn1time = X509_get_notAfter(x509))) { /* NO DUP - don't free! */ 00485 ossl_raise(eX509CertError, NULL); 00486 } 00487 00488 return asn1time_to_time(asn1time); 00489 } 00490 00491 /* 00492 * call-seq: 00493 * cert.not_after = time => time 00494 */ 00495 static VALUE 00496 ossl_x509_set_not_after(VALUE self, VALUE time) 00497 { 00498 X509 *x509; 00499 time_t sec; 00500 00501 sec = time_to_time_t(time); 00502 GetX509(self, x509); 00503 if (!X509_time_adj(X509_get_notAfter(x509), 0, &sec)) { 00504 ossl_raise(eX509CertError, NULL); 00505 } 00506 00507 return time; 00508 } 00509 00510 /* 00511 * call-seq: 00512 * cert.public_key => key 00513 */ 00514 static VALUE 00515 ossl_x509_get_public_key(VALUE self) 00516 { 00517 X509 *x509; 00518 EVP_PKEY *pkey; 00519 00520 GetX509(self, x509); 00521 if (!(pkey = X509_get_pubkey(x509))) { /* adds an reference */ 00522 ossl_raise(eX509CertError, NULL); 00523 } 00524 00525 return ossl_pkey_new(pkey); /* NO DUP - OK */ 00526 } 00527 00528 /* 00529 * call-seq: 00530 * cert.public_key = key => key 00531 */ 00532 static VALUE 00533 ossl_x509_set_public_key(VALUE self, VALUE key) 00534 { 00535 X509 *x509; 00536 00537 GetX509(self, x509); 00538 if (!X509_set_pubkey(x509, GetPKeyPtr(key))) { /* DUPs pkey */ 00539 ossl_raise(eX509CertError, NULL); 00540 } 00541 00542 return key; 00543 } 00544 00545 /* 00546 * call-seq: 00547 * cert.sign(key, digest) => self 00548 */ 00549 static VALUE 00550 ossl_x509_sign(VALUE self, VALUE key, VALUE digest) 00551 { 00552 X509 *x509; 00553 EVP_PKEY *pkey; 00554 const EVP_MD *md; 00555 00556 pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */ 00557 md = GetDigestPtr(digest); 00558 GetX509(self, x509); 00559 if (!X509_sign(x509, pkey, md)) { 00560 ossl_raise(eX509CertError, NULL); 00561 } 00562 00563 return self; 00564 } 00565 00566 /* 00567 * call-seq: 00568 * cert.verify(key) => true | false 00569 * 00570 * Checks that cert signature is made with PRIVversion of this PUBLIC 'key' 00571 */ 00572 static VALUE 00573 ossl_x509_verify(VALUE self, VALUE key) 00574 { 00575 X509 *x509; 00576 EVP_PKEY *pkey; 00577 int i; 00578 00579 pkey = GetPKeyPtr(key); /* NO NEED TO DUP */ 00580 GetX509(self, x509); 00581 if ((i = X509_verify(x509, pkey)) < 0) { 00582 ossl_raise(eX509CertError, NULL); 00583 } 00584 if (i > 0) { 00585 return Qtrue; 00586 } 00587 00588 return Qfalse; 00589 } 00590 00591 /* 00592 * call-seq: 00593 * cert.check_private_key(key) 00594 * 00595 * Checks if 'key' is PRIV key for this cert 00596 */ 00597 static VALUE 00598 ossl_x509_check_private_key(VALUE self, VALUE key) 00599 { 00600 X509 *x509; 00601 EVP_PKEY *pkey; 00602 00603 /* not needed private key, but should be */ 00604 pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */ 00605 GetX509(self, x509); 00606 if (!X509_check_private_key(x509, pkey)) { 00607 OSSL_Warning("Check private key:%s", OSSL_ErrMsg()); 00608 return Qfalse; 00609 } 00610 00611 return Qtrue; 00612 } 00613 00614 /* 00615 * call-seq: 00616 * cert.extensions => [extension...] 00617 */ 00618 static VALUE 00619 ossl_x509_get_extensions(VALUE self) 00620 { 00621 X509 *x509; 00622 int count, i; 00623 X509_EXTENSION *ext; 00624 VALUE ary; 00625 00626 GetX509(self, x509); 00627 count = X509_get_ext_count(x509); 00628 if (count < 0) { 00629 return rb_ary_new(); 00630 } 00631 ary = rb_ary_new2(count); 00632 for (i=0; i<count; i++) { 00633 ext = X509_get_ext(x509, i); /* NO DUP - don't free! */ 00634 rb_ary_push(ary, ossl_x509ext_new(ext)); 00635 } 00636 00637 return ary; 00638 } 00639 00640 /* 00641 * call-seq: 00642 * cert.extensions = [ext...] => [ext...] 00643 */ 00644 static VALUE 00645 ossl_x509_set_extensions(VALUE self, VALUE ary) 00646 { 00647 X509 *x509; 00648 X509_EXTENSION *ext; 00649 int i; 00650 00651 Check_Type(ary, T_ARRAY); 00652 /* All ary's members should be X509Extension */ 00653 for (i=0; i<RARRAY_LEN(ary); i++) { 00654 OSSL_Check_Kind(RARRAY_PTR(ary)[i], cX509Ext); 00655 } 00656 GetX509(self, x509); 00657 sk_X509_EXTENSION_pop_free(x509->cert_info->extensions, X509_EXTENSION_free); 00658 x509->cert_info->extensions = NULL; 00659 for (i=0; i<RARRAY_LEN(ary); i++) { 00660 ext = DupX509ExtPtr(RARRAY_PTR(ary)[i]); 00661 00662 if (!X509_add_ext(x509, ext, -1)) { /* DUPs ext - FREE it */ 00663 X509_EXTENSION_free(ext); 00664 ossl_raise(eX509CertError, NULL); 00665 } 00666 X509_EXTENSION_free(ext); 00667 } 00668 00669 return ary; 00670 } 00671 00672 /* 00673 * call-seq: 00674 * cert.add_extension(extension) => extension 00675 */ 00676 static VALUE 00677 ossl_x509_add_extension(VALUE self, VALUE extension) 00678 { 00679 X509 *x509; 00680 X509_EXTENSION *ext; 00681 00682 GetX509(self, x509); 00683 ext = DupX509ExtPtr(extension); 00684 if (!X509_add_ext(x509, ext, -1)) { /* DUPs ext - FREE it */ 00685 X509_EXTENSION_free(ext); 00686 ossl_raise(eX509CertError, NULL); 00687 } 00688 X509_EXTENSION_free(ext); 00689 00690 return extension; 00691 } 00692 00693 static VALUE 00694 ossl_x509_inspect(VALUE self) 00695 { 00696 VALUE str; 00697 const char *cname = rb_class2name(rb_obj_class(self)); 00698 00699 str = rb_str_new2("#<"); 00700 rb_str_cat2(str, cname); 00701 rb_str_cat2(str, " "); 00702 00703 rb_str_cat2(str, "subject="); 00704 rb_str_append(str, rb_inspect(ossl_x509_get_subject(self))); 00705 rb_str_cat2(str, ", "); 00706 00707 rb_str_cat2(str, "issuer="); 00708 rb_str_append(str, rb_inspect(ossl_x509_get_issuer(self))); 00709 rb_str_cat2(str, ", "); 00710 00711 rb_str_cat2(str, "serial="); 00712 rb_str_append(str, rb_inspect(ossl_x509_get_serial(self))); 00713 rb_str_cat2(str, ", "); 00714 00715 rb_str_cat2(str, "not_before="); 00716 rb_str_append(str, rb_inspect(ossl_x509_get_not_before(self))); 00717 rb_str_cat2(str, ", "); 00718 00719 rb_str_cat2(str, "not_after="); 00720 rb_str_append(str, rb_inspect(ossl_x509_get_not_after(self))); 00721 00722 str = rb_str_cat2(str, ">"); 00723 00724 return str; 00725 } 00726 00727 /* 00728 * INIT 00729 */ 00730 void 00731 Init_ossl_x509cert() 00732 { 00733 00734 #if 0 00735 mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */ 00736 mX509 = rb_define_module_under(mOSSL, "X509"); 00737 #endif 00738 00739 eX509CertError = rb_define_class_under(mX509, "CertificateError", eOSSLError); 00740 00741 /* Document-class: OpenSSL::X509::Certificate 00742 * 00743 * Implementation of an X.509 certificate as specified in RFC 5280. 00744 * Provides access to a certificate's attributes and allows certificates 00745 * to be read from a string, but also supports the creation of new 00746 * certificates from scratch. 00747 * 00748 * === Reading a certificate from a file 00749 * 00750 * Certificate is capable of handling DER-encoded certificates and 00751 * certificates encoded in OpenSSL's PEM format. 00752 * 00753 * raw = File.read "cert.cer" # DER- or PEM-encoded 00754 * certificate = OpenSSL::X509::Certificate.new raw 00755 * 00756 * === Saving a certificate to a file 00757 * 00758 * A certificate may be encoded in DER format 00759 * 00760 * cert = ... 00761 * File.open("cert.cer", "wb") { |f| f.print cert.to_der } 00762 * 00763 * or in PEM format 00764 * 00765 * cert = ... 00766 * File.open("cert.pem", "wb") { |f| f.print cert.to_pem } 00767 * 00768 * X.509 certificates are associated with a private/public key pair, 00769 * typically a RSA, DSA or ECC key (see also OpenSSL::PKey::RSA, 00770 * OpenSSL::PKey::DSA and OpenSSL::PKey::EC), the public key itself is 00771 * stored within the certificate and can be accessed in form of an 00772 * OpenSSL::PKey. Certificates are typically used to be able to associate 00773 * some form of identity with a key pair, for example web servers serving 00774 * pages over HTTPs use certificates to authenticate themselves to the user. 00775 * 00776 * The public key infrastructure (PKI) model relies on trusted certificate 00777 * authorities ("root CAs") that issue these certificates, so that end 00778 * users need to base their trust just on a selected few authorities 00779 * that themselves again vouch for subordinate CAs issuing their 00780 * certificates to end users. 00781 * 00782 * The OpenSSL::X509 module provides the tools to set up an independent 00783 * PKI, similar to scenarios where the 'openssl' command line tool is 00784 * used for issuing certificates in a private PKI. 00785 * 00786 * === Creating a root CA certificate and an end-entity certificate 00787 * 00788 * First, we need to create a "self-signed" root certificate. To do so, 00789 * we need to generate a key first. Please note that the choice of "1" 00790 * as a serial number is considered a security flaw for real certificates. 00791 * Secure choices are integers in the two-digit byte range and ideally 00792 * not sequential but secure random numbers, steps omitted here to keep 00793 * the example concise. 00794 * 00795 * root_key = OpenSSL::PKey::RSA.new 2048 # the CA's public/private key 00796 * root_ca = OpenSSL::X509::Certificate.new 00797 * root_ca.version = 2 # cf. RFC 5280 - to make it a "v3" certificate 00798 * root_ca.serial = 1 00799 * root_ca.subject = OpenSSL::X509::Name.parse "/DC=org/DC=ruby-lang/CN=Ruby CA" 00800 * root_ca.issuer = root_ca.subject # root CA's are "self-signed" 00801 * root_ca.public_key = root_key.public_key 00802 * root_ca.not_before = Time.now 00803 * root_ca.not_after = root_ca.not_before + 2 * 365 * 24 * 60 * 60 # 2 years validity 00804 * ef = OpenSSL::X509::ExtensionFactory.new 00805 * ef.subject_certificate = root_ca 00806 * ef.issuer_certificate = root_ca 00807 * root_ca.add_extension(ef.create_extension("basicConstraints","CA:TRUE",true)) 00808 * root_ca.add_extension(ef.create_extension("keyUsage","keyCertSign, cRLSign", true)) 00809 * root_ca.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false)) 00810 * root_ca.add_extension(ef.create_extension("authorityKeyIdentifier","keyid:always",false)) 00811 * root_ca.sign(root_key, OpenSSL::Digest::SHA256.new) 00812 * 00813 * The next step is to create the end-entity certificate using the root CA 00814 * certificate. 00815 * 00816 * key = OpenSSL::PKey::RSA.new 2048 00817 * cert = OpenSSL::X509::Certificate.new 00818 * cert.version = 2 00819 * cert.serial = 2 00820 * cert.subject = OpenSSL::X509::Name.parse "/DC=org/DC=ruby-lang/CN=Ruby certificate" 00821 * cert.issuer = root_ca.subject # root CA is the issuer 00822 * cert.public_key = key.public_key 00823 * cert.not_before = Time.now 00824 * cert.not_after = cert.not_before + 1 * 365 * 24 * 60 * 60 # 1 years validity 00825 * ef = OpenSSL::X509::ExtensionFactory.new 00826 * ef.subject_certificate = cert 00827 * ef.issuer_certificate = root_ca 00828 * cert.add_extension(ef.create_extension("keyUsage","digitalSignature", true)) 00829 * cert.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false)) 00830 * cert.sign(root_key, OpenSSL::Digest::SHA256.new) 00831 * 00832 */ 00833 cX509Cert = rb_define_class_under(mX509, "Certificate", rb_cObject); 00834 00835 rb_define_alloc_func(cX509Cert, ossl_x509_alloc); 00836 rb_define_method(cX509Cert, "initialize", ossl_x509_initialize, -1); 00837 rb_define_copy_func(cX509Cert, ossl_x509_copy); 00838 00839 rb_define_method(cX509Cert, "to_der", ossl_x509_to_der, 0); 00840 rb_define_method(cX509Cert, "to_pem", ossl_x509_to_pem, 0); 00841 rb_define_alias(cX509Cert, "to_s", "to_pem"); 00842 rb_define_method(cX509Cert, "to_text", ossl_x509_to_text, 0); 00843 rb_define_method(cX509Cert, "version", ossl_x509_get_version, 0); 00844 rb_define_method(cX509Cert, "version=", ossl_x509_set_version, 1); 00845 rb_define_method(cX509Cert, "signature_algorithm", ossl_x509_get_signature_algorithm, 0); 00846 rb_define_method(cX509Cert, "serial", ossl_x509_get_serial, 0); 00847 rb_define_method(cX509Cert, "serial=", ossl_x509_set_serial, 1); 00848 rb_define_method(cX509Cert, "subject", ossl_x509_get_subject, 0); 00849 rb_define_method(cX509Cert, "subject=", ossl_x509_set_subject, 1); 00850 rb_define_method(cX509Cert, "issuer", ossl_x509_get_issuer, 0); 00851 rb_define_method(cX509Cert, "issuer=", ossl_x509_set_issuer, 1); 00852 rb_define_method(cX509Cert, "not_before", ossl_x509_get_not_before, 0); 00853 rb_define_method(cX509Cert, "not_before=", ossl_x509_set_not_before, 1); 00854 rb_define_method(cX509Cert, "not_after", ossl_x509_get_not_after, 0); 00855 rb_define_method(cX509Cert, "not_after=", ossl_x509_set_not_after, 1); 00856 rb_define_method(cX509Cert, "public_key", ossl_x509_get_public_key, 0); 00857 rb_define_method(cX509Cert, "public_key=", ossl_x509_set_public_key, 1); 00858 rb_define_method(cX509Cert, "sign", ossl_x509_sign, 2); 00859 rb_define_method(cX509Cert, "verify", ossl_x509_verify, 1); 00860 rb_define_method(cX509Cert, "check_private_key", ossl_x509_check_private_key, 1); 00861 rb_define_method(cX509Cert, "extensions", ossl_x509_get_extensions, 0); 00862 rb_define_method(cX509Cert, "extensions=", ossl_x509_set_extensions, 1); 00863 rb_define_method(cX509Cert, "add_extension", ossl_x509_add_extension, 1); 00864 rb_define_method(cX509Cert, "inspect", ossl_x509_inspect, 0); 00865 } 00866 00867