misc: integrated custom key usages for issue-cert endpoint

This commit is contained in:
Sheen Capadngan
2024-09-11 01:57:16 +08:00
parent 6fab7d9507
commit 4e6b289e1b
12 changed files with 192 additions and 36 deletions

View File

@@ -5,6 +5,7 @@ import { CertKeyUsage } from "@app/services/certificate/certificate-types";
import { TableName } from "../schemas"; import { TableName } from "../schemas";
export async function up(knex: Knex): Promise<void> { export async function up(knex: Knex): Promise<void> {
// Certificate template
const hasKeyUsagesCol = await knex.schema.hasColumn(TableName.CertificateTemplate, "keyUsages"); const hasKeyUsagesCol = await knex.schema.hasColumn(TableName.CertificateTemplate, "keyUsages");
const hasExtendedKeyUsagesCol = await knex.schema.hasColumn(TableName.CertificateTemplate, "extendedKeyUsages"); const hasExtendedKeyUsagesCol = await knex.schema.hasColumn(TableName.CertificateTemplate, "extendedKeyUsages");
@@ -23,9 +24,41 @@ export async function up(knex: Knex): Promise<void> {
keyUsages: [CertKeyUsage.DIGITAL_SIGNATURE, CertKeyUsage.KEY_ENCIPHERMENT] keyUsages: [CertKeyUsage.DIGITAL_SIGNATURE, CertKeyUsage.KEY_ENCIPHERMENT]
}); });
} }
if (!hasExtendedKeyUsagesCol) {
await knex(TableName.CertificateTemplate).update({
extendedKeyUsages: []
});
}
// Certificate
const doesCertTableHaveKeyUsages = await knex.schema.hasColumn(TableName.Certificate, "keyUsages");
const doesCertTableHaveExtendedKeyUsages = await knex.schema.hasColumn(TableName.Certificate, "extendedKeyUsages");
await knex.schema.alterTable(TableName.Certificate, (tb) => {
if (!doesCertTableHaveKeyUsages) {
tb.specificType("keyUsages", "text[]");
}
if (!doesCertTableHaveExtendedKeyUsages) {
tb.specificType("extendedKeyUsages", "text[]");
}
});
if (!doesCertTableHaveKeyUsages) {
await knex(TableName.Certificate).update({
keyUsages: [CertKeyUsage.DIGITAL_SIGNATURE, CertKeyUsage.KEY_ENCIPHERMENT]
});
}
if (!doesCertTableHaveExtendedKeyUsages) {
await knex(TableName.Certificate).update({
extendedKeyUsages: []
});
}
} }
export async function down(knex: Knex): Promise<void> { export async function down(knex: Knex): Promise<void> {
// Certificate Template
const hasKeyUsagesCol = await knex.schema.hasColumn(TableName.CertificateTemplate, "keyUsages"); const hasKeyUsagesCol = await knex.schema.hasColumn(TableName.CertificateTemplate, "keyUsages");
const hasExtendedKeyUsagesCol = await knex.schema.hasColumn(TableName.CertificateTemplate, "extendedKeyUsages"); const hasExtendedKeyUsagesCol = await knex.schema.hasColumn(TableName.CertificateTemplate, "extendedKeyUsages");
@@ -37,4 +70,16 @@ export async function down(knex: Knex): Promise<void> {
t.dropColumn("extendedKeyUsages"); t.dropColumn("extendedKeyUsages");
} }
}); });
// Certificate
const doesCertTableHaveKeyUsages = await knex.schema.hasColumn(TableName.Certificate, "keyUsages");
const doesCertTableHaveExtendedKeyUsages = await knex.schema.hasColumn(TableName.Certificate, "extendedKeyUsages");
await knex.schema.alterTable(TableName.Certificate, (t) => {
if (doesCertTableHaveKeyUsages) {
t.dropColumn("keyUsages");
}
if (doesCertTableHaveExtendedKeyUsages) {
t.dropColumn("extendedKeyUsages");
}
});
} }

View File

@@ -22,7 +22,9 @@ export const CertificatesSchema = z.object({
revocationReason: z.number().nullable().optional(), revocationReason: z.number().nullable().optional(),
altNames: z.string().default("").nullable().optional(), altNames: z.string().default("").nullable().optional(),
caCertId: z.string().uuid(), caCertId: z.string().uuid(),
certificateTemplateId: z.string().uuid().nullable().optional() certificateTemplateId: z.string().uuid().nullable().optional(),
keyUsages: z.string().array().nullable().optional(),
extendedKeyUsages: z.string().array().nullable().optional()
}); });
export type TCertificates = z.infer<typeof CertificatesSchema>; export type TCertificates = z.infer<typeof CertificatesSchema>;

