blob: 81dfa003ec824804a234105d3cd13ddcfe130c1a [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.hybrid.HybridConfigTest');
goog.setTestOnly('tink.hybrid.HybridConfigTest');
const EciesAeadHkdfPrivateKeyManager = goog.require('tink.hybrid.EciesAeadHkdfPrivateKeyManager');
const EciesAeadHkdfPublicKeyManager = goog.require('tink.hybrid.EciesAeadHkdfPublicKeyManager');
const HybridConfig = goog.require('tink.hybrid.HybridConfig');
const {HybridDecrypt} = goog.require('google3.third_party.tink.javascript.hybrid.internal.hybrid_decrypt');
const {HybridEncrypt} = goog.require('google3.third_party.tink.javascript.hybrid.internal.hybrid_encrypt');
const HybridKeyTemplates = goog.require('tink.hybrid.HybridKeyTemplates');
const {KeysetHandle} = goog.require('google3.third_party.tink.javascript.internal.keyset_handle');
const Random = goog.require('google3.third_party.tink.javascript.subtle.random');
const Registry = goog.require('google3.third_party.tink.javascript.internal.registry');
const {PbKeyData, PbKeyStatusType, PbKeyTemplate, PbKeyset, PbOutputPrefixType} = goog.require('google3.third_party.tink.javascript.internal.proto');
describe('hybrid config test', function() {
beforeEach(function() {
// Use a generous promise timeout for running continuously.
jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000 * 1000; // 1000s
});
afterEach(function() {
Registry.reset();
// Reset the promise timeout to default value.
jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000; // 1s
});
it('constants', function() {
expect(HybridConfig.ENCRYPT_PRIMITIVE_NAME).toBe(ENCRYPT_PRIMITIVE_NAME);
expect(HybridConfig.DECRYPT_PRIMITIVE_NAME).toBe(DECRYPT_PRIMITIVE_NAME);
expect(HybridConfig.ECIES_AEAD_HKDF_PUBLIC_KEY_TYPE)
.toBe(ECIES_AEAD_HKDF_PUBLIC_KEY_TYPE);
expect(HybridConfig.ECIES_AEAD_HKDF_PRIVATE_KEY_TYPE)
.toBe(ECIES_AEAD_HKDF_PRIVATE_KEY_TYPE);
});
it('register, correct key managers were registered', function() {
HybridConfig.register();
// Test that the corresponding key managers were registered.
const publicKeyManager =
Registry.getKeyManager(ECIES_AEAD_HKDF_PUBLIC_KEY_TYPE);
expect(publicKeyManager instanceof EciesAeadHkdfPublicKeyManager)
.toBe(true);
const privateKeyManager =
Registry.getKeyManager(ECIES_AEAD_HKDF_PRIVATE_KEY_TYPE);
expect(privateKeyManager instanceof EciesAeadHkdfPrivateKeyManager)
.toBe(true);
});
// 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.
it('register, predefined templates should work', async function() {
HybridConfig.register();
let templates = [
HybridKeyTemplates.eciesP256HkdfHmacSha256Aes128Gcm(),
HybridKeyTemplates.eciesP256HkdfHmacSha256Aes128CtrHmacSha256()
];
// The following function adds all templates in uncompiled tests, thus if
// a new template is added without updating HybridConfig 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(getListOfTemplatesFromHybridKeyTemplatesClass());
for (let template of templates) {
const privateKeyData = await Registry.newKeyData(template);
const privateKeysetHandle = createKeysetHandleFromKeyData(privateKeyData);
const hybridDecrypt =
await privateKeysetHandle.getPrimitive(HybridDecrypt);
const publicKeyData = Registry.getPublicKeyData(
privateKeyData.getTypeUrl(), privateKeyData.getValue_asU8());
const publicKeysetHandle = createKeysetHandleFromKeyData(publicKeyData);
const hybridEncrypt =
await publicKeysetHandle.getPrimitive(HybridEncrypt);
const plaintext = new Uint8Array(Random.randBytes(10));
const contextInfo = new Uint8Array(Random.randBytes(8));
const ciphertext = await hybridEncrypt.encrypt(plaintext, contextInfo);
const decryptedCiphertext =
await hybridDecrypt.decrypt(ciphertext, contextInfo);
expect(decryptedCiphertext).toEqual(plaintext);
}
});
});
// Constants used in tests.
const ENCRYPT_PRIMITIVE_NAME = 'HybridEncrypt';
const DECRYPT_PRIMITIVE_NAME = 'HybridDecrypt';
const ECIES_AEAD_HKDF_PUBLIC_KEY_TYPE =
'type.googleapis.com/google.crypto.tink.EciesAeadHkdfPublicKey';
const ECIES_AEAD_HKDF_PRIVATE_KEY_TYPE =
'type.googleapis.com/google.crypto.tink.EciesAeadHkdfPrivateKey';
/**
* 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 HybridKeyTemplates 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 HybridKeyTemplates
* 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 getListOfTemplatesFromHybridKeyTemplatesClass = function() {
let templates = [];
for (let propertyName of Object.getOwnPropertyNames(HybridKeyTemplates)) {
// Only public methods (i.e. not ending with '_') without arguments (i.e.
// function.length == 0) generate key templates.
const property = HybridKeyTemplates[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;
};