xmldsig 0.2.6 → 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 96f6cce84663869fcc116f7468d838596f071814
4
- data.tar.gz: 4d4c59ff3419b6f450b804a3d7ae00c02a4d7c3e
3
+ metadata.gz: d8048f4065afca9b20df461f7731e4e40616efd1
4
+ data.tar.gz: 57000ef34e2df31dbe91635b81fe5456928b4095
5
5
  SHA512:
6
- metadata.gz: 47df30bf57027840f070b89c7008c0532f5461fb021da00671d149c7e9e4b519c1df39f5d92b574b4addf627ba9a9800dc340a4d417f64359c08c2a1ca60b982
7
- data.tar.gz: 33f8d0eaf16ba7cdd032e9f1c2916e38d1d70b1c32fe9722868cf45bd53b7d6663da55361ee294a9dba5517a9ef8398f270f1bc4c44bbe58242cf47cbd5abb2b
6
+ metadata.gz: 62153a54678fbfe19b71b05211bc8bcb488ce382934868c9c08000fe49793e87871c18cf49f5b5dee5c85bc87c4f4c350fed0dcb5030ed960b0573f28f7262e2
7
+ data.tar.gz: 9655ca3667ca5011b492a2b858c7c7f9ae3254b433b498e38cbaccca66fa46995c0a1e2844de7c0481b2c7c2e00c2cf7969e28cf35924d19b208ffaa2326ee58
@@ -1,13 +1,14 @@
1
1
  module Xmldsig
2
2
  class Reference
3
- attr_accessor :reference, :errors
3
+ attr_accessor :reference, :errors, :id_attr
4
4
 
5
5
  class ReferencedNodeNotFound < Exception;
6
6
  end
7
7
 
8
- def initialize(reference)
8
+ def initialize(reference, id_attr = nil)
9
9
  @reference = reference
10
10
  @errors = []
11
+ @id_attr = id_attr
11
12
  end
12
13
 
13
14
  def document
@@ -21,7 +22,8 @@ module Xmldsig
21
22
  def referenced_node
22
23
  if reference_uri && reference_uri != ""
23
24
  id = reference_uri[1..-1]
24
- if ref = document.dup.at_xpath("//*[@ID='#{id}' or @wsu:Id='#{id}']", NAMESPACES)
25
+ referenced_node_xpath = @id_attr ? "//*[@#{@id_attr}='#{id}']" : "//*[@ID='#{id}' or @wsu:Id='#{id}']"
26
+ if ref = document.dup.at_xpath(referenced_node_xpath, NAMESPACES)
25
27
  ref
26
28
  else
