Module: Mongo::Crypt::Hooks Private

Defined in:
lib/mongo/crypt/hooks.rb

Overview

This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.

A helper module that implements cryptography methods required for native Ruby crypto hooks. These methods are passed into FFI as C callbacks and called from the libmongocrypt library.

Class Method Summary collapse

Class Method Details

.aes(key, iv, input, decrypt: false, mode: :CBC) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

An AES encrypt or decrypt method.

Parameters:

  • key (String)

    The 32-byte AES encryption key

  • iv (String)

    The 16-byte AES IV

  • input (String)

    The data to be encrypted/decrypted

  • decrypt (true | false) (defaults to: false)

    Whether this method is decrypting. Default is false, which means the method will create an encryption cipher by default

  • mode (Symbol) (defaults to: :CBC)

    AES mode of operation

Returns:

  • (String)

    Output

Raises:

  • (Exception)

    Exceptions raised during encryption are propagated to caller.



43
44
45
46
47
48
49
50
51
52
# File 'lib/mongo/crypt/hooks.rb', line 43

def aes(key, iv, input, decrypt: false, mode: :CBC)
  cipher = OpenSSL::Cipher::AES.new(256, mode)

  decrypt ? cipher.decrypt : cipher.encrypt
  cipher.key = key
  cipher.iv = iv
  cipher.padding = 0

  encrypted = cipher.update(input)
end

.hash_sha256(input) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

A crypto hash (SHA-256) function

Parameters:

  • input (String)

    The data to be hashed

Returns:

  • (String)

Raises:

  • (Exception)

    Exceptions raised during encryption are propagated to caller.



88
89
90
# File 'lib/mongo/crypt/hooks.rb', line 88

def hash_sha256(input)
  Digest::SHA2.new(256).digest(input)
end

.hmac_sha(digest_name, key, input) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

An HMAC SHA-512 or SHA-256 function

Parameters:

  • digest_name (String)

    The name of the digest, either “SHA256” or “SHA512”

  • key (String)

    The 32-byte AES encryption key

  • input (String)

    The data to be tagged

Returns:

  • (String)

Raises:

  • (Exception)

    Exceptions raised during encryption are propagated to caller.



76
77
78
# File 'lib/mongo/crypt/hooks.rb', line 76

def hmac_sha(digest_name, key, input)
  OpenSSL::HMAC.digest(digest_name, key, input)
end

.random(num_bytes) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Crypto secure random function

Parameters:

  • num_bytes (Integer)

    The number of random bytes requested

Returns:

  • (String)

Raises:

  • (Exception)

    Exceptions raised during encryption are propagated to caller.



62
63
64
# File 'lib/mongo/crypt/hooks.rb', line 62

def random(num_bytes)
  SecureRandom.random_bytes(num_bytes)
end

.rsaes_pkcs_signature(key, input) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

An RSASSA-PKCS1-v1_5 with SHA-256 signature function.

Parameters:

  • key (String)

    The PKCS#8 private key in DER format, base64 encoded.

  • input (String)

    The data to be signed.

Returns:

  • (String)

    The signature.



99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/mongo/crypt/hooks.rb', line 99

def rsaes_pkcs_signature(key, input)
  private_key = if BSON::Environment.jruby?
    # JRuby cannot read DER format, we need to convert key into PEM first.
    key_pem = [
      "-----BEGIN PRIVATE KEY-----",
      Base64.strict_encode64(Base64.decode64(key)).scan(/.{1,64}/),
      "-----END PRIVATE KEY-----",
    ].join("\n")
    OpenSSL::PKey::RSA.new(key_pem)
  else
    OpenSSL::PKey.read(Base64.decode64(key))
  end
  private_key.sign(OpenSSL::Digest::SHA256.new, input)
end