secure-systems-lab / securesystemslib

Cryptographic and general-purpose routines for Secure Systems Lab projects at NYU

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

support PIV attestation

jku opened this issue · comments

This came up in a discussion with @kommendorkapten:

  • Yubikey PIV module can produce a certificate chain that proves the signing key was generated on the Yubikey (and isn't e.g. a file on a disk)
  • We could include that chain as custom metadata when storing the public key
  • When that custom metadata is present, we could verify it when using the key

I haven't thought this through very well and it may be complicated enough to implement that it does not make sense in securesystemslib:

  • I don't know if certificate lookup is something PKCS11 covers at all or if only Yubikeys yubivo-piv-tool can do this.
  • unsure if the device contains the whole chain or only the device cert
  • unsure if standard keytypes sometimes having custom metadata is a good idea (this could be done in a new keytype as well but that would require all clients to support the new keytype when in reality it may be that only the repository installation and other signers care about the key storage)

The deivce does not contain Yubico's root cert, that has to be fetched OOB via their webpage: https://developers.yubico.com/yubico-piv-tool/Attestation.html

This sounds a bit like the mistake of conflating two independent PKIs that we made with gpg keys, where we included expiration date, master/sub key delegation info, etc. although similar information is also provided by the in-toto/tuf context. This only made verification more complex without a security benefit.

IMO it's the same here. It's a good idea to verify the certificate, when the key is included in the in-toto/tuf context (e.g. on HSMKey.import_) but later that context should be the single authority.

Yeah I kind of agree... Yet I can see how a repository would like to enforce that keys are hw generated, which it can't since signer import happens at signer device.

It's valid to say that thats a signing system implementation problem and not a securesystemslib problem -- implementing a Key/Signer pair that handles this outside of securesystemslib is actually probably not too hard 🤔

Hm, okay, I didn't think of the signer -> repository trust bootstrapping.

I guess, if we add support to for this (extract sig, fetch root certificate, verify) to HSMKey.import_, we might as well expose it in some way.

I just want to make sure that the use case is clear. A tuf/in-toto client should definitely see the key in metadata as single authority and not require an additional certificate.

I think the canonical example of this is Sigstore's root of trust. In the repsitory, all key attestations are stored. Today there is custom tooling that can verify that a given key is a proper Yubikey.

What I see is that we are looking at two different trust levels.

  1. Trust in the TUF repository/keholders itself. Sigstore achieves this via transparent TUF management, where anyone can verify that the keys are coming from Yubikeys.
  2. Trust the content of the TUF repository.

If a user is convinced to trust the keyholders the user can then use the TUF repo. The client tooling would thus as @lukpueh mentions simply trust the signature of the metadata as the user provided a root.json that contains the approved keys.

What I think is the topic here is that if the new key type (with PIV attestation) would simplify the process of convincing the comminity to trust the TUF repo (and keyholders) in the first place, as it's guaranteed that secure Yubikeys are used.

I will try to resist getting nerd sniped further but I'll document the design that yesterdays chat crystallized:

  • we could have a custom CertifiedYubiKey implementation (within securesystemslib or outside) that uses the normal CryptoKey underneath. The key class contains the yubikey root cert and expects to find a custom metadata field that contains the device cert, and verifies that certificate chain on construction time
  • the serialized metadata of CertifiedYubiKey is still a "normal" key (just with a custom field in it): download clients can just use the default CryptoKey implementation. But a repository could decide to use CertifiedYubiKey instead: this would mean only proper Yubikeys would work in those places
  • There's two options for importing a CertifiedYubiKey:
    • Make HSMSigner._import() return CertifiedYubiKeys if the device cert is available (and maybe if an optional arg certified=True) -- this only makes sense if this implementation is in securesystemslib
    • Add a separate method to turn a key into a CertifiedYubikey (read the device cert, add it to metadata)

This all sounds good. I'm not a big fan of hardcoding a root certificate into securesystemslib, but we could ask CertifiedYubiKey to bring their own.