View File

@@ -7,7 +7,7 @@ import { CERTIFICATE_AUTHORITIES } from "@app/lib/api-docs";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type"; import { AuthMode } from "@app/services/auth/auth-type";
import { CertKeyAlgorithm } from "@app/services/certificate/certificate-types"; import { CertKeyAlgorithm, CertKeyUsage } from "@app/services/certificate/certificate-types";
import { CaRenewalType, CaStatus, CaType } from "@app/services/certificate-authority/certificate-authority-types"; import { CaRenewalType, CaStatus, CaType } from "@app/services/certificate-authority/certificate-authority-types";
import { import {
validateAltNamesField, validateAltNamesField,
@@ -573,7 +573,8 @@ export const registerCaRouter = async (server: FastifyZodProvider) => {
.refine((val) => ms(val) > 0, "TTL must be a positive number") .refine((val) => ms(val) > 0, "TTL must be a positive number")
.describe(CERTIFICATE_AUTHORITIES.ISSUE_CERT.ttl), .describe(CERTIFICATE_AUTHORITIES.ISSUE_CERT.ttl),
notBefore: validateCaDateField.optional().describe(CERTIFICATE_AUTHORITIES.ISSUE_CERT.notBefore), notBefore: validateCaDateField.optional().describe(CERTIFICATE_AUTHORITIES.ISSUE_CERT.notBefore),
notAfter: validateCaDateField.optional().describe(CERTIFICATE_AUTHORITIES.ISSUE_CERT.notAfter) notAfter: validateCaDateField.optional().describe(CERTIFICATE_AUTHORITIES.ISSUE_CERT.notAfter),
keyUsages: z.nativeEnum(CertKeyUsage).array().optional()
}) })
.refine( .refine(
(data) => { (data) => {

View File

@@ -7,7 +7,7 @@ import { CERTIFICATE_AUTHORITIES, CERTIFICATES } from "@app/lib/api-docs";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type"; import { AuthMode } from "@app/services/auth/auth-type";
import { CrlReason } from "@app/services/certificate/certificate-types"; import { CertKeyUsage, CrlReason } from "@app/services/certificate/certificate-types";
import { import {
validateAltNamesField, validateAltNamesField,
validateCaDateField validateCaDateField
@@ -86,7 +86,8 @@ export const registerCertRouter = async (server: FastifyZodProvider) => {
.refine((val) => ms(val) > 0, "TTL must be a positive number") .refine((val) => ms(val) > 0, "TTL must be a positive number")
.describe(CERTIFICATE_AUTHORITIES.ISSUE_CERT.ttl), .describe(CERTIFICATE_AUTHORITIES.ISSUE_CERT.ttl),
notBefore: validateCaDateField.optional().describe(CERTIFICATE_AUTHORITIES.ISSUE_CERT.notBefore), notBefore: validateCaDateField.optional().describe(CERTIFICATE_AUTHORITIES.ISSUE_CERT.notBefore),
notAfter: validateCaDateField.optional().describe(CERTIFICATE_AUTHORITIES.ISSUE_CERT.notAfter) notAfter: validateCaDateField.optional().describe(CERTIFICATE_AUTHORITIES.ISSUE_CERT.notAfter),
keyUsages: z.nativeEnum(CertKeyUsage).array().optional()
}) })
.refine( .refine(
(data) => { (data) => {

View File

@@ -19,7 +19,7 @@ import { TProjectDALFactory } from "@app/services/project/project-dal";
import { getProjectKmsCertificateKeyId } from "@app/services/project/project-fns"; import { getProjectKmsCertificateKeyId } from "@app/services/project/project-fns";
import { TCertificateAuthorityCrlDALFactory } from "../../ee/services/certificate-authority-crl/certificate-authority-crl-dal"; import { TCertificateAuthorityCrlDALFactory } from "../../ee/services/certificate-authority-crl/certificate-authority-crl-dal";
import { CertKeyAlgorithm, CertStatus } from "../certificate/certificate-types"; import { CertKeyAlgorithm, CertKeyUsage, CertStatus } from "../certificate/certificate-types";
import { TCertificateTemplateDALFactory } from "../certificate-template/certificate-template-dal"; import { TCertificateTemplateDALFactory } from "../certificate-template/certificate-template-dal";
import { validateCertificateDetailsAgainstTemplate } from "../certificate-template/certificate-template-fns"; import { validateCertificateDetailsAgainstTemplate } from "../certificate-template/certificate-template-fns";
import { TCertificateAuthorityCertDALFactory } from "./certificate-authority-cert-dal"; import { TCertificateAuthorityCertDALFactory } from "./certificate-authority-cert-dal";
@@ -1052,7 +1052,8 @@ export const certificateAuthorityServiceFactory = ({
actorId, actorId,
actorAuthMethod, actorAuthMethod,
actor, actor,
actorOrgId actorOrgId,
keyUsages
}: TIssueCertFromCaDTO) => { }: TIssueCertFromCaDTO) => {
let ca: TCertificateAuthorities | undefined; let ca: TCertificateAuthorities | undefined;
let certificateTemplate: TCertificateTemplates | undefined; let certificateTemplate: TCertificateTemplates | undefined;
@@ -1170,14 +1171,37 @@ export const certificateAuthorityServiceFactory = ({
const distributionPointUrl = `${appCfg.SITE_URL}/api/v1/pki/crl/${caCrl.id}`; const distributionPointUrl = `${appCfg.SITE_URL}/api/v1/pki/crl/${caCrl.id}`;
let selectedKeyUsages: CertKeyUsage[] = keyUsages ?? [];
if (keyUsages === undefined && !certificateTemplate) {
selectedKeyUsages = [CertKeyUsage.DIGITAL_SIGNATURE, CertKeyUsage.KEY_ENCIPHERMENT];
}
if (keyUsages === undefined && certificateTemplate) {
selectedKeyUsages = (certificateTemplate.keyUsages ?? []) as CertKeyUsage[];
}
if (keyUsages?.length && certificateTemplate) {
const validKeyUsages = certificateTemplate.keyUsages || [];
if (keyUsages.some((keyUsage) => !validKeyUsages.includes(keyUsage))) {
throw new BadRequestError({
message: "Invalid key usage value for certificate"
});
}
selectedKeyUsages = keyUsages;
}
const extensions: x509.Extension[] = [ const extensions: x509.Extension[] = [
new x509.KeyUsagesExtension(x509.KeyUsageFlags.digitalSignature | x509.KeyUsageFlags.keyEncipherment, true),
new x509.BasicConstraintsExtension(false), new x509.BasicConstraintsExtension(false),
new x509.CRLDistributionPointsExtension([distributionPointUrl]), new x509.CRLDistributionPointsExtension([distributionPointUrl]),
await x509.AuthorityKeyIdentifierExtension.create(caCertObj, false), await x509.AuthorityKeyIdentifierExtension.create(caCertObj, false),
await x509.SubjectKeyIdentifierExtension.create(csrObj.publicKey) await x509.SubjectKeyIdentifierExtension.create(csrObj.publicKey)
]; ];
const keyUsagesBitValue = selectedKeyUsages.reduce((accum, keyUsage) => accum | x509.KeyUsageFlags[keyUsage], 0);
if (keyUsagesBitValue) {
extensions.push(new x509.KeyUsagesExtension(keyUsagesBitValue, true));
}
let altNamesArray: { let altNamesArray: {
type: "email" | "dns"; type: "email" | "dns";
value: string; value: string;
@@ -1259,7 +1283,8 @@ export const certificateAuthorityServiceFactory = ({
altNames, altNames,
serialNumber, serialNumber,
notBefore: notBeforeDate, notBefore: notBeforeDate,
notAfter: notAfterDate notAfter: notAfterDate,
keyUsages: selectedKeyUsages
}, },
tx tx
); );

View File

@@ -4,7 +4,7 @@ import { TKmsServiceFactory } from "@app/services/kms/kms-service";
import { TProjectDALFactory } from "@app/services/project/project-dal"; import { TProjectDALFactory } from "@app/services/project/project-dal";
import { TCertificateAuthorityCrlDALFactory } from "../../ee/services/certificate-authority-crl/certificate-authority-crl-dal"; import { TCertificateAuthorityCrlDALFactory } from "../../ee/services/certificate-authority-crl/certificate-authority-crl-dal";
import { CertKeyAlgorithm } from "../certificate/certificate-types"; import { CertKeyAlgorithm, CertKeyUsage } from "../certificate/certificate-types";
import { TCertificateAuthorityCertDALFactory } from "./certificate-authority-cert-dal"; import { TCertificateAuthorityCertDALFactory } from "./certificate-authority-cert-dal";
import { TCertificateAuthorityDALFactory } from "./certificate-authority-dal"; import { TCertificateAuthorityDALFactory } from "./certificate-authority-dal";
import { TCertificateAuthoritySecretDALFactory } from "./certificate-authority-secret-dal"; import { TCertificateAuthoritySecretDALFactory } from "./certificate-authority-secret-dal";
@@ -97,6 +97,7 @@ export type TIssueCertFromCaDTO = {
ttl: string; ttl: string;
notBefore?: string; notBefore?: string;
notAfter?: string; notAfter?: string;
keyUsages?: CertKeyUsage[];
} & Omit<TProjectPermission, "projectId">; } & Omit<TProjectPermission, "projectId">;
export type TSignCertFromCaDTO = export type TSignCertFromCaDTO =

View File

@@ -50,9 +50,7 @@ export const certificateTemplateDALFactory = (db: TDbClient) => {
) )
.first(); .first();
if (certTemplate) { return certTemplate;
return { ...certTemplate, keyUsages: certTemplate.keyUsages || [] };
}
} catch (error) { } catch (error) {
throw new DatabaseError({ error, name: "Get certificate template by ID" }); throw new DatabaseError({ error, name: "Get certificate template by ID" });
} }

View File

@@ -9,11 +9,11 @@ export const sanitizedCertificateTemplate = CertificateTemplatesSchema.pick({
commonName: true, commonName: true,
subjectAlternativeName: true, subjectAlternativeName: true,
pkiCollectionId: true, pkiCollectionId: true,
ttl: true ttl: true,
keyUsages: true
}).merge( }).merge(
z.object({ z.object({
projectId: z.string(), projectId: z.string(),
caName: z.string(), caName: z.string()
keyUsages: z.string().array()
}) })
); );

View File

@@ -1,4 +1,5 @@
import { CertKeyAlgorithm } from "../certificates/enums"; import { CertKeyAlgorithm } from "../certificates/enums";
import { CertKeyUsage } from "../certificates/types";
import { CaRenewalType, CaStatus, CaType } from "./enums"; import { CaRenewalType, CaStatus, CaType } from "./enums";
export type TCertificateAuthority = { export type TCertificateAuthority = {
@@ -91,6 +92,7 @@ export type TCreateCertificateDTO = {
ttl: string; // string compatible with ms ttl: string; // string compatible with ms
notBefore?: string; notBefore?: string;
notAfter?: string; notAfter?: string;
keyUsages: CertKeyUsage[];
}; };
export type TCreateCertificateResponse = { export type TCreateCertificateResponse = {

View File

@@ -11,6 +11,7 @@ export type TCertificate = {
serialNumber: string; serialNumber: string;
notBefore: string; notBefore: string;
notAfter: string; notAfter: string;
keyUsages: CertKeyUsage[];
}; };
export type TDeleteCertDTO = { export type TDeleteCertDTO = {
@@ -35,3 +36,15 @@ export enum CertKeyUsage {
ENCIPHER_ONLY = "encipherOnly", ENCIPHER_ONLY = "encipherOnly",
DECIPHER_ONLY = "decipherOnly" DECIPHER_ONLY = "decipherOnly"
} }
export const KEY_USAGES_OPTIONS = [
{ value: CertKeyUsage.DIGITAL_SIGNATURE, label: "Digital Signature" },
{ value: CertKeyUsage.KEY_ENCIPHERMENT, label: "Key Encipherment" },
{ value: CertKeyUsage.NON_REPUDIATION, label: "Non Repudiation" },
{ value: CertKeyUsage.DATA_ENCIPHERMENT, label: "Data Encipherment" },
{ value: CertKeyUsage.KEY_AGREEMENT, label: "Key Agreement" },
{ value: CertKeyUsage.KEY_CERT_SIGN, label: "Certificate Sign" },
{ value: CertKeyUsage.CRL_SIGN, label: "CRL Sign" },
{ value: CertKeyUsage.ENCIPHER_ONLY, label: "Encipher Only" },
{ value: CertKeyUsage.DECIPHER_ONLY, label: "Decipher Only" }
] as const;

View File

@@ -7,7 +7,12 @@ import { z } from "zod";
import { createNotification } from "@app/components/notifications"; import { createNotification } from "@app/components/notifications";
import { import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
Button, Button,
Checkbox,
FormControl, FormControl,
FormLabel, FormLabel,
Input, Input,
@@ -28,6 +33,7 @@ import {
useListWorkspacePkiCollections useListWorkspacePkiCollections
} from "@app/hooks/api"; } from "@app/hooks/api";
import { caTypeToNameMap } from "@app/hooks/api/ca/constants"; import { caTypeToNameMap } from "@app/hooks/api/ca/constants";
import { CertKeyUsage, KEY_USAGES_OPTIONS } from "@app/hooks/api/certificates/types";
import { UsePopUpState } from "@app/hooks/usePopUp"; import { UsePopUpState } from "@app/hooks/usePopUp";
import { CertificateContent } from "./CertificateContent"; import { CertificateContent } from "./CertificateContent";
@@ -39,7 +45,18 @@ const schema = z.object({
friendlyName: z.string(), friendlyName: z.string(),
commonName: z.string().trim().min(1), commonName: z.string().trim().min(1),
altNames: z.string(), altNames: z.string(),
ttl: z.string().trim() ttl: z.string().trim(),
keyUsages: z.object({
[CertKeyUsage.DIGITAL_SIGNATURE]: z.boolean().optional(),
[CertKeyUsage.KEY_ENCIPHERMENT]: z.boolean().optional(),
[CertKeyUsage.NON_REPUDIATION]: z.boolean().optional(),
[CertKeyUsage.DATA_ENCIPHERMENT]: z.boolean().optional(),
[CertKeyUsage.KEY_AGREEMENT]: z.boolean().optional(),
[CertKeyUsage.KEY_CERT_SIGN]: z.boolean().optional(),
[CertKeyUsage.CRL_SIGN]: z.boolean().optional(),
[CertKeyUsage.ENCIPHER_ONLY]: z.boolean().optional(),
[CertKeyUsage.DECIPHER_ONLY]: z.boolean().optional()
})
}); });
export type FormData = z.infer<typeof schema>; export type FormData = z.infer<typeof schema>;
@@ -88,7 +105,13 @@ export const CertificateModal = ({ popUp, handlePopUpToggle }: Props) => {
setValue, setValue,
watch watch
} = useForm<FormData>({ } = useForm<FormData>({
resolver: zodResolver(schema) resolver: zodResolver(schema),
defaultValues: {
keyUsages: {
[CertKeyUsage.DIGITAL_SIGNATURE]: true,
[CertKeyUsage.KEY_ENCIPHERMENT]: true
}
}
}); });
const selectedCertTemplateId = watch("certificateTemplateId"); const selectedCertTemplateId = watch("certificateTemplateId");
@@ -107,7 +130,8 @@ export const CertificateModal = ({ popUp, handlePopUpToggle }: Props) => {
commonName: cert.commonName, commonName: cert.commonName,
altNames: cert.altNames, altNames: cert.altNames,
certificateTemplateId: cert.certificateTemplateId ?? CERT_TEMPLATE_NONE_VALUE, certificateTemplateId: cert.certificateTemplateId ?? CERT_TEMPLATE_NONE_VALUE,
ttl: "" ttl: "",
keyUsages: Object.fromEntries(cert.keyUsages.map((name) => [name, true]))
}); });
} else { } else {
reset({ reset({
@@ -116,7 +140,11 @@ export const CertificateModal = ({ popUp, handlePopUpToggle }: Props) => {
commonName: "", commonName: "",
altNames: "", altNames: "",
ttl: "", ttl: "",
certificateTemplateId: CERT_TEMPLATE_NONE_VALUE certificateTemplateId: CERT_TEMPLATE_NONE_VALUE,
keyUsages: {
[CertKeyUsage.DIGITAL_SIGNATURE]: true,
[CertKeyUsage.KEY_ENCIPHERMENT]: true
}
}); });
} }
}, [cert]); }, [cert]);
@@ -124,6 +152,10 @@ export const CertificateModal = ({ popUp, handlePopUpToggle }: Props) => {
useEffect(() => { useEffect(() => {
if (!cert && selectedCertTemplate) { if (!cert && selectedCertTemplate) {
setValue("ttl", selectedCertTemplate.ttl); setValue("ttl", selectedCertTemplate.ttl);
setValue(
"keyUsages",
Object.fromEntries(selectedCertTemplate.keyUsages.map((name) => [name, true]))
);
} }
}, [selectedCertTemplate, cert]); }, [selectedCertTemplate, cert]);
@@ -133,7 +165,8 @@ export const CertificateModal = ({ popUp, handlePopUpToggle }: Props) => {
collectionId, collectionId,
commonName, commonName,
altNames, altNames,
ttl ttl,
keyUsages
}: FormData) => { }: FormData) => {
try { try {
if (!currentWorkspace?.slug) return; if (!currentWorkspace?.slug) return;
@@ -146,7 +179,10 @@ export const CertificateModal = ({ popUp, handlePopUpToggle }: Props) => {
friendlyName, friendlyName,
commonName, commonName,
altNames, altNames,
ttl ttl,
keyUsages: Object.entries(keyUsages)
.filter(([, value]) => value)
.map(([key]) => key as CertKeyUsage)
}); });
reset(); reset();
@@ -363,8 +399,52 @@ export const CertificateModal = ({ popUp, handlePopUpToggle }: Props) => {
</FormControl> </FormControl>
)} )}
/> />
<Accordion type="single" collapsible className="w-full">
<AccordionItem value="key-usages" className="data-[state=open]:border-none">
<AccordionTrigger className="h-fit flex-none pl-1 text-sm">
<div className="order-1 ml-3">Key Usages</div>
</AccordionTrigger>
<AccordionContent>
<Controller
control={control}
name="keyUsages"
render={({ field: { onChange, value }, fieldState: { error } }) => {
return (
<FormControl
label="Key Usages"
errorText={error?.message}
isError={Boolean(error)}
>
<div className="mt-2 mb-7 grid grid-cols-2 gap-2">
{KEY_USAGES_OPTIONS.map(({ label, value: optionValue }) => {
return (
<Checkbox
id={optionValue}
key={optionValue}
className="data-[state=checked]:bg-primary"
isDisabled={Boolean(cert)}
isChecked={value[optionValue]}
onCheckedChange={(state) => {
onChange({
...value,
[optionValue]: state
});
}}
>
{label}
</Checkbox>
);
})}
</div>
</FormControl>
);
}}
/>
</AccordionContent>
</AccordionItem>
</Accordion>
{!cert && ( {!cert && (
<div className="flex items-center"> <div className="mt-4 flex items-center">
<Button <Button
className="mr-4" className="mr-4"
size="sm" size="sm"

View File

@@ -33,7 +33,7 @@ import {
useUpdateCertTemplate useUpdateCertTemplate
} from "@app/hooks/api"; } from "@app/hooks/api";
import { caTypeToNameMap } from "@app/hooks/api/ca/constants"; import { caTypeToNameMap } from "@app/hooks/api/ca/constants";
import { CertKeyUsage } from "@app/hooks/api/certificates/types"; import { CertKeyUsage, KEY_USAGES_OPTIONS } from "@app/hooks/api/certificates/types";
import { UsePopUpState } from "@app/hooks/usePopUp"; import { UsePopUpState } from "@app/hooks/usePopUp";
const validateTemplateRegexField = z const validateTemplateRegexField = z
@@ -77,18 +77,6 @@ type Props = {
) => void; ) => void;
}; };
const KEY_USAGES_OPTIONS = [
{ value: CertKeyUsage.DIGITAL_SIGNATURE, label: "Digital Signature" },
{ value: CertKeyUsage.KEY_ENCIPHERMENT, label: "Key Encipherment" },
{ value: CertKeyUsage.NON_REPUDIATION, label: "Non Repudiation" },
{ value: CertKeyUsage.DATA_ENCIPHERMENT, label: "Data Encipherment" },
{ value: CertKeyUsage.KEY_AGREEMENT, label: "Key Agreement" },
{ value: CertKeyUsage.KEY_CERT_SIGN, label: "Key Certification Sign" },
{ value: CertKeyUsage.CRL_SIGN, label: "CRL Sign" },
{ value: CertKeyUsage.ENCIPHER_ONLY, label: "Encipher Only" },
{ value: CertKeyUsage.DECIPHER_ONLY, label: "Decipher Only" }
] as const;
export const CertificateTemplateModal = ({ popUp, handlePopUpToggle, caId }: Props) => { export const CertificateTemplateModal = ({ popUp, handlePopUpToggle, caId }: Props) => {
const { currentWorkspace } = useWorkspace(); const { currentWorkspace } = useWorkspace();