-
Notifications
You must be signed in to change notification settings - Fork 1.7k
/
exportutils.go
86 lines (71 loc) · 2.32 KB
/
exportutils.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
package keys
import (
"encoding/json"
keystore "github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/pkg/errors"
"github.com/smartcontractkit/chainlink/v2/core/utils"
)
type Encrypted interface {
GetCrypto() keystore.CryptoJSON
}
// EncryptedKeyExport represents a chain specific encrypted key
type EncryptedKeyExport struct {
KeyType string `json:"keyType"`
PublicKey string `json:"publicKey"`
Crypto keystore.CryptoJSON `json:"crypto"`
}
func (x EncryptedKeyExport) GetCrypto() keystore.CryptoJSON {
return x.Crypto
}
// FromEncryptedJSON gets key [K] from keyJSON [E] and password
func FromEncryptedJSON[E Encrypted, K any](
identifier string,
keyJSON []byte,
password string,
passwordFunc func(string) string,
privKeyToKey func(export E, rawPrivKey []byte) (K, error),
) (K, error) {
// unmarshal byte data to [E] Encrypted key export
var export E
if err := json.Unmarshal(keyJSON, &export); err != nil {
return *new(K), err
}
// decrypt data using prefixed password
privKey, err := keystore.DecryptDataV3(export.GetCrypto(), passwordFunc(password))
if err != nil {
return *new(K), errors.Wrapf(err, "failed to decrypt %s key", identifier)
}
// convert unmarshalled data and decrypted key to [K] key format
key, err := privKeyToKey(export, privKey)
if err != nil {
return *new(K), errors.Wrapf(err, "failed to convert %s key to key bundle", identifier)
}
return key, nil
}
// ToEncryptedJSON returns encrypted JSON [E] representing key [K]
func ToEncryptedJSON[E Encrypted, K any](
identifier string,
raw []byte,
key K,
password string,
scryptParams utils.ScryptParams,
passwordFunc func(string) string,
buildExport func(id string, key K, cryptoJSON keystore.CryptoJSON) (E, error),
) (export []byte, err error) {
// encrypt data using prefixed password
cryptoJSON, err := keystore.EncryptDataV3(
raw,
[]byte(passwordFunc(password)),
scryptParams.N,
scryptParams.P,
)
if err != nil {
return nil, errors.Wrapf(err, "could not encrypt %s key", identifier)
}
// build [E] export struct using encrypted key, identifier, and original key [K]
encryptedKeyExport, err := buildExport(identifier, key, cryptoJSON)
if err != nil {
return nil, errors.Wrapf(err, "could not build encrypted export for %s key", identifier)
}
return json.Marshal(encryptedKeyExport)
}