UNPKG

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
/** * @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==