Dynamically create SSL certs/keys with common CA

1.2k views Asked by At

I'm having some trouble navigating the confusing world of Ruby OpenSSL libraries.

The desired end result would be dynamically creating SSL server certs and keys for use with WEBrick::HTTPProxyServer, each with a CN corresponding to the requested domain and all sharing the same CA.

The reason for this is to allow for an HTTP proxy to intercept and monitor HTTPS traffic of websites that have the HSTS header enabled, by first loading the CACert into the browser, thus making my self-signed certificates look legit for each given site.

If anyone's got experience with this sort of thing code examples would be greatly appreciated.

Thanks in advance.

PS. Nothing sinister going on here, just improving a feature of a penetration testing software.

1

There are 1 answers

2
Tasos Laskos On

Figured it out. :)

ca     = OpenSSL::X509::Certificate.new( File.read( INTERCEPTOR_CA_CERTIFICATE ) )
ca_key = OpenSSL::PKey::RSA.new( File.read( INTERCEPTOR_CA_KEY ) )

keypair = OpenSSL::PKey::RSA.new( 4096 )

req            = OpenSSL::X509::Request.new
req.version    = 0
req.subject    = OpenSSL::X509::Name.parse(
    "CN=www.origin-server.com/O=Arachni/OU=Proxy/L=Athens/ST=Attika/C=GR"
)
req.public_key = keypair.public_key
req.sign( keypair, OpenSSL::Digest::SHA1.new )

cert            = OpenSSL::X509::Certificate.new
cert.version    = 2
cert.serial     = rand( 999999 )
cert.not_before = Time.new
cert.not_after  = cert.not_before + (60 * 60 * 24 * 365)
cert.public_key = req.public_key
cert.subject    = req.subject
cert.issuer     = ca.subject

ef = OpenSSL::X509::ExtensionFactory.new
ef.subject_certificate = cert
ef.issuer_certificate  = ca

cert.extensions = [
    ef.create_extension( 'basicConstraints', 'CA:FALSE', true ),
    ef.create_extension( 'extendedKeyUsage', 'serverAuth', false ),
    ef.create_extension( 'subjectKeyIdentifier', 'hash' ),
    ef.create_extension( 'authorityKeyIdentifier', 'keyid:always,issuer:always' ),
    ef.create_extension( 'keyUsage',
        %w(nonRepudiation digitalSignature
        keyEncipherment dataEncipherment).join(","),
        true
    )
]
cert.sign( ca_key, OpenSSL::Digest::SHA1.new )

Helpful resources:

  1. http://users.nccs.gov/~fwang2/ruby/ruby_ssl.html
  2. http://acidx.net/wordpress/2012/09/creating-a-certification-authority-and-a-server-certificate-on-ubuntu/