blob: b444808cba855dfd968bf84dcc8cd427ffb68950 [file] [log] [blame]
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
goog.module('tink.signature.SignatureConfigTest');
goog.setTestOnly('tink.signature.SignatureConfigTest');
const EcdsaPrivateKeyManager = goog.require('tink.signature.EcdsaPrivateKeyManager');
const EcdsaPublicKeyManager = goog.require('tink.signature.EcdsaPublicKeyManager');
const KeysetHandle = goog.require('tink.KeysetHandle');
const PbKeyData = goog.require('proto.google.crypto.tink.KeyData');
const PbKeyStatusType = goog.require('proto.google.crypto.tink.KeyStatusType');
const PbKeyTemplate = goog.require('proto.google.crypto.tink.KeyTemplate');
const PbKeyset = goog.require('proto.google.crypto.tink.Keyset');
const PbOutputPrefixType = goog.require('proto.google.crypto.tink.OutputPrefixType');
const PublicKeySign = goog.require('tink.PublicKeySign');
const PublicKeyVerify = goog.require('tink.PublicKeyVerify');
const Random = goog.require('tink.subtle.Random');
const Registry = goog.require('tink.Registry');
const SignatureConfig = goog.require('tink.signature.SignatureConfig');
const SignatureKeyTemplates = goog.require('tink.signature.SignatureKeyTemplates');
const TestCase = goog.require('goog.testing.TestCase');
const testSuite = goog.require('goog.testing.testSuite');
const userAgent = goog.require('goog.userAgent');
testSuite({
shouldRunTests() {
return !userAgent.EDGE; // b/120286783
},
setUp() {
// Use a generous promise timeout for running continuously.
TestCase.getActiveTestCase().promiseTimeout = 1000 * 1000; // 1000s
},
tearDown() {
Registry.reset();
// Reset the promise timeout to default value.
TestCase.getActiveTestCase().promiseTimeout = 1000; // 1s
},
testConstants() {
assertEquals(VERIFY_PRIMITIVE_NAME, SignatureConfig.VERIFY_PRIMITIVE_NAME);
assertEquals(SIGN_PRIMITIVE_NAME, SignatureConfig.SIGN_PRIMITIVE_NAME);
assertEquals(ECDSA_PUBLIC_KEY_TYPE, SignatureConfig.ECDSA_PUBLIC_KEY_TYPE);
assertEquals(
ECDSA_PRIVATE_KEY_TYPE, SignatureConfig.ECDSA_PRIVATE_KEY_TYPE);
},
testRegister_correctKeyManagersWereRegistered() {
SignatureConfig.register();
// Test that the corresponding key managers were registered.
const publicKeyManager = Registry.getKeyManager(ECDSA_PUBLIC_KEY_TYPE);
assertTrue(publicKeyManager instanceof EcdsaPublicKeyManager);
const privateKeyManager = Registry.getKeyManager(ECDSA_PRIVATE_KEY_TYPE);
assertTrue(privateKeyManager instanceof EcdsaPrivateKeyManager);
},
// Check that everything was registered correctly and thus new keys may be
// generated using the predefined key templates and then they may be used for
// encryption and decryption.
async testRegister_predefinedTemplatesShouldWork() {
SignatureConfig.register();
let templates = [
SignatureKeyTemplates.ecdsaP256(),
SignatureKeyTemplates.ecdsaP256IeeeEncoding(),
SignatureKeyTemplates.ecdsaP384(),
SignatureKeyTemplates.ecdsaP384IeeeEncoding(),
SignatureKeyTemplates.ecdsaP521(),
SignatureKeyTemplates.ecdsaP521IeeeEncoding(),
];
// The following function adds all templates in uncompiled tests, thus if
// a new template is added without updating SignatureConfig correctly then
// at least the uncompiled tests should fail. But the templates are included
// also above as the following function does not add anything to the list in
// compiled code.
templates =
templates.concat(getListOfTemplatesFromSignatureKeyTemplatesClass());
for (let template of templates) {
const privateKeyData = await Registry.newKeyData(template);
const privateKeysetHandle = createKeysetHandleFromKeyData(privateKeyData);
const publicKeySign =
await privateKeysetHandle.getPrimitive(PublicKeySign);
const publicKeyData = Registry.getPublicKeyData(
privateKeyData.getTypeUrl(), privateKeyData.getValue_asU8());
const publicKeysetHandle = createKeysetHandleFromKeyData(publicKeyData);
const publicKeyVerify =
await publicKeysetHandle.getPrimitive(PublicKeyVerify);
const data = Random.randBytes(10);
const signature = await publicKeySign.sign(data);
const isValid = await publicKeyVerify.verify(signature, data);
assertTrue(isValid);
}
},
});
// Constants used in tests.
const VERIFY_PRIMITIVE_NAME = 'PublicKeyVerify';
const SIGN_PRIMITIVE_NAME = 'PublicKeySign';
const ECDSA_PUBLIC_KEY_TYPE =
'type.googleapis.com/google.crypto.tink.EcdsaPublicKey';
const ECDSA_PRIVATE_KEY_TYPE =
'type.googleapis.com/google.crypto.tink.EcdsaPrivateKey';
/**
* Creates a keyset containing only the key given by keyData and returns it
* wrapped in a KeysetHandle.
*
* @param {!PbKeyData} keyData
* @return {!KeysetHandle}
*/
const createKeysetHandleFromKeyData = function(keyData) {
const keyId = 1;
const key = new PbKeyset.Key()
.setKeyData(keyData)
.setStatus(PbKeyStatusType.ENABLED)
.setKeyId(keyId)
.setOutputPrefixType(PbOutputPrefixType.TINK);
const keyset = new PbKeyset();
keyset.addKey(key);
keyset.setPrimaryKeyId(keyId);
return new KeysetHandle(keyset);
};
/**
* Returns all templates from SignatureKeyTemplates class.
*
* WARNING: This function works only in uncompiled code. Once the code is
* compiled it returns only empty set due to optimizations which are run.
* Namely
* - after compilation the methods are no longer methods of
* SignatureKeyTemplates class, and
* - every method which is not referenced in this file or in the code used by
* these tests are considered as dead code and removed.
*
* @return {!Array<!PbKeyTemplate>}
*/
const getListOfTemplatesFromSignatureKeyTemplatesClass = function() {
let templates = [];
for (let propertyName of Object.getOwnPropertyNames(SignatureKeyTemplates)) {
// Only public methods (i.e. not ending with '_') without arguments (i.e.
// function.length == 0) generate key templates.
const property = SignatureKeyTemplates[propertyName];
if (typeof property === 'function' && property.length === 0 &&
propertyName[propertyName.length - 1] != '_') {
const template = property();
if (template instanceof PbKeyTemplate) {
templates = templates.concat([template]);
}
}
}
return templates;
};