google / google/go-tpm-tools

client: add a way to find a persistent key by its public key

Open
#901 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C
Stars
307
Forks
118
Avg merge
1d 16h
Merged PRs (30d)
33

Description

client.LoadCachedKey requires the caller to know the handle a key sits at. That handle is set by whoever provisioned the key and can differ between machines, so applications end up carrying it in config and keeping it in sync with provisioning.

If you have an X.509 certificate for a TPM key, the certificate's public key is the key's public half, so the key can be found by matching that public key against the TPM's persistent keys, with no configured handle needed.

Today that takes manual enumeration:

certPub := cert.PublicKey

handles, err := client.Handles(rw, tpm2.HandleTypePersistent)
if err != nil { ... }
for _, h := range handles {
    pub, _, _, err := tpm2.ReadPublic(rw, h)
    if err != nil { ... }
    key, err := pub.Key()
    if err != nil { ... }
    if key.(interface{ Equal(crypto.PublicKey) bool }).Equal(certPub) {
        // found it
    }
}

Every consumer that pairs a TPM key with an X.509 certificate (TLS client auth, CSR generation) has to write this same loop.

Proposal

// FindHandle returns the handle of the persistent key whose public key is pub,
// or ErrNoKeyFound if no persistent key matches.
func FindHandle(rw io.ReadWriter, pub crypto.PublicKey) (tpmutil.Handle, error)

This composes with the existing API: the result feeds into client.LoadCachedKey.

handle, err := client.FindHandle(rw, cert.PublicKey)
// ...
key, err := client.LoadCachedKey(rw, handle, mySession)

I'd scope this to persistent handles only, since the point is finding a key another process provisioned, and transient handles don't cross process boundaries anyway.

Happy to send a PR!

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the existing client.LoadCachedKey API and the Handles and ReadPublic calls shown in the issue. Trace how persistent handles and public keys are represented, then verify that the new lookup returns the matching handle or ErrNoKeyFound and composes with LoadCachedKey.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
security
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.