64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
# File 'lib/xml_security.rb', line 64
def validate_doc(base64_cert, soft = true)
inclusive_namespaces =
document = Nokogiri.parse(self.to_s)
self.sig_element ||= begin
element = REXML::XPath.first(self, "//ds:Signature", {"ds"=>DSIG})
element.remove
end
signed_info_element = REXML::XPath.first(sig_element, "//ds:SignedInfo", {"ds"=>DSIG})
self.noko_sig_element ||= document.at_xpath('//ds:Signature', 'ds' => DSIG)
noko_signed_info_element = noko_sig_element.at_xpath('./ds:SignedInfo', 'ds' => DSIG)
canon_algorithm = canon_algorithm REXML::XPath.first(sig_element, '//ds:CanonicalizationMethod')
canon_string = noko_signed_info_element.canonicalize(canon_algorithm)
noko_sig_element.remove
REXML::XPath.each(sig_element, "//ds:Reference", {"ds"=>DSIG}) do |ref|
uri = ref.attributes.get_attribute("URI").value
hashed_element = document.at_xpath("//*[@ID='#{uri[1..-1]}']")
canon_algorithm = canon_algorithm REXML::XPath.first(ref, '//ds:CanonicalizationMethod')
canon_hashed_element = hashed_element.canonicalize(canon_algorithm, inclusive_namespaces).gsub('&','&')
digest_algorithm = algorithm(REXML::XPath.first(ref, "//ds:DigestMethod"))
hash = digest_algorithm.digest(canon_hashed_element)
digest_value = Base64.decode64(REXML::XPath.first(ref, "//ds:DigestValue", {"ds"=>DSIG}).text)
unless digests_match?(hash, digest_value)
return soft ? false : (raise FederazioneTrentina::Saml::ValidationError.new("Digest mismatch"))
end
end
base64_signature = REXML::XPath.first(sig_element, "//ds:SignatureValue", {"ds"=>DSIG}).text
signature = Base64.decode64(base64_signature)
cert_text = Base64.decode64(base64_cert)
cert = OpenSSL::X509::Certificate.new(cert_text)
signature_algorithm = algorithm(REXML::XPath.first(signed_info_element, "//ds:SignatureMethod", {"ds"=>DSIG}))
unless cert.public_key.verify(signature_algorithm.new, signature, canon_string)
return soft ? false : (raise FederazioneTrentina::Saml::ValidationError.new("Key validation error"))
end
return true
end
|