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