@@ -2,6 +2,12 @@ package main
2
2
3
3
import (
4
4
"context"
5
+ "crypto/ecdsa"
6
+ "crypto/elliptic"
7
+ "crypto/rand"
8
+ "crypto/sha256"
9
+ "crypto/tls"
10
+ "crypto/x509"
5
11
"encoding/json"
6
12
"log/slog"
7
13
"sync"
@@ -13,6 +19,8 @@ import (
13
19
"github.com/edgelesssys/nunki/internal/memstore"
14
20
"github.com/stretchr/testify/assert"
15
21
"github.com/stretchr/testify/require"
22
+ "google.golang.org/grpc/credentials"
23
+ "google.golang.org/grpc/peer"
16
24
)
17
25
18
26
func TestManifestSet (t * testing.T ) {
@@ -28,12 +36,21 @@ func TestManifestSet(t *testing.T) {
28
36
require .NoError (t , err )
29
37
return b
30
38
}
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 )
31
47
32
48
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
37
54
}{
38
55
"empty request" : {
39
56
req : & coordapi.SetManifestRequest {},
@@ -110,6 +127,84 @@ func TestManifestSet(t *testing.T) {
110
127
caGetter : & stubCertChainGetter {},
111
128
wantErr : true ,
112
129
},
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
+ },
113
208
}
114
209
115
210
for name , tc := range testCases {
@@ -124,7 +219,7 @@ func TestManifestSet(t *testing.T) {
124
219
logger : slog .Default (),
125
220
}
126
221
127
- ctx := context . Background ( )
222
+ ctx := rpcContext ( tc . workloadOwnerKey )
128
223
resp , err := coordinator .SetManifest (ctx , tc .req )
129
224
130
225
if tc .wantErr {
@@ -303,6 +398,36 @@ func (s *stubCertChainGetter) GetRootCACert() []byte { return []byte("root") }
303
398
func (s * stubCertChainGetter ) GetMeshCACert () []byte { return []byte ("mesh" ) }
304
399
func (s * stubCertChainGetter ) GetIntermCert () []byte { return []byte ("inter" ) }
305
400
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
+
306
431
func toPtr [T any ](t T ) * T {
307
432
return & t
308
433
}
0 commit comments