Module: Fripa::VaultTransport

Defined in:
lib/fripa/vault_transport.rb

Constant Summary collapse

CIPHER =
"AES-128-CBC"
WRAPPING_ALGO =
"aes-128-cbc"
KEY_SIZE =
16
IV_SIZE =
16
RSA_KEY_SIZE =
2048
RSA_PADDING =
OpenSSL::PKey::RSA::PKCS1_PADDING

Class Method Summary collapse

Class Method Details

.decrypt(vault_data:, nonce:, session_key:) ⇒ Object



19
20
21
22
23
24
25
# File 'lib/fripa/vault_transport.rb', line 19

def self.decrypt(vault_data:, nonce:, session_key:)
  decipher = OpenSSL::Cipher.new(CIPHER)
  decipher.decrypt
  decipher.key = session_key
  decipher.iv = Base64.decode64(nonce)
  decipher.update(Base64.decode64(vault_data)) + decipher.final
end

.encrypt_data(data, key, nonce) ⇒ Object



40
41
42
43
44
45
# File 'lib/fripa/vault_transport.rb', line 40

def self.encrypt_data(data, key, nonce)
  cipher = OpenSSL::Cipher.new(CIPHER).encrypt
  cipher.key = key
  cipher.iv = nonce
  cipher.update(data.b) + cipher.final
end

.encrypt_session_key(session_key, cert_der) ⇒ Object



47
48
49
50
# File 'lib/fripa/vault_transport.rb', line 47

def self.encrypt_session_key(session_key, cert_der)
  cert = OpenSSL::X509::Certificate.new(cert_der)
  cert.public_key.public_encrypt(session_key, RSA_PADDING)
end

.generate_session_keyObject



15
16
17
# File 'lib/fripa/vault_transport.rb', line 15

def self.generate_session_key
  OpenSSL::Random.random_bytes(KEY_SIZE)
end

.generate_transport_keyObject



62
63
64
# File 'lib/fripa/vault_transport.rb', line 62

def self.generate_transport_key
  OpenSSL::PKey::RSA.generate(RSA_KEY_SIZE)
end

.unwrap(vault_data:, session_key:, nonce:, private_key:) ⇒ Object



52
53
54
55
56
57
58
59
60
# File 'lib/fripa/vault_transport.rb', line 52

def self.unwrap(vault_data:, session_key:, nonce:, private_key:)
  decrypted_session_key = private_key.private_decrypt(Base64.decode64(session_key), RSA_PADDING)

  decipher = OpenSSL::Cipher.new(CIPHER)
  decipher.decrypt
  decipher.key = decrypted_session_key
  decipher.iv = Base64.decode64(nonce)
  decipher.update(Base64.decode64(vault_data)) + decipher.final
end

.wrap(data, transport_cert_der) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/fripa/vault_transport.rb', line 27

def self.wrap(data, transport_cert_der)
  session_key = generate_session_key
  nonce = OpenSSL::Random.random_bytes(IV_SIZE)
  vault_data = encrypt_data(data, session_key, nonce)
  encrypted_session_key = encrypt_session_key(session_key, transport_cert_der)

  {
    vault_data: Base64.strict_encode64(vault_data),
    session_key: Base64.strict_encode64(encrypted_session_key),
    nonce: Base64.strict_encode64(nonce)
  }
end