Class: Rex::Socket::X509Certificate

Inherits:
Object
  • Object
show all
Defined in:
lib/rex/socket/x509_certificate.rb

Overview

This class parses the contents of a PEM-encoded X509 certificate file containing a private key, a public key, and any appended glue certificates.

Class Method Summary collapse

Class Method Details

.get_cert_file_hash(ssl_cert_file) ⇒ String

Parse a file that contains a certificate in unified PEM format and retrieve the SHA1 hash.

Parameters:

  • ssl_cert_file (String)

Returns:

  • (String)


83
84
85
86
87
88
89
# File 'lib/rex/socket/x509_certificate.rb', line 83

def self.get_cert_file_hash(ssl_cert_file)
  data = ''
  ::File.open(ssl_cert_file, 'rb') do |fd|
    data << fd.read(fd.stat.size)
  end
  get_cert_hash(data)
end

.get_cert_hash(ssl_cert) ⇒ String

Parse a certificate in unified PEM format and retrieve the SHA1 hash.

Parameters:

  • ssl_cert (String)

Returns:

  • (String)


67
68
69
70
71
72
73
74
75
# File 'lib/rex/socket/x509_certificate.rb', line 67

def self.get_cert_hash(ssl_cert)
  hcert = parse_pem(ssl_cert)

  unless hcert and hcert[0] and hcert[1]
    raise ArgumentError, "Could not parse a private key and certificate"
  end

  Rex::Text.sha1_raw(hcert[1].to_der)
end

.parse_pem(ssl_cert) ⇒ String, Array

Parse a certificate in unified PEM format that contains a private key and one or more certificates. The first certificate is the primary, while any additional certificates are treated as intermediary certificates. This emulates the behavior of web servers like nginx.

Parameters:

  • ssl_cert (String)

Returns:

  • (String, String, Array)


24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/rex/socket/x509_certificate.rb', line 24

def self.parse_pem(ssl_cert)
  cert  = nil
  key   = nil
  chain = nil

  certs = []
  ssl_cert.scan(/-----BEGIN\s*[^\-]+-----+\r?\n[^\-]*-----END\s*[^\-]+-----\r?\n?/nm).each do |pem|
    if pem =~ /EC PRIVATE KEY/
      key = OpenSSL::PKey::EC.new(pem)
    elsif pem =~ /PRIVATE KEY/
      key = OpenSSL::PKey::RSA.new(pem)
    elsif pem =~ /CERTIFICATE/
      certs << OpenSSL::X509::Certificate.new(pem)
    end
  end

  cert = certs.shift
  if certs.length > 0
    chain = certs
  end

  [key, cert, chain]
end

.parse_pem_file(ssl_cert_file) ⇒ String, Array

Parse a certificate in unified PEM format from a file

Parameters:

  • ssl_cert_file (String)

Returns:

  • (String, String, Array)


53
54
55
56
57
58
59
# File 'lib/rex/socket/x509_certificate.rb', line 53

def self.parse_pem_file(ssl_cert_file)
  data = ''
  ::File.open(ssl_cert_file, 'rb') do |fd|
    data << fd.read(fd.stat.size)
  end
  parse_pem(data)
end