Class: R509::CSR

Inherits:
Object
  • Object
show all
Includes:
Helpers
Defined in:
lib/r509/csr.rb

Overview

The primary certificate signing request object

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ CSR

Returns a new instance of CSR

Examples:

Generate a 4096-bit RSA key + CSR

:type => "RSA",
:bit_length => 4096,
:subject => [
  ['CN','somedomain.com'],
  ['O','My Org'],
  ['L','City'],
  ['ST','State'],
  ['C','US']
]

Generate a 2048-bit RSA key + CSR

:type => "RSA",
:bit_length => 4096,
:subject => { :CN => "myCN", :O => "org" }

Generate an ECDSA key using the secp384r1 curve parameters + CSR and sign with SHA512

:type => "EC",
:curve_name => 'secp384r1',
:message_digest => 'sha512',
:subject => [
  ['CN','somedomain.com'],
]

Parameters:

  • opts (Hash) (defaults to: {})

    a customizable set of options

Options Hash (opts):

  • :csr (String, OpenSSL::X509::Request)

    a csr

  • :type (String)

    Required if not providing existing :csr. Defaults to R509::PrivateKey::DEFAULT_TYPE. Allows R509::PrivateKey::KNOWN_TYPES.

  • :curve_name (String) — default: "secp384r1"

    Only used if :type is EC

  • :bit_length (Integer) — default: 2048

    Only used if :type is RSA or DSA

  • :bit_strength (Integer) — default: 2048

    Deprecated, identical to bit_length.

  • :message_digest (String)

    Optional digest. sha1, sha224, sha256, sha384, sha512, md5. Defaults to sha256

  • :san_names (Array, R509::ASN1::GeneralNames)

    List of domains, IPs, email addresses, or URIs to encode as subjectAltNames. The type is determined from the structure of the strings via the R509::ASN1.general_name_parser method. You can also pass an explicit R509::ASN1::GeneralNames object. Parsed names will be uniqued, but a GeneralNames object will not be touched.

  • :subject (R509::Subject, Array, OpenSSL::X509::Name)

    array of subject items

  • :key (R509::PrivateKey, String)

    optional private key to supply. either an unencrypted PEM/DER string or an R509::PrivateKey object (use the latter if you need password/hardware support)



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/r509/csr.rb', line 46

def initialize(opts = {})
  unless opts.is_a?(Hash)
    raise ArgumentError, 'Must provide a hash of options'
  end
  if opts.key?(:subject) && opts.key?(:csr)
    raise ArgumentError, "You must provide :subject or :csr, not both"
  end
  @bit_length = opts[:bit_length] || opts[:bit_strength] || R509::PrivateKey::DEFAULT_STRENGTH
  @curve_name = opts[:curve_name] || R509::PrivateKey::DEFAULT_CURVE

  @key = load_private_key(opts)

  @type = opts[:type] || R509::PrivateKey::DEFAULT_TYPE
  if !R509::PrivateKey::KNOWN_TYPES.include?(@type.upcase) && @key.nil?
    raise ArgumentError, "Must provide #{R509::PrivateKey::KNOWN_TYPES.join(", ")} as type when key is nil"
  end

  if opts.key?(:subject)
    san_names = R509::ASN1.general_name_parser(opts[:san_names])
    create_request(opts[:subject], san_names) # sets @req
  elsif opts.key?(:csr)
    if opts.key?(:san_names)
      raise ArgumentError, "You can't add domains to an existing CSR"
    end
    parse_csr(opts[:csr])
  else
    raise ArgumentError, "You must provide :subject or :csr"
  end

  if dsa?
    # only DSS1 is acceptable for DSA signing in OpenSSL < 1.0
    # post-1.0 you can sign with anything, but let's be conservative
    # see: http://www.ruby-doc.org/stdlib-1.9.3/libdoc/openssl/rdoc/OpenSSL/PKey/DSA.html
    @message_digest = R509::MessageDigest.new('dss1')
  else
    @message_digest = R509::MessageDigest.new(opts[:message_digest])
  end

  unless opts.key?(:csr)
    @req.sign(@key.key, @message_digest.digest)
  end
  if @key && !@req.verify(@key.public_key)
    raise R509Error, 'Key does not match request.'
  end
end

Instance Attribute Details

#attributesObject (readonly)

Returns the value of attribute attributes



15
16
17
# File 'lib/r509/csr.rb', line 15

def attributes
  @attributes
end

#keyObject (readonly)

Returns the value of attribute key



15
16
17
# File 'lib/r509/csr.rb', line 15

def key
  @key
end

#message_digestObject (readonly)

Returns the value of attribute message_digest



15
16
17
# File 'lib/r509/csr.rb', line 15

