I wrote about some useful
changes to ansible-vault in Ansible 2
in an earlier post. Unfortunately, another
significant change
to the vault internals was rejected for Ansible 2.
Vault cryptography
The
VaultAES256
class implements encryption and decryption. It uses sensible building
blocks: PBKDF2 for key generation with a random salt, AES-CTR for
encryption, and HMAC-SHA-256 for authentication (used in
encrypt-then-mac fashion). This is a major improvement over the earlier
VaultAES class, which used homebrew key generation and an
SHA-256 digest alone for “verification”.
Nevertheless, the code has some embarrassing oversights. They are not
vulnerabilities, but they show that the code was written with… rather
less familiarity with cryptography than one might wish:
- Plaintext is padded to the AES block size, but this is unnecessary
because AES-CTR is used as a stream cipher.
- An extra 32-byte block of PBKDF2 (10,000 iterations) output is
derived to initialise the 16-byte IV, and the other half discarded; but
this is unnecessary because the IV can be 0 (the salt ensures that we
do not use the same key to encrypt the same plaintext).
Finally, the ciphertext is passed through hexlify()
twice,
thereby inflating it to 4x the size (instead of using, say, Base64).
This is the least significant and yet the most annoying problem.
The most visible effects of the over-enthusiastic PBKDF2 use were
mitigated by a pull request to use an
optimised PBKDF2 implementation.
This reduced the startup time by an order of magnitude for setups that
loaded many vault-encrypted files from group_vars and
host_vars.
All of these problems were solved by
PR #12130,
which saw several rounds of changes and was slated for inclusion in
Ansible 2, but was eventually rejected by the maintainers because there
wasn't “anyone in-house to review it for security problems and it's late
to be adding it for v2”.
Other changes that didn't make it
A couple of other often-requested Vault changes fell by the wayside en
route to Ansible 2:
- GPG support
for the vault was submitted as a PR over a year ago, but the code is
now outdated after an initial rebase to the v2 codebase.
- Lookup support
(with the file lookup plugin, and also with the copy module) was partly
implemented but never completed and merged.
Many people left +1 comments on Github to indicate their
support for these features. I hope someone wants them enough to work on
them for v2.1, and that they have better luck getting this work merged
than I did.