Module: SAML2::Signable
- Included in:
- Entity, Entity::Group, Message, Role
- Defined in:
- lib/saml2/signable.rb
Instance Method Summary collapse
-
#sign(x509_certificate, private_key, algorithm_name = :sha256) ⇒ self
Sign this object.
- #signature ⇒ Nokogiri::XML::Element?
- #signed? ⇒ Boolean
- #signing_key ⇒ KeyInfo?
-
#valid_signature?(fingerprint: nil, cert: nil) ⇒ Boolean
Check if the signature on this object is valid.
-
#validate_signature(key: nil, fingerprint: nil, cert: nil) ⇒ Array<String>
Validate the signature on this object.
Instance Method Details
#sign(x509_certificate, private_key, algorithm_name = :sha256) ⇒ self
Sign this object.
103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/saml2/signable.rb', line 103 def sign(x509_certificate, private_key, algorithm_name = :sha256) to_xml xml = @document.root xml.set_id_attribute('ID') xml.sign!(cert: x509_certificate, key: private_key, digest_alg: algorithm_name.to_s, signature_alg: "rsa-#{algorithm_name}", uri: "##{id}") # the Signature element must be the first element signature = xml.at_xpath("dsig:Signature", Namespaces::ALL) xml.children.first.add_previous_sibling(signature) self end |
#signature ⇒ Nokogiri::XML::Element?
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# File 'lib/saml2/signable.rb', line 8 def signature unless instance_variable_defined?(:@signature) @signature = xml.at_xpath('dsig:Signature', Namespaces::ALL) if @signature signed_node = @signature.at_xpath('dsig:SignedInfo/dsig:Reference', Namespaces::ALL)['URI'] if signed_node == '' @signature = nil unless xml == xml.document.root elsif signed_node != "##{xml['ID']}" @signature = nil else # validating the schema will automatically add ID attributes, so check that first xml.set_id_attribute('ID') unless xml.document.get_id(xml['ID']) end end end @signature end |
#signed? ⇒ Boolean
31 32 33 |
# File 'lib/saml2/signable.rb', line 31 def signed? !!signature end |
#signing_key ⇒ KeyInfo?
27 28 29 |
# File 'lib/saml2/signable.rb', line 27 def signing_key @signing_key ||= KeyInfo.from_xml(signature) end |
#valid_signature?(fingerprint: nil, cert: nil) ⇒ Boolean
Check if the signature on this object is valid.
Either fingerprint
or cert
must be provided.
90 91 92 |
# File 'lib/saml2/signable.rb', line 90 def valid_signature?(fingerprint: nil, cert: nil) validate_signature(fingerprint: fingerprint, cert: cert).empty? end |
#validate_signature(key: nil, fingerprint: nil, cert: nil) ⇒ Array<String>
Validate the signature on this object.
At least one of key
, fingerprint
or cert
must be provided.
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/saml2/signable.rb', line 52 def validate_signature(key: nil, fingerprint: nil, cert: nil) return ["not signed"] unless signed? certs = Array(cert) certs = certs.dup if certs.equal?(cert) # see if any given fingerprints match the certificate embedded in the XML; # if so, extract the certificate, and add it to the allowed certificates list Array(fingerprint).each do |fp| certs << signing_key.certificate if signing_key&.fingerprint == SAML2::KeyInfo.format_fingerprint(fp) end certs = certs.uniq trusted_keys = certs.map do |cert| cert = cert.is_a?(String) ? OpenSSL::X509::Certificate.new(cert) : cert cert.public_key.to_s end if signing_key&.certificate && trusted_keys.include?(signing_key.certificate.public_key.to_s) key ||= signing_key.certificate.public_key.to_s end return ["no trusted signing key found"] if key.nil? begin result = signature.verify_with(key: key) result ? [] : ["signature is invalid"] rescue XMLSec::VerificationError => e [e.] end end |