mirror of
https://github.com/google/go-attestation.git
synced 2025-02-11 04:51:09 +00:00
attest: tpm.NewKeyCertifiedBy() method that does not need an entire attest.AK object. The new method only needs the AK handle and its algorithm. (#402)
Some checks failed
CodeQL / Analyze (go) (push) Has been cancelled
Test / test-linux (1.22.x) (push) Has been cancelled
Test / test-linux-tpm12 (1.22.x) (push) Has been cancelled
Test / test-macos (1.22.x) (push) Has been cancelled
Test / test-windows (1.22.x) (push) Has been cancelled
Some checks failed
CodeQL / Analyze (go) (push) Has been cancelled
Test / test-linux (1.22.x) (push) Has been cancelled
Test / test-linux-tpm12 (1.22.x) (push) Has been cancelled
Test / test-macos (1.22.x) (push) Has been cancelled
Test / test-windows (1.22.x) (push) Has been cancelled
This commit is contained in:
parent
dfabc9c919
commit
9cdb0fcd55
@ -364,6 +364,7 @@ type tpmBase interface {
|
|||||||
loadKey(opaqueBlob []byte) (*Key, error)
|
loadKey(opaqueBlob []byte) (*Key, error)
|
||||||
loadKeyWithParent(opaqueBlob []byte, parent ParentKeyConfig) (*Key, error)
|
loadKeyWithParent(opaqueBlob []byte, parent ParentKeyConfig) (*Key, error)
|
||||||
newKey(ak *AK, opts *KeyConfig) (*Key, error)
|
newKey(ak *AK, opts *KeyConfig) (*Key, error)
|
||||||
|
newKeyCertifiedByKey(ck certifyingKey, opts *KeyConfig) (*Key, error)
|
||||||
pcrs(alg HashAlg) ([]PCR, error)
|
pcrs(alg HashAlg) ([]PCR, error)
|
||||||
measurementLog() ([]byte, error)
|
measurementLog() ([]byte, error)
|
||||||
}
|
}
|
||||||
@ -449,6 +450,22 @@ func (t *TPM) NewKey(ak *AK, opts *KeyConfig) (*Key, error) {
|
|||||||
return t.tpm.newKey(ak, opts)
|
return t.tpm.newKey(ak, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewKeyCertifiedByKey creates an application key certified by
|
||||||
|
// the attestation key. Unlike NewKey(), this method does not require
|
||||||
|
// an attest.AK object and only requires the AK handle and its algorithm.
|
||||||
|
// Thus it can be used in cases where the attestation key was not created
|
||||||
|
// by go-attestation library. If opts is nil then DefaultConfig is used.
|
||||||
|
func (t *TPM) NewKeyCertifiedByKey(akHandle tpmutil.Handle, akAlg Algorithm, opts *KeyConfig) (*Key, error) {
|
||||||
|
if opts == nil {
|
||||||
|
opts = defaultConfig
|
||||||
|
}
|
||||||
|
if opts.Algorithm == "" && opts.Size == 0 {
|
||||||
|
opts = defaultConfig
|
||||||
|
}
|
||||||
|
ck := certifyingKey{handle: akHandle, alg: akAlg}
|
||||||
|
return t.tpm.newKeyCertifiedByKey(ck, opts)
|
||||||
|
}
|
||||||
|
|
||||||
// LoadKey loads a previously-created application key into the TPM for use.
|
// LoadKey loads a previously-created application key into the TPM for use.
|
||||||
// A key loaded via this function needs to be closed with .Close().
|
// A key loaded via this function needs to be closed with .Close().
|
||||||
// Only blobs generated by calling Key.Marshal() are valid parameters
|
// Only blobs generated by calling Key.Marshal() are valid parameters
|
||||||
|
@ -112,6 +112,10 @@ func (t *trousersTPM) newKey(*AK, *KeyConfig) (*Key, error) {
|
|||||||
return nil, fmt.Errorf("not implemented")
|
return nil, fmt.Errorf("not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *trousersTPM) newKeyCertifiedByKey(ck certifyingKey, opts *KeyConfig) (*Key, error) {
|
||||||
|
return nil, fmt.Errorf("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
func (t *trousersTPM) loadKey(opaqueBlob []byte) (*Key, error) {
|
func (t *trousersTPM) loadKey(opaqueBlob []byte) (*Key, error) {
|
||||||
return nil, fmt.Errorf("not implemented")
|
return nil, fmt.Errorf("not implemented")
|
||||||
}
|
}
|
||||||
|
@ -345,6 +345,10 @@ func (t *windowsTPM) newKey(*AK, *KeyConfig) (*Key, error) {
|
|||||||
return nil, fmt.Errorf("not implemented")
|
return nil, fmt.Errorf("not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *windowsTPM) newKeyCertifiedByKey(ck certifyingKey, opts *KeyConfig) (*Key, error) {
|
||||||
|
return nil, fmt.Errorf("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
func (t *windowsTPM) loadKey(opaqueBlob []byte) (*Key, error) {
|
func (t *windowsTPM) loadKey(opaqueBlob []byte) (*Key, error) {
|
||||||
return nil, fmt.Errorf("not implemented")
|
return nil, fmt.Errorf("not implemented")
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,12 @@ type wrappedTPM20 struct {
|
|||||||
tpmECCEkTemplate *tpm2.Public
|
tpmECCEkTemplate *tpm2.Public
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// certifyingKey contains details of a TPM key that could certify other keys.
|
||||||
|
type certifyingKey struct {
|
||||||
|
handle tpmutil.Handle
|
||||||
|
alg Algorithm
|
||||||
|
}
|
||||||
|
|
||||||
func (t *wrappedTPM20) rsaEkTemplate() tpm2.Public {
|
func (t *wrappedTPM20) rsaEkTemplate() tpm2.Public {
|
||||||
if t.tpmRSAEkTemplate != nil {
|
if t.tpmRSAEkTemplate != nil {
|
||||||
return *t.tpmRSAEkTemplate
|
return *t.tpmRSAEkTemplate
|
||||||
@ -285,6 +291,15 @@ func (t *wrappedTPM20) newKey(ak *AK, opts *KeyConfig) (*Key, error) {
|
|||||||
return nil, fmt.Errorf("expected *wrappedKey20, got: %T", k)
|
return nil, fmt.Errorf("expected *wrappedKey20, got: %T", k)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kAlg, err := k.algorithm()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("get algorithm: %v", err)
|
||||||
|
}
|
||||||
|
ck := certifyingKey{handle: k.hnd, alg: kAlg}
|
||||||
|
return t.newKeyCertifiedByKey(ck, opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *wrappedTPM20) newKeyCertifiedByKey(ck certifyingKey, opts *KeyConfig) (*Key, error) {
|
||||||
parent, blob, pub, creationData, err := createKey(t, opts)
|
parent, blob, pub, creationData, err := createKey(t, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot create key: %v", err)
|
return nil, fmt.Errorf("cannot create key: %v", err)
|
||||||
@ -303,9 +318,9 @@ func (t *wrappedTPM20) newKey(ak *AK, opts *KeyConfig) (*Key, error) {
|
|||||||
|
|
||||||
// Certify application key by AK
|
// Certify application key by AK
|
||||||
certifyOpts := CertifyOpts{QualifyingData: opts.QualifyingData}
|
certifyOpts := CertifyOpts{QualifyingData: opts.QualifyingData}
|
||||||
cp, err := k.certify(t, keyHandle, certifyOpts)
|
cp, err := certifyByKey(t, keyHandle, ck, certifyOpts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("ak.Certify() failed: %v", err)
|
return nil, fmt.Errorf("certifyByKey() failed: %v", err)
|
||||||
}
|
}
|
||||||
if !bytes.Equal(pub, cp.Public) {
|
if !bytes.Equal(pub, cp.Public) {
|
||||||
return nil, fmt.Errorf("certified incorrect key, expected: %v, certified: %v", pub, cp.Public)
|
return nil, fmt.Errorf("certified incorrect key, expected: %v, certified: %v", pub, cp.Public)
|
||||||
@ -567,28 +582,36 @@ func (k *wrappedKey20) activateCredential(tb tpmBase, in EncryptedCredential, ek
|
|||||||
}, k.hnd, ekHnd, credential, secret)
|
}, k.hnd, ekHnd, credential, secret)
|
||||||
}
|
}
|
||||||
|
|
||||||
func sigSchemeFromPublicKey(pub []byte) (tpm2.SigScheme, error) {
|
func sigSchemeFromAlgorithm(alg Algorithm) (tpm2.SigScheme, error) {
|
||||||
tpmPub, err := tpm2.DecodePublic(pub)
|
switch alg {
|
||||||
if err != nil {
|
case RSA:
|
||||||
return tpm2.SigScheme{}, fmt.Errorf("decode public key: %v", err)
|
|
||||||
}
|
|
||||||
switch tpmPub.Type {
|
|
||||||
case tpm2.AlgRSA:
|
|
||||||
return tpm2.SigScheme{
|
return tpm2.SigScheme{
|
||||||
Alg: tpm2.AlgRSASSA,
|
Alg: tpm2.AlgRSASSA,
|
||||||
Hash: tpm2.AlgSHA256,
|
Hash: tpm2.AlgSHA256,
|
||||||
}, nil
|
}, nil
|
||||||
case tpm2.AlgECC:
|
case ECDSA:
|
||||||
return tpm2.SigScheme{
|
return tpm2.SigScheme{
|
||||||
Alg: tpm2.AlgECDSA,
|
Alg: tpm2.AlgECDSA,
|
||||||
Hash: tpm2.AlgSHA256,
|
Hash: tpm2.AlgSHA256,
|
||||||
}, nil
|
}, nil
|
||||||
default:
|
default:
|
||||||
return tpm2.SigScheme{}, fmt.Errorf("public key of alg 0x%x not supported", tpmPub.Type)
|
return tpm2.SigScheme{}, fmt.Errorf("algorithm %v not supported", alg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k *wrappedKey20) certify(tb tpmBase, handle interface{}, opts CertifyOpts) (*CertificationParameters, error) {
|
func (k *wrappedKey20) certify(tb tpmBase, handle interface{}, opts CertifyOpts) (*CertificationParameters, error) {
|
||||||
|
kAlg, err := k.algorithm()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("unknown algorithm: %v", err)
|
||||||
|
}
|
||||||
|
ck := certifyingKey{
|
||||||
|
handle: k.hnd,
|
||||||
|
alg: kAlg,
|
||||||
|
}
|
||||||
|
return certifyByKey(tb, handle, ck, opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func certifyByKey(tb tpmBase, handle interface{}, ck certifyingKey, opts CertifyOpts) (*CertificationParameters, error) {
|
||||||
t, ok := tb.(*wrappedTPM20)
|
t, ok := tb.(*wrappedTPM20)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("expected *wrappedTPM20, got %T", tb)
|
return nil, fmt.Errorf("expected *wrappedTPM20, got %T", tb)
|
||||||
@ -597,11 +620,11 @@ func (k *wrappedKey20) certify(tb tpmBase, handle interface{}, opts CertifyOpts)
|
|||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("expected tpmutil.Handle, got %T", handle)
|
return nil, fmt.Errorf("expected tpmutil.Handle, got %T", handle)
|
||||||
}
|
}
|
||||||
scheme, err := sigSchemeFromPublicKey(k.public)
|
scheme, err := sigSchemeFromAlgorithm(ck.alg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("get signature scheme: %v", err)
|
return nil, fmt.Errorf("get signature scheme: %v", err)
|
||||||
}
|
}
|
||||||
return certify(t.rwc, hnd, k.hnd, opts.QualifyingData, scheme)
|
return certify(t.rwc, hnd, ck.handle, opts.QualifyingData, scheme)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k *wrappedKey20) quote(tb tpmBase, nonce []byte, alg HashAlg, selectedPCRs []int) (*Quote, error) {
|
func (k *wrappedKey20) quote(tb tpmBase, nonce []byte, alg HashAlg, selectedPCRs []int) (*Quote, error) {
|
||||||
@ -707,3 +730,18 @@ func (k *wrappedKey20) decrypt(tb tpmBase, ctxt []byte) ([]byte, error) {
|
|||||||
func (k *wrappedKey20) blobs() ([]byte, []byte, error) {
|
func (k *wrappedKey20) blobs() ([]byte, []byte, error) {
|
||||||
return k.public, k.blob, nil
|
return k.public, k.blob, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (k *wrappedKey20) algorithm() (Algorithm, error) {
|
||||||
|
tpmPub, err := tpm2.DecodePublic(k.public)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("decode public key: %v", err)
|
||||||
|
}
|
||||||
|
switch tpmPub.Type {
|
||||||
|
case tpm2.AlgRSA:
|
||||||
|
return RSA, nil
|
||||||
|
case tpm2.AlgECC:
|
||||||
|
return ECDSA, nil
|
||||||
|
default:
|
||||||
|
return "", fmt.Errorf("unsupported key type: %v", tpmPub.Type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user