Skip to content

Checking that we trust recipients breaks GPG's web of trust model #26

@bruntonspall

Description

@bruntonspall

The code at https://github.com/sihil/hiera-eyaml-gpg/blob/master/lib/hiera/backend/eyaml/encryptors/gpg.rb#L129-L138 checks whether the recipients that we are encrypting to are listed as having full validity within the web of trust.

This breaks the concept of the web of trust, since it conflates whether a recipient is who they say they are, and whether you trust a key to sign other keys.

I understand that this was done in order to check that an attacker had not added their own key to the list of recipients, and this is a valid attack to be concerned about, but the trust model is the wrong tool to solve that problem.

The issue that this gives for us is:

  1. We distribute passwordless keys to various public servers, for different stages.
    We are happy to encrypt to those keys, if somebody can possess that key they can decrypt the relevant parts of the context. That's a risk model that we already take with puppetmaster's anyway.
    However we are not happy to trust those keys to perform encryption or signing. If somebody can possess one of those keys and sign their own key with it, we don't want to trust the new key. If somebody uses one of those keys to write a new encrypted blob to out git repository we don't want to trust that block
    We only trust the human managed keys where we have confidence that the person will follow reasonable measures before signing another persons key
  2. Even worse, we have a developer passwordless key that we publish as part of our public repo.
    This key is used in vagrant builds to apply known compromised credentials (such as user DB, password: password) to developer machines. We know that key is publicly accessible, and we deliberate set the trust as NEVER for our GPG implementation, so we know that the key cannot ever be trusted to sign or encrypt anything.

Currently, the implementation we have here requires all of the team to trust that compromised key, or to set the always trust option, defeating the point of us setting up a web of trust.

I believe the correct solution here is probably:

  1. Remove the check for whether the recipients are trusted.
  2. To combat the original attack, the recipients list should be signed, and the tool should attempt to verify the signature before using it. The file should only verify the signature if the signing key is trusted, so it proves that a human you trust has modified the recipients list and correctly signed it. Manual recipient lists should work as before.
  3. You probably need a parameter to skip verifying the signature, to allow for upgrades and for users who choose not to use the recipient list signing function (always-trust maybe)
  4. the decrypt function should probably check that the encrypted contents are signed by someone on the web of trust. I believe this is the default in GPGME (sign and encrypt, decrypt and verify). The passwordless keys on the puppetmaster should trust either each member of staff, or a master key that trusts each member of staff (giving a proper web of trust). Only files encrypted by a trusted key should be accepted.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions