Class: R509::CertificateAuthority::Signer

Inherits:
Object
  • Object
show all
Defined in:
lib/r509/certificate_authority/signer.rb

Overview

Contains the certification authority signing operation methods

Class Method Summary (collapse)

Instance Method Summary (collapse)

Constructor Details

- (Signer) initialize(config)

A new instance of Signer

Parameters:



12
13
14
15
16
17
18
19
20
21
# File 'lib/r509/certificate_authority/signer.rb', line 12

def initialize(config)
  @config = config

  if not @config.nil? and not @config.kind_of?(R509::Config::CAConfig)
    raise R509::R509Error, "config must be a kind of R509::Config::CAConfig"
  end
  if not @config.nil? and not @config.ca_cert.has_private_key?
    raise R509::R509Error, "You must have a private key associated with your CA certificate to issue"
  end
end

Class Method Details

+ (R509::Cert) selfsign(options)

Self-signs a CSR

Parameters:

  • options (Hash)

    a customizable set of options

Options Hash (options):

  • :csr (R509::CSR)
  • :message_digest (String)

    the message digest to use for this certificate (defaults to R509::MessageDigest::DEFAULT_MD)

  • :serial (String) — default: random serial

    the serial number you want to issue the certificate with

  • :extensions (Array)

    An array of R509::Cert::Extensions::* objects that represent the extensions you want to embed in the final certificate

  • :not_before (Time) — default: Time.now - 6 hours

    the notBefore for the certificate

  • :not_after (Time) — default: Time.now + 365 days

    the notAfter for the certificate

Returns:



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/r509/certificate_authority/signer.rb', line 70

def self.selfsign(options)
  if not options.kind_of?(Hash)
    raise ArgumentError, "You must pass a hash of options consisting of at minimum :csr"
  end
  csr = options[:csr]
  if csr.key.nil?
    raise ArgumentError, 'CSR must also have a private key to self sign'
  end

  subject, public_key = R509::CertificateAuthority::Signer.extract_public_key_subject(options)

  cert = self.build_cert(
    :subject => subject.name,
    :issuer => subject.name,
    :not_before => options[:not_before],
    :not_after => options[:not_after],
    :public_key => public_key,
    :serial => options[:serial]
  )

  cert.extensions = options[:extensions] || [
    R509::Cert::Extensions::BasicConstraints.new(:ca => true),
    R509::Cert::Extensions::SubjectKeyIdentifier.new(:public_key => public_key),
    R509::Cert::Extensions::AuthorityKeyIdentifier.new(:public_key => public_key)
  ]

  if options.has_key?(:message_digest)
    message_digest = R509::MessageDigest.new(options[:message_digest])
  else
    message_digest = R509::MessageDigest.new(R509::MessageDigest::DEFAULT_MD)
  end

  cert.sign( csr.key.key, message_digest.digest )

  R509::Cert.new(:cert => cert, :key => csr.key)
end

Instance Method Details

- (R509::Cert) sign(options)

Signs a CSR

Parameters:

  • options (Hash)

    a customizable set of options

Options Hash (options):

  • :csr (R509::CSR)
  • :spki (R509::SPKI)
  • :subject (R509::Subject, OpenSSL::X509::Subject, Array)

    This is optional when passing a :csr but required for :spki

  • :message_digest (String)

    the message digest to use for this certificate instead of the default (see R509::MessageDigest::DEFAULT_MD).

  • :serial (String) — default: random serial

    the serial number you want to issue the certificate with

  • :extensions (Array)

    An array of R509::Cert::Extensions::* objects that represent the extensions you want to embed in the final certificate

  • :not_before (Time) — default: Time.now - 6 hours

    the notBefore for the certificate

  • :not_after (Time) — default: Time.now + 365 days

    the notAfter for the certificate

Returns:



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/r509/certificate_authority/signer.rb', line 33

def sign(options)
  R509::CertificateAuthority::Signer.check_options(options)

  message_digest = R509::MessageDigest.new(options[:message_digest])

  subject, public_key = R509::CertificateAuthority::Signer.extract_public_key_subject(options)

  cert = R509::CertificateAuthority::Signer.build_cert(
    :subject => subject.name,
    :issuer => @config.ca_cert.subject.name,
    :not_before => options[:not_before],
    :not_after => options[:not_after],
    :public_key => public_key,
    :serial => options[:serial]
  )

  cert.extensions = options[:extensions] || [
    R509::Cert::Extensions::SubjectKeyIdentifier.new(:public_key => public_key),
    R509::Cert::Extensions::AuthorityKeyIdentifier.new(:public_key => @config.ca_cert.public_key)
  ]

  #@config.ca_cert.key.key ... ugly. ca_cert returns R509::Cert
  # #key returns R509::PrivateKey and #key on that returns OpenSSL object we need
  cert.sign( @config.ca_cert.key.key, message_digest.digest )
  cert_opts = { :cert => cert }
  cert_opts[:key] = options[:csr].key if not options[:csr].nil? and not options[:csr].key.nil?
  R509::Cert.new(cert_opts)
end