kops/vendor/github.com/google/go-tpm-tools/client/import.go

84 lines
2.2 KiB
Go

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()
}