async function _createNewKey()

in lib/custom-resource-handlers/src/pgp-secret.ts [72:115]


async function _createNewKey(event: cfn.CreateEvent | cfn.UpdateEvent, context: lambda.Context): Promise<ResourceAttributes> {
  const passPhrase = crypto.randomBytes(32).toString('base64');
  const tempDir = await mkdtemp(path.join(os.tmpdir(), 'OpenPGP-'));
  try {
    process.env.GNUPGHOME = tempDir;

    const keyConfig = path.join(tempDir, 'key.config');
    await writeFile(keyConfig, [
      'Key-Type: RSA',
      `Key-Length: ${event.ResourceProperties.KeySizeBits}`,
      `Name-Real: ${event.ResourceProperties.Identity}`,
      `Name-Email: ${event.ResourceProperties.Email}`,
      `Expire-Date: ${event.ResourceProperties.Expiry}`,
      `Passphrase: ${passPhrase}`,
      '%commit',
      '%echo done',
    ].join('\n'), { encoding: 'utf8' });

    const gpgCommonArgs = [`--homedir=${tempDir}`, '--agent-program=/opt/gpg-agent'];
    await _exec('/opt/gpg', ...gpgCommonArgs, '--batch', '--gen-key', keyConfig);
    const keyMaterial = await _exec('/opt/gpg', ...gpgCommonArgs, '--batch', '--yes', '--export-secret-keys', '--armor');
    const publicKey = await _exec('/opt/gpg', ...gpgCommonArgs, '--batch', '--yes', '--export', '--armor');
    const secretOpts = {
      ClientRequestToken: context.awsRequestId,
      Description: event.ResourceProperties.Description,
      KmsKeyId: event.ResourceProperties.KeyArn,
      SecretString: JSON.stringify({
        PrivateKey: keyMaterial,
        Passphrase: passPhrase,
      }),
    };
    const secret = event.RequestType === cfn.RequestType.CREATE
      ? await secretsManager.createSecret({ ...secretOpts, Name: event.ResourceProperties.SecretName }).promise()
      : await secretsManager.updateSecret({ ...secretOpts, SecretId: event.PhysicalResourceId }).promise();

    return {
      Ref: secret.ARN!,
      SecretArn: secret.ARN!,
      PublicKey: publicKey,
    };
  } finally {
    await _rmrf(tempDir);
  }
}