Commit fcd5607
Changed files (2)
lib
saml
kit
spec
saml
lib/saml/kit/signature.rb
@@ -4,7 +4,7 @@ module Saml
include ActiveModel::Validations
validate :validate_signature
- #validate :validate_certificate
+ validate :validate_certificate
def initialize(xml_hash)
if xml_hash.is_a?(Hash)
@@ -16,8 +16,14 @@ module Saml
# Returns the embedded X509 Certificate
def certificate
- item = @document.at_xpath("//ds:KeyInfo/ds:X509Data/ds:X509Certificate", "ds": ::Xml::Kit::Namespaces::XMLDSIG)
- ::Xml::Kit::Certificate.new(item.text, use: :signing)
+ if @document
+ item = @document.at_xpath("//ds:KeyInfo/ds:X509Data/ds:X509Certificate", "ds": ::Xml::Kit::Namespaces::XMLDSIG)
+ ::Xml::Kit::Certificate.new(item.text, use: :signing)
+ else
+ value = to_h.fetch('KeyInfo', {}).fetch('X509Data', {}).fetch('X509Certificate', nil)
+ return if value.nil?
+ ::Xml::Kit::Certificate.new(value, use: :signing)
+ end
end
# Returns true when the fingerprint of the certificate matches one of the certificates registered in the metadata.
@@ -34,6 +40,8 @@ module Saml
private
def validate_signature
+ return errors[:base].push("is missing") if certificate.nil?
+
signature = Xmldsig::Signature.new(@document, 'ID=$uri or @Id')
unless signature.valid?(certificate.x509)
signature.errors.each { |error| errors.add(error, "is invalid") }
@@ -41,7 +49,7 @@ module Saml
end
def validate_certificate(now = Time.current)
- if certificate.expired?(now)
+ if certificate.present? && certificate.expired?(now)
error_message = "Not valid before #{certificate.not_before}. Not valid after #{certificate.not_after}."
errors.add(:certificate, error_message)
end
spec/saml/signature_spec.rb
@@ -10,7 +10,7 @@ RSpec.describe Saml::Kit::Signature do
expect(subject).to be_valid
end
- xit 'is invalid when the xml has been tampered' do
+ it 'is invalid when the xml has been tampered' do
signed_document = Saml::Kit::AuthenticationRequest.build do |x|
x.sign_with(key_pair)
end
@@ -18,5 +18,12 @@ RSpec.describe Saml::Kit::Signature do
subject = described_class.new(Hash.from_xml(tampered_xml))
expect(subject).to_not be_valid
end
+
+ it 'is invalid when the signature is missing' do
+ unsigned_document = Saml::Kit::AuthenticationRequest.build
+ subject = described_class.new(Hash.from_xml(unsigned_document.to_xml))
+ expect(subject).to_not be_valid
+ expect(subject.errors[:base]).to be_present
+ end
end
end