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);
}
}