mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-06 09:26:47 +00:00
fix: better file cleanup
This commit is contained in:
@@ -0,0 +1,35 @@
|
|||||||
|
import crypto from "crypto";
|
||||||
|
import fs from "fs/promises";
|
||||||
|
import os from "os";
|
||||||
|
import path from "path";
|
||||||
|
|
||||||
|
import { logger } from "@app/lib/logger";
|
||||||
|
|
||||||
|
const baseDir = path.join(os.tmpdir(), "temporary-signing");
|
||||||
|
const randomPath = () => `${crypto.randomBytes(32).toString("hex")}-`;
|
||||||
|
|
||||||
|
export const createTemporaryDirectory = async (name: string) => {
|
||||||
|
const tempDirPath = path.join(baseDir, `${name}-${randomPath()}-${randomPath()}`);
|
||||||
|
await fs.mkdir(tempDirPath, { recursive: true });
|
||||||
|
|
||||||
|
return tempDirPath;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const removeTemporaryBaseDirectory = async () => {
|
||||||
|
await fs.rm(baseDir, { force: true, recursive: true }).catch((err) => {
|
||||||
|
logger.error(err, `Failed to remove temporary base directory [path=${baseDir}]`);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const cleanTemporaryDirectory = async (dirPath: string) => {
|
||||||
|
await fs.rm(dirPath, { recursive: true, force: true }).catch((err) => {
|
||||||
|
logger.error(err, `Failed to cleanup temporary directory [path=${dirPath}]`);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const writeToTemporaryFile = async (tempDirPath: string, data: string | Buffer) => {
|
||||||
|
await fs.writeFile(tempDirPath, data, { mode: 0o600 }).catch((err) => {
|
||||||
|
logger.error(err, `Failed to write to temporary file [path=${tempDirPath}]`);
|
||||||
|
throw err;
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
import { execFile } from "child_process";
|
import { execFile } from "child_process";
|
||||||
import crypto from "crypto";
|
import crypto from "crypto";
|
||||||
import fs from "fs/promises";
|
import fs from "fs/promises";
|
||||||
import os from "os";
|
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { promisify } from "util";
|
import { promisify } from "util";
|
||||||
|
|
||||||
import { BadRequestError } from "@app/lib/errors";
|
import { BadRequestError } from "@app/lib/errors";
|
||||||
import { logger } from "@app/lib/logger";
|
import { logger } from "@app/lib/logger";
|
||||||
|
|
||||||
|
import { cleanTemporaryDirectory, createTemporaryDirectory, writeToTemporaryFile } from "./signing-fns";
|
||||||
import { AsymmetricKeyAlgorithm, SigningAlgorithm, TAsymmetricSignVerifyFns } from "./types";
|
import { AsymmetricKeyAlgorithm, SigningAlgorithm, TAsymmetricSignVerifyFns } from "./types";
|
||||||
|
|
||||||
const execFileAsync = promisify(execFile);
|
const execFileAsync = promisify(execFile);
|
||||||
@@ -30,11 +30,6 @@ const SHA256_DIGEST_LENGTH = 32;
|
|||||||
const SHA384_DIGEST_LENGTH = 48;
|
const SHA384_DIGEST_LENGTH = 48;
|
||||||
const SHA512_DIGEST_LENGTH = 64;
|
const SHA512_DIGEST_LENGTH = 64;
|
||||||
|
|
||||||
const makeTempDir = async (name: string) => {
|
|
||||||
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), `${name}-${crypto.randomBytes(16).toString("hex")}-`));
|
|
||||||
return tempDir;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service for cryptographic signing and verification operations using asymmetric keys
|
* Service for cryptographic signing and verification operations using asymmetric keys
|
||||||
*
|
*
|
||||||
@@ -124,14 +119,14 @@ export const signingService = (algorithm: AsymmetricKeyAlgorithm): TAsymmetricSi
|
|||||||
};
|
};
|
||||||
|
|
||||||
const $signRsaDigest = async (digest: Buffer, privateKey: Buffer, hashAlgorithm: SupportedHashAlgorithm) => {
|
const $signRsaDigest = async (digest: Buffer, privateKey: Buffer, hashAlgorithm: SupportedHashAlgorithm) => {
|
||||||
const tempDir = await makeTempDir("kms-rsa-sign");
|
const tempDir = await createTemporaryDirectory("kms-rsa-sign");
|
||||||
const digestPath = path.join(tempDir, "digest.bin");
|
const digestPath = path.join(tempDir, "digest.bin");
|
||||||
const keyPath = path.join(tempDir, "private_key.pem");
|
|
||||||
const sigPath = path.join(tempDir, "signature.bin");
|
const sigPath = path.join(tempDir, "signature.bin");
|
||||||
|
const keyPath = path.join(tempDir, "key.pem");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await fs.writeFile(digestPath, digest, { mode: 0o600 });
|
await writeToTemporaryFile(digestPath, digest);
|
||||||
await fs.writeFile(keyPath, privateKey, { mode: 0o600 });
|
await writeToTemporaryFile(keyPath, privateKey);
|
||||||
|
|
||||||
const { stderr } = await execFileAsync(
|
const { stderr } = await execFileAsync(
|
||||||
"openssl",
|
"openssl",
|
||||||
@@ -170,19 +165,19 @@ export const signingService = (algorithm: AsymmetricKeyAlgorithm): TAsymmetricSi
|
|||||||
|
|
||||||
return signature;
|
return signature;
|
||||||
} finally {
|
} finally {
|
||||||
await fs.rm(tempDir, { recursive: true, force: true }).catch(() => {});
|
await cleanTemporaryDirectory(tempDir);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const $signEccDigest = async (digest: Buffer, privateKey: Buffer, hashAlgorithm: SupportedHashAlgorithm) => {
|
const $signEccDigest = async (digest: Buffer, privateKey: Buffer, hashAlgorithm: SupportedHashAlgorithm) => {
|
||||||
const tempDir = await makeTempDir("ecc-sign");
|
const tempDir = await createTemporaryDirectory("ecc-sign");
|
||||||
const digestPath = path.join(tempDir, "digest.bin");
|
const digestPath = path.join(tempDir, "digest.bin");
|
||||||
const keyPath = path.join(tempDir, "private_key.pem");
|
const keyPath = path.join(tempDir, "key.pem");
|
||||||
const sigPath = path.join(tempDir, "signature.bin");
|
const sigPath = path.join(tempDir, "signature.bin");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await fs.writeFile(digestPath, digest);
|
await writeToTemporaryFile(digestPath, digest);
|
||||||
await fs.writeFile(keyPath, privateKey);
|
await writeToTemporaryFile(keyPath, privateKey);
|
||||||
|
|
||||||
const { stderr } = await execFileAsync(
|
const { stderr } = await execFileAsync(
|
||||||
"openssl",
|
"openssl",
|
||||||
@@ -222,7 +217,7 @@ export const signingService = (algorithm: AsymmetricKeyAlgorithm): TAsymmetricSi
|
|||||||
|
|
||||||
return signature;
|
return signature;
|
||||||
} finally {
|
} finally {
|
||||||
await fs.rm(tempDir, { recursive: true, force: true }).catch(() => {});
|
await cleanTemporaryDirectory(tempDir);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -232,15 +227,15 @@ export const signingService = (algorithm: AsymmetricKeyAlgorithm): TAsymmetricSi
|
|||||||
publicKey: Buffer,
|
publicKey: Buffer,
|
||||||
hashAlgorithm: SupportedHashAlgorithm
|
hashAlgorithm: SupportedHashAlgorithm
|
||||||
) => {
|
) => {
|
||||||
const tempDir = await makeTempDir("ecc-signature-verification");
|
const tempDir = await createTemporaryDirectory("ecc-signature-verification");
|
||||||
const pubKeyFile = path.join(tempDir, "public-key.pem");
|
const publicKeyFile = path.join(tempDir, "public-key.pem");
|
||||||
const sigFile = path.join(tempDir, "signature.sig");
|
const sigFile = path.join(tempDir, "signature.sig");
|
||||||
const digestFile = path.join(tempDir, "digest.bin");
|
const digestFile = path.join(tempDir, "digest.bin");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await fs.writeFile(pubKeyFile, publicKey, { mode: 0o600 });
|
await writeToTemporaryFile(publicKeyFile, publicKey);
|
||||||
await fs.writeFile(sigFile, signature, { mode: 0o600 });
|
await writeToTemporaryFile(sigFile, signature);
|
||||||
await fs.writeFile(digestFile, digest, { mode: 0o600 });
|
await writeToTemporaryFile(digestFile, digest);
|
||||||
|
|
||||||
await execFileAsync(
|
await execFileAsync(
|
||||||
"openssl",
|
"openssl",
|
||||||
@@ -250,7 +245,7 @@ export const signingService = (algorithm: AsymmetricKeyAlgorithm): TAsymmetricSi
|
|||||||
"-in",
|
"-in",
|
||||||
digestFile,
|
digestFile,
|
||||||
"-inkey",
|
"-inkey",
|
||||||
pubKeyFile,
|
publicKeyFile,
|
||||||
"-pubin", // Important for EC public keys
|
"-pubin", // Important for EC public keys
|
||||||
"-sigfile",
|
"-sigfile",
|
||||||
sigFile,
|
sigFile,
|
||||||
@@ -272,7 +267,7 @@ export const signingService = (algorithm: AsymmetricKeyAlgorithm): TAsymmetricSi
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
} finally {
|
} finally {
|
||||||
await fs.rm(tempDir, { recursive: true, force: true }).catch(() => {});
|
await cleanTemporaryDirectory(tempDir);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -282,15 +277,15 @@ export const signingService = (algorithm: AsymmetricKeyAlgorithm): TAsymmetricSi
|
|||||||
publicKey: Buffer,
|
publicKey: Buffer,
|
||||||
hashAlgorithm: SupportedHashAlgorithm
|
hashAlgorithm: SupportedHashAlgorithm
|
||||||
) => {
|
) => {
|
||||||
const tempDir = await makeTempDir("kms-signature-verification");
|
const tempDir = await createTemporaryDirectory("kms-signature-verification");
|
||||||
const publicKeyFile = path.join(tempDir, "public-key.pub");
|
const publicKeyFile = path.join(tempDir, "public-key.pub");
|
||||||
const signatureFile = path.join(tempDir, "signature.sig");
|
const signatureFile = path.join(tempDir, "signature.sig");
|
||||||
const digestFile = path.join(tempDir, "digest.bin");
|
const digestFile = path.join(tempDir, "digest.bin");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await fs.writeFile(publicKeyFile, publicKey, { mode: 0o600 });
|
await writeToTemporaryFile(publicKeyFile, publicKey);
|
||||||
await fs.writeFile(signatureFile, signature, { mode: 0o600 });
|
await writeToTemporaryFile(signatureFile, signature);
|
||||||
await fs.writeFile(digestFile, digest, { mode: 0o600 });
|
await writeToTemporaryFile(digestFile, digest);
|
||||||
|
|
||||||
await execFileAsync(
|
await execFileAsync(
|
||||||
"openssl",
|
"openssl",
|
||||||
@@ -320,7 +315,7 @@ export const signingService = (algorithm: AsymmetricKeyAlgorithm): TAsymmetricSi
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
} finally {
|
} finally {
|
||||||
await fs.rm(tempDir, { recursive: true, force: true }).catch(() => {});
|
await cleanTemporaryDirectory(tempDir);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { runMigrations } from "./auto-start-migrations";
|
|||||||
import { initAuditLogDbConnection, initDbConnection } from "./db";
|
import { initAuditLogDbConnection, initDbConnection } from "./db";
|
||||||
import { keyStoreFactory } from "./keystore/keystore";
|
import { keyStoreFactory } from "./keystore/keystore";
|
||||||
import { formatSmtpConfig, initEnvConfig } from "./lib/config/env";
|
import { formatSmtpConfig, initEnvConfig } from "./lib/config/env";
|
||||||
|
import { removeTemporaryBaseDirectory } from "./lib/crypto/sign/signing-fns";
|
||||||
import { initLogger } from "./lib/logger";
|
import { initLogger } from "./lib/logger";
|
||||||
import { queueServiceFactory } from "./queue";
|
import { queueServiceFactory } from "./queue";
|
||||||
import { main } from "./server/app";
|
import { main } from "./server/app";
|
||||||
@@ -21,6 +22,8 @@ const run = async () => {
|
|||||||
const logger = initLogger();
|
const logger = initLogger();
|
||||||
const envConfig = initEnvConfig(logger);
|
const envConfig = initEnvConfig(logger);
|
||||||
|
|
||||||
|
await removeTemporaryBaseDirectory();
|
||||||
|
|
||||||
const db = initDbConnection({
|
const db = initDbConnection({
|
||||||
dbConnectionUri: envConfig.DB_CONNECTION_URI,
|
dbConnectionUri: envConfig.DB_CONNECTION_URI,
|
||||||
dbRootCert: envConfig.DB_ROOT_CERT,
|
dbRootCert: envConfig.DB_ROOT_CERT,
|
||||||
@@ -71,6 +74,7 @@ const run = async () => {
|
|||||||
process.on("SIGINT", async () => {
|
process.on("SIGINT", async () => {
|
||||||
await server.close();
|
await server.close();
|
||||||
await db.destroy();
|
await db.destroy();
|
||||||
|
await removeTemporaryBaseDirectory();
|
||||||
hsmModule.finalize();
|
hsmModule.finalize();
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
});
|
});
|
||||||
@@ -79,6 +83,7 @@ const run = async () => {
|
|||||||
process.on("SIGTERM", async () => {
|
process.on("SIGTERM", async () => {
|
||||||
await server.close();
|
await server.close();
|
||||||
await db.destroy();
|
await db.destroy();
|
||||||
|
await removeTemporaryBaseDirectory();
|
||||||
hsmModule.finalize();
|
hsmModule.finalize();
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user