Commit a5c78650 authored by talyz's avatar talyz

Use the exactly 32 byte long version of db_key_base with aes-256-gcm

Treewide, usage of a truncated version of db_key_base has been common
and it works fairly well with `aes-256-cbc`. However, with
`aes-256-gcm` the key must be exactly 32 bytes long - if it's longer
it has to be truncated, but if it's shorter it has to be padded. For
this reason the such a version of the key,
`attr_encrypted_db_key_base_32`, was introduced in
777b6713. This changes all occurrences
of `attr_encrypted_db_key_base_truncated` being used with
`aes-256-gcm`.
parent 69f6e347
...@@ -10,7 +10,7 @@ module AlertManagement ...@@ -10,7 +10,7 @@ module AlertManagement
attr_encrypted :token, attr_encrypted :token,
mode: :per_attribute_iv, mode: :per_attribute_iv,
key: Settings.attr_encrypted_db_key_base_truncated, key: Settings.attr_encrypted_db_key_base_32,
algorithm: 'aes-256-gcm' algorithm: 'aes-256-gcm'
default_value_for(:endpoint_identifier, allows_nil: false) { SecureRandom.hex(8) } default_value_for(:endpoint_identifier, allows_nil: false) { SecureRandom.hex(8) }
......
...@@ -10,7 +10,7 @@ module Alerting ...@@ -10,7 +10,7 @@ module Alerting
attr_encrypted :token, attr_encrypted :token,
mode: :per_attribute_iv, mode: :per_attribute_iv,
key: Settings.attr_encrypted_db_key_base_truncated, key: Settings.attr_encrypted_db_key_base_32,
algorithm: 'aes-256-gcm' algorithm: 'aes-256-gcm'
before_validation :ensure_token before_validation :ensure_token
......
...@@ -481,29 +481,29 @@ class ApplicationSetting < ApplicationRecord ...@@ -481,29 +481,29 @@ class ApplicationSetting < ApplicationRecord
algorithm: 'aes-256-cbc', algorithm: 'aes-256-cbc',
insecure_mode: true insecure_mode: true
private_class_method def self.encryption_options_base_truncated_aes_256_gcm private_class_method def self.encryption_options_base_32_aes_256_gcm
{ {
mode: :per_attribute_iv, mode: :per_attribute_iv,
key: Settings.attr_encrypted_db_key_base_truncated, key: Settings.attr_encrypted_db_key_base_32,
algorithm: 'aes-256-gcm', algorithm: 'aes-256-gcm',
encode: true encode: true
} }
end end
attr_encrypted :external_auth_client_key, encryption_options_base_truncated_aes_256_gcm attr_encrypted :external_auth_client_key, encryption_options_base_32_aes_256_gcm
attr_encrypted :external_auth_client_key_pass, encryption_options_base_truncated_aes_256_gcm attr_encrypted :external_auth_client_key_pass, encryption_options_base_32_aes_256_gcm
attr_encrypted :lets_encrypt_private_key, encryption_options_base_truncated_aes_256_gcm attr_encrypted :lets_encrypt_private_key, encryption_options_base_32_aes_256_gcm
attr_encrypted :eks_secret_access_key, encryption_options_base_truncated_aes_256_gcm attr_encrypted :eks_secret_access_key, encryption_options_base_32_aes_256_gcm
attr_encrypted :akismet_api_key, encryption_options_base_truncated_aes_256_gcm attr_encrypted :akismet_api_key, encryption_options_base_32_aes_256_gcm
attr_encrypted :elasticsearch_aws_secret_access_key, encryption_options_base_truncated_aes_256_gcm attr_encrypted :elasticsearch_aws_secret_access_key, encryption_options_base_32_aes_256_gcm
attr_encrypted :recaptcha_private_key, encryption_options_base_truncated_aes_256_gcm attr_encrypted :recaptcha_private_key, encryption_options_base_32_aes_256_gcm
attr_encrypted :recaptcha_site_key, encryption_options_base_truncated_aes_256_gcm attr_encrypted :recaptcha_site_key, encryption_options_base_32_aes_256_gcm
attr_encrypted :slack_app_secret, encryption_options_base_truncated_aes_256_gcm attr_encrypted :slack_app_secret, encryption_options_base_32_aes_256_gcm
attr_encrypted :slack_app_verification_token, encryption_options_base_truncated_aes_256_gcm attr_encrypted :slack_app_verification_token, encryption_options_base_32_aes_256_gcm
attr_encrypted :ci_jwt_signing_key, encryption_options_base_truncated_aes_256_gcm attr_encrypted :ci_jwt_signing_key, encryption_options_base_32_aes_256_gcm
attr_encrypted :secret_detection_token_revocation_token, encryption_options_base_truncated_aes_256_gcm attr_encrypted :secret_detection_token_revocation_token, encryption_options_base_32_aes_256_gcm
attr_encrypted :cloud_license_auth_token, encryption_options_base_truncated_aes_256_gcm attr_encrypted :cloud_license_auth_token, encryption_options_base_32_aes_256_gcm
attr_encrypted :external_pipeline_validation_service_token, encryption_options_base_truncated_aes_256_gcm attr_encrypted :external_pipeline_validation_service_token, encryption_options_base_32_aes_256_gcm
validates :disable_feed_token, validates :disable_feed_token,
inclusion: { in: [true, false], message: _('must be a boolean value') } inclusion: { in: [true, false], message: _('must be a boolean value') }
......
...@@ -11,14 +11,14 @@ module Atlassian ...@@ -11,14 +11,14 @@ module Atlassian
attr_encrypted :token, attr_encrypted :token,
mode: :per_attribute_iv, mode: :per_attribute_iv,
key: Settings.attr_encrypted_db_key_base_truncated, key: Settings.attr_encrypted_db_key_base_32,
algorithm: 'aes-256-gcm', algorithm: 'aes-256-gcm',
encode: false, encode: false,
encode_iv: false encode_iv: false
attr_encrypted :refresh_token, attr_encrypted :refresh_token,
mode: :per_attribute_iv, mode: :per_attribute_iv,
key: Settings.attr_encrypted_db_key_base_truncated, key: Settings.attr_encrypted_db_key_base_32,
algorithm: 'aes-256-gcm', algorithm: 'aes-256-gcm',
encode: false, encode: false,
encode_iv: false encode_iv: false
......
...@@ -12,11 +12,11 @@ class BulkImports::Configuration < ApplicationRecord ...@@ -12,11 +12,11 @@ class BulkImports::Configuration < ApplicationRecord
allow_nil: true allow_nil: true
attr_encrypted :url, attr_encrypted :url,
key: Settings.attr_encrypted_db_key_base_truncated, key: Settings.attr_encrypted_db_key_base_32,
mode: :per_attribute_iv, mode: :per_attribute_iv,
algorithm: 'aes-256-gcm' algorithm: 'aes-256-gcm'
attr_encrypted :access_token, attr_encrypted :access_token,
key: Settings.attr_encrypted_db_key_base_truncated, key: Settings.attr_encrypted_db_key_base_32,
mode: :per_attribute_iv, mode: :per_attribute_iv,
algorithm: 'aes-256-gcm' algorithm: 'aes-256-gcm'
end end
...@@ -22,7 +22,7 @@ module Clusters ...@@ -22,7 +22,7 @@ module Clusters
attr_encrypted :alert_manager_token, attr_encrypted :alert_manager_token,
mode: :per_attribute_iv, mode: :per_attribute_iv,
key: Settings.attr_encrypted_db_key_base_truncated, key: Settings.attr_encrypted_db_key_base_32,
algorithm: 'aes-256-gcm' algorithm: 'aes-256-gcm'
after_destroy do after_destroy do
......
...@@ -18,7 +18,7 @@ module Clusters ...@@ -18,7 +18,7 @@ module Clusters
attr_encrypted :secret_access_key, attr_encrypted :secret_access_key,
mode: :per_attribute_iv, mode: :per_attribute_iv,
key: Settings.attr_encrypted_db_key_base_truncated, key: Settings.attr_encrypted_db_key_base_32,
algorithm: 'aes-256-gcm' algorithm: 'aes-256-gcm'
validates :role_arn, validates :role_arn,
......
...@@ -84,7 +84,7 @@ module Packages ...@@ -84,7 +84,7 @@ module Packages
attr_encrypted :signing_keys, attr_encrypted :signing_keys,
mode: :per_attribute_iv, mode: :per_attribute_iv,
key: Settings.attr_encrypted_db_key_base_truncated, key: Settings.attr_encrypted_db_key_base_32,
algorithm: 'aes-256-gcm', algorithm: 'aes-256-gcm',
encode: false, encode: false,
encode_iv: false encode_iv: false
......
...@@ -38,7 +38,7 @@ module ErrorTracking ...@@ -38,7 +38,7 @@ module ErrorTracking
attr_encrypted :token, attr_encrypted :token,
mode: :per_attribute_iv, mode: :per_attribute_iv,
key: Settings.attr_encrypted_db_key_base_truncated, key: Settings.attr_encrypted_db_key_base_32,
algorithm: 'aes-256-gcm' algorithm: 'aes-256-gcm'
after_save :clear_reactive_cache! after_save :clear_reactive_cache!
......
...@@ -12,7 +12,7 @@ module IncidentManagement ...@@ -12,7 +12,7 @@ module IncidentManagement
attr_encrypted :pagerduty_token, attr_encrypted :pagerduty_token,
mode: :per_attribute_iv, mode: :per_attribute_iv,
key: ::Settings.attr_encrypted_db_key_base_truncated, key: ::Settings.attr_encrypted_db_key_base_32,
algorithm: 'aes-256-gcm', algorithm: 'aes-256-gcm',
encode: false, # No need to encode for binary column https://github.com/attr-encrypted/attr_encrypted#the-encode-encode_iv-encode_salt-and-default_encoding-options encode: false, # No need to encode for binary column https://github.com/attr-encrypted/attr_encrypted#the-encode-encode_iv-encode_salt-and-default_encoding-options
encode_iv: false encode_iv: false
......
...@@ -14,7 +14,7 @@ class PagesDomainAcmeOrder < ApplicationRecord ...@@ -14,7 +14,7 @@ class PagesDomainAcmeOrder < ApplicationRecord
attr_encrypted :private_key, attr_encrypted :private_key,
mode: :per_attribute_iv, mode: :per_attribute_iv,
key: Settings.attr_encrypted_db_key_base_truncated, key: Settings.attr_encrypted_db_key_base_32,
algorithm: 'aes-256-gcm', algorithm: 'aes-256-gcm',
encode: true encode: true
......
...@@ -12,7 +12,7 @@ module Serverless ...@@ -12,7 +12,7 @@ module Serverless
attr_encrypted :key, attr_encrypted :key,
mode: :per_attribute_iv, mode: :per_attribute_iv,
key: Settings.attr_encrypted_db_key_base_truncated, key: Settings.attr_encrypted_db_key_base_32,
algorithm: 'aes-256-gcm' algorithm: 'aes-256-gcm'
validates :pages_domain, :knative, presence: true validates :pages_domain, :knative, presence: true
......
production: production:
# db_key_base is used to encrypt for Variables. Ensure that you don't lose it. # db_key_base is used to encrypt for Variables. Ensure that you don't lose it.
# If you change or lose this key you will be unable to access variables stored in database. # If you change or lose this key you will be unable to access variables stored in database.
# Make sure the secret is at least 30 characters and all random, # Make sure the secret is at least 32 characters and all random,
# no regular words or you'll be exposed to dictionary attacks. # no regular words or you'll be exposed to dictionary attacks.
# db_key_base: # db_key_base:
......
...@@ -126,16 +126,18 @@ class Settings < Settingslogic ...@@ -126,16 +126,18 @@ class Settings < Settingslogic
File.expand_path(path, Rails.root) File.expand_path(path, Rails.root)
end end
# Ruby 2.4+ requires passing in the exact required length for OpenSSL keys # Don't use this in new code, use attr_encrypted_db_key_base_32 instead!
# (https://github.com/ruby/ruby/commit/ce635262f53b760284d56bb1027baebaaec175d1).
# Previous versions quietly truncated the input.
#
# Use this when using :per_attribute_iv mode for attr_encrypted.
# We have to truncate the string to 32 bytes for a 256-bit cipher.
def attr_encrypted_db_key_base_truncated def attr_encrypted_db_key_base_truncated
Gitlab::Application.secrets.db_key_base[0..31] Gitlab::Application.secrets.db_key_base[0..31]
end end
# Ruby 2.4+ requires passing in the exact required length for OpenSSL keys
# (https://github.com/ruby/ruby/commit/ce635262f53b760284d56bb1027baebaaec175d1).
# Previous versions quietly truncated the input.
#
# Makes sure the key is exactly 32 bytes long, either by
# truncating or right-padding it with ASCII 0s. Use this when
# using :per_attribute_iv mode for attr_encrypted.
def attr_encrypted_db_key_base_32 def attr_encrypted_db_key_base_32
Gitlab::Utils.ensure_utf8_size(attr_encrypted_db_key_base, bytes: 32.bytes) Gitlab::Utils.ensure_utf8_size(attr_encrypted_db_key_base, bytes: 32.bytes)
end end
......
...@@ -17,21 +17,21 @@ class EncryptPlaintextAttributesOnApplicationSettings < ActiveRecord::Migration[ ...@@ -17,21 +17,21 @@ class EncryptPlaintextAttributesOnApplicationSettings < ActiveRecord::Migration[
class ApplicationSetting < ActiveRecord::Base class ApplicationSetting < ActiveRecord::Base
self.table_name = 'application_settings' self.table_name = 'application_settings'
def self.encryption_options_base_truncated_aes_256_gcm def self.encryption_options_base_32_aes_256_gcm
{ {
mode: :per_attribute_iv, mode: :per_attribute_iv,
key: Gitlab::Application.secrets.db_key_base[0..31], key: Gitlab::Utils.ensure_utf8_size(Rails.application.secrets.db_key_base, bytes: 32.bytes),
algorithm: 'aes-256-gcm', algorithm: 'aes-256-gcm',
encode: true encode: true
} }
end end
attr_encrypted :akismet_api_key, encryption_options_base_truncated_aes_256_gcm attr_encrypted :akismet_api_key, encryption_options_base_32_aes_256_gcm
attr_encrypted :elasticsearch_aws_secret_access_key, encryption_options_base_truncated_aes_256_gcm attr_encrypted :elasticsearch_aws_secret_access_key, encryption_options_base_32_aes_256_gcm
attr_encrypted :recaptcha_private_key, encryption_options_base_truncated_aes_256_gcm attr_encrypted :recaptcha_private_key, encryption_options_base_32_aes_256_gcm
attr_encrypted :recaptcha_site_key, encryption_options_base_truncated_aes_256_gcm attr_encrypted :recaptcha_site_key, encryption_options_base_32_aes_256_gcm
attr_encrypted :slack_app_secret, encryption_options_base_truncated_aes_256_gcm attr_encrypted :slack_app_secret, encryption_options_base_32_aes_256_gcm
attr_encrypted :slack_app_verification_token, encryption_options_base_truncated_aes_256_gcm attr_encrypted :slack_app_verification_token, encryption_options_base_32_aes_256_gcm
def akismet_api_key def akismet_api_key
decrypt(:akismet_api_key, self[:encrypted_akismet_api_key]) || self[:akismet_api_key] decrypt(:akismet_api_key, self[:encrypted_akismet_api_key]) || self[:akismet_api_key]
......
...@@ -8,7 +8,7 @@ class GenerateCiJwtSigningKey < ActiveRecord::Migration[6.0] ...@@ -8,7 +8,7 @@ class GenerateCiJwtSigningKey < ActiveRecord::Migration[6.0]
attr_encrypted :ci_jwt_signing_key, { attr_encrypted :ci_jwt_signing_key, {
mode: :per_attribute_iv, mode: :per_attribute_iv,
key: Rails.application.secrets.db_key_base[0..31], key: Gitlab::Utils.ensure_utf8_size(Rails.application.secrets.db_key_base, bytes: 32.bytes),
algorithm: 'aes-256-gcm', algorithm: 'aes-256-gcm',
encode: true encode: true
} }
......
...@@ -55,7 +55,7 @@ class GeoNode < ApplicationRecord ...@@ -55,7 +55,7 @@ class GeoNode < ApplicationRecord
scope :ordered, -> { order(:id) } scope :ordered, -> { order(:id) }
attr_encrypted :secret_access_key, attr_encrypted :secret_access_key,
key: Settings.attr_encrypted_db_key_base_truncated, key: Settings.attr_encrypted_db_key_base_32,
algorithm: 'aes-256-gcm', algorithm: 'aes-256-gcm',
mode: :per_attribute_iv, mode: :per_attribute_iv,
encode: true encode: true
......
...@@ -11,7 +11,7 @@ RSpec.describe GenerateCiJwtSigningKey do ...@@ -11,7 +11,7 @@ RSpec.describe GenerateCiJwtSigningKey do
attr_encrypted :ci_jwt_signing_key, { attr_encrypted :ci_jwt_signing_key, {
mode: :per_attribute_iv, mode: :per_attribute_iv,
key: Rails.application.secrets.db_key_base[0..31], key: Gitlab::Utils.ensure_utf8_size(Rails.application.secrets.db_key_base, bytes: 32.bytes),
algorithm: 'aes-256-gcm', algorithm: 'aes-256-gcm',
encode: true encode: true
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment