Skip to content

Commit 6b3308e

Browse files
authored
Merge pull request #955 from smallstep/mariano/key-public
Add a Public method to the tpm.Key
2 parents 3b1487e + cb7d649 commit 6b3308e

2 files changed

Lines changed: 76 additions & 0 deletions

File tree

tpm/key.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,28 @@ func (k *Key) WasAttestedBy(ak *AK) bool {
6363
return k.attestedBy == ak.name
6464
}
6565

66+
// Public returns the Key public key. This is backed
67+
// by a call to the TPM, so it can fail. If it fails,
68+
// nil is returned.
69+
func (k *Key) Public() crypto.PublicKey {
70+
var (
71+
err error
72+
ctx = context.Background()
73+
)
74+
if err = k.tpm.open(ctx); err != nil {
75+
return nil
76+
}
77+
defer closeTPM(context.Background(), k.tpm, &err)
78+
79+
key, err := k.tpm.attestTPM.LoadKey(k.data)
80+
if err != nil {
81+
return nil
82+
}
83+
defer key.Close()
84+
85+
return key.Public()
86+
}
87+
6688
// Certificate returns the certificate for the Key, if set.
6789
// Will return nil in case no AK certificate is available.
6890
func (k *Key) Certificate() *x509.Certificate {

tpm/tpm_simulator_test.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"context"
77
"crypto"
88
"crypto/ecdsa"
9+
"crypto/elliptic"
910
"crypto/rand"
1011
"crypto/rsa"
1112
"crypto/x509"
@@ -16,6 +17,7 @@ import (
1617
"fmt"
1718
"io"
1819
"math"
20+
"strconv"
1921
"strings"
2022
"testing"
2123

@@ -693,6 +695,58 @@ func TestKey_CertificationParameters(t *testing.T) {
693695
require.NoError(t, err)
694696
}
695697

698+
func TestKey_Public(t *testing.T) {
699+
ctx := t.Context()
700+
tpm := newSimulatedTPM(t)
701+
702+
t.Run("RSA", func(t *testing.T) {
703+
for _, size := range []int{1024, 2048} {
704+
sizeStr := strconv.Itoa(size)
705+
t.Run(sizeStr, func(t *testing.T) {
706+
key, err := tpm.CreateKey(ctx, "rsa-key-"+sizeStr, CreateKeyConfig{
707+
Algorithm: "RSA",
708+
Size: size,
709+
})
710+
require.NoError(t, err)
711+
712+
signer, err := key.Signer(ctx)
713+
require.NoError(t, err)
714+
715+
pub := key.Public()
716+
assert.Equal(t, signer.Public(), pub)
717+
if assert.IsType(t, &rsa.PublicKey{}, pub) {
718+
assert.Equal(t, size/8, pub.(*rsa.PublicKey).Size())
719+
}
720+
})
721+
}
722+
})
723+
724+
t.Run("ECDSA", func(t *testing.T) {
725+
for _, crv := range []elliptic.Curve{
726+
elliptic.P256(), elliptic.P384(), elliptic.P521(),
727+
} {
728+
size := crv.Params().BitSize
729+
sizeStr := strconv.Itoa(size)
730+
t.Run("P-"+sizeStr, func(t *testing.T) {
731+
key, err := tpm.CreateKey(ctx, "ecdsa-key-"+sizeStr, CreateKeyConfig{
732+
Algorithm: "ECDSA",
733+
Size: size,
734+
})
735+
require.NoError(t, err)
736+
737+
signer, err := key.Signer(ctx)
738+
require.NoError(t, err)
739+
740+
pub := key.Public()
741+
assert.Equal(t, signer.Public(), pub)
742+
if assert.IsType(t, &ecdsa.PublicKey{}, pub) {
743+
assert.Equal(t, crv, pub.(*ecdsa.PublicKey).Curve)
744+
}
745+
})
746+
}
747+
})
748+
}
749+
696750
func TestKey_Blobs(t *testing.T) {
697751
tpm := newSimulatedTPM(t)
698752
config := CreateKeyConfig{

0 commit comments

Comments
 (0)