Skip to content

Commit 6463150

Browse files
authored
Merge pull request #590 from smallstep/herman/tpm-capalgs-testing-option
Change the simulated TPM options to accept initializers and preparers
2 parents 3f1a5d6 + 841a145 commit 6463150

File tree

3 files changed

+96
-15
lines changed

3 files changed

+96
-15
lines changed

kms/tpmkms/tpmkms_simulator_test.go

Lines changed: 79 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,19 @@ import (
3737
"go.step.sm/crypto/tpm/tss2"
3838
)
3939

40-
type newSimulatedTPMOption func(t *testing.T, tpm *tpmp.TPM)
40+
type newSimulatedTPMOption any
4141

42-
func withAK(name string) newSimulatedTPMOption {
42+
type newSimulatedTPMPreparerOption func(t *testing.T, tpm *tpmp.TPM)
43+
44+
func withAK(name string) newSimulatedTPMPreparerOption {
4345
return func(t *testing.T, tpm *tpmp.TPM) {
4446
t.Helper()
4547
_, err := tpm.CreateAK(context.Background(), name)
4648
require.NoError(t, err)
4749
}
4850
}
4951

50-
func withKey(name string) newSimulatedTPMOption {
52+
func withKey(name string) newSimulatedTPMPreparerOption {
5153
return func(t *testing.T, tpm *tpmp.TPM) {
5254
t.Helper()
5355
config := tpmp.CreateKeyConfig{
@@ -59,20 +61,38 @@ func withKey(name string) newSimulatedTPMOption {
5961
}
6062
}
6163

64+
func withCapabilities(caps *tpmp.Capabilities) tpmp.NewTPMOption {
65+
return tpmp.WithCapabilities(caps)
66+
}
67+
6268
func newSimulatedTPM(t *testing.T, opts ...newSimulatedTPMOption) *tpmp.TPM {
6369
t.Helper()
70+
6471
tmpDir := t.TempDir()
6572
tpmOpts := []tpmp.NewTPMOption{
6673
withSimulator(t),
6774
tpmp.WithStore(storage.NewDirstore(tmpDir)),
6875
}
6976

70-
tpm, err := tpmp.New(tpmOpts...)
77+
var preparers []newSimulatedTPMPreparerOption
78+
for _, opt := range opts {
79+
switch o := opt.(type) {
80+
case tpmp.NewTPMOption:
81+
tpmOpts = append(tpmOpts, o)
82+
case newSimulatedTPMPreparerOption:
83+
preparers = append(preparers, o)
84+
default:
85+
require.Fail(t, "invalid TPM option type provided", `TPM option type "%T"`, o)
86+
}
87+
}
7188

89+
tpm, err := tpmp.New(tpmOpts...)
7290
require.NoError(t, err)
73-
for _, applyTo := range opts {
91+
92+
for _, applyTo := range preparers {
7493
applyTo(t, tpm)
7594
}
95+
7696
return tpm
7797
}
7898

@@ -93,6 +113,60 @@ func withSimulator(t *testing.T) tpmp.NewTPMOption {
93113
return tpmp.WithSimulator(sim)
94114
}
95115

116+
func TestTPMKMS_CreateKey_Capabilities(t *testing.T) {
117+
tpmWithNoCaps := newSimulatedTPM(t, withCapabilities(&tpmp.Capabilities{}))
118+
type fields struct {
119+
tpm *tpmp.TPM
120+
}
121+
type args struct {
122+
req *apiv1.CreateKeyRequest
123+
}
124+
tests := []struct {
125+
name string
126+
fields fields
127+
args args
128+
assertFunc assert.ValueAssertionFunc
129+
expErr error
130+
}{
131+
{
132+
name: "fail/unsupported-algorithm",
133+
fields: fields{
134+
tpm: tpmWithNoCaps,
135+
},
136+
args: args{
137+
req: &apiv1.CreateKeyRequest{
138+
Name: "tpmkms:name=key1",
139+
SignatureAlgorithm: apiv1.SHA256WithRSA,
140+
Bits: 2048,
141+
},
142+
},
143+
assertFunc: func(tt assert.TestingT, i1 interface{}, i2 ...interface{}) bool {
144+
if assert.IsType(t, &apiv1.CreateKeyResponse{}, i1) {
145+
r, _ := i1.(*apiv1.CreateKeyResponse)
146+
return assert.Nil(t, r)
147+
}
148+
return false
149+
},
150+
expErr: errors.New(`signature algorithm "SHA256-RSA" not supported by the TPM device`),
151+
},
152+
}
153+
for _, tt := range tests {
154+
t.Run(tt.name, func(t *testing.T) {
155+
k := &TPMKMS{
156+
tpm: tt.fields.tpm,
157+
}
158+
got, err := k.CreateKey(tt.args.req)
159+
if tt.expErr != nil {
160+
assert.EqualError(t, err, tt.expErr.Error())
161+
return
162+
}
163+
164+
assert.NoError(t, err)
165+
assert.True(t, tt.assertFunc(t, got))
166+
})
167+
}
168+
}
169+
96170
func TestTPMKMS_CreateKey(t *testing.T) {
97171
tpmWithAK := newSimulatedTPM(t, withAK("ak1"))
98172
type fields struct {

tpm/caps_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ package tpm
33
import (
44
"testing"
55

6-
"github.com/smallstep/assert"
6+
"github.com/stretchr/testify/assert"
7+
78
"go.step.sm/crypto/tpm/algorithm"
89
)
910

tpm/tpm.go

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -75,15 +75,6 @@ func WithDisableDownload() NewTPMOption {
7575
}
7676
}
7777

78-
// WithCapabilities explicits sets the capabilities rather
79-
// than acquiring them from the TPM directly.
80-
func WithCapabilities(caps *Capabilities) NewTPMOption {
81-
return func(o *options) error {
82-
o.caps = caps
83-
return nil
84-
}
85-
}
86-
8778
// WithSimulator is used to configure a TPM simulator implementation
8879
// that simulates TPM operations instead of interacting with an actual
8980
// TPM.
@@ -105,6 +96,21 @@ func WithCommandChannel(commandChannel CommandChannel) NewTPMOption {
10596
}
10697
}
10798

99+
// WithCapabilities explicitly sets the capabilities rather
100+
// than acquiring them from the TPM directly. The primary use
101+
// for this option is to ease testing different TPM capabilities.
102+
//
103+
// # Experimental
104+
//
105+
// Notice: This option is EXPERIMENTAL and may be changed or removed
106+
// in a later release.
107+
func WithCapabilities(caps *Capabilities) NewTPMOption {
108+
return func(o *options) error {
109+
o.caps = caps
110+
return nil
111+
}
112+
}
113+
108114
type options struct {
109115
deviceName string
110116
attestConfig *attest.OpenConfig

0 commit comments

Comments
 (0)