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.
225 lines • 25.8 kB
JavaScript
/**
* @license
* Copyright 2020 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
/**
* @fileoverview Registry for KeyManagers.
*
* Registry maps supported key types to corresponding KeyManager objects (i.e.
* the KeyManagers which may instantiate the primitive corresponding to the
* given key or generate new key of the given type). Keeping KeyManagers for all
* primitives in a single Registry (rather than having a separate keyManager per
* primitive) enables modular construction of compound primitives from "simple"
* ones (e.g. AES-CTR-HMAC AEAD encryption from IND-CPA encryption and MAC).
*
* Regular users will not usually work with Registry directly, but via primitive
* factories, which query Registry for the specific KeyManagers in the
* background.
*/
import { SecurityException } from '../exception/security_exception';
import { PbKeyData } from './proto';
import { bytesAsU8 } from './proto_shims';
import { isInstanceOf } from './util';
// key managers maps
const typeToManagerMap_ = new Map();
const typeToNewKeyAllowedMap_ = new Map();
// primitive wrappers map
const primitiveTypeToWrapper_ = new Map();
/**
* Register the given manager for the given key type. Manager must be
* non-nullptr. New keys are allowed if not specified.
*/
export function registerKeyManager(manager, opt_newKeyAllowed) {
if (opt_newKeyAllowed === undefined) {
opt_newKeyAllowed = true;
}
if (!manager) {
throw new SecurityException('Key manager cannot be null.');
}
const typeUrl = manager.getKeyType();
if (typeToManagerMap_.has(typeUrl)) {
// Cannot overwrite the existing key manager by a new one.
if (!(typeToManagerMap_.get(typeUrl) instanceof manager.constructor)) {
throw new SecurityException('Key manager for key type ' + typeUrl +
' has already been registered and cannot be overwritten.');
}
// It is forbidden to change new_key_allowed from false to true.
if (!typeToNewKeyAllowedMap_.get(typeUrl) && opt_newKeyAllowed) {
throw new SecurityException('Key manager for key type ' + typeUrl +
' has already been registered with forbidden new key operation.');
}
typeToNewKeyAllowedMap_.set(typeUrl, opt_newKeyAllowed);
}
typeToManagerMap_.set(typeUrl, manager);
typeToNewKeyAllowedMap_.set(typeUrl, opt_newKeyAllowed);
}
/**
* Returns a key manager for the given key type or throws an exception if no
* such manager found.
*
* @param typeUrl -- key type
*
*/
export function getKeyManager(typeUrl) {
const res = typeToManagerMap_.get(typeUrl);
if (!res) {
throw new SecurityException('Key manager for key type ' + typeUrl + ' has not been registered.');
}
return res;
}
/**
* It finds KeyManager according to key type (which is either given by
* PbKeyData or given by opt_typeUrl), than calls the corresponding
* manager's getPrimitive method.
*
* Either key is of type PbKeyData or opt_typeUrl must be provided.
*
* @param key -- key is either a proto of some key
* or key data.
* @param opt_typeUrl -- key type
* @this {typeof Registry}
*
*/
export function getPrimitive(primitiveType, key, opt_typeUrl) {
return __awaiter(this, void 0, void 0, function* () {
if (key instanceof PbKeyData) {
if (opt_typeUrl && key.getTypeUrl() != opt_typeUrl) {
throw new SecurityException('Key type is ' + opt_typeUrl + ', but it is expected to be ' +
key.getTypeUrl() + ' or undefined.');
}
opt_typeUrl = key.getTypeUrl();
}
if (!opt_typeUrl) {
throw new SecurityException('Key type has to be specified.');
}
const manager = getKeyManager(opt_typeUrl);
const primitive = yield manager.getPrimitive(primitiveType, key);
if (!isInstanceOf(primitive, primitiveType)) {
throw new TypeError('Unexpected type');
}
return primitive;
});
}
/**
* Generates a new PbKeyData for the specified keyTemplate. It finds a
* KeyManager given by keyTemplate.typeUrl and calls the newKeyData method of
* that manager.
*
*
*
*/
export function newKeyData(keyTemplate) {
return __awaiter(this, void 0, void 0, function* () {
const manager = getKeyManagerWithNewKeyAllowedCheck_(keyTemplate);
return manager.getKeyFactory().newKeyData(bytesAsU8(keyTemplate.getValue()));
});
}
/**
* Generates a new key for the specified keyTemplate using the
* KeyManager determined by typeUrl field of the keyTemplate.
*
*
*
* @return returns a key proto
*/
export function newKey(keyTemplate) {
return __awaiter(this, void 0, void 0, function* () {
const manager = getKeyManagerWithNewKeyAllowedCheck_(keyTemplate);
return manager.getKeyFactory().newKey(bytesAsU8(keyTemplate.getValue()));
});
}
/**
* Convenience method for extracting the public key data from the private key
* given by serializedPrivateKey.
* It looks up a KeyManager identified by typeUrl, which must hold
* PrivateKeyFactory, and calls getPublicKeyData method of that factory.
*
*/
export function getPublicKeyData(typeUrl, serializedPrivateKey) {
const manager = getKeyManager(typeUrl);
// This solution might cause some problems in the future due to Closure
// compiler optimizations, which may map factory.getPublicKeyData to
// concrete function.
const factory = manager.getKeyFactory();
if (!factory.getPublicKeyData) {
throw new SecurityException('Key manager for key type ' + typeUrl +
' does not have a private key factory.');
}
return factory.getPublicKeyData(serializedPrivateKey);
}
/**
* Resets the registry.
* After reset the registry is empty, i.e. it contains no key managers.
*
* This method is only for testing.
*/
export function reset() {
typeToManagerMap_.clear();
typeToNewKeyAllowedMap_.clear();
primitiveTypeToWrapper_.clear();
}
/**
* It finds a KeyManager given by keyTemplate.typeUrl and returns it if it
* allows creating new keys.
*
*
*/
function getKeyManagerWithNewKeyAllowedCheck_(keyTemplate) {
const keyType = keyTemplate.getTypeUrl();
const manager = getKeyManager(keyType);
if (!typeToNewKeyAllowedMap_.get(keyType)) {
throw new SecurityException('New key operation is forbidden for ' +
'key type: ' + keyType + '.');
}
return manager;
}
/**
* Tries to register a primitive wrapper.
*/
export function registerPrimitiveWrapper(wrapper) {
if (!wrapper) {
throw new SecurityException('primitive wrapper cannot be null');
}
const primitiveType = wrapper.getPrimitiveType();
if (!primitiveType) {
throw new SecurityException('primitive wrapper cannot be undefined');
}
if (primitiveTypeToWrapper_.has(primitiveType)) {
// Cannot overwrite the existing key manager by a new one.
if (!(primitiveTypeToWrapper_.get(primitiveType) instanceof
wrapper.constructor)) {
throw new SecurityException('primitive wrapper for type ' + primitiveType +
' has already been registered and cannot be overwritten');
}
}
primitiveTypeToWrapper_.set(primitiveType, wrapper);
}
/**
* Wraps a PrimitiveSet and returns a single instance.
*/
export function wrap(primitiveSet) {
if (!primitiveSet) {
throw new SecurityException('primitive set cannot be null.');
}
const primitiveType = primitiveSet.getPrimitiveType();
const wrapper = primitiveTypeToWrapper_.get(primitiveType);
if (!wrapper) {
throw new SecurityException('no primitive wrapper found for type ' + primitiveType);
}
const primitive = wrapper.wrap(primitiveSet);
if (!isInstanceOf(primitive, primitiveType)) {
throw new TypeError('Unexpected type');
}
return primitive;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVnaXN0cnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9pbnRlcm5hbC9yZWdpc3RyeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7OztHQUlHOzs7Ozs7Ozs7O0FBRUg7Ozs7Ozs7Ozs7Ozs7R0FhRztBQUVILE9BQU8sRUFBQyxpQkFBaUIsRUFBQyxNQUFNLGlDQUFpQyxDQUFDO0FBS2xFLE9BQU8sRUFBQyxTQUFTLEVBQTJCLE1BQU0sU0FBUyxDQUFDO0FBQzVELE9BQU8sRUFBQyxTQUFTLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFDeEMsT0FBTyxFQUFjLFlBQVksRUFBQyxNQUFNLFFBQVEsQ0FBQztBQUVqRCxvQkFBb0I7QUFDcEIsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLEdBQUcsRUFBMEMsQ0FBQztBQUU1RSxNQUFNLHVCQUF1QixHQUFHLElBQUksR0FBRyxFQUFtQixDQUFDO0FBRTNELHlCQUF5QjtBQUN6QixNQUFNLHVCQUF1QixHQUFHLElBQUksR0FBRyxFQUFzQyxDQUFDO0FBRTlFOzs7R0FHRztBQUNILE1BQU0sVUFBVSxrQkFBa0IsQ0FDOUIsT0FBdUMsRUFBRSxpQkFBMkI7SUFDdEUsSUFBSSxpQkFBaUIsS0FBSyxTQUFTLEVBQUU7UUFDbkMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDO0tBQzFCO0lBQ0QsSUFBSSxDQUFDLE9BQU8sRUFBRTtRQUNaLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDO0tBQzVEO0lBQ0QsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBQ3JDLElBQUksaUJBQWlCLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFO1FBQ2xDLDBEQUEwRDtRQUMxRCxJQUFJLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLFlBQVksT0FBTyxDQUFDLFdBQVcsQ0FBQyxFQUFFO1lBQ3BFLE1BQU0sSUFBSSxpQkFB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aUIsQ0FBQyx1Q0FBdUMsQ0FBQyxDQUFDO0tBQ3RFO0lBQ0QsSUFBSSx1QkFBdUIsQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFDLEVBQUU7UUFDOUMsMERBQTBEO1FBQzFELElBQUksQ0FBQyxDQUFDLHVCQUF1QixDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUM7WUFDMUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxFQUFFO1lBQzFCLE1BQU0sSUFBSSxpQkFBaUIsQ0FDdkIsNkJBQTZCLEdBQUcsYUFBYTtnQkFDN0Msd0RBQXdELENBQUMsQ0FBQztTQUMvRDtLQUNGO0lBQ0QsdUJBQXVCLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxPQUFPLENBQUMsQ0FBQztBQUN0RCxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFVBQVUsSUFBSSxDQUFJLFlBQTBDO0lBQ2hFLElBQUksQ0FBQyxZQUFZLEVBQUU7UUFDakIsTUFBTSxJQUFJLGlCQUFpQixDQUFDLCtCQUErQixDQUFDLENBQUM7S0FDOUQ7SUFDRCxNQUFNLGFBQWEsR0FBRyxZQUFZLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztJQUN0RCxNQUFNLE9BQU8sR0FBRyx1QkFBdUIsQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDM0QsSUFBSSxDQUFDLE9BQU8sRUFBRTtRQUNaLE1BQU0sSUFBSSxpQkFBaUIsQ0FDdkIsc0NBQXNDLEdBQUcsYUFBYSxDQUFDLENBQUM7S0FDN0Q7SUFDRCxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBQzdDLElBQUksQ0FBQyxZQUFZLENBQUMsU0FBUyxFQUFFLGFBQWEsQ0FBQyxFQUFFO1FBQzNDLE1BQU0sSUFBSSxTQUFTLENBQUMsaUJBQWlCLENBQUMsQ0FBQztLQUN4QztJQUNELE9BQU8sU0FBUyxDQUFDO0FBQ25CLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuICovXG5cbi8qKlxuICogQGZpbGVvdmVydmlldyBSZWdpc3RyeSBmb3IgS2V5TWFuYWdlcnMuXG4gKlxuICogUmVnaXN0cnkgbWFwcyBzdXBwb3J0ZWQga2V5IHR5cGVzIHRvIGNvcnJlc3BvbmRpbmcgS2V5TWFuYWdlciBvYmplY3RzIChpLmUuXG4gKiB0aGUgS2V5TWFuYWdlcnMgd2hpY2ggbWF5IGluc3RhbnRpYXRlIHRoZSBwcmltaXRpdmUgY29ycmVzcG9uZGluZyB0byB0aGVcbiAqIGdpdmVuIGtleSBvciBnZW5lcmF0ZSBuZXcga2V5IG9mIHRoZSBnaXZlbiB0eXBlKS4gS2VlcGluZyBLZXlNYW5hZ2VycyBmb3IgYWxsXG4gKiBwcmltaXRpdmVzIGluIGEgc2luZ2xlIFJlZ2lzdHJ5IChyYXRoZXIgdGhhbiBoYXZpbmcgYSBzZXBhcmF0ZSBrZXlNYW5hZ2VyIHBlclxuICogcHJpbWl0aXZlKSBlbmFibGVzIG1vZHVsYXIgY29uc3RydWN0aW9uIG9mIGNvbXBvdW5kIHByaW1pdGl2ZXMgZnJvbSBcInNpbXBsZVwiXG4gKiBvbmVzIChlLmcuIEFFUy1DVFItSE1BQyBBRUFEIGVuY3J5cHRpb24gZnJvbSBJTkQtQ1BBIGVuY3J5cHRpb24gYW5kIE1BQykuXG4gKlxuICogUmVndWxhciB1c2VycyB3aWxsIG5vdCB1c3VhbGx5IHdvcmsgd2l0aCBSZWdpc3RyeSBkaXJlY3RseSwgYnV0IHZpYSBwcmltaXRpdmVcbiAqIGZhY3Rvcmllcywgd2hpY2ggcXVlcnkgUmVnaXN0cnkgZm9yIHRoZSBzcGVjaWZpYyBLZXlNYW5hZ2VycyBpbiB0aGVcbiAqIGJhY2tncm91bmQuXG4gKi9cblxuaW1wb3J0IHtTZWN1cml0eUV4Y2VwdGlvbn0gZnJvbSAnLi4vZXhjZXB0aW9uL3NlY3VyaXR5X2V4Y2VwdGlvbic7XG5cbmltcG9ydCAqIGFzIEtleU1hbmFnZXIgZnJvbSAnLi9rZXlfbWFuYWdlcic7XG5pbXBvcnQgKiBhcyBQcmltaXRpdmVTZXQgZnJvbSAnLi9wcmltaXRpdmVfc2V0JztcbmltcG9ydCB7UHJpbWl0aXZlV3JhcHBlcn0gZnJvbSAnLi9wcmltaXRpdmVfd3JhcHBlcic7XG5pbXBvcnQge1BiS2V5RGF0YSwgUGJLZXlUZW1wbGF0ZSwgUGJNZXNzYWdlfSBmcm9tICcuL3Byb3RvJztcbmltcG9ydCB7Ynl0ZXNBc1U4fSBmcm9tICcuL3Byb3RvX3NoaW1zJztcbmltcG9ydCB7Q29uc3RydWN0b3IsIGlzSW5zdGFuY2VPZn0gZnJvbSAnLi91dGlsJztcblxuLy8ga2V5IG1hbmFnZXJzIG1hcHNcbmNvbnN0IHR5cGVUb01hbmFnZXJNYXBfID0gbmV3IE1hcDxzdHJpbmcsIEtleU1hbmFnZXIuS2V5TWFuYWdlcjx1bmtub3duPj4oKTtcblxuY29uc3QgdHlwZVRvTmV3S2V5QWxsb3dlZE1hcF8gPSBuZXcgTWFwPHN0cmluZywgYm9vbGVhbj4oKTtcblxuLy8gcHJpbWl0aXZlIHdyYXBwZXJzIG1hcFxuY29uc3QgcHJpbWl0aXZlVHlwZVRvV3JhcHBlcl8gPSBuZXcgTWFwPHVua25vd24sIFByaW1pdGl2ZVdyYXBwZXI8dW5rbm93bj4+KCk7XG5cbi8qKlxuICogUmVnaXN0ZXIgdGhlIGdpdmVuIG1hbmFnZXIgZm9yIHRoZSBnaXZlbiBrZXkgdHlwZS4gTWFuYWdlciBtdXN0IGJlXG4gKiBub24tbnVsbHB0ci4gTmV3IGtleXMgYXJlIGFsbG93ZWQgaWYgbm90IHNwZWNpZmllZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyS2V5TWFuYWdlcihcbiAgICBtYW5hZ2VyOiBLZXlNYW5hZ2VyLktleU1hbmFnZXI8dW5rbm93bj4sIG9wdF9uZXdLZXlBbGxvd2VkPzogYm9vbGVhbikge1xuICBpZiAob3B0X25ld0tleUFsbG93ZWQgPT09IHVuZGVmaW5lZCkge1xuICAgIG9wdF9uZXdLZXlBbGxvd2VkID0gdHJ1ZTtcbiAgfVxuICBpZiAoIW1hbmFnZXIpIHtcbiAgICB0aHJvdyBuZXcgU2VjdXJpdHlFeGNlcHRpb24oJ0tleSBtYW5hZ2VyIGNhbm5vdCBiZSBudWxsLicpO1xuICB9XG4gIGNvbnN0IHR5cGVVcmwgPSBtYW5hZ2VyLmdldEtleVR5cGUoKTtcbiAgaWYgKHR5cGVUb01hbmFnZXJNYXBfLmhhcyh0eXBlVXJsKSkge1xuICAgIC8vIENhbm5vdCBvdmVyd3JpdGUgdGhlIGV4aXN0aW5nIGtleSBtYW5hZ2VyIGJ5IGEgbmV3IG9uZS5cbiAgICBpZiAoISh0eXBlVG9NYW5hZ2VyTWFwXy5nZXQodHlwZVVybCkgaW5zdGFuY2VvZiBtYW5hZ2VyLmNvbnN0cnVjdG9yKSkge1xuICAgICAgdGhyb3cgbmV3IFNlY3VyaXR5RXhjZXB0aW9uKFxuICAgICAgICAgICdLZXkgbWFuYWdlciBmb3Iga2V5IHR5cGUgJyArIHR5cGVVcmwgK1xuICAgICAgICAgICcgaGFzIGFscmVhZHkgYmVlbiByZWdpc3RlcmVkIGFuZCBjYW5ub3QgYmUgb3ZlcndyaXR0ZW4uJyk7XG4gICAgfVxuXG4gICAgLy8gSXQgaXMgZm9yYmlkZGVuIHRvIGNoYW5nZSBuZXdfa2V5X2FsbG93ZWQgZnJvbSBmYWxzZSB0byB0cnVlLlxuICAgIGlmICghdHlwZVRvTmV3S2V5QWxsb3dlZE1hcF8uZ2V0KHR5cGVVcmwpICYmIG9wdF9uZXdLZXlBbGxvd2VkKSB7XG4gICAgICB0aHJvdyBuZXcgU2VjdXJpdHlFeGNlcHRpb24oXG4gICAgICAgICAgJ0tleSBtYW5hZ2VyIGZvciBrZXkgdHlwZSAnICsgdHlwZVVybCArXG4gICAgICAgICAgJyBoYXMgYWxyZWFkeSBiZWVuIHJlZ2lzdGVyZWQgd2l0aCBmb3JiaWRkZW4gbmV3IGtleSBvcGVyYXRpb24uJyk7XG4gICAgfVxuICAgIHR5cGVUb05ld0tleUFsbG93ZWRNYXBfLnNldCh0eXBlVXJsLCBvcHRfbmV3S2V5QWxsb3dlZCk7XG4gIH1cbiAgdHlwZVRvTWFuYWdlck1hcF8uc2V0KHR5cGVVcmwsIG1hbmFnZXIpO1xuICB0eXBlVG9OZXdLZXlBbGxvd2VkTWFwXy5zZXQodHlwZVVybCwgb3B0X25ld0tleUFsbG93ZWQpO1xufVxuXG4vKipcbiAqIFJldHVybnMgYSBrZXkgbWFuYWdlciBmb3IgdGhlIGdpdmVuIGtleSB0eXBlIG9yIHRocm93cyBhbiBleGNlcHRpb24gaWYgbm9cbiAqIHN1Y2ggbWFuYWdlciBmb3VuZC5cbiAqXG4gKiBAcGFyYW0gdHlwZVVybCAtLSBrZXkgdHlwZVxuICpcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEtleU1hbmFnZXIodHlwZVVybDogc3RyaW5nKTogS2V5TWFuYWdlci5LZXlNYW5hZ2VyPHVua25vd24+IHtcbiAgY29uc3QgcmVzID0gdHlwZVRvTWFuYWdlck1hcF8uZ2V0KHR5cGVVcmwpO1xuICBpZiAoIXJlcykge1xuICAgIHRocm93IG5ldyBTZWN1cml0eUV4Y2VwdGlvbihcbiAgICAgICAgJ0tleSBtYW5hZ2VyIGZvciBrZXkgdHlwZSAnICsgdHlwZVVybCArICcgaGFzIG5vdCBiZWVuIHJlZ2lzdGVyZWQuJyk7XG4gIH1cbiAgcmV0dXJuIHJlcztcbn1cblxuLyoqXG4gKiBJdCBmaW5kcyBLZXlNYW5hZ2VyIGFjY29yZGluZyB0byBrZXkgdHlwZSAod2hpY2ggaXMgZWl0aGVyIGdpdmVuIGJ5XG4gKiBQYktleURhdGEgb3IgZ2l2ZW4gYnkgb3B0X3R5cGVVcmwpLCB0aGFuIGNhbGxzIHRoZSBjb3JyZXNwb25kaW5nXG4gKiBtYW5hZ2VyJ3MgZ2V0UHJpbWl0aXZlIG1ldGhvZC5cbiAqXG4gKiBFaXRoZXIga2V5IGlzIG9mIHR5cGUgUGJLZXlEYXRhIG9yIG9wdF90eXBlVXJsIG11c3QgYmUgcHJvdmlkZWQuXG4gKlxuICogQHBhcmFtIGtleSAtLSBrZXkgaXMgZWl0aGVyIGEgcHJvdG8gb2Ygc29tZSBrZXlcbiAqICAgICBvciBrZXkgZGF0YS5cbiAqIEBwYXJhbSBvcHRfdHlwZVVybCAtLSBrZXkgdHlwZVxuICogQHRoaXMge3R5cGVvZiBSZWdpc3RyeX1cbiAqXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZXRQcmltaXRpdmU8UD4oXG4gICAgcHJpbWl0aXZlVHlwZTogQ29uc3RydWN0b3I8UD4sIGtleTogUGJLZXlEYXRhfFBiTWVzc2FnZSxcbiAgICBvcHRfdHlwZVVybD86IHN0cmluZ3xudWxsKTogUHJvbWlzZTxQPiB7XG4gIGlmIChrZXkgaW5zdGFuY2VvZiBQYktleURhdGEpIHtcbiAgICBpZiAob3B0X3R5cGVVcmwgJiYga2V5LmdldFR5cGVVcmwoKSAhPSBvcHRfdHlwZVVybCkge1xuICAgICAgdGhyb3cgbmV3IFNlY3VyaXR5RXhjZXB0aW9uKFxuICAgICAgICAgICdLZXkgdHlwZSBpcyAnICsgb3B0X3R5cGVVcmwgKyAnLCBidXQgaXQgaXMgZXhwZWN0ZWQgdG8gYmUgJyArXG4gICAgICAgICAga2V5LmdldFR5cGVVcmwoKSArICcgb3IgdW5kZWZpbmVkLicpO1xuICAgIH1cbiAgICBvcHRfdHlwZVVybCA9IGtleS5nZXRUeXBlVXJsKCk7XG4gIH1cbiAgaWYgKCFvcHRfdHlwZVVybCkge1xuICAgIHRocm93IG5ldyBTZWN1cml0eUV4Y2VwdGlvbignS2V5IHR5cGUgaGFzIHRvIGJlIHNwZWNpZmllZC4nKTtcbiAgfVxuICBjb25zdCBtYW5hZ2VyID0gZ2V0S2V5TWFuYWdlcihvcHRfdHlwZVVybCk7XG4gIGNvbnN0IHByaW1pdGl2ZSA9IGF3YWl0IG1hbmFnZXIuZ2V0UHJpbWl0aXZlKHByaW1pdGl2ZVR5cGUsIGtleSk7XG4gIGlmICghaXNJbnN0YW5jZU9mKHByaW1pdGl2ZSwgcHJpbWl0aXZlVHlwZSkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmV4cGVjdGVkIHR5cGUnKTtcbiAgfVxuICByZXR1cm4gcHJpbWl0aXZlO1xufVxuXG4vKipcbiAqIEdlbmVyYXRlcyBhIG5ldyBQYktleURhdGEgZm9yIHRoZSBzcGVjaWZpZWQga2V5VGVtcGxhdGUuIEl0IGZpbmRzIGFcbiAqIEtleU1hbmFnZXIgZ2l2ZW4gYnkga2V5VGVtcGxhdGUudHlwZVVybCBhbmQgY2FsbHMgdGhlIG5ld0tleURhdGEgbWV0aG9kIG9mXG4gKiB0aGF0IG1hbmFnZXIuXG4gKlxuICpcbiAqXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBuZXdLZXlEYXRhKGtleVRlbXBsYXRlOiBQYktleVRlbXBsYXRlKTpcbiAgICBQcm9taXNlPFBiS2V5RGF0YT4ge1xuICBjb25zdCBtYW5hZ2VyID0gZ2V0S2V5TWFuYWdlcldpdGhOZXdLZXlBbGxvd2VkQ2hlY2tfKGtleVRlbXBsYXRlKTtcbiAgcmV0dXJuIG1hbmFnZXIuZ2V0S2V5RmFjdG9yeSgpLm5ld0tleURhdGEoYnl0ZXNBc1U4KGtleVRlbXBsYXRlLmdldFZhbHVlKCkpKTtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZXMgYSBuZXcga2V5IGZvciB0aGUgc3BlY2lmaWVkIGtleVRlbXBsYXRlIHVzaW5nIHRoZVxuICogS2V5TWFuYWdlciBkZXRlcm1pbmVkIGJ5IHR5cGVVcmwgZmllbGQgb2YgdGhlIGtleVRlbXBsYXRlLlxuICpcbiAqXG4gKlxuICogQHJldHVybiByZXR1cm5zIGEga2V5IHByb3RvXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBuZXdLZXkoa2V5VGVtcGxhdGU6IFBiS2V5VGVtcGxhdGUpOiBQcm9taXNlPFBiTWVzc2FnZT4ge1xuICBjb25zdCBtYW5hZ2VyID0gZ2V0S2V5TWFuYWdlcldpdGhOZXdLZXlBbGxvd2VkQ2hlY2tfKGtleVRlbXBsYXRlKTtcbiAgcmV0dXJuIG1hbmFnZXIuZ2V0S2V5RmFjdG9yeSgpLm5ld0tleShieXRlc0FzVTgoa2V5VGVtcGxhdGUuZ2V0VmFsdWUoKSkpO1xufVxuXG4vKipcbiAqIENvbnZlbmllbmNlIG1ldGhvZCBmb3IgZXh0cmFjdGluZyB0aGUgcHVibGljIGtleSBkYXRhIGZyb20gdGhlIHByaXZhdGUga2V5XG4gKiBnaXZlbiBieSBzZXJpYWxpemVkUHJpdmF0ZUtleS5cbiAqIEl0IGxvb2tzIHVwIGEgS2V5TWFuYWdlciBpZGVudGlmaWVkIGJ5IHR5cGVVcmwsIHdoaWNoIG11c3QgaG9sZFxuICogUHJpdmF0ZUtleUZhY3RvcnksIGFuZCBjYWxscyBnZXRQdWJsaWNLZXlEYXRhIG1ldGhvZCBvZiB0aGF0IGZhY3RvcnkuXG4gKlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0UHVibGljS2V5RGF0YShcbiAgICB0eXBlVXJsOiBzdHJpbmcsIHNlcmlhbGl6ZWRQcml2YXRlS2V5OiBVaW50OEFycmF5KTogUGJLZXlEYXRhIHtcbiAgY29uc3QgbWFuYWdlciA9IGdldEtleU1hbmFnZXIodHlwZVVybCk7XG5cbiAgLy8gVGhpcyBzb2x1dGlvbiBtaWdodCBjYXVzZSBzb21lIHByb2JsZW1zIGluIHRoZSBmdXR1cmUgZHVlIHRvIENsb3N1cmVcbiAgLy8gY29tcGlsZXIgb3B0aW1pemF0aW9ucywgd2hpY2ggbWF5IG1hcCBmYWN0b3J5LmdldFB1YmxpY0tleURhdGEgdG9cbiAgLy8gY29uY3JldGUgZnVuY3Rpb24uXG4gIGNvbnN0IGZhY3RvcnkgPSBtYW5hZ2VyLmdldEtleUZhY3RvcnkoKTtcbiAgaWYgKCFmYWN0b3J5LmdldFB1YmxpY0tleURhdGEpIHtcbiAgICB0aHJvdyBuZXcgU2VjdXJpdHlFeGNlcHRpb24oXG4gICAgICAgICdLZXkgbWFuYWdlciBmb3Iga2V5IHR5cGUgJyArIHR5cGVVcmwgK1xuICAgICAgICAnIGRvZXMgbm90IGhhdmUgYSBwcml2YXRlIGtleSBmYWN0b3J5LicpO1xuICB9XG4gIHJldHVybiBmYWN0b3J5LmdldFB1YmxpY0tleURhdGEoc2VyaWFsaXplZFByaXZhdGVLZXkpO1xufVxuXG4vKipcbiAqIFJlc2V0cyB0aGUgcmVnaXN0cnkuXG4gKiBBZnRlciByZXNldCB0aGUgcmVnaXN0cnkgaXMgZW1wdHksIGkuZS4gaXQgY29udGFpbnMgbm8ga2V5IG1hbmFnZXJzLlxuICpcbiAqIFRoaXMgbWV0aG9kIGlzIG9ubHkgZm9yIHRlc3RpbmcuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNldCgpIHtcbiAgdHlwZVRvTWFuYWdlck1hcF8uY2xlYXIoKTtcbiAgdHlwZVRvTmV3S2V5QWxsb3dlZE1hcF8uY2xlYXIoKTtcbiAgcHJpbWl0aXZlVHlwZVRvV3JhcHBlcl8uY2xlYXIoKTtcbn1cblxuLyoqXG4gKiBJdCBmaW5kcyBhIEtleU1hbmFnZXIgZ2l2ZW4gYnkga2V5VGVtcGxhdGUudHlwZVVybCBhbmQgcmV0dXJucyBpdCBpZiBpdFxuICogYWxsb3dzIGNyZWF0aW5nIG5ldyBrZXlzLlxuICpcbiAqXG4gKi9cbmZ1bmN0aW9uIGdldEtleU1hbmFnZXJXaXRoTmV3S2V5QWxsb3dlZENoZWNrXyhrZXlUZW1wbGF0ZTogUGJLZXlUZW1wbGF0ZSk6XG4gICAgS2V5TWFuYWdlci5LZXlNYW5hZ2VyPHVua25vd24+IHtcbiAgY29uc3Qga2V5VHlwZSA9IGtleVRlbXBsYXRlLmdldFR5cGVVcmwoKTtcbiAgY29uc3QgbWFuYWdlciA9IGdldEtleU1hbmFnZXIoa2V5VHlwZSk7XG4gIGlmICghdHlwZVRvTmV3S2V5QWxsb3dlZE1hcF8uZ2V0KGtleVR5cGUpKSB7XG4gICAgdGhyb3cgbmV3IFNlY3VyaXR5RXhjZXB0aW9uKFxuICAgICAgICAnTmV3IGtleSBvcGVyYXRpb24gaXMgZm9yYmlkZGVuIGZvciAnICtcbiAgICAgICAgJ2tleSB0eXBlOiAnICsga2V5VHlwZSArICcuJyk7XG4gIH1cbiAgcmV0dXJuIG1hbmFnZXI7XG59XG5cbi8qKlxuICogVHJpZXMgdG8gcmVnaXN0ZXIgYSBwcmltaXRpdmUgd3JhcHBlci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyUHJpbWl0aXZlV3JhcHBlcjxQPih3cmFwcGVyOiBQcmltaXRpdmVXcmFwcGVyPFA+KSB7XG4gIGlmICghd3JhcHBlcikge1xuICAgIHRocm93IG5ldyBTZWN1cml0eUV4Y2VwdGlvbigncHJpbWl0aXZlIHdyYXBwZXIgY2Fubm90IGJlIG51bGwnKTtcbiAgfVxuICBjb25zdCBwcmltaXRpdmVUeXBlID0gd3JhcHBlci5nZXRQcmltaXRpdmVUeXBlKCk7XG4gIGlmICghcHJpbWl0aXZlVHlwZSkge1xuICAgIHRocm93IG5ldyBTZWN1cml0eUV4Y2VwdGlvbigncHJpbWl0aXZlIHdyYXBwZXIgY2Fubm90IGJlIHVuZGVmaW5lZCcpO1xuICB9XG4gIGlmIChwcmltaXRpdmVUeXBlVG9XcmFwcGVyXy5oYXMocHJpbWl0aXZlVHlwZSkpIHtcbiAgICAvLyBDYW5ub3Qgb3ZlcndyaXRlIHRoZSBleGlzdGluZyBrZXkgbWFuYWdlciBieSBhIG5ldyBvbmUuXG4gICAgaWYgKCEocHJpbWl0aXZlVHlwZVRvV3JhcHBlcl8uZ2V0KHByaW1pdGl2ZVR5cGUpIGluc3RhbmNlb2ZcbiAgICAgICAgICB3cmFwcGVyLmNvbnN0cnVjdG9yKSkge1xuICAgICAgdGhyb3cgbmV3IFNlY3VyaXR5RXhjZXB0aW9uKFxuICAgICAgICAgICdwcmltaXRpdmUgd3JhcHBlciBmb3IgdHlwZSAnICsgcHJpbWl0aXZlVHlwZSArXG4gICAgICAgICAgJyBoYXMgYWxyZWFkeSBiZWVuIHJlZ2lzdGVyZWQgYW5kIGNhbm5vdCBiZSBvdmVyd3JpdHRlbicpO1xuICAgIH1cbiAgfVxuICBwcmltaXRpdmVUeXBlVG9XcmFwcGVyXy5zZXQocHJpbWl0aXZlVHlwZSwgd3JhcHBlcik7XG59XG5cbi8qKlxuICogV3JhcHMgYSBQcmltaXRpdmVTZXQgYW5kIHJldHVybnMgYSBzaW5nbGUgaW5zdGFuY2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3cmFwPFA+KHByaW1pdGl2ZVNldDogUHJpbWl0aXZlU2V0LlByaW1pdGl2ZVNldDxQPik6IFAge1xuICBpZiAoIXByaW1pdGl2ZVNldCkge1xuICAgIHRocm93IG5ldyBTZWN1cml0eUV4Y2VwdGlvbigncHJpbWl0aXZlIHNldCBjYW5ub3QgYmUgbnVsbC4nKTtcbiAgfVxuICBjb25zdCBwcmltaXRpdmVUeXBlID0gcHJpbWl0aXZlU2V0LmdldFByaW1pdGl2ZVR5cGUoKTtcbiAgY29uc3Qgd3JhcHBlciA9IHByaW1pdGl2ZVR5cGVUb1dyYXBwZXJfLmdldChwcmltaXRpdmVUeXBlKTtcbiAgaWYgKCF3cmFwcGVyKSB7XG4gICAgdGhyb3cgbmV3IFNlY3VyaXR5RXhjZXB0aW9uKFxuICAgICAgICAnbm8gcHJpbWl0aXZlIHdyYXBwZXIgZm91bmQgZm9yIHR5cGUgJyArIHByaW1pdGl2ZVR5cGUpO1xuICB9XG4gIGNvbnN0IHByaW1pdGl2ZSA9IHdyYXBwZXIud3JhcChwcmltaXRpdmVTZXQpO1xuICBpZiAoIWlzSW5zdGFuY2VPZihwcmltaXRpdmUsIHByaW1pdGl2ZVR5cGUpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5leHBlY3RlZCB0eXBlJyk7XG4gIH1cbiAgcmV0dXJuIHByaW1pdGl2ZTtcbn1cbiJdfQ==