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.

160 lines 18.7 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()); }); }; import { SecurityException } from '../exception/security_exception'; import { PbAesGcmKey, PbAesGcmKeyFormat, PbKeyData } from '../internal/proto'; import { bytesAsU8, bytesLength } from '../internal/proto_shims'; import * as Registry from '../internal/registry'; import * as aesGcm from '../subtle/aes_gcm'; import * as Random from '../subtle/random'; import * as Validators from '../subtle/validators'; import { Aead } from './internal/aead'; const VERSION = 0; /** * @final */ class AesGcmKeyFactory { newKey(keyFormat) { const keyFormatProto = AesGcmKeyFactory.getKeyFormatProto(keyFormat); AesGcmKeyFactory.validateKeyFormat(keyFormatProto); const key = (new PbAesGcmKey()) .setKeyValue(Random.randBytes(keyFormatProto.getKeySize())) .setVersion(VERSION); return key; } newKeyData(serializedKeyFormat) { const key = (this.newKey(serializedKeyFormat)); const keyData = (new PbKeyData()) .setTypeUrl(AesGcmKeyManager.KEY_TYPE) .setValue(key.serializeBinary()) .setKeyMaterialType(PbKeyData.KeyMaterialType.SYMMETRIC); return keyData; } static validateKeyFormat(keyFormat) { Validators.validateAesKeySize(keyFormat.getKeySize()); } /** * The input keyFormat is either deserialized (in case that the input is * Uint8Array) or checked to be an AesGcmKeyFormat-proto (otherwise). * */ static getKeyFormatProto(keyFormat) { if (keyFormat instanceof Uint8Array) { return AesGcmKeyFactory.deserializeKeyFormat(keyFormat); } else if (keyFormat instanceof PbAesGcmKeyFormat) { return keyFormat; } else { throw new SecurityException('Expected AesGcmKeyFormat-proto'); } } static deserializeKeyFormat(keyFormat) { let keyFormatProto; try { keyFormatProto = PbAesGcmKeyFormat.deserializeBinary(keyFormat); } catch (e) { throw new SecurityException('Could not parse the input as a serialized proto of ' + AesGcmKeyManager.KEY_TYPE + ' key format.'); } if (!keyFormatProto.getKeySize()) { throw new SecurityException('Could not parse the input as a serialized proto of ' + AesGcmKeyManager.KEY_TYPE + ' key format.'); } return keyFormatProto; } } /** * @final */ export class AesGcmKeyManager { /** Visible for testing. */ constructor() { this.keyFactory = new AesGcmKeyFactory(); } getPrimitive(primitiveType, key) { return __awaiter(this, void 0, void 0, function* () { if (primitiveType != this.getPrimitiveType()) { throw new SecurityException('Requested primitive type which is not ' + 'supported by this key manager.'); } const keyProto = AesGcmKeyManager.getKeyProto(key); AesGcmKeyManager.validateKey(keyProto); return yield aesGcm.fromRawKey(bytesAsU8(keyProto.getKeyValue())); }); } doesSupport(keyType) { return keyType === this.getKeyType(); } getKeyType() { return AesGcmKeyManager.KEY_TYPE; } getPrimitiveType() { return AesGcmKeyManager.SUPPORTED_PRIMITIVE; } getVersion() { return VERSION; } getKeyFactory() { return this.keyFactory; } static validateKey(key) { Validators.validateAesKeySize(bytesLength(key.getKeyValue())); Validators.validateVersion(key.getVersion(), VERSION); } /** * The input key is either deserialized (in case that the input is * KeyData-proto) or checked to be an AesGcmKey-proto (otherwise). * */ static getKeyProto(keyMaterial) { if (keyMaterial instanceof PbKeyData) { return AesGcmKeyManager.getKeyProtoFromKeyData(keyMaterial); } else if (keyMaterial instanceof PbAesGcmKey) { return keyMaterial; } else { throw new SecurityException('Key type is not supported. ' + 'This key manager supports ' + AesGcmKeyManager.KEY_TYPE + '.'); } } /** * It validates the key type and returns a deserialized AesGcmKey-proto. * */ static getKeyProtoFromKeyData(keyData) { if (keyData.getTypeUrl() != AesGcmKeyManager.KEY_TYPE) { throw new SecurityException('Key type ' + keyData.getTypeUrl() + ' is not supported. This key manager supports ' + AesGcmKeyManager.KEY_TYPE + '.'); } let deserializedKey; try { deserializedKey = PbAesGcmKey.deserializeBinary(keyData.getValue()); } catch (e) { throw new SecurityException('Could not parse the input as a ' + 'serialized proto of ' + AesGcmKeyManager.KEY_TYPE + ' key.'); } return deserializedKey; } static register() { Registry.registerKeyManager(new AesGcmKeyManager()); } } AesGcmKeyManager.SUPPORTED_PRIMITIVE = Aead; AesGcmKeyManager.KEY_TYPE = 'type.googleapis.com/google.crypto.tink.AesGcmKey'; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWVzX2djbV9rZXlfbWFuYWdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2FlYWQvYWVzX2djbV9rZXlfbWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7OztHQUlHOzs7Ozs7Ozs7O0FBRUgsT0FBTyxFQUFDLGlCQUFpQixFQUFDLE1BQU0saUNBQWlDLENBQUM7QUFFbEUsT0FBTyxFQUFDLFdBQVcsRUFBRSxpQkFBaUIsRUFBRSxTQUFTLEVBQVksTUFBTSxtQkFBbUIsQ0FBQztBQUN2RixPQUFPLEVBQUMsU0FBUyxFQUFFLFdBQVcsRUFBQyxNQUFNLHlCQUF5QixDQUFDO0FBQy9ELE9BQU8sS0FBSyxRQUFRLE1BQU0sc0JBQXNCLENBQUM7QUFFakQsT0FBTyxLQUFLLE1BQU0sTUFBTSxtQkFBbUIsQ0FBQztBQUM1QyxPQUFPLEtBQUssTUFBTSxNQUFNLGtCQUFrQixDQUFDO0FBQzNDLE9BQU8sS0FBSyxVQUFVLE1BQU0sc0JBQXNCLENBQUM7QUFFbkQsT0FBTyxFQUFDLElBQUksRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBRXJDLE1BQU0sT0FBTyxHQUFHLENBQUMsQ0FBQztBQUVsQjs7R0FFRztBQUNILE1BQU0sZ0JBQWdCO0lBQ3BCLE1BQU0sQ0FBQyxTQUErQjtRQUNwQyxNQUFNLGNBQWMsR0FBRyxnQkFBZ0IsQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNyRSxnQkFBZ0IsQ0FBQyxpQkFBaUIsQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUNuRCxNQUFNLEdBQUcsR0FBRyxDQUFDLElBQUksV0FBVyxFQUFFLENBQUM7YUFDZCxXQUFXLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQzthQUMxRCxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDckMsT0FBTyxHQUFHLENBQUM7SUFDYixDQUFDO0lBRUQsVUFBVSxDQUFDLG1CQUErQjtR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ZUFBZSxDQUFDO0lBQ3pCLENBQUM7SUFFRCxNQUFNLENBQUMsUUFBUTtRQUNiLFFBQVEsQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLGdCQUFnQixFQUFFLENBQUMsQ0FBQztJQUN0RCxDQUFDOztBQXZGdUIsb0NBQW1CLEdBQUcsSUFBSSxDQUFDO0FBQzVDLHlCQUFRLEdBQVcsa0RBQWtELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuICovXG5cbmltcG9ydCB7U2VjdXJpdHlFeGNlcHRpb259IGZyb20gJy4uL2V4Y2VwdGlvbi9zZWN1cml0eV9leGNlcHRpb24nO1xuaW1wb3J0ICogYXMgS2V5TWFuYWdlciBmcm9tICcuLi9pbnRlcm5hbC9rZXlfbWFuYWdlcic7XG5pbXBvcnQge1BiQWVzR2NtS2V5LCBQYkFlc0djbUtleUZvcm1hdCwgUGJLZXlEYXRhLCBQYk1lc3NhZ2V9IGZyb20gJy4uL2ludGVybmFsL3Byb3RvJztcbmltcG9ydCB7Ynl0ZXNBc1U4LCBieXRlc0xlbmd0aH0gZnJvbSAnLi4vaW50ZXJuYWwvcHJvdG9fc2hpbXMnO1xuaW1wb3J0ICogYXMgUmVnaXN0cnkgZnJvbSAnLi4vaW50ZXJuYWwvcmVnaXN0cnknO1xuaW1wb3J0IHtDb25zdHJ1Y3Rvcn0gZnJvbSAnLi4vaW50ZXJuYWwvdXRpbCc7XG5pbXBvcnQgKiBhcyBhZXNHY20gZnJvbSAnLi4vc3VidGxlL2Flc19nY20nO1xuaW1wb3J0ICogYXMgUmFuZG9tIGZyb20gJy4uL3N1YnRsZS9yYW5kb20nO1xuaW1wb3J0ICogYXMgVmFsaWRhdG9ycyBmcm9tICcuLi9zdWJ0bGUvdmFsaWRhdG9ycyc7XG5cbmltcG9ydCB7QWVhZH0gZnJvbSAnLi9pbnRlcm5hbC9hZWFkJztcblxuY29uc3QgVkVSU0lPTiA9IDA7XG5cbi8qKlxuICogQGZpbmFsXG4gKi9cbmNsYXNzIEFlc0djbUtleUZhY3RvcnkgaW1wbGVtZW50cyBLZXlNYW5hZ2VyLktleUZhY3Rvcnkge1xuICBuZXdLZXkoa2V5Rm9ybWF0OiBQYk1lc3NhZ2V8VWludDhBcnJheSkge1xuICAgIGNvbnN0IGtleUZvcm1hdFByb3RvID0gQWVzR2NtS2V5RmFjdG9yeS5nZXRLZXlGb3JtYXRQcm90byhrZXlGb3JtYXQpO1xuICAgIEFlc0djbUtleUZhY3RvcnkudmFsaWRhdGVLZXlGb3JtYXQoa2V5Rm9ybWF0UHJvdG8pO1xuICAgIGNvbnN0IGtleSA9IChuZXcgUGJBZXNHY21LZXkoKSlcbiAgICAgICAgICAgICAgICAgICAgLnNldEtleVZhbHVlKFJhbmRvbS5yYW5kQnl0ZXMoa2V5Rm9ybWF0UHJvdG8uZ2V0S2V5U2l6ZSgpKSlcbiAgICAgICAgICAgICAgICAgICAgLnNldFZlcnNpb24oVkVSU0lPTik7XG4gICAgcmV0dXJuIGtleTtcbiAgfVxuXG4gIG5ld0tleURhdGEoc2VyaWFsaXplZEtleUZvcm1hdDogVWludDhBcnJheSkge1xuICAgIGNvbnN0IGtleSA9ICh0aGlzLm5ld0tleShzZXJpYWxpemVkS2V5Rm9ybWF0KSk7XG4gICAgY29uc3Qga2V5RGF0YSA9XG4gICAgICAgIChuZXcgUGJLZXlEYXRhKCkpXG4gICAgICAgICAgICAuc2V0VHlwZVVybChBZXNHY21LZXlNYW5hZ2VyLktFWV9UWVBFKVxuICAgICAgICAgICAgLnNldFZhbHVlKGtleS5zZXJpYWxpemVCaW5hcnkoKSlcbiAgICAgICAgICAgIC5zZXRLZXlNYXRlcmlhbFR5cGUoUGJLZXlEYXRhLktleU1hdGVyaWFsVHlwZS5TWU1NRVRSSUMpO1xuICAgIHJldHVybiBrZXlEYXRhO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgdmFsaWRhdGVLZXlGb3JtYXQoa2V5Rm9ybWF0OiBQYkFlc0djbUtleUZvcm1hdCkge1xuICAgIFZhbGlkYXRvcnMudmFsaWRhdGVBZXNLZXlTaXplKGtleUZvcm1hdC5nZXRLZXlTaXplKCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBpbnB1dCBrZXlGb3JtYXQgaXMgZWl0aGVyIGRlc2VyaWFsaXplZCAoaW4gY2FzZSB0aGF0IHRoZSBpbnB1dCBpc1xuICAgKiBVaW50OEFycmF5KSBvciBjaGVja2VkIHRvIGJlIGFuIEFlc0djbUtleUZvcm1hdC1wcm90byAob3RoZXJ3aXNlKS5cbiAgICpcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIGdldEtleUZvcm1hdFByb3RvKGtleUZvcm1hdDogUGJNZXNzYWdlfFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVaW50OEFycmF5KTogUGJBZXNHY21LZXlGb3JtYXQge1xuICAgIGlmIChrZXlGb3JtYXQgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB7XG4gICAgICByZXR1cm4gQWVzR2NtS2V5RmFjdG9yeS5kZXNlcmlhbGl6ZUtleUZvcm1hdChrZXlGb3JtYXQpO1xuICAgIH0gZWxzZSBpZiAoa2V5Rm9ybWF0IGluc3RhbmNlb2YgUGJBZXNHY21LZXlGb3JtYXQpIHtcbiAgICAgIHJldHVybiBrZXlGb3JtYXQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBTZWN1cml0eUV4Y2VwdGlvbignRXhwZWN0ZWQgQWVzR2NtS2V5Rm9ybWF0LXByb3RvJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgZGVzZXJpYWxpemVLZXlGb3JtYXQoa2V5Rm9ybWF0OiBVaW50OEFycmF5KTpcbiAgICAgIFBiQWVzR2NtS2V5Rm9ybWF0IHtcbiAgICBsZXQga2V5Rm9ybWF0UHJvdG86IFBiQWVzR2NtS2V5Rm9ybWF0O1xuICAgIHRyeSB7XG4gICAgICBrZXlGb3JtYXRQcm90byA9IFBiQWVzR2NtS2V5Rm9ybWF0LmRlc2VyaWFsaXplQmluYXJ5KGtleUZvcm1hdCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhyb3cgbmV3IFNlY3VyaXR5RXhjZXB0aW9uKFxuICAgICAgICAgICdDb3VsZCBub3QgcGFyc2UgdGhlIGlucHV0IGFzIGEgc2VyaWFsaXplZCBwcm90byBvZiAnICtcbiAgICAgICAgICBBZXNHY21LZXlNYW5hZ2VyLktFWV9UWVBFICsgJyBrZXkgZm9ybWF0LicpO1xuICAgIH1cbiAgICBpZiAoIWtleUZvcm1hdFByb3RvLmdldEtleVNpemUoKSkge1xuICAgICAgdGhyb3cgbmV3IFNlY3VyaXR5RXhjZXB0aW9uKFxuICAgICAgICAgICdDb3VsZCBub3QgcGFyc2UgdGhlIGlucHV0IGFzIGEgc2VyaWFsaXplZCBwcm90byBvZiAnICtcbiAgICAgICAgICBBZXNHY21LZXlNYW5hZ2VyLktFWV9UWVBFICsgJyBrZXkgZm9ybWF0LicpO1xuICAgIH1cbiAgICByZXR1cm4ga2V5Rm9ybWF0UHJvdG87XG4gIH1cbn1cblxuLyoqXG4gKiBAZmluYWxcbiAqL1xuZXhwb3J0IGNsYXNzIEFlc0djbUtleU1hbmFnZXIgaW1wbGVtZW50cyBLZXlNYW5hZ2VyLktleU1hbmFnZXI8QWVhZD4ge1xuICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBTVVBQT1JURURfUFJJTUlUSVZFID0gQWVhZDtcbiAgc3RhdGljIEtFWV9UWVBFOiBzdHJpbmcgPSAndHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUuY3J5cHRvLnRpbmsuQWVzR2NtS2V5JztcbiAgcHJpdmF0ZSByZWFkb25seSBrZXlGYWN0b3J5OiBBZXNHY21LZXlGYWN0b3J5O1xuXG4gIC8qKiBWaXNpYmxlIGZvciB0ZXN0aW5nLiAqL1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmtleUZhY3RvcnkgPSBuZXcgQWVzR2NtS2V5RmFjdG9yeSgpO1xuICB9XG5cbiAgYXN5bmMgZ2V0UHJpbWl0aXZlKFxuICAgICAgcHJpbWl0aXZlVHlwZTogQ29uc3RydWN0b3I8QWVhZD4sIGtleTogUGJLZXlEYXRhfFBiTWVzc2FnZSkge1xuICAgIGlmIChwcmltaXRpdmVUeXBlICE9IHRoaXMuZ2V0UHJpbWl0aXZlVHlwZSgpKSB7XG4gICAgICB0aHJvdyBuZXcgU2VjdXJpdHlFeGNlcHRpb24oXG4gICAgICAgICAgJ1JlcXVlc3RlZCBwcmltaXRpdmUgdHlwZSB3aGljaCBpcyBub3QgJyArXG4gICAgICAgICAgJ3N1cHBvcnRlZCBieSB0aGlzIGtleSBtYW5hZ2VyLicpO1xuICAgIH1cbiAgICBjb25zdCBrZXlQcm90byA9IEFlc0djbUtleU1hbmFnZXIuZ2V0S2V5UHJvdG8oa2V5KTtcbiAgICBBZXNHY21LZXlNYW5hZ2VyLnZhbGlkYXRlS2V5KGtleVByb3RvKTtcbiAgICByZXR1cm4gYXdhaXQgYWVzR2NtLmZyb21SYXdLZXkoYnl0ZXNBc1U4KGtleVByb3RvLmdldEtleVZhbHVlKCkpKTtcbiAgfVxuXG4gIGRvZXNTdXBwb3J0KGtleVR5cGU6IHN0cmluZykge1xuICAgIHJldHVybiBrZXlUeXBlID09PSB0aGlzLmdldEtleVR5cGUoKTtcbiAgfVxuXG4gIGdldEtleVR5cGUoKSB7XG4gICAgcmV0dXJuIEFlc0djbUtleU1hbmFnZXIuS0VZX1RZUEU7XG4gIH1cblxuICBnZXRQcmltaXRpdmVUeXBlKCkge1xuICAgIHJldHVybiBBZXNHY21LZXlNYW5hZ2VyLlNVUFBPUlRFRF9QUklNSVRJVkU7XG4gIH1cblxuICBnZXRWZXJzaW9uKCkge1xuICAgIHJldHVybiBWRVJTSU9OO1xuICB9XG5cbiAgZ2V0S2V5RmFjdG9yeSgpIHtcbiAgICByZXR1cm4gdGhpcy5rZXlGYWN0b3J5O1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgdmFsaWRhdGVLZXkoa2V5OiBQYkFlc0djbUtleSkge1xuICAgIFZhbGlkYXRvcnMudmFsaWRhdGVBZXNLZXlTaXplKGJ5dGVzTGVuZ3RoKGtleS5nZXRLZXlWYWx1ZSgpKSk7XG4gICAgVmFsaWRhdG9ycy52YWxpZGF0ZVZlcnNpb24oa2V5LmdldFZlcnNpb24oKSwgVkVSU0lPTik7XG4gIH1cblxuICAvKipcbiAgICogVGhlIGlucHV0IGtleSBpcyBlaXRoZXIgZGVzZXJpYWxpemVkIChpbiBjYXNlIHRoYXQgdGhlIGlucHV0IGlzXG4gICAqIEtleURhdGEtcHJvdG8pIG9yIGNoZWNrZWQgdG8gYmUgYW4gQWVzR2NtS2V5LXByb3RvIChvdGhlcndpc2UpLlxuICAgKlxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0S2V5UHJvdG8oa2V5TWF0ZXJpYWw6IFBiTWVzc2FnZXxQYktleURhdGEpOiBQYkFlc0djbUtleSB7XG4gICAgaWYgKGtleU1hdGVyaWFsIGluc3RhbmNlb2YgUGJLZXlEYXRhKSB7XG4gICAgICByZXR1cm4gQWVzR2NtS2V5TWFuYWdlci5nZXRLZXlQcm90b0Zyb21LZXlEYXRhKGtleU1hdGVyaWFsKTtcbiAgICB9IGVsc2UgaWYgKGtleU1hdGVyaWFsIGluc3RhbmNlb2YgUGJBZXNHY21LZXkpIHtcbiAgICAgIHJldHVybiBrZXlNYXRlcmlhbDtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IFNlY3VyaXR5RXhjZXB0aW9uKFxuICAgICAgICAgICdLZXkgdHlwZSBpcyBub3Qgc3VwcG9ydGVkLiAnICtcbiAgICAgICAgICAnVGhpcyBrZXkgbWFuYWdlciBzdXBwb3J0cyAnICsgQWVzR2NtS2V5TWFuYWdlci5LRVlfVFlQRSArICcuJyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEl0IHZhbGlkYXRlcyB0aGUga2V5IHR5cGUgYW5kIHJldHVybnMgYSBkZXNlcmlhbGl6ZWQgQWVzR2NtS2V5LXByb3RvLlxuICAgKlxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0S2V5UHJvdG9Gcm9tS2V5RGF0YShrZXlEYXRhOiBQYktleURhdGEpOiBQYkFlc0djbUtleSB7XG4gICAgaWYgKGtleURhdGEuZ2V0VHlwZVVybCgpICE9IEFlc0djbUtleU1hbmFnZXIuS0VZX1RZUEUpIHtcbiAgICAgIHRocm93IG5ldyBTZWN1cml0eUV4Y2VwdGlvbihcbiAgICAgICAgICAnS2V5IHR5cGUgJyArIGtleURhdGEuZ2V0VHlwZVVybCgpICtcbiAgICAgICAgICAnIGlzIG5vdCBzdXBwb3J0ZWQuIFRoaXMga2V5IG1hbmFnZXIgc3VwcG9ydHMgJyArXG4gICAgICAgICAgQWVzR2NtS2V5TWFuYWdlci5LRVlfVFlQRSArICcuJyk7XG4gICAgfVxuICAgIGxldCBkZXNlcmlhbGl6ZWRLZXk6IFBiQWVzR2NtS2V5O1xuICAgIHRyeSB7XG4gICAgICBkZXNlcmlhbGl6ZWRLZXkgPSBQYkFlc0djbUtleS5kZXNlcmlhbGl6ZUJpbmFyeShrZXlEYXRhLmdldFZhbHVlKCkpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRocm93IG5ldyBTZWN1cml0eUV4Y2VwdGlvbihcbiAgICAgICAgICAnQ291bGQgbm90IHBhcnNlIHRoZSBpbnB1dCBhcyBhICcgK1xuICAgICAgICAgICdzZXJpYWxpemVkIHByb3RvIG9mICcgKyBBZXNHY21LZXlNYW5hZ2VyLktFWV9UWVBFICsgJyBrZXkuJyk7XG4gICAgfVxuICAgIHJldHVybiBkZXNlcmlhbGl6ZWRLZXk7XG4gIH1cblxuICBzdGF0aWMgcmVnaXN0ZXIoKSB7XG4gICAgUmVnaXN0cnkucmVnaXN0ZXJLZXlNYW5hZ2VyKG5ldyBBZXNHY21LZXlNYW5hZ2VyKCkpO1xuICB9XG59XG4iXX0=