Skip to content

Commit a7b298c

Browse files
add tek
1 parent f1fc9f4 commit a7b298c

2 files changed

Lines changed: 153 additions & 13 deletions

File tree

internal/model/key.go

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ const (
1212
KeyRoleKek KeyRole = "kek"
1313
// KeyRoleDek represents a data encryption key, used to encrypt data directly.
1414
KeyRoleDek KeyRole = "dek"
15+
// KeyRoleTek represents a traffic encryption key.
16+
KeyRoleTek KeyRole = "tek"
1517
)
1618

1719
// KeyAlgorithmAES256 represents the AES-256 encryption algorithm.
@@ -43,17 +45,18 @@ var (
4345
ErrKeyHierarchyLastKeyNotDek = errors.New("last key must have role 'dek'")
4446
// ErrKeySpecKindEmpty is returned when a KeySpec has an empty kind.
4547
ErrKeySpecKindEmpty = errors.New("key kind cannot be empty")
46-
// ErrKeySpecRoleInvalid is returned when a KeySpec has a role other than 'root', 'kek', or 'dek'.
47-
ErrKeySpecRoleInvalid = errors.New("invalid role: must be 'root', 'kek', or 'dek'")
48+
// ErrKeySpecRoleInvalid is returned when a KeySpec has a role other than 'root', 'kek', 'tek', or 'dek'.
49+
ErrKeySpecRoleInvalid = errors.New("invalid role: must be 'root', 'kek', 'tek', or 'dek'")
4850
// ErrKeySpecAlgorithmInvalid is returned when a KeySpec has an algorithm other than 'AES256'.
4951
ErrKeySpecAlgorithmInvalid = errors.New("invalid algorithm: must be 'AES256'")
50-
// ErrKeyHierarchyIntermediateKeyNotKek is returned when an intermediate key in a KeyHierarchy does not have role 'kek'.
51-
ErrKeyHierarchyIntermediateKeyNotKek = errors.New("intermediate keys must have role 'kek'")
52+
// ErrKeyHierarchyInvalidIntermediateKey is returned when an intermediate key in a KeyHierarchy does not have role 'kek' or 'tek'.
53+
ErrKeyHierarchyInvalidIntermediateKey = errors.New("intermediate keys must have role 'kek' or 'tek'")
5254

5355
validKeyRoles = map[KeyRole]struct{}{
5456
KeyRoleRoot: {},
5557
KeyRoleKek: {},
5658
KeyRoleDek: {},
59+
KeyRoleTek: {},
5760
}
5861
)
5962

