diff --git a/backend/src/services/certificate-authority/certificate-authority-fns.test.ts b/backend/src/services/certificate-authority/certificate-authority-fns.test.ts index 6006cded4..870055711 100644 --- a/backend/src/services/certificate-authority/certificate-authority-fns.test.ts +++ b/backend/src/services/certificate-authority/certificate-authority-fns.test.ts @@ -28,6 +28,17 @@ describe("signatureAlgorithmToAlgCfg", () => { }); }); + it("should handle RSA-SHA256 with RSA_3072 correctly", () => { + const result = signatureAlgorithmToAlgCfg("RSA-SHA256", CertKeyAlgorithm.RSA_3072); + + expect(result).toEqual({ + name: "RSASSA-PKCS1-v1_5", + hash: "SHA-256", + publicExponent: new Uint8Array([1, 0, 1]), + modulusLength: 3072 + }); + }); + it("should handle RSA-SHA512 correctly", () => { const result = signatureAlgorithmToAlgCfg("RSA-SHA512", CertKeyAlgorithm.RSA_2048); diff --git a/backend/src/services/certificate-authority/certificate-authority-fns.ts b/backend/src/services/certificate-authority/certificate-authority-fns.ts index 24b2aa2cf..aff81dcc5 100644 --- a/backend/src/services/certificate-authority/certificate-authority-fns.ts +++ b/backend/src/services/certificate-authority/certificate-authority-fns.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-nested-ternary */ import * as x509 from "@peculiar/x509"; import { crypto } from "@app/lib/crypto/cryptography"; @@ -68,6 +69,13 @@ export const parseDistinguishedName = (dn: string): TDNParts => { export const keyAlgorithmToAlgCfg = (keyAlgorithm: CertKeyAlgorithm) => { switch (keyAlgorithm) { + case CertKeyAlgorithm.RSA_3072: + return { + name: "RSASSA-PKCS1-v1_5", + hash: "SHA-256", + publicExponent: new Uint8Array([1, 0, 1]), + modulusLength: 3072 + }; case CertKeyAlgorithm.RSA_4096: return { name: "RSASSA-PKCS1-v1_5", @@ -137,7 +145,8 @@ export const signatureAlgorithmToAlgCfg = (signatureAlgorithm: string, keyAlgori name: "RSASSA-PKCS1-v1_5", hash: normalizedHash || "SHA-256", publicExponent: new Uint8Array([1, 0, 1]), - modulusLength: keyAlgorithm === CertKeyAlgorithm.RSA_4096 ? 4096 : 2048 + modulusLength: + keyAlgorithm === CertKeyAlgorithm.RSA_4096 ? 4096 : keyAlgorithm === CertKeyAlgorithm.RSA_3072 ? 3072 : 2048 }; case "ECDSA": // eslint-disable-next-line no-case-declarations @@ -177,7 +186,8 @@ export const getCaCredentials = async ({ certificateAuthorityDAL, certificateAuthoritySecretDAL, projectDAL, - kmsService + kmsService, + signatureAlgorithm }: TGetCaCredentialsDTO) => { const ca = await certificateAuthorityDAL.findByIdWithAssociatedCa(caId); if (!ca?.internalCa?.id) throw new NotFoundError({ message: `Internal CA with ID '${caId}' not found` }); @@ -198,7 +208,7 @@ export const getCaCredentials = async ({ cipherTextBlob: caSecret.encryptedPrivateKey }); - const alg = keyAlgorithmToAlgCfg(ca.internalCa.keyAlgorithm as CertKeyAlgorithm); + const alg = signatureAlgorithm || keyAlgorithmToAlgCfg(ca.internalCa.keyAlgorithm as CertKeyAlgorithm); const skObj = crypto.nativeCrypto.createPrivateKey({ key: decryptedPrivateKey, format: "der", type: "pkcs8" }); const caPrivateKey = await crypto.nativeCrypto.subtle.importKey( "pkcs8", diff --git a/backend/src/services/certificate-authority/internal/internal-certificate-authority-service.ts b/backend/src/services/certificate-authority/internal/internal-certificate-authority-service.ts index 383b34c5f..8bf6ff075 100644 --- a/backend/src/services/certificate-authority/internal/internal-certificate-authority-service.ts +++ b/backend/src/services/certificate-authority/internal/internal-certificate-authority-service.ts @@ -1322,7 +1322,8 @@ export const internalCertificateAuthorityServiceFactory = ({ certificateAuthorityDAL, certificateAuthoritySecretDAL, projectDAL, - kmsService + kmsService, + signatureAlgorithm: signingAlg }); const caCrl = await certificateAuthorityCrlDAL.findOne({ caSecretId: caSecret.id }); diff --git a/backend/src/services/certificate-authority/internal/internal-certificate-authority-types.ts b/backend/src/services/certificate-authority/internal/internal-certificate-authority-types.ts index d402b20c1..2a9f53cc8 100644 --- a/backend/src/services/certificate-authority/internal/internal-certificate-authority-types.ts +++ b/backend/src/services/certificate-authority/internal/internal-certificate-authority-types.ts @@ -195,6 +195,7 @@ export type TGetCaCredentialsDTO = { certificateAuthoritySecretDAL: Pick; projectDAL: Pick; kmsService: Pick; + signatureAlgorithm?: RsaHashedImportParams | EcKeyImportParams; }; export type TGetCaCertChainsDTO = { diff --git a/backend/src/services/certificate-template-v2/certificate-template-v2-service.ts b/backend/src/services/certificate-template-v2/certificate-template-v2-service.ts index 4ea0a195d..8873e0587 100644 --- a/backend/src/services/certificate-template-v2/certificate-template-v2-service.ts +++ b/backend/src/services/certificate-template-v2/certificate-template-v2-service.ts @@ -174,9 +174,11 @@ export const certificateTemplateV2ServiceFactory = ({ const mapTemplateKeyAlgorithmToApi = (templateFormat: string): string => { const mapping: Record = { "RSA-2048": "RSA_2048", + "RSA-3072": "RSA_3072", "RSA-4096": "RSA_4096", "ECDSA-P256": "EC_prime256v1", - "ECDSA-P384": "EC_secp384r1" + "ECDSA-P384": "EC_secp384r1", + "ECDSA-P521": "EC_secp521r1" }; return mapping[templateFormat] || templateFormat; }; diff --git a/backend/src/services/certificate/certificate-types.ts b/backend/src/services/certificate/certificate-types.ts index fac7913a7..b747314b3 100644 --- a/backend/src/services/certificate/certificate-types.ts +++ b/backend/src/services/certificate/certificate-types.ts @@ -13,9 +13,11 @@ export enum CertStatus { export enum CertKeyAlgorithm { RSA_2048 = "RSA_2048", + RSA_3072 = "RSA_3072", RSA_4096 = "RSA_4096", ECDSA_P256 = "EC_prime256v1", - ECDSA_P384 = "EC_secp384r1" + ECDSA_P384 = "EC_secp384r1", + ECDSA_P521 = "EC_secp521r1" } export enum CertSignatureAlgorithm {