Source code
Revision control
Copy as Markdown
Other Tools
Test Info:
-
CI results over the last 22 days
- Manifest: xpcom/ioutils/tests/chrome.toml
<!-- Any copyright is dedicated to the Public Domain.
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test the IOUtils encryption transform</title>
<script src="file_ioutils_test_fixtures.js"></script>
<script>
"use strict";
const { Assert } = ChromeUtils.importESModule(
);
// The header IOUtils prepends to encrypted files: 'mozEnc0\0'.
const ENC_MAGIC = [0x6d, 0x6f, 0x7a, 0x45, 0x6e, 0x63, 0x30, 0x00];
function tmp(name) {
return PathUtils.join(PathUtils.tempDir, name);
}
add_task(async function test_encrypt_decrypt_roundtrip() {
const path = tmp("test_ioutils_encrypt_roundtrip.tmp");
const contents = "The quick brown fox jumps over the lazy dog. \u{1f98a}";
await IOUtils.writeUTF8(path, contents, { encrypt: "test" });
const readBack = await IOUtils.readUTF8(path, { decrypt: "test" });
Assert.equal(readBack, contents, "encrypt then decrypt round-trips");
await cleanup(path);
});
add_task(async function test_encrypted_file_is_ciphertext() {
const path = tmp("test_ioutils_encrypt_ciphertext.tmp");
const contents = "secret session data";
await IOUtils.writeUTF8(path, contents, { encrypt: "test" });
const raw = await IOUtils.read(path, { maxBytes: 8 });
Assert.deepEqual(
Array.from(raw.slice(0, ENC_MAGIC.length)),
ENC_MAGIC,
"encrypted file begins with the encryption magic header"
);
await cleanup(path);
});
add_task(async function test_compress_and_encrypt_compose() {
const path = tmp("test_ioutils_encrypt_compose.tmp");
// Use repetitive content so compression is meaningful.
const contents = "all work and no play\n".repeat(500);
await IOUtils.writeUTF8(path, contents, { compress: true, encrypt: "test" });
const readBack = await IOUtils.readUTF8(path, {
decompress: true,
decrypt: "test",
});
Assert.equal(readBack, contents, "compress+encrypt round-trips");
await cleanup(path);
});
add_task(async function test_decrypt_passthrough_for_plaintext() {
const path = tmp("test_ioutils_encrypt_passthrough.tmp");
const contents = "I was never encrypted";
// Written without encryption (legacy/plaintext on disk).
await IOUtils.writeUTF8(path, contents);
// Reading with decrypt:true must transparently return the plaintext.
const readBack = await IOUtils.readUTF8(path, { decrypt: "test" });
Assert.equal(readBack, contents, "decrypt of a plaintext file passes through");
await cleanup(path);
});
add_task(async function test_decrypt_passthrough_compressed_plaintext() {
const path = tmp("test_ioutils_encrypt_passthrough_lz4.tmp");
const contents = "lz4 but not encrypted ".repeat(50);
// Written compressed but not encrypted (e.g. an existing .jsonlz4 file).
await IOUtils.writeUTF8(path, contents, { compress: true });
// decrypt:true passes through (no magic), decompress:true then runs.
const readBack = await IOUtils.readUTF8(path, {
decompress: true,
decrypt: "test",
});
Assert.equal(readBack, contents, "decrypt passes through to decompress");
await cleanup(path);
});
add_task(async function test_tampered_ciphertext_rejects() {
const path = tmp("test_ioutils_encrypt_tamper.tmp");
const contents = "authenticated payload";
await IOUtils.writeUTF8(path, contents, { encrypt: "test" });
// Flip a byte well past the magic header (inside the AEAD-protected
// region) and write it back.
const raw = await IOUtils.read(path);
const tampered = new Uint8Array(raw);
tampered[tampered.length - 2] ^= 0x01;
await IOUtils.write(path, tampered);
await Assert.rejects(
IOUtils.readUTF8(path, { decrypt: "test" }),
/Could not read `.*'/,
"tampered ciphertext fails to decrypt"
);
await cleanup(path);
});
add_task(async function test_encrypt_json_roundtrip() {
const path = tmp("test_ioutils_encrypt_json.tmp");
await IOUtils.writeJSON(path, obj, { compress: true, encrypt: "test" });
const readBack = await IOUtils.readJSON(path, {
decompress: true,
decrypt: "test",
});
Assert.deepEqual(readBack, obj, "writeJSON/readJSON with encryption round-trips");
await cleanup(path);
});
</script>
</head>
<body>
</body>
</html>