Class: R509::Cert

Inherits:
Object
  • Object
show all
Includes:
IOHelpers
Defined in:
lib/r509/cert.rb,
lib/r509/cert/extensions.rb

Overview

The primary certificate object.

Defined Under Namespace

Modules: Extensions

Instance Attribute Summary (collapse)

Class Method Summary (collapse)

Instance Method Summary (collapse)

Methods included from IOHelpers

#read_data, read_data, #write_data, write_data

Constructor Details

- (Cert) initialize(opts = {})

A new instance of Cert

Parameters:

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

    a customizable set of options

Options Hash (opts):

  • :cert (String, OpenSSL::X509::Certificate)

    a cert

  • :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)

  • :pkcs12 (String)

    a PKCS12 object containing both key and cert

  • :password (String)

    password for PKCS12 or private key (if supplied)



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/r509/cert.rb', line 17

def initialize(opts={})
  if not opts.kind_of?(Hash)
    raise ArgumentError, 'Must provide a hash of options'
  end
  if opts.has_key?(:pkcs12) and ( opts.has_key?(:key) or opts.has_key?(:cert) )
    raise ArgumentError, "When providing pkcs12, do not pass cert or key"
  elsif opts.has_key?(:pkcs12)
    pkcs12 = OpenSSL::PKCS12.new( opts[:pkcs12], opts[:password] )
    parse_certificate(pkcs12.certificate)
    key = R509::PrivateKey.new( :key => pkcs12.key )
  elsif not opts.has_key?(:cert)
    raise ArgumentError, 'Must provide :cert or :pkcs12'
  else
    csr_check(opts[:cert])
    parse_certificate(opts[:cert])
  end

  if opts.has_key?(:key)
    if opts[:key].kind_of?(R509::PrivateKey)
      key = opts[:key]
    else
      key = R509::PrivateKey.new( :key => opts[:key], :password => opts[:password] )
    end
  end
  associate_private_key(key)
end

Instance Attribute Details

- (Object) cert (readonly)

Returns the value of attribute cert



11
12
13
# File 'lib/r509/cert.rb', line 11

def cert
  @cert
end

- (Object) issuer (readonly)

Returns the value of attribute issuer



11
12
13
# File 'lib/r509/cert.rb', line 11

def issuer
  @issuer
end

- (Object) key (readonly)

Returns the value of attribute key



11
12
13
# File 'lib/r509/cert.rb', line 11

def key
  @key
end

- (Object) subject (readonly)

Returns the value of attribute subject



11
12
13
# File 'lib/r509/cert.rb', line 11

def subject
  @subject
end

Class Method Details

+ (R509::Cert) load_from_file(filename)

Helper method to quickly load a cert from the filesystem

Parameters:

  • filename (String)

    Path to file you want to load

Returns:



48
49
50
# File 'lib/r509/cert.rb', line 48

def self.load_from_file( filename )
  return R509::Cert.new(:cert => IOHelpers.read_data(filename) )
end

Instance Method Details

- (Array) all_names

Return the CN, as well as all the subject alternative names (SANs).

Returns:

  • (Array)

    the array of names. Returns an empty array if there are no names, at all. Discards SAN types



156
157
158
159
160
161
162
# File 'lib/r509/cert.rb', line 156

def all_names
  ret = []
  ret << @subject.CN unless @subject.CN.nil?
  ret.concat( self.san.names.map { |n| n.value } ) unless self.san.nil?

  return ret.sort.uniq
end

- (R509::Cert::Extensions::AuthorityInfoAccess) authority_info_access Also known as: aia

Returns this object's AuthorityInfoAccess extension as an R509 extension

if this cert does not have a AuthorityInfoAccess extension.

Returns:



349
350
351
# File 'lib/r509/cert.rb', line 349

def authority_info_access
  return extensions[R509::Cert::Extensions::AuthorityInfoAccess]
end

- (R509::Cert::Extensions::AuthorityKeyIdentifier) authority_key_identifier

Returns this object's AuthorityKeyIdentifier extension as an R509 extension

if this cert does not have a AuthorityKeyIdentifier extension.

Returns:



331
332
333
# File 'lib/r509/cert.rb', line 331

def authority_key_identifier
  return extensions[R509::Cert::Extensions::AuthorityKeyIdentifier]
