fix: fixed local verification & added digest support

This commit is contained in:
Daniel Hougaard
2025-04-09 01:55:26 +04:00
parent 83206aad93
commit 939b77b050
11 changed files with 409 additions and 187 deletions
+8 -7
View File
@@ -301,13 +301,10 @@ export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService, proj
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionCmekActions.Read, ProjectPermissionSub.Cmek);
const publicKey = await kmsService.getPublicKey({ kmsId: keyId });
const base64EncodedPublicKey = publicKey.toString("base64");
return { publicKey: base64EncodedPublicKey, projectId: key.projectId };
return { publicKey: publicKey.toString("base64"), projectId: key.projectId };
};
const cmekSign = async ({ keyId, data, signingAlgorithm }: TCmekSignDTO, actor: OrgServiceActor) => {
const cmekSign = async ({ keyId, data, signingAlgorithm, isDigest }: TCmekSignDTO, actor: OrgServiceActor) => {
const key = await kmsDAL.findCmekById(keyId);
if (!key) throw new NotFoundError({ message: `Key with ID "${keyId}" not found` });
@@ -329,7 +326,7 @@ export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService, proj
const sign = await kmsService.signWithKmsKey({ kmsId: keyId });
const { signature, algorithm } = await sign({ data: Buffer.from(data, "base64"), signingAlgorithm });
const { signature, algorithm } = await sign({ data: Buffer.from(data, "base64"), signingAlgorithm, isDigest });
return {
signature: signature.toString("base64"),
@@ -339,7 +336,10 @@ export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService, proj
};
};
const cmekVerify = async ({ keyId, data, signature, signingAlgorithm }: TCmekVerifyDTO, actor: OrgServiceActor) => {
const cmekVerify = async (
{ keyId, data, signature, signingAlgorithm, isDigest }: TCmekVerifyDTO,
actor: OrgServiceActor
) => {
const key = await kmsDAL.findCmekById(keyId);
if (!key) throw new NotFoundError({ message: `Key with ID "${keyId}" not found` });
@@ -362,6 +362,7 @@ export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService, proj
const verify = await kmsService.verifyWithKmsKey({ kmsId: keyId, signingAlgorithm });
const { signatureValid, algorithm } = await verify({
isDigest,
data: Buffer.from(data, "base64"),
signature: Buffer.from(signature, "base64")
});
+2
View File
@@ -57,6 +57,7 @@ export type TCmekSignDTO = {
keyId: string;
data: string;
signingAlgorithm: SigningAlgorithm;
isDigest: boolean;
};
export type TCmekVerifyDTO = {
@@ -64,4 +65,5 @@ export type TCmekVerifyDTO = {
data: string;
signature: string;
signingAlgorithm: SigningAlgorithm;
isDigest: boolean;
};
+9 -18
View File
@@ -1,5 +1,3 @@
import crypto from "node:crypto";
import slugify from "@sindresorhus/slugify";
import { Knex } from "knex";
import { z } from "zod";
@@ -452,18 +450,7 @@ export const kmsServiceFactory = ({
const keyCipher = symmetricCipherService(SymmetricKeyAlgorithm.AES_GCM_256);
const kmsKey = keyCipher.decrypt(kmsDoc.internalKms?.encryptedKey as Buffer, ROOT_ENCRYPTION_KEY);
const publicKeyBuffer = signingService(encryptionAlgorithm).getPublicKeyFromPrivateKey(kmsKey);
return (
crypto
.createPublicKey({
key: publicKeyBuffer,
format: "pem",
type: "spki"
})
// We return as a DER encoded X.509 certificate (https://datatracker.ietf.org/doc/html/rfc5280)
.export({ type: "spki", format: "der" })
);
return signingService(encryptionAlgorithm).getPublicKeyFromPrivateKey(kmsKey);
};
const signWithKmsKey = async ({ kmsId }: Pick<TSignWithKmsDTO, "kmsId">) => {
@@ -479,9 +466,13 @@ export const kmsServiceFactory = ({
const keyCipher = symmetricCipherService(SymmetricKeyAlgorithm.AES_GCM_256);
const { sign } = signingService(encryptionAlgorithm);
return ({ data, signingAlgorithm }: Pick<TSignWithKmsDTO, "data" | "signingAlgorithm">) => {
return async ({
data,
signingAlgorithm,
isDigest
}: Pick<TSignWithKmsDTO, "data" | "signingAlgorithm" | "isDigest">) => {
const kmsKey = keyCipher.decrypt(kmsDoc.internalKms?.encryptedKey as Buffer, ROOT_ENCRYPTION_KEY);
const signature = sign(data, kmsKey, signingAlgorithm);
const signature = await sign(data, kmsKey, signingAlgorithm, isDigest);
return Promise.resolve({ signature, algorithm: signingAlgorithm });
};
@@ -503,11 +494,11 @@ export const kmsServiceFactory = ({
const keyCipher = symmetricCipherService(SymmetricKeyAlgorithm.AES_GCM_256);
const { verify, getPublicKeyFromPrivateKey } = signingService(encryptionAlgorithm);
return ({ data, signature }: Pick<TVerifyWithKmsDTO, "data" | "signature">) => {
return async ({ data, signature, isDigest }: Pick<TVerifyWithKmsDTO, "data" | "signature" | "isDigest">) => {
const kmsKey = keyCipher.decrypt(kmsDoc.internalKms?.encryptedKey as Buffer, ROOT_ENCRYPTION_KEY);
const publicKey = getPublicKeyFromPrivateKey(kmsKey);
const signatureValid = verify(data, signature, publicKey, signingAlgorithm);
const signatureValid = await verify(data, signature, publicKey, signingAlgorithm, isDigest);
return Promise.resolve({ signatureValid, algorithm: signingAlgorithm });
};
};
+2
View File
@@ -52,6 +52,7 @@ export type TSignWithKmsDTO = {
kmsId: string;
data: Buffer;
signingAlgorithm: SigningAlgorithm;
isDigest: boolean;
};
export type TVerifyWithKmsDTO = {
@@ -59,6 +60,7 @@ export type TVerifyWithKmsDTO = {
data: Buffer;
signature: Buffer;
signingAlgorithm: SigningAlgorithm;
isDigest: boolean;
};
export type TEncryptionWithKeyDTO = {