From 3c390f7aa2211c124263f6d2af1623e852d14cf6 Mon Sep 17 00:00:00 2001 From: Marcin Czenko Date: Thu, 3 Jul 2025 17:26:14 +0200 Subject: [PATCH] encrypts blocks when uploading original content --- codex/encryption/codexencryption.nim | 5 ++++- codex/node.nim | 10 ++++++++-- codex/rest/api.nim | 7 ++++++- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/codex/encryption/codexencryption.nim b/codex/encryption/codexencryption.nim index 27e58fbd..7149214e 100644 --- a/codex/encryption/codexencryption.nim +++ b/codex/encryption/codexencryption.nim @@ -27,12 +27,15 @@ type CodexEncryption* = ref object masterKey: seq[byte] proc newCodexEncryption*(): CodexEncryption = - let masterKey = newSeqWith(32, Rng.instance.rand(uint8.high).byte) + let masterKey = newSeqWith(MasterKeySize, Rng.instance.rand(uint8.high).byte) CodexEncryption(masterKey: masterKey) proc newCodexEncryption*(masterKey: seq[byte]): CodexEncryption = CodexEncryption(masterKey: masterKey) +proc getKeyHexEncoded*(self: CodexEncryption): string = + self.masterKey.toHex() + proc deriveKeyForBlockIndex(self: CodexEncryption, blockIndex: uint32): seq[byte] = let blockIndexArray = toBytes(blockIndex, bigEndian) bearSslHash( diff --git a/codex/node.nim b/codex/node.nim index e010b085..9331e4b4 100644 --- a/codex/node.nim +++ b/codex/node.nim @@ -46,6 +46,7 @@ import ./errors import ./logutils import ./utils/asynciter import ./utils/trackedfutures +import ./encryption/codexencryption export logutils @@ -403,6 +404,7 @@ proc store*( filename: ?string = string.none, mimetype: ?string = string.none, blockSize = DefaultBlockSize, + encryption: CodexEncryption, ): Future[?!Cid] {.async.} = ## Save stream contents as dataset with given blockSize ## to nodes's BlockStore, and return Cid of its manifest @@ -416,15 +418,19 @@ proc store*( var cids: seq[Cid] + var blockIndex = 0.uint32 + try: while (let chunk = await chunker.getBytes(); chunk.len > 0): - without mhash =? MultiHash.digest($hcodec, chunk).mapFailure, err: + let encryptedChunk = encryption.encryptBlock(chunk, blockIndex) + blockIndex.inc() + without mhash =? MultiHash.digest($hcodec, encryptedChunk).mapFailure, err: return failure(err) without cid =? Cid.init(CIDv1, dataCodec, mhash).mapFailure, err: return failure(err) - without blk =? bt.Block.new(cid, chunk, verify = false): + without blk =? bt.Block.new(cid, encryptedChunk, verify = false): return failure("Unable to init block from chunk!") cids.add(cid) diff --git a/codex/rest/api.nim b/codex/rest/api.nim index e31a0f59..ed2678f6 100644 --- a/codex/rest/api.nim +++ b/codex/rest/api.nim @@ -39,6 +39,7 @@ import ../manifest import ../streams/asyncstreamwrapper import ../stores import ../utils/options +import ../encryption/codexencryption import ./coders import ./json @@ -230,6 +231,9 @@ proc initDataApi(node: CodexNodeRef, repoStore: RepoStore, router: var RestRoute if filename.isSome and not isValidFilename(filename.get()): return RestApiResponse.error(Http422, "The filename is not valid.") + # prepare encryption service + let encryption = newCodexEncryption() + # Here we could check if the extension matches the filename if needed let reader = bodyReader.get() @@ -240,6 +244,7 @@ proc initDataApi(node: CodexNodeRef, repoStore: RepoStore, router: var RestRoute AsyncStreamWrapper.new(reader = AsyncStreamReader(reader)), filename = filename, mimetype = mimetype, + encryption = encryption, ) ), error: error "Error uploading file", exc = error.msg @@ -247,7 +252,7 @@ proc initDataApi(node: CodexNodeRef, repoStore: RepoStore, router: var RestRoute codex_api_uploads.inc() trace "Uploaded file", cid - return RestApiResponse.response($cid) + return RestApiResponse.response($cid & ":" & encryption.getKeyHexEncoded()) except CancelledError: trace "Upload cancelled error" return RestApiResponse.error(Http500)