UNPKG

pooja-docucomb-tink-crypto

Version:

A multi-language, cross-platform library that provides cryptographic APIs that are secure, easy to use correctly, and hard(er) to misuse.

203 lines (175 loc) 7.97 kB
/** * @license * Copyright 2020 Google LLC * SPDX-License-Identifier: Apache-2.0 */ import * as PrimitiveSet from '../internal/primitive_set'; import {PbKeysetKey, PbKeyStatusType, PbOutputPrefixType} from '../internal/proto'; import * as Bytes from '../subtle/bytes'; import * as Random from '../subtle/random'; import {PublicKeySign} from './internal/public_key_sign'; import {PublicKeyVerify} from './internal/public_key_verify'; import {PublicKeySignWrapper} from './public_key_sign_wrapper'; import {PublicKeyVerifyWrapper} from './public_key_verify_wrapper'; describe('public key verify wrapper test', function() { it('verify, with empty signature', async function() { const primitiveSets = createDummyPrimitiveSets(); const primitiveSet = primitiveSets['publicPrimitiveSet']; const publicKeyVerify = new PublicKeyVerifyWrapper().wrap(primitiveSet); expect( await publicKeyVerify.verify(new Uint8Array(0), Random.randBytes(10))) .toBe(false); }); it('verify, should work', async function() { const primitiveSets = createDummyPrimitiveSets(); const data = Random.randBytes(10); // As keys are just dummy keys which do not contain key data, the same key // is used for both sign and verify. const key = createDummyKeysetKey( /** keyId = */ 0xFFFFFFFF, PbOutputPrefixType.TINK, /** enabled = */ true); const signatureSuffix = Random.randBytes(10); // Get the signature const privatePrimitiveSet = primitiveSets['privatePrimitiveSet']; const signPrimitive = new DummyPublicKeySign(signatureSuffix); const entry = privatePrimitiveSet.addPrimitive(signPrimitive, key); // Has to be set to primary as then it is used in signing. privatePrimitiveSet.setPrimary(entry); const publicKeySign = new PublicKeySignWrapper().wrap(privatePrimitiveSet); const signature = await publicKeySign.sign(data); // Create a primitive set containing the primitives which can be used for // verification. Add also few more primitives with the same key as the // primitive set should verify the signature whenever there is at least // one primitive which does not fail to verify the signature. const publicPrimitiveSet = primitiveSets['publicPrimitiveSet']; const verifyPrimitive = new DummyPublicKeyVerify(signatureSuffix); publicPrimitiveSet.addPrimitive( new DummyPublicKeyVerify(Random.randBytes(5)), key); publicPrimitiveSet.addPrimitive(verifyPrimitive, key); publicPrimitiveSet.addPrimitive( new DummyPublicKeyVerify(Random.randBytes(5)), key); // Verify the signature. const publicKeyVerify = new PublicKeyVerifyWrapper().wrap(publicPrimitiveSet); const isValid = await publicKeyVerify.verify(signature, data); expect(isValid).toBe(true); }); it('verify, raw primitive', async function() { const primitiveSets = createDummyPrimitiveSets(); const data = Random.randBytes(10); const key = createDummyKeysetKey( /** keyId = */ 0xFFFFFFFF, PbOutputPrefixType.RAW, /** enabled = */ true); const signatureSuffix = Random.randBytes(10); // Get the signature. const signPrimitive = new DummyPublicKeySign(signatureSuffix); const signature = await signPrimitive.sign(data); // Verify the signature. const primitiveSet = primitiveSets['publicPrimitiveSet']; const verifyPrimitive = new DummyPublicKeyVerify(signatureSuffix); primitiveSet.addPrimitive(verifyPrimitive, key); const publicKeyVerify = new PublicKeyVerifyWrapper().wrap(primitiveSet); const isValid = await publicKeyVerify.verify(signature, data); expect(isValid).toBe(true); }); it('verify, with disabled primitive', async function() { const primitiveSets = createDummyPrimitiveSets(); const data = Random.randBytes(10); const key = createDummyKeysetKey( /** keyId = */ 0xFFFFFFFF, PbOutputPrefixType.RAW, /** enabled = */ false); const signatureSuffix = new Uint8Array([0, 0, 0, 0xFF]); const signPrimitive = new DummyPublicKeySign(signatureSuffix); const signature = await signPrimitive.sign(data); const primitiveSet = primitiveSets['publicPrimitiveSet']; const verifyPrimitive = new DummyPublicKeyVerify(signatureSuffix); primitiveSet.addPrimitive(verifyPrimitive, key); const publicKeyVerify = new PublicKeyVerifyWrapper().wrap(primitiveSet); const isValid = await publicKeyVerify.verify(signature, data); expect(isValid).toBe(false); }); }); /** 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); return key; } /** * Creates a primitive sets for PublicKeySign and PublicKeyVerify with * 'numberOfPrimitives' primitives. The keys corresponding to the primitives * have ids from the set [1, ..., numberOfPrimitives] and the primitive * corresponding to key with id 'numberOfPrimitives' is set to be primary * whenever opt_withPrimary is set to true (where true is the default value). */ function createDummyPrimitiveSets(opt_withPrimary: boolean = true): { publicPrimitiveSet: PrimitiveSet.PrimitiveSet<DummyPublicKeyVerify>, privatePrimitiveSet: PrimitiveSet.PrimitiveSet<DummyPublicKeySign>, } { const numberOfPrimitives = 5; const publicPrimitiveSet = new PrimitiveSet.PrimitiveSet<DummyPublicKeyVerify>(DummyPublicKeyVerify); const privatePrimitiveSet = new PrimitiveSet.PrimitiveSet<DummyPublicKeySign>(DummyPublicKeySign); for (let i = 1; i < numberOfPrimitives; i++) { let outputPrefix: PbOutputPrefixType; switch (i % 3) { case 0: outputPrefix = PbOutputPrefixType.TINK; break; case 1: outputPrefix = PbOutputPrefixType.LEGACY; break; default: outputPrefix = PbOutputPrefixType.RAW; } const key = createDummyKeysetKey(i, outputPrefix, /* enabled = */ i % 4 < 2); const signatureSuffix = new Uint8Array([0, 0, i]); const publicKeySign = new DummyPublicKeySign(signatureSuffix); privatePrimitiveSet.addPrimitive(publicKeySign, key); const publicKeyVerify = new DummyPublicKeyVerify(signatureSuffix); publicPrimitiveSet.addPrimitive(publicKeyVerify, key); } const key = createDummyKeysetKey( numberOfPrimitives, PbOutputPrefixType.TINK, /* enabled = */ true); const signatureSuffix = new Uint8Array([0, 0, numberOfPrimitives]); const publicKeySign = new DummyPublicKeySign(signatureSuffix); const signEntry = privatePrimitiveSet.addPrimitive(publicKeySign, key); const publicKeyVerify = new DummyPublicKeyVerify(signatureSuffix); const verifyEntry = publicPrimitiveSet.addPrimitive(publicKeyVerify, key); if (opt_withPrimary) { publicPrimitiveSet.setPrimary(verifyEntry); privatePrimitiveSet.setPrimary(signEntry); } return { 'publicPrimitiveSet': publicPrimitiveSet, 'privatePrimitiveSet': privatePrimitiveSet }; } /** @final */ class DummyPublicKeySign extends PublicKeySign { constructor(private readonly signatureSuffix: Uint8Array) { super(); } async sign(data: Uint8Array) { return Bytes.concat(data, this.signatureSuffix); } } /** @final */ class DummyPublicKeyVerify extends PublicKeyVerify { constructor(private readonly signatureSuffix: Uint8Array) { super(); } async verify(signature: Uint8Array, data: Uint8Array) { return Bytes.isEqual(Bytes.concat(data, this.signatureSuffix), signature); } }