Class: SymmetricEncryption::Keystore::File

Inherits:
Object
  • Object
show all
Defined in:
lib/symmetric_encryption/keystore/file.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(file_name:, key_encrypting_key: nil) ⇒ File

Stores the Encryption key in a file. Secures the Encryption key by encrypting it with a key encryption key.



63
64
65
66
# File 'lib/symmetric_encryption/keystore/file.rb', line 63

def initialize(file_name:, key_encrypting_key: nil)
  @file_name          = file_name
  @key_encrypting_key = key_encrypting_key
end

Instance Attribute Details

#file_nameObject

Returns the value of attribute file_name.



4
5
6
# File 'lib/symmetric_encryption/keystore/file.rb', line 4

def file_name
  @file_name
end

#key_encrypting_keyObject

Returns the value of attribute key_encrypting_key.



4
5
6
# File 'lib/symmetric_encryption/keystore/file.rb', line 4

def key_encrypting_key
  @key_encrypting_key
end

Class Method Details

.new_config(key_path: '/etc/symmetric-encryption', app_name: 'symmetric-encryption', environments: %i[development test release production],, cipher_name: 'aes-256-cbc') ⇒ Object

Returns [Hash] initial configuration. Generates the encrypted key file for every environment except development and test.



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/symmetric_encryption/keystore/file.rb', line 8

def self.new_config(key_path: '/etc/symmetric-encryption',
                    app_name: 'symmetric-encryption',
                    environments: i[development test release production],
                    cipher_name: 'aes-256-cbc')

  configs = {}
  environments.each do |environment|
    environment          = environment.to_sym
    configs[environment] =
      if i[development test].include?(environment)
        Keystore.dev_config
      else
        cfg = new_key_config(key_path: key_path, cipher_name: cipher_name, app_name: app_name, environment: environment)
        {
          ciphers: [cfg]
        }
      end
  end
  configs
end

.new_key_config(key_path:, cipher_name:, app_name:, environment:, version: 0, dek: nil) ⇒ Object

Returns [Hash] a new cipher, and writes its encrypted key file.

Increments the supplied version number by 1.



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/symmetric_encryption/keystore/file.rb', line 32

def self.new_key_config(key_path:, cipher_name:, app_name:, environment:, version: 0, dek: nil)
  version >= 255 ? (version = 1) : (version += 1)

  dek   ||= SymmetricEncryption::Key.new(cipher_name: cipher_name)
  kek   = SymmetricEncryption::Key.new(cipher_name: cipher_name)
  kekek = SymmetricEncryption::Key.new(cipher_name: cipher_name)

  dek_file_name = ::File.join(key_path, "#{app_name}_#{environment}_v#{version}.encrypted_key")
  new(file_name: dek_file_name, key_encrypting_key: kek).write(dek.key)

  kekek_file_name = ::File.join(key_path, "#{app_name}_#{environment}_v#{version}.kekek")
  new(file_name: kekek_file_name).write(kekek.key)

  {
    cipher_name:        dek.cipher_name,
    version:            version,
    key_filename:       dek_file_name,
    iv:                 dek.iv,
    key_encrypting_key: {
      encrypted_key:      kekek.encrypt(kek.key),
      iv:                 kek.iv,
      key_encrypting_key: {
        key_filename: kekek_file_name,
        iv:           kekek.iv
      }
    }
  }
end

Instance Method Details

#readObject

Returns the Encryption key in the clear.



69
70
71
72
73
74
75
# File 'lib/symmetric_encryption/keystore/file.rb', line 69

def read
  # TODO: Validate that file is not globally readable.
  raise(SymmetricEncryption::ConfigError, "Symmetric Encryption key file: '#{file_name}' not found") unless ::File.exist?(file_name)

  data = read_from_file
  key_encrypting_key ? key_encrypting_key.decrypt(data) : data
end

#write(key) ⇒ Object

Encrypt and write the key to file.



78
79
80
81
# File 'lib/symmetric_encryption/keystore/file.rb', line 78

def write(key)
  data = key_encrypting_key ? key_encrypting_key.encrypt(key) : key
  write_to_file(data)
end