Class: Rails::Auth::X509::Certificate

Inherits:
Object
  • Object
show all
Defined in:
lib/rails/auth/x509/certificate.rb

Overview

X.509 client certificates obtained from HTTP requests

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(certificate) ⇒ Certificate

Returns a new instance of Certificate.



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/rails/auth/x509/certificate.rb', line 10

def initialize(certificate)
  unless certificate.is_a?(OpenSSL::X509::Certificate)
    raise TypeError, "expecting OpenSSL::X509::Certificate, got #{certificate.class}"
  end

  @certificate = certificate.freeze
  @subject = {}

  @certificate.subject.to_a.each do |name, data, _type|
    @subject[name.freeze] = data.freeze
  end
  @subject_alt_names = SubjectAltNameExtension.new(certificate)
  @subject_alt_names.freeze
  @subject.freeze
end

Instance Attribute Details

#certificateObject (readonly)

Returns the value of attribute certificate.



8
9
10
# File 'lib/rails/auth/x509/certificate.rb', line 8

def certificate
  @certificate
end

Instance Method Details

#==(other) ⇒ Object Also known as: eql?

Compare ourself to another object by ensuring that it has the same type and that its certificate pem is the same as ours



81
82
83
# File 'lib/rails/auth/x509/certificate.rb', line 81

def ==(other)
  other.is_a?(self.class) && other.certificate.to_der == certificate.to_der
end

#[](component) ⇒ Object



26
27
28
# File 'lib/rails/auth/x509/certificate.rb', line 26

def [](component)
  @subject[component.to_s.upcase]
end

#attributesHash

Generates inspectable attributes for debugging

Returns:

  • (Hash)

    hash containing parts of the certificate subject (cn, ou) and subject alternative name extension (uris, dns_names) as well as SPIFFE ID (spiffe_id), which is just a convenience since those are already included in the uris



68
69
70
71
72
73
74
75
76
77
# File 'lib/rails/auth/x509/certificate.rb', line 68

def attributes
  {
    cn: cn,
    dns_names: dns_names,
    ips: ips,
    ou: ou,
    spiffe_id: spiffe_id,
    uris: uris
  }.reject { |_, v| v.nil? || v.empty? }
end

#cnObject Also known as: common_name



30
31
32
# File 'lib/rails/auth/x509/certificate.rb', line 30

def cn
  @subject["CN"]
end

#dns_namesObject



35
36
37
# File 'lib/rails/auth/x509/certificate.rb', line 35

def dns_names
  @subject_alt_names.dns_names
end

#ipsObject



39
40
41
# File 'lib/rails/auth/x509/certificate.rb', line 39

def ips
  @subject_alt_names.ips
end

#ouObject Also known as: organizational_unit



43
44
45
# File 'lib/rails/auth/x509/certificate.rb', line 43

def ou
  @subject["OU"]
end

#spiffe_idString?

According to the SPIFFE standard only one SPIFFE ID can exist in the URI SAN: (github.com/spiffe/spiffe/blob/master/standards/X509-SVID.md#2-spiffe-id)

Returns:

  • (String, nil)

    string containing SPIFFE ID if one is present in the certificate



58
59
60
# File 'lib/rails/auth/x509/certificate.rb', line 58

def spiffe_id
  uris.detect { |uri| uri.start_with?("spiffe://") }
end

#urisObject



48
49
50
# File 'lib/rails/auth/x509/certificate.rb', line 48

def uris
  @subject_alt_names.uris
end