Remove cert secret structure, show cert sk once upon issuance

This commit is contained in:
Tuan Dang
2024-05-28 22:04:13 -07:00
parent 2f06168b29
commit f9847f48b0
12 changed files with 347 additions and 478 deletions
@@ -5,7 +5,7 @@ import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
export async function up(knex: Knex): Promise<void> {
if (!(await knex.schema.hasTable(TableName.CertificateAuthority))) {
// TODO: consider adding algo details
// TODO: add algo deets
await knex.schema.createTable(TableName.CertificateAuthority, (t) => {
t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
t.timestamps(true, true, true);
@@ -77,30 +77,15 @@ export async function up(knex: Knex): Promise<void> {
});
}
if (!(await knex.schema.hasTable(TableName.CertificateSecret))) {
await knex.schema.createTable(TableName.CertificateSecret, (t) => {
t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
t.timestamps(true, true, true);
t.uuid("certId").notNullable().unique();
t.foreign("certId").references("id").inTable(TableName.Certificate).onDelete("CASCADE");
t.text("pk").notNullable(); // TODO: encrypt
t.text("sk").notNullable(); // TODO: encrypt
});
}
await createOnUpdateTrigger(knex, TableName.CertificateAuthority);
await createOnUpdateTrigger(knex, TableName.CertificateAuthorityCert);
await createOnUpdateTrigger(knex, TableName.CertificateAuthoritySk);
await createOnUpdateTrigger(knex, TableName.Certificate);
await createOnUpdateTrigger(knex, TableName.CertificateCert);
await createOnUpdateTrigger(knex, TableName.CertificateSecret);
}
export async function down(knex: Knex): Promise<void> {
// certificates
await knex.schema.dropTableIfExists(TableName.CertificateSecret);
await dropOnUpdateTrigger(knex, TableName.CertificateSecret);
await knex.schema.dropTableIfExists(TableName.CertificateCert);
await dropOnUpdateTrigger(knex, TableName.CertificateCert);
-5
View File
@@ -73,7 +73,6 @@ import { tokenDALFactory } from "@app/services/auth-token/auth-token-dal";
import { tokenServiceFactory } from "@app/services/auth-token/auth-token-service";
import { certificateCertDALFactory } from "@app/services/certificate/certificate-cert-dal";
import { certificateDALFactory } from "@app/services/certificate/certificate-dal";
import { certificateSecretDALFactory } from "@app/services/certificate/certificate-secret-dal";
import { certificateServiceFactory } from "@app/services/certificate/certificate-service";
import { certificateAuthorityCertDALFactory } from "@app/services/certificate-authority/certificate-authority-cert-dal";
import { certificateAuthorityDALFactory } from "@app/services/certificate-authority/certificate-authority-dal";
@@ -502,14 +501,11 @@ export const registerRoutes = async (
const certificateDAL = certificateDALFactory(db);
const certificateCertDAL = certificateCertDALFactory(db);
const certificateSecretDAL = certificateSecretDALFactory(db);
const certificateService = certificateServiceFactory({
certificateDAL,
certificateCertDAL,
certificateSecretDAL,
certificateAuthorityDAL,
certificateAuthorityCertDAL,
permissionService
});
@@ -519,7 +515,6 @@ export const registerRoutes = async (
certificateAuthoritySkDAL,
certificateDAL,
certificateCertDAL,
certificateSecretDAL,
projectDAL,
permissionService
});
@@ -86,26 +86,21 @@ export const registerCertRouter = async (server: FastifyZodProvider) => {
200: z.object({
certificate: z.string().trim(),
certificateChain: z.string().trim(),
issuingCaCertificate: z.string().trim(),
privateKey: z.string().trim(),
serialNumber: z.string().trim()
})
}
},
handler: async (req) => {
const { certificate, certificateChain, issuingCaCertificate, privateKey, serialNumber } =
await server.services.certificate.getCertCert({
certId: req.params.certId,
actor: req.permission.type,
actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId
});
const { certificate, certificateChain, serialNumber } = await server.services.certificate.getCertCert({
certId: req.params.certId,
actor: req.permission.type,
actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId
});
return {
certificate,
certificateChain,
issuingCaCertificate,
privateKey,
serialNumber
};
}
@@ -7,7 +7,6 @@ import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services
import { BadRequestError } from "@app/lib/errors";
import { TCertificateCertDALFactory } from "@app/services/certificate/certificate-cert-dal";
import { TCertificateDALFactory } from "@app/services/certificate/certificate-dal";
import { TCertificateSecretDALFactory } from "@app/services/certificate/certificate-secret-dal";
import { TProjectDALFactory } from "@app/services/project/project-dal";
import { TCertificateAuthorityCertDALFactory } from "./certificate-authority-cert-dal";
@@ -29,15 +28,16 @@ import {
} from "./certificate-authority-types";
type TCertificateAuthorityServiceFactoryDep = {
// TODO: Pick
certificateAuthorityDAL: TCertificateAuthorityDALFactory;
certificateAuthorityCertDAL: TCertificateAuthorityCertDALFactory;
certificateAuthoritySkDAL: TCertificateAuthoritySkDALFactory;
certificateDAL: TCertificateDALFactory;
certificateCertDAL: TCertificateCertDALFactory;
certificateSecretDAL: TCertificateSecretDALFactory;
projectDAL: TProjectDALFactory;
permissionService: TPermissionServiceFactory;
certificateAuthorityDAL: Pick<
TCertificateAuthorityDALFactory,
"transaction" | "create" | "findById" | "updateById" | "deleteById" | "findOne" | "buildCertificateChain"
>;
certificateAuthorityCertDAL: Pick<TCertificateAuthorityCertDALFactory, "create" | "findOne" | "transaction">;
certificateAuthoritySkDAL: Pick<TCertificateAuthoritySkDALFactory, "create" | "findOne">;
certificateDAL: Pick<TCertificateDALFactory, "transaction" | "create">;
certificateCertDAL: Pick<TCertificateCertDALFactory, "create">;
projectDAL: Pick<TProjectDALFactory, "findProjectBySlug">;
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
};
export type TCertificateAuthorityServiceFactory = ReturnType<typeof certificateAuthorityServiceFactory>;
@@ -48,7 +48,6 @@ export const certificateAuthorityServiceFactory = ({
certificateAuthoritySkDAL,
certificateDAL,
certificateCertDAL,
certificateSecretDAL,
projectDAL,
permissionService
}: TCertificateAuthorityServiceFactoryDep) => {
@@ -624,12 +623,6 @@ export const certificateAuthorityServiceFactory = ({
const chain = await certificateAuthorityDAL.buildCertificateChain(caId);
// https://nodejs.org/api/crypto.html#static-method-keyobjectfromkey
const skObj = KeyObject.from(leafKeys.privateKey);
const sk = skObj.export({ format: "pem", type: "pkcs8" }) as string;
const pkObj = KeyObject.from(leafKeys.publicKey);
const pk = pkObj.export({ format: "pem", type: "spki" }) as string;
await certificateDAL.transaction(async (tx) => {
const cert = await certificateDAL.create(
{
@@ -650,15 +643,6 @@ export const certificateAuthorityServiceFactory = ({
tx
);
await certificateSecretDAL.create(
{
certId: cert.id,
pk, // TODO: encrypt
sk // TODO: encrypt
},
tx
);
return cert;
});
@@ -1,10 +0,0 @@
import { TDbClient } from "@app/db";
import { TableName } from "@app/db/schemas";
import { ormify } from "@app/lib/knex";
export type TCertificateSecretDALFactory = ReturnType<typeof certificateSecretDALFactory>;
export const certificateSecretDALFactory = (db: TDbClient) => {
const certificateSecretOrm = ormify(db, TableName.CertificateSecret);
return certificateSecretOrm;
};
@@ -5,20 +5,15 @@ import { TPermissionServiceFactory } from "@app/ee/services/permission/permissio
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
import { TCertificateCertDALFactory } from "@app/services/certificate/certificate-cert-dal";
import { TCertificateDALFactory } from "@app/services/certificate/certificate-dal";
import { TCertificateSecretDALFactory } from "@app/services/certificate/certificate-secret-dal";
import { TCertificateAuthorityCertDALFactory } from "@app/services/certificate-authority/certificate-authority-cert-dal";
import { TCertificateAuthorityDALFactory } from "@app/services/certificate-authority/certificate-authority-dal";
import { TDeleteCertDTO, TGetCertCertDTO, TGetCertDTO } from "./certificate-types";
type TCertificateServiceFactoryDep = {
// TODO: Pick
certificateDAL: TCertificateDALFactory;
certificateCertDAL: TCertificateCertDALFactory;
certificateSecretDAL: TCertificateSecretDALFactory;
certificateAuthorityDAL: TCertificateAuthorityDALFactory;
certificateAuthorityCertDAL: TCertificateAuthorityCertDALFactory;
permissionService: TPermissionServiceFactory;
certificateDAL: Pick<TCertificateDALFactory, "findById" | "deleteById">;
certificateCertDAL: Pick<TCertificateCertDALFactory, "findOne">;
certificateAuthorityDAL: Pick<TCertificateAuthorityDALFactory, "findById">;
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
};
export type TCertificateServiceFactory = ReturnType<typeof certificateServiceFactory>;
@@ -26,9 +21,7 @@ export type TCertificateServiceFactory = ReturnType<typeof certificateServiceFac
export const certificateServiceFactory = ({
certificateDAL,
certificateCertDAL,
certificateSecretDAL,
certificateAuthorityDAL,
certificateAuthorityCertDAL,
permissionService
}: TCertificateServiceFactoryDep) => {
const getCertById = async ({ certId, actorId, actorAuthMethod, actor, actorOrgId }: TGetCertDTO) => {
@@ -77,19 +70,15 @@ export const certificateServiceFactory = ({
actorAuthMethod,
actorOrgId
);
// TODO: re-evaluate this permission
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Certificates);
const caCert = await certificateAuthorityCertDAL.findOne({ caId: ca.id });
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Certificates);
const certCert = await certificateCertDAL.findOne({ certId });
const certSecret = await certificateSecretDAL.findOne({ certId });
const certObj = new x509.X509Certificate(certCert.certificate);
return {
certificate: certCert.certificate,
certificateChain: certCert.certificateChain,
issuingCaCertificate: caCert.certificate,
privateKey: certSecret.sk,
serialNumber: certObj.serialNumber
};
};