Phase 2 green: implement crypto primitives
Each stub is replaced with a thin wrapper over libsodium-wrappers-sumo:
* init() awaits sodium.ready
* toBase64 / toBase64URL / fromBase64 use sodium's base64 variants;
fromBase64 tries all four (standard, standard-no-pad, URL-safe,
URL-safe-no-pad) so callers don't have to know which form Ente
delivered
* deriveKEK is sodium.crypto_pwhash with ALG_ARGON2ID13 and 32-byte
output
* deriveLoginSubkey is sodium.crypto_kdf_derive_from_key(32, 1,
'loginctx', kek).slice(0, 16) per the upstream Ente clients
* decryptBox is sodium.crypto_secretbox_open_easy
* decryptSealed is sodium.crypto_box_seal_open
* initStreamPull / pullStreamChunk wrap the secretstream pull API,
throwing on authentication failure rather than returning false
All 32 tests pass; make check is green.
This commit is contained in:
@@ -1,13 +1,31 @@
|
||||
// Stub: see the README "Development workflow" section for TDD policy.
|
||||
import sodium from "libsodium-wrappers-sumo";
|
||||
|
||||
export const fromBase64 = (_s: string): Uint8Array => {
|
||||
throw new Error("crypto.fromBase64 not implemented");
|
||||
};
|
||||
export const toBase64 = (b: Uint8Array): string =>
|
||||
sodium.to_base64(b, sodium.base64_variants.ORIGINAL);
|
||||
|
||||
export const toBase64 = (_b: Uint8Array): string => {
|
||||
throw new Error("crypto.toBase64 not implemented");
|
||||
};
|
||||
export const toBase64URL = (b: Uint8Array): string =>
|
||||
sodium.to_base64(b, sodium.base64_variants.URLSAFE_NO_PADDING);
|
||||
|
||||
export const toBase64URL = (_b: Uint8Array): string => {
|
||||
throw new Error("crypto.toBase64URL not implemented");
|
||||
// Ente uses standard base64 for most fields, URL-safe (with padding stripped)
|
||||
// for the auth token. Rather than make callers specify, fromBase64 accepts
|
||||
// any of the four variants libsodium understands and returns the bytes.
|
||||
const VARIANTS = [
|
||||
sodium.base64_variants.ORIGINAL,
|
||||
sodium.base64_variants.ORIGINAL_NO_PADDING,
|
||||
sodium.base64_variants.URLSAFE,
|
||||
sodium.base64_variants.URLSAFE_NO_PADDING,
|
||||
] as const;
|
||||
|
||||
export const fromBase64 = (s: string): Uint8Array => {
|
||||
let lastError: unknown;
|
||||
for (const variant of VARIANTS) {
|
||||
try {
|
||||
return sodium.from_base64(s, variant);
|
||||
} catch (err) {
|
||||
lastError = err;
|
||||
}
|
||||
}
|
||||
throw lastError instanceof Error
|
||||
? lastError
|
||||
: new Error("invalid base64 input");
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user