1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
// Author: cirakg & claude ai
// Summary: Tests for the encrypted barcode matrix cache: round trip, keys of locked entries, invalidation and tampering.
import Toybox.Lang;
import Toybox.Test;
(:test)
function codeCacheRoundTripsAndInvalidates(logger as Test.Logger) as Boolean {
var store = new MemoryBackend();
var vault = new Vault(store, new FakeTime());
var e = StorageFixtures.code("QR card");
e.type = Codes.QR;
var id = vault.add(e);
var qr = Qr.encode("cache me", 1, 0, -1) as Qr.MatrixCode;
var matrix = new Codes.Matrix(qr.size, qr.size, 4, qr.modules);
vault.saveCodeCache(id, matrix.toBytes());
var back = Codes.Matrix.fromBytes(vault.loadCodeCache(id) as ByteArray);
var same = back != null && back.width == qr.size && back.quiet == 4 && Bytes.equal(back.modules, qr.modules);
// The cache is sealed: tampering gives no cache rather than a wrong code.
var stored = store.raw("x." + id) as ByteArray;
stored[stored.size() - 1] = stored[stored.size() - 1] ^ 1;
var tampered = vault.loadCodeCache(id) == null;
vault.saveCodeCache(id, matrix.toBytes());
var opened = vault.open(id);
vault.update(opened);
opened.wipeSecrets();
var clearedByUpdate = store.getValue("x." + id) == null;
vault.saveCodeCache(id, matrix.toBytes());
vault.remove(id);
return same && tampered && clearedByUpdate && store.getValue("x." + id) == null;
}
// A locked entry's cache uses the master key: unreadable while locked.
(:test)
function codeCacheOfLockedEntriesNeedsTheSession(logger as Test.Logger) as Boolean {
var vault = new Vault(new MemoryBackend(), new FakeTime());
StorageFixtures.setPin(vault, StorageFixtures.PIN);
var e = StorageFixtures.code("Locked QR");
e.type = Codes.QR;
e.locked = true;
var id = vault.add(e);
vault.saveCodeCache(id, [3, 1, 4, 1, 0xE0]b);
vault.lock();
var code = 0;
try {
vault.loadCodeCache(id);
} catch (err instanceof VaultError) {
code = err.code;
}
StorageFixtures.unlock(vault, StorageFixtures.PIN);
var back = vault.loadCodeCache(id);
var pdf = new Codes.Matrix(3, 2, 2, [1, 0, 1, 0, 1, 1]b);
pdf.rowHeight = 3;
var round = Codes.Matrix.fromBytes(pdf.toBytes());
return code == VaultError.LOCKED && back != null && Bytes.equal(back, [3, 1, 4, 1, 0xE0]b)
&& Codes.Matrix.fromBytes([3, 1, 4, 1, 0xE0]b) != null && Codes.Matrix.fromBytes([3, 1, 4]b) == null
&& round != null && round.rowHeight == 3 && Bytes.equal(round.modules, [1, 0, 1, 0, 1, 1]b);
}
|