ciam-es 0.0.1

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.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/.document +5 -0
  3. data/Gemfile +4 -0
  4. data/README.md +127 -0
  5. data/ciam-es.gemspec +23 -0
  6. data/lib/ciam-es.rb +14 -0
  7. data/lib/ciam/ruby-saml/authrequest.rb +206 -0
  8. data/lib/ciam/ruby-saml/coding.rb +34 -0
  9. data/lib/ciam/ruby-saml/error_handling.rb +27 -0
  10. data/lib/ciam/ruby-saml/logging.rb +26 -0
  11. data/lib/ciam/ruby-saml/logout_request.rb +126 -0
  12. data/lib/ciam/ruby-saml/logout_response.rb +132 -0
  13. data/lib/ciam/ruby-saml/metadata.rb +509 -0
  14. data/lib/ciam/ruby-saml/request.rb +81 -0
  15. data/lib/ciam/ruby-saml/response.rb +683 -0
  16. data/lib/ciam/ruby-saml/settings.rb +89 -0
  17. data/lib/ciam/ruby-saml/utils.rb +225 -0
  18. data/lib/ciam/ruby-saml/validation_error.rb +7 -0
  19. data/lib/ciam/ruby-saml/version.rb +5 -0
  20. data/lib/ciam/xml_security.rb +166 -0
  21. data/lib/ciam/xml_security_new.rb +373 -0
  22. data/lib/schemas/saml20assertion_schema.xsd +283 -0
  23. data/lib/schemas/saml20protocol_schema.xsd +302 -0
  24. data/lib/schemas/xenc_schema.xsd +146 -0
  25. data/lib/schemas/xmldsig_schema.xsd +318 -0
  26. data/test/certificates/certificate1 +12 -0
  27. data/test/logoutrequest_test.rb +98 -0
  28. data/test/request_test.rb +53 -0
  29. data/test/response_test.rb +219 -0
  30. data/test/responses/adfs_response_sha1.xml +46 -0
  31. data/test/responses/adfs_response_sha256.xml +46 -0
  32. data/test/responses/adfs_response_sha384.xml +46 -0
  33. data/test/responses/adfs_response_sha512.xml +46 -0
  34. data/test/responses/no_signature_ns.xml +48 -0
  35. data/test/responses/open_saml_response.xml +56 -0
  36. data/test/responses/response1.xml.base64 +1 -0
  37. data/test/responses/response2.xml.base64 +79 -0
  38. data/test/responses/response3.xml.base64 +66 -0
  39. data/test/responses/response4.xml.base64 +93 -0
  40. data/test/responses/response5.xml.base64 +102 -0
  41. data/test/responses/response_with_ampersands.xml +139 -0
  42. data/test/responses/response_with_ampersands.xml.base64 +93 -0
  43. data/test/responses/simple_saml_php.xml +71 -0
  44. data/test/responses/wrapped_response_2.xml.base64 +150 -0
  45. data/test/settings_test.rb +43 -0
  46. data/test/test_helper.rb +65 -0
  47. data/test/xml_security_test.rb +123 -0
  48. metadata +145 -0
@@ -0,0 +1,373 @@
1
+ # The contents of this file are subject to the terms
2
+ # of the Common Development and Distribution License
3
+ # (the License). You may not use this file except in
4
+ # compliance with the License.
5
+ #
6
+ # You can obtain a copy of the License at
7
+ # https://opensso.dev.java.net/public/CDDLv1.0.html or
8
+ # opensso/legal/CDDLv1.0.txt
9
+ # See the License for the specific language governing
10
+ # permission and limitations under the License.
11
+ #
12
+ # When distributing Covered Code, include this CDDL
13
+ # Header Notice in each file and include the License file
14
+ # at opensso/legal/CDDLv1.0.txt.
15
+ # If applicable, add the following below the CDDL Header,
16
+ # with the fields enclosed by brackets [] replaced by
17
+ # your own identifying information:
18
+ # "Portions Copyrighted [year] [name of copyright owner]"
19
+ #
20
+ # $Id: xml_sec.rb,v 1.6 2007/10/24 00:28:41 todddd Exp $
21
+ #
22
+ # Copyright 2007 Sun Microsystems Inc. All Rights Reserved
23
+ # Portions Copyrighted 2007 Todd W Saxton.
24
+
25
+ require 'rubygems'
26
+ require "rexml/document"
27
+ require "rexml/xpath"
28
+ require "openssl"
29
+ require 'nokogiri'
30
+ require "digest/sha1"
31
+ require "digest/sha2"
32
+ require "ciam/ruby-saml/error_handling"
33
+
34
+ module Ciam
35
+ module XMLSecurityNew
36
+
37
+ class BaseDocument < REXML::Document
38
+ REXML::Document::entity_expansion_limit = 0
39
+
40
+ C14N = "http://www.w3.org/2001/10/xml-exc-c14n#"
41
+ DSIG = "http://www.w3.org/2000/09/xmldsig#"
42
+ NOKOGIRI_OPTIONS = Nokogiri::XML::ParseOptions::STRICT |
43
+ Nokogiri::XML::ParseOptions::NONET
44
+
45
+ def canon_algorithm(element)
46
+ algorithm = element
47
+ if algorithm.is_a?(REXML::Element)
48
+ algorithm = element.attribute('Algorithm').value
49
+ end
50
+
51
+ case algorithm
52
+ when "http://www.w3.org/TR/2001/REC-xml-c14n-20010315",
53
+ "http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"
54
+ Nokogiri::XML::XML_C14N_1_0
55
+ when "http://www.w3.org/2006/12/xml-c14n11",
56
+ "http://www.w3.org/2006/12/xml-c14n11#WithComments"
57
+ Nokogiri::XML::XML_C14N_1_1
58
+ else
59
+ Nokogiri::XML::XML_C14N_EXCLUSIVE_1_0
60
+ end
61
+ Nokogiri::XML::XML_C14N_EXCLUSIVE_1_0
62
+ end
63
+
64
+ def algorithm(element)
65
+ algorithm = element
66
+ if algorithm.is_a?(REXML::Element)
67
+ algorithm = element.attribute("Algorithm").value
68
+ end
69
+
70
+ algorithm = algorithm && algorithm =~ /(rsa-)?sha(.*?)$/i && $2.to_i
71
+
72
+ case algorithm
73
+ when 256 then OpenSSL::Digest::SHA256
74
+ when 384 then OpenSSL::Digest::SHA384
75
+ when 512 then OpenSSL::Digest::SHA512
76
+ else
77
+ OpenSSL::Digest::SHA256
78
+ end
79
+ end
80
+
81
+ end
82
+
83
+ class Document < BaseDocument
84
+ RSA_SHA1 = "http://www.w3.org/2000/09/xmldsig#rsa-sha1"
85
+ RSA_SHA256 = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"
86
+ RSA_SHA384 = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha384"
87
+ RSA_SHA512 = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"
88
+ SHA1 = "http://www.w3.org/2000/09/xmldsig#sha1"
89
+ SHA256 = 'http://www.w3.org/2001/04/xmlenc#sha256'
90
+ SHA384 = "http://www.w3.org/2001/04/xmldsig-more#sha384"
91
+ SHA512 = 'http://www.w3.org/2001/04/xmlenc#sha512'
92
+ ENVELOPED_SIG = "http://www.w3.org/2000/09/xmldsig#enveloped-signature"
93
+ INC_PREFIX_LIST = "#default samlp saml2p saml ds xs xsi md"
94
+
95
+ attr_accessor :uuid
96
+
97
+ def uuid
98
+ @uuid ||= begin
99
+ document.root.nil? ? nil : document.root.attributes['ID']
100
+ end
101
+ end
102
+
103
+ #<Signature>
104
+ #<SignedInfo>
105
+ #<CanonicalizationMethod />
106
+ #<SignatureMethod />
107
+ #<Reference>
108
+ #<Transforms>
109
+ #<DigestMethod>
110
+ #<DigestValue>
111
+ #</Reference>
112
+ #<Reference /> etc.
113
+ #</SignedInfo>
114
+ #<SignatureValue />
115
+ #<KeyInfo />
116
+ #<Object />
117
+ #</Signature>
118
+ def sign_document(private_key, certificate, signature_method = RSA_SHA256, digest_method = SHA256)
119
+ noko = Nokogiri::XML(self.to_s) do |config|
120
+ config.options = Ciam::XMLSecurityNew::BaseDocument::NOKOGIRI_OPTIONS
121
+ end
122
+
123
+ signature_element = REXML::Element.new("ds:Signature").add_namespace('ds', DSIG)
124
+ signed_info_element = signature_element.add_element("ds:SignedInfo")
125
+ signed_info_element.add_element("ds:CanonicalizationMethod", {"Algorithm" => C14N})
126
+ signed_info_element.add_element("ds:SignatureMethod", {"Algorithm"=>signature_method})
127
+
128
+ # Add Reference
129
+ reference_element = signed_info_element.add_element("ds:Reference", {"URI" => "##{uuid}"})
130
+
131
+ # Add Transforms
132
+ transforms_element = reference_element.add_element("ds:Transforms")
133
+ transforms_element.add_element("ds:Transform", {"Algorithm" => ENVELOPED_SIG})
134
+ c14element = transforms_element.add_element("ds:Transform", {"Algorithm" => C14N})
135
+ c14element.add_element("ec:InclusiveNamespaces", {"xmlns:ec" => C14N, "PrefixList" => INC_PREFIX_LIST})
136
+
137
+ digest_method_element = reference_element.add_element("ds:DigestMethod", {"Algorithm" => digest_method})
138
+ inclusive_namespaces = INC_PREFIX_LIST.split(" ")
139
+ canon_doc = noko.canonicalize(canon_algorithm(C14N), inclusive_namespaces)
140
+ #canon_doc = noko.canonicalize(canon_algorithm(C14N))
141
+ reference_element.add_element("ds:DigestValue").text = compute_digest(canon_doc, algorithm(digest_method_element))
142
+
143
+ # add SignatureValue
144
+ noko_sig_element = Nokogiri::XML(signature_element.to_s) do |config|
145
+ config.options = Ciam::XMLSecurityNew::BaseDocument::NOKOGIRI_OPTIONS
146
+ end
147
+
148
+ noko_signed_info_element = noko_sig_element.at_xpath('//ds:Signature/ds:SignedInfo', 'ds' => DSIG)
149
+ canon_string = noko_signed_info_element.canonicalize(canon_algorithm(C14N), inclusive_namespaces)
150
+
151
+ signature = compute_signature(private_key, algorithm(signature_method).new, canon_string)
152
+ signature_element.add_element("ds:SignatureValue").text = signature.to_s.gsub(/\n/, "").gsub(/\t/, "")
153
+
154
+ # add KeyInfo
155
+ key_info_element = signature_element.add_element("ds:KeyInfo")
156
+ x509_element = key_info_element.add_element("ds:X509Data")
157
+ x509_cert_element = x509_element.add_element("ds:X509Certificate")
158
+ if certificate.is_a?(String)
159
+ certificate = OpenSSL::X509::Certificate.new(certificate)
160
+ end
161
+ x509_cert_element.text = Base64.encode64(certificate.to_der).to_s.gsub(/\n/, "").gsub(/\t/, "")
162
+
163
+ # add the signature
164
+ sp_sso_descriptor = self.root.elements["md:SPSSODescriptor"]
165
+ unless sp_sso_descriptor.blank?
166
+ #inserisco firma nei metadata
167
+ self.root.insert_before sp_sso_descriptor, signature_element
168
+ else
169
+ #inserisco firma nella request
170
+ saml_issuer = self.root.elements["saml:Issuer"]
171
+ self.root.insert_after saml_issuer, signature_element
172
+ end
173
+
174
+
175
+ end
176
+
177
+ protected
178
+
179
+ def compute_signature(private_key, signature_algorithm, document)
180
+ Base64.encode64(private_key.sign(signature_algorithm, document)).to_s.gsub(/\n/, "").gsub(/\t/, "")
181
+ end
182
+
183
+ def compute_digest(document, digest_algorithm)
184
+ digest = digest_algorithm.digest(document)
185
+ Base64.encode64(digest).strip!
186
+ end
187
+
188
+ end
189
+
190
+ class SignedDocument < BaseDocument
191
+ include Ciam::Saml::ErrorHandling
192
+
193
+ attr_accessor :signed_element_id
194
+
195
+ def initialize(response, errors = [])
196
+ super(response)
197
+ @errors = errors
198
+ end
199
+
200
+ def signed_element_id
201
+ @signed_element_id ||= extract_signed_element_id
202
+ end
203
+
204
+ def validate_document(idp_cert_fingerprint, soft = true, options = {})
205
+ # get cert from response
206
+ cert_element = REXML::XPath.first(
207
+ self,
208
+ "//ds:X509Certificate",
209
+ { "ds"=>DSIG }
210
+ )
211
+
212
+ if cert_element
213
+ base64_cert = cert_element.text
214
+ cert_text = Base64.decode64(base64_cert)
215
+ begin
216
+ cert = OpenSSL::X509::Certificate.new(cert_text)
217
+ rescue OpenSSL::X509::CertificateError => e
218
+ return append_error("Certificate Error", soft)
219
+ end
220
+
221
+ if options[:fingerprint_alg]
222
+ fingerprint_alg = Ciam::XMLSecurityNew::BaseDocument.new.algorithm(options[:fingerprint_alg]).new
223
+ else
224
+ fingerprint_alg = OpenSSL::Digest::SHA256.new
225
+ end
226
+ fingerprint = fingerprint_alg.hexdigest(cert.to_der)
227
+
228
+ # check cert matches registered idp cert
229
+ if fingerprint != idp_cert_fingerprint.gsub(/[^a-zA-Z0-9]/,"").downcase
230
+ @errors << "Fingerprint mismatch"
231
+ return append_error("Fingerprint mismatch", soft)
232
+ end
233
+ else
234
+ if options[:cert]
235
+ base64_cert = Base64.encode64(options[:cert].to_pem)
236
+ else
237
+ if soft
238
+ return false
239
+ else
240
+ return append_error("Certificate element missing in response (ds:X509Certificate) and not cert provided at settings", soft)
241
+ end
242
+ end
243
+ end
244
+ validate_signature(base64_cert, soft)
245
+ end
246
+
247
+ def validate_signature(base64_cert, soft = true)
248
+
249
+ document = Nokogiri::XML(self.to_s) do |config|
250
+ config.options = Ciam::XMLSecurityNew::BaseDocument::NOKOGIRI_OPTIONS
251
+ end
252
+
253
+ # create a rexml document
254
+ @working_copy ||= REXML::Document.new(self.to_s).root
255
+
256
+ # get signature node
257
+ sig_element = REXML::XPath.first(
258
+ @working_copy,
259
+ "//ds:Signature",
260
+ {"ds"=>DSIG}
261
+ )
262
+
263
+ # signature method
264
+ sig_alg_value = REXML::XPath.first(
265
+ sig_element,
266
+ "./ds:SignedInfo/ds:SignatureMethod",
267
+ {"ds"=>DSIG}
268
+ )
269
+ signature_algorithm = algorithm(sig_alg_value)
270
+
271
+ # get signature
272
+ base64_signature = REXML::XPath.first(
273
+ sig_element,
274
+ "./ds:SignatureValue",
275
+ {"ds" => DSIG}
276
+ ).text
277
+ signature = Base64.decode64(base64_signature)
278
+
279
+ # canonicalization method
280
+ canon_algorithm = canon_algorithm REXML::XPath.first(
281
+ sig_element,
282
+ './ds:SignedInfo/ds:CanonicalizationMethod',
283
+ 'ds' => DSIG
284
+ )
285
+
286
+ noko_sig_element = document.at_xpath('//ds:Signature', 'ds' => DSIG)
287
+ noko_signed_info_element = noko_sig_element.at_xpath('./ds:SignedInfo', 'ds' => DSIG)
288
+
289
+ canon_string = noko_signed_info_element.canonicalize(canon_algorithm)
290
+ noko_sig_element.remove
291
+
292
+ # get inclusive namespaces
293
+ inclusive_namespaces = extract_inclusive_namespaces
294
+
295
+ # check digests
296
+ ref = REXML::XPath.first(sig_element, "//ds:Reference", {"ds"=>DSIG})
297
+ uri = ref.attributes.get_attribute("URI").value
298
+
299
+ hashed_element = document.at_xpath("//*[@ID=$id]", nil, { 'id' => extract_signed_element_id })
300
+
301
+ canon_algorithm = canon_algorithm REXML::XPath.first(
302
+ ref,
303
+ '//ds:CanonicalizationMethod',
304
+ { "ds" => DSIG }
305
+ )
306
+ canon_hashed_element = hashed_element.canonicalize(canon_algorithm, inclusive_namespaces)
307
+
308
+ digest_algorithm = algorithm(REXML::XPath.first(
309
+ ref,
310
+ "//ds:DigestMethod",
311
+ { "ds" => DSIG }
312
+ ))
313
+ hash = digest_algorithm.digest(canon_hashed_element)
314
+ encoded_digest_value = REXML::XPath.first(
315
+ ref,
316
+ "//ds:DigestValue",
317
+ { "ds" => DSIG }
318
+ ).text
319
+ digest_value = Base64.decode64(encoded_digest_value)
320
+
321
+ unless digests_match?(hash, digest_value)
322
+ @errors << "Digest mismatch"
323
+ return append_error("Digest mismatch", soft)
324
+ end
325
+
326
+ # get certificate object
327
+ cert_text = Base64.decode64(base64_cert)
328
+ cert = OpenSSL::X509::Certificate.new(cert_text)
329
+
330
+ # verify signature
331
+ unless cert.public_key.verify(signature_algorithm.new, signature, canon_string)
332
+ return append_error("Key validation error", soft)
333
+ end
334
+
335
+ return true
336
+ end
337
+
338
+ private
339
+
340
+ def digests_match?(hash, digest_value)
341
+ hash == digest_value
342
+ end
343
+
344
+ def extract_signed_element_id
345
+ reference_element = REXML::XPath.first(
346
+ self,
347
+ "//ds:Signature/ds:SignedInfo/ds:Reference",
348
+ {"ds"=>DSIG}
349
+ )
350
+
351
+ return nil if reference_element.nil?
352
+
353
+ sei = reference_element.attribute("URI").value[1..-1]
354
+ sei.nil? ? reference_element.parent.parent.parent.attribute("ID").value : sei
355
+ end
356
+
357
+ def extract_inclusive_namespaces
358
+ element = REXML::XPath.first(
359
+ self,
360
+ "//ec:InclusiveNamespaces",
361
+ { "ec" => C14N }
362
+ )
363
+ if element
364
+ prefix_list = element.attributes.get_attribute("PrefixList").value
365
+ prefix_list.split(" ")
366
+ else
367
+ nil
368
+ end
369
+ end
370
+
371
+ end
372
+ end
373
+ end
@@ -0,0 +1,283 @@
1
+ <?xml version="1.0" encoding="US-ASCII"?>
2
+ <schema
3
+ targetNamespace="urn:oasis:names:tc:SAML:2.0:assertion"
4
+ xmlns="http://www.w3.org/2001/XMLSchema"
5
+ xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
6
+ xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
7
+ xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"
8
+ elementFormDefault="unqualified"
9
+ attributeFormDefault="unqualified"
10
+ blockDefault="substitution"
11
+ version="2.0">
12
+ <import namespace="http://www.w3.org/2000/09/xmldsig#"
13
+ schemaLocation="xmldsig_schema.xsd"/>
14
+ <import namespace="http://www.w3.org/2001/04/xmlenc#"
15
+ schemaLocation="xenc_schema.xsd"/>
16
+ <annotation>
17
+ <documentation>
18
+ Document identifier: saml-schema-assertion-2.0
19
+ Location: http://docs.oasis-open.org/security/saml/v2.0/
20
+ Revision history:
21
+ V1.0 (November, 2002):
22
+ Initial Standard Schema.
23
+ V1.1 (September, 2003):
24
+ Updates within the same V1.0 namespace.
25
+ V2.0 (March, 2005):
26
+ New assertion schema for SAML V2.0 namespace.
27
+ </documentation>
28
+ </annotation>
29
+ <attributeGroup name="IDNameQualifiers">
30
+ <attribute name="NameQualifier" type="string" use="optional"/>
31
+ <attribute name="SPNameQualifier" type="string" use="optional"/>
32
+ </attributeGroup>
33
+ <element name="BaseID" type="saml:BaseIDAbstractType"/>
34
+ <complexType name="BaseIDAbstractType" abstract="true">
35
+ <attributeGroup ref="saml:IDNameQualifiers"/>
36
+ </complexType>
37
+ <element name="NameID" type="saml:NameIDType"/>
38
+ <complexType name="NameIDType">
39
+ <simpleContent>
40
+ <extension base="string">
41
+ <attributeGroup ref="saml:IDNameQualifiers"/>
42
+ <attribute name="Format" type="anyURI" use="optional"/>
43
+ <attribute name="SPProvidedID" type="string" use="optional"/>
44
+ </extension>
45
+ </simpleContent>
46
+ </complexType>
47
+ <complexType name="EncryptedElementType">
48
+ <sequence>
49
+ <element ref="xenc:EncryptedData"/>
50
+ <element ref="xenc:EncryptedKey" minOccurs="0" maxOccurs="unbounded"/>
51
+ </sequence>
52
+ </complexType>
53
+ <element name="EncryptedID" type="saml:EncryptedElementType"/>
54
+ <element name="Issuer" type="saml:NameIDType"/>
55
+ <element name="AssertionIDRef" type="NCName"/>
56
+ <element name="AssertionURIRef" type="anyURI"/>
57
+ <element name="Assertion" type="saml:AssertionType"/>
58
+ <complexType name="AssertionType">
59
+ <sequence>
60
+ <element ref="saml:Issuer"/>
61
+ <element ref="ds:Signature" minOccurs="0"/>
62
+ <element ref="saml:Subject" minOccurs="0"/>
63
+ <element ref="saml:Conditions" minOccurs="0"/>
64
+ <element ref="saml:Advice" minOccurs="0"/>
65
+ <choice minOccurs="0" maxOccurs="unbounded">
66
+ <element ref="saml:Statement"/>
67
+ <element ref="saml:AuthnStatement"/>
68
+ <element ref="saml:AuthzDecisionStatement"/>
69
+ <element ref="saml:AttributeStatement"/>
70
+ </choice>
71
+ </sequence>
72
+ <attribute name="Version" type="string" use="required"/>
73
+ <attribute name="ID" type="ID" use="required"/>
74
+ <attribute name="IssueInstant" type="dateTime" use="required"/>
75
+ </complexType>
76
+ <element name="Subject" type="saml:SubjectType"/>
77
+ <complexType name="SubjectType">
78
+ <choice>
79
+ <sequence>
80
+ <choice>
81
+ <element ref="saml:BaseID"/>
82
+ <element ref="saml:NameID"/>
83
+ <element ref="saml:EncryptedID"/>
84
+ </choice>
85
+ <element ref="saml:SubjectConfirmation" minOccurs="0" maxOccurs="unbounded"/>
86
+ </sequence>
87
+ <element ref="saml:SubjectConfirmation" maxOccurs="unbounded"/>
88
+ </choice>
89
+ </complexType>
90
+ <element name="SubjectConfirmation" type="saml:SubjectConfirmationType"/>
91
+ <complexType name="SubjectConfirmationType">
92
+ <sequence>
93
+ <choice minOccurs="0">
94
+ <element ref="saml:BaseID"/>
95
+ <element ref="saml:NameID"/>
96
+ <element ref="saml:EncryptedID"/>
97
+ </choice>
98
+ <element ref="saml:SubjectConfirmationData" minOccurs="0"/>
99
+ </sequence>
100
+ <attribute name="Method" type="anyURI" use="required"/>
101
+ </complexType>
102
+ <element name="SubjectConfirmationData" type="saml:SubjectConfirmationDataType"/>
103
+ <complexType name="SubjectConfirmationDataType" mixed="true">
104
+ <complexContent>
105
+ <restriction base="anyType">
106
+ <sequence>
107
+ <any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
108
+ </sequence>
109
+ <attribute name="NotBefore" type="dateTime" use="optional"/>
110
+ <attribute name="NotOnOrAfter" type="dateTime" use="optional"/>
111
+ <attribute name="Recipient" type="anyURI" use="optional"/>
112
+ <attribute name="InResponseTo" type="NCName" use="optional"/>
113
+ <attribute name="Address" type="string" use="optional"/>
114
+ <anyAttribute namespace="##other" processContents="lax"/>
115
+ </restriction>
116
+ </complexContent>
117
+ </complexType>
118
+ <complexType name="KeyInfoConfirmationDataType" mixed="false">
119
+ <complexContent>
120
+ <restriction base="saml:SubjectConfirmationDataType">
121
+ <sequence>
122
+ <element ref="ds:KeyInfo" maxOccurs="unbounded"/>
123
+ </sequence>
124
+ </restriction>
125
+ </complexContent>
126
+ </complexType>
127
+ <element name="Conditions" type="saml:ConditionsType"/>
128
+ <complexType name="ConditionsType">
129
+ <choice minOccurs="0" maxOccurs="unbounded">
130
+ <element ref="saml:Condition"/>
131
+ <element ref="saml:AudienceRestriction"/>
132
+ <element ref="saml:OneTimeUse"/>
133
+ <element ref="saml:ProxyRestriction"/>
134
+ </choice>
135
+ <attribute name="NotBefore" type="dateTime" use="optional"/>
136
+ <attribute name="NotOnOrAfter" type="dateTime" use="optional"/>
137
+ </complexType>
138
+ <element name="Condition" type="saml:ConditionAbstractType"/>
139
+ <complexType name="ConditionAbstractType" abstract="true"/>
140
+ <element name="AudienceRestriction" type="saml:AudienceRestrictionType"/>
141
+ <complexType name="AudienceRestrictionType">
142
+ <complexContent>
143
+ <extension base="saml:ConditionAbstractType">
144
+ <sequence>
145
+ <element ref="saml:Audience" maxOccurs="unbounded"/>
146
+ </sequence>
147
+ </extension>
148
+ </complexContent>
149
+ </complexType>
150
+ <element name="Audience" type="anyURI"/>
151
+ <element name="OneTimeUse" type="saml:OneTimeUseType" />
152
+ <complexType name="OneTimeUseType">
153
+ <complexContent>
154
+ <extension base="saml:ConditionAbstractType"/>
155
+ </complexContent>
156
+ </complexType>
157
+ <element name="ProxyRestriction" type="saml:ProxyRestrictionType"/>
158
+ <complexType name="ProxyRestrictionType">
159
+ <complexContent>
160
+ <extension base="saml:ConditionAbstractType">
161
+ <sequence>
162
+ <element ref="saml:Audience" minOccurs="0" maxOccurs="unbounded"/>
163
+ </sequence>
164
+ <attribute name="Count" type="nonNegativeInteger" use="optional"/>
165
+ </extension>
166
+ </complexContent>
167
+ </complexType>
168
+ <element name="Advice" type="saml:AdviceType"/>
169
+ <complexType name="AdviceType">
170
+ <choice minOccurs="0" maxOccurs="unbounded">
171
+ <element ref="saml:AssertionIDRef"/>
172
+ <element ref="saml:AssertionURIRef"/>
173
+ <element ref="saml:Assertion"/>
174
+ <element ref="saml:EncryptedAssertion"/>
175
+ <any namespace="##other" processContents="lax"/>
176
+ </choice>
177
+ </complexType>
178
+ <element name="EncryptedAssertion" type="saml:EncryptedElementType"/>
179
+ <element name="Statement" type="saml:StatementAbstractType"/>
180
+ <complexType name="StatementAbstractType" abstract="true"/>
181
+ <element name="AuthnStatement" type="saml:AuthnStatementType"/>
182
+ <complexType name="AuthnStatementType">
183
+ <complexContent>
184
+ <extension base="saml:StatementAbstractType">
185
+ <sequence>
186
+ <element ref="saml:SubjectLocality" minOccurs="0"/>
187
+ <element ref="saml:AuthnContext"/>
188
+ </sequence>
189
+ <attribute name="AuthnInstant" type="dateTime" use="required"/>
190
+ <attribute name="SessionIndex" type="string" use="optional"/>
191
+ <attribute name="SessionNotOnOrAfter" type="dateTime" use="optional"/>
192
+ </extension>
193
+ </complexContent>
194
+ </complexType>
195
+ <element name="SubjectLocality" type="saml:SubjectLocalityType"/>
196
+ <complexType name="SubjectLocalityType">
197
+ <attribute name="Address" type="string" use="optional"/>
198
+ <attribute name="DNSName" type="string" use="optional"/>
199
+ </complexType>
200
+ <element name="AuthnContext" type="saml:AuthnContextType"/>
201
+ <complexType name="AuthnContextType">
202
+ <sequence>
203
+ <choice>
204
+ <sequence>
205
+ <element ref="saml:AuthnContextClassRef"/>
206
+ <choice minOccurs="0">
207
+ <element ref="saml:AuthnContextDecl"/>
208
+ <element ref="saml:AuthnContextDeclRef"/>
209
+ </choice>
210
+ </sequence>
211
+ <choice>
212
+ <element ref="saml:AuthnContextDecl"/>
213
+ <element ref="saml:AuthnContextDeclRef"/>
214
+ </choice>
215
+ </choice>
216
+ <element ref="saml:AuthenticatingAuthority" minOccurs="0" maxOccurs="unbounded"/>
217
+ </sequence>
218
+ </complexType>
219
+ <element name="AuthnContextClassRef" type="anyURI"/>
220
+ <element name="AuthnContextDeclRef" type="anyURI"/>
221
+ <element name="AuthnContextDecl" type="anyType"/>
222
+ <element name="AuthenticatingAuthority" type="anyURI"/>
223
+ <element name="AuthzDecisionStatement" type="saml:AuthzDecisionStatementType"/>
224
+ <complexType name="AuthzDecisionStatementType">
225
+ <complexContent>
226
+ <extension base="saml:StatementAbstractType">
227
+ <sequence>
228
+ <element ref="saml:Action" maxOccurs="unbounded"/>
229
+ <element ref="saml:Evidence" minOccurs="0"/>
230
+ </sequence>
231
+ <attribute name="Resource" type="anyURI" use="required"/>
232
+ <attribute name="Decision" type="saml:DecisionType" use="required"/>
233
+ </extension>
234
+ </complexContent>
235
+ </complexType>
236
+ <simpleType name="DecisionType">
237
+ <restriction base="string">
238
+ <enumeration value="Permit"/>
239
+ <enumeration value="Deny"/>
240
+ <enumeration value="Indeterminate"/>
241
+ </restriction>
242
+ </simpleType>
243
+ <element name="Action" type="saml:ActionType"/>
244
+ <complexType name="ActionType">
245
+ <simpleContent>
246
+ <extension base="string">
247
+ <attribute name="Namespace" type="anyURI" use="required"/>
248
+ </extension>
249
+ </simpleContent>
250
+ </complexType>
251
+ <element name="Evidence" type="saml:EvidenceType"/>
252
+ <complexType name="EvidenceType">
253
+ <choice maxOccurs="unbounded">
254
+ <element ref="saml:AssertionIDRef"/>
255
+ <element ref="saml:AssertionURIRef"/>
256
+ <element ref="saml:Assertion"/>
257
+ <element ref="saml:EncryptedAssertion"/>
258
+ </choice>
259
+ </complexType>
260
+ <element name="AttributeStatement" type="saml:AttributeStatementType"/>
261
+ <complexType name="AttributeStatementType">
262
+ <complexContent>
263
+ <extension base="saml:StatementAbstractType">
264
+ <choice maxOccurs="unbounded">
265
+ <element ref="saml:Attribute"/>
266
+ <element ref="saml:EncryptedAttribute"/>
267
+ </choice>
268
+ </extension>
269
+ </complexContent>
270
+ </complexType>
271
+ <element name="Attribute" type="saml:AttributeType"/>
272
+ <complexType name="AttributeType">
273
+ <sequence>
274
+ <element ref="saml:AttributeValue" minOccurs="0" maxOccurs="unbounded"/>
275
+ </sequence>
276
+ <attribute name="Name" type="string" use="required"/>
277
+ <attribute name="NameFormat" type="anyURI" use="optional"/>
278
+ <attribute name="FriendlyName" type="string" use="optional"/>
279
+ <anyAttribute namespace="##other" processContents="lax"/>
280
+ </complexType>
281
+ <element name="AttributeValue" type="anyType" nillable="true"/>
282
+ <element name="EncryptedAttribute" type="saml:EncryptedElementType"/>
283
+ </schema>