xmldsig 0.6.5 → 0.6.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a9796692edf2edbf8dc5b0b3e034e72c110b9632
4
- data.tar.gz: 987fa5579e92b79490237b25eb01bdea3fb9e7db
3
+ metadata.gz: df1410861d55968a7bca96a9c3ea4a3610938f91
4
+ data.tar.gz: 839b63410739fca62890f35bb03890523c192bf1
5
5
  SHA512:
6
- metadata.gz: 36cc6186cf9d51dbd483c2d64d31bd81f3c7411e53fa43be74463ca7613dd107efc679893fa9510f985230ad40289bc0fb50b73ae83d389d13e5e40482452f1e
7
- data.tar.gz: aafbdeb71da7b102eb054f6ae9db0e590ddda376cca8a85056279511d03b85a4b426a83fd1511c2cc6451a68b5d817c2665a9c89cd7c972edf1800009327dc6f
6
+ metadata.gz: f57cc44c4425d043a97d55af347f8bc9e4c89ae8352b5ff5c74b1fc44c6031ec6277775ea3eb097956d7e042c872c8ecb91b69c94d046e8c952174cd1f4dba59
7
+ data.tar.gz: a001df00e557acf52e267b4a267aa8e0ed69af44ee21a62b5e84310427024b8755efe240c90c9c15f28731ac1166a39e13b5ed28484d21938da839f737c84d2e
@@ -1,4 +1,8 @@
1
1
  # Changelog
2
+ v0.6.6
3
+ - Add support for cid references to external documents. (iterateNZ)
4
+ - Add support for http://www.w3.org/TR/1999/REC-xpath-19991116 transforms (iterateNZ)
5
+
2
6
  v0.6.5
3
7
  - Added inclusive namespace prefix list for canonicalization method (jmhooper)
4
8
 
data/README.md CHANGED
@@ -24,6 +24,9 @@ unsigned_xml = <<-XML
24
24
  <?xml version="1.0" encoding="UTF-8"?>
25
25
  <foo:Foo ID="foo" xmlns:foo="http://example.com/foo#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#">
26
26
  <foo:Bar>bar</foo:Bar>
27
+ <foo:Baz>
28
+ <foo:Qux>quuz</foo:Qux>
29
+ </foo:Baz>
27
30
  <ds:Signature>
28
31
  <ds:SignedInfo>
29
32
  <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
@@ -31,6 +34,9 @@ unsigned_xml = <<-XML
31
34
  <ds:Reference URI="#foo">
32
35
  <ds:Transforms>
33
36
  <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
37
+ <ds:Transform Algorithm="http://www.w3.org/TR/1999/REC-xpath-19991116">
38
+ <ds:XPath>not(ancestor-or-self::foo:Baz)</ds:XPath>
39
+ </ds:Transform>
34
40
  <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
35
41
  <ec:InclusiveNamespaces PrefixList="foo"/>
36
42
  </ds:Transform>
@@ -25,6 +25,7 @@ require "xmldsig/signed_document"
25
25
  require "xmldsig/transforms/transform"
26
26
  require "xmldsig/transforms/canonicalize"
27
27
  require "xmldsig/transforms/enveloped_signature"
28
+ require "xmldsig/transforms/xpath"
28
29
  require "xmldsig/transforms"
29
30
  require "xmldsig/reference"
30
31
  require "xmldsig/signature"
@@ -5,10 +5,11 @@ module Xmldsig
5
5
  class ReferencedNodeNotFound < Exception;
6
6
  end
7
7
 
8
- def initialize(reference, id_attr = nil)
8
+ def initialize(reference, id_attr = nil, referenced_documents = {})
9
9
  @reference = reference
10
10
  @errors = []
11
11
  @id_attr = id_attr
12
+ @referenced_documents = referenced_documents
12
13
  end
13
14
 
14
15
  def document
@@ -21,16 +22,28 @@ module Xmldsig
21
22
 
22
23
  def referenced_node
23
24
  if reference_uri && reference_uri != ""
