blob: 3d0af979878f4b170b4f7dfcacd8e071f3002537 [file] [log] [blame]
/**
* @license
* Copyright 2020 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import * as Random from '../subtle/random';
import {assertMessageEquals} from '../testing/internal/test_utils';
import {BinaryKeysetReader} from './binary_keyset_reader';
import {PbKeyData, PbKeyset, PbKeysetKey, PbKeyStatusType, PbOutputPrefixType} from './proto';
describe('binary keyset reader test', function() {
it('read, invalid serialized keyset proto', function() {
for (let i = 0; i < 2; i++) {
// The Uint8Array is not a serialized keyset.
const reader = BinaryKeysetReader.withUint8Array(new Uint8Array(i));
try {
reader.read();
fail('An exception should be thrown.');
} catch (e: any) {
expect(e.toString()).toBe(ExceptionText.invalidSerialization());
}
}
});
it('read', function() {
// Create keyset proto and serialize it.
const keyset = new PbKeyset();
// The for cycle starts from 1 as setting any proto value to 0 sets it to
// null and after serialization and deserialization null is changed to
// undefined and the assertion at the end fails (unless you compare the
// keyset and newly created keyset value by value).
for (let i = 1; i < 20; i++) {
let outputPrefix;
switch (i % 3) {
case 0:
outputPrefix = PbOutputPrefixType.TINK;
break;
case 1:
outputPrefix = PbOutputPrefixType.RAW;
break;
default:
outputPrefix = PbOutputPrefixType.LEGACY;
}
keyset.addKey(createDummyKeysetKey(
/* keyId = */ i, outputPrefix, /* enabled = */ i % 4 < 3));
}
keyset.setPrimaryKeyId(1);
const serializedKeyset = keyset.serializeBinary();
// Read the keyset proto serialization.
const reader = BinaryKeysetReader.withUint8Array(serializedKeyset);
const keysetFromReader = reader.read();
// Test that it returns the same object as was created.
assertMessageEquals(keysetFromReader, keyset);
});
it('read encrypted, not implemented yet', function() {
const reader = BinaryKeysetReader.withUint8Array(new Uint8Array(10));
try {
reader.readEncrypted();
fail('An exception should be thrown.');
} catch (e: any) {
expect(e.toString()).toBe(ExceptionText.notImplemented());
}
});
});
////////////////////////////////////////////////////////////////////////////////
// helper functions and classes for tests
////////////////////////////////////////////////////////////////////////////////
/**
* Class which holds texts for each type of exception.
* @final
*/
class ExceptionText {
static notImplemented(): string {
return 'SecurityException: Not implemented yet.';
}
static nullKeyset(): string {
return 'SecurityException: Serialized keyset has to be non-null.';
}
static invalidSerialization(): string {
return 'SecurityException: Could not parse the given serialized proto as ' +
'a keyset proto.';
}
}
/** Function for creating keys for testing purposes. */
function createDummyKeysetKey(
keyId: number, outputPrefix: PbOutputPrefixType,
enabled: boolean): PbKeysetKey {
const key = new PbKeysetKey();
if (enabled) {
key.setStatus(PbKeyStatusType.ENABLED);
} else {
key.setStatus(PbKeyStatusType.DISABLED);
}
key.setOutputPrefixType(outputPrefix);
key.setKeyId(keyId);
// Set some key data.
key.setKeyData(new PbKeyData());
key.getKeyData()?.setTypeUrl('SOME_KEY_TYPE_URL_' + keyId.toString());
key.getKeyData()?.setKeyMaterialType(PbKeyData.KeyMaterialType.SYMMETRIC);
key.getKeyData()?.setValue(Random.randBytes(10));
return key;
}