The changes explained below were made in order to remove the encryption in the upload process and decryption in the download process, as well as the cryptographic headers as all are unnecessary for the Allas UI interface. Any other changes made are also detailed.
swift-browser-ui is the base repository and all the changes made for the Allas-UI are as follows:
-
The folder
$REPO/swift_browser_ui_frontend/wasm/src
that included all thec
files and the header files was removed. The folder$REPO/swift_browser_ui_frontend/wasm/test
that included all the tests for thosec
functions was removed as well. -
Makefile
Modification: This is the modifiedmakefile
all: upload download upload: build/upworker.js build/upworker.wasm download: build/downworker.js build/downworker.wasm build/upworker.js: emcc -O3 \ -s WASM=1 \ -s TOTAL_MEMORY=268435456 \ -s ALLOW_MEMORY_GROWTH=1 \ -s ASSERTIONS=1 \ -s LLD_REPORT_UNDEFINED \ -s FORCE_FILESYSTEM=1 \ -o $@ \ --post-js build/upworker-post.js \ --pre-js js/crypt-pre.js build/downworker.js: emcc -O3 \ -s WASM=1 \ -s TOTAL_MEMORY=268435456 \ -s ALLOW_MEMORY_GROWTH=1 \ -s ASSERTIONS=1 \ -s LLD_REPORT_UNDEFINED \ -s FORCE_FILESYSTEM=1 \ -o $@ \ --post-js build/downworker-post.js \ --pre-js js/crypt-pre.js clean: rm -rf build
This file has been modified to remove the encryption in the upload process. Changes described as follows:
-
Changes in
createUploadSession()
Function: The function calls to thec
functionsread_in_recv_keys_path()
,wrap_chunk_content()
andwrap_chunk_len()
were removed. -
Removed
createUploadSessionFile()
andencryptChunk()
Functions:createUploadSessionFile()
was responsible for creating a file header using encryption keys and session information.encryptChunk()
was responsible for encrypting a single chunk of an upload. Both are not longer needed. -
Changes in
StreamSlicer
Class:- Removed the call to
encryptChunk()
in thegetChunk()
function. - Return
return new Uint8Array(enBuffer);
in thegetChunk()
function directly return the chunk without encryption. - Removed the call to
free_crypt4gh_session_key()
in thefinishFile()
function.
- Removed the call to
-
Changes in
openWebSocket()
Function: Function calls towaitAsm()
andlibinit()
removed. -
Changes in
addFiles
Function:- Removed the
.c4gh
extension from thepath
variable. - Removed the call to
createUploadSessionFile()
function. - Removed the
data
property from themsg
object in the loop, indicating that the file header data is no longer sent as part of the message. Instead of"add_header"
command, the command"start_upload"
is sent to initiate the upload process.let msg = { command: "start_upload", container: container, object: path, name: uploads[container].projectName, total: totalBytes, };
- Removed the
In the handle_upload_ws()
function the command "add_header"
was chnaged to "start_upload"
to work with the change mentioned in the addFiles()
function.
# Open msgpack and handle message
try:
msg_unpacked: typing.Dict[str, typing.Any] = msgpack.unpackb(msg.data)
if msg_unpacked["command"] == "start_upload":
await upload_session.handle_begin_upload(msg_unpacked)
if msg_unpacked["command"] == "add_chunk":
await upload_session.handle_upload_chunk(msg_unpacked)
if msg_unpacked["command"] == "add_chunks":
await upload_session.handle_upload_chunks(msg_unpacked)
if msg_unpacked["command"] == "cancel":
await upload_session.handle_close()
if msg_unpacked["command"] == "finish":
await upload_session.handle_finish_upload(msg_unpacked)
except ValueError:
LOGGER.error("Received an empty message.")
LOGGER.debug(msg.data)
except msgpack.exceptions.ExtraData:
LOGGER.error("Extra data in message.")
LOGGER.debug(msg.data)
except msgpack.exceptions.FormatError:
LOGGER.error("Incorrectly formatted message.")
LOGGER.error(msg.data)
-
In the
handle_begin_upload()
function the last lineawait self.uploads[container][path].add_header(bytes(msg["data"]))
was changed to
await self.uploads[container][path].init_upload()
-
The
init_upload()
function is basically the oldadd_header()
function without the encryption header part.async def init_upload(self) -> None: """Initialize the upload.""" if ( not await self.a_create_container() and self.socket is not None and not self.socket.closed ): await self.socket.send_bytes( msgpack.packb( { "command": "abort", "container": self.container, "object": self.path, "reason": "Could not create or access the container.", } ) ) self.failed = True self.tasks = [ asyncio.create_task(self.upload_segment(i)) for i in range(0, self.total_segments) ] await self.start_upload()
This file has been modified to remove the decryption in the download process. Changes described as follows:
-
let libinitDone = true;
was changed to true and the calls towaitAsm()
andlibinit()
(at the end of the file) were removed. -
Changes in
createDownloadSession()
Function:
- The function calls to the
c
functionscreate_keypair()
andget_keypair_public_key()
were removed. keypair
andpubkey
properties removed from thedownloadsp[id]
object.
- Changes in
createDownloadSessionFile()
Function:
- The function call to
get_session_key_from_header()
was removed. key
property indownloads[id].files[path]
was set to 0 since no decryption will be used.- removed header decryption related code.
return true
always return true since decryption is not needed.// Add a file to the download session function createDownloadSessionFile(id, container, path, header, url, size) { if (checkPollutingName(path)) return; let headerPath = `header_${container}_` + Math.random().toString(36) + Math.random().toString(36); FS.writeFile( headerPath, header, ); downloads[id].files[path] = { key: 0, // Set key to 0 since no decryption will be used url: url, size: getFileSize(size, 0), realsize: getFileSize(size, 0), }; return true; // Always return true since decryption is not needed }
-
Removed
decryptChunk()
Function:decryptChunk()
was responsible for decrypting a single chunk of a download. Not longer needed. -
Changes in
FileSlicer
Class:
- In the
concatFile()
function the concatination of the headers decryption functions were removed. - The
sliceFile()
function was changed and modified.async sliceFile() { // Get the first chunk from stream await this.getStart(); // Slice the file and write content to output while (!this.done) { if (aborted) return; await this.getSlice(); if (this.output instanceof WritableStream) { // Write the contents directly in the file stream if // downloading to File System if (this.bytes > 0) { await this.output.write(new Uint8Array(this.enChunkBuf.subarray(0, this.bytes))); } } else { // Otherwise queue to the streamController since we're using a // ServiceWorker for downloading while(this.output.desiredSize <= 0) { await timeout(10); } if (this.bytes > 0) { this.output.enqueue(new Uint8Array(this.enChunkBuf.subarray(0, this.bytes))); } } } // Round up to a multiple of 512, because tar await this.padFile(); return true; }
-
Changes in
finishDownloadSession()
Function: The call tofree_keypair()
was removed. -
Changes in
beginDownloadInSession()
Function:
- Changed
let path = file.replace(".c4gh", "");
tolet path = file;
. - Changed the
slicer
instance logicconst slicer = new FileSlicer( fileStream, id, file); let res; // Always use concatFile since there's no decryption key res = await slicer.concatFile().catch(() => { return false; }); if (!res) { if (!aborted) startAbort(!inServiceWorker, "error"); await abortDownload(id, fileStream); return; }
- Changes in
addEventListener()
Function:
- In every call to
createDownloadSession()
function whenpostMessage()
function is called,pubkey: downloads[e.data.id].pubkey
was removed from every call.
While pressing the Download button. In the browser's console log this error was received:
In order to solve that error I have made these changes in $REPO/swift_browser_ui/common/vault_client.py
in the put_whitelist_key()
function
async def put_whitelist_key(
self, project: str, flavor: str, public_key: bytes
) -> None:
"""Update the project's whitelisted key.
:param project: Project ID
:param flavor: Public key flavor: one of crypt4gh or ed25519
:param public_key: Public key bytes
"""
await self._request(
"POST",
f"c4ghtransit/whitelist/{project}/{self.service}/{self._key_name}",
json_data={
"flavor": flavor,
"pubkey": 0, # to resolve missing pubkey error
},
)
As can be seen in the picture below the "Advanced excryption options" are not longer needed and were removed.
-
Changes in
$REPO/swift_browser_ui_frontend/src/common/lang.js
: Underencrypt:
both in the English and the Finnish languagesmultipleReceivers:
,pubkey:
,pubkeyLabel:
,pubkeyError:
,noRecipients:
,addkey:
andadvancedOptions:
were all removed. -
Changes in
$REPO/swift_browser_ui_frontend/src/components/UploadModal.vue
: Underid="accordion"
this code was removed:<c-accordion-item :heading="$t('message.encrypt.advancedOptions')" :value="$t('message.encrypt.advancedOptions')" > <c-container> <c-flex> <h3 class="title is-6"> {{ $t('message.encrypt.multipleReceivers') }} </h3> <c-text-field v-model="addRecvkey" v-csc-control :label="$t('message.encrypt.pubkey')" type="text" rows="2" :valid="validatePubkey(addRecvkey) || addRecvkey.length === 0" :validation="$t('message.encrypt.pubkeyError')" /> <c-button :disabled="!validatePubkey(addRecvkey)" @click="appendPublicKey" @keyup.enter="appendPublicKey" > {{ $t("message.encrypt.addkey") }} </c-button> Footer options needs to be in CamelCase, because csc-ui wont recognise it otherwise. <c-data-table class="publickey-table" :data.prop="recvHashedKeys" :headers.prop="publickeyHeaders" :no-data-text="$t('message.encrypt.noRecipients')" :pagination.prop="keyPagination" :footerOptions.prop="{hideDetails: true}" @click="checkPage($event,true)" /> </c-flex> </c-container> </c-accordion-item>
Changes were made in these files:
-
$REPO/swift_browser_ui_frontend/src/common/bucketOverride.js
File Created: All the necessary wording that will override thelang.js
file when the toggle is pressed. -
Changes in
$REPO/swift_browser_ui_frontend/src/components/BrowserMainNavbar.vue
: Root icons are buckets, if the bucket is full there will be folder and file icons. -
Changes in
$REPO/swift_browser_ui_frontend/src/components/ContainerTable.vue
: Root icons are buckets, if the bucket is full there will be folder and file icons. -
Changes in
$REPO/swift_browser_ui_frontend/src/components/ObjectTable.vue
: Root icons are buckets, if the bucket is full there will be folder and file icons. -
Changes in
$REPO/swift_browser_ui_frontend/src/components/CObjectTable.vue
: Root icons are buckets, if the bucket is full there will be folder and file icons.
-
csc-ui local npm package added
-
package.json
change: using modified npm package - https://www.npmjs.com/package/allas-ui?activeTab=readme -
dockerfiles/Dockerfile-build-crypt
Change: copies of the localcsc-ui
added