@@ -85,8 +88,9 @@ type (
8588

8689
// Validate checks the KeyHierarchy for structural correctness. It returns an error if the name is
8790
// empty, the keys list is empty or nil, the first key does not have role 'root', the last key in a
88-
// multi-key hierarchy does not have role 'dek', intermediate keys must have role 'kek', there are
89-
// multiple keys with role 'root', there are duplicate key kinds, or any KeySpec fails its own validation.
91+
// multi-key hierarchy does not have role 'dek', intermediate keys must have role 'kek' or 'tek',
92+
// there are multiple keys with role 'root', there are duplicate key kinds, or any KeySpec fails its
93+
// own validation.
9094
func (h *KeyHierarchy) Validate() error {
9195
if h.Name == "" {
9296
return ErrKeyHierarchyNameEmpty
@@ -117,7 +121,7 @@ func (h *KeyHierarchy) Validate() error {
117121
case KeyRoleRoot:
118122
return ErrKeyHierarchyDuplicateRoot
119123
case KeyRoleDek:
120-
return ErrKeyHierarchyIntermediateKeyNotKek
124+
return ErrKeyHierarchyInvalidIntermediateKey
121125
}
122126
}
123127

@@ -158,7 +162,7 @@ func (h *KeyHierarchy) Usage(kind KeyKind) (KeyUsage, bool) {
158162
} else {
159163
usage = KeyUsageWrap | KeyUsageUnwrap
160164
}
161-
case KeyRoleKek:
165+
case KeyRoleKek, KeyRoleTek:
162166
usage = KeyUsageWrap | KeyUsageUnwrap
163167
case KeyRoleDek:
164168
usage = KeyUsageEncrypt | KeyUsageDecrypt
@@ -180,7 +184,7 @@ func (ku KeyUsage) Has(usage KeyUsage) bool {
180184
}
181185

182186
// Validate checks the KeySpec for correctness. It returns an error if the kind is empty,
183-
// the role is not one of 'root', 'kek', or 'dek', or the algorithm is not 'AES256'.
187+
// the role is not one of 'root', 'kek', 'tek', or 'dek', or the algorithm is not 'AES256'.
184188
func (k KeySpec) Validate() error {
185189
if k.Kind == "" {
186190
return ErrKeySpecKindEmpty

internal/model/key_test.go

Lines changed: 140 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func TestKeyHierarchy(t *testing.T) {
4646
expErr: model.ErrKeyHierarchyKeysListEmpty,
4747
},
4848
{
49-
name: "should return error if first key does not have role 'root'",
49+
name: "should return error if first key is 'kek'",
5050
input: &model.KeyHierarchy{
5151
Name: "production-hierarchy",
5252
Keys: []model.KeySpec{
@@ -59,6 +59,34 @@ func TestKeyHierarchy(t *testing.T) {
5959
},
6060
expErr: model.ErrKeyHierarchyFirstKeyNotRoot,
6161
},
62+
{
63+
name: "should return error if first key is 'dek'",
64+
input: &model.KeyHierarchy{
65+
Name: "production-hierarchy",
66+
Keys: []model.KeySpec{
67+
{
68+
Kind: "K0",
69+
Role: model.KeyRoleDek,
70+
Algorithm: model.KeyAlgorithmAES256,
71+
},
72+
},
73+
},
74+
expErr: model.ErrKeyHierarchyFirstKeyNotRoot,
75+
},
76+
{
77+
name: "should return error if first key is 'tek'",
78+
input: &model.KeyHierarchy{
79+
Name: "production-hierarchy",
80+
Keys: []model.KeySpec{
81+
{
82+
Kind: "K0",
83+
Role: model.KeyRoleTek,
84+
Algorithm: model.KeyAlgorithmAES256,
85+
},
86+
},
87+
},
88+
expErr: model.ErrKeyHierarchyFirstKeyNotRoot,
89+
},
6290
{
6391
name: "should return error if there are duplicate key kinds",
6492
input: &model.KeyHierarchy{
@@ -177,10 +205,10 @@ func TestKeyHierarchy(t *testing.T) {
177205
},
178206
},
179207
},
180-
expErr: model.ErrKeyHierarchyIntermediateKeyNotKek,
208+
expErr: model.ErrKeyHierarchyInvalidIntermediateKey,
181209
},
182210
{
183-
name: "should return error if there is a non-kek key in the middle of the hierarchy",
211+
name: "should return error if there is a non-kek(dek) key in the middle of the hierarchy",
184212
input: &model.KeyHierarchy{
185213
Name: "production-hierarchy",
186214
Keys: []model.KeySpec{
@@ -206,7 +234,46 @@ func TestKeyHierarchy(t *testing.T) {
206234
},
207235
},
208236
},
209-
expErr: model.ErrKeyHierarchyIntermediateKeyNotKek,
237+
expErr: model.ErrKeyHierarchyInvalidIntermediateKey,
238+
},
239+
240+
{
241+
name: "should return error if the hierarchy has root and kek keys",
242+
input: &model.KeyHierarchy{
243+
Name: "production-hierarchy",
244+
Keys: []model.KeySpec{
245+
{
246+
Kind: "K0",
247+
Role: model.KeyRoleRoot,
248+
Algorithm: model.KeyAlgorithmAES256,
249+
},
250+
{
251+
Kind: "K1",
252+
Role: model.KeyRoleKek,
253+
Algorithm: model.KeyAlgorithmAES256,
254+
},
255+
},
256+
},
257+
expErr: model.ErrKeyHierarchyLastKeyNotDek,
258+
},
259+
{
260+
name: "should return error if the hierarchy has root and tek keys",
261+
input: &model.KeyHierarchy{
262+
Name: "production-hierarchy",
263+
Keys: []model.KeySpec{
264+
{
265+
Kind: "K0",
266+
Role: model.KeyRoleRoot,
267+
Algorithm: model.KeyAlgorithmAES256,
268+
},
269+
{
270+
Kind: "K1",
271+
Role: model.KeyRoleTek,
272+
Algorithm: model.KeyAlgorithmAES256,
273+
},
274+
},
275+
},
276+
expErr: model.ErrKeyHierarchyLastKeyNotDek,
210277
},
211278
{
212279
name: "should return nil if the hierarchy has root and dek keys",
@@ -251,6 +318,40 @@ func TestKeyHierarchy(t *testing.T) {
251318
},
252319
expErr: nil,
253320
},
321+
{
322+
name: "should return nil if the hierarchy has root, kek, tek and dek keys",
323+
input: &model.KeyHierarchy{
324+
Name: "production-hierarchy",
325+
Keys: []model.KeySpec{
326+
{
327+
Kind: "K0",
328+
Role: model.KeyRoleRoot,
329+
Algorithm: model.KeyAlgorithmAES256,
330+
},
331+
{
332+
Kind: "K1",
333+
Role: model.KeyRoleKek,
334+
Algorithm: model.KeyAlgorithmAES256,
335+
},
336+
{
337+
Kind: "K2",
338+
Role: model.KeyRoleTek,
339+
Algorithm: model.KeyAlgorithmAES256,
340+
},
341+
{
342+
Kind: "K3",
343+
Role: model.KeyRoleKek,
344+
Algorithm: model.KeyAlgorithmAES256,
345+
},
346+
{
347+
Kind: "K4",
348+
Role: model.KeyRoleDek,
349+
Algorithm: model.KeyAlgorithmAES256,
350+
},
351+
},
352+
},
353+
expErr: nil,
354+
},
254355
{
255356
name: "should return nil if the hierarchy has only a root key",
256357
input: &model.KeyHierarchy{
@@ -426,6 +527,33 @@ func TestKeyUsage(t *testing.T) {
426527
expIsWrap: true,
427528
expIsUnwrap: true,
428529
},
530+
{
531+
name: "should return wrap and unwrap if the key kind belongs to a 'tek' key in a multi-key hierarchy",
532+
input: &model.KeyHierarchy{
533+
Name: "production-hierarchy",
534+
Keys: []model.KeySpec{
535+
{
536+
Kind: "K0",
537+
Role: model.KeyRoleRoot,
538+
Algorithm: model.KeyAlgorithmAES256,
539+
},
540+
{
541+
Kind: "K1",
542+
Role: model.KeyRoleTek,
543+
Algorithm: model.KeyAlgorithmAES256,
544+
},
545+
{
546+
Kind: "K2",
547+
Role: model.KeyRoleDek,
548+
Algorithm: model.KeyAlgorithmAES256,
549+
},
550+
},
551+
},
552+
keyToCheck: "K1",
553+
expIsFound: true,
554+
expIsWrap: true,
555+
expIsUnwrap: true,
556+
},
429557
{
430558
name: "should return encrypt and decrypt if the key kind belongs to a 'dek' key in a multi-key hierarchy",
431559
input: &model.KeyHierarchy{
@@ -649,6 +777,14 @@ func TestKeySpec(t *testing.T) {
649777
Algorithm: model.KeyAlgorithmAES256,
650778
},
651779
},
780+
{
781+
name: "should return nil if role is 'tek'",
782+
input: model.KeySpec{
783+
Kind: "K0",
784+
Role: model.KeyRoleTek,
785+
Algorithm: model.KeyAlgorithmAES256,
786+
},
787+
},
652788
}
653789

654790
for _, tt := range tts {

0 commit comments

Comments
 (0)