package client import ( "fmt" "github.com/google/go-tpm-tools/internal" pb "github.com/google/go-tpm-tools/proto/tpm" "github.com/google/go-tpm/tpm2" "github.com/google/go-tpm/tpmutil" ) func loadHandle(k *Key, blob *pb.ImportBlob) (tpmutil.Handle, error) { auth, err := k.session.Auth() if err != nil { return tpm2.HandleNull, err } private, err := tpm2.Import(k.rw, k.Handle(), auth, blob.PublicArea, blob.Duplicate, blob.EncryptedSeed, nil, nil) if err != nil { return tpm2.HandleNull, fmt.Errorf("import failed: %w", err) } auth, err = k.session.Auth() if err != nil { return tpm2.HandleNull, err } handle, _, err := tpm2.LoadUsingAuth(k.rw, k.Handle(), auth, blob.PublicArea, private) if err != nil { return tpm2.HandleNull, fmt.Errorf("load failed: %w", err) } return handle, nil } // Import decrypts the secret contained in an encoded import request. // The key used must be an encryption key (signing keys cannot be used). // The req parameter should come from server.CreateImportBlob. func (k *Key) Import(blob *pb.ImportBlob) ([]byte, error) { handle, err := loadHandle(k, blob) if err != nil { return nil, err } defer tpm2.FlushContext(k.rw, handle) unsealSession, err := newPCRSession(k.rw, internal.PCRSelection(blob.Pcrs)) if err != nil { return nil, err } defer unsealSession.Close() auth, err := unsealSession.Auth() if err != nil { return nil, err } out, err := tpm2.UnsealWithSession(k.rw, auth.Session, handle, "") if err != nil { return nil, fmt.Errorf("unseal failed: %w", err) } return out, nil } // ImportSigningKey returns the signing key contained in an encoded import request. // The parent key must be an encryption key (signing keys cannot be used). // The req parameter should come from server.CreateSigningKeyImportBlob. func (k *Key) ImportSigningKey(blob *pb.ImportBlob) (key *Key, err error) { handle, err := loadHandle(k, blob) if err != nil { return nil, err } key = &Key{rw: k.rw, handle: handle} defer func() { if err != nil { key.Close() } }() if key.pubArea, _, _, err = tpm2.ReadPublic(k.rw, handle); err != nil { return } if key.session, err = newPCRSession(k.rw, internal.PCRSelection(blob.Pcrs)); err != nil { return } return key, key.finish() }