lib/vault/rails.rb in vault-rails-0.4.0 vs lib/vault/rails.rb in vault-rails-0.5.0

- old
+ new

@@ -4,11 +4,11 @@ require "json" require_relative "encrypted_model" require_relative "rails/configurable" require_relative "rails/errors" -require_relative "rails/serializer" +require_relative "rails/json_serializer" require_relative "rails/version" module Vault module Rails # The list of serializers. @@ -70,23 +70,23 @@ # @param [Vault::Client] client # the Vault client to use # # @return [String] # the encrypted cipher text - def encrypt(path, key, plaintext, client = self.client) + def encrypt(path, key, plaintext, client: self.client, context: nil) if plaintext.blank? return plaintext end path = path.to_s if !path.is_a?(String) key = key.to_s if !key.is_a?(String) with_retries do if self.enabled? - result = self.vault_encrypt(path, key, plaintext, client) + result = self.vault_encrypt(path, key, plaintext, client: client, context: context) else - result = self.memory_encrypt(path, key, plaintext, client) + result = self.memory_encrypt(path, key, plaintext, client: client, context: context) end return self.force_encoding(result) end end @@ -102,23 +102,23 @@ # @param [Vault::Client] client # the Vault client to use # # @return [String] # the decrypted plaintext text - def decrypt(path, key, ciphertext, client = self.client) + def decrypt(path, key, ciphertext, client: self.client, context: nil) if ciphertext.blank? return ciphertext end path = path.to_s if !path.is_a?(String) key = key.to_s if !key.is_a?(String) with_retries do if self.enabled? - result = self.vault_decrypt(path, key, ciphertext, client) + result = self.vault_decrypt(path, key, ciphertext, client: client, context: context) else - result = self.memory_decrypt(path, key, ciphertext, client) + result = self.memory_decrypt(path, key, ciphertext, client: client, context: context) end return self.force_encoding(result) end end @@ -141,58 +141,70 @@ end protected # Perform in-memory encryption. This is useful for testing and development. - def memory_encrypt(path, key, plaintext, client) + def memory_encrypt(path, key, plaintext, client: , context: nil) log_warning(DEV_WARNING) if self.in_memory_warnings_enabled? return nil if plaintext.nil? cipher = OpenSSL::Cipher::AES.new(128, :CBC) cipher.encrypt - cipher.key = memory_key_for(path, key) + cipher.key = memory_key_for(path, key, context: context) return Base64.strict_encode64(cipher.update(plaintext) + cipher.final) end # Perform in-memory decryption. This is useful for testing and development. - def memory_decrypt(path, key, ciphertext, client) + def memory_decrypt(path, key, ciphertext, client: , context: nil) log_warning(DEV_WARNING) if self.in_memory_warnings_enabled? return nil if ciphertext.nil? cipher = OpenSSL::Cipher::AES.new(128, :CBC) cipher.decrypt - cipher.key = memory_key_for(path, key) + cipher.key = memory_key_for(path, key, context: context) return cipher.update(Base64.strict_decode64(ciphertext)) + cipher.final end + # The symmetric key for the given params. + # @return [String] + def memory_key_for(path, key, context: nil) + md5 = OpenSSL::Digest::MD5.new + md5 << path + md5 << key + md5 << context if context + md5.digest + end + # Perform encryption using Vault. This will raise exceptions if Vault is # unavailable. - def vault_encrypt(path, key, plaintext, client) + def vault_encrypt(path, key, plaintext, client: , context: nil) return nil if plaintext.nil? - route = File.join(path, "encrypt", key) - secret = client.logical.write(route, - plaintext: Base64.strict_encode64(plaintext), - ) + route = File.join(path, "encrypt", key) + + data = { plaintext: Base64.strict_encode64(plaintext) } + data[:context] = Base64.strict_encode64(context) if context + + secret = client.logical.write(route, data) + return secret.data[:ciphertext] end # Perform decryption using Vault. This will raise exceptions if Vault is # unavailable. - def vault_decrypt(path, key, ciphertext, client) + def vault_decrypt(path, key, ciphertext, client: , context: nil) return nil if ciphertext.nil? - route = File.join(path, "decrypt", key) - secret = client.logical.write(route, ciphertext: ciphertext) - return Base64.strict_decode64(secret.data[:plaintext]) - end + route = File.join(path, "decrypt", key) - # The symmetric key for the given params. - # @return [String] - def memory_key_for(path, key) - return Base64.strict_encode64("#{path}/#{key}".ljust(16, "x")).byteslice(0..15) + data = { ciphertext: ciphertext } + data[:context] = Base64.strict_encode64(context) if context + + secret = client.logical.write(route, data) + + return Base64.strict_decode64(secret.data[:plaintext]) end # Forces the encoding into the default Rails encoding and returns the # newly encoded string. # @return [String]