diff --git a/lib/xmldsig/reference.rb b/lib/xmldsig/reference.rb index 739137c..945ebe2 100644 --- a/lib/xmldsig/reference.rb +++ b/lib/xmldsig/reference.rb @@ -24,14 +24,9 @@ def referenced_node if reference_uri && reference_uri != "" if @id_attr.nil? && reference_uri.start_with?("cid:") content_id = reference_uri[4..-1] - if @referenced_documents.has_key?(content_id) - @referenced_documents[content_id].dup - else - raise( - ReferencedNodeNotFound, - "Could not find referenced document with ContentId #{content_id}" - ) - end + get_node_by_referenced_documents!(@referenced_documents, content_id) + elsif !File.extname(reference_uri).gsub('.', '').empty? + get_node_by_referenced_documents!(@referenced_documents, reference_uri) else id = reference_uri[1..-1] referenced_node_xpath = @id_attr ? "//*[@#{@id_attr}=$uri]" : "//*[@ID=$uri or @wsu:Id=$uri]" @@ -96,5 +91,18 @@ def validate_digest_value @errors << :digest_value end end + + private + + def get_node_by_referenced_documents!(referenced_documents, content_id) + if referenced_documents.has_key?(content_id) + referenced_documents[content_id].dup + else + raise( + ReferencedNodeNotFound, + "Could not find referenced document with ContentId #{content_id}" + ) + end + end end end diff --git a/spec/fixtures/unsigned_with_xml_reference.xml b/spec/fixtures/unsigned_with_xml_reference.xml new file mode 100644 index 0000000..b5e0e7c --- /dev/null +++ b/spec/fixtures/unsigned_with_xml_reference.xml @@ -0,0 +1,15 @@ + + + bar + + + + + + + + + + + + diff --git a/spec/lib/xmldsig/reference_spec.rb b/spec/lib/xmldsig/reference_spec.rb index 54994ec..fe4d7f1 100644 --- a/spec/lib/xmldsig/reference_spec.rb +++ b/spec/lib/xmldsig/reference_spec.rb @@ -102,6 +102,30 @@ end end end + + context "when the referenced node is file name" do + let(:document) { Nokogiri::XML::Document.parse File.read("spec/fixtures/unsigned_with_xml_reference.xml") } + let(:xml_document) { "present" } + let(:referenced_documents) { { "test.xml" => xml_document } } + let(:reference) { Xmldsig::Reference.new(document.at_xpath('//ds:Reference', Xmldsig::NAMESPACES), nil, referenced_documents) } + + it "has the correct reference_uri" do + expect(reference.reference_uri).to eq "test.xml" + end + + it "returns the document referenced by file name" do + expect(reference.referenced_node).to eq xml_document + end + + context "when the document has no referenced_documents matching the referenced name" do + let(:referenced_documents) { Hash.new } + + it "raises ReferencedNodeNotFound" do + expect { reference.referenced_node }. + to raise_error(Xmldsig::Reference::ReferencedNodeNotFound) + end + end + end end describe "#reference_uri" do