class MiniCa::Certificate
Constants
- DIGEST
Attributes
ca[R]
issuer[R]
private_key[R]
x509[R]
Public Class Methods
new( cn, sans: nil, issuer: nil, ca: false, serial: nil, not_before: nil, not_after: nil, country: nil, state: nil, location: nil, organization: nil, private_key: nil )
click to toggle source
rubocop:disable ParameterLists
# File lib/mini_ca/certificate.rb, line 8 def initialize( cn, sans: nil, issuer: nil, ca: false, serial: nil, not_before: nil, not_after: nil, country: nil, state: nil, location: nil, organization: nil, private_key: nil ) @private_key = private_key || OpenSSL::PKey::RSA.new(2048) @x509 = OpenSSL::X509::Certificate.new @issuer = issuer @ca = ca @counter = 0 x509.version = 0x2 x509.serial = serial || 0 x509.public_key = public_key x509.subject = OpenSSL::X509::Name.new [ ['CN', cn], ['C', country], ['ST', state], ['L', location], ['O', organization] ].each do |prop, value| next if value.nil? x509.subject = x509.subject.add_entry(prop, value) end x509.issuer = issuer ? issuer.x509.subject : x509.subject if issuer not_before ||= issuer.x509.not_before not_after ||= issuer.x509.not_after if issuer.x509.not_before > not_before raise Error, 'Certificate cannot become valid before issuer' end if issuer.x509.not_after < not_after raise Error, 'Certificate cannot expire after issuer' end else not_before ||= Time.now - 3600 * 24 not_after ||= Time.now + 3600 + 24 end x509.not_before = not_before x509.not_after = not_after ef = OpenSSL::X509::ExtensionFactory.new ef.subject_certificate = x509 sans = (sans || []) + ["DNS:#{cn}"] exts = if ca [ ef.create_extension('basicConstraints', 'CA:TRUE', true) ] else [ ef.create_extension('basicConstraints', 'CA:FALSE', true), ef.create_extension('subjectAltName', sans.join(','), false) ] end exts.each { |e| x509.add_extension(e) } signing_key = issuer ? issuer.private_key : send(:private_key) x509.sign signing_key, DIGEST.new end
Public Instance Methods
bundle()
click to toggle source
# File lib/mini_ca/certificate.rb, line 110 def bundle [self] + chain end
bundle_pem()
click to toggle source
# File lib/mini_ca/certificate.rb, line 122 def bundle_pem bundle.map(&:x509).map(&:to_pem).join('') end
chain()
click to toggle source
# File lib/mini_ca/certificate.rb, line 101 def chain bits = [] this_cert = self until (this_cert = this_cert.issuer).nil? bits << this_cert end bits[0...-1] end
chain_pem()
click to toggle source
# File lib/mini_ca/certificate.rb, line 118 def chain_pem chain.map(&:x509).map(&:to_pem).join('') end
issue(cn, **opts)
click to toggle source
rubocop:enable ParameterLists
# File lib/mini_ca/certificate.rb, line 90 def issue(cn, **opts) raise 'CA must be set to use #issue' unless ca @counter += 1 Certificate.new(cn, issuer: self, serial: @counter, **opts) end
private_key_pem()
click to toggle source
# File lib/mini_ca/certificate.rb, line 126 def private_key_pem private_key.to_pem end
public_key()
click to toggle source
# File lib/mini_ca/certificate.rb, line 130 def public_key case private_key when OpenSSL::PKey::RSA private_key.public_key when OpenSSL::PKey::EC # See: https://github.com/ruby/openssl/issues/29#issuecomment-230664793 # See: https://alexpeattie.com/blog/signing-a-csr-with-ecdsa-in-ruby pub = OpenSSL::PKey::EC.new(private_key.group) pub.public_key = private_key.public_key pub else raise Error, "Unsupported private_key: #{private_key.class}" end end
store()
click to toggle source
# File lib/mini_ca/certificate.rb, line 96 def store raise 'CA must be set to use #store' unless ca OpenSSL::X509::Store.new.tap { |store| store.add_cert(x509) } end
x509_pem()
click to toggle source
# File lib/mini_ca/certificate.rb, line 114 def x509_pem x509.to_pem end