class SAML2::KeyInfo

This represents the XML Signatures <KeyInfo> element, and actually contains a reference to an X.509 certificate, not solely a public key.

Attributes

key[RW]

@return [OpenSSL::PKey::PKey] An RSA Public Key

x509[R]

@return [String] The PEM encoded certificate.

Public Class Methods

format_fingerprint(fingerprint) click to toggle source

Formats a fingerprint as all lowercase, with a : every two characters, stripping all non-hexadecimal characters. @param fingerprint [String] @return [String]

# File lib/saml2/key.rb, line 57
def self.format_fingerprint(fingerprint)
  fingerprint.downcase.gsub(/[^0-9a-f]/, "").gsub(/(\h{2})(?=\h)/, '\1:')
end
new(x509 = nil) click to toggle source

@param x509 [String] The PEM encoded certificate.

Calls superclass method SAML2::Base::new
# File lib/saml2/key.rb, line 18
def initialize(x509 = nil)
  super()
  self.x509 = x509
end

Public Instance Methods

build(builder) click to toggle source

(see Base#build)

# File lib/saml2/key.rb, line 69
def build(builder)
  builder["dsig"].KeyInfo do |key_info|
    if x509
      key_info["dsig"].X509Data do |x509_data|
        x509_data["dsig"].X509Certificate(x509)
      end
    end
    if key.is_a?(OpenSSL::PKey::RSA)
      key_info["dsig"].KeyValue do |key_value|
        key_value["dsig"].RSAKeyValue do |rsa_key_value|
          rsa_key_value["dsig"].Modulus(Base64.encode64(key.n.to_s(2)))
          rsa_key_value["dsig"].Exponent(Base64.encode64(key.e.to_s(2)))
        end
      end
    end
  end
end
certificate() click to toggle source

@return [OpenSSL::X509::Certificate]

# File lib/saml2/key.rb, line 42
def certificate
  return nil if x509.nil?

  @certificate ||= OpenSSL::X509::Certificate.new(Base64.decode64(x509))
end
fingerprint() click to toggle source

@return [String]

# File lib/saml2/key.rb, line 62
def fingerprint
  return nil unless certificate

  @fingerprint ||= self.class.format_fingerprint(Digest::SHA1.hexdigest(certificate.to_der))
end
from_xml(node) click to toggle source

(see Base#from_xml)

# File lib/saml2/key.rb, line 24
def from_xml(node)
  self.x509 = node.at_xpath("dsig:X509Data/dsig:X509Certificate", Namespaces::ALL)&.content&.strip
  return unless (rsa_key_value = node.at_xpath("dsig:KeyValue/dsig:RSAKeyValue", Namespaces::ALL))

  modulus = crypto_binary_to_integer(rsa_key_value.at_xpath("dsig:Modulus", Namespaces::ALL)&.content&.strip)
  exponent = crypto_binary_to_integer(rsa_key_value.at_xpath("dsig:Exponent", Namespaces::ALL)&.content&.strip)
  return unless modulus && exponent

  @key = OpenSSL::PKey::RSA.new(
    OpenSSL::ASN1::Sequence([OpenSSL::ASN1::Integer(modulus), OpenSSL::ASN1::Integer(exponent)]).to_der
  )
end
public_key() click to toggle source

@return [OpenSSL::PKey::PKey]

# File lib/saml2/key.rb, line 49
def public_key
  key || certificate&.public_key
end
x509=(value) click to toggle source
# File lib/saml2/key.rb, line 37
def x509=(value)
  @x509 = value&.gsub(/\w*-+(BEGIN|END) CERTIFICATE-+\w*/, "")&.strip
end

Private Instance Methods

crypto_binary_to_integer(str) click to toggle source
# File lib/saml2/key.rb, line 89
def crypto_binary_to_integer(str)
  return nil unless str

  OpenSSL::BN.new(Base64.decode64(str), 2)
end