summaryrefslogtreecommitdiff
path: root/lib/gitlab/crypto_helper.rb
blob: 4428354642d7f3de40d81cd667f408378731e28a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# frozen_string_literal: true

module Gitlab
  module CryptoHelper
    extend self

    AES256_GCM_OPTIONS = {
      algorithm: 'aes-256-gcm',
      key: Settings.attr_encrypted_db_key_base_32
    }.freeze

    AES256_GCM_IV_STATIC = Settings.attr_encrypted_db_key_base_12

    def sha256(value)
      salt = Settings.attr_encrypted_db_key_base_truncated
      ::Digest::SHA256.base64digest("#{value}#{salt}")
    end

    def aes256_gcm_encrypt(value, nonce: nil)
      aes256_gcm_encrypt_using_static_nonce(value)
    end

    def aes256_gcm_decrypt(value)
      return unless value

      nonce = Feature.enabled?(:dynamic_nonce_creation) ? dynamic_nonce(value) : AES256_GCM_IV_STATIC
      encrypted_token = Base64.decode64(value)
      decrypted_token = Encryptor.decrypt(AES256_GCM_OPTIONS.merge(value: encrypted_token, iv: nonce))
      decrypted_token
    end

    def dynamic_nonce(value)
      TokenWithIv.find_nonce_by_hashed_token(value) || AES256_GCM_IV_STATIC
    end

    def aes256_gcm_encrypt_using_static_nonce(value)
      create_encrypted_token(value, AES256_GCM_IV_STATIC)
    end

    def read_only?
      Gitlab::Database.read_only?
    end

    def create_encrypted_token(value, iv)
      encrypted_token = Encryptor.encrypt(AES256_GCM_OPTIONS.merge(value: value, iv: iv))
      Base64.strict_encode64(encrypted_token)
    end
  end
end