rsaml 0.1.2
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.
- data/LICENSE +0 -0
- data/README +13 -0
- data/Rakefile +136 -0
- data/lib/rsaml.rb +57 -0
- data/lib/rsaml/action.rb +57 -0
- data/lib/rsaml/action_namespace.rb +63 -0
- data/lib/rsaml/advice.rb +34 -0
- data/lib/rsaml/assertion.rb +192 -0
- data/lib/rsaml/attribute.rb +76 -0
- data/lib/rsaml/audience.rb +19 -0
- data/lib/rsaml/authentication_context.rb +34 -0
- data/lib/rsaml/authn_context/README +1 -0
- data/lib/rsaml/authn_context/authentication_context_declaration.rb +42 -0
- data/lib/rsaml/authn_context/identification.rb +10 -0
- data/lib/rsaml/authn_context/physical_verification.rb +24 -0
- data/lib/rsaml/condition.rb +13 -0
- data/lib/rsaml/conditions.rb +107 -0
- data/lib/rsaml/encrypted.rb +12 -0
- data/lib/rsaml/errors.rb +16 -0
- data/lib/rsaml/evidence.rb +21 -0
- data/lib/rsaml/ext/string.rb +5 -0
- data/lib/rsaml/identifier.rb +9 -0
- data/lib/rsaml/identifier/base.rb +23 -0
- data/lib/rsaml/identifier/issuer.rb +28 -0
- data/lib/rsaml/identifier/name.rb +55 -0
- data/lib/rsaml/parser.rb +23 -0
- data/lib/rsaml/protocol.rb +21 -0
- data/lib/rsaml/protocol/artifact_resolve.rb +14 -0
- data/lib/rsaml/protocol/assertion_id_request.rb +18 -0
- data/lib/rsaml/protocol/authn_request.rb +91 -0
- data/lib/rsaml/protocol/idp_entry.rb +18 -0
- data/lib/rsaml/protocol/idp_list.rb +28 -0
- data/lib/rsaml/protocol/message.rb +65 -0
- data/lib/rsaml/protocol/name_id_policy.rb +31 -0
- data/lib/rsaml/protocol/query.rb +12 -0
- data/lib/rsaml/protocol/query/attribute_query.rb +56 -0
- data/lib/rsaml/protocol/query/authn_query.rb +30 -0
- data/lib/rsaml/protocol/query/authz_decision_query.rb +40 -0
- data/lib/rsaml/protocol/query/subject_query.rb +22 -0
- data/lib/rsaml/protocol/request.rb +27 -0
- data/lib/rsaml/protocol/requested_authn_context.rb +34 -0
- data/lib/rsaml/protocol/response.rb +56 -0
- data/lib/rsaml/protocol/scoping.rb +33 -0
- data/lib/rsaml/protocol/status.rb +38 -0
- data/lib/rsaml/protocol/status_code.rb +84 -0
- data/lib/rsaml/proxy_restriction.rb +30 -0
- data/lib/rsaml/statement.rb +10 -0
- data/lib/rsaml/statement/attribute_statement.rb +27 -0
- data/lib/rsaml/statement/authentication_statement.rb +57 -0
- data/lib/rsaml/statement/authorization_decision_statement.rb +53 -0
- data/lib/rsaml/statement/base.rb +9 -0
- data/lib/rsaml/subject.rb +37 -0
- data/lib/rsaml/subject_confirmation.rb +35 -0
- data/lib/rsaml/subject_confirmation_data.rb +55 -0
- data/lib/rsaml/subject_locality.rb +27 -0
- data/lib/rsaml/validatable.rb +21 -0
- data/lib/rsaml/version.rb +9 -0
- data/lib/xml_enc.rb +3 -0
- data/lib/xml_sig.rb +11 -0
- data/lib/xml_sig/canonicalization_method.rb +43 -0
- data/lib/xml_sig/key_info.rb +55 -0
- data/lib/xml_sig/reference.rb +57 -0
- data/lib/xml_sig/signature.rb +29 -0
- data/lib/xml_sig/signature_method.rb +20 -0
- data/lib/xml_sig/signed_info.rb +27 -0
- data/lib/xml_sig/transform.rb +37 -0
- data/test/action_namespace_test.rb +93 -0
- data/test/action_test.rb +51 -0
- data/test/advice_test.rb +25 -0
- data/test/assertion_test.rb +192 -0
- data/test/attribute_test.rb +60 -0
- data/test/authentication_context_test.rb +26 -0
- data/test/conditions_test.rb +84 -0
- data/test/evidence_test.rb +33 -0
- data/test/identifier_test.rb +22 -0
- data/test/issuer_test.rb +33 -0
- data/test/name_test.rb +33 -0
- data/test/parser_test.rb +32 -0
- data/test/protocol/assertion_id_request_test.rb +19 -0
- data/test/protocol/attribute_query_test.rb +30 -0
- data/test/protocol/authn_query_test.rb +20 -0
- data/test/protocol/authn_request_test.rb +56 -0
- data/test/protocol/authz_decision_query_test.rb +31 -0
- data/test/protocol/idp_list_test.rb +15 -0
- data/test/protocol/request_test.rb +66 -0
- data/test/protocol/response_test.rb +68 -0
- data/test/protocol/scoping_test.rb +20 -0
- data/test/protocol/status_code_test.rb +34 -0
- data/test/protocol/status_test.rb +16 -0
- data/test/proxy_restriction_test.rb +20 -0
- data/test/rsaml_test.rb +12 -0
- data/test/statement_test.rb +101 -0
- data/test/subject_locality_test.rb +27 -0
- data/test/subject_test.rb +44 -0
- data/test/test_helper.rb +16 -0
- data/test/xml_sig/canonicalization_test.rb +19 -0
- metadata +187 -0
@@ -0,0 +1,57 @@
|
|
1
|
+
module RSAML #:nodoc:
|
2
|
+
module Statement #:nodoc:
|
3
|
+
# The assertion subject was authenticated by a particular means at a particular time.
|
4
|
+
class AuthenticationStatement < Base
|
5
|
+
# Specifies the time at which the authentication took place. The time value is encoded in UTC
|
6
|
+
attr_accessor :authn_instant
|
7
|
+
|
8
|
+
# Specifies the index of a particular session between the principal identified by the subject and the
|
9
|
+
# authenticating authority. In general, any string value MAY be used as a SessionIndex value.
|
10
|
+
# However, when privacy is a consideration, care must be taken to ensure that the SessionIndex
|
11
|
+
# value does not invalidate other privacy mechanisms. Accordingly, the value SHOULD NOT be usable
|
12
|
+
# to correlate activity by a principal across different session participants.
|
13
|
+
attr_accessor :session_index
|
14
|
+
|
15
|
+
# Specifies a time instant at which the session between the principal identified by the subject and the
|
16
|
+
# SAML authority issuing this statement MUST be considered ended. The time value is encoded in
|
17
|
+
# UTCSpecifies
|
18
|
+
attr_accessor :session_not_on_or_after
|
19
|
+
|
20
|
+
# Specifies the DNS domain name and IP address for the system from which the assertion subject was
|
21
|
+
# apparently authenticated.
|
22
|
+
attr_accessor :subject_locality
|
23
|
+
|
24
|
+
# The authentication context.
|
25
|
+
attr_accessor :authn_context
|
26
|
+
|
27
|
+
# Initialize the statement
|
28
|
+
def initialize(authn_context)
|
29
|
+
@authn_context = authn_context
|
30
|
+
@authn_instant = Time.now.utc
|
31
|
+
end
|
32
|
+
|
33
|
+
# Validate the structure of the authentication statement. Raise a ValidationError if the
|
34
|
+
# statement is invalid.
|
35
|
+
def validate
|
36
|
+
if session_not_on_or_after && !session_not_on_or_after.utc?
|
37
|
+
raise ValidationError, "Session not on or after must be UTC"
|
38
|
+
end
|
39
|
+
raise ValidationError, "Authn context required" unless authn_context
|
40
|
+
raise ValidationError, "Authn instant required" unless authn_instant
|
41
|
+
raise ValidationError, "Authn instant must be UTC" unless authn_instant.utc?
|
42
|
+
end
|
43
|
+
|
44
|
+
# Construct an XML fragment representing the authentication statement
|
45
|
+
def to_xml(xml=Builder::XmlMarkup.new)
|
46
|
+
validate
|
47
|
+
attributes = {'AuthnInstant' => authn_instant.xmlschema}
|
48
|
+
attributes['SessionIndex'] = session_index unless session_index.nil?
|
49
|
+
attributes['SessionNotOnOrAfter'] = session_not_on_or_after.xmlschema unless session_not_on_or_after.nil?
|
50
|
+
xml.tag!('saml:AuthnStatement', attributes) {
|
51
|
+
xml << authn_context.to_xml
|
52
|
+
xml << subject_locality.to_xml unless subject_locality.nil?
|
53
|
+
}
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module RSAML #:nodoc:
|
2
|
+
module Statement #:nodoc:
|
3
|
+
# A request to allow the assertion subject to access the specified resource
|
4
|
+
# has been granted or denied.
|
5
|
+
class AuthorizationDecisionStatement < Base
|
6
|
+
# defines the possible values to be reported as the status of an authorization decision statement.
|
7
|
+
#
|
8
|
+
# Possible values are:
|
9
|
+
# * <tt>Permit</tt>: The specified action is permitted.
|
10
|
+
# * <tt>Deny</tt>: The specified action is denied.
|
11
|
+
# * <tt>Indeterminate</tt> The SAML authority cannot determine whether the specified action
|
12
|
+
# is permitted or denied.
|
13
|
+
def self.decision_types
|
14
|
+
%w(Permit Deny Indeterminate)
|
15
|
+
end
|
16
|
+
|
17
|
+
# A URI reference identifying the resource to which access authorization is sought.
|
18
|
+
# This attribute MAY have the value of the empty URI reference (""), and the meaning
|
19
|
+
# is defined to be "the start of the current document"
|
20
|
+
attr_accessor :resource
|
21
|
+
|
22
|
+
# The decision rendered by the SAML authority with respect to the specified resource.
|
23
|
+
attr_accessor :decision
|
24
|
+
|
25
|
+
# The set of actions authorized to be performed on the specified resource.
|
26
|
+
def actions
|
27
|
+
@actions ||= []
|
28
|
+
end
|
29
|
+
|
30
|
+
# A set of assertions that the SAML authority relied on in making the decision.
|
31
|
+
def evidence
|
32
|
+
@evidence ||= []
|
33
|
+
end
|
34
|
+
|
35
|
+
# Validate the structure
|
36
|
+
def validate
|
37
|
+
raise ValidationError, "Resource is required" if resource.nil?
|
38
|
+
raise ValidationError, "Decision is required" if decision.nil?
|
39
|
+
raise ValidationError, "One or more actions must be specified" if actions.empty?
|
40
|
+
actions.each { |action| action.validate }
|
41
|
+
end
|
42
|
+
|
43
|
+
# Construct an XML fragment representing the authorization decision statement
|
44
|
+
def to_xml(xml=Builder::XmlMarkup.new)
|
45
|
+
attributes = {'Resource' => resource, 'Decision' => decision}
|
46
|
+
xml.tag!('saml:AuthzStatement', attributes) {
|
47
|
+
actions.each { |action| xml << action.to_xml }
|
48
|
+
evidence.each { |e| xml << e.to_xml }
|
49
|
+
}
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module RSAML #:nodoc:
|
2
|
+
# Specifies the principal that is the subject of all of the (zero or more)
|
3
|
+
# statements in an assertion.
|
4
|
+
class Subject
|
5
|
+
|
6
|
+
# The subject identifier
|
7
|
+
attr_accessor :identifier
|
8
|
+
|
9
|
+
# Initialize the subject with the given identifier
|
10
|
+
def initialize(identifier=nil)
|
11
|
+
@identifier = identifier
|
12
|
+
end
|
13
|
+
|
14
|
+
# Information that allows the subject to be confirmed. If more than one subject confirmation is provided,
|
15
|
+
# then satisfying any one of them is sufficient to confirm the subject for the purpose of applying the
|
16
|
+
# assertion.
|
17
|
+
def subject_confirmations
|
18
|
+
@subject_confirmations ||= []
|
19
|
+
end
|
20
|
+
|
21
|
+
# Construct an XML fragment representing the subject
|
22
|
+
def to_xml(xml=Builder::XmlMarkup.new)
|
23
|
+
xml.tag!('saml:Subject') {
|
24
|
+
xml << identifier.to_xml unless identifier.nil?
|
25
|
+
xml << subject_confirmations.map { |sc| sc.to_xml }.join
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
# Construct a Subject from an XML Element.
|
30
|
+
def self.from_xml(element)
|
31
|
+
element = REXML::Document.new(element).root if element.is_a?(String)
|
32
|
+
element.get_elements('saml:NameID').each do |identifier|
|
33
|
+
return Subject.new(Identifier::Name.from_xml(identifier))
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module RSAML #:nodoc:
|
2
|
+
# Provides the means for a relying party to verify the correspondence of the subject of the
|
3
|
+
# assertion with the party with whom the relying party is communicating.
|
4
|
+
class SubjectConfirmation
|
5
|
+
|
6
|
+
# Hash of available SAML methods for subject confirmation
|
7
|
+
def self.methods
|
8
|
+
{
|
9
|
+
:holder_of_key => 'urn:oasis:names:tc:SAML:2.0:cm:holder-of-key',
|
10
|
+
:sender_vouches => 'urn:oasis:names:tc:SAML:2.0:cm:sender-vouches',
|
11
|
+
:bearer => 'urn:oasis:names:tc:SAML:2.0:cm:bearer'
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
# A URI reference that identifies a protocol or mechanism to be used to confirm the subject.
|
16
|
+
attr_accessor :method
|
17
|
+
|
18
|
+
# Identifies the entity expected to satisfy the enclosing subject confirmation requirements.
|
19
|
+
attr_accessor :identifier
|
20
|
+
|
21
|
+
# Additional confirmation information to be used by a specific confirmation method.
|
22
|
+
attr_accessor :subject_confirmation_data
|
23
|
+
|
24
|
+
def initialize(method)
|
25
|
+
@method = method
|
26
|
+
end
|
27
|
+
|
28
|
+
# Construct an XML fragment representing the subject confirmation
|
29
|
+
def to_xml(xml=Builder::XmlMarkup.new)
|
30
|
+
attributes = {'Method' => method}
|
31
|
+
subject_confirmation_data_block = Proc.new { xml << subject_confirmation_data.to_xml} if subject_confirmation_data
|
32
|
+
xml.tag!('saml:SubjectConfirmation', attributes, &subject_confirmation_data_block)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module RSAML #:nodoc:
|
2
|
+
# specifies additional data that allows the subject to be confirmed or constrains the circumstances under
|
3
|
+
# which the act of subject confirmation can take place. Subject confirmation takes place when a relying
|
4
|
+
# party seeks to verify the relationship between an entity presenting the assertion (that is, the attesting
|
5
|
+
# entity) and the subject of the assertion's claims.
|
6
|
+
class SubjectConfirmationData
|
7
|
+
# A time instant before which the subject cannot be confirmed. The time value is encoded in UTC.
|
8
|
+
attr_accessor :not_before
|
9
|
+
|
10
|
+
# A time instant at which the subject can no longer be confirmed. The time value is encoded in UTC.
|
11
|
+
attr_accessor :not_on_or_after
|
12
|
+
|
13
|
+
# A URI specifying the entity or location to which an attesting entity can present the assertion. For
|
14
|
+
# example, this attribute might indicate that the assertion must be delivered to a particular network
|
15
|
+
# endpoint in order to prevent an intermediary from redirecting it someplace else.
|
16
|
+
attr_accessor :recipient
|
17
|
+
|
18
|
+
# The ID of a SAML protocol message in response to which an attesting entity can present the
|
19
|
+
# assertion. For example, this attribute might be used to correlate the assertion to a SAML request that
|
20
|
+
# resulted in its presentation.
|
21
|
+
attr_accessor :in_response_to
|
22
|
+
|
23
|
+
# The network address/location from which an attesting entity can present the assertion. For example,
|
24
|
+
# this attribute might be used to bind the assertion to particular client addresses to prevent an attacker
|
25
|
+
# from easily stealing and presenting the assertion from another location.
|
26
|
+
attr_accessor :address
|
27
|
+
|
28
|
+
# Point for extension attributes
|
29
|
+
def attributes
|
30
|
+
@attributes = []
|
31
|
+
end
|
32
|
+
|
33
|
+
# Point for extension elements
|
34
|
+
def elements
|
35
|
+
@elements = []
|
36
|
+
end
|
37
|
+
|
38
|
+
# Confirm the subject confirmation data
|
39
|
+
def confirm
|
40
|
+
raise ConfirmationError, "Subject confirmation failed: not before" if not_before && Time.now < not_before
|
41
|
+
raise ConfirmationError, "Subject confirmation failed: not on or after" if not_on_or_after && Time.now >= not_on_or_after
|
42
|
+
# TODO implement tests for remaining elements such as recipient, in_response_to and address
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_xml(xml=Builder::XmlMarkup.new)
|
46
|
+
attributes = {}
|
47
|
+
attributes['Recipient'] = recipient unless recipient.nil?
|
48
|
+
attributes['NotOnOrAfter'] = not_on_or_after.xmlschema unless not_on_or_after.nil?
|
49
|
+
attributes['NotBefore'] = not_before.xmlschema unless not_before.nil?
|
50
|
+
attributes['InResponseTo'] = in_response_to unless in_response_to.nil?
|
51
|
+
attributes[ 'Address'] = address unless address.nil?
|
52
|
+
xml.tag!('saml:SubjectConfirmationData', attributes)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module RSAML #:nodoc:
|
2
|
+
# This element is entirely advisory, since both of these fields are quite easily "spoofed,"
|
3
|
+
# but may be useful information in some applications.
|
4
|
+
class SubjectLocality
|
5
|
+
# The network address of the system from which the principal identified by the subject was
|
6
|
+
# authenticated.
|
7
|
+
attr_accessor :address
|
8
|
+
|
9
|
+
# The DNS name of the system from which the principal identified by the subject was authenticated.
|
10
|
+
attr_accessor :dns_name
|
11
|
+
|
12
|
+
# Raise an error if the subject locality is structurally invalid.
|
13
|
+
def validate
|
14
|
+
unless address =~ /^(\d{1,3}\.){3}\d{1,3}$/
|
15
|
+
raise ValidationError, "Invalid address"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Construct an XML fragment representing the subject locality
|
20
|
+
def to_xml(xml=Builder::XmlMarkup.new)
|
21
|
+
attributes = {}
|
22
|
+
attributes['Address'] = address unless address.nil?
|
23
|
+
attributes['DNSName'] = dns_name unless dns_name.nil?
|
24
|
+
xml.tag!('saml:SubjectLocality', attributes)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module RSAML
|
2
|
+
# Module that can be mixed in to any class to provide a :valid? method. This method
|
3
|
+
# will look for a :validate method and invoke it, catching any ValidationError exceptions
|
4
|
+
# and return either true if the SAML object is structurally valid or false if it isn't.
|
5
|
+
module Validatable
|
6
|
+
attr_accessor :verbose
|
7
|
+
# Return true if the object is valid. Only objects with a validate method will
|
8
|
+
# be checked for validity.
|
9
|
+
def valid?
|
10
|
+
if respond_to?(:validate)
|
11
|
+
begin
|
12
|
+
validate
|
13
|
+
rescue ValidationError => e
|
14
|
+
puts "Validation failed: #{e.message}" if verbose
|
15
|
+
return false
|
16
|
+
end
|
17
|
+
end
|
18
|
+
return true
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/xml_enc.rb
ADDED
data/lib/xml_sig.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
# Ruby XML Signature implementation
|
2
|
+
module XmlSig
|
3
|
+
end
|
4
|
+
|
5
|
+
require 'xml_sig/signature'
|
6
|
+
require 'xml_sig/signature_method'
|
7
|
+
require 'xml_sig/canonicalization_method'
|
8
|
+
require 'xml_sig/reference'
|
9
|
+
require 'xml_sig/signed_info'
|
10
|
+
require 'xml_sig/key_info'
|
11
|
+
require 'xml_sig/transform'
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'iconv'
|
2
|
+
|
3
|
+
module XmlSig #:nodoc:
|
4
|
+
class CanonicalizationMethod
|
5
|
+
attr_accessor :algorithm
|
6
|
+
|
7
|
+
def validate
|
8
|
+
raise ValidationError, "Algorithm is required" if algorithm.nil?
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_xml(xml=Builder::XmlMarkup.new)
|
12
|
+
attributes = {'Algorightm' => algorithm}
|
13
|
+
xml.tag!('ds:CanonicalizationMethod', attributes)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class XMLC14NBase
|
18
|
+
# Convert the content from the given charset to UTF-8.
|
19
|
+
def convert_to_utf8(content, from)
|
20
|
+
Iconv.iconv('UTF-8', from, content).join
|
21
|
+
end
|
22
|
+
def convert_linebreaks(content)
|
23
|
+
content.gsub(/\r\n/, "\n").gsub(/\r/, "\n")
|
24
|
+
end
|
25
|
+
def normalize_attribute_values(content)
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Canonicalization algorithm for XML removing comments
|
31
|
+
class XMLC14NWithComments < XMLC14NBase
|
32
|
+
def process(content, charset='UTF-8')
|
33
|
+
content = convert_to_utf8(content) unless charset == 'UTF-8'
|
34
|
+
content
|
35
|
+
end
|
36
|
+
end
|
37
|
+
class XMLC14NWithoutComments < XMLC14NBase
|
38
|
+
def process(content, charset='UTF-8')
|
39
|
+
content = convert_to_utf8(content) unless charset == 'UTF-8'
|
40
|
+
doc = REXML::Document.new(content)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module XmlSig #:nodoc:
|
2
|
+
class KeyInfo
|
3
|
+
attr_accessor :id
|
4
|
+
attr_accessor :key_name
|
5
|
+
attr_accessor :key_value
|
6
|
+
attr_accessor :retrieval_method
|
7
|
+
attr_accessor :key_data
|
8
|
+
|
9
|
+
def to_xml(xml=Builder::XmlMarkup.new)
|
10
|
+
xml.tag!('ds:KeyInfo') {
|
11
|
+
xml.tag!('ds:KeyName', key_name)
|
12
|
+
xml.tag!('ds:KeyValue') {
|
13
|
+
xml << key_value.to_xml
|
14
|
+
}
|
15
|
+
}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class RetrievalMethod
|
20
|
+
attr_accessor :uri
|
21
|
+
attr_accessor :type
|
22
|
+
|
23
|
+
def transforms
|
24
|
+
@transforms ||= []
|
25
|
+
end
|
26
|
+
|
27
|
+
def validate
|
28
|
+
raise ValidationError, "URI is required" if uri.nil?
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_xml(xml=Builder::XmlMarkup.new)
|
32
|
+
attributes = {'URI' => uri}
|
33
|
+
attributes['Type'] = type unless type.nil?
|
34
|
+
xml.tag!('ds:RetrievalMethod', attributes) {
|
35
|
+
transforms.each { |transform| xml << transform.to_xml }
|
36
|
+
}
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# REQUIRED
|
41
|
+
class DSAKeyValue
|
42
|
+
end
|
43
|
+
# OPTIONAL
|
44
|
+
class RSAKeyValue
|
45
|
+
end
|
46
|
+
|
47
|
+
class X509Data
|
48
|
+
end
|
49
|
+
class PGPData
|
50
|
+
end
|
51
|
+
class SPKIData
|
52
|
+
end
|
53
|
+
class MgmtData
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module XmlSig #:nooc:
|
2
|
+
class Reference
|
3
|
+
attr_accessor :id
|
4
|
+
attr_accessor :uri
|
5
|
+
attr_accessor :type
|
6
|
+
|
7
|
+
attr_accessor :digest_method
|
8
|
+
|
9
|
+
# DigestValue is an element that contains the encoded value of the digest. The
|
10
|
+
# digest is always encoded using base64
|
11
|
+
attr_accessor :digest_value
|
12
|
+
|
13
|
+
def transforms
|
14
|
+
@transforms ||= []
|
15
|
+
end
|
16
|
+
|
17
|
+
def validate
|
18
|
+
raise ValidationError, "Digest method is required" if digest_method.nil?
|
19
|
+
raise ValidationError, "Digest value is required" if digest_value.nil?
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_xml(xml=Builder::XmlMarkup.new)
|
23
|
+
attributes = {}
|
24
|
+
attributes['Id'] = id unless id.nil?
|
25
|
+
attributes['URI'] = uri unless uri.nil?
|
26
|
+
attributes['Type'] = type unless type.nil?
|
27
|
+
xml.tag!('ds:Reference', attributes) {
|
28
|
+
xml.tag!('ds:Transforms') {
|
29
|
+
transforms.each { |transform| xml << transform.to_xml }
|
30
|
+
}
|
31
|
+
xml << digest_method.to_xml unless digest_method.nil?
|
32
|
+
xml.tag!('ds:DigestValue', digest_value)
|
33
|
+
}
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# DigestMethod is a required element that identifies the digest algorithm to be applied
|
38
|
+
# to the signed object.
|
39
|
+
class DigestMethod
|
40
|
+
def self.identifiers
|
41
|
+
@identifiers ||= {
|
42
|
+
'SHA-1', 'http://www.w3.org/2000/09/xmldsig#sha1'
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
attr_accessor :algorithm
|
47
|
+
|
48
|
+
def validate
|
49
|
+
raise ValidationError, "Algorithm is required" if algorithm.nil?
|
50
|
+
end
|
51
|
+
|
52
|
+
def to_xml(xml=Builder::XmlMarkup.new)
|
53
|
+
attributes = {'Algorightm' => algorithm}
|
54
|
+
xml.tag!('ds:DigestMethod', attributes)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|