Class: Ronin::DB::Cert

Inherits:
ActiveRecord::Base
  • Object
show all
Includes:
Model, Model::Importable
Defined in:
lib/ronin/db/cert.rb

Overview

Represents a SSL/TLS certificate.

Since:

  • 0.2.0

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Model::Importable

included

Methods included from Model

included

Instance Attribute Details

#created_atTime

When the certificate was created.

Returns:

  • (Time)


131
# File 'lib/ronin/db/cert.rb', line 131

attribute :created_at, :datetime

#idInteger

The primary ID of the certificate.

Returns:

  • (Integer)


40
# File 'lib/ronin/db/cert.rb', line 40

attribute :id, :integer

#ip_addressesArray<IPAddress>

The IP addresses that use this certificate.

Returns:



150
# File 'lib/ronin/db/cert.rb', line 150

has_many :ip_addresses, through: :open_ports

#issuerCertIssuer?

Note:

When the certificate is self-signed, #issuer will not be set.

The certificate issuer information.

Returns:



77
78
# File 'lib/ronin/db/cert.rb', line 77

belongs_to :issuer, class_name: 'CertIssuer',
optional:   true

#not_afterTime

When the certificate expires.

Returns:

  • (Time)


67
# File 'lib/ronin/db/cert.rb', line 67

attribute :not_after, :datetime

#not_beforeTime

When the certificate starts being valid.

Returns:

  • (Time)


60
# File 'lib/ronin/db/cert.rb', line 60

attribute :not_before, :datetime

#notesArray<Note>

The associated notes.

Returns:

Since:

  • 0.2.0



158
# File 'lib/ronin/db/cert.rb', line 158

has_many :notes

#open_portsArray<OpenPort>

The open ports that use this certificate.

Returns:



144
# File 'lib/ronin/db/cert.rb', line 144

has_many :open_ports, dependent: :nullify

#pemString

The PEM encoded version of the certificate.

Returns:

  • (String)


124
# File 'lib/ronin/db/cert.rb', line 124

attribute :pem, :text

#public_key_algorithm"rsa", ...

The public key algorithm.

Returns:

  • ("rsa", "dsa", "dh", "ec")


91
# File 'lib/ronin/db/cert.rb', line 91

enum :public_key_algorithm, {rsa: 'RSA', dsa: 'DSA', dh: 'DH', ec: 'EC'}

#public_key_sizeObject

The public key size in bits.



98
# File 'lib/ronin/db/cert.rb', line 98

attribute :public_key_size, :integer

#serialString

The certificate's serial number.

Returns:

  • (String)


46
# File 'lib/ronin/db/cert.rb', line 46

attribute :serial, :string

#sha1_fingerprintString

The SHA1 fingerprint of the certificate.

Returns:

  • (String)


112
# File 'lib/ronin/db/cert.rb', line 112

attribute :sha1_fingerprint

#sha256_fingerprintString

The SHA256 fingerprint of the certificate.

Returns:

  • (String)


118
# File 'lib/ronin/db/cert.rb', line 118

attribute :sha256_fingerprint

#signing_algorithmString

The algorithm used to sign the certificate.

Returns:

  • (String)


105
# File 'lib/ronin/db/cert.rb', line 105

attribute :signing_algorithm, :string

#subjectCertSubject

The certificate subject information.

Returns:



84
85
# File 'lib/ronin/db/cert.rb', line 84

belongs_to :subject, class_name: 'CertSubject',
required:   true

#subject_alt_namesArray<CertSubjectAltName>

The subjectAltNames of the certificate.

Returns:



137
138
# File 'lib/ronin/db/cert.rb', line 137

has_many :subject_alt_names, class_name: 'CertSubjectAltName',
dependent:  :destroy

#versionInteger

The certificate's version number.

Returns:

  • (Integer)


53
# File 'lib/ronin/db/cert.rb', line 53

attribute :version, :integer

Class Method Details

.activeArray<Cert>

Queries all active certificates.

Returns:

Since:

  • 0.2.0



165
166
167
168
169
# File 'lib/ronin/db/cert.rb', line 165

def self.active
  now = DateTime.now

  where(not_before: ..now, not_after: now...)
end

.expiredArray<Cert>

Queries all expired certificates.

Returns:

Since:

  • 0.2.0



176
177
178
# File 'lib/ronin/db/cert.rb', line 176

def self.expired
  where(not_after: ...Time.now)
end

.import(cert) ⇒ Cert

Imports an SSL/TLS X509 certificate into the database.

Parameters:

  • cert (OpenSSL::X509::Certificate)

    The certificate object to import.