24
- id = reference_uri[1..-1]
25
- referenced_node_xpath = @id_attr ? "//*[@#{@id_attr}=$uri]" : "//*[@ID=$uri or @wsu:Id=$uri]"
26
- variable_bindings = { 'uri' => id }
27
- if ref = document.dup.at_xpath(referenced_node_xpath, NAMESPACES, variable_bindings)
28
- ref
25
+ if @id_attr.nil? && reference_uri.start_with?("cid:")
26
+ content_id = reference_uri[4..-1]
27
+ if @referenced_documents.has_key?(content_id)
28
+ @referenced_documents[content_id].dup
29
+ else
30
+ raise(
31
+ ReferencedNodeNotFound,
32
+ "Could not find referenced document with ContentId #{content_id}"
33
+ )
34
+ end
29
35
  else
30
- raise(
31
- ReferencedNodeNotFound,
32
- "Could not find the referenced node #{id}'"
33
- )
36
+ id = reference_uri[1..-1]
37
+ referenced_node_xpath = @id_attr ? "//*[@#{@id_attr}=$uri]" : "//*[@ID=$uri or @wsu:Id=$uri]"
38
+ variable_bindings = { 'uri' => id }
39
+ if ref = document.dup.at_xpath(referenced_node_xpath, NAMESPACES, variable_bindings)
40
+ ref
41
+ else
42
+ raise(
43
+ ReferencedNodeNotFound,
44
+ "Could not find the referenced node #{id}'"
45
+ )
46
+ end
34
47
  end
35
48
  else
36
49
  document.dup.root
@@ -2,14 +2,15 @@ module Xmldsig
2
2
  class Signature
3
3
  attr_accessor :signature
4
4
 
5
- def initialize(signature, id_attr = nil)
5
+ def initialize(signature, id_attr = nil, referenced_documents = {})
6
6
  @signature = signature
7
7
  @id_attr = id_attr
8
+ @referenced_documents = referenced_documents
8
9
  end
9
10
 
10
11
  def references
11
12
  @references ||= signature.xpath("descendant::ds:Reference", NAMESPACES).map do |node|
12
- Reference.new(node, @id_attr)
13
+ Reference.new(node, @id_attr, @referenced_documents)
13
14
  end
14
15
  end
15
16
 
@@ -1,6 +1,6 @@
1
1
  module Xmldsig
2
2
  class SignedDocument
3
- attr_accessor :document, :id_attr, :force
3
+ attr_accessor :document, :id_attr, :force, :referenced_documents
4
4
 
5
5
  def initialize(document, options = {})
6
6
  @document = if document.kind_of?(Nokogiri::XML::Document)
@@ -10,6 +10,7 @@ module Xmldsig
10
10
  end
11
11
  @id_attr = options[:id_attr] if options[:id_attr]
12
12
  @force = options[:force]
13
+ @referenced_documents = options.fetch(:referenced_documents, {})
13
14
  end
14
15
 
15
16
  def validate(certificate = nil, schema = nil, &block)
@@ -35,7 +36,7 @@ module Xmldsig
35
36
  def signatures
36
37
  document.xpath("//ds:Signature", NAMESPACES).
37
38
  sort { |left, right| left.ancestors.size <=> right.ancestors.size }.
38
- collect { |node| Signature.new(node, @id_attr) } || []
39
+ collect { |node| Signature.new(node, @id_attr, referenced_documents) } || []
39
40
  end
40
41
  end
41
42
  end
@@ -21,6 +21,8 @@ module Xmldsig
21
21
  Transforms::Canonicalize.new(node, transform_node)
22
22
  when "http://www.w3.org/2001/10/xml-exc-c14n#WithComments"
23
23
  Transforms::Canonicalize.new(node, transform_node, true)
24
+ when "http://www.w3.org/TR/1999/REC-xpath-19991116"
25
+ Transforms::XPath.new(node, transform_node)
24
26
  end
25
27
  end
26
28
 
@@ -0,0 +1,22 @@
1
+ module Xmldsig
2
+ class Transforms < Array
3
+ class XPath < Transform
4
+ attr_reader :xpath_query
5
+
6
+ REC_XPATH_1991116_QUERY = "(//. | //@* | //namespace::*)"
7
+
8
+ def initialize(node, transform_node)
9
+ @xpath_query = transform_node.at_xpath("ds:XPath", NAMESPACES).text
10
+ super(node, transform_node)
11
+ end
12
+
13
+ def transform
14
+ node.xpath(REC_XPATH_1991116_QUERY)
15
+ .reject { |n| !n.respond_to?(:xpath) }
16
+ .reject { |n| n.xpath(@xpath_query, node.namespaces) }
17
+ .each(&:remove)
18
+ node
19
+ end
20
+ end
21
+ end
22
+ end
@@ -1,3 +1,3 @@
1
1
  module Xmldsig
