Implement template check for external ca

# Conflicts:
#	backend/src/ee/services/pki-acme/pki-acme-service.ts
#	backend/src/server/routes/index.ts
This commit is contained in:
Fang-Pen Lin
2025-12-02 20:10:48 -08:00
parent 4ec0a92888
commit 11ccfb6da2
2 changed files with 21 additions and 2 deletions
@@ -37,6 +37,8 @@ import {
EnrollmentType, EnrollmentType,
TCertificateProfileWithConfigs TCertificateProfileWithConfigs
} from "@app/services/certificate-profile/certificate-profile-types"; } from "@app/services/certificate-profile/certificate-profile-types";
import { TCertificateTemplateV2DALFactory } from "@app/services/certificate-template-v2/certificate-template-v2-dal";
import { TCertificateTemplateV2ServiceFactory } from "@app/services/certificate-template-v2/certificate-template-v2-service";
import { TCertificateV3ServiceFactory } from "@app/services/certificate-v3/certificate-v3-service"; import { TCertificateV3ServiceFactory } from "@app/services/certificate-v3/certificate-v3-service";
import { TKmsServiceFactory } from "@app/services/kms/kms-service"; import { TKmsServiceFactory } from "@app/services/kms/kms-service";
import { TProjectDALFactory } from "@app/services/project/project-dal"; import { TProjectDALFactory } from "@app/services/project/project-dal";
@@ -101,6 +103,7 @@ type TPkiAcmeServiceFactoryDep = {
certificateProfileDAL: Pick<TCertificateProfileDALFactory, "findByIdWithOwnerOrgId" | "findByIdWithConfigs">; certificateProfileDAL: Pick<TCertificateProfileDALFactory, "findByIdWithOwnerOrgId" | "findByIdWithConfigs">;
certificateBodyDAL: Pick<TCertificateBodyDALFactory, "findOne" | "create">; certificateBodyDAL: Pick<TCertificateBodyDALFactory, "findOne" | "create">;
certificateSecretDAL: Pick<TCertificateSecretDALFactory, "findOne" | "create">; certificateSecretDAL: Pick<TCertificateSecretDALFactory, "findOne" | "create">;
certificateTemplateV2DAL: Pick<TCertificateTemplateV2DALFactory, "findById">;
acmeAccountDAL: Pick< acmeAccountDAL: Pick<
TPkiAcmeAccountDALFactory, TPkiAcmeAccountDALFactory,
"findByProjectIdAndAccountId" | "findByProfileIdAndPublicKeyThumbprintAndAlg" | "create" "findByProjectIdAndAccountId" | "findByProfileIdAndPublicKeyThumbprintAndAlg" | "create"
@@ -127,6 +130,7 @@ type TPkiAcmeServiceFactoryDep = {
>; >;
licenseService: Pick<TLicenseServiceFactory, "getPlan">; licenseService: Pick<TLicenseServiceFactory, "getPlan">;
certificateV3Service: Pick<TCertificateV3ServiceFactory, "signCertificateFromProfile">; certificateV3Service: Pick<TCertificateV3ServiceFactory, "signCertificateFromProfile">;
certificateTemplateV2Service: Pick<TCertificateTemplateV2ServiceFactory, "validateCertificateRequest">;
acmeChallengeService: Pick<TPkiAcmeChallengeServiceFactory, "markChallengeAsReady">; acmeChallengeService: Pick<TPkiAcmeChallengeServiceFactory, "markChallengeAsReady">;
pkiAcmeQueueService: Pick<TPkiAcmeQueueServiceFactory, "queueChallengeValidation">; pkiAcmeQueueService: Pick<TPkiAcmeQueueServiceFactory, "queueChallengeValidation">;
}; };
@@ -140,6 +144,7 @@ export const pkiAcmeServiceFactory = ({
certificateProfileDAL, certificateProfileDAL,
certificateBodyDAL, certificateBodyDAL,
certificateSecretDAL, certificateSecretDAL,
certificateTemplateV2DAL,
acmeAccountDAL, acmeAccountDAL,
acmeOrderDAL, acmeOrderDAL,
acmeAuthDAL, acmeAuthDAL,
@@ -149,6 +154,8 @@ export const pkiAcmeServiceFactory = ({
kmsService, kmsService,
licenseService, licenseService,
certificateV3Service, certificateV3Service,
certificateTemplateV2Service,
acmeChallengeService
acmeChallengeService, acmeChallengeService,
pkiAcmeQueueService pkiAcmeQueueService
}: TPkiAcmeServiceFactoryDep): TPkiAcmeServiceFactory => { }: TPkiAcmeServiceFactoryDep): TPkiAcmeServiceFactory => {
@@ -772,8 +779,18 @@ export const pkiAcmeServiceFactory = ({
const { certificateAuthority } = (await certificateProfileDAL.findByIdWithConfigs(profileId, tx))!; const { certificateAuthority } = (await certificateProfileDAL.findByIdWithConfigs(profileId, tx))!;
const csrObj = new x509.Pkcs10CertificateRequest(csr); const csrObj = new x509.Pkcs10CertificateRequest(csr);
const csrPem = csrObj.toString("pem"); const csrPem = csrObj.toString("pem");
// TODO: for internal CA, we rely on the internal certificate authority service to check CSR against the template
// we should check the CSR against the template here const template = await certificateTemplateV2DAL.findById(profile.certificateTemplateId);
if (!template) {
throw new NotFoundError({ message: "Certificate template not found" });
}
const validationResult = await certificateTemplateV2Service.validateCertificateRequest(
template.id,
certificateRequest
);
if (!validationResult.isValid) {
throw new AcmeBadCSRError({ message: `Invalid CSR: ${validationResult.errors.join(", ")}` });
}
// TODO: this is pretty slow, and we are holding the transaction open for a long time, // TODO: this is pretty slow, and we are holding the transaction open for a long time,
// we should queue the certificate issuance to a background job instead // we should queue the certificate issuance to a background job instead
const cert = await orderCertificate( const cert = await orderCertificate(
+2
View File
@@ -2301,6 +2301,7 @@ export const registerRoutes = async (
certificateProfileDAL, certificateProfileDAL,
certificateBodyDAL, certificateBodyDAL,
certificateSecretDAL, certificateSecretDAL,
certificateTemplateV2DAL,
acmeAccountDAL, acmeAccountDAL,
acmeOrderDAL, acmeOrderDAL,
acmeAuthDAL, acmeAuthDAL,
@@ -2310,6 +2311,7 @@ export const registerRoutes = async (
kmsService, kmsService,
licenseService, licenseService,
certificateV3Service, certificateV3Service,
certificateTemplateV2Service,
acmeChallengeService, acmeChallengeService,
pkiAcmeQueueService pkiAcmeQueueService
}); });