This repository has been archived by the owner on May 13, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 346
/
memory_key_store.go
96 lines (85 loc) · 2.53 KB
/
memory_key_store.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
package keys
import (
"context"
"crypto/rand"
"fmt"
"github.com/hyperledger/burrow/acm"
"github.com/hyperledger/burrow/crypto"
)
type MemoryKeyStore struct {
keyByAddress map[crypto.Address]crypto.PrivateKey
keyByName map[string]crypto.PrivateKey
}
func NewMemoryKeyStore(privateAccounts ...*acm.PrivateAccount) *MemoryKeyStore {
mks := &MemoryKeyStore{
keyByAddress: make(map[crypto.Address]crypto.PrivateKey),
keyByName: make(map[string]crypto.PrivateKey),
}
for _, pa := range privateAccounts {
mks.keyByAddress[pa.GetAddress()] = pa.PrivateKey()
}
return mks
}
func (mks *MemoryKeyStore) GetAddressForKeyName(keyName string) (crypto.Address, error) {
key, ok := mks.keyByName[keyName]
if !ok {
return crypto.Address{}, fmt.Errorf("could not find key with name %s", keyName)
}
return key.GetPublicKey().GetAddress(), nil
}
func (mks *MemoryKeyStore) GenerateKey(ctx context.Context, in *GenRequest) (*GenResponse, error) {
curveType, err := crypto.CurveTypeFromString(in.CurveType)
if err != nil {
return nil, fmt.Errorf("unknown curve type '%s'", in.CurveType)
}
key, err := crypto.GeneratePrivateKey(rand.Reader, curveType)
if err != nil {
return nil, fmt.Errorf("could not generate key: %w", err)
}
address := key.GetPublicKey().GetAddress()
mks.keyByAddress[address] = key
if in.KeyName != "" {
mks.keyByName[in.KeyName] = key
}
return &GenResponse{
Address: address.String(),
}, nil
}
func (mks *MemoryKeyStore) PublicKey(ctx context.Context, in *PubRequest) (*PubResponse, error) {
key, err := mks.getKey(in.Name, in.Address)
if err != nil {
return nil, err
}
return &PubResponse{
CurveType: key.CurveType.String(),
PublicKey: key.PublicKey,
}, nil
}
func (mks *MemoryKeyStore) Sign(ctx context.Context, in *SignRequest) (*SignResponse, error) {
key, err := mks.getKey(in.Name, in.Address)
if err != nil {
return nil, err
}
signature, err := key.Sign(in.Message)
if err != nil {
return nil, fmt.Errorf("could not sign message: %w", err)
}
return &SignResponse{
Signature: signature,
}, nil
}
// Get a stringly referenced key first by name, then by address
func (mks *MemoryKeyStore) getKey(name string, addressHex string) (*crypto.PrivateKey, error) {
key, ok := mks.keyByName[name]
if !ok {
address, err := crypto.AddressFromHexString(addressHex)
if err != nil {
return nil, fmt.Errorf("could not get PublicKey: %w", err)
}
key, ok = mks.keyByAddress[address]
if !ok {
return nil, fmt.Errorf("could not find key with address %v: %w", address, err)
}
}
return &key, nil
}