Skip to content

Commit

Permalink
Add encryption contexts to session KMS events (#2787)
Browse files Browse the repository at this point in the history
**Why**: So they will show up in cloudtrail with a context, which
separates them from legacy password encryption events
  • Loading branch information
jmhooper authored Feb 26, 2019

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent 2b9ceb5 commit 5f1a887
Showing 4 changed files with 52 additions and 5 deletions.
14 changes: 12 additions & 2 deletions app/services/encryption/encryptors/session_encryptor.rb
Original file line number Diff line number Diff line change
@@ -5,17 +5,27 @@ class SessionEncryptor

def encrypt(plaintext)
aes_ciphertext = AesEncryptor.new.encrypt(plaintext, aes_encryption_key)
kms_ciphertext = ContextlessKmsClient.new.encrypt(aes_ciphertext)
kms_ciphertext = encrypt_with_kms(aes_ciphertext)
encode(kms_ciphertext)
end

def decrypt(ciphertext)
aes_ciphertext = ContextlessKmsClient.new.decrypt(decode(ciphertext))
aes_ciphertext = KmsClient.new.decrypt(
decode(ciphertext), 'context' => 'session-encryption'
)
aes_encryptor.decrypt(aes_ciphertext, aes_encryption_key)
end

private

def encrypt_with_kms(ciphertext)
if FeatureManagement.use_kms_context_for_sessions?
KmsClient.new.encrypt(ciphertext, 'context' => 'session-encryption')
else
ContextlessKmsClient.new.encrypt(ciphertext)
end
end

def aes_encryptor
AesEncryptor.new
end
3 changes: 3 additions & 0 deletions config/application.yml.example
Original file line number Diff line number Diff line change
@@ -204,6 +204,7 @@ development:
twilio_record_voice: 'true'
use_dashboard_service_providers: 'true'
use_kms: 'false'
use_kms_context_for_sessions: 'false'
use_kms_contexts: 'false'
usps_confirmation_max_days: '10'
enable_load_testing_mode: 'false'
@@ -318,6 +319,7 @@ production:
twilio_record_voice: 'false'
twilio_verify_api_key: 'change-me'
use_kms: 'true'
use_kms_context_for_sessions: 'false'
use_kms_contexts: 'false'
usps_confirmation_max_days: '30'
enable_load_testing_mode: 'false'
@@ -436,6 +438,7 @@ test:
twilio_record_voice: 'true'
twilio_verify_api_key: 'secret'
use_kms: 'false'
use_kms_context_for_sessions: 'true'
use_kms_contexts: 'true'
usps_confirmation_max_days: '10'
enable_load_testing_mode: 'false'
4 changes: 4 additions & 0 deletions lib/feature_management.rb
Original file line number Diff line number Diff line change
@@ -109,4 +109,8 @@ def self.use_kms_contexts?
def self.write_2lkms_passwords?
Figaro.env.write_2lkms_passwords == 'true'
end

def self.use_kms_context_for_sessions?
Figaro.env.use_kms_context_for_sessions == 'true'
end
end
36 changes: 33 additions & 3 deletions spec/services/encryption/encryptors/session_encryptor_spec.rb
Original file line number Diff line number Diff line change
@@ -6,22 +6,52 @@
describe '#encrypt' do
it 'returns a KMS wrapped AES encrypted ciphertext' do
aes_encryptor = instance_double(Encryption::Encryptors::AesEncryptor)
kms_client = instance_double(Encryption::ContextlessKmsClient)
kms_client = instance_double(Encryption::KmsClient)
allow(aes_encryptor).to receive(:encrypt).
with(plaintext, Figaro.env.session_encryption_key[0...32]).
and_return('aes output')
allow(kms_client).to receive(:encrypt).
with('aes output').
with('aes output', 'context' => 'session-encryption').
and_return('kms output')
allow(Encryption::Encryptors::AesEncryptor).to receive(:new).and_return(aes_encryptor)
allow(Encryption::ContextlessKmsClient).to receive(:new).and_return(kms_client)
allow(Encryption::KmsClient).to receive(:new).and_return(kms_client)

expected_ciphertext = Base64.strict_encode64('kms output')

ciphertext = subject.encrypt(plaintext)

expect(ciphertext).to eq(expected_ciphertext)
end

context 'when use_kms_context_for_sessions is true' do
before do
allow(FeatureManagement).to receive(:use_kms_context_for_sessions?).and_return(true)
end

it 'sets an encryption context' do
client = instance_double(Encryption::KmsClient)
expect(client).to receive(:encrypt).with(
instance_of(String), 'context' => 'session-encryption'
).and_return('kms_ciphertext')
allow(Encryption::KmsClient).to receive(:new).and_return(client)

subject.encrypt(plaintext)
end
end

context 'when use_kms_context_for_sessions is false' do
before do
allow(FeatureManagement).to receive(:use_kms_context_for_sessions?).and_return(false)
end

it 'does not set an encryption context' do
client = instance_double(Encryption::ContextlessKmsClient)
expect(client).to receive(:encrypt).with(instance_of(String)).and_return('kms_ciphertext')
allow(Encryption::ContextlessKmsClient).to receive(:new).and_return(client)

subject.encrypt(plaintext)
end
end
end

describe '#decrypt' do

0 comments on commit 5f1a887

Please sign in to comment.