mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
Modularized repetitive ca + chain logic
This commit is contained in:
@@ -5,7 +5,7 @@ import { BadRequestError } from "@app/lib/errors";
|
||||
import { getProjectKmsCertificateKeyId } from "@app/services/project/project-fns";
|
||||
|
||||
import { CertKeyAlgorithm, CertStatus } from "../certificate/certificate-types";
|
||||
import { TDNParts, TRebuildCaCrlDTO } from "./certificate-authority-types";
|
||||
import { TDNParts, TGetCaCertChainDTO, TGetCaCredentialsDTO, TRebuildCaCrlDTO } from "./certificate-authority-types";
|
||||
|
||||
export const createDistinguishedName = (parts: TDNParts) => {
|
||||
const dnParts = [];
|
||||
@@ -51,6 +51,101 @@ export const keyAlgorithmToAlgCfg = (keyAlgorithm: CertKeyAlgorithm) => {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the public and private key of CA with id [caId]
|
||||
* Note: credentials are returned as crypto.webcrypto.CryptoKey
|
||||
* suitable for use with @peculiar/x509 module
|
||||
*/
|
||||
export const getCaCredentials = async ({
|
||||
caId,
|
||||
certificateAuthorityDAL,
|
||||
certificateAuthoritySecretDAL,
|
||||
projectDAL,
|
||||
kmsService
|
||||
}: TGetCaCredentialsDTO) => {
|
||||
const ca = await certificateAuthorityDAL.findById(caId);
|
||||
if (!ca) throw new BadRequestError({ message: "CA not found" });
|
||||
|
||||
const caSecret = await certificateAuthoritySecretDAL.findOne({ caId });
|
||||
if (!caSecret) throw new BadRequestError({ message: "CA secret not found" });
|
||||
|
||||
const keyId = await getProjectKmsCertificateKeyId({
|
||||
projectId: ca.projectId,
|
||||
projectDAL,
|
||||
kmsService
|
||||
});
|
||||
|
||||
const decryptedPrivateKey = await kmsService.decrypt({
|
||||
kmsId: keyId,
|
||||
cipherTextBlob: caSecret.encryptedPrivateKey
|
||||
});
|
||||
|
||||
const alg = keyAlgorithmToAlgCfg(ca.keyAlgorithm as CertKeyAlgorithm);
|
||||
const skObj = crypto.createPrivateKey({ key: decryptedPrivateKey, format: "der", type: "pkcs8" });
|
||||
const caPrivateKey = await crypto.subtle.importKey(
|
||||
"pkcs8",
|
||||
skObj.export({ format: "der", type: "pkcs8" }),
|
||||
alg,
|
||||
true,
|
||||
["sign"]
|
||||
);
|
||||
|
||||
const pkObj = crypto.createPublicKey(skObj);
|
||||
const caPublicKey = await crypto.subtle.importKey("spki", pkObj.export({ format: "der", type: "spki" }), alg, true, [
|
||||
"verify"
|
||||
]);
|
||||
|
||||
return {
|
||||
caPrivateKey,
|
||||
caPublicKey
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the decrypted pem-encoded certificate and certificate chain
|
||||
* for CA with id [caId].
|
||||
*/
|
||||
export const getCaCertChain = async ({
|
||||
caId,
|
||||
certificateAuthorityDAL,
|
||||
certificateAuthorityCertDAL,
|
||||
projectDAL,
|
||||
kmsService
|
||||
}: TGetCaCertChainDTO) => {
|
||||
const ca = await certificateAuthorityDAL.findById(caId);
|
||||
if (!ca) throw new BadRequestError({ message: "CA not found" });
|
||||
|
||||
const caCert = await certificateAuthorityCertDAL.findOne({ caId: ca.id });
|
||||
|
||||
const keyId = await getProjectKmsCertificateKeyId({
|
||||
projectId: ca.projectId,
|
||||
projectDAL,
|
||||
kmsService
|
||||
});
|
||||
|
||||
const decryptedCaCert = await kmsService.decrypt({
|
||||
kmsId: keyId,
|
||||
cipherTextBlob: caCert.encryptedCertificate
|
||||
});
|
||||
|
||||
const caCertObj = new x509.X509Certificate(decryptedCaCert);
|
||||
|
||||
const decryptedChain = await kmsService.decrypt({
|
||||
kmsId: keyId,
|
||||
cipherTextBlob: caCert.encryptedCertificateChain
|
||||
});
|
||||
|
||||
return {
|
||||
caCert: caCertObj.toString("pem"),
|
||||
caCertChain: decryptedChain.toString("utf-8"),
|
||||
serialNumber: caCertObj.serialNumber
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Rebuilds the certificate revocation list (CRL)
|
||||
* for CA with id [caId]
|
||||
*/
|
||||
export const rebuildCaCrl = async ({
|
||||
caId,
|
||||
certificateAuthorityDAL,
|
||||
|
||||
@@ -16,7 +16,12 @@ import { CertKeyAlgorithm, CertStatus } from "../certificate/certificate-types";
|
||||
import { TCertificateAuthorityCertDALFactory } from "./certificate-authority-cert-dal";
|
||||
import { TCertificateAuthorityCrlDALFactory } from "./certificate-authority-crl-dal";
|
||||
import { TCertificateAuthorityDALFactory } from "./certificate-authority-dal";
|
||||
import { createDistinguishedName, keyAlgorithmToAlgCfg } from "./certificate-authority-fns";
|
||||
import {
|
||||
createDistinguishedName,
|
||||
getCaCertChain,
|
||||
getCaCredentials,
|
||||
keyAlgorithmToAlgCfg
|
||||
} from "./certificate-authority-fns";
|
||||
import { TCertificateAuthorityQueueFactory } from "./certificate-authority-queue";
|
||||
import { TCertificateAuthoritySecretDALFactory } from "./certificate-authority-secret-dal";
|
||||
import {
|
||||
@@ -65,7 +70,7 @@ export const certificateAuthorityServiceFactory = ({
|
||||
permissionService
|
||||
}: TCertificateAuthorityServiceFactoryDep) => {
|
||||
/**
|
||||
* Generates a new root or intermediate CA
|
||||
* Generates new root or intermediate CA
|
||||
*/
|
||||
const createCa = async ({
|
||||
projectSlug,
|
||||
@@ -237,6 +242,9 @@ export const certificateAuthorityServiceFactory = ({
|
||||
return newCa;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return CA with id [caId]
|
||||
*/
|
||||
const getCaById = async ({ caId, actorId, actorAuthMethod, actor, actorOrgId }: TGetCaDTO) => {
|
||||
const ca = await certificateAuthorityDAL.findById(caId);
|
||||
if (!ca) throw new BadRequestError({ message: "CA not found" });
|
||||
@@ -256,6 +264,10 @@ export const certificateAuthorityServiceFactory = ({
|
||||
return ca;
|
||||
};
|
||||
|
||||
/**
|
||||
* Update CA with id [caId].
|
||||
* Note: Used to enable/disable CA
|
||||
*/
|
||||
const updateCaById = async ({ caId, status, actorId, actorAuthMethod, actor, actorOrgId }: TUpdateCaDTO) => {
|
||||
const ca = await certificateAuthorityDAL.findById(caId);
|
||||
if (!ca) throw new BadRequestError({ message: "CA not found" });
|
||||
@@ -278,6 +290,9 @@ export const certificateAuthorityServiceFactory = ({
|
||||
return updatedCa;
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete CA with id [caId]
|
||||
*/
|
||||
const deleteCaById = async ({ caId, actorId, actorAuthMethod, actor, actorOrgId }: TDeleteCaDTO) => {
|
||||
const ca = await certificateAuthorityDAL.findById(caId);
|
||||
if (!ca) throw new BadRequestError({ message: "CA not found" });
|
||||
@@ -301,7 +316,7 @@ export const certificateAuthorityServiceFactory = ({
|
||||
};
|
||||
|
||||
/**
|
||||
* Generates a CSR for a CA
|
||||
* Return certificate signing request (CSR) made with CA with id [caId]
|
||||
*/
|
||||
const getCaCsr = async ({ caId, actorId, actorAuthMethod, actor, actorOrgId }: TGetCaCsrDTO) => {
|
||||
const ca = await certificateAuthorityDAL.findById(caId);
|
||||
@@ -325,33 +340,22 @@ export const certificateAuthorityServiceFactory = ({
|
||||
const caCert = await certificateAuthorityCertDAL.findOne({ caId: ca.id });
|
||||
if (caCert) throw new BadRequestError({ message: "CA already has a certificate installed" });
|
||||
|
||||
const caSecret = await certificateAuthoritySecretDAL.findOne({ caId: ca.id });
|
||||
|
||||
const keyId = await getProjectKmsCertificateKeyId({
|
||||
projectId: ca.projectId,
|
||||
const { caPrivateKey, caPublicKey } = await getCaCredentials({
|
||||
caId,
|
||||
certificateAuthorityDAL,
|
||||
certificateAuthoritySecretDAL,
|
||||
projectDAL,
|
||||
kmsService
|
||||
});
|
||||
|
||||
const privateKey = await kmsService.decrypt({
|
||||
kmsId: keyId,
|
||||
cipherTextBlob: caSecret.encryptedPrivateKey
|
||||
});
|
||||
|
||||
const alg = keyAlgorithmToAlgCfg(ca.keyAlgorithm as CertKeyAlgorithm);
|
||||
const skObj = crypto.createPrivateKey({ key: privateKey, format: "der", type: "pkcs8" });
|
||||
const sk = await crypto.subtle.importKey("pkcs8", skObj.export({ format: "der", type: "pkcs8" }), alg, true, [
|
||||
"sign"
|
||||
]);
|
||||
const pkObj = crypto.createPublicKey(skObj);
|
||||
|
||||
const pk = await crypto.subtle.importKey("spki", pkObj.export({ format: "der", type: "spki" }), alg, true, [
|
||||
"verify"
|
||||
]);
|
||||
|
||||
const csrObj = await x509.Pkcs10CertificateRequestGenerator.create({
|
||||
name: ca.dn,
|
||||
keys: { privateKey: sk, publicKey: pk },
|
||||
keys: {
|
||||
privateKey: caPrivateKey,
|
||||
publicKey: caPublicKey
|
||||
},
|
||||
signingAlgorithm: alg,
|
||||
extensions: [
|
||||
// eslint-disable-next-line no-bitwise
|
||||
@@ -388,30 +392,18 @@ export const certificateAuthorityServiceFactory = ({
|
||||
ProjectPermissionSub.CertificateAuthorities
|
||||
);
|
||||
|
||||
const caCert = await certificateAuthorityCertDAL.findOne({ caId: ca.id });
|
||||
|
||||
const keyId = await getProjectKmsCertificateKeyId({
|
||||
projectId: ca.projectId,
|
||||
const { caCert, caCertChain, serialNumber } = await getCaCertChain({
|
||||
caId,
|
||||
certificateAuthorityDAL,
|
||||
certificateAuthorityCertDAL,
|
||||
projectDAL,
|
||||
kmsService
|
||||
});
|
||||
|
||||
const decryptedCaCert = await kmsService.decrypt({
|
||||
kmsId: keyId,
|
||||
cipherTextBlob: caCert.encryptedCertificate
|
||||
});
|
||||
|
||||
const certObj = new x509.X509Certificate(decryptedCaCert);
|
||||
|
||||
const decryptedChain = await kmsService.decrypt({
|
||||
kmsId: keyId,
|
||||
cipherTextBlob: caCert.encryptedCertificateChain
|
||||
});
|
||||
|
||||
return {
|
||||
certificate: certObj.toString("pem"),
|
||||
certificateChain: decryptedChain.toString("utf-8"),
|
||||
serialNumber: certObj.serialNumber
|
||||
certificate: caCert,
|
||||
certificateChain: caCertChain,
|
||||
serialNumber
|
||||
};
|
||||
};
|
||||
|
||||
@@ -456,18 +448,6 @@ export const certificateAuthorityServiceFactory = ({
|
||||
});
|
||||
|
||||
const caCert = await certificateAuthorityCertDAL.findOne({ caId: ca.id });
|
||||
const caSecret = await certificateAuthoritySecretDAL.findOne({ caId: ca.id });
|
||||
|
||||
const privateKey = await kmsService.decrypt({
|
||||
kmsId: keyId,
|
||||
cipherTextBlob: caSecret.encryptedPrivateKey
|
||||
});
|
||||
|
||||
const skObj = crypto.createPrivateKey({ key: privateKey, format: "der", type: "pkcs8" });
|
||||
const sk = await crypto.subtle.importKey("pkcs8", skObj.export({ format: "der", type: "pkcs8" }), alg, true, [
|
||||
"sign"
|
||||
]);
|
||||
|
||||
const decryptedCaCert = await kmsService.decrypt({
|
||||
kmsId: keyId,
|
||||
cipherTextBlob: caCert.encryptedCertificate
|
||||
@@ -507,6 +487,14 @@ export const certificateAuthorityServiceFactory = ({
|
||||
throw new BadRequestError({ message: "notAfter date is after CA certificate's notAfter date" });
|
||||
}
|
||||
|
||||
const { caPrivateKey } = await getCaCredentials({
|
||||
caId: ca.id,
|
||||
certificateAuthorityDAL,
|
||||
certificateAuthoritySecretDAL,
|
||||
projectDAL,
|
||||
kmsService
|
||||
});
|
||||
|
||||
const serialNumber = crypto.randomBytes(32).toString("hex");
|
||||
const intermediateCert = await x509.X509CertificateGenerator.create({
|
||||
serialNumber,
|
||||
@@ -514,7 +502,7 @@ export const certificateAuthorityServiceFactory = ({
|
||||
issuer: caCertObj.subject,
|
||||
notBefore: notBeforeDate,
|
||||
notAfter: notAfterDate,
|
||||
signingKey: sk,
|
||||
signingKey: caPrivateKey,
|
||||
publicKey: csrObj.publicKey,
|
||||
signingAlgorithm: alg,
|
||||
extensions: [
|
||||
@@ -531,21 +519,27 @@ export const certificateAuthorityServiceFactory = ({
|
||||
]
|
||||
});
|
||||
|
||||
const caCertChain = await kmsService.decrypt({
|
||||
kmsId: keyId,
|
||||
cipherTextBlob: caCert.encryptedCertificateChain
|
||||
const { caCert: issuingCaCertificate, caCertChain } = await getCaCertChain({
|
||||
caId,
|
||||
certificateAuthorityDAL,
|
||||
certificateAuthorityCertDAL,
|
||||
projectDAL,
|
||||
kmsService
|
||||
});
|
||||
|
||||
const certificateChain = `${caCertObj.toString("pem")}\n${caCertChain.toString("utf-8")}`.trim();
|
||||
|
||||
return {
|
||||
certificate: intermediateCert.toString("pem"),
|
||||
issuingCaCertificate: caCertObj.toString("pem"),
|
||||
certificateChain,
|
||||
issuingCaCertificate,
|
||||
certificateChain: `${issuingCaCertificate}\n${caCertChain}`.trim(),
|
||||
serialNumber: intermediateCert.serialNumber
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Import certificate for (un-installed) CA with id [caId].
|
||||
* Note: Can be used to import an external certificate and certificate chain
|
||||
* to be installed into the CA.
|
||||
*/
|
||||
const importCertToCa = async ({
|
||||
caId,
|
||||
actorId,
|
||||
@@ -643,6 +637,9 @@ export const certificateAuthorityServiceFactory = ({
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Return new leaf certificate issued by CA with id [caId]
|
||||
*/
|
||||
const issueCertFromCa = async ({
|
||||
caId,
|
||||
commonName,
|
||||
@@ -685,33 +682,6 @@ export const certificateAuthorityServiceFactory = ({
|
||||
|
||||
const caCertObj = new x509.X509Certificate(decryptedCaCert);
|
||||
|
||||
const caSecret = await certificateAuthoritySecretDAL.findOne({ caId: ca.id });
|
||||
|
||||
const privateKey = await kmsService.decrypt({
|
||||
kmsId: keyId,
|
||||
cipherTextBlob: caSecret.encryptedPrivateKey
|
||||
});
|
||||
|
||||
const alg = keyAlgorithmToAlgCfg(ca.keyAlgorithm as CertKeyAlgorithm);
|
||||
|
||||
const caSkObj = crypto.createPrivateKey({ key: privateKey, format: "der", type: "pkcs8" });
|
||||
const caSk = await crypto.subtle.importKey("pkcs8", caSkObj.export({ format: "der", type: "pkcs8" }), alg, true, [
|
||||
"sign"
|
||||
]);
|
||||
|
||||
const leafKeys = await crypto.subtle.generateKey(alg, true, ["sign", "verify"]);
|
||||
|
||||
const csrObj = await x509.Pkcs10CertificateRequestGenerator.create({
|
||||
name: `CN=${commonName}`,
|
||||
keys: leafKeys,
|
||||
signingAlgorithm: alg,
|
||||
extensions: [
|
||||
// eslint-disable-next-line no-bitwise
|
||||
new x509.KeyUsagesExtension(x509.KeyUsageFlags.digitalSignature | x509.KeyUsageFlags.keyEncipherment)
|
||||
],
|
||||
attributes: [new x509.ChallengePasswordAttribute("password")]
|
||||
});
|
||||
|
||||
const notBeforeDate = notBefore ? new Date(notBefore) : new Date();
|
||||
|
||||
let notAfterDate = new Date(new Date().setFullYear(new Date().getFullYear() + 1));
|
||||
@@ -737,6 +707,28 @@ export const certificateAuthorityServiceFactory = ({
|
||||
throw new BadRequestError({ message: "notAfter date is after CA certificate's notAfter date" });
|
||||
}
|
||||
|
||||
const alg = keyAlgorithmToAlgCfg(ca.keyAlgorithm as CertKeyAlgorithm);
|
||||
const leafKeys = await crypto.subtle.generateKey(alg, true, ["sign", "verify"]);
|
||||
|
||||
const csrObj = await x509.Pkcs10CertificateRequestGenerator.create({
|
||||
name: `CN=${commonName}`,
|
||||
keys: leafKeys,
|
||||
signingAlgorithm: alg,
|
||||
extensions: [
|
||||
// eslint-disable-next-line no-bitwise
|
||||
new x509.KeyUsagesExtension(x509.KeyUsageFlags.digitalSignature | x509.KeyUsageFlags.keyEncipherment)
|
||||
],
|
||||
attributes: [new x509.ChallengePasswordAttribute("password")]
|
||||
});
|
||||
|
||||
const { caPrivateKey } = await getCaCredentials({
|
||||
caId: ca.id,
|
||||
certificateAuthorityDAL,
|
||||
certificateAuthoritySecretDAL,
|
||||
projectDAL,
|
||||
kmsService
|
||||
});
|
||||
|
||||
const serialNumber = crypto.randomBytes(32).toString("hex");
|
||||
const leafCert = await x509.X509CertificateGenerator.create({
|
||||
serialNumber,
|
||||
@@ -744,7 +736,7 @@ export const certificateAuthorityServiceFactory = ({
|
||||
issuer: caCertObj.subject,
|
||||
notBefore: notBeforeDate,
|
||||
notAfter: notAfterDate,
|
||||
signingKey: caSk,
|
||||
signingKey: caPrivateKey,
|
||||
publicKey: csrObj.publicKey,
|
||||
signingAlgorithm: alg,
|
||||
extensions: [
|
||||
@@ -763,11 +755,6 @@ export const certificateAuthorityServiceFactory = ({
|
||||
plainText: Buffer.from(new Uint8Array(leafCert.rawData))
|
||||
});
|
||||
|
||||
const caCertChain = await kmsService.decrypt({
|
||||
kmsId: keyId,
|
||||
cipherTextBlob: caCert.encryptedCertificateChain
|
||||
});
|
||||
|
||||
await certificateDAL.transaction(async (tx) => {
|
||||
const cert = await certificateDAL.create(
|
||||
{
|
||||
@@ -792,19 +779,25 @@ export const certificateAuthorityServiceFactory = ({
|
||||
return cert;
|
||||
});
|
||||
|
||||
const certificateChain = `${caCertObj.toString("pem")}\n${caCertChain.toString("utf-8")}`.trim();
|
||||
const { caCert: issuingCaCertificate, caCertChain } = await getCaCertChain({
|
||||
caId: ca.id,
|
||||
certificateAuthorityDAL,
|
||||
certificateAuthorityCertDAL,
|
||||
projectDAL,
|
||||
kmsService
|
||||
});
|
||||
|
||||
return {
|
||||
certificate: leafCert.toString("pem"),
|
||||
certificateChain,
|
||||
issuingCaCertificate: caCertObj.toString("pem"),
|
||||
certificateChain: `${issuingCaCertificate}\n${caCertChain}`.trim(),
|
||||
issuingCaCertificate,
|
||||
privateKey: skLeaf,
|
||||
serialNumber
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the Certificate Revocation List (CRL) for the CA
|
||||
* Return the Certificate Revocation List (CRL) for CA with id [caId]
|
||||
*/
|
||||
const getCaCrl = async ({ caId, actorId, actorAuthMethod, actor, actorOrgId }: TGetCrl) => {
|
||||
const ca = await certificateAuthorityDAL.findById(caId);
|
||||
|
||||
@@ -4,6 +4,7 @@ import { TKmsServiceFactory } from "@app/services/kms/kms-service";
|
||||
import { TProjectDALFactory } from "@app/services/project/project-dal";
|
||||
|
||||
import { CertKeyAlgorithm } from "../certificate/certificate-types";
|
||||
import { TCertificateAuthorityCertDALFactory } from "./certificate-authority-cert-dal";
|
||||
import { TCertificateAuthorityCrlDALFactory } from "./certificate-authority-crl-dal";
|
||||
import { TCertificateAuthorityDALFactory } from "./certificate-authority-dal";
|
||||
import { TCertificateAuthoritySecretDALFactory } from "./certificate-authority-secret-dal";
|
||||
@@ -94,6 +95,22 @@ export type TDNParts = {
|
||||
locality?: string;
|
||||
};
|
||||
|
||||
export type TGetCaCredentialsDTO = {
|
||||
caId: string;
|
||||
certificateAuthorityDAL: Pick<TCertificateAuthorityDALFactory, "findById">;
|
||||
certificateAuthoritySecretDAL: Pick<TCertificateAuthoritySecretDALFactory, "findOne">;
|
||||
projectDAL: Pick<TProjectDALFactory, "findOne" | "updateById" | "transaction">;
|
||||
kmsService: Pick<TKmsServiceFactory, "decrypt" | "generateKmsKey">;
|
||||
};
|
||||
|
||||
export type TGetCaCertChainDTO = {
|
||||
caId: string;
|
||||
certificateAuthorityDAL: Pick<TCertificateAuthorityDALFactory, "findById">;
|
||||
certificateAuthorityCertDAL: Pick<TCertificateAuthorityCertDALFactory, "findOne">;
|
||||
projectDAL: Pick<TProjectDALFactory, "findOne" | "updateById" | "transaction">;
|
||||
kmsService: Pick<TKmsServiceFactory, "decrypt" | "generateKmsKey">;
|
||||
};
|
||||
|
||||
export type TRebuildCaCrlDTO = {
|
||||
caId: string;
|
||||
certificateAuthorityDAL: Pick<TCertificateAuthorityDALFactory, "findById">;
|
||||
|
||||
@@ -13,7 +13,7 @@ import { TKmsServiceFactory } from "@app/services/kms/kms-service";
|
||||
import { TProjectDALFactory } from "@app/services/project/project-dal";
|
||||
import { getProjectKmsCertificateKeyId } from "@app/services/project/project-fns";
|
||||
|
||||
import { rebuildCaCrl } from "../certificate-authority/certificate-authority-fns";
|
||||
import { getCaCertChain, rebuildCaCrl } from "../certificate-authority/certificate-authority-fns";
|
||||
import { revocationReasonToCrlCode } from "./certificate-fns";
|
||||
import { CertStatus, TDeleteCertDTO, TGetCertCertDTO, TGetCertDTO, TRevokeCertDTO } from "./certificate-types";
|
||||
|
||||
@@ -42,6 +42,9 @@ export const certificateServiceFactory = ({
|
||||
kmsService,
|
||||
permissionService
|
||||
}: TCertificateServiceFactoryDep) => {
|
||||
/**
|
||||
* Return details for certificate with serial number [serialNumber]
|
||||
*/
|
||||
const getCert = async ({ serialNumber, actorId, actorAuthMethod, actor, actorOrgId }: TGetCertDTO) => {
|
||||
const cert = await certificateDAL.findOne({ serialNumber });
|
||||
const ca = await certificateAuthorityDAL.findById(cert.caId);
|
||||
@@ -59,6 +62,9 @@ export const certificateServiceFactory = ({
|
||||
return cert;
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete certificate with serial number [serialNumber]
|
||||
*/
|
||||
const deleteCert = async ({ serialNumber, actorId, actorAuthMethod, actor, actorOrgId }: TDeleteCertDTO) => {
|
||||
const cert = await certificateDAL.findOne({ serialNumber });
|
||||
const ca = await certificateAuthorityDAL.findById(cert.caId);
|
||||
@@ -77,6 +83,11 @@ export const certificateServiceFactory = ({
|
||||
return deletedCert;
|
||||
};
|
||||
|
||||
/**
|
||||
* Revoke certificate with serial number [serialNumber].
|
||||
* Note: Revoking a certificate adds it to the certificate revocation list (CRL)
|
||||
* of its issuing CA
|
||||
*/
|
||||
const revokeCert = async ({
|
||||
serialNumber,
|
||||
revocationReason,
|
||||
@@ -126,10 +137,13 @@ export const certificateServiceFactory = ({
|
||||
return { revokedAt };
|
||||
};
|
||||
|
||||
/**
|
||||
* Return certificate body and certificate chain for certificate with
|
||||
* serial number [serialNumber]
|
||||
*/
|
||||
const getCertCert = async ({ serialNumber, actorId, actorAuthMethod, actor, actorOrgId }: TGetCertCertDTO) => {
|
||||
const cert = await certificateDAL.findOne({ serialNumber });
|
||||
const ca = await certificateAuthorityDAL.findById(cert.caId);
|
||||
const caCert = await certificateAuthorityCertDAL.findOne({ caId: ca.id });
|
||||
|
||||
const { permission } = await permissionService.getProjectPermission(
|
||||
actor,
|
||||
@@ -154,25 +168,19 @@ export const certificateServiceFactory = ({
|
||||
cipherTextBlob: certCert.encryptedCertificate
|
||||
});
|
||||
|
||||
const caCertChain = await kmsService.decrypt({
|
||||
kmsId: keyId,
|
||||
cipherTextBlob: caCert.encryptedCertificateChain
|
||||
});
|
||||
|
||||
const certObj = new x509.X509Certificate(decryptedCert);
|
||||
|
||||
const decryptedCaCert = await kmsService.decrypt({
|
||||
kmsId: keyId,
|
||||
cipherTextBlob: caCert.encryptedCertificate
|
||||
const { caCert, caCertChain } = await getCaCertChain({
|
||||
caId: ca.id,
|
||||
certificateAuthorityDAL,
|
||||
certificateAuthorityCertDAL,
|
||||
projectDAL,
|
||||
kmsService
|
||||
});
|
||||
|
||||
const caCertObj = new x509.X509Certificate(decryptedCaCert);
|
||||
|
||||
const certificateChain = `${caCertObj.toString("pem")}\n${caCertChain.toString("utf-8")}`.trim();
|
||||
|
||||
return {
|
||||
certificate: certObj.toString("pem"),
|
||||
certificateChain,
|
||||
certificateChain: `${caCert}\n${caCertChain}`.trim(),
|
||||
serialNumber: certObj.serialNumber
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user