Class: Gitlab::License::Encryptor

Inherits:
Object
  • Object
show all
Defined in:
lib/gitlab/license/encryptor.rb

Defined Under Namespace

Classes: DecryptionError, Error, KeyError

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(key) ⇒ Encryptor

Returns a new instance of Encryptor.

Raises:



10
11
12
13
14
# File 'lib/gitlab/license/encryptor.rb', line 10

def initialize(key)
  raise KeyError, 'No RSA encryption key provided.' if key && !key.is_a?(OpenSSL::PKey::RSA)

  @key = key
end

Instance Attribute Details

#keyObject

Returns the value of attribute key.



8
9
10
# File 'lib/gitlab/license/encryptor.rb', line 8

def key
  @key
end

Instance Method Details

#decrypt(data) ⇒ Object

Raises:



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/gitlab/license/encryptor.rb', line 40

def decrypt(data)
  raise KeyError, 'Provided key is not a public key.' unless key.public?

  json_data = Base64.decode64(data.chomp)

  begin
    encryption_data = JSON.parse(json_data)
  rescue JSON::ParserError
    raise DecryptionError, 'Encryption data is invalid JSON.'
  end

  unless %w[data key iv].all? { |key| encryption_data[key] }
    raise DecryptionError, 'Required field missing from encryption data.'
  end

  encrypted_data  = Base64.decode64(encryption_data['data'])
  encrypted_key   = Base64.decode64(encryption_data['key'])
  aes_iv          = Base64.decode64(encryption_data['iv'])

  begin
    # Decrypt the AES key using asymmetric RSA encryption.
    aes_key = self.key.public_decrypt(encrypted_key)
  rescue OpenSSL::PKey::RSAError
    raise DecryptionError, 'AES encryption key could not be decrypted.'
  end

  # Decrypt the data using symmetric AES encryption.
  cipher = OpenSSL::Cipher::AES128.new(:CBC)
  cipher.decrypt

  begin
    cipher.key = aes_key
  rescue OpenSSL::Cipher::CipherError
    raise DecryptionError, 'AES encryption key is invalid.'
  end

  begin
    cipher.iv = aes_iv
  rescue OpenSSL::Cipher::CipherError
    raise DecryptionError, 'AES IV is invalid.'
  end

  begin
    data = cipher.update(encrypted_data) + cipher.final
  rescue OpenSSL::Cipher::CipherError
    raise DecryptionError, 'Data could not be decrypted.'
  end

  data
end

#encrypt(data) ⇒ Object

Raises:



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/gitlab/license/encryptor.rb', line 16

def encrypt(data)
  raise KeyError, 'Provided key is not a private key.' unless key.private?

  # Encrypt the data using symmetric AES encryption.
  cipher = OpenSSL::Cipher::AES128.new(:CBC)
  cipher.encrypt
  aes_key = cipher.random_key
  aes_iv  = cipher.random_iv

  encrypted_data = cipher.update(data) + cipher.final

  # Encrypt the AES key using asymmetric RSA encryption.
  encrypted_key = key.private_encrypt(aes_key)

  encryption_data = {
    'data' => Base64.encode64(encrypted_data),
    'key' => Base64.encode64(encrypted_key),
    'iv' => Base64.encode64(aes_iv)
  }

  json_data = JSON.dump(encryption_data)
  Base64.encode64(json_data)
end