Files
ubicloud/rhizome/host/lib/storage_key_encryption.rb
Burak Yucesoy c5dfa6d2c1 Restructure rhizome folder to accommodate new services
I needed this while building the postgres service. Since it makes sense on its
own, I'm committing it separately.

Many services will need their own rhizome folders. Currently it is only used
for setting up host machine and there is no hierarchy in it. With this commit
we are moving content of the rhizome folder to rhizome/host. Other services,
such as postgres will create their own rhizome folders. Installation of the
rhizome folders is handled by BootstrapRhizome and InstallRhizome progs (as
before). We only put target_folder variable to their frames to specify which
sub-folder should be put to the server.

Also, there could be some files shared across services, one good example is
utility functions in lib folders. For such files, I created /rhizome/common,
which will be installed to servers along with their own folder.
2023-09-06 00:51:26 +03:00

67 lines
2.1 KiB
Ruby

# frozen_string_literal: true
require_relative "../../common/lib/util"
require "openssl"
require "base64"
class StorageKeyEncryption
def initialize(key_encryption_cipher)
@key_encryption_cipher = key_encryption_cipher
end
def write_encrypted_dek(key_file, data_encryption_key)
File.open(key_file, "w") {
_1.write(JSON.pretty_generate({
cipher: data_encryption_key[:cipher],
key: wrap_key(data_encryption_key[:key]),
key2: wrap_key(data_encryption_key[:key2])
}))
fsync_or_fail(_1)
}
end
def read_encrypted_dek(key_file)
data_encryption_key = JSON.parse(File.read(key_file))
{
cipher: data_encryption_key["cipher"],
key: unwrap_key(data_encryption_key["key"]),
key2: unwrap_key(data_encryption_key["key2"])
}
end
def wrap_key(key)
algorithm = @key_encryption_cipher["algorithm"]
fail "currently only aes-256-gcm is supported" unless algorithm == "aes-256-gcm"
cipher = OpenSSL::Cipher.new(algorithm)
cipher.encrypt
cipher.key = Base64.decode64(@key_encryption_cipher["key"])
cipher.iv = Base64.decode64(@key_encryption_cipher["init_vector"])
cipher.auth_data = @key_encryption_cipher["auth_data"]
[
Base64.encode64(cipher.update(key) + cipher.final),
Base64.encode64(cipher.auth_tag)
]
end
def unwrap_key(encrypted_key)
algorithm = @key_encryption_cipher["algorithm"]
fail "currently only aes-256-gcm is supported" unless algorithm == "aes-256-gcm"
decipher = OpenSSL::Cipher.new(algorithm)
decipher.decrypt
decipher.key = Base64.decode64(@key_encryption_cipher["key"])
decipher.iv = Base64.decode64(@key_encryption_cipher["init_vector"])
decipher.auth_data = @key_encryption_cipher["auth_data"]
auth_tag = Base64.decode64(encrypted_key[1])
# We reject if auth_tag length is not the spec maximum (16), see
# https://github.com/ruby/openssl/issues/63 for more details.
fail "Invalid auth_tag size: #{auth_tag.bytesize}" unless auth_tag.bytesize == 16
decipher.auth_tag = auth_tag
decipher.update(Base64.decode64(encrypted_key[0])) + decipher.final
end
end