2
- VERSION = '0.6.5'
2
+ VERSION = '0.6.6'
3
3
  end
@@ -0,0 +1,15 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <foo:Foo xmlns:foo="http://example.com/foo#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" ID="foo">
3
+ <foo:Bar>bar</foo:Bar>
4
+ <ds:Signature>
5
+ <ds:SignedInfo>
6
+ <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
7
+ <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
8
+ <ds:Reference URI="cid:fooDocument">
9
+ <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
10
+ <ds:DigestValue>tdQEXD9Gb6kf4sxqvnkjKhpXzfEE96JucW4KHieJ33g=</ds:DigestValue>
11
+ </ds:Reference>
12
+ </ds:SignedInfo>
13
+ <ds:SignatureValue>JI5XLfznf8BsNA5vtm0kPG5kni983qrJV1EFx4oZnb6tPvARvPbtR1oEaxnB5ROQJ6xzBuuxDsUFT1BNNUR8vL1S2qPk80USXwNhl0Cfa4mDULNw1rRhN6q82VEvAC/Hb32mvgKDLlJZymdafZhUUeEmaQj+YHsTU54kPCY5w+E=</ds:SignatureValue>
14
+ </ds:Signature>
15
+ </foo:Foo>
@@ -0,0 +1,35 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
3
+ <soapenv:Body>
4
+ <samlp:ArtifactResponse xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" ID="_91e79cb2e8cded9a7fd4d68dc480b49d2d1adf88" Version="2.0" IssueInstant="2013-01-17T09:02:44Z">
5
+ <ds:Signature>
6
+ <ds:SignedInfo>
7
+ <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
8
+ <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
9
+ <ds:Reference>
10
+ <ds:Transforms>
11
+ <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
12
+ <ds:Transform Algorithm="http://www.w3.org/TR/1999/REC-xpath-19991116">
13
+ <ds:XPath>not(ancestor-or-self::samlp:Status)</ds:XPath>
14
+ </ds:Transform>
15
+ <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
16
+ <ec:InclusiveNamespaces PrefixList="ds saml samlp xs"/>
17
+ </ds:Transform>
18
+ </ds:Transforms>
19
+ <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
20
+ <ds:DigestValue></ds:DigestValue>
21
+ </ds:Reference>
22
+ </ds:SignedInfo>
23
+ <ds:SignatureValue></ds:SignatureValue>
24
+ </ds:Signature>
25
+ <samlp:Status>
26
+ <samlp:StatusCode/>
27
+ </samlp:Status>
28
+ <samlp:Response ID="_5a88b4aeb1d290c86073874278e5ef302da66739" Version="2.0" IssueInstant="2013-01-17T09:02:44Z">
29
+ <samlp:Status>
30
+ <samlp:StatusCode/>
31
+ </samlp:Status>
32
+ </samlp:Response>
33
+ </samlp:ArtifactResponse>
34
+ </soapenv:Body>
35
+ </soapenv:Envelope>
@@ -0,0 +1,15 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <foo:Foo xmlns:foo="http://example.com/foo#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" ID="foo">
3
+ <foo:Bar>bar</foo:Bar>
4
+ <ds:Signature>
5
+ <ds:SignedInfo>
6
+ <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
7
+ <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
8
+ <ds:Reference URI="cid:fooDocument">
9
+ <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
10
+ <ds:DigestValue></ds:DigestValue>
11
+ </ds:Reference>
12
+ </ds:SignedInfo>
13
+ <ds:SignatureValue></ds:SignatureValue>
14
+ </ds:Signature>
15
+ </foo:Foo>
@@ -78,6 +78,30 @@ describe Xmldsig::Reference do
78
78
  expect { malicious_reference.referenced_node }.
79
79
  to raise_error(Xmldsig::Reference::ReferencedNodeNotFound)
80
80
  end