Returns:

  • (Cert)

    The imported certificate.

Since:

  • 0.2.0



370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
# File 'lib/ronin/db/cert.rb', line 370

def self.import(cert)
  case (public_key = cert.public_key)
  when OpenSSL::PKey::RSA
    public_key_algorithm = :rsa
    public_key_size      = public_key.n.num_bits
  when OpenSSL::PKey::DSA
    public_key_algorithm = :dsa
    public_key_size      = public_key.p.num_bits
  when OpenSSL::PKey::DH
    public_key_algorithm = :dh
    public_key_size      = public_key.p.num_bits
  when OpenSSL::PKey::EC
    public_key_algorithm = :ec

    public_key_text = public_key.to_text
    public_key_size = if (match = public_key_text.match(/\((\d+) bit\)/))
                        match[1].to_i
                      end
  else
    raise(NotImplementedError,"unsupported public key type: #{public_key.inspect}")
  end

  der = cert.to_der

  create(
    serial:  cert.serial.to_s(16),
    version: cert.version,

    not_before: cert.not_before,
    not_after:  cert.not_after,

    # NOTE: set #issuer to nil if the cert is self-signed
    issuer: unless cert.issuer == cert.subject
              CertIssuer.import(cert.issuer)
            end,

    subject: CertSubject.import(cert.subject),

    public_key_algorithm: public_key_algorithm,
    public_key_size:      public_key_size,

    signing_algorithm: cert.signature_algorithm,

    sha1_fingerprint:   Digest::SHA1.hexdigest(der),
    sha256_fingerprint: Digest::SHA256.hexdigest(der),

    pem: cert.to_pem
  ) do |new_cert|
    if (subject_alt_name = cert.find_extension('subjectAltName'))
      CertSubjectAltName.parse(subject_alt_name.value).each do |name|
        new_cert.subject_alt_names.new(
          name: CertName.find_or_import(name)
        )
      end
    end
  end
end

.lookup(cert) ⇒ Cert?

Looks up the certificate.

Parameters:

  • cert (OpenSSL::X509::Certificate)

    The X509 certificate object or PEM string.

Returns:

  • (Cert, nil)

    The matching certificate.

Since:

  • 0.2.0



357
358
359
# File 'lib/ronin/db/cert.rb', line 357

def self.lookup(cert)
  find_by(sha256_fingerprint: Digest::SHA256.hexdigest(cert.to_der))
end

.with_common_name(name) ⇒ Array<Cert>

Queries all certificates with the common name (CN).

Parameters:

  • name (String)

    The common name to search for.

Returns:

Since:

  • 0.2.0



320
321
322
323
324
325
326
327
328
# File 'lib/ronin/db/cert.rb', line 320

def self.with_common_name(name)
  joins(subject: [:common_name]).where(
    subject: {
      ronin_cert_names: {
        name: name
      }
    }
  )
end

.with_country(country) ⇒ Array<Cert>

Queries all certificates with the subject country (C).

Parameters:

  • country (String)

    The two-letter country code to search for.

Returns:

Since:

  • 0.2.0



308
309
310
# File 'lib/ronin/db/cert.rb', line 308

def self.with_country(country)
  joins(:subject).where(subject: {country: country})
end

.with_issuer_common_name(name) ⇒ Array<Cert>

Queries all certificates with the issuer common name (CN).

Parameters:

  • name (String)

    The issuer common name to search for.

Returns:

Since:

  • 0.2.0



188
189
190
# File 'lib/ronin/db/cert.rb', line 188

def self.with_issuer_common_name(name)
  joins(:issuer).where(issuer: {common_name: name})
end

.with_issuer_country(country) ⇒ Array<Cert>

Queries all certificates with the issuer common name (C).

Parameters:

  • country (String)

    The issuer's two-letter country code to search for.

Returns:

Since:

  • 0.2.0



248
249
250
# File 'lib/ronin/db/cert.rb', line 248

def self.with_issuer_country(country)
  joins(:issuer).where(issuer: {country: country})
end

.with_issuer_locality(locality) ⇒ Array<Cert>

Queries all certificates with the issuer common name (L).

Parameters:

  • locality (String)

    The issuer locality to search for.

Returns:

Since:

  • 0.2.0



224
225
226
# File 'lib/ronin/db/cert.rb', line 224

def self.with_issuer_locality(locality)
  joins(:issuer).where(issuer: {locality: locality})
end

.with_issuer_organization(name) ⇒ Array<Cert>

Queries all certificates with the issuer common name (O).

Parameters:

  • name (String)

    The issuer organization to search for.

