This repository has been archived by the owner on Jan 13, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnative.go
102 lines (83 loc) · 2.21 KB
/
native.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package secrets
import (
"errors"
"fmt"
)
var (
infraKeyNamespace = "infra-x" // k8s doesn't like names that start or end with _
infraRootKeyID = infraKeyNamespace + "/__root_key" // k8s requires one slash in the name
keyBlockSizeInBits = 256
keyBlockSizeInBytes = keyBlockSizeInBits / 8
)
var AlgorithmAESGCM = "aesgcm"
func NewNativeKeyProvider(storage SecretStorage) *NativeKeyProvider {
return &NativeKeyProvider{
SecretStorage: storage,
}
}
var _ SymmetricKeyProvider = &NativeKeyProvider{}
type NativeKeyProvider struct {
SecretStorage SecretStorage
}
func (n *NativeKeyProvider) GenerateDataKey(rootKeyID string) (*SymmetricKey, error) {
if rootKeyID == "" {
rootKeyID = infraRootKeyID
}
rootKey, err := n.SecretStorage.GetSecret(rootKeyID)
if err != nil {
if !errors.Is(err, ErrNotFound) {
return nil, fmt.Errorf("getting root key: %w", err)
}
}
if len(rootKey) == 0 {
// generate root key
rootKey, err = cryptoRandRead(keyBlockSizeInBytes)
if err != nil {
return nil, err
}
if err = n.SecretStorage.SetSecret(rootKeyID, rootKey); err != nil {
return nil, fmt.Errorf("saving root key: %w", err)
}
}
fullRootKey := &SymmetricKey{
unencrypted: rootKey,
Algorithm: AlgorithmAESGCM,
}
dataKey, err := cryptoRandRead(keyBlockSizeInBytes)
if err != nil {
return nil, err
}
encDataKey, err := Seal(fullRootKey, dataKey)
if err != nil {
return nil, fmt.Errorf("sealing: %w", err)
}
return &SymmetricKey{
unencrypted: dataKey,
Encrypted: encDataKey,
Algorithm: AlgorithmAESGCM,
RootKeyID: rootKeyID,
}, nil
}
func (n *NativeKeyProvider) DecryptDataKey(rootKeyID string, keyData []byte) (*SymmetricKey, error) {
if rootKeyID == "" {
rootKeyID = infraRootKeyID
}
rootKey, err := n.SecretStorage.GetSecret(rootKeyID)
if err != nil {
return nil, fmt.Errorf("getting root key: %w", err)
}
fullRootKey := &SymmetricKey{
unencrypted: rootKey,
Algorithm: AlgorithmAESGCM,
}
unsealed, err := Unseal(fullRootKey, keyData)
if err != nil {
return nil, fmt.Errorf("unsealing: %w", err)
}
return &SymmetricKey{
unencrypted: unsealed,
Encrypted: keyData,
Algorithm: AlgorithmAESGCM,
RootKeyID: rootKeyID,
}, nil
}