mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-15 10:35:17 +00:00
feat: kmip create and get
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
import { ProjectType } from "@app/db/schemas";
|
||||
import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors";
|
||||
import { TKmsKeyDALFactory } from "@app/services/kms/kms-key-dal";
|
||||
import { TKmsServiceFactory } from "@app/services/kms/kms-service";
|
||||
import { TProjectDALFactory } from "@app/services/project/project-dal";
|
||||
|
||||
import { TKmipClientDALFactory } from "./kmip-client-dal";
|
||||
import { KmipPermission } from "./kmip-enum";
|
||||
import { TKmipCreateDTO, TKmipGetDTO } from "./kmip-types";
|
||||
|
||||
type TKmipOperationServiceFactoryDep = {
|
||||
kmsService: TKmsServiceFactory;
|
||||
kmsDAL: TKmsKeyDALFactory;
|
||||
kmipClientDAL: TKmipClientDALFactory;
|
||||
projectDAL: Pick<TProjectDALFactory, "getProjectFromSplitId" | "findById">;
|
||||
};
|
||||
|
||||
export type TKmipOperationServiceFactory = ReturnType<typeof kmipOperationServiceFactory>;
|
||||
|
||||
export const kmipOperationServiceFactory = ({
|
||||
kmsService,
|
||||
kmsDAL,
|
||||
projectDAL,
|
||||
kmipClientDAL
|
||||
}: TKmipOperationServiceFactoryDep) => {
|
||||
const create = async ({ projectId: preSplitProjectId, clientId, encryptionAlgorithm }: TKmipCreateDTO) => {
|
||||
let projectId = preSplitProjectId;
|
||||
const cmekProjectFromSplit = await projectDAL.getProjectFromSplitId(projectId, ProjectType.KMS);
|
||||
if (cmekProjectFromSplit) {
|
||||
projectId = cmekProjectFromSplit.id;
|
||||
}
|
||||
|
||||
const project = await projectDAL.findById(projectId);
|
||||
const kmipClient = await kmipClientDAL.findOne({
|
||||
id: clientId,
|
||||
projectId
|
||||
});
|
||||
|
||||
if (!kmipClient.permissions?.includes(KmipPermission.Create)) {
|
||||
throw new ForbiddenRequestError({
|
||||
message: "Client does not have sufficient permission to perform KMIP create"
|
||||
});
|
||||
}
|
||||
|
||||
const kmsKey = await kmsService.generateKmsKey({
|
||||
encryptionAlgorithm,
|
||||
orgId: project.orgId,
|
||||
projectId,
|
||||
isReserved: false
|
||||
});
|
||||
|
||||
return kmsKey;
|
||||
};
|
||||
|
||||
const get = async ({ projectId: preSplitProjectId, id, clientId }: TKmipGetDTO) => {
|
||||
let projectId = preSplitProjectId;
|
||||
const cmekProjectFromSplit = await projectDAL.getProjectFromSplitId(projectId, ProjectType.KMS);
|
||||
|
||||
if (cmekProjectFromSplit) {
|
||||
projectId = cmekProjectFromSplit.id;
|
||||
}
|
||||
|
||||
const kmipClient = await kmipClientDAL.findOne({
|
||||
id: clientId,
|
||||
projectId
|
||||
});
|
||||
|
||||
if (!kmipClient.permissions?.includes(KmipPermission.Get)) {
|
||||
throw new ForbiddenRequestError({
|
||||
message: "Client does not have sufficient permission to perform KMIP get"
|
||||
});
|
||||
}
|
||||
|
||||
const key = await kmsDAL.findOne({
|
||||
id,
|
||||
projectId
|
||||
});
|
||||
|
||||
if (!key) {
|
||||
throw new NotFoundError({ message: `Key with ID ${id} not found` });
|
||||
}
|
||||
|
||||
if (key.isReserved) {
|
||||
throw new BadRequestError({ message: "Cannot get reserved keys" });
|
||||
}
|
||||
|
||||
const completeKeyDetails = await kmsDAL.findByIdWithAssociatedKms(id);
|
||||
|
||||
if (!completeKeyDetails.internalKms) {
|
||||
throw new BadRequestError({
|
||||
message: "Cannot get external key"
|
||||
});
|
||||
}
|
||||
|
||||
const kmsKey = await kmsService.getKeyMaterial({
|
||||
kmsId: key.id
|
||||
});
|
||||
|
||||
return {
|
||||
id: key.id,
|
||||
value: kmsKey.toString("base64"),
|
||||
algorithm: completeKeyDetails.internalKms.encryptionAlgorithm
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
create,
|
||||
get
|
||||
};
|
||||
};
|
||||
@@ -18,6 +18,7 @@ import { TKmipClientCertificateDALFactory } from "./kmip-client-certificate-dal"
|
||||
import { TKmipClientDALFactory } from "./kmip-client-dal";
|
||||
import { INSTANCE_KMIP_CONFIG_ID } from "./kmip-constants";
|
||||
import { TKmipInstanceConfigDALFactory } from "./kmip-instance-config-dal";
|
||||
import { TKmipInstanceServerCertificateDALFactory } from "./kmip-instance-server-certificate-dal";
|
||||
import {
|
||||
TCreateKmipClientCertificateDTO,
|
||||
TCreateKmipClientDTO,
|
||||
@@ -30,6 +31,7 @@ import {
|
||||
type TKmipServiceFactoryDep = {
|
||||
kmipClientDAL: TKmipClientDALFactory;
|
||||
kmipClientCertificateDAL: TKmipClientCertificateDALFactory;
|
||||
kmipInstanceServerCertificateDAL: TKmipInstanceServerCertificateDALFactory;
|
||||
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
||||
kmsService: Pick<TKmsServiceFactory, "decryptWithRootKey">;
|
||||
kmipInstanceConfigDAL: TKmipInstanceConfigDALFactory;
|
||||
@@ -42,7 +44,8 @@ export const kmipServiceFactory = ({
|
||||
permissionService,
|
||||
kmipClientCertificateDAL,
|
||||
kmipInstanceConfigDAL,
|
||||
kmsService
|
||||
kmsService,
|
||||
kmipInstanceServerCertificateDAL
|
||||
}: TKmipServiceFactoryDep) => {
|
||||
const createKmipClient = async ({
|
||||
actor,
|
||||
@@ -325,12 +328,33 @@ export const kmipServiceFactory = ({
|
||||
};
|
||||
};
|
||||
|
||||
const getServerCertificateBySerialNumber = async (serialNumber: string) => {
|
||||
const serverCert = await kmipInstanceServerCertificateDAL.findOne({
|
||||
serialNumber
|
||||
});
|
||||
|
||||
if (!serverCert) {
|
||||
throw new NotFoundError({
|
||||
message: "Server certificate not found"
|
||||
});
|
||||
}
|
||||
|
||||
const decryptWithRootKey = kmsService.decryptWithRootKey();
|
||||
const parsedCertificate = new x509.X509Certificate(decryptWithRootKey(serverCert.encryptedCertificate));
|
||||
|
||||
return {
|
||||
publicKey: parsedCertificate.publicKey.toString("pem"),
|
||||
keyAlgorithm: serverCert.keyAlgorithm as CertKeyAlgorithm
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
createKmipClient,
|
||||
updateKmipClient,
|
||||
deleteKmipClient,
|
||||
getKmipClient,
|
||||
listKmipClientsByProjectId,
|
||||
createKmipClientCertificate
|
||||
createKmipClientCertificate,
|
||||
getServerCertificateBySerialNumber
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { SymmetricEncryption } from "@app/lib/crypto/cipher";
|
||||
import { OrderByDirection, TProjectPermission } from "@app/lib/types";
|
||||
import { CertKeyAlgorithm } from "@app/services/certificate/certificate-types";
|
||||
|
||||
@@ -41,3 +42,15 @@ export type TListKmipClientsByProjectIdDTO = {
|
||||
orderDirection?: OrderByDirection;
|
||||
search?: string;
|
||||
} & TProjectPermission;
|
||||
|
||||
export type TKmipCreateDTO = {
|
||||
clientId: string;
|
||||
projectId: string;
|
||||
encryptionAlgorithm: SymmetricEncryption;
|
||||
};
|
||||
|
||||
export type TKmipGetDTO = {
|
||||
clientId: string;
|
||||
projectId: string;
|
||||
id: string;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user