mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
feat: added encrypt/decrypt with key for kms service and changed kms encrytion to hoc to avoid back to back db calls
This commit is contained in:
@@ -17,7 +17,7 @@ type TCertificateAuthorityCrlServiceFactoryDep = {
|
|||||||
certificateAuthorityDAL: Pick<TCertificateAuthorityDALFactory, "findById">;
|
certificateAuthorityDAL: Pick<TCertificateAuthorityDALFactory, "findById">;
|
||||||
certificateAuthorityCrlDAL: Pick<TCertificateAuthorityCrlDALFactory, "findOne">;
|
certificateAuthorityCrlDAL: Pick<TCertificateAuthorityCrlDALFactory, "findOne">;
|
||||||
projectDAL: Pick<TProjectDALFactory, "findOne" | "updateById" | "transaction">;
|
projectDAL: Pick<TProjectDALFactory, "findOne" | "updateById" | "transaction">;
|
||||||
kmsService: Pick<TKmsServiceFactory, "decrypt" | "generateKmsKey">;
|
kmsService: Pick<TKmsServiceFactory, "decryptWithKmsKey" | "generateKmsKey">;
|
||||||
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
||||||
licenseService: Pick<TLicenseServiceFactory, "getPlan">;
|
licenseService: Pick<TLicenseServiceFactory, "getPlan">;
|
||||||
};
|
};
|
||||||
@@ -68,11 +68,11 @@ export const certificateAuthorityCrlServiceFactory = ({
|
|||||||
kmsService
|
kmsService
|
||||||
});
|
});
|
||||||
|
|
||||||
const decryptedCrl = await kmsService.decrypt({
|
const kmsDecryptor = await kmsService.decryptWithKmsKey({
|
||||||
kmsId: keyId,
|
kmsId: keyId
|
||||||
cipherTextBlob: caCrl.encryptedCrl
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const decryptedCrl = kmsDecryptor({ cipherTextBlob: caCrl.encryptedCrl });
|
||||||
const crl = new x509.X509Crl(decryptedCrl);
|
const crl = new x509.X509Crl(decryptedCrl);
|
||||||
|
|
||||||
const base64crl = crl.toString("base64");
|
const base64crl = crl.toString("base64");
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import { ExternalKmsAwsSchema, KmsProviders } from "./providers/model";
|
|||||||
|
|
||||||
type TExternalKmsServiceFactoryDep = {
|
type TExternalKmsServiceFactoryDep = {
|
||||||
externalKmsDAL: TExternalKmsDALFactory;
|
externalKmsDAL: TExternalKmsDALFactory;
|
||||||
kmsService: Pick<TKmsServiceFactory, "getOrgKmsKeyId" | "encrypt" | "decrypt">;
|
kmsService: Pick<TKmsServiceFactory, "getOrgKmsKeyId" | "encryptWithKmsKey" | "decryptWithKmsKey">;
|
||||||
kmsDAL: Pick<TKmsKeyDALFactory, "create" | "updateById" | "findById" | "deleteById" | "findOne">;
|
kmsDAL: Pick<TKmsKeyDALFactory, "create" | "updateById" | "findById" | "deleteById" | "findOne">;
|
||||||
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
|
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
|
||||||
};
|
};
|
||||||
@@ -70,8 +70,10 @@ export const externalKmsServiceFactory = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const orgKmsKeyId = await kmsService.getOrgKmsKeyId(actorOrgId);
|
const orgKmsKeyId = await kmsService.getOrgKmsKeyId(actorOrgId);
|
||||||
const { cipherTextBlob: encryptedProviderInputs } = await kmsService.encrypt({
|
const kmsEncryptor = await kmsService.encryptWithKmsKey({
|
||||||
kmsId: orgKmsKeyId,
|
kmsId: orgKmsKeyId
|
||||||
|
});
|
||||||
|
const { cipherTextBlob: encryptedProviderInputs } = kmsEncryptor({
|
||||||
plainText: Buffer.from(sanitizedProviderInput, "utf8")
|
plainText: Buffer.from(sanitizedProviderInput, "utf8")
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -126,8 +128,10 @@ export const externalKmsServiceFactory = ({
|
|||||||
const orgDefaultKmsId = await kmsService.getOrgKmsKeyId(kmsDoc.orgId);
|
const orgDefaultKmsId = await kmsService.getOrgKmsKeyId(kmsDoc.orgId);
|
||||||
let sanitizedProviderInput = "";
|
let sanitizedProviderInput = "";
|
||||||
if (provider) {
|
if (provider) {
|
||||||
const decryptedProviderInputBlob = await kmsService.decrypt({
|
const kmsDecryptor = await kmsService.decryptWithKmsKey({
|
||||||
kmsId: orgDefaultKmsId,
|
kmsId: orgDefaultKmsId
|
||||||
|
});
|
||||||
|
const decryptedProviderInputBlob = kmsDecryptor({
|
||||||
cipherTextBlob: externalKmsDoc.encryptedProviderInputs
|
cipherTextBlob: externalKmsDoc.encryptedProviderInputs
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -150,8 +154,10 @@ export const externalKmsServiceFactory = ({
|
|||||||
|
|
||||||
let encryptedProviderInputs: Buffer | undefined;
|
let encryptedProviderInputs: Buffer | undefined;
|
||||||
if (sanitizedProviderInput) {
|
if (sanitizedProviderInput) {
|
||||||
const { cipherTextBlob } = await kmsService.encrypt({
|
const kmsEncryptor = await kmsService.encryptWithKmsKey({
|
||||||
kmsId: orgDefaultKmsId,
|
kmsId: orgDefaultKmsId
|
||||||
|
});
|
||||||
|
const { cipherTextBlob } = kmsEncryptor({
|
||||||
plainText: Buffer.from(sanitizedProviderInput, "utf8")
|
plainText: Buffer.from(sanitizedProviderInput, "utf8")
|
||||||
});
|
});
|
||||||
encryptedProviderInputs = cipherTextBlob;
|
encryptedProviderInputs = cipherTextBlob;
|
||||||
@@ -234,8 +240,10 @@ export const externalKmsServiceFactory = ({
|
|||||||
if (!externalKmsDoc) throw new BadRequestError({ message: "External kms not found" });
|
if (!externalKmsDoc) throw new BadRequestError({ message: "External kms not found" });
|
||||||
|
|
||||||
const orgDefaultKmsId = await kmsService.getOrgKmsKeyId(kmsDoc.orgId);
|
const orgDefaultKmsId = await kmsService.getOrgKmsKeyId(kmsDoc.orgId);
|
||||||
const decryptedProviderInputBlob = await kmsService.decrypt({
|
const kmsDecryptor = await kmsService.decryptWithKmsKey({
|
||||||
kmsId: orgDefaultKmsId,
|
kmsId: orgDefaultKmsId
|
||||||
|
});
|
||||||
|
const decryptedProviderInputBlob = kmsDecryptor({
|
||||||
cipherTextBlob: externalKmsDoc.encryptedProviderInputs
|
cipherTextBlob: externalKmsDoc.encryptedProviderInputs
|
||||||
});
|
});
|
||||||
switch (externalKmsDoc.provider) {
|
switch (externalKmsDoc.provider) {
|
||||||
@@ -271,10 +279,13 @@ export const externalKmsServiceFactory = ({
|
|||||||
if (!externalKmsDoc) throw new BadRequestError({ message: "External kms not found" });
|
if (!externalKmsDoc) throw new BadRequestError({ message: "External kms not found" });
|
||||||
|
|
||||||
const orgDefaultKmsId = await kmsService.getOrgKmsKeyId(kmsDoc.orgId);
|
const orgDefaultKmsId = await kmsService.getOrgKmsKeyId(kmsDoc.orgId);
|
||||||
const decryptedProviderInputBlob = await kmsService.decrypt({
|
const kmsDecryptor = await kmsService.decryptWithKmsKey({
|
||||||
kmsId: orgDefaultKmsId,
|
kmsId: orgDefaultKmsId
|
||||||
|
});
|
||||||
|
const decryptedProviderInputBlob = kmsDecryptor({
|
||||||
cipherTextBlob: externalKmsDoc.encryptedProviderInputs
|
cipherTextBlob: externalKmsDoc.encryptedProviderInputs
|
||||||
});
|
});
|
||||||
|
|
||||||
switch (externalKmsDoc.provider) {
|
switch (externalKmsDoc.provider) {
|
||||||
case KmsProviders.Aws: {
|
case KmsProviders.Aws: {
|
||||||
const decryptedProviderInput = await ExternalKmsAwsSchema.parseAsync(
|
const decryptedProviderInput = await ExternalKmsAwsSchema.parseAsync(
|
||||||
|
|||||||
@@ -75,8 +75,10 @@ export const getCaCredentials = async ({
|
|||||||
kmsService
|
kmsService
|
||||||
});
|
});
|
||||||
|
|
||||||
const decryptedPrivateKey = await kmsService.decrypt({
|
const kmsDecryptor = await kmsService.decryptWithKmsKey({
|
||||||
kmsId: keyId,
|
kmsId: keyId
|
||||||
|
});
|
||||||
|
const decryptedPrivateKey = kmsDecryptor({
|
||||||
cipherTextBlob: caSecret.encryptedPrivateKey
|
cipherTextBlob: caSecret.encryptedPrivateKey
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -123,15 +125,17 @@ export const getCaCertChain = async ({
|
|||||||
kmsService
|
kmsService
|
||||||
});
|
});
|
||||||
|
|
||||||
const decryptedCaCert = await kmsService.decrypt({
|
const kmsDecryptor = await kmsService.decryptWithKmsKey({
|
||||||
kmsId: keyId,
|
kmsId: keyId
|
||||||
|
});
|
||||||
|
|
||||||
|
const decryptedCaCert = kmsDecryptor({
|
||||||
cipherTextBlob: caCert.encryptedCertificate
|
cipherTextBlob: caCert.encryptedCertificate
|
||||||
});
|
});
|
||||||
|
|
||||||
const caCertObj = new x509.X509Certificate(decryptedCaCert);
|
const caCertObj = new x509.X509Certificate(decryptedCaCert);
|
||||||
|
|
||||||
const decryptedChain = await kmsService.decrypt({
|
const decryptedChain = kmsDecryptor({
|
||||||
kmsId: keyId,
|
|
||||||
cipherTextBlob: caCert.encryptedCertificateChain
|
cipherTextBlob: caCert.encryptedCertificateChain
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -168,8 +172,11 @@ export const rebuildCaCrl = async ({
|
|||||||
kmsService
|
kmsService
|
||||||
});
|
});
|
||||||
|
|
||||||
const privateKey = await kmsService.decrypt({
|
const kmsDecryptor = await kmsService.decryptWithKmsKey({
|
||||||
kmsId: keyId,
|
kmsId: keyId
|
||||||
|
});
|
||||||
|
|
||||||
|
const privateKey = kmsDecryptor({
|
||||||
cipherTextBlob: caSecret.encryptedPrivateKey
|
cipherTextBlob: caSecret.encryptedPrivateKey
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -200,8 +207,10 @@ export const rebuildCaCrl = async ({
|
|||||||
signingKey: sk
|
signingKey: sk
|
||||||
});
|
});
|
||||||
|
|
||||||
const { cipherTextBlob: encryptedCrl } = await kmsService.encrypt({
|
const kmsEncryptor = await kmsService.encryptWithKmsKey({
|
||||||
kmsId: keyId,
|
kmsId: keyId
|
||||||
|
});
|
||||||
|
const { cipherTextBlob: encryptedCrl } = kmsEncryptor({
|
||||||
plainText: Buffer.from(new Uint8Array(crl.rawData))
|
plainText: Buffer.from(new Uint8Array(crl.rawData))
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ type TCertificateAuthorityQueueFactoryDep = {
|
|||||||
certificateAuthoritySecretDAL: TCertificateAuthoritySecretDALFactory;
|
certificateAuthoritySecretDAL: TCertificateAuthoritySecretDALFactory;
|
||||||
certificateDAL: TCertificateDALFactory;
|
certificateDAL: TCertificateDALFactory;
|
||||||
projectDAL: Pick<TProjectDALFactory, "findProjectBySlug" | "findOne" | "updateById" | "findById" | "transaction">;
|
projectDAL: Pick<TProjectDALFactory, "findProjectBySlug" | "findOne" | "updateById" | "findById" | "transaction">;
|
||||||
kmsService: Pick<TKmsServiceFactory, "generateKmsKey" | "encrypt" | "decrypt">;
|
kmsService: Pick<TKmsServiceFactory, "generateKmsKey" | "encryptWithKmsKey" | "decryptWithKmsKey">;
|
||||||
queueService: TQueueServiceFactory;
|
queueService: TQueueServiceFactory;
|
||||||
};
|
};
|
||||||
export type TCertificateAuthorityQueueFactory = ReturnType<typeof certificateAuthorityQueueFactory>;
|
export type TCertificateAuthorityQueueFactory = ReturnType<typeof certificateAuthorityQueueFactory>;
|
||||||
@@ -88,8 +88,10 @@ export const certificateAuthorityQueueFactory = ({
|
|||||||
kmsService
|
kmsService
|
||||||
});
|
});
|
||||||
|
|
||||||
const privateKey = await kmsService.decrypt({
|
const kmsDecryptor = await kmsService.decryptWithKmsKey({
|
||||||
kmsId: keyId,
|
kmsId: keyId
|
||||||
|
});
|
||||||
|
const privateKey = kmsDecryptor({
|
||||||
cipherTextBlob: caSecret.encryptedPrivateKey
|
cipherTextBlob: caSecret.encryptedPrivateKey
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -120,8 +122,10 @@ export const certificateAuthorityQueueFactory = ({
|
|||||||
signingKey: sk
|
signingKey: sk
|
||||||
});
|
});
|
||||||
|
|
||||||
const { cipherTextBlob: encryptedCrl } = await kmsService.encrypt({
|
const kmsEncryptor = await kmsService.encryptWithKmsKey({
|
||||||
kmsId: keyId,
|
kmsId: keyId
|
||||||
|
});
|
||||||
|
const { cipherTextBlob: encryptedCrl } = kmsEncryptor({
|
||||||
plainText: Buffer.from(new Uint8Array(crl.rawData))
|
plainText: Buffer.from(new Uint8Array(crl.rawData))
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ type TCertificateAuthorityServiceFactoryDep = {
|
|||||||
certificateDAL: Pick<TCertificateDALFactory, "transaction" | "create" | "find">;
|
certificateDAL: Pick<TCertificateDALFactory, "transaction" | "create" | "find">;
|
||||||
certificateBodyDAL: Pick<TCertificateBodyDALFactory, "create">;
|
certificateBodyDAL: Pick<TCertificateBodyDALFactory, "create">;
|
||||||
projectDAL: Pick<TProjectDALFactory, "findProjectBySlug" | "findOne" | "updateById" | "findById" | "transaction">;
|
projectDAL: Pick<TProjectDALFactory, "findProjectBySlug" | "findOne" | "updateById" | "findById" | "transaction">;
|
||||||
kmsService: Pick<TKmsServiceFactory, "generateKmsKey" | "encrypt" | "decrypt">;
|
kmsService: Pick<TKmsServiceFactory, "generateKmsKey" | "encryptWithKmsKey" | "decryptWithKmsKey">;
|
||||||
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -154,11 +154,14 @@ export const certificateAuthorityServiceFactory = ({
|
|||||||
tx
|
tx
|
||||||
);
|
);
|
||||||
|
|
||||||
const keyId = await getProjectKmsCertificateKeyId({
|
const certificateManagerKmsId = await getProjectKmsCertificateKeyId({
|
||||||
projectId: project.id,
|
projectId: project.id,
|
||||||
projectDAL,
|
projectDAL,
|
||||||
kmsService
|
kmsService
|
||||||
});
|
});
|
||||||
|
const kmsEncryptor = await kmsService.encryptWithKmsKey({
|
||||||
|
kmsId: certificateManagerKmsId
|
||||||
|
});
|
||||||
|
|
||||||
if (type === CaType.ROOT) {
|
if (type === CaType.ROOT) {
|
||||||
// note: create self-signed cert only applicable for root CA
|
// note: create self-signed cert only applicable for root CA
|
||||||
@@ -178,13 +181,11 @@ export const certificateAuthorityServiceFactory = ({
|
|||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
const { cipherTextBlob: encryptedCertificate } = await kmsService.encrypt({
|
const { cipherTextBlob: encryptedCertificate } = kmsEncryptor({
|
||||||
kmsId: keyId,
|
|
||||||
plainText: Buffer.from(new Uint8Array(cert.rawData))
|
plainText: Buffer.from(new Uint8Array(cert.rawData))
|
||||||
});
|
});
|
||||||
|
|
||||||
const { cipherTextBlob: encryptedCertificateChain } = await kmsService.encrypt({
|
const { cipherTextBlob: encryptedCertificateChain } = kmsEncryptor({
|
||||||
kmsId: keyId,
|
|
||||||
plainText: Buffer.alloc(0)
|
plainText: Buffer.alloc(0)
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -208,8 +209,7 @@ export const certificateAuthorityServiceFactory = ({
|
|||||||
signingKey: keys.privateKey
|
signingKey: keys.privateKey
|
||||||
});
|
});
|
||||||
|
|
||||||
const { cipherTextBlob: encryptedCrl } = await kmsService.encrypt({
|
const { cipherTextBlob: encryptedCrl } = kmsEncryptor({
|
||||||
kmsId: keyId,
|
|
||||||
plainText: Buffer.from(new Uint8Array(crl.rawData))
|
plainText: Buffer.from(new Uint8Array(crl.rawData))
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -224,8 +224,7 @@ export const certificateAuthorityServiceFactory = ({
|
|||||||
// https://nodejs.org/api/crypto.html#static-method-keyobjectfromkey
|
// https://nodejs.org/api/crypto.html#static-method-keyobjectfromkey
|
||||||
const skObj = KeyObject.from(keys.privateKey);
|
const skObj = KeyObject.from(keys.privateKey);
|
||||||
|
|
||||||
const { cipherTextBlob: encryptedPrivateKey } = await kmsService.encrypt({
|
const { cipherTextBlob: encryptedPrivateKey } = kmsEncryptor({
|
||||||
kmsId: keyId,
|
|
||||||
plainText: skObj.export({
|
plainText: skObj.export({
|
||||||
type: "pkcs8",
|
type: "pkcs8",
|
||||||
format: "der"
|
format: "der"
|
||||||
@@ -449,15 +448,17 @@ export const certificateAuthorityServiceFactory = ({
|
|||||||
|
|
||||||
const alg = keyAlgorithmToAlgCfg(ca.keyAlgorithm as CertKeyAlgorithm);
|
const alg = keyAlgorithmToAlgCfg(ca.keyAlgorithm as CertKeyAlgorithm);
|
||||||
|
|
||||||
const keyId = await getProjectKmsCertificateKeyId({
|
const certificateManagerKmsId = await getProjectKmsCertificateKeyId({
|
||||||
projectId: ca.projectId,
|
projectId: ca.projectId,
|
||||||
projectDAL,
|
projectDAL,
|
||||||
kmsService
|
kmsService
|
||||||
});
|
});
|
||||||
|
const kmsDecryptor = await kmsService.decryptWithKmsKey({
|
||||||
|
kmsId: certificateManagerKmsId
|
||||||
|
});
|
||||||
|
|
||||||
const caCert = await certificateAuthorityCertDAL.findOne({ caId: ca.id });
|
const caCert = await certificateAuthorityCertDAL.findOne({ caId: ca.id });
|
||||||
const decryptedCaCert = await kmsService.decrypt({
|
const decryptedCaCert = kmsDecryptor({
|
||||||
kmsId: keyId,
|
|
||||||
cipherTextBlob: caCert.encryptedCertificate
|
cipherTextBlob: caCert.encryptedCertificate
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -605,19 +606,20 @@ export const certificateAuthorityServiceFactory = ({
|
|||||||
dn: parentCertSubject
|
dn: parentCertSubject
|
||||||
});
|
});
|
||||||
|
|
||||||
const keyId = await getProjectKmsCertificateKeyId({
|
const certificateManagerKmsId = await getProjectKmsCertificateKeyId({
|
||||||
projectId: ca.projectId,
|
projectId: ca.projectId,
|
||||||
projectDAL,
|
projectDAL,
|
||||||
kmsService
|
kmsService
|
||||||
});
|
});
|
||||||
|
const kmsEncryptor = await kmsService.encryptWithKmsKey({
|
||||||
|
kmsId: certificateManagerKmsId
|
||||||
|
});
|
||||||
|
|
||||||
const { cipherTextBlob: encryptedCertificate } = await kmsService.encrypt({
|
const { cipherTextBlob: encryptedCertificate } = kmsEncryptor({
|
||||||
kmsId: keyId,
|
|
||||||
plainText: Buffer.from(new Uint8Array(certObj.rawData))
|
plainText: Buffer.from(new Uint8Array(certObj.rawData))
|
||||||
});
|
});
|
||||||
|
|
||||||
const { cipherTextBlob: encryptedCertificateChain } = await kmsService.encrypt({
|
const { cipherTextBlob: encryptedCertificateChain } = kmsEncryptor({
|
||||||
kmsId: keyId,
|
|
||||||
plainText: Buffer.from(certificateChain)
|
plainText: Buffer.from(certificateChain)
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -682,14 +684,16 @@ export const certificateAuthorityServiceFactory = ({
|
|||||||
const caCert = await certificateAuthorityCertDAL.findOne({ caId: ca.id });
|
const caCert = await certificateAuthorityCertDAL.findOne({ caId: ca.id });
|
||||||
if (!caCert) throw new BadRequestError({ message: "CA does not have a certificate installed" });
|
if (!caCert) throw new BadRequestError({ message: "CA does not have a certificate installed" });
|
||||||
|
|
||||||
const keyId = await getProjectKmsCertificateKeyId({
|
const certificateManagerKmsId = await getProjectKmsCertificateKeyId({
|
||||||
projectId: ca.projectId,
|
projectId: ca.projectId,
|
||||||
projectDAL,
|
projectDAL,
|
||||||
kmsService
|
kmsService
|
||||||
});
|
});
|
||||||
|
const kmsDecryptor = await kmsService.decryptWithKmsKey({
|
||||||
|
kmsId: certificateManagerKmsId
|
||||||
|
});
|
||||||
|
|
||||||
const decryptedCaCert = await kmsService.decrypt({
|
const decryptedCaCert = kmsDecryptor({
|
||||||
kmsId: keyId,
|
|
||||||
cipherTextBlob: caCert.encryptedCertificate
|
cipherTextBlob: caCert.encryptedCertificate
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -796,8 +800,10 @@ export const certificateAuthorityServiceFactory = ({
|
|||||||
const skLeafObj = KeyObject.from(leafKeys.privateKey);
|
const skLeafObj = KeyObject.from(leafKeys.privateKey);
|
||||||
const skLeaf = skLeafObj.export({ format: "pem", type: "pkcs8" }) as string;
|
const skLeaf = skLeafObj.export({ format: "pem", type: "pkcs8" }) as string;
|
||||||
|
|
||||||
const { cipherTextBlob: encryptedCertificate } = await kmsService.encrypt({
|
const kmsEncryptor = await kmsService.encryptWithKmsKey({
|
||||||
kmsId: keyId,
|
kmsId: certificateManagerKmsId
|
||||||
|
});
|
||||||
|
const { cipherTextBlob: encryptedCertificate } = kmsEncryptor({
|
||||||
plainText: Buffer.from(new Uint8Array(leafCert.rawData))
|
plainText: Buffer.from(new Uint8Array(leafCert.rawData))
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ export type TGetCaCredentialsDTO = {
|
|||||||
certificateAuthorityDAL: Pick<TCertificateAuthorityDALFactory, "findById">;
|
certificateAuthorityDAL: Pick<TCertificateAuthorityDALFactory, "findById">;
|
||||||
certificateAuthoritySecretDAL: Pick<TCertificateAuthoritySecretDALFactory, "findOne">;
|
certificateAuthoritySecretDAL: Pick<TCertificateAuthoritySecretDALFactory, "findOne">;
|
||||||
projectDAL: Pick<TProjectDALFactory, "findOne" | "updateById" | "transaction">;
|
projectDAL: Pick<TProjectDALFactory, "findOne" | "updateById" | "transaction">;
|
||||||
kmsService: Pick<TKmsServiceFactory, "decrypt" | "generateKmsKey">;
|
kmsService: Pick<TKmsServiceFactory, "decryptWithKmsKey" | "generateKmsKey">;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TGetCaCertChainDTO = {
|
export type TGetCaCertChainDTO = {
|
||||||
@@ -103,7 +103,7 @@ export type TGetCaCertChainDTO = {
|
|||||||
certificateAuthorityDAL: Pick<TCertificateAuthorityDALFactory, "findById">;
|
certificateAuthorityDAL: Pick<TCertificateAuthorityDALFactory, "findById">;
|
||||||
certificateAuthorityCertDAL: Pick<TCertificateAuthorityCertDALFactory, "findOne">;
|
certificateAuthorityCertDAL: Pick<TCertificateAuthorityCertDALFactory, "findOne">;
|
||||||
projectDAL: Pick<TProjectDALFactory, "findOne" | "updateById" | "transaction">;
|
projectDAL: Pick<TProjectDALFactory, "findOne" | "updateById" | "transaction">;
|
||||||
kmsService: Pick<TKmsServiceFactory, "decrypt" | "generateKmsKey">;
|
kmsService: Pick<TKmsServiceFactory, "decryptWithKmsKey" | "generateKmsKey">;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TRebuildCaCrlDTO = {
|
export type TRebuildCaCrlDTO = {
|
||||||
@@ -113,7 +113,7 @@ export type TRebuildCaCrlDTO = {
|
|||||||
certificateAuthoritySecretDAL: Pick<TCertificateAuthoritySecretDALFactory, "findOne">;
|
certificateAuthoritySecretDAL: Pick<TCertificateAuthoritySecretDALFactory, "findOne">;
|
||||||
projectDAL: Pick<TProjectDALFactory, "findOne" | "updateById" | "transaction">;
|
projectDAL: Pick<TProjectDALFactory, "findOne" | "updateById" | "transaction">;
|
||||||
certificateDAL: Pick<TCertificateDALFactory, "find">;
|
certificateDAL: Pick<TCertificateDALFactory, "find">;
|
||||||
kmsService: Pick<TKmsServiceFactory, "generateKmsKey" | "decrypt" | "encrypt">;
|
kmsService: Pick<TKmsServiceFactory, "generateKmsKey" | "decryptWithKmsKey" | "encryptWithKmsKey">;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TRotateCaCrlTriggerDTO = {
|
export type TRotateCaCrlTriggerDTO = {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ type TCertificateServiceFactoryDep = {
|
|||||||
certificateAuthorityCrlDAL: Pick<TCertificateAuthorityCrlDALFactory, "update">;
|
certificateAuthorityCrlDAL: Pick<TCertificateAuthorityCrlDALFactory, "update">;
|
||||||
certificateAuthoritySecretDAL: Pick<TCertificateAuthoritySecretDALFactory, "findOne">;
|
certificateAuthoritySecretDAL: Pick<TCertificateAuthoritySecretDALFactory, "findOne">;
|
||||||
projectDAL: Pick<TProjectDALFactory, "findOne" | "updateById" | "findById" | "transaction">;
|
projectDAL: Pick<TProjectDALFactory, "findOne" | "updateById" | "findById" | "transaction">;
|
||||||
kmsService: Pick<TKmsServiceFactory, "generateKmsKey" | "encrypt" | "decrypt">;
|
kmsService: Pick<TKmsServiceFactory, "generateKmsKey" | "encryptWithKmsKey" | "decryptWithKmsKey">;
|
||||||
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -164,14 +164,16 @@ export const certificateServiceFactory = ({
|
|||||||
|
|
||||||
const certBody = await certificateBodyDAL.findOne({ certId: cert.id });
|
const certBody = await certificateBodyDAL.findOne({ certId: cert.id });
|
||||||
|
|
||||||
const keyId = await getProjectKmsCertificateKeyId({
|
const certificateManagerKeyId = await getProjectKmsCertificateKeyId({
|
||||||
projectId: ca.projectId,
|
projectId: ca.projectId,
|
||||||
projectDAL,
|
projectDAL,
|
||||||
kmsService
|
kmsService
|
||||||
});
|
});
|
||||||
|
|
||||||
const decryptedCert = await kmsService.decrypt({
|
const kmsDecryptor = await kmsService.decryptWithKmsKey({
|
||||||
kmsId: keyId,
|
kmsId: certificateManagerKeyId
|
||||||
|
});
|
||||||
|
const decryptedCert = kmsDecryptor({
|
||||||
cipherTextBlob: certBody.encryptedCertificate
|
cipherTextBlob: certBody.encryptedCertificate
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,13 @@ import { TProjectDALFactory } from "../project/project-dal";
|
|||||||
import { TInternalKmsDALFactory } from "./internal-kms-dal";
|
import { TInternalKmsDALFactory } from "./internal-kms-dal";
|
||||||
import { TKmsKeyDALFactory } from "./kms-key-dal";
|
import { TKmsKeyDALFactory } from "./kms-key-dal";
|
||||||
import { TKmsRootConfigDALFactory } from "./kms-root-config-dal";
|
import { TKmsRootConfigDALFactory } from "./kms-root-config-dal";
|
||||||
import { EncryptionMode, TGenerateKMSDTO, TKmsServiceDecryptionDTO, TKmsServiceEncryptionDTO } from "./kms-types";
|
import {
|
||||||
|
TDecryptWithKeyDTO,
|
||||||
|
TDecryptWithKmsDTO,
|
||||||
|
TEncryptionWithKeyDTO,
|
||||||
|
TEncryptWithKmsDTO,
|
||||||
|
TGenerateKMSDTO
|
||||||
|
} from "./kms-types";
|
||||||
|
|
||||||
type TKmsServiceFactoryDep = {
|
type TKmsServiceFactoryDep = {
|
||||||
kmsDAL: TKmsKeyDALFactory;
|
kmsDAL: TKmsKeyDALFactory;
|
||||||
@@ -74,64 +80,55 @@ export const kmsServiceFactory = ({
|
|||||||
return doc;
|
return doc;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
const encryptWithKmsKey = async ({ kmsId }: Omit<TEncryptWithKmsDTO, "plainText">) => {
|
||||||
* KMS encryption service
|
const kmsDoc = await kmsDAL.findByIdWithAssociatedKms(kmsId);
|
||||||
* Function to handle various kinds of encryption like
|
if (!kmsDoc) throw new BadRequestError({ message: "KMS ID not found" });
|
||||||
* Normal encryption
|
|
||||||
* Encrypt with KMS key - internal or external
|
|
||||||
*/
|
|
||||||
const encrypt = async (encryptionDetails: TKmsServiceEncryptionDTO) => {
|
|
||||||
// akhilmhdh: as more encryption are added do a check here on kmsDoc.encryptionAlgorithm
|
// akhilmhdh: as more encryption are added do a check here on kmsDoc.encryptionAlgorithm
|
||||||
const cipher = symmetricCipherService(SymmetricEncryption.AES_GCM_256);
|
const cipher = symmetricCipherService(SymmetricEncryption.AES_GCM_256);
|
||||||
// instead of using kms key encrypt with the provided key
|
return ({ plainText }: Pick<TEncryptWithKmsDTO, "plainText">) => {
|
||||||
if (encryptionDetails.type === EncryptionMode.EncryptionKey) {
|
const kmsKey = cipher.decrypt(kmsDoc.internalKms?.encryptedKey as Buffer, ROOT_ENCRYPTION_KEY);
|
||||||
const { plainText, encryptionKey } = encryptionDetails;
|
const encryptedPlainTextBlob = cipher.encrypt(plainText, kmsKey);
|
||||||
|
|
||||||
const encryptedPlainTextBlob = cipher.encrypt(plainText, encryptionKey);
|
|
||||||
// Buffer#1 encrypted text + Buffer#2 version number
|
// Buffer#1 encrypted text + Buffer#2 version number
|
||||||
const versionBlob = Buffer.from(KMS_VERSION, "utf8"); // length is 3
|
const versionBlob = Buffer.from(KMS_VERSION, "utf8"); // length is 3
|
||||||
const cipherTextBlob = Buffer.concat([encryptedPlainTextBlob, versionBlob]);
|
const cipherTextBlob = Buffer.concat([encryptedPlainTextBlob, versionBlob]);
|
||||||
return { cipherTextBlob };
|
return { cipherTextBlob };
|
||||||
}
|
};
|
||||||
|
|
||||||
// this mean use kms to encrypt it
|
|
||||||
const { plainText, kmsId } = encryptionDetails;
|
|
||||||
const kmsDoc = await kmsDAL.findByIdWithAssociatedKms(kmsId);
|
|
||||||
if (!kmsDoc) throw new BadRequestError({ message: "KMS ID not found" });
|
|
||||||
|
|
||||||
const kmsKey = cipher.decrypt(kmsDoc.internalKms?.encryptedKey as Buffer, ROOT_ENCRYPTION_KEY);
|
|
||||||
const encryptedPlainTextBlob = cipher.encrypt(plainText, kmsKey);
|
|
||||||
|
|
||||||
// Buffer#1 encrypted text + Buffer#2 version number
|
|
||||||
const versionBlob = Buffer.from(KMS_VERSION, "utf8"); // length is 3
|
|
||||||
const cipherTextBlob = Buffer.concat([encryptedPlainTextBlob, versionBlob]);
|
|
||||||
return { cipherTextBlob };
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
const encryptWithInputKey = async ({ key }: Omit<TEncryptionWithKeyDTO, "plainText">) => {
|
||||||
* KMS decryption service
|
|
||||||
* Function to handle various kinds of decryptionlike
|
|
||||||
* Normal decryption with a key
|
|
||||||
* Encrypt with KMS key - internal or external
|
|
||||||
*/
|
|
||||||
const decrypt = async (encryptionDetails: TKmsServiceDecryptionDTO) => {
|
|
||||||
// akhilmhdh: as more encryption are added do a check here on kmsDoc.encryptionAlgorithm
|
// akhilmhdh: as more encryption are added do a check here on kmsDoc.encryptionAlgorithm
|
||||||
const cipher = symmetricCipherService(SymmetricEncryption.AES_GCM_256);
|
const cipher = symmetricCipherService(SymmetricEncryption.AES_GCM_256);
|
||||||
if (encryptionDetails.type === EncryptionMode.EncryptionKey) {
|
return ({ plainText }: Pick<TEncryptWithKmsDTO, "plainText">) => {
|
||||||
const { cipherTextBlob: versionedCipherTextBlob, encryptionKey } = encryptionDetails;
|
const encryptedPlainTextBlob = cipher.encrypt(plainText, key);
|
||||||
const cipherTextBlob = versionedCipherTextBlob.subarray(0, -KMS_VERSION_BLOB_LENGTH);
|
// Buffer#1 encrypted text + Buffer#2 version number
|
||||||
const decryptedBlob = cipher.decrypt(cipherTextBlob, encryptionKey);
|
const versionBlob = Buffer.from(KMS_VERSION, "utf8"); // length is 3
|
||||||
return decryptedBlob;
|
const cipherTextBlob = Buffer.concat([encryptedPlainTextBlob, versionBlob]);
|
||||||
}
|
return { cipherTextBlob };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
const { cipherTextBlob: versionedCipherTextBlob, kmsId } = encryptionDetails;
|
const decryptWithKmsKey = async ({ kmsId }: Omit<TDecryptWithKmsDTO, "cipherTextBlob">) => {
|
||||||
const kmsDoc = await kmsDAL.findByIdWithAssociatedKms(kmsId);
|
const kmsDoc = await kmsDAL.findByIdWithAssociatedKms(kmsId);
|
||||||
if (!kmsDoc) throw new BadRequestError({ message: "KMS ID not found" });
|
if (!kmsDoc) throw new BadRequestError({ message: "KMS ID not found" });
|
||||||
|
const cipher = symmetricCipherService(SymmetricEncryption.AES_GCM_256);
|
||||||
const kmsKey = cipher.decrypt(kmsDoc.internalKms?.encryptedKey as Buffer, ROOT_ENCRYPTION_KEY);
|
const kmsKey = cipher.decrypt(kmsDoc.internalKms?.encryptedKey as Buffer, ROOT_ENCRYPTION_KEY);
|
||||||
|
|
||||||
const cipherTextBlob = versionedCipherTextBlob.subarray(0, -KMS_VERSION_BLOB_LENGTH);
|
return ({ cipherTextBlob: versionedCipherTextBlob }: Pick<TDecryptWithKmsDTO, "cipherTextBlob">) => {
|
||||||
const decryptedBlob = cipher.decrypt(cipherTextBlob, kmsKey);
|
const cipherTextBlob = versionedCipherTextBlob.subarray(0, -KMS_VERSION_BLOB_LENGTH);
|
||||||
return decryptedBlob;
|
const decryptedBlob = cipher.decrypt(cipherTextBlob, kmsKey);
|
||||||
|
return decryptedBlob;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const decryptWithInputKey = async ({ key }: Omit<TDecryptWithKeyDTO, "cipherTextBlob">) => {
|
||||||
|
const cipher = symmetricCipherService(SymmetricEncryption.AES_GCM_256);
|
||||||
|
|
||||||
|
return ({ cipherTextBlob: versionedCipherTextBlob }: Pick<TDecryptWithKeyDTO, "cipherTextBlob">) => {
|
||||||
|
const cipherTextBlob = versionedCipherTextBlob.subarray(0, -KMS_VERSION_BLOB_LENGTH);
|
||||||
|
const decryptedBlob = cipher.decrypt(cipherTextBlob, key);
|
||||||
|
return decryptedBlob;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const getOrgKmsKeyId = async (orgId: string) => {
|
const getOrgKmsKeyId = async (orgId: string) => {
|
||||||
@@ -246,8 +243,10 @@ export const kmsServiceFactory = ({
|
|||||||
return {
|
return {
|
||||||
startService,
|
startService,
|
||||||
generateKmsKey,
|
generateKmsKey,
|
||||||
encrypt,
|
encryptWithKmsKey,
|
||||||
decrypt,
|
encryptWithInputKey,
|
||||||
|
decryptWithKmsKey,
|
||||||
|
decryptWithInputKey,
|
||||||
getOrgKmsKeyId,
|
getOrgKmsKeyId,
|
||||||
getProjectSecretManagerKmsKeyId
|
getProjectSecretManagerKmsKeyId
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,35 +7,22 @@ export type TGenerateKMSDTO = {
|
|||||||
tx?: Knex;
|
tx?: Knex;
|
||||||
};
|
};
|
||||||
|
|
||||||
export enum EncryptionMode {
|
|
||||||
KMS = "kms",
|
|
||||||
EncryptionKey = "encryption-key"
|
|
||||||
}
|
|
||||||
|
|
||||||
export type TEncryptWithKmsDTO = {
|
export type TEncryptWithKmsDTO = {
|
||||||
type?: EncryptionMode.KMS;
|
|
||||||
kmsId: string;
|
kmsId: string;
|
||||||
plainText: Buffer;
|
plainText: Buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TEncryptionWithKeyDTO = {
|
export type TEncryptionWithKeyDTO = {
|
||||||
type: EncryptionMode.EncryptionKey;
|
key: Buffer;
|
||||||
encryptionKey: Buffer;
|
|
||||||
plainText: Buffer;
|
plainText: Buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TKmsServiceEncryptionDTO = TEncryptWithKmsDTO | TEncryptionWithKeyDTO;
|
|
||||||
|
|
||||||
export type TDecryptWithKmsDTO = {
|
export type TDecryptWithKmsDTO = {
|
||||||
type?: EncryptionMode.KMS;
|
|
||||||
kmsId: string;
|
kmsId: string;
|
||||||
cipherTextBlob: Buffer;
|
cipherTextBlob: Buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TDecryptWithEncryptionKeyDTO = {
|
export type TDecryptWithKeyDTO = {
|
||||||
type: EncryptionMode.EncryptionKey;
|
key: Buffer;
|
||||||
encryptionKey: Buffer;
|
|
||||||
cipherTextBlob: Buffer;
|
cipherTextBlob: Buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TKmsServiceDecryptionDTO = TDecryptWithKmsDTO | TDecryptWithEncryptionKeyDTO;
|
|
||||||
|
|||||||
Reference in New Issue
Block a user