81
+
82
+ context "when the referenced node is prefixed with 'cid:'" do
83
+ let(:document) { Nokogiri::XML::Document.parse File.read("spec/fixtures/unsigned_with_cid_reference.xml") }
84
+ let(:foo_document) { "<test><ing>present</ing></test>" }
85
+ let(:referenced_documents) { { "fooDocument" => foo_document } }
86
+ let(:reference) { Xmldsig::Reference.new(document.at_xpath('//ds:Reference', Xmldsig::NAMESPACES), nil, referenced_documents) }
87
+
88
+ it "has the correct reference_uri" do
89
+ expect(reference.reference_uri).to eq "cid:fooDocument"
90
+ end
91
+
92
+ it "returns the document referenced by the content id" do
93
+ expect(reference.referenced_node).to eq foo_document
94
+ end
95
+
96
+ context "when the document has no referenced_documents matching the referenced name" do
97
+ let(:referenced_documents) { Hash.new }
98
+
99
+ it "raises ReferencedNodeNotFound" do
100
+ expect { reference.referenced_node }.
101
+ to raise_error(Xmldsig::Reference::ReferencedNodeNotFound)
102
+ end
103
+ end
104
+ end
81
105
  end
82
106
 
83
107
  describe "#reference_uri" do
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe Xmldsig::Transforms::XPath do
4
+ let(:expected_xpath_query) { "not(ancestor-or-self::samlp:Status)" }
5
+ let(:unsigned_xml) { File.read('spec/fixtures/unsigned/with_xpath_algorithm.xml') }
6
+ let(:unsigned_document) { Xmldsig::SignedDocument.new(unsigned_xml) }
7
+ let(:transform_node) { unsigned_document.signatures.first.references.first.transforms[1] }
8
+ subject(:xpath_transform) { described_class.new(unsigned_document.document, transform_node) }
9
+
10
+ it 'reads the xpath' do
11
+ expect(xpath_transform.xpath_query).to eq expected_xpath_query
12
+ end
13
+
14
+ it 'filters out the nodes matching the xpath expression' do
15
+ transformed_node = xpath_transform.transform
16
+ expect(transform_node.children).to all(satisfy { |n| n.xpath(expected_xpath_query, unsigned_document.document.namespaces) })
17
+ end
18
+ end
@@ -81,4 +81,31 @@ describe Xmldsig do
81
81
  end
82
82
  end
83
83
  end
84
+
85
+ describe "Allows passing referenced documents" do
86
+ let(:referenced_documents) { { 'fooDocument' => 'ABC' } }
87
+
88
+ describe "an unsigned document" do
89
+ let(:unsigned_xml) { File.read("spec/fixtures/unsigned_with_cid_reference.xml") }
90
+ let(:unsigned_document) { Xmldsig::SignedDocument.new(unsigned_xml, referenced_documents: referenced_documents) }
91
+ let(:signed_document) { unsigned_document.sign(private_key) }
92
+
93
+ it "should be signable an validateable" do
94
+ expect(Xmldsig::SignedDocument.new(signed_document, referenced_documents: referenced_documents).validate(certificate)).to eq(true)
95
+ end
96
+
97
+ it 'should have at least 1 signature element' do
98
+ expect(Xmldsig::SignedDocument.new(signed_document).signatures.count).to be >= 1
99
+ end
100
+ end
101
+
102
+ context "a signed document" do
103
+ let(:signed_xml) { File.read("spec/fixtures/signed_with_cid_reference.xml") }
104
+ let(:signed_document) { Xmldsig::SignedDocument.new(signed_xml, referenced_documents: referenced_documents) }
105
+
106
+ it "should be validateable" do
107
+ expect(signed_document.validate(certificate)).to eq(true)
108
+ end
109
+ end
110
+ end
84
111
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xmldsig
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.5
4
+ version: 0.6.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - benoist
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-11-30 00:00:00.000000000 Z
11
+ date: 2018-03-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -55,6 +55,7 @@ files:
55
55
  - lib/xmldsig/transforms/canonicalize.rb
56
56
  - lib/xmldsig/transforms/enveloped_signature.rb
57
57
  - lib/xmldsig/transforms/transform.rb
58
+ - lib/xmldsig/transforms/xpath.rb
58
59
  - lib/xmldsig/version.rb
59
60
  - lib/xmldsig/xmldsig-core-schema-x509-serial-fix.xsd
