saml-kit 0.1.0 → 0.2.0
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/exe/saml-kit-decode-http-post +8 -0
 - data/lib/saml/kit.rb +4 -4
 - data/lib/saml/kit/authentication_request.rb +3 -13
 - data/lib/saml/kit/bindings.rb +45 -0
 - data/lib/saml/kit/bindings/binding.rb +42 -0
 - data/lib/saml/kit/bindings/http_post.rb +29 -0
 - data/lib/saml/kit/bindings/http_redirect.rb +61 -0
 - data/lib/saml/kit/bindings/url_builder.rb +40 -0
 - data/lib/saml/kit/configuration.rb +22 -1
 - data/lib/saml/kit/crypto.rb +16 -0
 - data/lib/saml/kit/crypto/oaep_cipher.rb +22 -0
 - data/lib/saml/kit/crypto/rsa_cipher.rb +23 -0
 - data/lib/saml/kit/crypto/simple_cipher.rb +38 -0
 - data/lib/saml/kit/crypto/unknown_cipher.rb +18 -0
 - data/lib/saml/kit/cryptography.rb +30 -0
 - data/lib/saml/kit/default_registry.rb +1 -0
 - data/lib/saml/kit/document.rb +6 -2
 - data/lib/saml/kit/identity_provider_metadata.rb +9 -9
 - data/lib/saml/kit/locales/en.yml +4 -3
 - data/lib/saml/kit/logout_request.rb +2 -2
 - data/lib/saml/kit/logout_response.rb +3 -3
 - data/lib/saml/kit/metadata.rb +12 -37
 - data/lib/saml/kit/namespaces.rb +1 -13
 - data/lib/saml/kit/respondable.rb +4 -0
 - data/lib/saml/kit/response.rb +120 -37
 - data/lib/saml/kit/service_provider_metadata.rb +16 -7
 - data/lib/saml/kit/signature.rb +16 -13
 - data/lib/saml/kit/trustable.rb +14 -6
 - data/lib/saml/kit/version.rb +1 -1
 - data/lib/saml/kit/xml.rb +19 -3
 - data/saml-kit.gemspec +2 -2
 - metadata +23 -14
 - data/lib/saml/kit/binding.rb +0 -40
 - data/lib/saml/kit/http_post_binding.rb +0 -27
 - data/lib/saml/kit/http_redirect_binding.rb +0 -58
 - data/lib/saml/kit/url_builder.rb +0 -38
 
| 
         @@ -0,0 +1,38 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Saml
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Kit
         
     | 
| 
      
 3 
     | 
    
         
            +
                module Crypto
         
     | 
| 
      
 4 
     | 
    
         
            +
                  class SimpleCipher
         
     | 
| 
      
 5 
     | 
    
         
            +
                    ALGORITHMS = {
         
     | 
| 
      
 6 
     | 
    
         
            +
                      'http://www.w3.org/2001/04/xmlenc#tripledes-cbc' => 'DES-EDE3-CBC',
         
     | 
| 
      
 7 
     | 
    
         
            +
                      'http://www.w3.org/2001/04/xmlenc#aes128-cbc' => 'AES-128-CBC',
         
     | 
| 
      
 8 
     | 
    
         
            +
                      'http://www.w3.org/2001/04/xmlenc#aes192-cbc' => 'AES-192-CBC',
         
     | 
| 
      
 9 
     | 
    
         
            +
                      'http://www.w3.org/2001/04/xmlenc#aes256-cbc' => 'AES-256-CBC',
         
     | 
| 
      
 10 
     | 
    
         
            +
                    }
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                    def initialize(algorithm, private_key)
         
     | 
| 
      
 13 
     | 
    
         
            +
                      @algorithm = algorithm
         
     | 
| 
      
 14 
     | 
    
         
            +
                      @private_key = private_key
         
     | 
| 
      
 15 
     | 
    
         
            +
                    end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                    def self.matches?(algorithm)
         
     | 
| 
      
 18 
     | 
    
         
            +
                      ALGORITHMS[algorithm]
         
     | 
| 
      
 19 
     | 
    
         
            +
                    end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                    def decrypt(cipher_text)
         
     | 
| 
      
 22 
     | 
    
         
            +
                      cipher = OpenSSL::Cipher.new(ALGORITHMS[@algorithm])
         
     | 
| 
      
 23 
     | 
    
         
            +
                      cipher.decrypt
         
     | 
| 
      
 24 
     | 
    
         
            +
                      iv = cipher_text[0..cipher.iv_len-1]
         
     | 
| 
      
 25 
     | 
    
         
            +
                      data = cipher_text[cipher.iv_len..-1]
         
     | 
| 
      
 26 
     | 
    
         
            +
                      #cipher.padding = 0
         
     | 
| 
      
 27 
     | 
    
         
            +
                      cipher.key = @private_key
         
     | 
| 
      
 28 
     | 
    
         
            +
                      cipher.iv = iv
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                      Saml::Kit.logger.debug ['-key', @private_key].inspect
         
     | 
| 
      
 31 
     | 
    
         
            +
                      Saml::Kit.logger.debug ['-iv', iv].inspect
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                      cipher.update(data) + cipher.final
         
     | 
| 
      
 34 
     | 
    
         
            +
                    end
         
     | 
| 
      
 35 
     | 
    
         
            +
                  end
         
     | 
| 
      
 36 
     | 
    
         
            +
                end
         
     | 
| 
      
 37 
     | 
    
         
            +
              end
         
     | 
| 
      
 38 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,30 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Saml
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Kit
         
     | 
| 
      
 3 
     | 
    
         
            +
                class Cryptography
         
     | 
| 
      
 4 
     | 
    
         
            +
                  attr_reader :private_key
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                  def initialize(private_key = Saml::Kit.configuration.encryption_private_key)
         
     | 
| 
      
 7 
     | 
    
         
            +
                    @private_key = private_key
         
     | 
| 
      
 8 
     | 
    
         
            +
                  end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                  def decrypt(data)
         
     | 
| 
      
 11 
     | 
    
         
            +
                    encrypt_data = data['EncryptedData']
         
     | 
| 
      
 12 
     | 
    
         
            +
                    symmetric_key = symmetric_key_from(encrypt_data)
         
     | 
| 
      
 13 
     | 
    
         
            +
                    cipher_text = Base64.decode64(encrypt_data["CipherData"]["CipherValue"])
         
     | 
| 
      
 14 
     | 
    
         
            +
                    to_plaintext(cipher_text, symmetric_key, encrypt_data["EncryptionMethod"]['Algorithm'])
         
     | 
