lib/kms_encrypted/database.rb in kms_encrypted-1.0.0 vs lib/kms_encrypted/database.rb in kms_encrypted-1.0.1
- old
+ new
@@ -6,88 +6,58 @@
@record = record
@key_method = key_method
@options = record.class.kms_keys[key_method.to_sym]
end
- def name
- options[:name]
+ def version
+ @version ||= evaluate_option(:version).to_i
end
- def current_version
- @version ||= begin
- version = options[:version]
- version = record.instance_exec(&version) if version.respond_to?(:call)
- version.to_i
- end
+ def key_id
+ @key_id ||= evaluate_option(:key_id)
end
- def key_version(version)
- versions = (options[:previous_versions] || {}).dup
- versions[current_version] ||= options.slice(:key_id)
-
- raise KmsEncrypted::Error, "Version not active: #{version}" unless versions[version]
-
- key_id = versions[version][:key_id]
-
- raise ArgumentError, "Missing key id" unless key_id
-
- key_id
+ def previous_versions
+ @previous_versions ||= evaluate_option(:previous_versions)
end
def context(version)
+ name = options[:name]
context_method = name ? "kms_encryption_context_#{name}" : "kms_encryption_context"
if record.method(context_method).arity == 0
record.send(context_method)
else
record.send(context_method, version: version)
end
end
def encrypt(plaintext)
- key_id = key_version(current_version)
- context = context(current_version)
- ciphertext = KmsEncrypted::Client.new(key_id: key_id, data_key: true).encrypt(plaintext, context: context)
- "v#{current_version}:#{encode64(ciphertext)}"
+ context = context(version)
+
+ KmsEncrypted::Box.new(
+ key_id: key_id,
+ version: version,
+ previous_versions: previous_versions
+ ).encrypt(plaintext, context: context)
end
def decrypt(ciphertext)
+ # determine version for context
m = /\Av(\d+):/.match(ciphertext)
- if m
- version = m[1].to_i
- ciphertext = ciphertext.sub("v#{version}:", "")
- else
- version = 1
- context = {} if options[:upgrade_context]
- legacy_context = true
+ version = m ? m[1].to_i : 1
+ context = (options[:upgrade_context] && !m) ? {} : context(version)
- # legacy
- if ciphertext.start_with?("$gc$")
- _, _, short_key_id, ciphertext = ciphertext.split("$", 4)
-
- # restore key, except for cryptoKeyVersion
- stored_key_id = decode64(short_key_id).split("/")[0..3]
- stored_key_id.insert(0, "projects")
- stored_key_id.insert(2, "locations")
- stored_key_id.insert(4, "keyRings")
- stored_key_id.insert(6, "cryptoKeys")
- key_id = stored_key_id.join("/")
- elsif ciphertext.start_with?("vault:")
- ciphertext = Base64.encode64(ciphertext)
- end
- end
-
- key_id ||= key_version(version)
- context ||= context(version)
- ciphertext = decode64(ciphertext)
-
- KmsEncrypted::Client.new(key_id: key_id, data_key: true, legacy_context: legacy_context).decrypt(ciphertext, context: context)
+ KmsEncrypted::Box.new(
+ key_id: key_id,
+ previous_versions: previous_versions
+ ).decrypt(ciphertext, context: context)
end
- def encode64(bytes)
- Base64.strict_encode64(bytes)
- end
+ private
- def decode64(bytes)
- Base64.decode64(bytes)
+ def evaluate_option(key)
+ opt = options[key]
+ opt = record.instance_exec(&opt) if opt.respond_to?(:call)
+ opt
end
end
end