Module: Legion::Crypt::Cipher

Includes:
ClusterSecret, Logging::Helper
Included in:
Legion::Crypt
Defined in:
lib/legion/crypt/cipher.rb

Constant Summary collapse

AUTHENTICATED_CIPHER =
'aes-256-gcm'
LEGACY_CIPHER =
'aes-256-cbc'
AUTHENTICATED_PREFIX =
'gcm'
RSA_OAEP_PREFIX =
'oaep'
RSA_OAEP_PADDING =
OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING
RSA_LEGACY_PADDING =
OpenSSL::PKey::RSA::PKCS1_PADDING

Constants included from Logging::Helper

Logging::Helper::CompatLogger

Instance Method Summary collapse

Methods included from Logging::Helper

#handle_exception, #log

Methods included from ClusterSecret

#cluster_secret_timeout, #cluster_secret_vault_path, #cs, #find_cluster_secret, #force_cluster_secret, #from_settings, #from_transport, #from_vault, #generate_secure_random, #only_member?, #push_cs_to_vault, #secret_length, #set_cluster_secret, #settings_push_vault, #validate_hex

Instance Method Details

#decrypt(message, init_vector) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/legion/crypt/cipher.rb', line 39

def decrypt(message, init_vector)
  secret = wait_for_cluster_secret
  result = if authenticated_ciphertext?(message)
             decrypt_authenticated(message, init_vector, secret)
           else
             decrypt_legacy(message, init_vector, secret)
           end
  log.debug 'Cipher decrypt completed'
  result
rescue StandardError => e
  handle_exception(e, level: :error, operation: 'crypt.cipher.decrypt')
  raise
end

#decrypt_from_keypair(message:, **_opts) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/legion/crypt/cipher.rb', line 65

def decrypt_from_keypair(message:, **_opts)
  decrypted_message = if rsa_oaep_ciphertext?(message)
                        decrypt_oaep_from_keypair(message)
                      else
                        decrypt_legacy_from_keypair(message)
                      end
  log.debug 'Cipher keypair decryption completed'
  decrypted_message
rescue StandardError => e
  handle_exception(e, level: :error, operation: 'crypt.cipher.decrypt_from_keypair')
  raise
end

#encrypt(message) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/legion/crypt/cipher.rb', line 20

def encrypt(message)
  cipher = OpenSSL::Cipher.new(AUTHENTICATED_CIPHER)
  cipher.encrypt
  cipher.key = cs
  iv = cipher.random_iv
  ciphertext = cipher.update(message) + cipher.final
  encoded_ciphertext = Base64.strict_encode64(ciphertext)
  encoded_auth_tag = Base64.strict_encode64(cipher.auth_tag)
  result = {
    enciphered_message: "#{AUTHENTICATED_PREFIX}:#{encoded_ciphertext}:#{encoded_auth_tag}",
    iv:                 Base64.strict_encode64(iv)
  }
  log.debug 'Cipher encrypt completed'
  result
rescue StandardError => e
  handle_exception(e, level: :error, operation: 'crypt.cipher.encrypt')
  raise
end

#encrypt_from_keypair(message:, pub_key: public_key) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
# File 'lib/legion/crypt/cipher.rb', line 53

def encrypt_from_keypair(message:, pub_key: public_key)
  rsa_public_key = OpenSSL::PKey::RSA.new(pub_key)

  encrypted_message = rsa_public_key.public_encrypt(message, RSA_OAEP_PADDING)
  encoded_message = "#{RSA_OAEP_PREFIX}:#{Base64.strict_encode64(encrypted_message)}"
  log.debug 'Cipher keypair encryption completed'
  encoded_message
rescue StandardError => e
  handle_exception(e, level: :error, operation: 'crypt.cipher.encrypt_from_keypair')
  raise
end

#private_keyObject



82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/legion/crypt/cipher.rb', line 82

def private_key
  @private_key ||= if Legion::Settings[:crypt][:read_private_key] && File.exist?('./legionio.key')
                     log.info 'Cipher loading RSA private key from disk'
                     OpenSSL::PKey::RSA.new File.read './legionio.key'
                   else
                     log.info 'Cipher generating RSA private key'
                     OpenSSL::PKey::RSA.new 2048
                   end
rescue StandardError => e
  handle_exception(e, level: :error, operation: 'crypt.cipher.private_key')
  raise
end

#public_keyObject



78
79
80
# File 'lib/legion/crypt/cipher.rb', line 78

def public_key
  @public_key ||= private_key.public_key.to_s
end