Skip to content

Commit 606e2c2

Browse files
committed
coordinator: add tests for SetManifest peer authentication
1 parent a52c173 commit 606e2c2

File tree

1 file changed

+130
-5
lines changed

1 file changed

+130
-5
lines changed

coordinator/coordapi_test.go

+130-5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@ package main
22

33
import (
44
"context"
5+
"crypto/ecdsa"
6+
"crypto/elliptic"
7+
"crypto/rand"
8+
"crypto/sha256"
9+
"crypto/tls"
10+
"crypto/x509"
511
"encoding/json"
612
"log/slog"
713
"sync"
@@ -13,6 +19,8 @@ import (
1319
"github.com/edgelesssys/nunki/internal/memstore"
1420
"github.com/stretchr/testify/assert"
1521
"github.com/stretchr/testify/require"
22+
"google.golang.org/grpc/credentials"
23+
"google.golang.org/grpc/peer"
1624
)
1725

1826
func TestManifestSet(t *testing.T) {
@@ -28,12 +36,21 @@ func TestManifestSet(t *testing.T) {
2836
require.NoError(t, err)
2937
return b
3038
}
39+
trustedKey, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
40+
require.NoError(t, err)
41+
untrustedKey, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
42+
require.NoError(t, err)
43+
manifestWithTrustedKey, err := manifestWithWorkloadOwnerKey(trustedKey)
44+
require.NoError(t, err)
45+
manifestWithoutTrustedKey, err := manifestWithWorkloadOwnerKey(nil)
46+
require.NoError(t, err)
3147

3248
testCases := map[string]struct {
33-
req *coordapi.SetManifestRequest
34-
mSGetter *stubManifestSetGetter
35-
caGetter *stubCertChainGetter
36-
wantErr bool
49+
req *coordapi.SetManifestRequest
50+
mSGetter *stubManifestSetGetter
51+
caGetter *stubCertChainGetter
52+
workloadOwnerKey *ecdsa.PrivateKey
53+
wantErr bool
3754
}{
3855
"empty request": {
3956
req: &coordapi.SetManifestRequest{},
@@ -110,6 +127,84 @@ func TestManifestSet(t *testing.T) {
110127
caGetter: &stubCertChainGetter{},
111128
wantErr: true,
112129
},
130+
"workload owner key match": {
131+
req: &coordapi.SetManifestRequest{
132+
Manifest: newManifestBytes(func(m *manifest.Manifest) {
133+
m.Policies = map[manifest.HexString][]string{
134+
manifest.HexString("ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb"): {"a1", "a2"},
135+
manifest.HexString("3e23e8160039594a33894f6564e1b1348bbd7a0088d42c4acb73eeaed59c009d"): {"b1", "b2"},
136+
}
137+
}),
138+
Policies: [][]byte{
139+
[]byte("a"),
140+
[]byte("b"),
141+
},
142+
},
143+
mSGetter: &stubManifestSetGetter{
144+
getManifestResp: []*manifest.Manifest{manifestWithTrustedKey},
145+
},
146+
caGetter: &stubCertChainGetter{},
147+
workloadOwnerKey: trustedKey,
148+
},
149+
"workload owner key mismatch": {
150+
req: &coordapi.SetManifestRequest{
151+
Manifest: newManifestBytes(func(m *manifest.Manifest) {
152+
m.Policies = map[manifest.HexString][]string{
153+
manifest.HexString("ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb"): {"a1", "a2"},
154+
manifest.HexString("3e23e8160039594a33894f6564e1b1348bbd7a0088d42c4acb73eeaed59c009d"): {"b1", "b2"},
155+
}
156+
}),
157+
Policies: [][]byte{
158+
[]byte("a"),
159+
[]byte("b"),
160+
},
161+
},
162+
mSGetter: &stubManifestSetGetter{
163+
getManifestResp: []*manifest.Manifest{manifestWithTrustedKey},
164+
},
165+
caGetter: &stubCertChainGetter{},
166+
workloadOwnerKey: untrustedKey,
167+
wantErr: true,
168+
},
169+
"workload owner key missing": {
170+
req: &coordapi.SetManifestRequest{
171+
Manifest: newManifestBytes(func(m *manifest.Manifest) {
172+
m.Policies = map[manifest.HexString][]string{
173+
manifest.HexString("ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb"): {"a1", "a2"},
174+
manifest.HexString("3e23e8160039594a33894f6564e1b1348bbd7a0088d42c4acb73eeaed59c009d"): {"b1", "b2"},
175+
}
176+
}),
177+
Policies: [][]byte{
178+
[]byte("a"),
179+
[]byte("b"),
180+
},
181+
},
182+
mSGetter: &stubManifestSetGetter{
183+
getManifestResp: []*manifest.Manifest{manifestWithTrustedKey},
184+
},
185+
caGetter: &stubCertChainGetter{},
186+
wantErr: true,
187+
},
188+
"manifest not updatable": {
189+
req: &coordapi.SetManifestRequest{
190+
Manifest: newManifestBytes(func(m *manifest.Manifest) {
191+
m.Policies = map[manifest.HexString][]string{
192+
manifest.HexString("ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb"): {"a1", "a2"},
193+
manifest.HexString("3e23e8160039594a33894f6564e1b1348bbd7a0088d42c4acb73eeaed59c009d"): {"b1", "b2"},
194+
}
195+
}),
196+
Policies: [][]byte{
197+
[]byte("a"),
198+
[]byte("b"),
199+
},
200+
},
201+
mSGetter: &stubManifestSetGetter{
202+
getManifestResp: []*manifest.Manifest{manifestWithoutTrustedKey},
203+
},
204+
caGetter: &stubCertChainGetter{},
205+
workloadOwnerKey: trustedKey,
206+
wantErr: true,
207+
},
113208
}
114209

115210
for name, tc := range testCases {
@@ -124,7 +219,7 @@ func TestManifestSet(t *testing.T) {
124219
logger: slog.Default(),
125220
}
126221

127-
ctx := context.Background()
222+
ctx := rpcContext(tc.workloadOwnerKey)
128223
resp, err := coordinator.SetManifest(ctx, tc.req)
129224

130225
if tc.wantErr {
@@ -303,6 +398,36 @@ func (s *stubCertChainGetter) GetRootCACert() []byte { return []byte("root") }
303398
func (s *stubCertChainGetter) GetMeshCACert() []byte { return []byte("mesh") }
304399
func (s *stubCertChainGetter) GetIntermCert() []byte { return []byte("inter") }
305400

401+
func rpcContext(key *ecdsa.PrivateKey) context.Context {
402+
var peerCertificates []*x509.Certificate
403+
if key != nil {
404+
peerCertificates = []*x509.Certificate{{
405+
PublicKey: key.Public(),
406+
PublicKeyAlgorithm: x509.ECDSA,
407+
}}
408+
}
409+
return peer.NewContext(context.Background(), &peer.Peer{
410+
AuthInfo: credentials.TLSInfo{State: tls.ConnectionState{
411+
PeerCertificates: peerCertificates,
412+
}},
413+
})
414+
}
415+
416+
func manifestWithWorkloadOwnerKey(key *ecdsa.PrivateKey) (*manifest.Manifest, error) {
417+
m := manifest.Default()
418+
if key == nil {
419+
return &m, nil
420+
}
421+
pubKey, err := x509.MarshalPKIXPublicKey(&key.PublicKey)
422+
if err != nil {
423+
return nil, err
424+
}
425+
ownerKeyHash := sha256.Sum256(pubKey)
426+
ownerKeyHex := manifest.NewHexString(ownerKeyHash[:])
427+
m.WorkloadOwnerKeyDigests = []manifest.HexString{ownerKeyHex}
428+
return &m, nil
429+
}
430+
306431
func toPtr[T any](t T) *T {
307432
return &t
308433
}

0 commit comments

Comments
 (0)