13
13
#define WrapX509(klass, obj, x509) do { \
15
15
ossl_raise(rb_eRuntimeError, "CERT wasn't initialized!"); \
17
obj = Data_Wrap_Struct(klass, 0, X509_free, x509); \
17
(obj) = Data_Wrap_Struct((klass), 0, X509_free, (x509)); \
19
19
#define GetX509(obj, x509) do { \
20
Data_Get_Struct(obj, X509, x509); \
20
Data_Get_Struct((obj), X509, (x509)); \
22
22
ossl_raise(rb_eRuntimeError, "CERT wasn't initialized!"); \
25
25
#define SafeGetX509(obj, x509) do { \
26
OSSL_Check_Kind(obj, cX509Cert); \
26
OSSL_Check_Kind((obj), cX509Cert); \
27
GetX509((obj), (x509)); \
729
730
Init_ossl_x509cert()
734
mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */
735
mX509 = rb_define_module_under(mOSSL, "X509");
738
eX509CertError = rb_define_class_under(mX509, "CertificateError", eOSSLError);
740
/* Document-class: OpenSSL::X509::Certificate
742
* Implementation of an X.509 certificate as specified in RFC 5280.
743
* Provides access to a certificate's attributes and allows certificates
744
* to be read from a string, but also supports the creation of new
745
* certificates from scratch.
747
* === Reading a certificate from a file
749
* Certificate is capable of handling DER-encoded certificates and
750
* certificates encoded in OpenSSL's PEM format.
752
* raw = File.read "cert.cer" # DER- or PEM-encoded
753
* certificate = OpenSSL::X509::Certificate.new raw
755
* === Saving a certificate to a file
757
* A certificate may be encoded in DER format
760
* File.open("cert.cer", "wb") { |f| f.print cert.to_der }
765
* File.open("cert.pem", "wb") { |f| f.print cert.to_pem }
767
* X.509 certificates are associated with a private/public key pair,
768
* typically a RSA, DSA or ECC key (see also OpenSSL::PKey::RSA,
769
* OpenSSL::PKey::DSA and OpenSSL::PKey::EC), the public key itself is
770
* stored within the certificate and can be accessed in form of an
771
* OpenSSL::PKey. Certificates are typically used to be able to associate
772
* some form of identity with a key pair, for example web servers serving
773
* pages over HTTPs use certificates to authenticate themselves to the user.
775
* The public key infrastructure (PKI) model relies on trusted certificate
776
* authorities ("root CAs") that issue these certificates, so that end
777
* users need to base their trust just on a selected few authorities
778
* that themselves again vouch for subordinate CAs issuing their
779
* certificates to end users.
781
* The OpenSSL::X509 module provides the tools to set up an independent
782
* PKI, similar to scenarios where the 'openssl' command line tool is
783
* used for issuing certificates in a private PKI.
785
* === Creating a root CA certificate and an end-entity certificate
787
* First, we need to create a "self-signed" root certificate. To do so,
788
* we need to generate a key first. Please note that the choice of "1"
789
* as a serial number is considered a security flaw for real certificates.
790
* Secure choices are integers in the two-digit byte range and ideally
791
* not sequential but secure random numbers, steps omitted here to keep
792
* the example concise.
794
* root_key = OpenSSL::PKey::RSA.new 2048 # the CA's public/private key
795
* root_ca = OpenSSL::X509::Certificate.new
796
* root_ca.version = 2 # cf. RFC 5280 - to make it a "v3" certificate
798
* root_ca.subject = OpenSSL::X509::Name.parse "/DC=org/DC=ruby-lang/CN=Ruby CA"
799
* root_ca.issuer = root_ca.subject # root CA's are "self-signed"
800
* root_ca.public_key = root_key.public_key
801
* root_ca.not_before = Time.now
802
* root_ca.not_after = root_ca.not_before + 2 * 365 * 24 * 60 * 60 # 2 years validity
803
* ef = OpenSSL::X509::ExtensionFactory.new
804
* ef.subject_certificate = root_ca
805
* ef.issuer_certificate = root_ca
806
* root_ca.add_extension(ef.create_extension("basicConstraints","CA:TRUE",true))
807
* root_ca.add_extension(ef.create_extension("keyUsage","keyCertSign, cRLSign", true))
808
* root_ca.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false))
809
* root_ca.add_extension(ef.create_extension("authorityKeyIdentifier","keyid:always",false))
810
* root_ca.sign(root_key, OpenSSL::Digest::SHA256.new)
812
* The next step is to create the end-entity certificate using the root CA
815
* key = OpenSSL::PKey::RSA.new 2048
816
* cert = OpenSSL::X509::Certificate.new
819
* cert.subject = OpenSSL::X509::Name.parse "/DC=org/DC=ruby-lang/CN=Ruby certificate"
820
* cert.issuer = root_ca.subject # root CA is the issuer
821
* cert.public_key = key.public_key
822
* cert.not_before = Time.now
823
* cert.not_after = cert.not_before + 1 * 365 * 24 * 60 * 60 # 1 years validity
824
* ef = OpenSSL::X509::ExtensionFactory.new
825
* ef.subject_certificate = cert
826
* ef.issuer_certificate = root_ca
827
* cert.add_extension(ef.create_extension("keyUsage","digitalSignature", true))
828
* cert.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false))
829
* cert.sign(root_key, OpenSSL::Digest::SHA256.new)
731
833
eX509CertError = rb_define_class_under(mX509, "CertificateError", eOSSLError);
733
835
cX509Cert = rb_define_class_under(mX509, "Certificate", rb_cObject);