Skip to content

Commit 5054276

Browse files
authored
Merge branch 'develop' into jsimnz/fix/groupby-field-result-ignore
2 parents 73130eb + 75405a4 commit 5054276

4 files changed

Lines changed: 275 additions & 36 deletions

File tree

internal/kms/enc_store.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,20 +57,26 @@ func (s *ipldEncStorage) get(ctx context.Context, cidBytes []byte) (*coreblock.E
5757
return coreblock.GetEncryptionBlockFromNode(nd)
5858
}
5959

60-
func (s *ipldEncStorage) put(ctx context.Context, blockBytes []byte) ([]byte, error) {
60+
func (s *ipldEncStorage) putBlock(ctx context.Context, block coreblock.Encryption) ([]byte, error) {
6161
lsys := cidlink.DefaultLinkSystem()
6262
lsys.SetWriteStorage(blockstore.NewIPLDStore(s.encstore))
6363

64-
var encBlock coreblock.Encryption
65-
err := encBlock.Unmarshal(blockBytes)
64+
link, err := lsys.Store(linking.LinkContext{Ctx: ctx}, coreblock.GetLinkPrototype(), block.GenerateNode())
6665
if err != nil {
6766
return nil, err
6867
}
6968

70-
link, err := lsys.Store(linking.LinkContext{Ctx: ctx}, coreblock.GetLinkPrototype(), encBlock.GenerateNode())
69+
return []byte(link.String()), nil
70+
}
71+
72+
func (s *ipldEncStorage) computeBlockLink(ctx context.Context, block coreblock.Encryption) ([]byte, error) {
73+
lsys := cidlink.DefaultLinkSystem()
74+
lsys.SetWriteStorage(blockstore.NewIPLDStore(s.encstore))
75+
76+
link, err := lsys.ComputeLink(coreblock.GetLinkPrototype(), block.GenerateNode())
7177
if err != nil {
7278
return nil, err
7379
}
7480

75-
return []byte(link.String()), nil
81+
return []byte(link.Binary()), nil
7682
}

internal/kms/errors.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,38 @@ import (
1717
const (
1818
errUnknownKMSType string = "unknown KMS type"
1919
errNoPeerSuppliedEncryptionKey string = "no peer supplied the encryption key"
20+
21+
errPeerErrorKeyReply string = "encryption key peer reply carried error"
22+
errEncryptionKeyUnmarshal string = "unmarshal encryption key response"
23+
errReplyLinksAndBlocksMismatch string = "encryption key peer reply had mismatched links and blocks"
24+
errDecryptEncryptionKey string = "decrypting encryption key"
25+
errDecodingEncryptionKey string = "decoding encryption key"
26+
errEncryptionKeyCIDMismatch string = "key CID mismatch"
27+
errEncryptionKeyStore string = "store encryption key"
28+
errKeyCIDGeneration string = "key cid generation"
2029
)
2130

2231
var (
2332
ErrUnknownKMSType = errors.New(errUnknownKMSType)
2433
ErrNoPeerSuppliedEncryptionKey = errors.New(errNoPeerSuppliedEncryptionKey)
34+
35+
ErrPeerErrorKeyReply = errors.New(errPeerErrorKeyReply)
36+
ErrEncryptionKeyUnmarshal = errors.New(errEncryptionKeyUnmarshal)
37+
ErrReplyLinksAndBlocksMismatch = errors.New(errReplyLinksAndBlocksMismatch)
38+
ErrDecryptEncryptionKey = errors.New(errDecryptEncryptionKey)
39+
ErrDecodingEncryptionKey = errors.New(errDecodingEncryptionKey)
40+
ErrEncryptionKeyCIDMismatch = errors.New(errEncryptionKeyCIDMismatch)
41+
ErrEncryptionKeyStore = errors.New(errEncryptionKeyStore)
42+
ErrKeyCIDGeneration = errors.New(errKeyCIDGeneration)
2543
)
2644

2745
func NewErrUnknownKMSType(t ServiceType) error {
2846
return errors.New(errUnknownKMSType, errors.NewKV("Type", t))
2947
}
48+
49+
func NewErrReplyLinksAndBlocksMismatch(linkCount, blockCount int) error {
50+
return errors.New(errReplyLinksAndBlocksMismatch,
51+
errors.NewKV("LinkCount", linkCount),
52+
errors.NewKV("BlockCount", blockCount),
53+
)
54+
}

internal/kms/pubsub.go

Lines changed: 41 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import (
2222
cidlink "github.com/ipld/go-ipld-prime/linking/cid"
2323
grpcpeer "google.golang.org/grpc/peer"
2424

25-
"github.com/sourcenetwork/corelog"
2625
"github.com/sourcenetwork/immutable"
2726

2827
"github.com/sourcenetwork/defradb/acp/dac"
@@ -31,6 +30,7 @@ import (
3130
"github.com/sourcenetwork/defradb/client"
3231
"github.com/sourcenetwork/defradb/crypto"
3332
"github.com/sourcenetwork/defradb/errors"
33+
coreblock "github.com/sourcenetwork/defradb/internal/core/block"
3434
"github.com/sourcenetwork/defradb/internal/datastore"
3535
acpDB "github.com/sourcenetwork/defradb/internal/db/acp"
3636
"github.com/sourcenetwork/defradb/internal/encryption"
@@ -290,16 +290,14 @@ func (s *pubSubService) handleFetchEncryptionKeyResponses(
290290
respChan = nextRespChan
291291
continue
292292
}
293-
items, ok := s.tryHandleFetchEncryptionKeyResponse(resp, req, privateKey)
293+
items, ok, err := s.tryHandleFetchEncryptionKeyResponse(resp, req, privateKey, false /* skipVerify */)
294294
if !ok {
295+
if err != nil {
296+
log.ErrorContextE(s.ctx, "Failed handling of encryption key response", err)
297+
}
295298
continue
296299
}
297300

298-
// TODO: If multi-key requests become common, aggregate partial
299-
// responses from multiple peers until every requested link is found or
300-
// the timeout fires. A single valid response may contain fewer blocks
301-
// than the request asked for.
302-
// https://github.com/sourcenetwork/defradb/issues/4947
303301
result <- encryption.Result{Items: items}
304302
return
305303

@@ -364,37 +362,35 @@ func (s *pubSubService) tryHandleFetchEncryptionKeyResponse(
364362
resp client.PubsubResponse,
365363
req *fetchEncryptionKeyRequest,
366364
privateKey *ecdh.PrivateKey,
367-
) ([]encryption.Item, bool) {
365+
skipVerify bool,
366+
) ([]encryption.Item, bool, error) {
368367
if resp.Err != nil {
369-
log.ErrorContextE(s.ctx, "encryption key peer reply carried error", resp.Err)
370-
return nil, false
368+
return nil, false, errors.Join(ErrPeerErrorKeyReply, resp.Err)
371369
}
372370

373371
var keyResp fetchEncryptionKeyReply
374372
if err := cbor.Unmarshal(resp.Data, &keyResp); err != nil {
375-
log.ErrorContextE(s.ctx, "Failed to unmarshal encryption key response", err)
376-
return nil, false
373+
return nil, false, errors.Join(ErrEncryptionKeyUnmarshal, err)
377374
}
378375

379376
if len(keyResp.Blocks) == 0 {
380377
// Peer didn't have the key; keep waiting for the one that does.
381-
return nil, false
378+
return nil, false, nil
382379
}
383380
if len(keyResp.Links) != len(keyResp.Blocks) {
384-
log.ErrorContext(
385-
s.ctx,
386-
"encryption key peer reply had mismatched links and blocks",
387-
corelog.Int("LinkCount", len(keyResp.Links)),
388-
corelog.Int("BlockCount", len(keyResp.Blocks)),
389-
)
390-
return nil, false
381+
return nil, false, NewErrReplyLinksAndBlocksMismatch(len(keyResp.Links), len(keyResp.Blocks))
391382
}
392383

393384
senderID := keyResp.Sender
394385
if senderID == "" {
395386
senderID = resp.From
396387
}
397388

389+
reqSet := make(map[string]struct{}, len(req.Links))
390+
for _, l := range req.Links {
391+
reqSet[string(l)] = struct{}{}
392+
}
393+
398394
resultEncItems := make([]encryption.Item, 0, len(keyResp.Blocks))
399395
for i, block := range keyResp.Blocks {
400396
decryptedData, err := crypto.DecryptECIES(
@@ -405,25 +401,41 @@ func (s *pubSubService) tryHandleFetchEncryptionKeyResponse(
405401
crypto.WithPubKeyPrepended(false),
406402
)
407403
if err != nil {
408-
log.ErrorContextE(s.ctx, "Failed to decrypt encryption key", err)
409-
return nil, false
404+
return nil, false, errors.Join(ErrDecryptEncryptionKey, err)
405+
}
406+
407+
var encBlock coreblock.Encryption
408+
err = encBlock.Unmarshal(decryptedData)
409+
if err != nil {
410+
return nil, false, errors.Join(ErrDecodingEncryptionKey, err)
411+
}
412+
413+
if !skipVerify {
414+
link, err := s.encStore.computeBlockLink(s.ctx, encBlock)
415+
if err != nil {
416+
return nil, false, errors.Join(ErrKeyCIDGeneration, err)
417+
}
418+
419+
if !bytes.Equal(keyResp.Links[i], link) {
420+
return nil, false, ErrEncryptionKeyCIDMismatch
421+
}
422+
423+
if _, ok := reqSet[string(link)]; !ok {
424+
return nil, false, ErrEncryptionKeyCIDMismatch
425+
}
410426
}
411427

412-
if _, err := s.encStore.put(context.Background(), decryptedData); err != nil {
413-
log.ErrorContextE(s.ctx, "Failed to store encryption key", err)
414-
return nil, false
428+
if _, err := s.encStore.putBlock(context.Background(), encBlock); err != nil {
429+
return nil, false, errors.Join(ErrEncryptionKeyStore, err)
415430
}
416431

417-
// todo: verify incoming response order block/CIDs match the request
418-
// current implementation assumes trusted response ordering
419-
// https://github.com/sourcenetwork/defradb/issues/4948
420432
resultEncItems = append(resultEncItems, encryption.Item{
421433
Link: keyResp.Links[i],
422434
Block: decryptedData,
423435
})
424436
}
425437

426-
return resultEncItems, true
438+
return resultEncItems, true, nil
427439
}
428440

429441
// makeAssociatedData creates the associated data for the encryption key request

0 commit comments

Comments
 (0)