samlr 2.7.1.pre.2 → 2.7.1.pre.3
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 +4 -4
- data/lib/samlr/signature.rb +72 -17
- data/lib/samlr/version.rb +1 -1
- metadata +45 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 99111c7af501ed1d300602d81d603fe0869e042dc9b330cb38aa800c77a79517
|
|
4
|
+
data.tar.gz: 755f39f3397bdff3454a05bd47c329ebbf0440c4103469153ed3518bf1aa47c1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 49bb0ebfda779df0a6950eaedac7487b5c1a03475b488573b028d4b86b51a1cbf16c641ad09f15e3bae9bc8717795572d59103590b456b82f22879347881a4d2
|
|
7
|
+
data.tar.gz: f111bab5d4b7f933bf217b7bd0a2c89d179768409fc0215e78e9c0a739ebf8bf5860fb481ec4c94da9e352da7c6975f8293003acc19160c03d04e2ae38bd8577
|
data/lib/samlr/signature.rb
CHANGED
|
@@ -20,11 +20,11 @@ module Samlr
|
|
|
20
20
|
# TODO: This option exists only in a pre-release version to allow testing the feature; remove it from the final release
|
|
21
21
|
if options[:skip_signature_reference_checking]
|
|
22
22
|
@signature = @document.at("#{prefix}/ds:Signature", NS_MAP)
|
|
23
|
+
@signature.remove if @signature # enveloped signatures only
|
|
23
24
|
else
|
|
24
25
|
id = @document.at("#{prefix}", NS_MAP)&.attribute('ID')
|
|
25
|
-
@signature =
|
|
26
|
+
@signature = find_signature_for_element_id(id) if id
|
|
26
27
|
end
|
|
27
|
-
@signature.remove if @signature # enveloped signatures only
|
|
28
28
|
|
|
29
29
|
@fingerprint = if options[:fingerprint]
|
|
30
30
|
Fingerprint.from_string(options[:fingerprint])
|
|
@@ -45,17 +45,30 @@ module Samlr
|
|
|
45
45
|
raise SignatureError.new("No signature at #{prefix}/ds:Signature") unless present?
|
|
46
46
|
|
|
47
47
|
verify_fingerprint! unless options[:skip_fingerprint]
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
if options[:skip_signature_reference_checking]
|
|
49
|
+
verify_digests!
|
|
50
|
+
verify_signature!
|
|
51
|
+
else
|
|
52
|
+
verify_signature! # <- Do this first while signature is still available
|
|
53
|
+
verify_digests! # <- This can remove the signature
|
|
54
|
+
end
|
|
50
55
|
|
|
51
56
|
true
|
|
52
57
|
end
|
|
53
58
|
|
|
54
59
|
def references
|
|
55
60
|
@references ||= [].tap do |refs|
|
|
56
|
-
|
|
57
|
-
|
|
61
|
+
if options[:skip_signature_reference_checking]
|
|
62
|
+
original.xpath("#{prefix}/ds:Signature/ds:SignedInfo/ds:Reference[@URI]", NS_MAP).each do |ref|
|
|
63
|
+
refs << Samlr::Reference.new(ref)
|
|
64
|
+
end
|
|
65
|
+
else
|
|
66
|
+
refs_xpath = @signature.xpath("./ds:SignedInfo/ds:Reference[@URI]", NS_MAP)
|
|
67
|
+
refs_xpath.each do |ref|
|
|
68
|
+
refs << Samlr::Reference.new(ref)
|
|
69
|
+
end
|
|
58
70
|
end
|
|
71
|
+
|
|
59
72
|
end
|
|
60
73
|
end
|
|
61
74
|
|
|
@@ -72,24 +85,58 @@ module Samlr
|
|
|
72
85
|
|
|
73
86
|
# Tests that the document content has not been edited
|
|
74
87
|
def verify_digests!
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
88
|
+
if options[:skip_signature_reference_checking]
|
|
89
|
+
references.each do |reference|
|
|
90
|
+
node = referenced_node(reference.uri)
|
|
91
|
+
canoned = node.canonicalize(C14N, reference.namespaces)
|
|
92
|
+
digest = reference.digest_method.digest(canoned)
|
|
93
|
+
|
|
94
|
+
if digest != reference.decoded_digest_value
|
|
95
|
+
raise SignatureError.new("Reference validation error: Digest mismatch for #{reference.uri}")
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
else
|
|
99
|
+
# Check if we need to remove an enveloped signature
|
|
100
|
+
if @signature && !@signature_removed
|
|
101
|
+
signed_element = @document.at("#{prefix}", NS_MAP)
|
|
102
|
+
is_enveloped = signed_element&.xpath(".//ds:Signature", NS_MAP)&.include?(@signature)
|
|
103
|
+
|
|
104
|
+
# Remove enveloped signature for digest verification
|
|
105
|
+
if is_enveloped
|
|
106
|
+
@signature.remove
|
|
107
|
+
@signature_removed = true
|
|
108
|
+
end
|
|
109
|
+
end
|
|
79
110
|
|
|
80
|
-
|
|
81
|
-
|
|
111
|
+
references.each do |reference|
|
|
112
|
+
node = referenced_node(reference.uri)
|
|
113
|
+
canoned = node.canonicalize(C14N, reference.namespaces)
|
|
114
|
+
digest = reference.digest_method.digest(canoned)
|
|
115
|
+
|
|
116
|
+
if digest != reference.decoded_digest_value
|
|
117
|
+
raise SignatureError.new("Reference validation error: Digest mismatch for #{reference.uri}")
|
|
118
|
+
end
|
|
82
119
|
end
|
|
83
120
|
end
|
|
84
121
|
end
|
|
85
122
|
|
|
86
123
|
# Tests correctness of the signature (and hence digests)
|
|
87
124
|
def verify_signature!
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
125
|
+
if options[:skip_signature_reference_checking]
|
|
126
|
+
node = original.at("#{prefix}/ds:Signature/ds:SignedInfo", NS_MAP)
|
|
127
|
+
canoned = node.canonicalize(C14N)
|
|
128
|
+
unless x509.public_key.verify(signature_method.new, decoded_signature_value, canoned)
|
|
129
|
+
raise SignatureError.new("Signature validation error: Possible canonicalization mismatch", "This canonicalizer returns #{canoned}")
|
|
130
|
+
end
|
|
131
|
+
else
|
|
132
|
+
# Cache the canonicalized SignedInfo to avoid DOM issues with multiple verifications
|
|
133
|
+
unless @canonicalized_signed_info
|
|
134
|
+
node = @signature.at("./ds:SignedInfo", NS_MAP)
|
|
135
|
+
@canonicalized_signed_info = node.canonicalize(C14N)
|
|
136
|
+
end
|
|
137
|
+
unless x509.public_key.verify(signature_method.new, decoded_signature_value, @canonicalized_signed_info)
|
|
138
|
+
raise SignatureError.new("Signature validation error: Possible canonicalization mismatch", "This canonicalizer returns #{@canonicalized_signed_info}")
|
|
139
|
+
end
|
|
93
140
|
end
|
|
94
141
|
end
|
|
95
142
|
|
|
@@ -135,5 +182,13 @@ module Samlr
|
|
|
135
182
|
def certificate_node
|
|
136
183
|
signature.at("./ds:KeyInfo/ds:X509Data/ds:X509Certificate", NS_MAP)
|
|
137
184
|
end
|
|
185
|
+
|
|
186
|
+
def find_signature_for_element_id(element_id)
|
|
187
|
+
return nil unless element_id
|
|
188
|
+
|
|
189
|
+
return @document.at_xpath("//ds:Signature[ds:SignedInfo/ds:Reference[@URI='##{element_id}']]", NS_MAP)
|
|
190
|
+
|
|
191
|
+
end
|
|
192
|
+
|
|
138
193
|
end
|
|
139
194
|
end
|
data/lib/samlr/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: samlr
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.7.1.pre.
|
|
4
|
+
version: 2.7.1.pre.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Morten Primdahl
|
|
@@ -37,6 +37,34 @@ dependencies:
|
|
|
37
37
|
- - ">="
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
39
|
version: 2.1.3
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: base64
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - ">="
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '0'
|
|
47
|
+
type: :runtime
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - ">="
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '0'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: logger
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '0'
|
|
61
|
+
type: :runtime
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - ">="
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '0'
|
|
40
68
|
- !ruby/object:Gem::Dependency
|
|
41
69
|
name: rake
|
|
42
70
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -66,7 +94,7 @@ dependencies:
|
|
|
66
94
|
- !ruby/object:Gem::Version
|
|
67
95
|
version: '0'
|
|
68
96
|
- !ruby/object:Gem::Dependency
|
|
69
|
-
name:
|
|
97
|
+
name: bump
|
|
70
98
|
requirement: !ruby/object:Gem::Requirement
|
|
71
99
|
requirements:
|
|
72
100
|
- - ">="
|
|
@@ -80,7 +108,21 @@ dependencies:
|
|
|
80
108
|
- !ruby/object:Gem::Version
|
|
81
109
|
version: '0'
|
|
82
110
|
- !ruby/object:Gem::Dependency
|
|
83
|
-
name:
|
|
111
|
+
name: minitest
|
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
|
113
|
+
requirements:
|
|
114
|
+
- - "~>"
|
|
115
|
+
- !ruby/object:Gem::Version
|
|
116
|
+
version: '6.0'
|
|
117
|
+
type: :development
|
|
118
|
+
prerelease: false
|
|
119
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
120
|
+
requirements:
|
|
121
|
+
- - "~>"
|
|
122
|
+
- !ruby/object:Gem::Version
|
|
123
|
+
version: '6.0'
|
|
124
|
+
- !ruby/object:Gem::Dependency
|
|
125
|
+
name: minitest-mock
|
|
84
126
|
requirement: !ruby/object:Gem::Requirement
|
|
85
127
|
requirements:
|
|
86
128
|
- - ">="
|