From fb62ab20f83cbc7bb1b4f21118694df04b174433 Mon Sep 17 00:00:00 2001 From: nov Date: Tue, 12 Jan 2021 17:14:32 +0900 Subject: [PATCH 1/2] add "include_key_retrieval_method" option on those methods * Saml::Response#encrypt_assertions * Saml::Util#encrypt_assertion ref.) https://github.com/digidentity/libsaml/issues/151 --- lib/saml/response.rb | 8 ++++++-- lib/saml/util.rb | 5 ++++- spec/lib/saml/util_spec.rb | 21 +++++++++++++++++++++ 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/lib/saml/response.rb b/lib/saml/response.rb index f81d0da..6d0c4fc 100644 --- a/lib/saml/response.rb +++ b/lib/saml/response.rb @@ -28,10 +28,14 @@ def unknown_principal? !success? && status.status_code.unknown_principal? end - def encrypt_assertions(certificate, include_certificate: false) + def encrypt_assertions(key_descriptor_or_certificate, include_certificate: false, include_key_retrieval_method: false) @encrypted_assertions = [] assertions.each do |assertion| - @encrypted_assertions << Saml::Util.encrypt_assertion(assertion, certificate, include_certificate: include_certificate) + @encrypted_assertions << Saml::Util.encrypt_assertion( + assertion, key_descriptor_or_certificate, + include_certificate: include_certificate, + include_key_retrieval_method: include_key_retrieval_method + ) end assertions.clear end diff --git a/lib/saml/util.rb b/lib/saml/util.rb index 180f8ed..4a6c316 100644 --- a/lib/saml/util.rb +++ b/lib/saml/util.rb @@ -60,7 +60,7 @@ def sign_xml(message, format = :xml, include_nested_prefixlist = false, &block) end end - def encrypt_assertion(assertion, key_descriptor_or_certificate, include_certificate: false) + def encrypt_assertion(assertion, key_descriptor_or_certificate, include_certificate: false, include_key_retrieval_method: false) case key_descriptor_or_certificate when OpenSSL::X509::Certificate certificate = key_descriptor_or_certificate @@ -75,6 +75,9 @@ def encrypt_assertion(assertion, key_descriptor_or_certificate, include_certific assertion = assertion.to_xml(nil, nil, false) if assertion.is_a?(Assertion) # create xml without instruct encrypted_data = Xmlenc::Builder::EncryptedData.new + if include_key_retrieval_method && key_name + encrypted_data.set_key_retrieval_method (Xmlenc::Builder::RetrievalMethod.new(uri: "##{key_name}")) + end encrypted_data.set_encryption_method(algorithm: 'http://www.w3.org/2001/04/xmlenc#aes128-cbc') encrypted_key = encrypted_data.encrypt(assertion.to_s) diff --git a/spec/lib/saml/util_spec.rb b/spec/lib/saml/util_spec.rb index 092d6d8..5c8b57c 100644 --- a/spec/lib/saml/util_spec.rb +++ b/spec/lib/saml/util_spec.rb @@ -371,6 +371,16 @@ def initialize expect(encrypted_assertion.encrypted_keys.key_info.x509Data.x509certificate.to_pem).to eq service_provider.certificate.to_pem end end + + context 'with include_key_retrieval_method option' do + let(:encrypted_assertion) do + Saml::Util.encrypt_assertion(Saml::Assertion.new, service_provider.certificate, include_key_retrieval_method: true) + end + + it 'ignores the option' do + expect(encrypted_assertion.encrypted_data.key_info).to be_nil + end + end end context 'with a key descriptor as param' do @@ -393,6 +403,17 @@ def initialize expect(encrypted_assertion.encrypted_keys.key_info.x509Data.x509certificate.to_pem).to eq service_provider.certificate.to_pem end end + + context 'with include_key_retrieval_method option' do + let(:encrypted_assertion) do + Saml::Util.encrypt_assertion(Saml::Assertion.new, key_descriptor, include_key_retrieval_method: true) + end + + it 'add key_retrieval_method' do + expect(encrypted_assertion.encrypted_keys.key_info.key_name).to eq key_name + expect(encrypted_assertion.encrypted_data.key_info.retrieval_method.uri).to eq "##{key_name}" + end + end end context 'with a wrong param' do From 8e0f8d887e1d4ed8fbddccda8bd890096593db1b Mon Sep 17 00:00:00 2001 From: nov Date: Tue, 12 Jan 2021 18:07:14 +0900 Subject: [PATCH 2/2] retrieval_method should reference to id, not key_name --- lib/saml/util.rb | 8 +++++--- spec/lib/saml/util_spec.rb | 9 +++++---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/saml/util.rb b/lib/saml/util.rb index 4a6c316..e2bad26 100644 --- a/lib/saml/util.rb +++ b/lib/saml/util.rb @@ -75,9 +75,6 @@ def encrypt_assertion(assertion, key_descriptor_or_certificate, include_certific assertion = assertion.to_xml(nil, nil, false) if assertion.is_a?(Assertion) # create xml without instruct encrypted_data = Xmlenc::Builder::EncryptedData.new - if include_key_retrieval_method && key_name - encrypted_data.set_key_retrieval_method (Xmlenc::Builder::RetrievalMethod.new(uri: "##{key_name}")) - end encrypted_data.set_encryption_method(algorithm: 'http://www.w3.org/2001/04/xmlenc#aes128-cbc') encrypted_key = encrypted_data.encrypt(assertion.to_s) @@ -90,6 +87,11 @@ def encrypt_assertion(assertion, key_descriptor_or_certificate, include_certific end encrypted_key.encrypt(certificate.public_key) + if include_key_retrieval_method + encrypted_key.id = '_' + SecureRandom.uuid + encrypted_data.set_key_retrieval_method (Xmlenc::Builder::RetrievalMethod.new(uri: "##{encrypted_key.id}")) + end + Saml::Elements::EncryptedAssertion.new(encrypted_data: encrypted_data, encrypted_keys: encrypted_key) end diff --git a/spec/lib/saml/util_spec.rb b/spec/lib/saml/util_spec.rb index 5c8b57c..b364088 100644 --- a/spec/lib/saml/util_spec.rb +++ b/spec/lib/saml/util_spec.rb @@ -377,8 +377,9 @@ def initialize Saml::Util.encrypt_assertion(Saml::Assertion.new, service_provider.certificate, include_key_retrieval_method: true) end - it 'ignores the option' do - expect(encrypted_assertion.encrypted_data.key_info).to be_nil + it 'add key_retrieval_method' do + expect(encrypted_assertion.encrypted_keys.id).not_to be_nil + expect(encrypted_assertion.encrypted_data.key_info.retrieval_method.uri).to eq "##{encrypted_assertion.encrypted_keys.id}" end end end @@ -410,8 +411,8 @@ def initialize end it 'add key_retrieval_method' do - expect(encrypted_assertion.encrypted_keys.key_info.key_name).to eq key_name - expect(encrypted_assertion.encrypted_data.key_info.retrieval_method.uri).to eq "##{key_name}" + expect(encrypted_assertion.encrypted_keys.id).not_to be_nil + expect(encrypted_assertion.encrypted_data.key_info.retrieval_method.uri).to eq "##{encrypted_assertion.encrypted_keys.id}" end end end