Files
ubicloud/rhizome/host/spec/storage_key_tool_spec.rb
Daniel Farina 46e2647d69 Add rhizome multi-device storage abstractions
Managing multiple storage devices per VM indicates makes the old
one-to-one assumptions of the code in `vm_path.rb` obsolete.  This
patch introduces a similar `storage_path.rb` that is capable of
computing paths for multiple storage devices.

With the exception of the storage-key-tool interface change -- largely
harmless as the key tool is not run automatically -- these rhizome
changes are thought to be backwards compatible, and can be deployed
first.

Hadi wrote the code, but I am taking responsibility for breaking it up
and deploying it.

Co-authored-by: Hadi Moshayedi <hadi@ubicloud.com>
2024-01-24 09:19:33 -08:00

116 lines
3.4 KiB
Ruby

# frozen_string_literal: true
require_relative "../lib/storage_key_tool"
require "openssl"
require "base64"
RSpec.describe StorageKeyTool do
subject(:skt) { described_class.new("vm12345", DEFAULT_STORAGE_DEVICE, 3) }
def generate_kek
key_wrapping_algorithm = "aes-256-gcm"
cipher = OpenSSL::Cipher.new(key_wrapping_algorithm)
{
algorithm: key_wrapping_algorithm,
key: cipher.random_key,
init_vector: cipher.random_iv,
auth_data: "Ubicloud-Storage-Auth"
}
end
def key_file
"/var/storage/vm12345/3/data_encryption_key.json"
end
def new_key_file
"#{key_file}.new"
end
def register_ro_storage_key_encryption(kek, key_file, cipher, key, key2)
ske = instance_double(StorageKeyEncryption)
expect(ske).to receive(:read_encrypted_dek).with(key_file).and_return({
cipher: cipher,
key: key,
key2: key2
})
expect(StorageKeyEncryption).to receive(:new).with(kek).and_return(ske)
end
def register_wo_storage_key_encryption(kek, key_file, cipher, key, key2)
ske = instance_double(StorageKeyEncryption)
expect(ske).to receive(:write_encrypted_dek).with(key_file, {
cipher: cipher,
key: key,
key2: key2
})
expect(StorageKeyEncryption).to receive(:new).with(kek).and_return(ske)
end
it "can reencrypt key file" do
old_key = generate_kek
new_key = generate_kek
register_ro_storage_key_encryption(old_key, key_file, "cipher", "key", "key2")
register_wo_storage_key_encryption(new_key, new_key_file, "cipher", "key", "key2")
expect(skt.reencrypt_key_file(old_key, new_key)).to be_nil
end
describe "#test_keys" do
it "raises error if ciphers don't match" do
old_key = generate_kek
new_key = generate_kek
register_ro_storage_key_encryption(old_key, key_file, "cipher_1", "key", "key2")
register_ro_storage_key_encryption(new_key, new_key_file, "cipher_2", "key", "key2")
expect {
skt.test_keys(old_key, new_key)
}.to raise_error RuntimeError, "ciphers don't match"
end
it "raises error if keys don't match" do
old_key = generate_kek
new_key = generate_kek
register_ro_storage_key_encryption(old_key, key_file, "cipher", "key_1", "key2")
register_ro_storage_key_encryption(new_key, new_key_file, "cipher", "key_2", "key2")
expect {
skt.test_keys(old_key, new_key)
}.to raise_error RuntimeError, "keys don't match"
end
it "raises error if second keys don't match" do
old_key = generate_kek
new_key = generate_kek
register_ro_storage_key_encryption(old_key, key_file, "cipher", "key", "key2_1")
register_ro_storage_key_encryption(new_key, new_key_file, "cipher", "key", "key2_2")
expect {
skt.test_keys(old_key, new_key)
}.to raise_error RuntimeError, "second keys don't match"
end
it "can test keys" do
old_key = generate_kek
new_key = generate_kek
register_ro_storage_key_encryption(old_key, key_file, "cipher", "key", "key2")
register_ro_storage_key_encryption(new_key, new_key_file, "cipher", "key", "key2")
expect(skt.test_keys(old_key, new_key)).to be_nil
end
end
it "can retire old key" do
expect(File).to receive(:rename).with(new_key_file, key_file)
f = instance_double(File)
expect(File).to receive(:open).with("/var/storage/vm12345/3").and_return(f)
skt.retire_old_key
end
end