Commit 47601b4
Changed files (12)
lib
xml
kit
spec
fixtures
support
lib/xml/kit/crypto/oaep_cipher.rb
@@ -8,7 +8,10 @@ module Xml
ALGORITHMS = {
ALGORITHM => true
}.freeze
- def initialize(_algorithm, key)
+ attr_reader :algorithm, :key
+
+ def initialize(algorithm, key)
+ @algorithm = algorithm
@key = key
end
lib/xml/kit/crypto/rsa_cipher.rb
@@ -5,8 +5,10 @@ module Xml
module Crypto
class RsaCipher
ALGORITHM = "#{::Xml::Kit::Namespaces::XMLENC}rsa-1_5".freeze
+ attr_reader :algorithm, :key
- def initialize(_algorithm, key)
+ def initialize(algorithm, key)
+ @algorithm = algorithm
@key = key
end
lib/xml/kit/crypto/unknown_cipher.rb
@@ -4,7 +4,12 @@ module Xml
module Kit
module Crypto
class UnknownCipher
- def initialize(algorithm, key); end
+ attr_reader :algorithm, :key
+
+ def initialize(algorithm, key)
+ @algorithm = algorithm
+ @key = key
+ end
def self.matches?(_algorithm)
true
lib/xml/kit/templates/encrypted_key.builder
@@ -1,7 +1,7 @@
# frozen_string_literal: true
xml.EncryptedKey Id: id, xmlns: ::Xml::Kit::Namespaces::XMLENC do
- xml.EncryptionMethod Algorithm: algorithm
+ xml.EncryptionMethod Algorithm: asymmetric_cipher.algorithm
render(key_info, xml: xml) if key_info
xml.CipherData do
xml.CipherValue cipher_value
lib/xml/kit/encrypted_key.rb
@@ -6,31 +6,19 @@ module Xml
module Kit
class EncryptedKey
include ::Xml::Kit::Templatable
- DEFAULT_ALGORITHM = ::Xml::Kit::Crypto::RsaCipher::ALGORITHM
-
- attr_reader :id, :algorithm
- attr_reader :public_key, :key
+ attr_reader :id
+ attr_reader :asymmetric_cipher, :symmetric_cipher
attr_accessor :key_info
- def initialize(id: Id.generate, public_key:, key:, key_info: nil, algorithm: DEFAULT_ALGORITHM)
+ def initialize(id: Id.generate, asymmetric_cipher:, symmetric_cipher:, key_info: nil)
@id = id
- @algorithm = algorithm
- @public_key = public_key
- @key = key
+ @asymmetric_cipher = asymmetric_cipher
+ @symmetric_cipher = symmetric_cipher
@key_info = key_info
end
def cipher_value
- asymmetric_cipher = asymmetric(algorithm, public_key)
- Base64.strict_encode64(asymmetric_cipher.encrypt(key))
- end
-
- private
-
- def asymmetric(algorithm, public_key)
- return algorithm unless algorithm.is_a?(String)
-
- ::Xml::Kit::Crypto.cipher_for(algorithm, public_key)
+ Base64.strict_encode64(asymmetric_cipher.encrypt(symmetric_cipher.key))
end
end
end
lib/xml/kit/encryption.rb
@@ -41,11 +41,18 @@ module Xml
end
def create_key_info_for(public_key, symmetric_cipher, asymmetric_algorithm)
+ asymmetric_cipher = asymmetric(asymmetric_algorithm, public_key)
KeyInfo.new do |x|
- x.encrypted_key = EncryptedKey.new(public_key: public_key, key: symmetric_cipher.key, algorithm: asymmetric_algorithm)
+ x.encrypted_key = EncryptedKey.new(asymmetric_cipher: asymmetric_cipher, symmetric_cipher: symmetric_cipher)
@asymmetric_cipher_value = x.encrypted_key.cipher_value
end
end
+
+ def asymmetric(algorithm, public_key)
+ return algorithm unless algorithm.is_a?(String)
+
+ ::Xml::Kit::Crypto.cipher_for(algorithm, public_key)
+ end
end
end
end
lib/xml/kit/templatable.rb
@@ -24,7 +24,11 @@ module Xml
end
def encrypt_key_for(xml:, id:, public_key:, key:)
- ::Xml::Kit::EncryptedKey.new(id: id, public_key: public_key, key: key).to_xml(xml: xml)
+ ::Xml::Kit::EncryptedKey.new(
+ id: id,
+ asymmetric_cipher: asymmetric_cipher,
+ symmetric_cipher: symmetric_cipher
+ ).to_xml(xml: xml)
end
def encryption_for(*args, &block)
@@ -32,7 +36,7 @@ module Xml
encrypt_data_for(*args, &block)
end
- def encrypt_data_for(xml:, key_info: nil, symmetric_cipher: Crypto::SymmetricCipher.new)
+ def encrypt_data_for(xml:, key_info: nil)
return yield xml unless encrypt?
temp = ::Builder::XmlMarkup.new
@@ -41,10 +45,19 @@ module Xml
signatures.complete(temp.target!),
encryption_certificate.public_key,
symmetric_algorithm: symmetric_cipher,
+ asymmetric_algorithm: asymmetric_cipher,
key_info: key_info
).to_xml(xml: xml)
end
+ def asymmetric_cipher(algorithm: Crypto::RsaCipher::ALGORITHM)
+ @asymmetric_cipher ||= Crypto.cipher_for(algorithm, encryption_certificate.public_key)
+ end
+
+ def symmetric_cipher
+ @symmetric_cipher ||= Crypto::SymmetricCipher.new
+ end
+
def render(model, options)
::Xml::Kit::Template.new(model).to_xml(options)
end
spec/fixtures/soap.builder
@@ -8,7 +8,7 @@ xml.Envelope xmlns: "http://schemas.xmlsoap.org/soap/envelope/" do
end
end
xml.Body xmlns: 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd', Id: id do
- encrypt_data_for xml: xml, key_info: body_key_info, symmetric_cipher: symmetric_cipher do |xml|
+ encrypt_data_for xml: xml, key_info: body_key_info do |xml|
xml.EncryptMe do
xml.Secret "secret"
end
spec/support/soap.rb
@@ -19,10 +19,6 @@ class Soap
symmetric_cipher.key
end
- def symmetric_cipher
- @symmetric_cipher ||= ::Xml::Kit::Crypto::SymmetricCipher.new
- end
-
def key_id
'EK-E2C32E59F27A1320A215468956686717'
end
spec/xml/kit/encrypted_key_spec.rb
@@ -2,14 +2,14 @@
RSpec.describe ::Xml::Kit::EncryptedKey do
describe '#to_xml' do
- subject { described_class.new(id: id, algorithm: algorithm, public_key: public_key, key: symmetric_key, key_info: key_info) }
+ subject { described_class.new(id: id, asymmetric_cipher: asymmetric_cipher, symmetric_cipher: symmetric_cipher, key_info: key_info) }
+ let(:symmetric_cipher) { ::Xml::Kit::Crypto::SymmetricCipher.new }
+ let(:asymmetric_cipher) { ::Xml::Kit::Crypto.cipher_for(algorithm, private_key.public_key) }
let(:algorithm) { ::Xml::Kit::Crypto::RsaCipher::ALGORITHM }
let(:key_info) { ::Xml::Kit::KeyInfo.new }
let(:id) { ::Xml::Kit::Id.generate }
let(:private_key) { OpenSSL::PKey::RSA.new(2048) }
- let(:public_key) { private_key.public_key }
- let(:symmetric_key) { SecureRandom.hex(32) }
let(:result) { Hash.from_xml(subject.to_xml) }
before do
@@ -19,9 +19,9 @@ RSpec.describe ::Xml::Kit::EncryptedKey do
specify { expect(result.key?('EncryptedKey')).to be_present }
specify { expect(result['EncryptedKey']['Id']).to eql(id) }
specify { expect(result['EncryptedKey']['xmlns']).to eql(::Xml::Kit::Namespaces::XMLENC) }
- specify { expect(result['EncryptedKey']['EncryptionMethod']['Algorithm']).to be_present }
+ specify { expect(result['EncryptedKey']['EncryptionMethod']['Algorithm']).to eql(algorithm) }
specify { expect(result['EncryptedKey']['CipherData']['CipherValue']).to be_present }
- specify { expect(private_key.private_decrypt(Base64.decode64(result['EncryptedKey']['CipherData']['CipherValue']))).to eql(symmetric_key) }
+ specify { expect(private_key.private_decrypt(Base64.decode64(result['EncryptedKey']['CipherData']['CipherValue']))).to eql(symmetric_cipher.key) }
specify { expect(subject.to_xml).to match_xsd('xenc-schema') }
specify { expect(result['EncryptedKey'].key?('KeyInfo')).to be(true) }
end
spec/xml/kit/encryption_spec.rb
@@ -37,7 +37,7 @@ RSpec.describe Xml::Kit::Encryption do
subject { described_class.new(xml, public_key, symmetric_algorithm: symmetric_cipher, asymmetric_algorithm: asymmetric_cipher) }
let(:symmetric_cipher) { instance_double(Xml::Kit::Crypto::SymmetricCipher, key: 'symmetric_key', encrypt: 'CIPHERTEXT', to_s: 'symmetric_cipher') }
- let(:asymmetric_cipher) { instance_double(Xml::Kit::Crypto::RsaCipher, encrypt: 'asymmetric CIPHERTEXT', to_s: 'asymmetric_cipher') }
+ let(:asymmetric_cipher) { instance_double(Xml::Kit::Crypto::RsaCipher, encrypt: 'asymmetric CIPHERTEXT', to_s: 'asymmetric_cipher', algorithm: 'asymmetric_cipher') }
let(:key_pair) { Xml::Kit::KeyPair.generate(use: :encryption) }
let(:public_key) { key_pair.public_key }
let(:xml) do
spec/xml/kit/key_info_spec.rb
@@ -5,12 +5,12 @@ RSpec.describe Xml::Kit::KeyInfo do
describe '#to_xml' do
context 'with encrypted key' do
- let(:encrypted_key) { ::Xml::Kit::EncryptedKey.new(id: id, algorithm: algorithm, public_key: public_key, key: symmetric_key) }
+ let(:encrypted_key) { ::Xml::Kit::EncryptedKey.new(id: id, asymmetric_cipher: asymmetric_cipher, symmetric_cipher: symmetric_cipher) }
+ let(:symmetric_cipher) { ::Xml::Kit::Crypto::SymmetricCipher.new }
+ let(:asymmetric_cipher) { ::Xml::Kit::Crypto.cipher_for(algorithm, private_key.public_key) }
let(:algorithm) { ::Xml::Kit::Crypto::RsaCipher::ALGORITHM }
let(:id) { ::Xml::Kit::Id.generate }
let(:private_key) { OpenSSL::PKey::RSA.new(2048) }
- let(:public_key) { private_key.public_key }
- let(:symmetric_key) { SecureRandom.hex(32) }
let(:result) { Hash.from_xml(subject.to_xml) }
before do
@@ -18,7 +18,7 @@ RSpec.describe Xml::Kit::KeyInfo do
end
specify { expect(result['KeyInfo']['EncryptedKey']['EncryptionMethod']['Algorithm']).to eql(algorithm) }
- specify { expect(private_key.private_decrypt(Base64.decode64(result['KeyInfo']['EncryptedKey']['CipherData']['CipherValue']))).to eql(symmetric_key) }
+ specify { expect(private_key.private_decrypt(Base64.decode64(result['KeyInfo']['EncryptedKey']['CipherData']['CipherValue']))).to eql(symmetric_cipher.key) }
end
context 'with key name' do