def message_digest
  @message_digest
end

#reqObject (readonly) Also known as: internal_obj

Returns the value of attribute req



15
16
17
# File 'lib/r509/csr.rb', line 15

def req
  @req
end

#sanObject (readonly)

Returns the value of attribute san



15
16
17
# File 'lib/r509/csr.rb', line 15

def san
  @san
end

#subjectObject (readonly)

Returns the value of attribute subject



15
16
17
# File 'lib/r509/csr.rb', line 15

def subject
  @subject
end

Class Method Details

.load_from_file(filename) ⇒ R509::CSR

Helper method to quickly load a CSR from the filesystem

Parameters:

  • filename (String)

    Path to file you want to load

Returns:



96
97
98
# File 'lib/r509/csr.rb', line 96

def self.load_from_file(filename)
  R509::CSR.new(:csr => IOHelpers.read_data(filename))
end

Instance Method Details

#bit_lengthInteger Also known as: bit_strength Originally defined in module Helpers

Returns the bit length of the key

Returns:

  • (Integer)

    the integer bit length.

#curve_nameString Originally defined in module Helpers

Returns the short name of the elliptic curve used to generate the public key if the key is EC. If not, raises an error.

Returns:

  • (String)

    elliptic curve name

#dsa?Boolean Originally defined in module Helpers

Returns whether the public key is DSA

Returns:

  • (Boolean)

    true if the public key is DSA, false otherwise

#ec?Boolean Originally defined in module Helpers

Returns whether the public key is EC

Returns:

  • (Boolean)

    true if the public key is EC, false otherwise

#has_private_key?Boolean

Returns Boolean of whether the object contains a private key

Returns:

  • (Boolean)

    Boolean of whether the object contains a private key



112
113
114
115
116
117
118
# File 'lib/r509/csr.rb', line 112

def has_private_key?
  if @key
    true
  else
    false
  end
end

#key_algorithmString

Returns key algorithm (RSA/DSA/EC)

Returns:

  • (String)

    value of the key algorithm. RSA, DSA, or EC



145
146
147
148
149
150
151
152
153
# File 'lib/r509/csr.rb', line 145

def key_algorithm
  if @req.public_key.is_a? OpenSSL::PKey::RSA
    "RSA"
  elsif @req.public_key.is_a? OpenSSL::PKey::DSA
    "DSA"
  elsif @req.public_key.is_a? OpenSSL::PKey::EC
    "EC"
  end
end

#public_keyOpenSSL::PKey::RSA, ...

Returns public key

Returns:

  • (OpenSSL::PKey::RSA, OpenSSL::PKey::DSA, OpenSSL::PKey::EC)

    public key



101
102
103
# File 'lib/r509/csr.rb', line 101

def public_key
  @req.public_key
end

#rsa?Boolean Originally defined in module Helpers

Returns whether the public key is RSA

Returns:

  • (Boolean)

    true if the public key is RSA, false otherwise

#signature_algorithmString

Returns signature algorithm

Returns:

  • (String)

    value of the signature algorithm. E.g. sha1WithRSAEncryption, sha256WithRSAEncryption, md5WithRSAEncryption



138
139
140
# File 'lib/r509/csr.rb', line 138

def signature_algorithm
  @req.signature_algorithm
end

#subject_component(short_name) ⇒ String

Returns subject component

Parameters:

  • short_name (String)

    short name subject component (e.g. CN, O, ST)

Returns:

  • (String)

    value of the subject component requested



126
127
128
129
130
131
132
133
# File 'lib/r509/csr.rb', line 126

def subject_component(short_name)
  @req.subject.to_a.each do |element|
    if element[0].downcase == short_name.downcase
      return element[1]
    end
  end
  nil
end

#to_derString Originally defined in module Helpers

Converts the object into DER format

Returns:

  • (String)

    the object converted into DER format.

#to_pemString Originally defined in module Helpers

Converts the object into PEM format

Returns:

  • (String)

    the object converted into PEM format.

#verify_signatureBoolean

Verifies the integrity of the signature on the request

Returns:

  • (Boolean)


107
108
109
# File 'lib/r509/csr.rb', line 107

def verify_signature
  @req.verify(public_key)
end

#write_der(filename_or_io) ⇒ Object Originally defined in module Helpers

Writes the object into DER format

Parameters:

  • filename_or_io (String, #write)

    Either a string of the path for the file that you'd like to write, or an IO-like object.

#write_pem(filename_or_io) ⇒ Object Originally defined in module Helpers

Writes the object into PEM format

Parameters:

  • filename_or_io (String, #write)

    Either a string of the path for the file that you'd like to write, or an IO-like object.