60
61
  - lib/xmldsig/xmldsig-core-schema.xsd
@@ -70,6 +71,7 @@ files:
70
71
  - spec/fixtures/signed/shib.xml
71
72
  - spec/fixtures/signed_custom_attribute_id.xml
72
73
  - spec/fixtures/signed_signature_namespace.xml
74
+ - spec/fixtures/signed_with_cid_reference.xml
73
75
  - spec/fixtures/signed_xml-exc-c14n#with_comments.xml
74
76
  - spec/fixtures/unsigned-invalid.xml
75
77
  - spec/fixtures/unsigned-malicious.xml
@@ -87,6 +89,7 @@ files:
87
89
  - spec/fixtures/unsigned/unsigned_nested_signature_at_bottom.xml
88
90
  - spec/fixtures/unsigned/unsigned_nested_signature_at_top.xml
89
91
  - spec/fixtures/unsigned/with_soap_envelope.xml
92
+ - spec/fixtures/unsigned/with_xpath_algorithm.xml
90
93
  - spec/fixtures/unsigned/without_canonicalization.xml
91
94
  - spec/fixtures/unsigned/without_namespace_prefix.xml
92
95
  - spec/fixtures/unsigned/without_reference_uri.xml
@@ -95,11 +98,13 @@ files:
95
98
  - spec/fixtures/unsigned_nested_signature.xml
96
99
  - spec/fixtures/unsigned_nested_signed_signature.xml
97
100
  - spec/fixtures/unsigned_signature_namespace.xml
101
+ - spec/fixtures/unsigned_with_cid_reference.xml
98
102
  - spec/lib/xmldsig/reference_spec.rb
99
103
  - spec/lib/xmldsig/signature_spec.rb
100
104
  - spec/lib/xmldsig/signed_document_spec.rb
101
105
  - spec/lib/xmldsig/transforms/enveloped_signature_spec.rb
102
106
  - spec/lib/xmldsig/transforms/transform_spec.rb
107
+ - spec/lib/xmldsig/transforms/xpath_spec.rb
103
108
  - spec/lib/xmldsig_spec.rb
104
109
  - spec/spec_helper.rb
105
110
  - xmldsig.gemspec
@@ -139,6 +144,7 @@ test_files:
139
144
  - spec/fixtures/signed/shib.xml
140
145
  - spec/fixtures/signed_custom_attribute_id.xml
141
146
  - spec/fixtures/signed_signature_namespace.xml
147
+ - spec/fixtures/signed_with_cid_reference.xml
142
148
  - spec/fixtures/signed_xml-exc-c14n#with_comments.xml
143
149
  - spec/fixtures/unsigned-invalid.xml
144
150
  - spec/fixtures/unsigned-malicious.xml
@@ -156,6 +162,7 @@ test_files:
156
162
  - spec/fixtures/unsigned/unsigned_nested_signature_at_bottom.xml
157
163
  - spec/fixtures/unsigned/unsigned_nested_signature_at_top.xml
158
164
  - spec/fixtures/unsigned/with_soap_envelope.xml
165
+ - spec/fixtures/unsigned/with_xpath_algorithm.xml
159
166
  - spec/fixtures/unsigned/without_canonicalization.xml
160
167
  - spec/fixtures/unsigned/without_namespace_prefix.xml
161
168
  - spec/fixtures/unsigned/without_reference_uri.xml
@@ -164,10 +171,12 @@ test_files:
164
171
  - spec/fixtures/unsigned_nested_signature.xml
165
172
  - spec/fixtures/unsigned_nested_signed_signature.xml
166
173
  - spec/fixtures/unsigned_signature_namespace.xml
174
+ - spec/fixtures/unsigned_with_cid_reference.xml
167
175
  - spec/lib/xmldsig/reference_spec.rb
168
176
  - spec/lib/xmldsig/signature_spec.rb
169
177
  - spec/lib/xmldsig/signed_document_spec.rb
170
178
  - spec/lib/xmldsig/transforms/enveloped_signature_spec.rb
171
179
  - spec/lib/xmldsig/transforms/transform_spec.rb
180
+ - spec/lib/xmldsig/transforms/xpath_spec.rb
172
181
  - spec/lib/xmldsig_spec.rb
173
182
  - spec/spec_helper.rb