27
29
  raise(
@@ -2,13 +2,14 @@ module Xmldsig
2
2
  class Signature
3
3
  attr_accessor :signature
4
4
 
5
- def initialize(signature)
5
+ def initialize(signature, id_attr = nil)
6
6
  @signature = signature
7
+ @id_attr = id_attr
7
8
  end
8
9
 
9
10
  def references
10
11
  @references ||= signature.xpath("descendant::ds:Reference", NAMESPACES).map do |node|
11
- Reference.new(node)
12
+ Reference.new(node, @id_attr)
12
13
  end
13
14
  end
14
15
 
@@ -17,7 +18,7 @@ module Xmldsig
17
18
  end
18
19
 
19
20
  def sign(private_key = nil, &block)
20
- references.each(&:sign)
21
+ references.each { |reference| reference.sign }
21
22
  self.signature_value = calculate_signature_value(private_key, &block)
22
23
  end
23
24
 
@@ -1,6 +1,6 @@
1
1
  module Xmldsig
2
2
  class SignedDocument
3
- attr_accessor :document
3
+ attr_accessor :document, :id_attr
4
4
 
5
5
  def initialize(document, options = {})
6
6
  @document = if document.kind_of?(Nokogiri::XML::Document)
@@ -8,6 +8,7 @@ module Xmldsig
8
8
  else
9
9
  Nokogiri::XML(document, nil, nil, Nokogiri::XML::ParseOptions::STRICT)
10
10
  end
11
+ @id_attr = options[:id_attr] if options[:id_attr]
11
12
  end
12
13
 
13
14
  def validate(certificate = nil, &block)
@@ -24,7 +25,7 @@ module Xmldsig
24
25
  end
25
26
 
26
27
  def signatures
27
- document.xpath("//ds:Signature", NAMESPACES).reverse.collect { |node| Signature.new(node) } || []
28
+ document.xpath("//ds:Signature", NAMESPACES).reverse.collect { |node| Signature.new(node, @id_attr) } || []
28
29
  end
29
30
  end
30
31
  end
@@ -1,3 +1,3 @@
1
1
  module Xmldsig
2
- VERSION = '0.2.6'
2
+ VERSION = '0.2.7'
3
3
  end
@@ -0,0 +1,23 @@
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#" MyID="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/2000/09/xmldsig#rsa-sha1"/>
8
+ <ds:Reference URI="#foo">
9
+ <ds:Transforms>
10
+ <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
11
+ <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
12
+ <ec:InclusiveNamespaces PrefixList="foo"/>
13
+ </ds:Transform>
14
+ </ds:Transforms>
15
+ <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
16
+ <ds:DigestValue>/GxRLc5AEfTmGlQFGC++jLfhJNE=</ds:DigestValue>
17
+ </ds:Reference>
18
+ </ds:SignedInfo>
19
+ <ds:SignatureValue>QRr9nX1iGo0OwKsxOMsvoMQ8oWtl5NS9w8JzF3/+DcbLU1oNriaNKM7HixPH
20
+ TQyyPgwn1Ysvyf0twWhiZ7TnPQ71EFcJFKCexGGC6SaChSIIJjnVukmUC6Le
21
+ NdazERYV+QZZV5pmq5EfgW3RfDOinBXsMRuTDR8y1iG6K1gMKws=</ds:SignatureValue>
22
+ </ds:Signature>
23
+ </foo:Foo>
@@ -0,0 +1,21 @@
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#" MyID="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/2000/09/xmldsig#rsa-sha1"/>
8
+ <ds:Reference URI="#foo">
9
+ <ds:Transforms>
10
+ <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
11
+ <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
12
+ <ec:InclusiveNamespaces PrefixList="foo"/>
13
+ </ds:Transform>
14
+ </ds:Transforms>
15
+ <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
16
+ <ds:DigestValue></ds:DigestValue>
17
+ </ds:Reference>
18
+ </ds:SignedInfo>
19
+ <ds:SignatureValue></ds:SignatureValue>
20
+ </ds:Signature>
21
+ </foo:Foo>
@@ -48,6 +48,16 @@ describe Xmldsig::Reference do
48
48
  should == 'foo'
49
49
  end
50
50
 
51
+ it "returns the reference node when using a custom id attribute" do
52
+ node = document.at_xpath('//*[@ID]')
53
+ node.remove_attribute('ID')
54
+ node.set_attribute('MyID', 'foo')
55
+ reference = Xmldsig::Reference.new(document.at_xpath('//ds:Reference', Xmldsig::NAMESPACES), 'MyID')
56
+
57
+ reference.referenced_node.to_s.should ==
58
+ document.at_xpath("//*[@MyID='foo']").to_s
59
+ end
60
+
51
61
  it "raises ReferencedNodeNotFound when the refenced node is not present" do
52
62
  node = document.at_xpath('//*[@ID]')
53
63
  node.remove_attribute('ID')
@@ -44,4 +44,37 @@ describe Xmldsig do
44
44
  end
45
45
  end
46
46
 
47
+ describe "Allows specifying a custom id attribute" do
48
+ context "an unsigned document" do
49
+ let(:unsigned_xml) { File.read("spec/fixtures/unsigned_custom_attribute_id.xml") }
50
+ let(:unsigned_document) { Xmldsig::SignedDocument.new(unsigned_xml, :id_attr => 'MyID') }
51
+ let(:signed_document) { unsigned_document.sign(private_key) }
52
+
53
+ it "should be signable an validateable" do
54
+ Xmldsig::SignedDocument.new(signed_document, :id_attr => 'MyID').validate(certificate).should be == true
55
+ end
56
+
57
+ it 'should have a signature element' do
58
+ Xmldsig::SignedDocument.new(signed_document, :id_attr => 'MyID').signatures.count.should == 1
59
+ end
60
+
61
+ # TODO: remove this verification step when library matures
62
+ # it 'matches the result from xmlsec1' do
63
+ # document = "spec/fixtures/unsigned_custom_attribute_id.xml"
64
+ # result = `xmlsec1 --sign --privkey-pem spec/fixtures/key.pem --id-attr:MyID Foo #{document}`
65
+ # result.gsub!("\n", '')
66
+ # signed_document.gsub!("\n", '')
67
+ # result.should == signed_document
68
+ # end
69
+ end
70
+
71
+ context "a signed document" do
72
+ let(:signed_xml) { File.read("spec/fixtures/signed_custom_attribute_id.xml") }
73
+ let(:signed_document) { Xmldsig::SignedDocument.new(signed_xml, :id_attr => 'MyID') }
74
+
75
+ it "should be validateable" do
76
+ signed_document.validate(certificate).should be == true
77
+ end
78
+ end
79
+ end
47
80
  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.2.6
4
+ version: 0.2.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - benoist
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-11 00:00:00.000000000 Z
11
+ date: 2015-03-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -57,6 +57,7 @@ files:
57
57
  - spec/fixtures/signed.xml
58
58
  - spec/fixtures/signed/ideal.cert
59
59
  - spec/fixtures/signed/ideal.txt
60
+ - spec/fixtures/signed_custom_attribute_id.xml
60
61
  - spec/fixtures/unsigned.xml
61
62
  - spec/fixtures/unsigned/canonicalizer_1_0.xml
62
63
  - spec/fixtures/unsigned/canonicalizer_1_1.xml
@@ -66,6 +67,7 @@ files:
66
67
  - spec/fixtures/unsigned/without_canonicalization.xml
67
68
  - spec/fixtures/unsigned/without_namespace_prefix.xml
68
69
  - spec/fixtures/unsigned/without_reference_uri.xml
70
+ - spec/fixtures/unsigned_custom_attribute_id.xml
69
71
  - spec/fixtures/unsigned_multiple_references.xml
70
72
  - spec/fixtures/unsigned_nested_signature.xml
71
73
  - spec/lib/xmldsig/reference_spec.rb
@@ -107,6 +109,7 @@ test_files:
107
109
  - spec/fixtures/signed.xml
108
110
  - spec/fixtures/signed/ideal.cert
109
111
  - spec/fixtures/signed/ideal.txt
112
+ - spec/fixtures/signed_custom_attribute_id.xml
110
113
  - spec/fixtures/unsigned.xml
111
114
  - spec/fixtures/unsigned/canonicalizer_1_0.xml
112
115
  - spec/fixtures/unsigned/canonicalizer_1_1.xml
@@ -116,6 +119,7 @@ test_files:
116
119
  - spec/fixtures/unsigned/without_canonicalization.xml
117
120
  - spec/fixtures/unsigned/without_namespace_prefix.xml
118
121
  - spec/fixtures/unsigned/without_reference_uri.xml
122
+ - spec/fixtures/unsigned_custom_attribute_id.xml
119
123
  - spec/fixtures/unsigned_multiple_references.xml
120
124
  - spec/fixtures/unsigned_nested_signature.xml
121
125
  - spec/lib/xmldsig/reference_spec.rb