Returns:

Since:

  • 0.2.0



200
201
202
# File 'lib/ronin/db/cert.rb', line 200

def self.with_issuer_organization(name)
  joins(:issuer).where(issuer: {organization: name})
end

.with_issuer_organizational_unit(unit) ⇒ Array<Cert>

Queries all certificates with the issuer common name (OU).

Parameters:

  • unit (String)

    The issuer organizational unit name to search for.

Returns:

Since:

  • 0.2.0



212
213
214
# File 'lib/ronin/db/cert.rb', line 212

def self.with_issuer_organizational_unit(unit)
  joins(:issuer).where(issuer: {organizational_unit: unit})
end

.with_issuer_state(state) ⇒ Array<Cert>

Queries all certificates with the issuer common name (ST).

Parameters:

  • state (String)

    The issuer state name to search for.

Returns:

Since:

  • 0.2.0



236
237
238
# File 'lib/ronin/db/cert.rb', line 236

def self.with_issuer_state(state)
  joins(:issuer).where(issuer: {state: state})
end

.with_locality(locality) ⇒ Array<Cert>

Queries all certificates with the subject state (L).

Parameters:

  • locality (String)

    The locality to search for.

Returns:

Since:

  • 0.2.0



284
285
286
# File 'lib/ronin/db/cert.rb', line 284

def self.with_locality(locality)
  joins(:subject).where(subject: {locality: locality})
end

.with_organization(name) ⇒ Array<Cert>

Queries all certificates with the subject state (O).

Parameters:

  • name (String)

    The organization name to search for.

Returns:

Since:

  • 0.2.0



260
261
262
# File 'lib/ronin/db/cert.rb', line 260

def self.with_organization(name)
  joins(:subject).where(subject: {organization: name})
end

.with_organizational_unit(unit) ⇒ Array<Cert>

Queries all certificates with the subject state (OU).

Parameters:

  • unit (String)

    The organizational unit name to search for.

Returns:

Since:

  • 0.2.0



272
273
274
# File 'lib/ronin/db/cert.rb', line 272

def self.with_organizational_unit(unit)
  joins(:subject).where(subject: {organizational_unit: unit})
end

.with_state(state) ⇒ Array<Cert>

Queries all certificates with the subject state (ST).

Parameters:

  • state (String)

    The state name to search for.

Returns:

Since:

  • 0.2.0



296
297
298
# File 'lib/ronin/db/cert.rb', line 296

def self.with_state(state)
  joins(:subject).where(subject: {state: state})
end

.with_subject_alt_name(name) ⇒ Array<Cert>

Queries all certificates with the subjectAltName value.

Parameters:

  • name (String)

    The host name or IP address to query.

Returns:

Since:

  • 0.2.0



338
339
340
341
342
343
344
345
346
# File 'lib/ronin/db/cert.rb', line 338

def self.with_subject_alt_name(name)
  joins(subject_alt_names: [:name]).where(
    subject_alt_names: {
      ronin_cert_names: {
        name: name
      }
    }
  )
end

Instance Method Details

#common_nameString

The subject's common name (CN).

Returns:

  • (String)

Since:

  • 0.2.0



433
434
435
# File 'lib/ronin/db/cert.rb', line 433

def common_name
  subject.common_name
end

#countryString

The subject's country (C).

Returns:

  • (String)

Since:

  • 0.2.0



478
479
480
# File 'lib/ronin/db/cert.rb', line 478

def country
  subject.country
end

#localityString

The subject's locality (L).

Returns:

  • (String)

Since:

  • 0.2.0



460
461
462
# File 'lib/ronin/db/cert.rb', line 460

def locality
  subject.locality
end

#organizationString

The subject's organization (O).

Returns:

  • (String)

Since:

  • 0.2.0



442
443
444
# File 'lib/ronin/db/cert.rb', line 442

def organization
  subject.organization
end

#organizational_unitString

The subject's organizational unit (OU).

Returns:

  • (String)

Since:

  • 0.2.0



451
452
453
# File 'lib/ronin/db/cert.rb', line 451

def organizational_unit
  subject.organizational_unit
end

#stateString

The subject's state (ST).

Returns:

  • (String)

Since:

  • 0.2.0



469
470
471
# File 'lib/ronin/db/cert.rb', line 469

def state
  subject.state
end

#to_pemString Also known as: to_s

Converts the certificate back into PEM format.

Returns:

  • (String)

Since:

  • 0.2.0



487
488
489
# File 'lib/ronin/db/cert.rb', line 487

def to_pem
  pem
end