| 
      
 15 
     | 
    
         
            +
                  end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                  private
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  def symmetric_key_from(encrypted_data)
         
     | 
| 
      
 20 
     | 
    
         
            +
                    encrypted_key = encrypted_data['KeyInfo']['EncryptedKey']
         
     | 
| 
      
 21 
     | 
    
         
            +
                    cipher_text = Base64.decode64(encrypted_key['CipherData']['CipherValue'])
         
     | 
| 
      
 22 
     | 
    
         
            +
                    to_plaintext(cipher_text, private_key, encrypted_key["EncryptionMethod"]['Algorithm'])
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                  def to_plaintext(cipher_text, symmetric_key, algorithm)
         
     | 
| 
      
 26 
     | 
    
         
            +
                    return Crypto.decryptor_for(algorithm, symmetric_key).decrypt(cipher_text)
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/saml/kit/document.rb
    CHANGED
    
    
| 
         @@ -7,7 +7,7 @@ module Saml 
     | 
|
| 
       7 
7 
     | 
    
         | 
| 
       8 
8 
     | 
    
         
             
                  def want_authn_requests_signed
         
     | 
| 
       9 
9 
     | 
    
         
             
                    xpath = "/md:EntityDescriptor/md:#{name}"
         
     | 
| 
       10 
     | 
    
         
            -
                    attribute = find_by(xpath).attribute("WantAuthnRequestsSigned")
         
     | 
| 
      
 10 
     | 
    
         
            +
                    attribute = document.find_by(xpath).attribute("WantAuthnRequestsSigned")
         
     | 
| 
       11 
11 
     | 
    
         
             
                    return true if attribute.nil?
         
     | 
| 
       12 
12 
     | 
    
         
             
                    attribute.text.downcase == "true"
         
     | 
| 
       13 
13 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -21,7 +21,7 @@ module Saml 
     | 
|
| 
       21 
21 
     | 
    
         
             
                  end
         
     | 
| 
       22 
22 
     | 
    
         | 
| 
       23 
23 
     | 
    
         
             
                  def attributes
         
     | 
| 
       24 
     | 
    
         
            -
                    find_all("/md:EntityDescriptor/md:#{name}/saml:Attribute").map do |item|
         
     | 
| 
      
 24 
     | 
    
         
            +
                    document.find_all("/md:EntityDescriptor/md:#{name}/saml:Attribute").map do |item|
         
     | 
| 
       25 
