Skip to content

Commit

Permalink
Fixed: caching keys didn't work since chrome.local doesn't support
Browse files Browse the repository at this point in the history
binary data; instead use IndexedDB for storing them.
  • Loading branch information
philipp-classen committed Jan 27, 2023
1 parent ffd41c7 commit 4866da9
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 89 deletions.
6 changes: 3 additions & 3 deletions packages/anonymous-communication/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ import { InvalidMessageError } from './errors.js';
import { TrustedClock } from './trusted-clock.js';

export default class AnonymousCommunication {
constructor({ config, storage }) {
constructor({ config, connectDatabase }) {
this.cacheDatabase = connectDatabase('cache');
this.serverPublicKeyAccessor = new ServerPublicKeyAccessor({
config,
storage,
storageKey: 'wtm.anonymous-communication.server-ecdh-keys',
database: this.cacheDatabase,
});
this.config = config;
if (!config.CHANNEL) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ function isYYYYMMDD(date) {
}

export default class ServerPublicKeyAccessor {
constructor({ config, storage, storageKey }) {
constructor({ config, database }) {
// Note: do not go through proxies when fetching keys; otherwise,
// the proxy could replace it, and the key exchange would be insecure.
this.collectorUrl = config.COLLECTOR_DIRECT_URL;
this.storage = storage;
this.storageKey = storageKey;
this.database = database;
this.storageKey = 'server-ecdh-keys';
this._knownKeys = new Map();
}

Expand Down Expand Up @@ -51,7 +51,7 @@ export default class ServerPublicKeyAccessor {
// try to load from disk
let knownKeys;
try {
const keysFromDisk = await this.storage
const keysFromDisk = await this.database
.get(this.storageKey)
.catch(() => null);
if (keysFromDisk && keysFromDisk.some(([date]) => date === today)) {
Expand Down Expand Up @@ -94,8 +94,8 @@ export default class ServerPublicKeyAccessor {

// update disk cache
try {
const entry = [...knownKeys].map((date, { key }) => [date, key]);
await this.storage.set(this.storageKey, entry);
const entry = [...knownKeys].map(([date, { key }]) => [date, key]);
await this.database.set(this.storageKey, entry);
} catch (e) {
logger.warn('Failed to cache server keys to disk.', e);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* WhoTracks.Me
* https://whotracks.me/
*
* Copyright 2017-present Ghostery GmbH. All rights reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0
*/

/**
* Implements the IndexedDBKeyValueStore interface.
*/
export default class InMemoryDatabase {
constructor() {
this.db = new Map();
}

async open() {}

async close() {}

async get(key) {
return this.db.get(key);
}

async set(key, value) {
this.db.set(key, value);
}

async remove(key) {
return this.db.delete(key);
}

async clear() {
this.db.clear();
}

async keys() {
return [...this.db.keys()];
}
}
72 changes: 0 additions & 72 deletions packages/anonymous-communication/test/helpers/memory-map.js

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { expect } from 'chai';
import sinon from 'sinon';
import { Buffer } from 'buffer';

import MemoryPersistentMap from './helpers/memory-map.js';
import InMemoryDatabase from './helpers/in-memory-database.js';

import ServerPublicKeyAccessor from '../src/server-public-key-accessor.js';
import logger from '../src/logger.js';
Expand Down Expand Up @@ -52,28 +52,25 @@ const MOCKS = {
};

describe('#ServerPublicKeyAccessor', function () {
let storage;
let database;
let uut;
const someStorageKey = 'test-storage-key';

const assumeKeysOnDisk = async (storedKeys) => {
const entry = storedKeys.map(({ date, key }) => [
date,
Buffer.from(key, 'base64'),
]);
await storage.set(someStorageKey, entry);
await database.set(uut.storageKey, entry);
};

beforeEach(async function () {
// in-memory implementation of storage
storage = new MemoryPersistentMap();
database = new InMemoryDatabase();
const config = {
COLLECTOR_DIRECT_URL: '192.0.2.0', // TEST-NET-1 address
};
uut = new ServerPublicKeyAccessor({
config,
storage,
storageKey: someStorageKey,
database,
});
MOCKS.reset();
sinon.stub(window, 'fetch').callsFake(MOCKS.fetch);
Expand Down Expand Up @@ -117,4 +114,22 @@ describe('#ServerPublicKeyAccessor', function () {
});
expect(MOCKS.fetch._numCalls).to.equal(0);
});

it('should fetch newer keys if the cached ones are outdated', async function () {
const oneYearAgo = (MOCKS.today - '00010000').toString();
await assumeKeysOnDisk([{ date: oneYearAgo, key: MOCKS.fakeKey }]);
expect(await uut.getKey(MOCKS.today)).to.deep.equal({
date: MOCKS.today,
publicKey: MOCKS.fakeImportedKey,
});
expect(MOCKS.fetch._numCalls).to.equal(1);

// also check that the new keys were properly cached
MOCKS.fetch._numCalls = 0;
expect(await uut.getKey(MOCKS.today)).to.deep.equal({
date: MOCKS.today,
publicKey: MOCKS.fakeImportedKey,
});
expect(MOCKS.fetch._numCalls).to.equal(0);
});
});

0 comments on commit 4866da9

Please sign in to comment.