diff options
Diffstat (limited to 'ext/openssl/ossl_x509cert.c')
-rw-r--r-- | ext/openssl/ossl_x509cert.c | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/ext/openssl/ossl_x509cert.c b/ext/openssl/ossl_x509cert.c index 3fb19b465f..a820afb5c4 100644 --- a/ext/openssl/ossl_x509cert.c +++ b/ext/openssl/ossl_x509cert.c @@ -729,8 +729,106 @@ ossl_x509_inspect(VALUE self) void Init_ossl_x509cert() { + +#if 0 + mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */ + mX509 = rb_define_module_under(mOSSL, "X509"); +#endif + eX509CertError = rb_define_class_under(mX509, "CertificateError", eOSSLError); + /* Document-class: OpenSSL::X509::Certificate + * + * Implementation of an X.509 certificate as specified in RFC 5280. + * Provides access to a certificate's attributes and allows certificates + * to be read from a string, but also supports the creation of new + * certificates from scratch. + * + * === Reading a certificate from a file + * + * Certificate is capable of handling DER-encoded certificates and + * certificates encoded in OpenSSL's PEM format. + * + * raw = File.read "cert.cer" # DER- or PEM-encoded + * certificate = OpenSSL::X509::Certificate.new raw + * + * === Saving a certificate to a file + * + * A certificate may be encoded in DER format + * + * cert = ... + * File.open("cert.cer", "wb") { |f| f.print cert.to_der } + * + * or in PEM format + * + * cert = ... + * File.open("cert.pem", "wb") { |f| f.print cert.to_pem } + * + * X.509 certificates are associated with a private/public key pair, + * typically a RSA, DSA or ECC key (see also OpenSSL::PKey::RSA, + * OpenSSL::PKey::DSA and OpenSSL::PKey::EC), the public key itself is + * stored within the certificate and can be accessed in form of an + * OpenSSL::PKey. Certificates are typically used to be able to associate + * some form of identity with a key pair, for example web servers serving + * pages over HTTPs use certificates to authenticate themselves to the user. + * + * The public key infrastructure (PKI) model relies on trusted certificate + * authorities ("root CAs") that issue these certificates, so that end + * users need to base their trust just on a selected few authorities + * that themselves again vouch for subordinate CAs issuing their + * certificates to end users. + * + * The OpenSSL::X509 module provides the tools to set up an independent + * PKI, similar to scenarios where the 'openssl' command line tool is + * used for issuing certificates in a private PKI. + * + * === Creating a root CA certificate and an end-entity certificate + * + * First, we need to create a "self-signed" root certificate. To do so, + * we need to generate a key first. Please note that the choice of "1" + * as a serial number is considered a security flaw for real certificates. + * Secure choices are integers in the two-digit byte range and ideally + * not sequential but secure random numbers, steps omitted here to keep + * the example concise. + * + * root_key = OpenSSL::PKey::RSA.new 2048 # the CA's public/private key + * root_ca = OpenSSL::X509::Certificate.new + * root_ca.version = 2 # cf. RFC 5280 - to make it a "v3" certificate + * root_ca.serial = 1 + * root_ca.subject = OpenSSL::X509::Name.parse "/DC=org/DC=ruby-lang/CN=Ruby CA" + * root_ca.issuer = root_ca.subject # root CA's are "self-signed" + * root_ca.public_key = root_key.public_key + * root_ca.not_before = Time.now + * root_ca.not_after = root_ca.not_before + 2 * 365 * 24 * 60 * 60 # 2 years validity + * ef = OpenSSL::X509::ExtensionFactory.new + * ef.subject_certificate = root_ca + * ef.issuer_certificate = root_ca + * root_ca.add_extension(ef.create_extension("basicConstraints","CA:TRUE",true)) + * root_ca.add_extension(ef.create_extension("keyUsage","keyCertSign, cRLSign", true)) + * root_ca.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false)) + * root_ca.add_extension(ef.create_extension("authorityKeyIdentifier","keyid:always",false)) + * root_ca.sign(root_key, OpenSSL::Digest::SHA256.new) + * + * The next step is to create the end-entity certificate using the root CA + * certificate. + * + * key = OpenSSL::PKey::RSA.new 2048 + * cert = OpenSSL::X509::Certificate.new + * cert.version = 2 + * cert.serial = 2 + * cert.subject = OpenSSL::X509::Name.parse "/DC=org/DC=ruby-lang/CN=Ruby certificate" + * cert.issuer = root_ca.subject # root CA is the issuer + * cert.public_key = key.public_key + * cert.not_before = Time.now + * cert.not_after = cert.not_before + 1 * 365 * 24 * 60 * 60 # 1 years validity + * ef = OpenSSL::X509::ExtensionFactory.new + * ef.subject_certificate = cert + * ef.issuer_certificate = root_ca + * cert.add_extension(ef.create_extension("keyUsage","digitalSignature", true)) + * cert.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false)) + * cert.sign(root_key, OpenSSL::Digest::SHA256.new) + * + */ cX509Cert = rb_define_class_under(mX509, "Certificate", rb_cObject); rb_define_alloc_func(cX509Cert, ossl_x509_alloc); |