Skip to content

Commit 1c82519

Browse files
Implement encryptor in keystore library (#1587)
* Wip encryptor * Add a test and more documentation for encryption * Switch to protobuf to trim the ciphertext size * More test coverage * add field to capability response metadata to convey the total number … (#1574) * add field to capability response metadata to convey the total number of don participants * update property for better clarity and add to helpers * Comply with go naming conventions * Improve encrypt test coverage * Add a test harness, fix a few bugs * Added a readme warning * Comments and re-orient API around anonymous encryption * Rename * PR comments + port a critical fix * Fix test * Use errors.New --------- Co-authored-by: Awbrey Hughlett <athughlett@gmail.com>
1 parent 033e9be commit 1c82519

11 files changed

Lines changed: 841 additions & 35 deletions

keystore/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
WARNING: In development do not use in production.
2+
13
# Keystore
24
Design principles:
35
- Use structs for typed extensibility of the interfaces. Easy

keystore/admin.go

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package keystore
22

33
import (
44
"context"
5+
"crypto/ecdh"
56
"crypto/ecdsa"
67
"crypto/ed25519"
78
"crypto/rand"
@@ -128,6 +129,8 @@ func ValidKeyName(name string) error {
128129
return nil
129130
}
130131

132+
// CreateKeys creates multiple keys in a single operation. The response preserves the order of the request.
133+
// It's atomic - either all keys are created or none are created.
131134
func (ks *keystore) CreateKeys(ctx context.Context, req CreateKeysRequest) (CreateKeysResponse, error) {
132135
ks.mu.Lock()
133136
defer ks.mu.Unlock()
@@ -152,16 +155,19 @@ func (ks *keystore) CreateKeys(ctx context.Context, req CreateKeysRequest) (Crea
152155
return CreateKeysResponse{}, fmt.Errorf("failed to get public key from private key: %w", err)
153156
}
154157
ksCopy[keyReq.KeyName] = newKey(keyReq.KeyType, internal.NewRaw(privateKey), publicKey, time.Now(), []byte{})
155-
case EcdsaSecp256k1:
158+
case ECDSA_S256:
156159
privateKey, err := ecdsa.GenerateKey(crypto.S256(), rand.Reader)
157160
if err != nil {
158-
return CreateKeysResponse{}, fmt.Errorf("failed to generate EcdsaSecp256k1 key: %w", err)
161+
return CreateKeysResponse{}, fmt.Errorf("failed to generate ECDSA_S256 key: %w", err)
159162
}
160-
publicKey, err := publicKeyFromPrivateKey(internal.NewRaw(privateKey.D.Bytes()), keyReq.KeyType)
163+
// Must copy the private key into 32 byte slice because leading zeros are stripped.
164+
privateKeyBytes := make([]byte, 32)
165+
copy(privateKeyBytes, privateKey.D.Bytes())
166+
publicKey, err := publicKeyFromPrivateKey(internal.NewRaw(privateKeyBytes), keyReq.KeyType)
161167
if err != nil {
162168
return CreateKeysResponse{}, fmt.Errorf("failed to get public key from private key: %w", err)
163169
}
164-
ksCopy[keyReq.KeyName] = newKey(keyReq.KeyType, internal.NewRaw(privateKey.D.Bytes()), publicKey, time.Now(), []byte{})
170+
ksCopy[keyReq.KeyName] = newKey(keyReq.KeyType, internal.NewRaw(privateKeyBytes), publicKey, time.Now(), []byte{})
165171
case X25519:
166172
privateKey := [curve25519.ScalarSize]byte{}
167173
_, err := rand.Read(privateKey[:])
@@ -173,6 +179,16 @@ func (ks *keystore) CreateKeys(ctx context.Context, req CreateKeysRequest) (Crea
173179
return CreateKeysResponse{}, fmt.Errorf("failed to get public key from private key: %w", err)
174180
}
175181
ksCopy[keyReq.KeyName] = newKey(keyReq.KeyType, internal.NewRaw(privateKey[:]), publicKey, time.Now(), []byte{})
182+
case ECDH_P256:
183+
privateKey, err := ecdh.P256().GenerateKey(rand.Reader)
184+
if err != nil {
185+
return CreateKeysResponse{}, fmt.Errorf("failed to generate ECDH_P256 key: %w", err)
186+
}
187+
publicKey, err := publicKeyFromPrivateKey(internal.NewRaw(privateKey.Bytes()), keyReq.KeyType)
188+
if err != nil {
189+
return CreateKeysResponse{}, fmt.Errorf("failed to get public key from private key: %w", err)
190+
}
191+
ksCopy[keyReq.KeyName] = newKey(keyReq.KeyType, internal.NewRaw(privateKey.Bytes()), publicKey, time.Now(), []byte{})
176192
default:
177193
return CreateKeysResponse{}, fmt.Errorf("%w: %s", ErrUnsupportedKeyType, keyReq.KeyType)
178194
}

keystore/admin_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import (
1414
)
1515

1616
func TestKeystore_CreateDeleteReadKeys(t *testing.T) {
17-
ctx := context.Background()
17+
ctx := t.Context()
1818
type key struct {
1919
name string
2020
metadata []byte

0 commit comments

Comments
 (0)