fix: improved root kms encryption methods

This commit is contained in:
Daniel Hougaard
2024-09-30 22:51:02 +04:00
parent d79099946a
commit 1a2495a95c
4 changed files with 25 additions and 40 deletions
+8 -8
View File
@@ -208,20 +208,20 @@ export const kmsServiceFactory = ({
return org.kmsDefaultKeyId; return org.kmsDefaultKeyId;
}; };
const encryptWithRootKey = async () => { const encryptWithRootKey = () => {
const cipher = symmetricCipherService(SymmetricEncryption.AES_GCM_256); const cipher = symmetricCipherService(SymmetricEncryption.AES_GCM_256);
return ({ plainText }: { plainText: Buffer }) => {
const encryptedPlainTextBlob = cipher.encrypt(plainText, ROOT_ENCRYPTION_KEY);
return Promise.resolve({ cipherTextBlob: encryptedPlainTextBlob }); return (plainTextBuffer: Buffer) => {
const encryptedBuffer = cipher.encrypt(plainTextBuffer, ROOT_ENCRYPTION_KEY);
return encryptedBuffer;
}; };
}; };
const decryptWithRootKey = async () => { const decryptWithRootKey = () => {
const cipher = symmetricCipherService(SymmetricEncryption.AES_GCM_256); const cipher = symmetricCipherService(SymmetricEncryption.AES_GCM_256);
return ({ cipherTextBlob }: { cipherTextBlob: Buffer }) => {
const decryptedBlob = cipher.decrypt(cipherTextBlob, ROOT_ENCRYPTION_KEY); return (cipherTextBuffer: Buffer) => {
return Promise.resolve(decryptedBlob); return cipher.decrypt(cipherTextBuffer, ROOT_ENCRYPTION_KEY);
}; };
}; };
@@ -65,11 +65,9 @@ export const secretSharingServiceFactory = ({
throw new BadRequestError({ message: "Shared secret value too long" }); throw new BadRequestError({ message: "Shared secret value too long" });
} }
const encryptWithRoot = await kmsService.encryptWithRootKey(); const encryptWithRoot = kmsService.encryptWithRootKey();
const encryptedSecret = await encryptWithRoot({ const encryptedSecret = encryptWithRoot(Buffer.from(secretValue));
plainText: Buffer.from(secretValue)
});
const hashedHex = crypto.createHash("sha256").update(secretValue).digest("hex").substring(0, 13); const hashedHex = crypto.createHash("sha256").update(secretValue).digest("hex").substring(0, 13);
const hashedPassword = password ? await bcrypt.hash(password, 10) : null; const hashedPassword = password ? await bcrypt.hash(password, 10) : null;
@@ -77,10 +75,8 @@ export const secretSharingServiceFactory = ({
iv: null, iv: null,
tag: null, tag: null,
encryptedValue: null, encryptedValue: null,
encryptedSecret,
encryptedSecret: encryptedSecret.cipherTextBlob,
hashedHex, hashedHex,
name, name,
password: hashedPassword, password: hashedPassword,
expiresAt: new Date(expiresAt), expiresAt: new Date(expiresAt),
@@ -117,10 +113,8 @@ export const secretSharingServiceFactory = ({
throw new BadRequestError({ message: "Shared secret value too long" }); throw new BadRequestError({ message: "Shared secret value too long" });
} }
const encryptWithRoot = await kmsService.encryptWithRootKey(); const encryptWithRoot = kmsService.encryptWithRootKey();
const encrypted = await encryptWithRoot({ const encryptedSecret = encryptWithRoot(Buffer.from(secretValue));
plainText: Buffer.from(secretValue)
});
const hashedHex = crypto.createHash("sha256").update(secretValue).digest("hex").substring(0, 13); const hashedHex = crypto.createHash("sha256").update(secretValue).digest("hex").substring(0, 13);
const hashedPassword = password ? await bcrypt.hash(password, 10) : null; const hashedPassword = password ? await bcrypt.hash(password, 10) : null;
@@ -130,7 +124,7 @@ export const secretSharingServiceFactory = ({
iv: null, iv: null,
tag: null, tag: null,
hashedHex, hashedHex,
encryptedSecret: encrypted.cipherTextBlob, encryptedSecret,
password: hashedPassword, password: hashedPassword,
expiresAt: new Date(expiresAt), expiresAt: new Date(expiresAt),
@@ -242,11 +236,8 @@ export const secretSharingServiceFactory = ({
// If encryptedSecret is set, we know that this secret has been encrypted using KMS, and we can therefore do server-side decryption. // If encryptedSecret is set, we know that this secret has been encrypted using KMS, and we can therefore do server-side decryption.
let decryptedSecretValue: Buffer | undefined; let decryptedSecretValue: Buffer | undefined;
if (sharedSecret.encryptedSecret) { if (sharedSecret.encryptedSecret) {
const decrypt = await kmsService.decryptWithRootKey(); const decryptWithRoot = kmsService.decryptWithRootKey();
decryptedSecretValue = decryptWithRoot(sharedSecret.encryptedSecret);
decryptedSecretValue = await decrypt({
cipherTextBlob: sharedSecret.encryptedSecret
});
} }
// decrement when we are sure the user will view secret. // decrement when we are sure the user will view secret.
+3 -5
View File
@@ -141,16 +141,14 @@ export const slackServiceFactory = ({
let slackClientId = appCfg.WORKFLOW_SLACK_CLIENT_ID as string; let slackClientId = appCfg.WORKFLOW_SLACK_CLIENT_ID as string;
let slackClientSecret = appCfg.WORKFLOW_SLACK_CLIENT_SECRET as string; let slackClientSecret = appCfg.WORKFLOW_SLACK_CLIENT_SECRET as string;
const decrypt = await kmsService.decryptWithRootKey(); const decrypt = kmsService.decryptWithRootKey();
if (serverCfg.encryptedSlackClientId) { if (serverCfg.encryptedSlackClientId) {
slackClientId = (await decrypt({ cipherTextBlob: Buffer.from(serverCfg.encryptedSlackClientId) })).toString(); slackClientId = decrypt(Buffer.from(serverCfg.encryptedSlackClientId)).toString();
} }
if (serverCfg.encryptedSlackClientSecret) { if (serverCfg.encryptedSlackClientSecret) {
slackClientSecret = ( slackClientSecret = decrypt(Buffer.from(serverCfg.encryptedSlackClientSecret)).toString();
await decrypt({ cipherTextBlob: Buffer.from(serverCfg.encryptedSlackClientSecret) })
).toString();
} }
if (!slackClientId || !slackClientSecret) { if (!slackClientId || !slackClientSecret) {
@@ -122,20 +122,16 @@ export const superAdminServiceFactory = ({
} }
} }
const encryptWithRoot = await kmsService.encryptWithRootKey(); const encryptWithRoot = kmsService.encryptWithRootKey();
if (data.slackClientId) { if (data.slackClientId) {
const { cipherTextBlob: encryptedClientId } = await encryptWithRoot({ const encryptedClientId = encryptWithRoot(Buffer.from(data.slackClientId));
plainText: Buffer.from(data.slackClientId)
});
updatedData.encryptedSlackClientId = encryptedClientId; updatedData.encryptedSlackClientId = encryptedClientId;
updatedData.slackClientId = undefined; updatedData.slackClientId = undefined;
} }
if (data.slackClientSecret) { if (data.slackClientSecret) {
const { cipherTextBlob: encryptedClientSecret } = await encryptWithRoot({ const encryptedClientSecret = encryptWithRoot(Buffer.from(data.slackClientSecret));
plainText: Buffer.from(data.slackClientSecret)
});
updatedData.encryptedSlackClientSecret = encryptedClientSecret; updatedData.encryptedSlackClientSecret = encryptedClientSecret;
updatedData.slackClientSecret = undefined; updatedData.slackClientSecret = undefined;
@@ -270,14 +266,14 @@ export const superAdminServiceFactory = ({
let clientId = ""; let clientId = "";
let clientSecret = ""; let clientSecret = "";
const decrypt = await kmsService.decryptWithRootKey(); const decrypt = kmsService.decryptWithRootKey();
if (serverCfg.encryptedSlackClientId) { if (serverCfg.encryptedSlackClientId) {
clientId = (await decrypt({ cipherTextBlob: serverCfg.encryptedSlackClientId })).toString(); clientId = decrypt(serverCfg.encryptedSlackClientId).toString();
} }
if (serverCfg.encryptedSlackClientSecret) { if (serverCfg.encryptedSlackClientSecret) {
clientSecret = (await decrypt({ cipherTextBlob: serverCfg.encryptedSlackClientSecret })).toString(); clientSecret = decrypt(serverCfg.encryptedSlackClientSecret).toString();
} }
return { return {