UNPKG

5.23 kBJavaScriptView Raw
1"use strict";
2/**
3 * Provides encryption and decryption methods with a consistent API but
4 * differing mechanisms for dealing with encryption keys.
5 */
6var __importDefault = (this && this.__importDefault) || function (mod) {
7 return (mod && mod.__esModule) ? mod : { "default": mod };
8};
9Object.defineProperty(exports, "__esModule", { value: true });
10exports.DefaultProvider = exports.S3KeyPairProvider = void 0;
11const noop_1 = __importDefault(require("lodash/noop"));
12const aws_sdk_1 = __importDefault(require("aws-sdk"));
13const node_forge_1 = __importDefault(require("node-forge"));
14const util_1 = require("./util");
15const test_utils_1 = require("./test-utils");
16var kms_1 = require("./kms");
17Object.defineProperty(exports, "KMS", { enumerable: true, get: function () { return kms_1.KMS; } });
18const getLocalStackHost = () => {
19 if (process.env.LOCAL_S3_HOST) {
20 return process.env.LOCAL_S3_HOST;
21 }
22 if (!process.env.LOCALSTACK_HOST) {
23 throw new Error('The LOCALSTACK_HOST environment variable is not set.');
24 }
25 return process.env.LOCALSTACK_HOST;
26};
27const buildS3Client = () => {
28 var _a;
29 const region = (_a = process.env.AWS_DEFAULT_REGION) !== null && _a !== void 0 ? _a : 'us-east-1';
30 aws_sdk_1.default.config.update({ region });
31 // Workaround upload hangs. See: https://github.com/andrewrk/node-s3-client/issues/74'
32 // @ts-expect-error
33 aws_sdk_1.default.util.update(aws_sdk_1.default.S3.prototype, { addExpect100Continue: noop_1.default });
34 aws_sdk_1.default.config.setPromisesDependency(Promise);
35 const options = {
36 apiVersion: '2006-03-01',
37 };
38 if (test_utils_1.inTestMode()) {
39 options.accessKeyId = 'my-access-key-id';
40 options.endpoint = `http://${getLocalStackHost()}:4572`;
41 options.region = 'us-east-1';
42 options.s3ForcePathStyle = true;
43 options.secretAccessKey = 'my-secret-access-key';
44 }
45 return new aws_sdk_1.default.S3(options);
46};
47const getTextObject = async (bucket, key) => {
48 const s3 = buildS3Client();
49 const { Body } = await s3.getObject({
50 Bucket: bucket,
51 Key: key,
52 }).promise();
53 return Body ? Body.toString() : undefined;
54};
55const retrieveKey = async (keyId, bucket = process.env.system_bucket, stack = process.env.stackName) => {
56 if (!bucket) {
57 throw new Error('Unable to determine bucket to retrieve key from');
58 }
59 if (!stack) {
60 throw new Error('Unable to determine stack to retrieve key for');
61 }
62 const key = `${stack}/crypto/${keyId}`;
63 try {
64 return await getTextObject(bucket, key);
65 }
66 catch (error) {
67 throw new Error(`Failed to retrieve S3KeyPair key from s3://${bucket}/${key}: ${error.message}`);
68 }
69};
70/**
71 * Provides encryption and decryption methods using a keypair stored in S3
72 */
73class S3KeyPairProvider {
74 /**
75 * Encrypt the given string using the given public key stored in the system_bucket.
76 *
77 * @param {string} str - The string to encrypt
78 * @param {string} [keyId] - The name of the public key to use for encryption
79 * @param {string} [bucket] - the optional bucket name. if not provided will
80 * use env variable "system_bucket"
81 * @param {stack} [stack] - the optional stack name. if not provided will
82 * use env variable "stackName"
83 * @returns {Promise.<string>} the encrypted string
84 */
85 static async encrypt(str, keyId = 'public.pub', bucket, stack) {
86 util_1.deprecate('@cumulus/common/key-pair-provider', '1.17.0', '@cumulus/aws-client/KMS.encrypt');
87 // Download the publickey
88 const pki = node_forge_1.default.pki;
89 const pub = await retrieveKey(keyId, bucket, stack);
90 if (!pub) {
91 throw new Error('Unable to retrieve public key');
92 }
93 const publicKey = pki.publicKeyFromPem(pub);
94 return node_forge_1.default.util.encode64(publicKey.encrypt(str));
95 }
96 /**
97 * Decrypt the given string using a private key stored in S3
98 *
99 * @param {string} str - The string to decrypt
100 * @param {string} [keyId] - The name of the public key to use for decryption
101 * @param {string} [bucket] - the optional bucket name. Defaults to the value
102 * of the "system_bucket" environment variable
103 * @param {string} [stack] - the optional stack name. Defaults to the value of
104 * the "stackName" environment variable
105 * @returns {Promise.<string>} the decrypted string
106 */
107 static async decrypt(str, keyId = 'private.pem', bucket, stack) {
108 util_1.deprecate('@cumulus/common/key-pair-provider', '1.17.0', '@cumulus/aws-client/KMS.decryptBase64String');
109 const pki = node_forge_1.default.pki;
110 const priv = await retrieveKey(keyId, bucket, stack);
111 if (!priv) {
112 throw new Error('Unable to retrieve private key');
113 }
114 const decoded = node_forge_1.default.util.decode64(str);
115 const privateKey = pki.privateKeyFromPem(priv);
116 return privateKey.decrypt(decoded);
117 }
118}
119exports.S3KeyPairProvider = S3KeyPairProvider;
120exports.DefaultProvider = S3KeyPairProvider;
121//# sourceMappingURL=key-pair-provider.js.map
\No newline at end of file