end

- (R509::Cert::Extensions::BasicConstraints) basic_constraints

Returns this object's BasicConstraints extension as an R509 extension

if this cert does not have a BasicConstraints extension.

Returns:



297
298
299
# File 'lib/r509/cert.rb', line 297

def basic_constraints
  return extensions[R509::Cert::Extensions::BasicConstraints]
end

- (Integer) bit_strength

Returns the bit strength of the key used to create the certificate

Returns:

  • (Integer)

    integer value of bit strength



188
189
190
191
192
193
194
195
196
# File 'lib/r509/cert.rb', line 188

def bit_strength
  if self.rsa?
    return @cert.public_key.n.num_bits
  elsif self.dsa?
    return @cert.public_key.p.num_bits
  elsif self.ec?
    raise R509::R509Error, 'Bit strength is not available for EC at this time.'
  end
end

- (R509::Cert::Extensions::CertificatePolicies) certificate_policies

Returns this object's CertificatePolicies extension as an R509 extension

if this cert does not have a CertificatePolicies extension.

Returns:



375
376
377
# File 'lib/r509/cert.rb', line 375

def certificate_policies
  return extensions[R509::Cert::Extensions::CertificatePolicies]
end

- (R509::Cert::Extensions::CRLDistributionPoints) crl_distribution_points Also known as: cdp

Returns this object's CRLDistributionPoints extension as an R509 extension

if this cert does not have a CRLDistributionPoints extension.

Returns:



358
359
360
# File 'lib/r509/cert.rb', line 358

def crl_distribution_points
  return extensions[R509::Cert::Extensions::CRLDistributionPoints]
end

- (String) curve_name

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



202
203
204
205
206
207
208
# File 'lib/r509/cert.rb', line 202

def curve_name
  if self.ec?
    @cert.public_key.group.curve_name
  else
    raise R509::R509Error, 'Curve name is only available with EC certs'
  end
end

- (Boolean) dsa?

Returns whether the public key is DSA

Returns:

  • (Boolean)

    true if the public key is DSA, false otherwise



174
175
176
# File 'lib/r509/cert.rb', line 174

def dsa?
  @cert.public_key.kind_of?(OpenSSL::PKey::DSA)
end

- (Boolean) ec?

Returns whether the public key is EC

Returns:

  • (Boolean)

    true if the public key is EC, false otherwise



181
182
183
# File 'lib/r509/cert.rb', line 181

def ec?
  @cert.public_key.kind_of?(OpenSSL::PKey::EC)
end

- (R509::Cert::Extensions::ExtendedKeyUsage) extended_key_usage Also known as: eku

Returns this object's ExtendedKeyUsage extension as an R509 extension

if this cert does not have a ExtendedKeyUsage extension.

Returns:



314
315
316
# File 'lib/r509/cert.rb', line 314

def extended_key_usage
  return extensions[R509::Cert::Extensions::ExtendedKeyUsage]
end

- (Hash) extensions

Returns the certificate extensions as a hash of R509::Cert::Extensions specific objects.

