Fix CA issuance blocker for profiles

This commit is contained in:
Carlos Monastyrski
2025-10-20 15:55:32 -03:00
parent 5ce39fc823
commit 686cf92233
6 changed files with 20 additions and 12 deletions
@@ -142,7 +142,7 @@ export const registerCertificateProfilesRouter = async (server: FastifyZodProvid
.object({ .object({
id: z.string(), id: z.string(),
disableBootstrapCaValidation: z.boolean(), disableBootstrapCaValidation: z.boolean(),
passphrase: z.string(), passphrase: z.string().optional(),
caChain: z.string().optional() caChain: z.string().optional()
}) })
.optional(), .optional(),
@@ -1179,7 +1179,8 @@ export const internalCertificateAuthorityServiceFactory = ({
keyUsages, keyUsages,
extendedKeyUsages, extendedKeyUsages,
signatureAlgorithm, signatureAlgorithm,
keyAlgorithm keyAlgorithm,
isFromProfile
}: TIssueCertFromCaDTO) => { }: TIssueCertFromCaDTO) => {
let ca: TCertificateAuthorityWithAssociatedCa | undefined; let ca: TCertificateAuthorityWithAssociatedCa | undefined;
let certificateTemplate: TCertificateTemplates | undefined; let certificateTemplate: TCertificateTemplates | undefined;
@@ -1226,7 +1227,7 @@ export const internalCertificateAuthorityServiceFactory = ({
if (ca.status !== CaStatus.ACTIVE) throw new BadRequestError({ message: "CA is not active" }); if (ca.status !== CaStatus.ACTIVE) throw new BadRequestError({ message: "CA is not active" });
if (!ca.internalCa.activeCaCertId) if (!ca.internalCa.activeCaCertId)
throw new BadRequestError({ message: "CA does not have a certificate installed" }); throw new BadRequestError({ message: "CA does not have a certificate installed" });
if (!ca.enableDirectIssuance && !certificateTemplate) { if (!isFromProfile && !ca.enableDirectIssuance && !certificateTemplate) {
throw new BadRequestError({ message: "Certificate template or subscriber is required for issuance" }); throw new BadRequestError({ message: "Certificate template or subscriber is required for issuance" });
} }
@@ -1355,7 +1356,7 @@ export const internalCertificateAuthorityServiceFactory = ({
// handle key usages // handle key usages
let selectedKeyUsages: CertKeyUsage[] = keyUsages ?? []; let selectedKeyUsages: CertKeyUsage[] = keyUsages ?? [];
if (keyUsages === undefined && !certificateTemplate) { if (keyUsages === undefined && !certificateTemplate) {
selectedKeyUsages = [CertKeyUsage.DIGITAL_SIGNATURE, CertKeyUsage.KEY_ENCIPHERMENT]; selectedKeyUsages = isFromProfile ? [] : [CertKeyUsage.DIGITAL_SIGNATURE, CertKeyUsage.KEY_ENCIPHERMENT];
} }
if (keyUsages === undefined && certificateTemplate) { if (keyUsages === undefined && certificateTemplate) {
@@ -1601,7 +1602,7 @@ export const internalCertificateAuthorityServiceFactory = ({
if (ca.status !== CaStatus.ACTIVE) throw new BadRequestError({ message: "CA is not active" }); if (ca.status !== CaStatus.ACTIVE) throw new BadRequestError({ message: "CA is not active" });
if (!ca.internalCa.activeCaCertId) if (!ca.internalCa.activeCaCertId)
throw new BadRequestError({ message: "CA does not have a certificate installed" }); throw new BadRequestError({ message: "CA does not have a certificate installed" });
if (!ca.enableDirectIssuance && !certificateTemplate) { if (!dto.isFromProfile && !ca.enableDirectIssuance && !certificateTemplate) {
throw new BadRequestError({ message: "Certificate template or subscriber is required for issuance" }); throw new BadRequestError({ message: "Certificate template or subscriber is required for issuance" });
} }
@@ -1731,7 +1732,7 @@ export const internalCertificateAuthorityServiceFactory = ({
if (csrKeyUsageExtension) { if (csrKeyUsageExtension) {
selectedKeyUsages = csrKeyUsages; selectedKeyUsages = csrKeyUsages;
} else { } else {
selectedKeyUsages = [CertKeyUsage.DIGITAL_SIGNATURE, CertKeyUsage.KEY_ENCIPHERMENT]; selectedKeyUsages = dto.isFromProfile ? [] : [CertKeyUsage.DIGITAL_SIGNATURE, CertKeyUsage.KEY_ENCIPHERMENT];
} }
} }
@@ -138,6 +138,7 @@ export type TIssueCertFromCaDTO = {
extendedKeyUsages?: CertExtendedKeyUsage[]; extendedKeyUsages?: CertExtendedKeyUsage[];
signatureAlgorithm?: CertSignatureAlgorithm; signatureAlgorithm?: CertSignatureAlgorithm;
keyAlgorithm?: CertKeyAlgorithm; keyAlgorithm?: CertKeyAlgorithm;
isFromProfile?: boolean;
} & Omit<TProjectPermission, "projectId">; } & Omit<TProjectPermission, "projectId">;
export type TSignCertFromCaDTO = export type TSignCertFromCaDTO =
@@ -157,6 +158,7 @@ export type TSignCertFromCaDTO =
extendedKeyUsages?: CertExtendedKeyUsage[]; extendedKeyUsages?: CertExtendedKeyUsage[];
signatureAlgorithm?: string; signatureAlgorithm?: string;
keyAlgorithm?: string; keyAlgorithm?: string;
isFromProfile?: boolean;
} }
| ({ | ({
isInternal: false; isInternal: false;
@@ -174,6 +176,7 @@ export type TSignCertFromCaDTO =
extendedKeyUsages?: CertExtendedKeyUsage[]; extendedKeyUsages?: CertExtendedKeyUsage[];
signatureAlgorithm?: string; signatureAlgorithm?: string;
keyAlgorithm?: string; keyAlgorithm?: string;
isFromProfile?: boolean;
} & Omit<TProjectPermission, "projectId">); } & Omit<TProjectPermission, "projectId">);
export type TGetCaCertificateTemplatesDTO = { export type TGetCaCertificateTemplatesDTO = {
@@ -213,7 +213,8 @@ export const certificateEstV3ServiceFactory = ({
const { certificate } = await internalCertificateAuthorityService.signCertFromCa({ const { certificate } = await internalCertificateAuthorityService.signCertFromCa({
isInternal: true, isInternal: true,
caId: profile.caId, caId: profile.caId,
csr csr,
isFromProfile: true
}); });
return convertRawCertsToPkcs7([certificate.rawData]); return convertRawCertsToPkcs7([certificate.rawData]);
@@ -332,7 +333,8 @@ export const certificateEstV3ServiceFactory = ({
const { certificate } = await internalCertificateAuthorityService.signCertFromCa({ const { certificate } = await internalCertificateAuthorityService.signCertFromCa({
isInternal: true, isInternal: true,
caId: profile.caId, caId: profile.caId,
csr csr,
isFromProfile: true
}); });
return convertRawCertsToPkcs7([certificate.rawData]); return convertRawCertsToPkcs7([certificate.rawData]);
@@ -123,7 +123,7 @@ export const certificateProfileDALFactory = (db: TDbClient) => {
? ({ ? ({
id: result.estConfigId, id: result.estConfigId,
disableBootstrapCaValidation: !!result.estConfigDisableBootstrapCaValidation, disableBootstrapCaValidation: !!result.estConfigDisableBootstrapCaValidation,
passphrase: "", passphrase: result.estConfigHashedPassphrase,
caChain: result.estConfigEncryptedCaChain ? result.estConfigEncryptedCaChain.toString("utf8") : "" caChain: result.estConfigEncryptedCaChain ? result.estConfigEncryptedCaChain.toString("utf8") : ""
} as TCertificateProfileWithConfigs["estConfig"]) } as TCertificateProfileWithConfigs["estConfig"])
: undefined; : undefined;
@@ -324,7 +324,7 @@ export const certificateProfileDALFactory = (db: TDbClient) => {
? { ? {
id: result.estId as string, id: result.estId as string,
disableBootstrapCaValidation: !!result.estDisableBootstrapCaValidation, disableBootstrapCaValidation: !!result.estDisableBootstrapCaValidation,
passphrase: "", passphrase: result.estConfigHashedPassphrase,
caChain: result.estEncryptedCaChain ? (result.estEncryptedCaChain as Buffer).toString("utf8") : "" caChain: result.estEncryptedCaChain ? (result.estEncryptedCaChain as Buffer).toString("utf8") : ""
} }
: undefined; : undefined;
@@ -265,7 +265,8 @@ export const certificateV3ServiceFactory = ({
actor, actor,
actorId, actorId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId,
isFromProfile: true
}); });
const cert = await certificateDAL.findOne({ serialNumber, caId: ca.id }); const cert = await certificateDAL.findOne({ serialNumber, caId: ca.id });
@@ -361,7 +362,8 @@ export const certificateV3ServiceFactory = ({
notBefore: normalizeDateForApi(notBefore), notBefore: normalizeDateForApi(notBefore),
notAfter: normalizeDateForApi(notAfter), notAfter: normalizeDateForApi(notAfter),
signatureAlgorithm: effectiveSignatureAlgorithm, signatureAlgorithm: effectiveSignatureAlgorithm,
keyAlgorithm: effectiveKeyAlgorithm keyAlgorithm: effectiveKeyAlgorithm,
isFromProfile: true
}); });
const cert = await certificateDAL.findOne({ serialNumber, caId: ca.id }); const cert = await certificateDAL.findOne({ serialNumber, caId: ca.id });