feat: fips inside support (checkpoint)

This commit is contained in:
Daniel Hougaard
2025-07-06 15:44:07 +04:00
parent 83f0a500bd
commit 9aa3c14bf2
121 changed files with 1766 additions and 1277 deletions

View File

@@ -1,8 +1,6 @@
import crypto from "node:crypto";
import { SecretType, TSecrets } from "@app/db/schemas";
import { decryptSecret, encryptSecret, getUserPrivateKey, seedData1 } from "@app/db/seed-data";
import { decryptAsymmetric, decryptSymmetric128BitHexKeyUTF8, encryptSymmetric128BitHexKeyUTF8 } from "@app/lib/crypto";
import { SymmetricKeySize } from "@app/lib/crypto";
const createServiceToken = async (
scopes: { environment: string; secretPath: string }[],
@@ -26,15 +24,21 @@ const createServiceToken = async (
});
const { user: userInfo } = JSON.parse(userInfoRes.payload);
const privateKey = await getUserPrivateKey(seedData1.password, userInfo);
const projectKey = decryptAsymmetric({
const projectKey = testCryptoProvider.encryption().asymmetric().decrypt({
ciphertext: projectKeyEnc.encryptedKey,
nonce: projectKeyEnc.nonce,
publicKey: projectKeyEnc.sender.publicKey,
privateKey
});
const randomBytes = crypto.randomBytes(16).toString("hex");
const { ciphertext, iv, tag } = encryptSymmetric128BitHexKeyUTF8(projectKey, randomBytes);
const randomBytes = testCryptoProvider.randomBytes(16).toString("hex");
const { ciphertext, iv, tag } = testCryptoProvider.encryption().encryptSymmetric({
plaintext: projectKey,
key: randomBytes,
keySize: SymmetricKeySize.Bits128
});
const serviceTokenRes = await testServer.inject({
method: "POST",
url: "/api/v2/service-token",
@@ -153,11 +157,13 @@ describe("Service token secret ops", async () => {
expect(serviceTokenInfoRes.statusCode).toBe(200);
const serviceTokenInfo = serviceTokenInfoRes.json();
const serviceTokenParts = serviceToken.split(".");
projectKey = decryptSymmetric128BitHexKeyUTF8({
projectKey = testCryptoProvider.encryption().decryptSymmetric({
key: serviceTokenParts[3],
tag: serviceTokenInfo.tag,
ciphertext: serviceTokenInfo.encryptedKey,
iv: serviceTokenInfo.iv
iv: serviceTokenInfo.iv,
keySize: SymmetricKeySize.Bits128
});
// create a deep folder
@@ -551,7 +557,7 @@ describe("Service token fail cases", async () => {
type: SecretType.Shared,
secretPath: "/",
// doesn't matter project key because this will fail before that due to read only access
...encryptSecret(crypto.randomBytes(16).toString("hex"), "NEW", "value", "")
...encryptSecret(testCryptoProvider.randomBytes(16).toString("hex"), "NEW", "value", "")
},
headers: {
authorization: `Bearer ${serviceToken}`

View File

@@ -1,6 +1,5 @@
import { SecretType, TSecrets } from "@app/db/schemas";
import { decryptSecret, encryptSecret, getUserPrivateKey, seedData1 } from "@app/db/seed-data";
import { decryptAsymmetric, encryptAsymmetric } from "@app/lib/crypto";
import { AuthMode } from "@app/services/auth/auth-type";
const createSecret = async (dto: {
@@ -173,7 +172,7 @@ describe("Secret V3 Router", async () => {
});
const { user: userInfo } = JSON.parse(userInfoRes.payload);
const privateKey = await getUserPrivateKey(seedData1.password, userInfo);
projectKey = decryptAsymmetric({
projectKey = testCryptoProvider.encryption().asymmetric().decrypt({
ciphertext: projectKeyEncryptionDetails.encryptedKey,
nonce: projectKeyEncryptionDetails.nonce,
publicKey: projectKeyEncryptionDetails.sender.publicKey,
@@ -669,7 +668,7 @@ describe.each([{ auth: AuthMode.JWT }, { auth: AuthMode.IDENTITY_ACCESS_TOKEN }]
const { user: userInfo } = JSON.parse(userInfoRes.payload);
const privateKey = await getUserPrivateKey(seedData1.password, userInfo);
const projectKey = decryptAsymmetric({
const projectKey = testCryptoProvider.encryption().asymmetric().decrypt({
ciphertext: projectKeyEnc.encryptedKey,
nonce: projectKeyEnc.nonce,
publicKey: projectKeyEnc.sender.publicKey,
@@ -685,7 +684,7 @@ describe.each([{ auth: AuthMode.JWT }, { auth: AuthMode.IDENTITY_ACCESS_TOKEN }]
});
expect(projectBotRes.statusCode).toEqual(200);
const projectBot = JSON.parse(projectBotRes.payload).bot;
const botKey = encryptAsymmetric(projectKey, projectBot.publicKey, privateKey);
const botKey = testCryptoProvider.encryption().asymmetric().encrypt(projectKey, projectBot.publicKey, privateKey);
// set bot as active
const setBotActive = await testServer.inject({

View File

@@ -17,6 +17,8 @@ import { queueServiceFactory } from "@app/queue";
import { keyStoreFactory } from "@app/keystore/keystore";
import { initializeHsmModule } from "@app/ee/services/hsm/hsm-fns";
import { buildRedisFromConfig } from "@app/lib/config/redis";
import { superAdminDALFactory } from "@app/services/super-admin/super-admin-dal";
import { crypto } from "@app/lib/crypto/cryptography";
dotenv.config({ path: path.join(__dirname, "../../.env.test"), debug: true });
export default {
@@ -29,6 +31,8 @@ export default {
dbConnectionUri: envConfig.DB_CONNECTION_URI,
dbRootCert: envConfig.DB_ROOT_CERT
});
const superAdminDAL = superAdminDALFactory(db);
await crypto.initialize(superAdminDAL);
const redis = buildRedisFromConfig(envConfig);
await redis.flushdb("SYNC");
@@ -68,6 +72,7 @@ export default {
queue,
keyStore,
hsmModule: hsmModule.getModule(),
superAdminDAL,
redis,
envConfig
});
@@ -75,6 +80,8 @@ export default {
// @ts-expect-error type
globalThis.testServer = server;
// @ts-expect-error type
globalThis.testCryptoProvider = crypto;
// @ts-expect-error type
globalThis.jwtAuthToken = jwt.sign(
{
authTokenType: AuthTokenType.ACCESS_TOKEN,