R509::Cert::Extensions module, each specific to the extension. The hash is keyed with the R509 extension class. Extensions without an R509 implementation are ignored (see #get_unknown_extensions).

Returns:

  • (Hash)

    A hash, in which the values are classes from the



273
274
275
276
277
278
279
# File 'lib/r509/cert.rb', line 273

def extensions
  if @r509_extensions.nil?
    @r509_extensions = Extensions.wrap_openssl_extensions( self.cert.extensions )
  end

  return @r509_extensions
end

- (String) fingerprint(algorithm = 'sha1')

Returns the certificate fingerprint with the specified algorithm (default sha1)

Parameters:

  • algorithm (String) (defaults to: 'sha1')

    Which algorithm to use for the fingerprint. See R509::MessageDigest for supported algorithm names

Returns:

  • (String)

    hex digest of the certificate



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

def fingerprint(algorithm='sha1')
  message_digest = R509::MessageDigest.new(algorithm)
  md = message_digest.digest
  md.update(@cert.to_der)
  md.to_s
end

- (Boolean) has_private_key?

Boolean of whether the object contains a private key

Returns:

  • (Boolean)

    Boolean of whether the object contains a private key



144
145
146
147
148
149
150
# File 'lib/r509/cert.rb', line 144

def has_private_key?
  if not @key.nil?
    true
  else
    false
  end
end

- (String) hexserial

Returns the serial number of the certificate in hexadecimal form

Returns:

  • (String)


90
91
92
# File 'lib/r509/cert.rb', line 90

def hexserial
  @cert.serial.to_s(16)
end

- (R509::Cert::Extensions::InhibitAnyPolicy) inhibit_any_policy

Returns this object's InhibitAnyPolicy extension as an R509 extension

if this cert does not have a InhibitAnyPolicy extension.

Returns:



383
384
385
# File 'lib/r509/cert.rb', line 383

def inhibit_any_policy
  return extensions[R509::Cert::Extensions::InhibitAnyPolicy]
end

- (Boolean) is_revoked_by_crl?(r509_crl)

Checks the given CRL for this certificate's serial number. Note that this does NOT check to verify that the CRL you're checking is signed by the same CA as the cert so do that check yourself

Parameters:

Returns:

  • (Boolean)


262
263
264
# File 'lib/r509/cert.rb', line 262

def is_revoked_by_crl?( r509_crl )
  return r509_crl.revoked?( self.serial )
end

- (Symbol) key_algorithm

Returns key algorithm (RSA, DSA, EC)

Returns:

  • (Symbol)

    value of the key algorithm. :rsa, :dsa, :ec



220
221
222
223
224
225
226
227
228
# File 'lib/r509/cert.rb', line 220

def key_algorithm
  if self.rsa?
    :rsa
  elsif self.dsa?
    :dsa
  elsif self.ec?
    :ec
  end
end

- (R509::Cert::Extensions::KeyUsage) key_usage Also known as: ku

Returns this object's KeyUsage extension as an R509 extension

if this cert does not have a KeyUsage extension.

Returns:



305
306
307
# File 'lib/r509/cert.rb', line 305

def key_usage
  return extensions[R509::Cert::Extensions::KeyUsage]
end

- (R509::Cert::Extensions::NameConstraints) name_constraints

Returns this object's NameConstraints extension as an R509 extension

if this cert does not have a NameConstraints extension.

Returns:



399
400
401
# File 'lib/r509/cert.rb', line 399

def name_constraints
  return extensions[R509::Cert::Extensions::NameConstraints]
end

- (Time) not_after

Returns ending (notAfter) of certificate validity period

Returns:

  • (Time)

    time object



97
98
99
# File 'lib/r509/cert.rb', line 97

def not_after
  @cert.not_after
end

- (Time) not_before

Returns beginning (notBefore) of certificate validity period

Returns:

  • (Time)

    time object



76
77
78
# File 'lib/r509/cert.rb', line 76

def not_before
  @cert.not_before
end

- (Boolean) ocsp_no_check?

Returns true if the OCSP No Check extension is present (value is irrelevant to this extension)

Returns:

  • (Boolean)

    presence/absence of the nocheck extension



367
368
369
# File 'lib/r509/cert.rb', line 367

def ocsp_no_check?
  return (extensions.has_key?(R509::Cert::Extensions::OCSPNoCheck))
end

- (R509::Cert::Extensions::PolicyConstraints) policy_constraints

Returns this object's PolicyConstraints extension as an R509 extension

if this cert does not have a PolicyConstraints extension.

Returns:



391
392
393
# File 'lib/r509/cert.rb', line 391

def policy_constraints
  return extensions[R509::Cert::Extensions::PolicyConstraints]
end

- (OpenSSL::PKey::RSA) public_key

Returns the certificate public key

Returns:

  • (OpenSSL::PKey::RSA)

    public key object



104
105
106
# File 'lib/r509/cert.rb', line 104

def public_key
  @cert.public_key
end

- (Boolean) rsa?

Returns whether the public key is RSA

Returns:

  • (Boolean)

    true if the public key is RSA, false otherwise



167
168
169
# File 'lib/r509/cert.rb', line 167

def rsa?
  @cert.public_key.kind_of?(OpenSSL::PKey::RSA)
end

- (Integer) serial

Returns the serial number of the certificate in decimal form

Returns:

  • (Integer)


83
84
85
# File 'lib/r509/cert.rb', line 83

def serial
  @cert.serial.to_i
end

- (String) signature_algorithm

Returns signature algorithm

Returns:

  • (String)

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



213
214
215
# File 'lib/r509/cert.rb', line 213

def signature_algorithm
  @cert.signature_algorithm
end

- (R509::Cert::Extensions::SubjectAlternativeName) subject_alternative_name Also known as: san, subject_alt_name

Returns this object's SubjectAlternativeName extension as an R509 extension

if this cert does not have a SubjectAlternativeName extension.

Returns:



339
340
341
# File 'lib/r509/cert.rb', line 339

def subject_alternative_name
  return extensions[R509::Cert::Extensions::SubjectAlternativeName]
end

- (R509::Cert::Extensions::SubjectKeyIdentifier) subject_key_identifier

Returns this object's SubjectKeyIdentifier extension as an R509 extension

if this cert does not have a SubjectKeyIdentifier extension.

Returns:



323
324
325
# File 'lib/r509/cert.rb', line 323

def subject_key_identifier
  return extensions[R509::Cert::Extensions::SubjectKeyIdentifier]
end

- (String) to_der

Converts the Cert into the DER format

Returns:

  • (String)

    the Cert converted into DER format.



67
68
69
70
71
# File 'lib/r509/cert.rb', line 67

def to_der
  if @cert.kind_of?(OpenSSL::X509::Certificate)
    return @cert.to_der
  end
end

- (String) to_pem Also known as: to_s

Converts the Cert into the PEM format

Returns:

  • (String)

    the Cert converted into PEM format.



56
57
58
59
60
# File 'lib/r509/cert.rb', line 56

def to_pem
  if @cert.kind_of?(OpenSSL::X509::Certificate)
    return @cert.to_pem.chomp
  end
end

- (Array) unknown_extensions

Returns an array of OpenSSL::X509::Extension objects representing the extensions that do not have R509 implementations.

Returns:

  • (Array)

    An array of OpenSSL::X509::Extension objects.



285
286
287
# File 'lib/r509/cert.rb', line 285

def unknown_extensions
  return Extensions.get_unknown_extensions( self.cert.extensions )
end

- (Boolean) valid?

Returns whether the current time is between the notBefore and notAfter times in the certificate.

Returns:

  • (Boolean)


123
124
125
# File 'lib/r509/cert.rb', line 123

def valid?
  valid_at?(Time.now)
end

- (Boolean) valid_at?(time)

Returns whether the certificate was between its notBefore and notAfter at the time provided

Parameters:

  • time (Time, Integer)

    Time object or integer timestamp

Returns:

  • (Boolean)


131
132
133
134
135
136
137
138
139
140
141
# File 'lib/r509/cert.rb', line 131

def valid_at?(time)
  if time.kind_of?(Integer)
    time = Time.at(time)
  end

  if (self.not_after < time) or (self.not_before > time)
    false
  else
    true
  end
end

- (Object) write_der(filename_or_io)

Writes the Cert into the 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.



240
241
242
# File 'lib/r509/cert.rb', line 240

def write_der(filename_or_io)
  write_data(filename_or_io, @cert.to_der)
end

- (Object) write_pem(filename_or_io)

Writes the Cert into the 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.



233
234
235
# File 'lib/r509/cert.rb', line 233

def write_pem(filename_or_io)
  write_data(filename_or_io, @cert.to_pem)
end

- (Object) write_pkcs12(filename_or_io, password, friendly_name = 'r509 pkcs12')

Writes cert and key into PKCS12 format using OpenSSL defaults for encryption (des3)

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.

  • password (String)

    password

  • friendly_name (String) (defaults to: 'r509 pkcs12')

    An optional string to encode in the PKCS12 for friendlyName. defaults to "r509 pkcs12"



249
250
251
252
253
254
255
# File 'lib/r509/cert.rb', line 249

def write_pkcs12(filename_or_io,password,friendly_name='r509 pkcs12')
  if @key.nil?
    raise R509::R509Error, "Writing a PKCS12 requires both key and cert"
  end
  pkcs12 = OpenSSL::PKCS12.create(password,friendly_name,@key.key,@cert)
  write_data(filename_or_io, pkcs12.to_der)
end