Commit fcd5607

mo <mo@mokhan.ca>
2018-02-14 23:04:52
check if a signature is present.
1 parent 98f414e
Changed files (2)
lib
spec
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