25 
     | 
    
         
             
                      {
         
     | 
| 
       26 
26 
     | 
    
         
             
                        format: item.attribute("NameFormat").try(:value),
         
     | 
| 
       27 
27 
     | 
    
         
             
                        name: item.attribute("Name").value,
         
     | 
| 
         @@ -48,19 +48,19 @@ module Saml 
     | 
|
| 
       48 
48 
     | 
    
         
             
                      @want_authn_requests_signed = true
         
     | 
| 
       49 
49 
     | 
    
         
             
                    end
         
     | 
| 
       50 
50 
     | 
    
         | 
| 
       51 
     | 
    
         
            -
                    def add_single_sign_on_service(url, binding: : 
     | 
| 
       52 
     | 
    
         
            -
                      @single_sign_on_urls.push(location: url, binding:  
     | 
| 
      
 51 
     | 
    
         
            +
                    def add_single_sign_on_service(url, binding: :http_post)
         
     | 
| 
      
 52 
     | 
    
         
            +
                      @single_sign_on_urls.push(location: url, binding: Bindings.binding_for(binding))
         
     | 
| 
       53 
53 
     | 
    
         
             
                    end
         
     | 
| 
       54 
54 
     | 
    
         | 
| 
       55 
     | 
    
         
            -
                    def add_single_logout_service(url, binding: : 
     | 
| 
       56 
     | 
    
         
            -
                      @logout_urls.push(location: url, binding:  
     | 
| 
      
 55 
     | 
    
         
            +
                    def add_single_logout_service(url, binding: :http_post)
         
     | 
| 
      
 56 
     | 
    
         
            +
                      @logout_urls.push(location: url, binding: Bindings.binding_for(binding))
         
     | 
| 
       57 
57 
     | 
    
         
             
                    end
         
     | 
| 
       58 
58 
     | 
    
         | 
| 
       59 
59 
     | 
    
         
             
                    def to_xml
         
     | 
| 
       60 
     | 
    
         
            -
                      Signature.sign( 
     | 
| 
      
 60 
     | 
    
         
            +
                      Signature.sign(sign: sign) do |xml, signature|
         
     | 
| 
       61 
61 
     | 
    
         
             
                        xml.instruct!
         
     | 
| 
       62 
62 
     | 
    
         
             
                        xml.EntityDescriptor entity_descriptor_options do
         
     | 
| 
       63 
     | 
    
         
            -
                          signature.template( 
     | 
| 
      
 63 
     | 
    
         
            +
                          signature.template(id)
         
     | 
| 
       64 
64 
     | 
    
         
             
                          xml.IDPSSODescriptor idp_sso_descriptor_options do
         
     | 
| 
       65 
65 
     | 
    
         
             
                            xml.KeyDescriptor use: "signing" do
         
     | 
| 
       66 
66 
     | 
    
         
             
                              xml.KeyInfo "xmlns": Namespaces::XMLDSIG do
         
     | 
| 
         @@ -112,8 +112,8 @@ module Saml 
     | 
|
| 
       112 
112 
     | 
    
         | 
| 
       113 
113 
     | 
    
         
             
                    def idp_sso_descriptor_options
         
     | 
| 
       114 
114 
     | 
    
         
             
                      {
         
     | 
| 
      
 115 
     | 
    
         
            +
                        WantAuthnRequestsSigned: want_authn_requests_signed,
         
     | 
| 
       115 
116 
     | 
    
         
             
                        protocolSupportEnumeration: Namespaces::PROTOCOL,
         
     | 
| 
       116 
     | 
    
         
            -
                        WantAuthnRequestsSigned: want_authn_requests_signed
         
     | 
| 
       117 
117 
     | 
    
         
             
                      }
         
     | 
| 
       118 
118 
     | 
    
         
             
                    end
         
     | 
| 
       119 
119 
     | 
    
         
             
                  end
         
     | 
    
        data/lib/saml/kit/locales/en.yml
    CHANGED
    
    | 
         @@ -14,12 +14,13 @@ en: 
     | 
|
| 
       14 
14 
     | 
    
         
             
                  LogoutResponse:
         
     | 
| 
       15 
15 
     | 
    
         
             
                    unregistered: "is unregistered."
         
     | 
| 
       16 
16 
     | 
    
         
             
                  Response:
         
     | 
| 
       17 
     | 
    
         
            -
                    invalid: "must contain Response."
         
     | 
| 
       18 
     | 
    
         
            -
                    unregistered: "must originate from registered identity provider."
         
     | 
| 
       19 
17 
     | 
    
         
             
                    expired: "must not be expired."
         
     | 
| 
       20 
     | 
    
         
            -
                     
     | 
| 
      
 18 
     | 
    
         
            +
                    invalid: "must contain Response."
         
     | 
| 
      
 19 
     | 
    
         
            +
                    invalid_fingerprint: "does not match."
         
     | 
| 
       21 
20 
     | 
    
         
             
                    invalid_response_to: "must match request id."
         
     | 
| 
      
 21 
     | 
    
         
            +
                    invalid_version: "must be 2.0."
         
     | 
| 
       22 
22 
     | 
    
         
             
                    must_match_issuer: "must match entityId."
         
     | 
| 
      
 23 
     | 
    
         
            +
                    unregistered: "must originate from registered identity provider."
         
     | 
| 
       23 
24 
     | 
    
         
             
                  SPSSODescriptor:
         
     | 
| 
       24 
25 
     | 
    
         
             
                    invalid: "must contain SPSSODescriptor."
         
     | 
| 
       25 
26 
     | 
    
         
             
                    invalid_signature: "invalid signature."
         
     | 
| 
         @@ -40,11 +40,11 @@ module Saml 
     | 
|
| 
       40 
40 
     | 
    
         
             
                    end
         
     | 
| 
       41 
41 
     | 
    
         | 
| 
       42 
42 
     | 
    
         
             
                    def to_xml
         
     | 
| 
       43 
     | 
    
         
            -
                      Signature.sign( 
     | 
| 
      
 43 
     | 
    
         
            +
                      Signature.sign(sign: sign) do |xml, signature|
         
     | 
| 
       44 
44 
     | 
    
         
             
                        xml.instruct!
         
     | 
| 
       45 
45 
     | 
    
         
             
                        xml.LogoutRequest logout_request_options do
         
     | 
| 
       46 
46 
     | 
    
         
             
                          xml.Issuer({ xmlns: Namespaces::ASSERTION }, issuer)
         
     | 
| 
       47 
     | 
    
         
            -
                          signature.template( 
     | 
| 
      
 47 
     | 
    
         
            +
                          signature.template(id)
         
     | 
| 
       48 
48 
     | 
    
         
             
                          xml.NameID name_id_options, user.name_id_for(name_id_format)
         
     | 
| 
       49 
49 
     | 
    
         
             
                        end
         
     | 
| 
       50 
50 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -25,15 +25,15 @@ module Saml 
     | 
|
| 
       25 
25 
     | 
    
         
             
                      @issuer = configuration.issuer
         
     | 
| 
       26 
26 
     | 
    
         
             
                      provider = configuration.registry.metadata_for(@issuer)
         
     | 
| 
       27 
27 
     | 
    
         
             
                      if provider
         
     | 
| 
       28 
     | 
    
         
            -
                        @destination = provider.single_logout_service_for(binding: : 
     | 
| 
      
 28 
     | 
    
         
            +
                        @destination = provider.single_logout_service_for(binding: :http_post).try(:location)
         
     | 
| 
       29 
29 
     | 
    
         
             
                      end
         
     | 
| 
       30 
30 
     | 
    
         
             
                    end
         
     | 
| 
       31 
31 
     | 
    
         | 
| 
       32 
32 
     | 
    
         
             
                    def to_xml
         
     | 
| 
       33 
     | 
    
         
            -
                      Signature.sign( 
     | 
| 
      
 33 
     | 
    
         
            +
                      Signature.sign(sign: sign) do |xml, signature|
         
     | 
| 
       34 
34 
     | 
    
         
             
                        xml.LogoutResponse logout_response_options do
         
     | 
| 
       35 
35 
     | 
    
         
             
                          xml.Issuer(issuer, xmlns: Namespaces::ASSERTION)
         
     | 
| 
       36 
     | 
    
         
            -
                          signature.template( 
     | 
| 
      
 36 
     | 
    
         
            +
                          signature.template(id)
         
     | 
| 
       37 
37 
     | 
    
         
             
                          xml.Status do
         
     | 
| 
       38 
38 
     | 
    
         
             
                            xml.StatusCode Value: status_code
         
     | 
| 
       39 
39 
     | 
    
         
             
                          end
         
     | 
    
        data/lib/saml/kit/metadata.rb
    CHANGED
    
    | 
         @@ -3,14 +3,7 @@ module Saml 
     | 
|
| 
       3 
3 
     | 
    
         
             
                class Metadata
         
     | 
| 
       4 
4 
     | 
    
         
             
                  include ActiveModel::Validations
         
     | 
| 
       5 
5 
     | 
    
         
             
                  include XsdValidatable
         
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
6 
     | 
    
         
             
                  METADATA_XSD = File.expand_path("./xsd/saml-schema-metadata-2.0.xsd", File.dirname(__FILE__)).freeze
         
     | 
| 
       8 
     | 
    
         
            -
                  NAMESPACES = {
         
     | 
| 
       9 
     | 
    
         
            -
                    "NameFormat": Namespaces::ATTR_SPLAT,
         
     | 
| 
       10 
     | 
    
         
            -
                    "ds": Namespaces::XMLDSIG,
         
     | 
| 
       11 
     | 
    
         
            -
                    "md": Namespaces::METADATA,
         
     | 
| 
       12 
     | 
    
         
            -
                    "saml": Namespaces::ASSERTION,
         
     | 
| 
       13 
     | 
    
         
            -
                  }.freeze
         
     | 
| 
       14 
7 
     | 
    
         | 
| 
       15 
8 
     | 
    
         
             
                  validates_presence_of :metadata
         
     | 
| 
       16 
9 
     | 
    
         
             
                  validate :must_contain_descriptor
         
     | 
| 
         @@ -27,16 +20,16 @@ module Saml 
     | 
|
| 
       27 
20 
     | 
    
         
             
                  end
         
     | 
| 
       28 
21 
     | 
    
         | 
| 
       29 
22 
     | 
    
         
             
                  def entity_id
         
     | 
| 
       30 
     | 
    
         
            -
                    find_by("/md:EntityDescriptor/@entityID").value
         
     | 
| 
      
 23 
     | 
    
         
            +
                    document.find_by("/md:EntityDescriptor/@entityID").value
         
     | 
| 
       31 
24 
     | 
    
         
             
                  end
         
     | 
| 
       32 
25 
     | 
    
         | 
| 
       33 
26 
     | 
    
         
             
                  def name_id_formats
         
     | 
| 
       34 
     | 
    
         
            -
                    find_all("/md:EntityDescriptor/md:#{name}/md:NameIDFormat").map(&:text)
         
     | 
| 
      
 27 
     | 
    
         
            +
                    document.find_all("/md:EntityDescriptor/md:#{name}/md:NameIDFormat").map(&:text)
         
     | 
| 
       35 
28 
     | 
    
         
             
                  end
         
     | 
| 
       36 
29 
     | 
    
         | 
| 
       37 
30 
     | 
    
         
             
                  def certificates
         
     | 
| 
       38 
     | 
    
         
            -
                    @certificates ||= find_all("/md:EntityDescriptor/md:#{name}/md:KeyDescriptor").map do |item|
         
     | 
| 
       39 
     | 
    
         
            -
                      cert = item.at_xpath("./ds:KeyInfo/ds:X509Data/ds:X509Certificate", NAMESPACES).text
         
     | 
| 
      
 31 
     | 
    
         
            +
                    @certificates ||= document.find_all("/md:EntityDescriptor/md:#{name}/md:KeyDescriptor").map do |item|
         
     | 
| 
      
 32 
     | 
    
         
            +
                      cert = item.at_xpath("./ds:KeyInfo/ds:X509Data/ds:X509Certificate", Xml::NAMESPACES).text
         
     | 
| 
       40 
33 
     | 
    
         
             
                      {
         
     | 
| 
       41 
34 
     | 
    
         
             
                        text: cert,
         
     | 
| 
       42 
35 
     | 
    
         
             
                        fingerprint: Fingerprint.new(cert).algorithm(hash_algorithm),
         
     | 
| 
         @@ -54,15 +47,15 @@ module Saml 
     | 
|
| 
       54 
47 
     | 
    
         
             
                  end
         
     | 
| 
       55 
48 
     | 
    
         | 
| 
       56 
49 
     | 
    
         
             
                  def services(type)
         
     | 
| 
       57 
     | 
    
         
            -
                    find_all("/md:EntityDescriptor/md:#{name}/md:#{type}").map do |item|
         
     | 
| 
      
 50 
     | 
    
         
            +
                    document.find_all("/md:EntityDescriptor/md:#{name}/md:#{type}").map do |item|
         
     | 
| 
       58 
51 
     | 
    
         
             
                      binding = item.attribute("Binding").value
         
     | 
| 
       59 
52 
     | 
    
         
             
                      location = item.attribute("Location").value
         
     | 
| 
       60 
     | 
    
         
            -
                       
     | 
| 
      
 53 
     | 
    
         
            +
                      Saml::Kit::Bindings.create_for(binding, location)
         
     | 
| 
       61 
54 
     | 
    
         
             
                    end
         
     | 
| 
       62 
55 
     | 
    
         
             
                  end
         
     | 
| 
       63 
56 
     | 
    
         | 
| 
       64 
57 
     | 
    
         
             
                  def service_for(binding:, type:)
         
     | 
| 
       65 
     | 
    
         
            -
                    binding = Saml::Kit:: 
     | 
| 
      
 58 
     | 
    
         
            +
                    binding = Saml::Kit::Bindings.binding_for(binding)
         
     | 
| 
       66 
59 
     | 
    
         
             
                    services(type).find { |x| x.binding?(binding) }
         
     | 
| 
       67 
60 
     | 
    
         
             
                  end
         
     | 
| 
       68 
61 
     | 
    
         | 
| 
         @@ -78,6 +71,7 @@ module Saml 
     | 
|
| 
       78 
71 
     | 
    
         
             
                    if :signing == use.to_sym
         
     | 
| 
       79 
72 
     | 
    
         
             
                      hash_value = fingerprint.algorithm(hash_algorithm)
         
     | 
| 
       80 
73 
     | 
    
         
             
                      signing_certificates.find do |signing_certificate|
         
     | 
| 
      
 74 
     | 
    
         
            +
                        Saml::Kit.logger.debug [hash_value, signing_certificate[:fingerprint]].inspect
         
     | 
| 
       81 
75 
     | 
    
         
             
                        hash_value == signing_certificate[:fingerprint]
         
     | 
| 
       82 
76 
     | 
    
         
             
                      end
         
     | 
| 
       83 
77 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -87,8 +81,8 @@ module Saml 
     | 
|
| 
       87 
81 
     | 
    
         
             
                    @xml_hash ||= Hash.from_xml(to_xml)
         
     | 
| 
       88 
82 
     | 
    
         
             
                  end
         
     | 
| 
       89 
83 
     | 
    
         | 
| 
       90 
     | 
    
         
            -
                  def to_xml
         
     | 
| 
       91 
     | 
    
         
            -
                     
     | 
| 
      
 84 
     | 
    
         
            +
                  def to_xml(pretty: false)
         
     | 
| 
      
 85 
     | 
    
         
            +
                    document.to_xml(pretty: pretty)
         
     | 
| 
       92 
86 
     | 
    
         
             
                  end
         
     | 
| 
       93 
87 
     | 
    
         | 
| 
       94 
88 
     | 
    
         
             
                  def to_s
         
     | 
| 
         @@ -116,19 +110,11 @@ module Saml 
     | 
|
| 
       116 
110 
     | 
    
         
             
                  private
         
     | 
| 
       117 
111 
     | 
    
         | 
| 
       118 
112 
     | 
    
         
             
                  def document
         
     | 
| 
       119 
     | 
    
         
            -
                    @document ||=  
     | 
| 
       120 
     | 
    
         
            -
                  end
         
     | 
| 
       121 
     | 
    
         
            -
             
     | 
| 
       122 
     | 
    
         
            -
                  def find_by(xpath)
         
     | 
| 
       123 
     | 
    
         
            -
                    document.at_xpath(xpath, NAMESPACES)
         
     | 
| 
       124 
     | 
    
         
            -
                  end
         
     | 
| 
       125 
     | 
    
         
            -
             
     | 
| 
       126 
     | 
    
         
            -
                  def find_all(xpath)
         
     | 
| 
       127 
     | 
    
         
            -
                    document.search(xpath, NAMESPACES)
         
     | 
| 
      
 113 
     | 
    
         
            +
                    @document ||= Xml.new(xml)
         
     | 
| 
       128 
114 
     | 
    
         
             
                  end
         
     | 
| 
       129 
115 
     | 
    
         | 
| 
       130 
116 
     | 
    
         
             
                  def metadata
         
     | 
| 
       131 
     | 
    
         
            -
                    find_by("/md:EntityDescriptor/md:#{name}").present?
         
     | 
| 
      
 117 
     | 
    
         
            +
                    document.find_by("/md:EntityDescriptor/md:#{name}").present?
         
     | 
| 
       132 
118 
     | 
    
         
             
                  end
         
     | 
| 
       133 
119 
     | 
    
         | 
| 
       134 
120 
     | 
    
         
             
                  def must_contain_descriptor
         
     | 
| 
         @@ -155,17 +141,6 @@ module Saml 
     | 
|
| 
       155 
141 
     | 
    
         
             
                    end
         
     | 
| 
       156 
142 
     | 
    
         
             
                    result
         
     | 
| 
       157 
143 
     | 
    
         
             
                  end
         
     | 
| 
       158 
     | 
    
         
            -
             
     | 
| 
       159 
     | 
    
         
            -
                  def binding_for(binding, location)
         
     | 
| 
       160 
     | 
    
         
            -
                    case binding
         
     | 
| 
       161 
     | 
    
         
            -
                    when Namespaces::HTTP_REDIRECT
         
     | 
| 
       162 
     | 
    
         
            -
                      Saml::Kit::HttpRedirectBinding.new(location: location)
         
     | 
| 
       163 
     | 
    
         
            -
                    when Namespaces::POST
         
     | 
| 
       164 
     | 
    
         
            -
                      Saml::Kit::HttpPostBinding.new(location: location)
         
     | 
| 
       165 
     | 
    
         
            -
                    else
         
     | 
| 
       166 
     | 
    
         
            -
                      Saml::Kit::Binding.new(binding: binding, location: location)
         
     | 
| 
       167 
     | 
    
         
            -
                    end
         
     | 
| 
       168 
     | 
    
         
            -
                  end
         
     | 
| 
       169 
144 
     | 
    
         
             
                end
         
     | 
| 
       170 
145 
     | 
    
         
             
              end
         
     | 
| 
       171 
146 
     | 
    
         
             
            end
         
     | 
    
        data/lib/saml/kit/namespaces.rb
    CHANGED
    
    | 
         @@ -7,9 +7,6 @@ module Saml 
     | 
|
| 
       7 
7 
     | 
    
         
             
                  BEARER = "urn:oasis:names:tc:SAML:2.0:cm:bearer"
         
     | 
| 
       8 
8 
     | 
    
         
             
                  EMAIL_ADDRESS = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
         
     | 
| 
       9 
9 
     | 
    
         
             
                  ENVELOPED_SIG = "http://www.w3.org/2000/09/xmldsig#enveloped-signature"
         
     | 
| 
       10 
     | 
    
         
            -
                  HTTP_ARTIFACT = 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact'
         
     | 
| 
       11 
     | 
    
         
            -
                  HTTP_POST = POST = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
         
     | 
| 
       12 
     | 
    
         
            -
                  HTTP_REDIRECT = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
         
     | 
| 
       13 
10 
     | 
    
         
             
                  METADATA = "urn:oasis:names:tc:SAML:2.0:metadata"
         
     | 
| 
       14 
11 
     | 
    
         
             
                  PASSWORD = "urn:oasis:names:tc:SAML:2.0:ac:classes:Password"
         
     | 
| 
       15 
12 
     | 
    
         
             
                  PASSWORD_PROTECTED = "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport"
         
     | 
| 
         @@ -32,16 +29,7 @@ module Saml 
     | 
|
| 
       32 
29 
     | 
    
         
             
                  URI = "urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
         
     | 
| 
       33 
30 
     | 
    
         
             
                  VERSION_MISMATCH_ERROR = "urn:oasis:names:tc:SAML:2.0:status:VersionMismatch"
         
     | 
| 
       34 
31 
     | 
    
         
             
                  XMLDSIG = "http://www.w3.org/2000/09/xmldsig#"
         
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
                  def self.binding_for(binding)
         
     | 
| 
       37 
     | 
    
         
            -
                    if :post == binding
         
     | 
| 
       38 
     | 
    
         
            -
                      Namespaces::HTTP_POST
         
     | 
| 
       39 
     | 
    
         
            -
                    elsif :http_redirect == binding
         
     | 
| 
       40 
     | 
    
         
            -
                      Namespaces::HTTP_REDIRECT
         
     | 
| 
       41 
     | 
    
         
            -
                    else
         
     | 
| 
       42 
     | 
    
         
            -
                      nil
         
     | 
| 
       43 
     | 
    
         
            -
                    end
         
     | 
| 
       44 
     | 
    
         
            -
                  end
         
     | 
| 
      
 32 
     | 
    
         
            +
                  XMLENC = "http://www.w3.org/2001/04/xmlenc#"
         
     | 
| 
       45 
33 
     | 
    
         
             
                end
         
     | 
| 
       46 
34 
     | 
    
         
             
              end
         
     | 
| 
       47 
35 
     | 
    
         
             
            end
         
     | 
    
        data/lib/saml/kit/respondable.rb
    CHANGED
    
    
    
        data/lib/saml/kit/response.rb
    CHANGED
    
    | 
         @@ -12,7 +12,7 @@ module Saml 
     | 
|
| 
       12 
12 
     | 
    
         
             
                  end
         
     | 
| 
       13 
13 
     | 
    
         | 
| 
       14 
14 
     | 
    
         
             
                  def name_id
         
     | 
| 
       15 
     | 
    
         
            -
                     
     | 
| 
      
 15 
     | 
    
         
            +
                    assertion.fetch('Subject', {}).fetch('NameID', nil)
         
     | 
| 
       16 
16 
     | 
    
         
             
                  end
         
     | 
| 
       17 
17 
     | 
    
         | 
| 
       18 
18 
     | 
    
         
             
                  def [](key)
         
     | 
| 
         @@ -20,18 +20,19 @@ module Saml 
     | 
|
| 
       20 
20 
     | 
    
         
             
                  end
         
     | 
| 
       21 
21 
     | 
    
         | 
| 
       22 
22 
     | 
    
         
             
                  def attributes
         
     | 
| 
       23 
     | 
    
         
            -
                    @attributes ||= Hash[ 
     | 
| 
       24 
     | 
    
         
            -
                       
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
      
 23 
     | 
    
         
            +
                    @attributes ||= Hash[
         
     | 
| 
      
 24 
     | 
    
         
            +
                      assertion.fetch('AttributeStatement', {}).fetch('Attribute', []).map do |item|
         
     | 
| 
      
 25 
     | 
    
         
            +
                        [item['Name'].to_sym, item['AttributeValue']]
         
     | 
| 
      
 26 
     | 
    
         
            +
                      end
         
     | 
| 
      
 27 
     | 
    
         
            +
                    ].with_indifferent_access
         
     | 
| 
       26 
28 
     | 
    
         
             
                  end
         
     | 
| 
       27 
29 
     | 
    
         | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
30 
     | 
    
         
             
                  def started_at
         
     | 
| 
       30 
     | 
    
         
            -
                    parse_date( 
     | 
| 
      
 31 
     | 
    
         
            +
                    parse_date(assertion.fetch('Conditions', {}).fetch('NotBefore', nil))
         
     | 
| 
       31 
32 
     | 
    
         
             
                  end
         
     | 
| 
       32 
33 
     | 
    
         | 
| 
       33 
34 
     | 
    
         
             
                  def expired_at
         
     | 
| 
       34 
     | 
    
         
            -
                    parse_date( 
     | 
| 
      
 35 
     | 
    
         
            +
                    parse_date(assertion.fetch('Conditions', {}).fetch('NotOnOrAfter', nil))
         
     | 
| 
       35 
36 
     | 
    
         
             
                  end
         
     | 
| 
       36 
37 
     | 
    
         | 
| 
       37 
38 
     | 
    
         
             
                  def expired?
         
     | 
| 
         @@ -42,15 +43,42 @@ module Saml 
     | 
|
| 
       42 
43 
     | 
    
         
             
                    Time.current > started_at && !expired?
         
     | 
| 
       43 
44 
     | 
    
         
             
                  end
         
     | 
| 
       44 
45 
     | 
    
         | 
| 
      
 46 
     | 
    
         
            +
                  def encrypted?
         
     | 
| 
      
 47 
     | 
    
         
            +
                    to_h[name]['EncryptedAssertion'].present?
         
     | 
| 
      
 48 
     | 
    
         
            +
                  end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                  def assertion
         
     | 
| 
      
 51 
     | 
    
         
            +
                    @assertion =
         
     | 
| 
      
 52 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 53 
     | 
    
         
            +
                        if encrypted?
         
     | 
| 
      
 54 
     | 
    
         
            +
                          decrypted = Cryptography.new.decrypt(to_h.fetch(name, {}).fetch('EncryptedAssertion', {}))
         
     | 
| 
      
 55 
     | 
    
         
            +
                          Saml::Kit.logger.debug(decrypted)
         
     | 
| 
      
 56 
     | 
    
         
            +
                          Hash.from_xml(decrypted)['Assertion']
         
     | 
| 
      
 57 
     | 
    
         
            +
                        else
         
     | 
| 
      
 58 
     | 
    
         
            +
                          to_h.fetch(name, {}).fetch('Assertion', {})
         
     | 
| 
      
 59 
     | 
    
         
            +
                        end
         
     | 
| 
      
 60 
     | 
    
         
            +
                      end
         
     | 
| 
      
 61 
     | 
    
         
            +
                  end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                  def signed?
         
     | 
| 
      
 64 
     | 
    
         
            +
                    super || assertion.fetch('Signature', nil).present?
         
     | 
| 
      
 65 
     | 
    
         
            +
                  end
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                  def certificate
         
     | 
| 
      
 68 
     | 
    
         
            +
                    super || assertion.fetch('Signature', {}).fetch('KeyInfo', {}).fetch('X509Data', {}).fetch('X509Certificate', nil)
         
     | 
| 
      
 69 
     | 
    
         
            +
                  end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
       45 
71 
     | 
    
         
             
                  private
         
     | 
| 
       46 
72 
     | 
    
         | 
| 
       47 
73 
     | 
    
         
             
                  def must_be_active_session
         
     | 
| 
       48 
74 
     | 
    
         
             
                    return unless expected_type?
         
     | 
| 
      
 75 
     | 
    
         
            +
                    return unless success?
         
     | 
| 
       49 
76 
     | 
    
         
             
                    errors[:base] << error_message(:expired) unless active?
         
     | 
| 
       50 
77 
     | 
    
         
             
                  end
         
     | 
| 
       51 
78 
     | 
    
         | 
| 
       52 
79 
     | 
    
         
             
                  def must_match_issuer
         
     | 
| 
       53 
80 
     | 
    
         
             
                    return unless expected_type?
         
     | 
| 
      
 81 
     | 
    
         
            +
                    return unless success?
         
     | 
| 
       54 
82 
     | 
    
         | 
| 
       55 
83 
     | 
    
         
             
                    unless audiences.include?(Saml::Kit.configuration.issuer)
         
     | 
| 
       56 
84 
     | 
    
         
             
                      errors[:audience] << error_message(:must_match_issuer)
         
     | 
| 
         @@ -58,7 +86,7 @@ module Saml 
     | 
|
| 
       58 
86 
     | 
    
         
             
                  end
         
     | 
| 
       59 
87 
     | 
    
         | 
| 
       60 
88 
     | 
    
         
             
                  def audiences
         
     | 
| 
       61 
     | 
    
         
            -
                    Array( 
     | 
| 
      
 89 
     | 
    
         
            +
                    Array(assertion['Conditions']['AudienceRestriction']['Audience'])
         
     | 
| 
       62 
90 
     | 
    
         
             
                  rescue => error
         
     | 
| 
       63 
91 
     | 
    
         
             
                    Saml::Kit.logger.error(error)
         
     | 
| 
       64 
92 
     | 
    
         
             
                    []
         
     | 
| 
         @@ -75,7 +103,7 @@ module Saml 
     | 
|
| 
       75 
103 
     | 
    
         
             
                    attr_reader :user, :request
         
     | 
| 
       76 
104 
     | 
    
         
             
                    attr_accessor :id, :reference_id, :now
         
     | 
| 
       77 
105 
     | 
    
         
             
                    attr_accessor :version, :status_code
         
     | 
| 
       78 
     | 
    
         
            -
                    attr_accessor :issuer, :sign, :destination
         
     | 
| 
      
 106 
     | 
    
         
            +
                    attr_accessor :issuer, :sign, :destination, :encrypt
         
     | 
| 
       79 
107 
     | 
    
         | 
| 
       80 
108 
     | 
    
         
             
                    def initialize(user, request)
         
     | 
| 
       81 
109 
     | 
    
         
             
                      @user = user
         
     | 
| 
         @@ -86,8 +114,9 @@ module Saml 
     | 
|
| 
       86 
114 
     | 
    
         
             
                      @version = "2.0"
         
     | 
| 
       87 
115 
     | 
    
         
             
                      @status_code = Namespaces::SUCCESS
         
     | 
| 
       88 
116 
     | 
    
         
             
                      @issuer = configuration.issuer
         
     | 
| 
       89 
     | 
    
         
            -
                      @destination = request 
     | 
| 
      
 117 
     | 
    
         
            +
                      @destination = destination_for(request)
         
     | 
| 
       90 
118 
     | 
    
         
             
                      @sign = want_assertions_signed
         
     | 
| 
      
 119 
     | 
    
         
            +
                      @encrypt = false
         
     | 
| 
       91 
120 
     | 
    
         
             
                    end
         
     | 
| 
       92 
121 
     | 
    
         | 
| 
       93 
122 
     | 
    
         
             
                    def want_assertions_signed
         
     | 
| 
         @@ -98,38 +127,51 @@ module Saml 
     | 
|
| 
       98 
127 
     | 
    
         
             
                    end
         
     | 
| 
       99 
128 
     | 
    
         | 
| 
       100 
129 
     | 
    
         
             
                    def to_xml
         
     | 
| 
       101 
     | 
    
         
            -
                      Signature.sign( 
     | 
| 
      
 130 
     | 
    
         
            +
                      Signature.sign(sign: sign) do |xml, signature|
         
     | 
| 
       102 
131 
     | 
    
         
             
                        xml.Response response_options do
         
     | 
| 
       103 
132 
     | 
    
         
             
                          xml.Issuer(issuer, xmlns: Namespaces::ASSERTION)
         
     | 
| 
       104 
     | 
    
         
            -
                          signature.template( 
     | 
| 
      
 133 
     | 
    
         
            +
                          signature.template(id)
         
     | 
| 
       105 
134 
     | 
    
         
             
                          xml.Status do
         
     | 
| 
       106 
135 
     | 
    
         
             
                            xml.StatusCode Value: status_code
         
     | 
| 
       107 
136 
     | 
    
         
             
                          end
         
     | 
| 
       108 
     | 
    
         
            -
                          xml 
     | 
| 
       109 
     | 
    
         
            -
             
     | 
| 
       110 
     | 
    
         
            -
             
     | 
| 
       111 
     | 
    
         
            -
             
     | 
| 
       112 
     | 
    
         
            -
             
     | 
| 
       113 
     | 
    
         
            -
             
     | 
| 
       114 
     | 
    
         
            -
             
     | 
| 
      
 137 
     | 
    
         
            +
                          assertion(xml, signature)
         
     | 
| 
      
 138 
     | 
    
         
            +
                        end
         
     | 
| 
      
 139 
     | 
    
         
            +
                      end
         
     | 
| 
      
 140 
     | 
    
         
            +
                    end
         
     | 
| 
      
 141 
     | 
    
         
            +
             
     | 
| 
      
 142 
     | 
    
         
            +
                    def build
         
     | 
| 
      
 143 
     | 
    
         
            +
                      Response.new(to_xml, request_id: request.id)
         
     | 
| 
      
 144 
     | 
    
         
            +
                    end
         
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
      
 146 
     | 
    
         
            +
                    private
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
                    def assertion(xml, signature)
         
     | 
| 
      
 149 
     | 
    
         
            +
                      with_encryption(xml) do |xml|
         
     | 
| 
      
 150 
     | 
    
         
            +
                        xml.Assertion(assertion_options) do
         
     | 
| 
      
 151 
     | 
    
         
            +
                          xml.Issuer issuer
         
     | 
| 
      
 152 
     | 
    
         
            +
                          signature.template(reference_id) unless encrypt
         
     | 
| 
      
 153 
     | 
    
         
            +
                          xml.Subject do
         
     | 
| 
      
 154 
     | 
    
         
            +
                            xml.NameID user.name_id_for(request.name_id_format), Format: request.name_id_format
         
     | 
| 
      
 155 
     | 
    
         
            +
                            xml.SubjectConfirmation Method: Namespaces::BEARER do
         
     | 
| 
      
 156 
     | 
    
         
            +
                              xml.SubjectConfirmationData "", subject_confirmation_data_options
         
     | 
| 
       115 
157 
     | 
    
         
             
                            end
         
     | 
| 
       116 
     | 
    
         
            -
             
     | 
| 
       117 
     | 
    
         
            -
             
     | 
| 
       118 
     | 
    
         
            -
             
     | 
| 
       119 
     | 
    
         
            -
                               
     | 
| 
      
 158 
     | 
    
         
            +
                          end
         
     | 
| 
      
 159 
     | 
    
         
            +
                          xml.Conditions conditions_options do
         
     | 
| 
      
 160 
     | 
    
         
            +
                            xml.AudienceRestriction do
         
     | 
| 
      
 161 
     | 
    
         
            +
                              xml.Audience request.issuer
         
     | 
| 
       120 
162 
     | 
    
         
             
                            end
         
     | 
| 
       121 
     | 
    
         
            -
             
     | 
| 
       122 
     | 
    
         
            -
             
     | 
| 
       123 
     | 
    
         
            -
             
     | 
| 
       124 
     | 
    
         
            -
                               
     | 
| 
      
 163 
     | 
    
         
            +
                          end
         
     | 
| 
      
 164 
     | 
    
         
            +
                          xml.AuthnStatement authn_statement_options do
         
     | 
| 
      
 165 
     | 
    
         
            +
                            xml.AuthnContext do
         
     | 
| 
      
 166 
     | 
    
         
            +
                              xml.AuthnContextClassRef Namespaces::PASSWORD
         
     | 
| 
       125 
167 
     | 
    
         
             
                            end
         
     | 
| 
       126 
     | 
    
         
            -
             
     | 
| 
       127 
     | 
    
         
            -
             
     | 
| 
       128 
     | 
    
         
            -
             
     | 
| 
       129 
     | 
    
         
            -
             
     | 
| 
       130 
     | 
    
         
            -
             
     | 
| 
       131 
     | 
    
         
            -
             
     | 
| 
       132 
     | 
    
         
            -
                                   
     | 
| 
      
 168 
     | 
    
         
            +
                          end
         
     | 
| 
      
 169 
     | 
    
         
            +
                          assertion_attributes = user.assertion_attributes_for(request)
         
     | 
| 
      
 170 
     | 
    
         
            +
                          if assertion_attributes.any?
         
     | 
| 
      
 171 
     | 
    
         
            +
                            xml.AttributeStatement do
         
     | 
| 
      
 172 
     | 
    
         
            +
                              assertion_attributes.each do |key, value|
         
     | 
| 
      
 173 
     | 
    
         
            +
                                xml.Attribute Name: key, NameFormat: Namespaces::URI, FriendlyName: key do
         
     | 
| 
      
 174 
     | 
    
         
            +
                                  xml.AttributeValue value.to_s
         
     | 
| 
       133 
175 
     | 
    
         
             
                                end
         
     | 
| 
       134 
176 
     | 
    
         
             
                              end
         
     | 
| 
       135 
177 
     | 
    
         
             
                            end
         
     | 
| 
         @@ -138,11 +180,52 @@ module Saml 
     | 
|
| 
       138 
180 
     | 
    
         
             
                      end
         
     | 
| 
       139 
181 
     | 
    
         
             
                    end
         
     | 
| 
       140 
182 
     | 
    
         | 
| 
       141 
     | 
    
         
            -
                    def  
     | 
| 
       142 
     | 
    
         
            -
                       
     | 
| 
      
 183 
     | 
    
         
            +
                    def with_encryption(xml)
         
     | 
| 
      
 184 
     | 
    
         
            +
                      if encrypt
         
     | 
| 
      
 185 
     | 
    
         
            +
                        temp = ::Builder::XmlMarkup.new
         
     | 
| 
      
 186 
     | 
    
         
            +
                        yield temp
         
     | 
| 
      
 187 
     | 
    
         
            +
                        raw_xml_to_encrypt = temp.target!
         
     | 
| 
      
 188 
     | 
    
         
            +
             
     | 
| 
      
 189 
     | 
    
         
            +
                        encryption_certificate = OpenSSL::X509::Certificate.new(Base64.decode64(request.provider.encryption_certificates.first[:text]))
         
     | 
| 
      
 190 
     | 
    
         
            +
                        public_key = encryption_certificate.public_key
         
     | 
| 
      
 191 
     | 
    
         
            +
             
     | 
| 
      
 192 
     | 
    
         
            +
                        cipher = OpenSSL::Cipher.new('AES-256-CBC')
         
     | 
| 
      
 193 
     | 
    
         
            +
                        cipher.encrypt
         
     | 
| 
      
 194 
     | 
    
         
            +
                        key = cipher.random_key
         
     | 
| 
      
 195 
     | 
    
         
            +
                        iv = cipher.random_iv
         
     | 
| 
      
 196 
     | 
    
         
            +
                        encrypted = cipher.update(raw_xml_to_encrypt) + cipher.final
         
     | 
| 
      
 197 
     | 
    
         
            +
             
     | 
| 
      
 198 
     | 
    
         
            +
                        Saml::Kit.logger.debug ['+iv', iv].inspect
         
     | 
| 
      
 199 
     | 
    
         
            +
                        Saml::Kit.logger.debug ['+key', key].inspect
         
     | 
| 
      
 200 
     | 
    
         
            +
             
     | 
| 
      
 201 
     | 
    
         
            +
                        xml.EncryptedAssertion xmlns: Namespaces::ASSERTION do
         
     | 
| 
      
 202 
     | 
    
         
            +
                          xml.EncryptedData xmlns: Namespaces::XMLENC do
         
     | 
| 
      
 203 
     | 
    
         
            +
                            xml.EncryptionMethod Algorithm: "http://www.w3.org/2001/04/xmlenc#aes256-cbc"
         
     | 
| 
      
 204 
     | 
    
         
            +
                            xml.KeyInfo xmlns: Namespaces::XMLDSIG do
         
     | 
| 
      
 205 
     | 
    
         
            +
                              xml.EncryptedKey xmlns: Namespaces::XMLENC do
         
     | 
| 
      
 206 
     | 
    
         
            +
                                xml.EncryptionMethod Algorithm: "http://www.w3.org/2001/04/xmlenc#rsa-1_5"
         
     | 
| 
      
 207 
     | 
    
         
            +
                                xml.CipherData do
         
     | 
| 
      
 208 
     | 
    
         
            +
                                  xml.CipherValue Base64.encode64(public_key.public_encrypt(key))
         
     | 
| 
      
 209 
     | 
    
         
            +
                                end
         
     | 
| 
      
 210 
     | 
    
         
            +
                              end
         
     | 
| 
      
 211 
     | 
    
         
            +
                            end
         
     | 
| 
      
 212 
     | 
    
         
            +
                            xml.CipherData do
         
     | 
| 
      
 213 
     | 
    
         
            +
                              xml.CipherValue Base64.encode64(iv + encrypted)
         
     | 
| 
      
 214 
     | 
    
         
            +
                            end
         
     | 
| 
      
 215 
     | 
    
         
            +
                          end
         
     | 
| 
      
 216 
     | 
    
         
            +
                        end
         
     | 
| 
      
 217 
     | 
    
         
            +
                      else
         
     | 
| 
      
 218 
     | 
    
         
            +
                        yield xml
         
     | 
| 
      
 219 
     | 
    
         
            +
                      end
         
     | 
| 
       143 
220 
     | 
    
         
             
                    end
         
     | 
| 
       144 
221 
     | 
    
         | 
| 
       145 
     | 
    
         
            -
                     
     | 
| 
      
 222 
     | 
    
         
            +
                    def destination_for(request)
         
     | 
| 
      
 223 
     | 
    
         
            +
                      if request.signed? && request.trusted?
         
     | 
| 
      
 224 
     | 
    
         
            +
                        request.acs_url || request.provider.assertion_consumer_service_for(binding: :http_post).try(:location)
         
     | 
| 
      
 225 
     | 
    
         
            +
                      else
         
     | 
| 
      
 226 
     | 
    
         
            +
                        request.provider.assertion_consumer_service_for(binding: :http_post).try(:location)
         
     | 
| 
      
 227 
     | 
    
         
            +
                      end
         
     | 
| 
      
 228 
     | 
    
         
            +
                    end
         
     | 
| 
       146 
229 
     | 
    
         | 
| 
       147 
230 
     | 
    
         
             
                    def configuration
         
     | 
| 
       148 
231 
     | 
    
         
             
                      Saml::Kit.configuration
         
     |