class Ansible::Vault::Cryptor

The base class for handling the en/decryption process

This is here mostly to supply a consistent configuration for the various primitives in use.

@!attribute [r] file

@return [FileReader] The object handling manipulating data for the vault
  format.

Constants

BLOCK_SIZE

The number of bytes in the cipher’s block

CIPHER

The Cipher spec OpenSSL expects when building our cipher object.

HASH_ALGORITHM

The hashing algorithm for use in the KDF and HMAC calculations

KDF_ITERATIONS

The number of iterations to use in the key derivation function, this was pulled from the Ansible source. Do not change.

KDF_OUTPUT_LENGTH

The total number of bytes to be output by the key derivation function.

KEY_LENGTH

The number of bytes in each key we need to generate

Attributes

file[R]

Public Class Methods

new(password:, file:) click to toggle source

Build a new cryptor object

@param password [String] The password to be fed into the KDF @param file [FileReader] The object for correctly reading/writing the

Ansible vault file format.
# File lib/ansible/vault/cryptor.rb, line 37
def initialize(password:, file:)
  @password = password
  @file = file
end

Public Instance Methods

inspect() click to toggle source

Inspect the cryptor object.

Overridden from the default to prevent key/password leakage.

# File lib/ansible/vault/cryptor.rb, line 45
def inspect
  "#<#{self.class.name}:#{"0x00%x" % (object_id << 1)}>"
end

Private Instance Methods

calculated_hmac() click to toggle source
# File lib/ansible/vault/cryptor.rb, line 51
def calculated_hmac
  return @calculated_hmac if defined?(@calculated_hmac)
  digest = OpenSSL::Digest.new(HASH_ALGORITHM)
  hmac_algorithm = OpenSSL::HMAC.new(hmac_key, digest)
  hmac_algorithm << file.ciphertext
  @calculated_hmac = hmac_algorithm.hexdigest
end
cipher(mode: :decrypt) click to toggle source
# File lib/ansible/vault/cryptor.rb, line 59
def cipher(mode: :decrypt)
  @cipher ||= OpenSSL::Cipher.new(CIPHER).tap do |cipher|
    cipher.public_send(mode)
    cipher.key = cipher_key
    cipher.iv = iv
  end
end
cipher_key() click to toggle source
# File lib/ansible/vault/cryptor.rb, line 67
def cipher_key
  return @cipher_key if defined?(@cipher_key)
  derive_keys
  @cipher_key
end
derive_keys() click to toggle source
# File lib/ansible/vault/cryptor.rb, line 85
def derive_keys
  if salt.nil? || salt.strip.empty?
    raise MissingSalt, "Unable to derive keys, no salt available!"
  end
  key = OpenSSL::PKCS5.pbkdf2_hmac(
    @password,
    salt,
    KDF_ITERATIONS,
    KDF_OUTPUT_LENGTH,
    HASH_ALGORITHM
  )
  @cipher_key = key[0,KEY_LENGTH].shred_later
  @hmac_key = key[KEY_LENGTH, KEY_LENGTH].shred_later
  @iv = key[KEY_LENGTH*2, IV_LENGTH].shred_later
  key.shred!
  nil
end
hmac_key() click to toggle source
# File lib/ansible/vault/cryptor.rb, line 73
def hmac_key
  return @hmac_key if defined?(@hmac_key)
  derive_keys
  @hmac_key
end
iv() click to toggle source
# File lib/ansible/vault/cryptor.rb, line 79
def iv
  return @iv if defined?(@iv)
  derive_keys
  @iv
end