-
Notifications
You must be signed in to change notification settings - Fork 1.7k
/
dkgsign.go
164 lines (143 loc) · 3.75 KB
/
dkgsign.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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
package keystore
import (
"context"
"fmt"
"github.com/pkg/errors"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/dkgsignkey"
)
//go:generate mockery --quiet --name DKGSign --output mocks/ --case=underscore
// DKGSign provides signing keys for the DKG.
type DKGSign interface {
Get(id string) (dkgsignkey.Key, error)
GetAll() ([]dkgsignkey.Key, error)
Create(ctx context.Context) (dkgsignkey.Key, error)
Add(ctx context.Context, key dkgsignkey.Key) error
Delete(ctx context.Context, id string) (dkgsignkey.Key, error)
Import(ctx context.Context, keyJSON []byte, password string) (dkgsignkey.Key, error)
Export(id string, password string) ([]byte, error)
EnsureKey(ctx context.Context) error
}
type dkgSign struct {
*keyManager
}
func newDKGSignKeyStore(km *keyManager) *dkgSign {
return &dkgSign{
keyManager: km,
}
}
var _ DKGSign = &dkgSign{}
// Add implements DKGSign
func (d *dkgSign) Add(ctx context.Context, key dkgsignkey.Key) error {
d.lock.Lock()
defer d.lock.Unlock()
if d.isLocked() {
return ErrLocked
}
return d.safeAddKey(ctx, key)
}
// Create implements DKGSign
func (d *dkgSign) Create(ctx context.Context) (dkgsignkey.Key, error) {
d.lock.Lock()
defer d.lock.Unlock()
if d.isLocked() {
return dkgsignkey.Key{}, ErrLocked
}
key, err := dkgsignkey.New()
if err != nil {
return dkgsignkey.Key{}, errors.Wrap(err, "dkgsignkey New()")
}
return key, d.safeAddKey(ctx, key)
}
// Delete implements DKGSign
func (d *dkgSign) Delete(ctx context.Context, id string) (dkgsignkey.Key, error) {
d.lock.Lock()
defer d.lock.Unlock()
if d.isLocked() {
return dkgsignkey.Key{}, ErrLocked
}
key, err := d.getByID(id)
if err != nil {
return dkgsignkey.Key{}, err
}
err = d.safeRemoveKey(ctx, key)
return key, errors.Wrap(err, "safe remove key")
}
// EnsureKey implements DKGSign
func (d *dkgSign) EnsureKey(ctx context.Context) error {
d.lock.Lock()
defer d.lock.Unlock()
if d.isLocked() {
return ErrLocked
}
if len(d.keyRing.DKGSign) > 0 {
return nil
}
key, err := dkgsignkey.New()
if err != nil {
return errors.Wrap(err, "dkgsignkey New()")
}
d.logger.Infof("Created DKGSign key with ID %s", key.ID())
return d.safeAddKey(ctx, key)
}
// Export implements DKGSign
func (d *dkgSign) Export(id string, password string) ([]byte, error) {
d.lock.RLock()
defer d.lock.RUnlock()
if d.isLocked() {
return nil, ErrLocked
}
key, err := d.getByID(id)
if err != nil {
return nil, err
}
return key.ToEncryptedJSON(password, d.scryptParams)
}
// Get implements DKGSign
func (d *dkgSign) Get(id string) (keys dkgsignkey.Key, err error) {
d.lock.RLock()
defer d.lock.RUnlock()
if d.isLocked() {
return dkgsignkey.Key{}, ErrLocked
}
return d.getByID(id)
}
// GetAll implements DKGSign
func (d *dkgSign) GetAll() (keys []dkgsignkey.Key, err error) {
d.lock.RLock()
defer d.lock.RUnlock()
if d.isLocked() {
return nil, ErrLocked
}
for _, key := range d.keyRing.DKGSign {
keys = append(keys, key)
}
return keys, nil
}
// Import implements DKGSign
func (d *dkgSign) Import(ctx context.Context, keyJSON []byte, password string) (dkgsignkey.Key, error) {
d.lock.Lock()
defer d.lock.Unlock()
if d.isLocked() {
return dkgsignkey.Key{}, ErrLocked
}
key, err := dkgsignkey.FromEncryptedJSON(keyJSON, password)
if err != nil {
return dkgsignkey.Key{}, errors.Wrap(err, "from encrypted json")
}
_, err = d.getByID(key.ID())
if err == nil {
return dkgsignkey.Key{}, fmt.Errorf("key with ID %s already exists", key.ID())
}
return key, d.keyManager.safeAddKey(ctx, key)
}
// caller must hold lock
func (d *dkgSign) getByID(id string) (dkgsignkey.Key, error) {
key, found := d.keyRing.DKGSign[id]
if !found {
return dkgsignkey.Key{}, KeyNotFoundError{
ID: id,
KeyType: "DKGSign",
}
}
return key, nil
}