class EaSSL::Certificate

Author

Paul Nicholson (paul@webpowerdesign.net)

Co-Author

Adam Williams (adam@thewilliams.ws)

Copyright

Copyright © 2006 WebPower Design

License

Distributes under the same terms as Ruby

Public Class Methods

load(pem_file_path) click to toggle source
# File lib/eassl/certificate.rb, line 105
def self.load(pem_file_path)
  new({}).load(File.read(pem_file_path))
end
new(options) click to toggle source
# File lib/eassl/certificate.rb, line 9
def initialize(options)
  @options = {
    :days_valid       => (365 * 5),
    :signing_request  => nil,               #required
    :ca_certificate   => nil,               #required
    :comment          => "Ruby/OpenSSL/EaSSL Generated Certificate",
    :type             => "server",
    :subject_alt_name => nil, #optional e.g. [ "*.example.com", "example.com", {:name => "IP", :value => "127.0.0.1"} ]
    :override_req     => true,
    :extensions       => nil #if type is custom, [ {:name => "keyUsage", :value => "digitalSignature"} ]
  }.update(options)
end

Public Instance Methods

load(pem_string) click to toggle source
# File lib/eassl/certificate.rb, line 109
def load(pem_string)
  begin
    @ssl = OpenSSL::X509::Certificate.new(pem_string)
  rescue
    raise "CertificateLoader: Error loading certificate"
  end
  self
end
method_missing(method) click to toggle source

This method is used to intercept and pass-thru calls to openSSL methods and instance variables.

# File lib/eassl/certificate.rb, line 101
def method_missing(method)
  ssl.send(method)
end
sha1_fingerprint() click to toggle source

Returns a SHA1 fingerprint of the certificate in the OpenSSL style

# File lib/eassl/certificate.rb, line 95
def sha1_fingerprint
  Digest::SHA1.hexdigest(ssl.to_der).upcase.gsub(/(..)/, '\1:').chop
end
sign(ca_key, digest=OpenSSL::Digest::SHA1.new) click to toggle source
# File lib/eassl/certificate.rb, line 86
def sign(ca_key, digest=OpenSSL::Digest::SHA1.new)
  ssl.sign(ca_key.private_key, digest)
end
ssl() click to toggle source
# File lib/eassl/certificate.rb, line 22
def ssl
  unless @ssl
    @ssl = OpenSSL::X509::Certificate.new
    @ssl.not_before = Time.now
    @ssl.subject = @options[:signing_request].subject
    @ssl.issuer = @options[:ca_certificate]? @options[:ca_certificate].subject :  @ssl.subject
    @ssl.not_after = @ssl.not_before + @options[:days_valid] * 24 * 60 * 60
    @ssl.public_key = @options[:signing_request].public_key
    @ssl.serial = @options[:serial] || 2
    @ssl.version = 2 # X509v3

    ef = OpenSSL::X509::ExtensionFactory.new
    ef.subject_certificate = @ssl
    ef.issuer_certificate = @options[:ca_certificate]? @options[:ca_certificate].ssl : @ssl
    @ssl.extensions = [ ef.create_extension("subjectKeyIdentifier", "hash") ]
    @ssl.add_extension(ef.create_extension("authorityKeyIdentifier", "keyid:always,issuer:always"))
    
    extensions = Array.new
    
    extensions << ef.create_extension("basicConstraints","CA:FALSE")
    extensions << ef.create_extension("nsComment", @options[:comment])

    case @options[:type]
    when 'server'
      extensions << ef.create_extension("keyUsage", "digitalSignature,keyEncipherment")
      extensions << ef.create_extension("extendedKeyUsage", "serverAuth")
    when 'client'
      extensions << ef.create_extension("keyUsage", "nonRepudiation,digitalSignature,keyEncipherment")
      extensions << ef.create_extension("extendedKeyUsage", "clientAuth,emailProtection")
    when 'peer'
      extensions << ef.create_extension("keyUsage", "digitalSignature,keyEncipherment")
      extensions << ef.create_extension("extendedKeyUsage", "serverAuth,clientAuth")
    when 'custom'
      exten_opts = @options[:extensions] || @options[:signing_request].options[:extensions]
      exten_opts.each do |ext|
        extensions << ef.create_extension(ext[:name], ext[:value])
      end
    end

    #add subject alternate names
    if @options[:subject_alt_name]
      subjectAltName = @options[:subject_alt_name].map {|d| d.is_a?(Hash) ? "#{d[:name]}: #{d[:value]}" : "DNS: #{d}"  }.join(',')
      extensions << ef.create_extension("subjectAltName", subjectAltName)
    end

    if sr = @options[:signing_request] and not sr.extensions.nil?
      sr.extensions.each do |ext|
        if @options[:override_req] # CA extensions take precedence in merge, default behavior
          extensions << ext unless extensions.any? { |e| e.oid == ext.oid }
        else # Req extensions take precedence in merge
          extensions.delete_if { |e| e.oid == ext.oid }
          extensions << ext
        end
      end
    end

    extensions.each do |ext|
      @ssl.add_extension(ext)
    end

  end
  @ssl
end
to_pem() click to toggle source
# File lib/eassl/certificate.rb, line 90
def to_pem
  ssl.to_pem
end