feat: updated backward compatiable enc key

This commit is contained in:
Akhil Mohan
2023-10-30 22:41:15 +05:30
parent 6280d7eb34
commit c6846f8bf1
3 changed files with 53 additions and 23 deletions
@@ -6,7 +6,11 @@ import { getWebhookPayload, triggerWebhookRequest } from "../../services/Webhook
import { BadRequestError, ResourceNotFoundError } from "../../utils/errors"; import { BadRequestError, ResourceNotFoundError } from "../../utils/errors";
import { EEAuditLogService } from "../../ee/services"; import { EEAuditLogService } from "../../ee/services";
import { EventType } from "../../ee/models"; import { EventType } from "../../ee/models";
import { ALGORITHM_AES_256_GCM, ENCODING_SCHEME_BASE64 } from "../../variables"; import {
ALGORITHM_AES_256_GCM,
ENCODING_SCHEME_BASE64,
ENCODING_SCHEME_UTF8
} from "../../variables";
import { validateRequest } from "../../helpers/validation"; import { validateRequest } from "../../helpers/validation";
import * as reqValidator from "../../validation/webhooks"; import * as reqValidator from "../../validation/webhooks";
import { import {
@@ -15,6 +19,7 @@ import {
getUserProjectPermissions getUserProjectPermissions
} from "../../ee/services/ProjectRoleService"; } from "../../ee/services/ProjectRoleService";
import { ForbiddenError } from "@casl/ability"; import { ForbiddenError } from "@casl/ability";
import { encryptSymmetric128BitHexKeyUTF8 } from "../../utils/crypto";
export const createWebhook = async (req: Request, res: Response) => { export const createWebhook = async (req: Request, res: Response) => {
const { const {
@@ -31,20 +36,31 @@ export const createWebhook = async (req: Request, res: Response) => {
workspace: workspaceId, workspace: workspaceId,
environment, environment,
secretPath, secretPath,
url: webhookUrl, url: webhookUrl
algorithm: ALGORITHM_AES_256_GCM,
keyEncoding: ENCODING_SCHEME_BASE64
}); });
if (webhookSecretKey) { if (webhookSecretKey) {
let encryptionKey = await getRootEncryptionKey(); const encryptionKey = await getEncryptionKey();
if (!encryptionKey) { const rootEncryptionKey = await getRootEncryptionKey();
encryptionKey = await getEncryptionKey();
} if (rootEncryptionKey) {
const { ciphertext, iv, tag } = client.encryptSymmetric(webhookSecretKey, encryptionKey); const { ciphertext, iv, tag } = client.encryptSymmetric(webhookSecretKey, rootEncryptionKey);
webhook.iv = iv; webhook.iv = iv;
webhook.tag = tag; webhook.tag = tag;
webhook.encryptedSecretKey = ciphertext; webhook.encryptedSecretKey = ciphertext;
webhook.algorithm = ALGORITHM_AES_256_GCM;
webhook.keyEncoding = ENCODING_SCHEME_BASE64;
} else if (encryptionKey) {
const { ciphertext, iv, tag } = encryptSymmetric128BitHexKeyUTF8({
plaintext: webhookSecretKey,
key: encryptionKey
});
webhook.iv = iv;
webhook.tag = tag;
webhook.encryptedSecretKey = ciphertext;
webhook.algorithm = ALGORITHM_AES_256_GCM;
webhook.keyEncoding = ENCODING_SCHEME_UTF8;
}
} }
await webhook.save(); await webhook.save();
-2
View File
@@ -65,13 +65,11 @@ const WebhookSchema = new Schema<IWebhook>(
// the encryption algorithm used // the encryption algorithm used
type: String, type: String,
enum: [ALGORITHM_AES_256_GCM], enum: [ALGORITHM_AES_256_GCM],
required: true,
select: false select: false
}, },
keyEncoding: { keyEncoding: {
type: String, type: String,
enum: [ENCODING_SCHEME_UTF8, ENCODING_SCHEME_BASE64], enum: [ENCODING_SCHEME_UTF8, ENCODING_SCHEME_BASE64],
required: true,
select: false select: false
} }
}, },
+20 -4
View File
@@ -2,26 +2,42 @@ import axios from "axios";
import crypto from "crypto"; import crypto from "crypto";
import { Types } from "mongoose"; import { Types } from "mongoose";
import picomatch from "picomatch"; import picomatch from "picomatch";
import { client, getRootEncryptionKey } from "../config"; import { client, getEncryptionKey, getRootEncryptionKey } from "../config";
import { IWebhook, Webhook } from "../models"; import { IWebhook, Webhook } from "../models";
import { decryptSymmetric128BitHexKeyUTF8 } from "../utils/crypto";
import { ENCODING_SCHEME_BASE64, ENCODING_SCHEME_UTF8 } from "../variables";
export const triggerWebhookRequest = async ( export const triggerWebhookRequest = async (
{ url, encryptedSecretKey, iv, tag }: IWebhook, { url, encryptedSecretKey, iv, tag, keyEncoding }: IWebhook,
payload: Record<string, unknown> payload: Record<string, unknown>
) => { ) => {
const headers: Record<string, string> = {}; const headers: Record<string, string> = {};
payload["timestamp"] = Date.now(); payload["timestamp"] = Date.now();
if (encryptedSecretKey) { if (encryptedSecretKey) {
const encryptionKey = await getEncryptionKey();
const rootEncryptionKey = await getRootEncryptionKey(); const rootEncryptionKey = await getRootEncryptionKey();
const secretKey = client.decryptSymmetric(encryptedSecretKey, rootEncryptionKey, iv, tag); let secretKey;
if (rootEncryptionKey && keyEncoding === ENCODING_SCHEME_BASE64) {
// case: encoding scheme is base64
secretKey = client.decryptSymmetric(encryptedSecretKey, rootEncryptionKey, iv, tag);
} else if (encryptionKey && keyEncoding === ENCODING_SCHEME_UTF8) {
// case: encoding scheme is utf8
secretKey = decryptSymmetric128BitHexKeyUTF8({
ciphertext: encryptedSecretKey,
iv: iv,
tag: tag,
key: encryptionKey
});
}
if (secretKey) {
const webhookSign = crypto const webhookSign = crypto
.createHmac("sha256", secretKey) .createHmac("sha256", secretKey)
.update(JSON.stringify(payload)) .update(JSON.stringify(payload))
.digest("hex"); .digest("hex");
headers["x-infisical-signature"] = `t=${payload["timestamp"]};${webhookSign}`; headers["x-infisical-signature"] = `t=${payload["timestamp"]};${webhookSign}`;
} }
}
const req = await axios.post(url, payload, { headers }); const req = await axios.post(url, payload, { headers });
return req; return req;
}; };