mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-15 20:25:43 +00:00
Merge pull request #3973 from Infisical/daniel/fips-initative
feat(fips): native FIPS support
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import bcrypt from "bcrypt";
|
||||
import { z } from "zod";
|
||||
|
||||
import { getConfig } from "@app/lib/config/env";
|
||||
import { crypto } from "@app/lib/crypto/cryptography";
|
||||
import { BadRequestError, UnauthorizedError } from "@app/lib/errors";
|
||||
import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
|
||||
|
||||
@@ -85,7 +85,7 @@ export const registerCertificateEstRouter = async (server: FastifyZodProvider) =
|
||||
});
|
||||
}
|
||||
|
||||
const isPasswordValid = await bcrypt.compare(password, estConfig.hashedPassphrase);
|
||||
const isPasswordValid = await crypto.hashing().compareHash(password, estConfig.hashedPassphrase);
|
||||
if (!isPasswordValid) {
|
||||
throw new UnauthorizedError({
|
||||
message: "Invalid credentials"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ForbiddenError } from "@casl/ability";
|
||||
import jwt from "jsonwebtoken";
|
||||
|
||||
import { getConfig } from "@app/lib/config/env";
|
||||
import { crypto } from "@app/lib/crypto/cryptography";
|
||||
import { ForbiddenRequestError, NotFoundError } from "@app/lib/errors";
|
||||
import { ActorType } from "@app/services/auth/auth-type";
|
||||
import { TProjectDALFactory } from "@app/services/project/project-dal";
|
||||
@@ -62,7 +62,7 @@ export const assumePrivilegeServiceFactory = ({
|
||||
});
|
||||
|
||||
const appCfg = getConfig();
|
||||
const assumePrivilegesToken = jwt.sign(
|
||||
const assumePrivilegesToken = crypto.jwt().sign(
|
||||
{
|
||||
tokenVersionId,
|
||||
actorType: targetActorType,
|
||||
@@ -82,7 +82,7 @@ export const assumePrivilegeServiceFactory = ({
|
||||
tokenVersionId
|
||||
) => {
|
||||
const appCfg = getConfig();
|
||||
const decodedToken = jwt.verify(token, appCfg.AUTH_SECRET) as {
|
||||
const decodedToken = crypto.jwt().verify(token, appCfg.AUTH_SECRET) as {
|
||||
tokenVersionId: string;
|
||||
projectId: string;
|
||||
requesterId: string;
|
||||
|
||||
@@ -4,7 +4,7 @@ import { RawAxiosRequestHeaders } from "axios";
|
||||
import { SecretKeyEncoding } from "@app/db/schemas";
|
||||
import { getConfig } from "@app/lib/config/env";
|
||||
import { request } from "@app/lib/config/request";
|
||||
import { infisicalSymmetricDecrypt, infisicalSymmetricEncypt } from "@app/lib/crypto/encryption";
|
||||
import { crypto } from "@app/lib/crypto/cryptography";
|
||||
import { BadRequestError, NotFoundError, UnauthorizedError } from "@app/lib/errors";
|
||||
import { blockLocalAndPrivateIpAddresses } from "@app/lib/validator";
|
||||
|
||||
@@ -86,7 +86,10 @@ export const auditLogStreamServiceFactory = ({
|
||||
.catch((err) => {
|
||||
throw new BadRequestError({ message: `Failed to connect with upstream source: ${(err as Error)?.message}` });
|
||||
});
|
||||
const encryptedHeaders = headers ? infisicalSymmetricEncypt(JSON.stringify(headers)) : undefined;
|
||||
|
||||
const encryptedHeaders = headers
|
||||
? crypto.encryption().symmetric().encryptWithRootEncryptionKey(JSON.stringify(headers))
|
||||
: undefined;
|
||||
const logStream = await auditLogStreamDAL.create({
|
||||
orgId: actorOrgId,
|
||||
url,
|
||||
@@ -152,7 +155,9 @@ export const auditLogStreamServiceFactory = ({
|
||||
throw new Error(`Failed to connect with the source ${(err as Error)?.message}`);
|
||||
});
|
||||
|
||||
const encryptedHeaders = headers ? infisicalSymmetricEncypt(JSON.stringify(headers)) : undefined;
|
||||
const encryptedHeaders = headers
|
||||
? crypto.encryption().symmetric().encryptWithRootEncryptionKey(JSON.stringify(headers))
|
||||
: undefined;
|
||||
const updatedLogStream = await auditLogStreamDAL.updateById(id, {
|
||||
url,
|
||||
...(encryptedHeaders
|
||||
@@ -205,12 +210,15 @@ export const auditLogStreamServiceFactory = ({
|
||||
const headers =
|
||||
logStream?.encryptedHeadersCiphertext && logStream?.encryptedHeadersIV && logStream?.encryptedHeadersTag
|
||||
? (JSON.parse(
|
||||
infisicalSymmetricDecrypt({
|
||||
tag: logStream.encryptedHeadersTag,
|
||||
iv: logStream.encryptedHeadersIV,
|
||||
ciphertext: logStream.encryptedHeadersCiphertext,
|
||||
keyEncoding: logStream.encryptedHeadersKeyEncoding as SecretKeyEncoding
|
||||
})
|
||||
crypto
|
||||
.encryption()
|
||||
.symmetric()
|
||||
.decryptWithRootEncryptionKey({
|
||||
tag: logStream.encryptedHeadersTag,
|
||||
iv: logStream.encryptedHeadersIV,
|
||||
ciphertext: logStream.encryptedHeadersCiphertext,
|
||||
keyEncoding: logStream.encryptedHeadersKeyEncoding as SecretKeyEncoding
|
||||
})
|
||||
) as LogStreamHeaders[])
|
||||
: undefined;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { AxiosError, RawAxiosRequestHeaders } from "axios";
|
||||
import { SecretKeyEncoding } from "@app/db/schemas";
|
||||
import { getConfig } from "@app/lib/config/env";
|
||||
import { request } from "@app/lib/config/request";
|
||||
import { infisicalSymmetricDecrypt } from "@app/lib/crypto/encryption";
|
||||
import { crypto } from "@app/lib/crypto/cryptography";
|
||||
import { logger } from "@app/lib/logger";
|
||||
import { QueueJobs, QueueName, TQueueServiceFactory } from "@app/queue";
|
||||
import { TProjectDALFactory } from "@app/services/project/project-dal";
|
||||
@@ -114,12 +114,15 @@ export const auditLogQueueServiceFactory = async ({
|
||||
const streamHeaders =
|
||||
encryptedHeadersIV && encryptedHeadersCiphertext && encryptedHeadersTag
|
||||
? (JSON.parse(
|
||||
infisicalSymmetricDecrypt({
|
||||
keyEncoding: encryptedHeadersKeyEncoding as SecretKeyEncoding,
|
||||
iv: encryptedHeadersIV,
|
||||
tag: encryptedHeadersTag,
|
||||
ciphertext: encryptedHeadersCiphertext
|
||||
})
|
||||
crypto
|
||||
.encryption()
|
||||
.symmetric()
|
||||
.decryptWithRootEncryptionKey({
|
||||
keyEncoding: encryptedHeadersKeyEncoding as SecretKeyEncoding,
|
||||
iv: encryptedHeadersIV,
|
||||
tag: encryptedHeadersTag,
|
||||
ciphertext: encryptedHeadersCiphertext
|
||||
})
|
||||
) as LogStreamHeaders[])
|
||||
: [];
|
||||
|
||||
@@ -216,12 +219,15 @@ export const auditLogQueueServiceFactory = async ({
|
||||
const streamHeaders =
|
||||
encryptedHeadersIV && encryptedHeadersCiphertext && encryptedHeadersTag
|
||||
? (JSON.parse(
|
||||
infisicalSymmetricDecrypt({
|
||||
keyEncoding: encryptedHeadersKeyEncoding as SecretKeyEncoding,
|
||||
iv: encryptedHeadersIV,
|
||||
tag: encryptedHeadersTag,
|
||||
ciphertext: encryptedHeadersCiphertext
|
||||
})
|
||||
crypto
|
||||
.encryption()
|
||||
.symmetric()
|
||||
.decryptWithRootEncryptionKey({
|
||||
keyEncoding: encryptedHeadersKeyEncoding as SecretKeyEncoding,
|
||||
iv: encryptedHeadersIV,
|
||||
tag: encryptedHeadersTag,
|
||||
ciphertext: encryptedHeadersCiphertext
|
||||
})
|
||||
) as LogStreamHeaders[])
|
||||
: [];
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
ProjectPermissionDynamicSecretActions,
|
||||
ProjectPermissionSub
|
||||
} from "@app/ee/services/permission/project-permission";
|
||||
import { crypto } from "@app/lib/crypto";
|
||||
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
||||
import { OrderByDirection } from "@app/lib/types";
|
||||
import { TKmsServiceFactory } from "@app/services/kms/kms-service";
|
||||
@@ -92,6 +93,12 @@ export const dynamicSecretServiceFactory = ({
|
||||
});
|
||||
}
|
||||
|
||||
if (provider.type === DynamicSecretProviders.MongoAtlas && crypto.isFipsModeEnabled()) {
|
||||
throw new BadRequestError({
|
||||
message: "MongoDB Atlas dynamic secret is not supported in FIPS mode of operation"
|
||||
});
|
||||
}
|
||||
|
||||
const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path);
|
||||
if (!folder) {
|
||||
throw new NotFoundError({ message: `Folder with path '${path}' in environment '${environmentSlug}' not found` });
|
||||
|
||||
@@ -12,6 +12,8 @@ import handlebars from "handlebars";
|
||||
import { customAlphabet } from "nanoid";
|
||||
import { z } from "zod";
|
||||
|
||||
import { CustomAWSHasher } from "@app/lib/aws/hashing";
|
||||
import { crypto } from "@app/lib/crypto";
|
||||
import { BadRequestError } from "@app/lib/errors";
|
||||
import { validateHandlebarTemplate } from "@app/lib/template/validate-handlebars";
|
||||
|
||||
@@ -39,8 +41,11 @@ type TDeleteElastiCacheUserInput = z.infer<typeof DeleteElasticCacheUserSchema>;
|
||||
const ElastiCacheUserManager = (credentials: TBasicAWSCredentials, region: string) => {
|
||||
const elastiCache = new ElastiCache({
|
||||
region,
|
||||
useFipsEndpoint: crypto.isFipsModeEnabled(),
|
||||
sha256: CustomAWSHasher,
|
||||
credentials
|
||||
});
|
||||
|
||||
const infisicalGroup = "infisical-managed-group-elasticache";
|
||||
|
||||
const ensureInfisicalGroupExists = async (clusterName: string) => {
|
||||
|
||||
@@ -17,10 +17,11 @@ import {
|
||||
RemoveUserFromGroupCommand
|
||||
} from "@aws-sdk/client-iam";
|
||||
import { AssumeRoleCommand, STSClient } from "@aws-sdk/client-sts";
|
||||
import { randomUUID } from "crypto";
|
||||
import { z } from "zod";
|
||||
|
||||
import { CustomAWSHasher } from "@app/lib/aws/hashing";
|
||||
import { getConfig } from "@app/lib/config/env";
|
||||
import { crypto } from "@app/lib/crypto/cryptography";
|
||||
import { BadRequestError, UnauthorizedError } from "@app/lib/errors";
|
||||
import { alphaNumericNanoId } from "@app/lib/nanoid";
|
||||
|
||||
@@ -49,6 +50,8 @@ export const AwsIamProvider = (): TDynamicProviderFns => {
|
||||
if (providerInputs.method === AwsIamAuthType.AssumeRole) {
|
||||
const stsClient = new STSClient({
|
||||
region: providerInputs.region,
|
||||
useFipsEndpoint: crypto.isFipsModeEnabled(),
|
||||
sha256: CustomAWSHasher,
|
||||
credentials:
|
||||
appCfg.DYNAMIC_SECRET_AWS_ACCESS_KEY_ID && appCfg.DYNAMIC_SECRET_AWS_SECRET_ACCESS_KEY
|
||||
? {
|
||||
@@ -60,7 +63,7 @@ export const AwsIamProvider = (): TDynamicProviderFns => {
|
||||
|
||||
const command = new AssumeRoleCommand({
|
||||
RoleArn: providerInputs.roleArn,
|
||||
RoleSessionName: `infisical-dynamic-secret-${randomUUID()}`,
|
||||
RoleSessionName: `infisical-dynamic-secret-${crypto.nativeCrypto.randomUUID()}`,
|
||||
DurationSeconds: 900, // 15 mins
|
||||
ExternalId: projectId
|
||||
});
|
||||
@@ -72,6 +75,8 @@ export const AwsIamProvider = (): TDynamicProviderFns => {
|
||||
}
|
||||
const client = new IAMClient({
|
||||
region: providerInputs.region,
|
||||
useFipsEndpoint: crypto.isFipsModeEnabled(),
|
||||
sha256: CustomAWSHasher,
|
||||
credentials: {
|
||||
accessKeyId: assumeRes.Credentials?.AccessKeyId,
|
||||
secretAccessKey: assumeRes.Credentials?.SecretAccessKey,
|
||||
@@ -91,13 +96,17 @@ export const AwsIamProvider = (): TDynamicProviderFns => {
|
||||
|
||||
// The SDK will automatically pick up credentials from the environment
|
||||
const client = new IAMClient({
|
||||
region: providerInputs.region
|
||||
region: providerInputs.region,
|
||||
useFipsEndpoint: crypto.isFipsModeEnabled(),
|
||||
sha256: CustomAWSHasher
|
||||
});
|
||||
return client;
|
||||
}
|
||||
|
||||
const client = new IAMClient({
|
||||
region: providerInputs.region,
|
||||
useFipsEndpoint: crypto.isFipsModeEnabled(),
|
||||
sha256: CustomAWSHasher,
|
||||
credentials: {
|
||||
accessKeyId: providerInputs.accessKey,
|
||||
secretAccessKey: providerInputs.secretAccessKey
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import axios from "axios";
|
||||
import jwt from "jsonwebtoken";
|
||||
|
||||
import { crypto } from "@app/lib/crypto";
|
||||
import { BadRequestError, InternalServerError } from "@app/lib/errors";
|
||||
import { alphaNumericNanoId } from "@app/lib/nanoid";
|
||||
import { IntegrationUrls } from "@app/services/integration-auth/integration-list";
|
||||
@@ -40,7 +41,7 @@ export const GithubProvider = (): TDynamicProviderFns => {
|
||||
|
||||
let appJwt: string;
|
||||
try {
|
||||
appJwt = jwt.sign(jwtPayload, privateKey, { algorithm: "RS256" });
|
||||
appJwt = crypto.jwt().sign(jwtPayload, privateKey, { algorithm: "RS256" });
|
||||
} catch (error) {
|
||||
let message = "Failed to sign JWT.";
|
||||
if (error instanceof jwt.JsonWebTokenError) {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { randomInt } from "crypto";
|
||||
import handlebars from "handlebars";
|
||||
import knex from "knex";
|
||||
import { z } from "zod";
|
||||
|
||||
import { crypto } from "@app/lib/crypto/cryptography";
|
||||
import { GatewayProxyProtocol, withGatewayProxy } from "@app/lib/gateway";
|
||||
import { alphaNumericNanoId } from "@app/lib/nanoid";
|
||||
import { validateHandlebarTemplate } from "@app/lib/template/validate-handlebars";
|
||||
@@ -50,7 +50,7 @@ const generatePassword = (provider: SqlProviders, requirements?: PasswordRequire
|
||||
parts.push(
|
||||
...Array(required.lowercase)
|
||||
.fill(0)
|
||||
.map(() => chars.lowercase[randomInt(chars.lowercase.length)])
|
||||
.map(() => chars.lowercase[crypto.randomInt(chars.lowercase.length)])
|
||||
);
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ const generatePassword = (provider: SqlProviders, requirements?: PasswordRequire
|
||||
parts.push(
|
||||
...Array(required.uppercase)
|
||||
.fill(0)
|
||||
.map(() => chars.uppercase[randomInt(chars.uppercase.length)])
|
||||
.map(() => chars.uppercase[crypto.randomInt(chars.uppercase.length)])
|
||||
);
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ const generatePassword = (provider: SqlProviders, requirements?: PasswordRequire
|
||||
parts.push(
|
||||
...Array(required.digits)
|
||||
.fill(0)
|
||||
.map(() => chars.digits[randomInt(chars.digits.length)])
|
||||
.map(() => chars.digits[crypto.randomInt(chars.digits.length)])
|
||||
);
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ const generatePassword = (provider: SqlProviders, requirements?: PasswordRequire
|
||||
parts.push(
|
||||
...Array(required.symbols)
|
||||
.fill(0)
|
||||
.map(() => chars.symbols[randomInt(chars.symbols.length)])
|
||||
.map(() => chars.symbols[crypto.randomInt(chars.symbols.length)])
|
||||
);
|
||||
}
|
||||
|
||||
@@ -89,12 +89,12 @@ const generatePassword = (provider: SqlProviders, requirements?: PasswordRequire
|
||||
parts.push(
|
||||
...Array(remainingLength)
|
||||
.fill(0)
|
||||
.map(() => allowedChars[randomInt(allowedChars.length)])
|
||||
.map(() => allowedChars[crypto.randomInt(allowedChars.length)])
|
||||
);
|
||||
|
||||
// shuffle the array to mix up the characters
|
||||
for (let i = parts.length - 1; i > 0; i -= 1) {
|
||||
const j = randomInt(i + 1);
|
||||
const j = crypto.randomInt(i + 1);
|
||||
[parts[i], parts[j]] = [parts[j], parts[i]];
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { randomInt } from "crypto";
|
||||
import handlebars from "handlebars";
|
||||
import knex, { Knex } from "knex";
|
||||
import { z } from "zod";
|
||||
|
||||
import { crypto } from "@app/lib/crypto/cryptography";
|
||||
import { BadRequestError } from "@app/lib/errors";
|
||||
import { GatewayProxyProtocol, withGatewayProxy } from "@app/lib/gateway";
|
||||
import { logger } from "@app/lib/logger";
|
||||
@@ -64,7 +64,7 @@ const generatePassword = (requirements?: PasswordRequirements) => {
|
||||
parts.push(
|
||||
...Array(required.lowercase)
|
||||
.fill(0)
|
||||
.map(() => chars.lowercase[randomInt(chars.lowercase.length)])
|
||||
.map(() => chars.lowercase[crypto.randomInt(chars.lowercase.length)])
|
||||
);
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ const generatePassword = (requirements?: PasswordRequirements) => {
|
||||
parts.push(
|
||||
...Array(required.uppercase)
|
||||
.fill(0)
|
||||
.map(() => chars.uppercase[randomInt(chars.uppercase.length)])
|
||||
.map(() => chars.uppercase[crypto.randomInt(chars.uppercase.length)])
|
||||
);
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ const generatePassword = (requirements?: PasswordRequirements) => {
|
||||
parts.push(
|
||||
...Array(required.digits)
|
||||
.fill(0)
|
||||
.map(() => chars.digits[randomInt(chars.digits.length)])
|
||||
.map(() => chars.digits[crypto.randomInt(chars.digits.length)])
|
||||
);
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ const generatePassword = (requirements?: PasswordRequirements) => {
|
||||
parts.push(
|
||||
...Array(required.symbols)
|
||||
.fill(0)
|
||||
.map(() => chars.symbols[randomInt(chars.symbols.length)])
|
||||
.map(() => chars.symbols[crypto.randomInt(chars.symbols.length)])
|
||||
);
|
||||
}
|
||||
|
||||
@@ -103,12 +103,12 @@ const generatePassword = (requirements?: PasswordRequirements) => {
|
||||
parts.push(
|
||||
...Array(remainingLength)
|
||||
.fill(0)
|
||||
.map(() => allowedChars[randomInt(allowedChars.length)])
|
||||
.map(() => allowedChars[crypto.randomInt(allowedChars.length)])
|
||||
);
|
||||
|
||||
// shuffle the array to mix up the characters
|
||||
for (let i = parts.length - 1; i > 0; i -= 1) {
|
||||
const j = randomInt(i + 1);
|
||||
const j = crypto.randomInt(i + 1);
|
||||
[parts[i], parts[j]] = [parts[j], parts[i]];
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { CreateKeyCommand, DecryptCommand, DescribeKeyCommand, EncryptCommand, KMSClient } from "@aws-sdk/client-kms";
|
||||
import { AssumeRoleCommand, STSClient } from "@aws-sdk/client-sts";
|
||||
import { randomUUID } from "crypto";
|
||||
|
||||
import { CustomAWSHasher } from "@app/lib/aws/hashing";
|
||||
import { crypto } from "@app/lib/crypto/cryptography";
|
||||
|
||||
import { ExternalKmsAwsSchema, KmsAwsCredentialType, TExternalKmsAwsSchema, TExternalKmsProviderFns } from "./model";
|
||||
|
||||
@@ -8,11 +10,13 @@ const getAwsKmsClient = async (providerInputs: TExternalKmsAwsSchema) => {
|
||||
if (providerInputs.credential.type === KmsAwsCredentialType.AssumeRole) {
|
||||
const awsCredential = providerInputs.credential.data;
|
||||
const stsClient = new STSClient({
|
||||
region: providerInputs.awsRegion
|
||||
region: providerInputs.awsRegion,
|
||||
useFipsEndpoint: crypto.isFipsModeEnabled(),
|
||||
sha256: CustomAWSHasher
|
||||
});
|
||||
const command = new AssumeRoleCommand({
|
||||
RoleArn: awsCredential.assumeRoleArn,
|
||||
RoleSessionName: `infisical-kms-${randomUUID()}`,
|
||||
RoleSessionName: `infisical-kms-${crypto.nativeCrypto.randomUUID()}`,
|
||||
DurationSeconds: 900, // 15mins
|
||||
ExternalId: awsCredential.externalId
|
||||
});
|
||||
@@ -22,6 +26,8 @@ const getAwsKmsClient = async (providerInputs: TExternalKmsAwsSchema) => {
|
||||
|
||||
const kmsClient = new KMSClient({
|
||||
region: providerInputs.awsRegion,
|
||||
useFipsEndpoint: crypto.isFipsModeEnabled(),
|
||||
sha256: CustomAWSHasher,
|
||||
credentials: {
|
||||
accessKeyId: response.Credentials.AccessKeyId,
|
||||
secretAccessKey: response.Credentials.SecretAccessKey,
|
||||
@@ -34,6 +40,8 @@ const getAwsKmsClient = async (providerInputs: TExternalKmsAwsSchema) => {
|
||||
const awsCredential = providerInputs.credential.data;
|
||||
const kmsClient = new KMSClient({
|
||||
region: providerInputs.awsRegion,
|
||||
useFipsEndpoint: crypto.isFipsModeEnabled(),
|
||||
sha256: CustomAWSHasher,
|
||||
credentials: {
|
||||
accessKeyId: awsCredential.accessKey,
|
||||
secretAccessKey: awsCredential.secretKey
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import crypto from "node:crypto";
|
||||
|
||||
import { ForbiddenError } from "@casl/ability";
|
||||
import * as x509 from "@peculiar/x509";
|
||||
import { z } from "zod";
|
||||
|
||||
import { KeyStorePrefixes, PgSqlLock, TKeyStoreFactory } from "@app/keystore/keystore";
|
||||
import { getConfig } from "@app/lib/config/env";
|
||||
import { crypto } from "@app/lib/crypto/cryptography";
|
||||
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
||||
import { pingGatewayAndVerify } from "@app/lib/gateway";
|
||||
import { alphaNumericNanoId } from "@app/lib/nanoid";
|
||||
@@ -149,9 +148,9 @@ export const gatewayServiceFactory = ({
|
||||
|
||||
const alg = keyAlgorithmToAlgCfg(CertKeyAlgorithm.RSA_2048);
|
||||
// generate root CA
|
||||
const rootCaKeys = await crypto.subtle.generateKey(alg, true, ["sign", "verify"]);
|
||||
const rootCaKeys = await crypto.nativeCrypto.subtle.generateKey(alg, true, ["sign", "verify"]);
|
||||
const rootCaSerialNumber = createSerialNumber();
|
||||
const rootCaSkObj = crypto.KeyObject.from(rootCaKeys.privateKey);
|
||||
const rootCaSkObj = crypto.nativeCrypto.KeyObject.from(rootCaKeys.privateKey);
|
||||
const rootCaIssuedAt = new Date();
|
||||
const rootCaKeyAlgorithm = CertKeyAlgorithm.RSA_2048;
|
||||
const rootCaExpiration = new Date(new Date().setFullYear(2045));
|
||||
@@ -173,8 +172,8 @@ export const gatewayServiceFactory = ({
|
||||
const clientCaSerialNumber = createSerialNumber();
|
||||
const clientCaIssuedAt = new Date();
|
||||
const clientCaExpiration = new Date(new Date().setFullYear(2045));
|
||||
const clientCaKeys = await crypto.subtle.generateKey(alg, true, ["sign", "verify"]);
|
||||
const clientCaSkObj = crypto.KeyObject.from(clientCaKeys.privateKey);
|
||||
const clientCaKeys = await crypto.nativeCrypto.subtle.generateKey(alg, true, ["sign", "verify"]);
|
||||
const clientCaSkObj = crypto.nativeCrypto.KeyObject.from(clientCaKeys.privateKey);
|
||||
|
||||
const clientCaCert = await x509.X509CertificateGenerator.create({
|
||||
serialNumber: clientCaSerialNumber,
|
||||
@@ -200,7 +199,7 @@ export const gatewayServiceFactory = ({
|
||||
]
|
||||
});
|
||||
|
||||
const clientKeys = await crypto.subtle.generateKey(alg, true, ["sign", "verify"]);
|
||||
const clientKeys = await crypto.nativeCrypto.subtle.generateKey(alg, true, ["sign", "verify"]);
|
||||
const clientCertSerialNumber = createSerialNumber();
|
||||
const clientCert = await x509.X509CertificateGenerator.create({
|
||||
serialNumber: clientCertSerialNumber,
|
||||
@@ -226,14 +225,14 @@ export const gatewayServiceFactory = ({
|
||||
new x509.ExtendedKeyUsageExtension([x509.ExtendedKeyUsage[CertExtendedKeyUsage.CLIENT_AUTH]], true)
|
||||
]
|
||||
});
|
||||
const clientSkObj = crypto.KeyObject.from(clientKeys.privateKey);
|
||||
const clientSkObj = crypto.nativeCrypto.KeyObject.from(clientKeys.privateKey);
|
||||
|
||||
// generate gateway ca
|
||||
const gatewayCaSerialNumber = createSerialNumber();
|
||||
const gatewayCaIssuedAt = new Date();
|
||||
const gatewayCaExpiration = new Date(new Date().setFullYear(2045));
|
||||
const gatewayCaKeys = await crypto.subtle.generateKey(alg, true, ["sign", "verify"]);
|
||||
const gatewayCaSkObj = crypto.KeyObject.from(gatewayCaKeys.privateKey);
|
||||
const gatewayCaKeys = await crypto.nativeCrypto.subtle.generateKey(alg, true, ["sign", "verify"]);
|
||||
const gatewayCaSkObj = crypto.nativeCrypto.KeyObject.from(gatewayCaKeys.privateKey);
|
||||
const gatewayCaCert = await x509.X509CertificateGenerator.create({
|
||||
serialNumber: gatewayCaSerialNumber,
|
||||
subject: `O=${identityOrg},CN=Gateway CA`,
|
||||
@@ -326,7 +325,7 @@ export const gatewayServiceFactory = ({
|
||||
);
|
||||
|
||||
const gatewayCaAlg = keyAlgorithmToAlgCfg(orgGatewayConfig.rootCaKeyAlgorithm as CertKeyAlgorithm);
|
||||
const gatewayCaSkObj = crypto.createPrivateKey({
|
||||
const gatewayCaSkObj = crypto.nativeCrypto.createPrivateKey({
|
||||
key: orgKmsDecryptor({ cipherTextBlob: orgGatewayConfig.encryptedGatewayCaPrivateKey }),
|
||||
format: "der",
|
||||
type: "pkcs8"
|
||||
@@ -337,7 +336,7 @@ export const gatewayServiceFactory = ({
|
||||
})
|
||||
);
|
||||
|
||||
const gatewayCaPrivateKey = await crypto.subtle.importKey(
|
||||
const gatewayCaPrivateKey = await crypto.nativeCrypto.subtle.importKey(
|
||||
"pkcs8",
|
||||
gatewayCaSkObj.export({ format: "der", type: "pkcs8" }),
|
||||
gatewayCaAlg,
|
||||
@@ -346,7 +345,7 @@ export const gatewayServiceFactory = ({
|
||||
);
|
||||
|
||||
const alg = keyAlgorithmToAlgCfg(CertKeyAlgorithm.RSA_2048);
|
||||
const gatewayKeys = await crypto.subtle.generateKey(alg, true, ["sign", "verify"]);
|
||||
const gatewayKeys = await crypto.nativeCrypto.subtle.generateKey(alg, true, ["sign", "verify"]);
|
||||
const certIssuedAt = new Date();
|
||||
// then need to periodically init
|
||||
const certExpireAt = new Date(new Date().setMonth(new Date().getMonth() + 1));
|
||||
@@ -367,7 +366,7 @@ export const gatewayServiceFactory = ({
|
||||
];
|
||||
|
||||
const serialNumber = createSerialNumber();
|
||||
const privateKey = crypto.KeyObject.from(gatewayKeys.privateKey);
|
||||
const privateKey = crypto.nativeCrypto.KeyObject.from(gatewayKeys.privateKey);
|
||||
const gatewayCertificate = await x509.X509CertificateGenerator.create({
|
||||
serialNumber,
|
||||
subject: `CN=${identityId},O=${identityOrg},OU=Gateway`,
|
||||
@@ -454,7 +453,7 @@ export const gatewayServiceFactory = ({
|
||||
})
|
||||
);
|
||||
|
||||
const privateKey = crypto
|
||||
const privateKey = crypto.nativeCrypto
|
||||
.createPrivateKey({
|
||||
key: orgKmsDecryptor({ cipherTextBlob: orgGatewayConfig.encryptedClientPrivateKey }),
|
||||
format: "der",
|
||||
@@ -588,7 +587,7 @@ export const gatewayServiceFactory = ({
|
||||
})
|
||||
);
|
||||
|
||||
const clientSkObj = crypto.createPrivateKey({
|
||||
const clientSkObj = crypto.nativeCrypto.createPrivateKey({
|
||||
key: orgKmsDecryptor({ cipherTextBlob: orgGatewayConfig.encryptedClientPrivateKey }),
|
||||
format: "der",
|
||||
type: "pkcs8"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Knex } from "knex";
|
||||
|
||||
import { SecretKeyEncoding, TableName, TUsers } from "@app/db/schemas";
|
||||
import { decryptAsymmetric, encryptAsymmetric, infisicalSymmetricDecrypt } from "@app/lib/crypto/encryption";
|
||||
import { crypto } from "@app/lib/crypto/cryptography";
|
||||
import { BadRequestError, ForbiddenRequestError, NotFoundError, ScimRequestError } from "@app/lib/errors";
|
||||
|
||||
import {
|
||||
@@ -94,14 +94,17 @@ const addAcceptedUsersToGroup = async ({
|
||||
});
|
||||
}
|
||||
|
||||
const botPrivateKey = infisicalSymmetricDecrypt({
|
||||
keyEncoding: bot.keyEncoding as SecretKeyEncoding,
|
||||
iv: bot.iv,
|
||||
tag: bot.tag,
|
||||
ciphertext: bot.encryptedPrivateKey
|
||||
});
|
||||
const botPrivateKey = crypto
|
||||
.encryption()
|
||||
.symmetric()
|
||||
.decryptWithRootEncryptionKey({
|
||||
keyEncoding: bot.keyEncoding as SecretKeyEncoding,
|
||||
iv: bot.iv,
|
||||
tag: bot.tag,
|
||||
ciphertext: bot.encryptedPrivateKey
|
||||
});
|
||||
|
||||
const plaintextProjectKey = decryptAsymmetric({
|
||||
const plaintextProjectKey = crypto.encryption().asymmetric().decrypt({
|
||||
ciphertext: ghostUserLatestKey.encryptedKey,
|
||||
nonce: ghostUserLatestKey.nonce,
|
||||
publicKey: ghostUserLatestKey.sender.publicKey,
|
||||
@@ -109,11 +112,10 @@ const addAcceptedUsersToGroup = async ({
|
||||
});
|
||||
|
||||
const projectKeysToAdd = usersToAddProjectKeyFor.map((user) => {
|
||||
const { ciphertext: encryptedKey, nonce } = encryptAsymmetric(
|
||||
plaintextProjectKey,
|
||||
user.publicKey,
|
||||
botPrivateKey
|
||||
);
|
||||
const { ciphertext: encryptedKey, nonce } = crypto
|
||||
.encryption()
|
||||
.asymmetric()
|
||||
.encrypt(plaintextProjectKey, user.publicKey, botPrivateKey);
|
||||
return {
|
||||
encryptedKey,
|
||||
nonce,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ForbiddenError } from "@casl/ability";
|
||||
import * as x509 from "@peculiar/x509";
|
||||
import crypto, { KeyObject } from "crypto";
|
||||
|
||||
import { crypto } from "@app/lib/crypto/cryptography";
|
||||
import { BadRequestError, InternalServerError, NotFoundError } from "@app/lib/errors";
|
||||
import { isValidIp } from "@app/lib/ip";
|
||||
import { ms } from "@app/lib/ms";
|
||||
@@ -67,6 +67,12 @@ export const kmipServiceFactory = ({
|
||||
description,
|
||||
permissions
|
||||
}: TCreateKmipClientDTO) => {
|
||||
if (crypto.isFipsModeEnabled()) {
|
||||
throw new BadRequestError({
|
||||
message: "KMIP is currently not supported in FIPS mode of operation."
|
||||
});
|
||||
}
|
||||
|
||||
const { permission } = await permissionService.getProjectPermission({
|
||||
actor,
|
||||
actorId,
|
||||
@@ -292,7 +298,7 @@ export const kmipServiceFactory = ({
|
||||
}
|
||||
|
||||
const alg = keyAlgorithmToAlgCfg(keyAlgorithm);
|
||||
const leafKeys = await crypto.subtle.generateKey(alg, true, ["sign", "verify"]);
|
||||
const leafKeys = await crypto.nativeCrypto.subtle.generateKey(alg, true, ["sign", "verify"]);
|
||||
|
||||
const extensions: x509.Extension[] = [
|
||||
new x509.BasicConstraintsExtension(false),
|
||||
@@ -311,13 +317,13 @@ export const kmipServiceFactory = ({
|
||||
|
||||
const caAlg = keyAlgorithmToAlgCfg(kmipConfig.caKeyAlgorithm as CertKeyAlgorithm);
|
||||
|
||||
const caSkObj = crypto.createPrivateKey({
|
||||
const caSkObj = crypto.nativeCrypto.createPrivateKey({
|
||||
key: decryptor({ cipherTextBlob: kmipConfig.encryptedClientIntermediateCaPrivateKey }),
|
||||
format: "der",
|
||||
type: "pkcs8"
|
||||
});
|
||||
|
||||
const caPrivateKey = await crypto.subtle.importKey(
|
||||
const caPrivateKey = await crypto.nativeCrypto.subtle.importKey(
|
||||
"pkcs8",
|
||||
caSkObj.export({ format: "der", type: "pkcs8" }),
|
||||
caAlg,
|
||||
@@ -338,7 +344,7 @@ export const kmipServiceFactory = ({
|
||||
extensions
|
||||
});
|
||||
|
||||
const skLeafObj = KeyObject.from(leafKeys.privateKey);
|
||||
const skLeafObj = crypto.nativeCrypto.KeyObject.from(leafKeys.privateKey);
|
||||
|
||||
const rootCaCert = new x509.X509Certificate(decryptor({ cipherTextBlob: kmipConfig.encryptedRootCaCertificate }));
|
||||
const serverIntermediateCaCert = new x509.X509Certificate(
|
||||
@@ -417,8 +423,8 @@ export const kmipServiceFactory = ({
|
||||
|
||||
// generate root CA
|
||||
const rootCaSerialNumber = createSerialNumber();
|
||||
const rootCaKeys = await crypto.subtle.generateKey(alg, true, ["sign", "verify"]);
|
||||
const rootCaSkObj = KeyObject.from(rootCaKeys.privateKey);
|
||||
const rootCaKeys = await crypto.nativeCrypto.subtle.generateKey(alg, true, ["sign", "verify"]);
|
||||
const rootCaSkObj = crypto.nativeCrypto.KeyObject.from(rootCaKeys.privateKey);
|
||||
const rootCaIssuedAt = new Date();
|
||||
const rootCaExpiration = new Date(new Date().setFullYear(new Date().getFullYear() + 20));
|
||||
|
||||
@@ -440,8 +446,8 @@ export const kmipServiceFactory = ({
|
||||
const serverIntermediateCaSerialNumber = createSerialNumber();
|
||||
const serverIntermediateCaIssuedAt = new Date();
|
||||
const serverIntermediateCaExpiration = new Date(new Date().setFullYear(new Date().getFullYear() + 10));
|
||||
const serverIntermediateCaKeys = await crypto.subtle.generateKey(alg, true, ["sign", "verify"]);
|
||||
const serverIntermediateCaSkObj = KeyObject.from(serverIntermediateCaKeys.privateKey);
|
||||
const serverIntermediateCaKeys = await crypto.nativeCrypto.subtle.generateKey(alg, true, ["sign", "verify"]);
|
||||
const serverIntermediateCaSkObj = crypto.nativeCrypto.KeyObject.from(serverIntermediateCaKeys.privateKey);
|
||||
|
||||
const serverIntermediateCaCert = await x509.X509CertificateGenerator.create({
|
||||
serialNumber: serverIntermediateCaSerialNumber,
|
||||
@@ -471,8 +477,8 @@ export const kmipServiceFactory = ({
|
||||
const clientIntermediateCaSerialNumber = createSerialNumber();
|
||||
const clientIntermediateCaIssuedAt = new Date();
|
||||
const clientIntermediateCaExpiration = new Date(new Date().setFullYear(new Date().getFullYear() + 10));
|
||||
const clientIntermediateCaKeys = await crypto.subtle.generateKey(alg, true, ["sign", "verify"]);
|
||||
const clientIntermediateCaSkObj = KeyObject.from(clientIntermediateCaKeys.privateKey);
|
||||
const clientIntermediateCaKeys = await crypto.nativeCrypto.subtle.generateKey(alg, true, ["sign", "verify"]);
|
||||
const clientIntermediateCaSkObj = crypto.nativeCrypto.KeyObject.from(clientIntermediateCaKeys.privateKey);
|
||||
|
||||
const clientIntermediateCaCert = await x509.X509CertificateGenerator.create({
|
||||
serialNumber: clientIntermediateCaSerialNumber,
|
||||
@@ -637,7 +643,8 @@ export const kmipServiceFactory = ({
|
||||
}
|
||||
|
||||
const alg = keyAlgorithmToAlgCfg(keyAlgorithm);
|
||||
const leafKeys = await crypto.subtle.generateKey(alg, true, ["sign", "verify"]);
|
||||
|
||||
const leafKeys = await crypto.nativeCrypto.subtle.generateKey(alg, true, ["sign", "verify"]);
|
||||
|
||||
const extensions: x509.Extension[] = [
|
||||
new x509.BasicConstraintsExtension(false),
|
||||
@@ -685,13 +692,13 @@ export const kmipServiceFactory = ({
|
||||
cipherTextBlob: kmipOrgConfig.encryptedServerIntermediateCaChain
|
||||
}).toString("utf-8");
|
||||
|
||||
const caSkObj = crypto.createPrivateKey({
|
||||
const caSkObj = crypto.nativeCrypto.createPrivateKey({
|
||||
key: decryptor({ cipherTextBlob: kmipOrgConfig.encryptedServerIntermediateCaPrivateKey }),
|
||||
format: "der",
|
||||
type: "pkcs8"
|
||||
});
|
||||
|
||||
const caPrivateKey = await crypto.subtle.importKey(
|
||||
const caPrivateKey = await crypto.nativeCrypto.subtle.importKey(
|
||||
"pkcs8",
|
||||
caSkObj.export({ format: "der", type: "pkcs8" }),
|
||||
caAlg,
|
||||
@@ -712,7 +719,7 @@ export const kmipServiceFactory = ({
|
||||
extensions
|
||||
});
|
||||
|
||||
const skLeafObj = KeyObject.from(leafKeys.privateKey);
|
||||
const skLeafObj = crypto.nativeCrypto.KeyObject.from(leafKeys.privateKey);
|
||||
const certificateChain = `${caCertObj.toString("pem")}\n${decryptedCaCertChain}`.trim();
|
||||
|
||||
await kmipOrgServerCertificateDAL.create({
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { ForbiddenError } from "@casl/ability";
|
||||
import jwt from "jsonwebtoken";
|
||||
|
||||
import { OrgMembershipStatus, TableName, TLdapConfigsUpdate, TUsers } from "@app/db/schemas";
|
||||
import { TGroupDALFactory } from "@app/ee/services/group/group-dal";
|
||||
import { addUsersToGroupByUserIds, removeUsersFromGroupByUserIds } from "@app/ee/services/group/group-fns";
|
||||
import { TUserGroupMembershipDALFactory } from "@app/ee/services/group/user-group-membership-dal";
|
||||
import { getConfig } from "@app/lib/config/env";
|
||||
import { crypto } from "@app/lib/crypto";
|
||||
import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors";
|
||||
import { AuthMethod, AuthTokenType } from "@app/services/auth/auth-type";
|
||||
import { TAuthTokenServiceFactory } from "@app/services/auth-token/auth-token-service";
|
||||
@@ -529,7 +529,7 @@ export const ldapConfigServiceFactory = ({
|
||||
const isUserCompleted = Boolean(user.isAccepted);
|
||||
const userEnc = await userDAL.findUserEncKeyByUserId(user.id);
|
||||
|
||||
const providerAuthToken = jwt.sign(
|
||||
const providerAuthToken = crypto.jwt().sign(
|
||||
{
|
||||
authTokenType: AuthTokenType.PROVIDER_TOKEN,
|
||||
userId: user.id,
|
||||
|
||||
@@ -58,7 +58,8 @@ export const getDefaultOnPremFeatures = (): TFeatureSet => ({
|
||||
sshHostGroups: false,
|
||||
secretScanning: false,
|
||||
enterpriseSecretSyncs: false,
|
||||
enterpriseAppConnections: false
|
||||
enterpriseAppConnections: false,
|
||||
fips: false
|
||||
});
|
||||
|
||||
export const setupLicenseRequestWithStore = (
|
||||
|
||||
@@ -75,6 +75,7 @@ export type TFeatureSet = {
|
||||
secretScanning: false;
|
||||
enterpriseSecretSyncs: false;
|
||||
enterpriseAppConnections: false;
|
||||
fips: false;
|
||||
};
|
||||
|
||||
export type TOrgPlansTableDTO = {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||
import { ForbiddenError } from "@casl/ability";
|
||||
import jwt from "jsonwebtoken";
|
||||
import { Issuer, Issuer as OpenIdIssuer, Strategy as OpenIdStrategy, TokenSet } from "openid-client";
|
||||
|
||||
import { OrgMembershipStatus, TableName, TUsers } from "@app/db/schemas";
|
||||
@@ -13,6 +12,7 @@ import { TLicenseServiceFactory } from "@app/ee/services/license/license-service
|
||||
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||
import { getConfig } from "@app/lib/config/env";
|
||||
import { crypto } from "@app/lib/crypto";
|
||||
import { BadRequestError, ForbiddenRequestError, NotFoundError, OidcAuthError } from "@app/lib/errors";
|
||||
import { OrgServiceActor } from "@app/lib/types";
|
||||
import { ActorType, AuthMethod, AuthTokenType } from "@app/services/auth/auth-type";
|
||||
@@ -406,7 +406,7 @@ export const oidcConfigServiceFactory = ({
|
||||
|
||||
const userEnc = await userDAL.findUserEncKeyByUserId(user.id);
|
||||
const isUserCompleted = Boolean(user.isAccepted);
|
||||
const providerAuthToken = jwt.sign(
|
||||
const providerAuthToken = crypto.jwt().sign(
|
||||
{
|
||||
authTokenType: AuthTokenType.PROVIDER_TOKEN,
|
||||
userId: user.id,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { ForbiddenError } from "@casl/ability";
|
||||
import jwt from "jsonwebtoken";
|
||||
|
||||
import { OrgMembershipStatus, TableName, TSamlConfigs, TSamlConfigsUpdate, TUsers } from "@app/db/schemas";
|
||||
import { getConfig } from "@app/lib/config/env";
|
||||
import { crypto } from "@app/lib/crypto";
|
||||
import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors";
|
||||
import { AuthTokenType } from "@app/services/auth/auth-type";
|
||||
import { TAuthTokenServiceFactory } from "@app/services/auth-token/auth-token-service";
|
||||
@@ -412,7 +412,7 @@ export const samlConfigServiceFactory = ({
|
||||
|
||||
const isUserCompleted = Boolean(user.isAccepted);
|
||||
const userEnc = await userDAL.findUserEncKeyByUserId(user.id);
|
||||
const providerAuthToken = jwt.sign(
|
||||
const providerAuthToken = crypto.jwt().sign(
|
||||
{
|
||||
authTokenType: AuthTokenType.PROVIDER_TOKEN,
|
||||
userId: user.id,
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { ForbiddenError } from "@casl/ability";
|
||||
import slugify from "@sindresorhus/slugify";
|
||||
import jwt from "jsonwebtoken";
|
||||
import { scimPatch } from "scim-patch";
|
||||
|
||||
import { OrgMembershipRole, OrgMembershipStatus, TableName, TGroups, TOrgMemberships, TUsers } from "@app/db/schemas";
|
||||
@@ -9,6 +8,7 @@ import { addUsersToGroupByUserIds, removeUsersFromGroupByUserIds } from "@app/ee
|
||||
import { TUserGroupMembershipDALFactory } from "@app/ee/services/group/user-group-membership-dal";
|
||||
import { TScimDALFactory } from "@app/ee/services/scim/scim-dal";
|
||||
import { getConfig } from "@app/lib/config/env";
|
||||
import { crypto } from "@app/lib/crypto";
|
||||
import { BadRequestError, NotFoundError, ScimRequestError, UnauthorizedError } from "@app/lib/errors";
|
||||
import { alphaNumericNanoId } from "@app/lib/nanoid";
|
||||
import { AuthTokenType } from "@app/services/auth/auth-type";
|
||||
@@ -137,7 +137,7 @@ export const scimServiceFactory = ({
|
||||
ttlDays
|
||||
});
|
||||
|
||||
const scimToken = jwt.sign(
|
||||
const scimToken = crypto.jwt().sign(
|
||||
{
|
||||
scimTokenId: scimTokenData.id,
|
||||
authTokenType: AuthTokenType.SCIM_TOKEN
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
} from "@app/db/schemas";
|
||||
import { Event, EventType } from "@app/ee/services/audit-log/audit-log-types";
|
||||
import { getConfig } from "@app/lib/config/env";
|
||||
import { decryptSymmetric128BitHexKeyUTF8 } from "@app/lib/crypto";
|
||||
import { crypto, SymmetricKeySize } from "@app/lib/crypto/cryptography";
|
||||
import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors";
|
||||
import { groupBy, pick, unique } from "@app/lib/fn";
|
||||
import { setKnexStringValue } from "@app/lib/knex";
|
||||
@@ -820,11 +820,12 @@ export const secretApprovalRequestServiceFactory = ({
|
||||
type: SecretType.Shared,
|
||||
references: botKey
|
||||
? getAllNestedSecretReferences(
|
||||
decryptSymmetric128BitHexKeyUTF8({
|
||||
crypto.encryption().symmetric().decrypt({
|
||||
ciphertext: el.secretValueCiphertext,
|
||||
iv: el.secretValueIV,
|
||||
tag: el.secretValueTag,
|
||||
key: botKey
|
||||
key: botKey,
|
||||
keySize: SymmetricKeySize.Bits128
|
||||
})
|
||||
)
|
||||
: undefined
|
||||
@@ -865,11 +866,12 @@ export const secretApprovalRequestServiceFactory = ({
|
||||
]),
|
||||
references: botKey
|
||||
? getAllNestedSecretReferences(
|
||||
decryptSymmetric128BitHexKeyUTF8({
|
||||
crypto.encryption().symmetric().decrypt({
|
||||
ciphertext: el.secretValueCiphertext,
|
||||
iv: el.secretValueIV,
|
||||
tag: el.secretValueTag,
|
||||
key: botKey
|
||||
key: botKey,
|
||||
keySize: SymmetricKeySize.Bits128
|
||||
})
|
||||
)
|
||||
: undefined
|
||||
|
||||
@@ -3,7 +3,7 @@ import { TSecretApprovalPolicyServiceFactory } from "@app/ee/services/secret-app
|
||||
import { TSecretApprovalRequestDALFactory } from "@app/ee/services/secret-approval-request/secret-approval-request-dal";
|
||||
import { TSecretApprovalRequestSecretDALFactory } from "@app/ee/services/secret-approval-request/secret-approval-request-secret-dal";
|
||||
import { KeyStorePrefixes, TKeyStoreFactory } from "@app/keystore/keystore";
|
||||
import { decryptSymmetric128BitHexKeyUTF8 } from "@app/lib/crypto";
|
||||
import { crypto, SymmetricKeySize } from "@app/lib/crypto/cryptography";
|
||||
import { NotFoundError } from "@app/lib/errors";
|
||||
import { groupBy, unique } from "@app/lib/fn";
|
||||
import { logger } from "@app/lib/logger";
|
||||
@@ -100,18 +100,20 @@ const getReplicationKeyLockPrefix = (projectId: string, environmentSlug: string,
|
||||
export const getReplicationFolderName = (importId: string) => `${ReservedFolders.SecretReplication}${importId}`;
|
||||
|
||||
const getDecryptedKeyValue = (key: string, secret: TSecrets) => {
|
||||
const secretKey = decryptSymmetric128BitHexKeyUTF8({
|
||||
const secretKey = crypto.encryption().symmetric().decrypt({
|
||||
ciphertext: secret.secretKeyCiphertext,
|
||||
iv: secret.secretKeyIV,
|
||||
tag: secret.secretKeyTag,
|
||||
key
|
||||
key,
|
||||
keySize: SymmetricKeySize.Bits128
|
||||
});
|
||||
|
||||
const secretValue = decryptSymmetric128BitHexKeyUTF8({
|
||||
const secretValue = crypto.encryption().symmetric().decrypt({
|
||||
ciphertext: secret.secretValueCiphertext,
|
||||
iv: secret.secretValueIV,
|
||||
tag: secret.secretValueTag,
|
||||
key
|
||||
key,
|
||||
keySize: SymmetricKeySize.Bits128
|
||||
});
|
||||
return { key: secretKey, value: secretValue };
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { randomInt } from "crypto";
|
||||
import { crypto } from "@app/lib/crypto/cryptography";
|
||||
|
||||
type TPasswordRequirements = {
|
||||
length: number;
|
||||
@@ -39,7 +39,7 @@ export const generatePassword = (passwordRequirements?: TPasswordRequirements) =
|
||||
parts.push(
|
||||
...Array(required.lowercase)
|
||||
.fill(0)
|
||||
.map(() => chars.lowercase[randomInt(chars.lowercase.length)])
|
||||
.map(() => chars.lowercase[crypto.randomInt(chars.lowercase.length)])
|
||||
);
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ export const generatePassword = (passwordRequirements?: TPasswordRequirements) =
|
||||
parts.push(
|
||||
...Array(required.uppercase)
|
||||
.fill(0)
|
||||
.map(() => chars.uppercase[randomInt(chars.uppercase.length)])
|
||||
.map(() => chars.uppercase[crypto.randomInt(chars.uppercase.length)])
|
||||
);
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ export const generatePassword = (passwordRequirements?: TPasswordRequirements) =
|
||||
parts.push(
|
||||
...Array(required.digits)
|
||||
.fill(0)
|
||||
.map(() => chars.digits[randomInt(chars.digits.length)])
|
||||
.map(() => chars.digits[crypto.randomInt(chars.digits.length)])
|
||||
);
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ export const generatePassword = (passwordRequirements?: TPasswordRequirements) =
|
||||
parts.push(
|
||||
...Array(required.symbols)
|
||||
.fill(0)
|
||||
.map(() => chars.symbols[randomInt(chars.symbols.length)])
|
||||
.map(() => chars.symbols[crypto.randomInt(chars.symbols.length)])
|
||||
);
|
||||
}
|
||||
|
||||
@@ -78,12 +78,12 @@ export const generatePassword = (passwordRequirements?: TPasswordRequirements) =
|
||||
parts.push(
|
||||
...Array(remainingLength)
|
||||
.fill(0)
|
||||
.map(() => allowedChars[randomInt(allowedChars.length)])
|
||||
.map(() => allowedChars[crypto.randomInt(allowedChars.length)])
|
||||
);
|
||||
|
||||
// shuffle the array to mix up the characters
|
||||
for (let i = parts.length - 1; i > 0; i -= 1) {
|
||||
const j = randomInt(i + 1);
|
||||
const j = crypto.randomInt(i + 1);
|
||||
[parts[i], parts[j]] = [parts[j], parts[i]];
|
||||
}
|
||||
|
||||
|
||||
+18
-7
@@ -6,8 +6,9 @@ import {
|
||||
} from "@aws-sdk/client-iam";
|
||||
|
||||
import { SecretType } from "@app/db/schemas";
|
||||
import { CustomAWSHasher } from "@app/lib/aws/hashing";
|
||||
import { getConfig } from "@app/lib/config/env";
|
||||
import { encryptSymmetric128BitHexKeyUTF8 } from "@app/lib/crypto/encryption";
|
||||
import { crypto, SymmetricKeySize } from "@app/lib/crypto/cryptography";
|
||||
import { daysToMillisecond, secondsToMillis } from "@app/lib/dates";
|
||||
import { NotFoundError } from "@app/lib/errors";
|
||||
import { logger } from "@app/lib/logger";
|
||||
@@ -117,6 +118,7 @@ export const secretRotationQueueFactory = ({
|
||||
queue.start(QueueName.SecretRotation, async (job) => {
|
||||
const { rotationId } = job.data;
|
||||
const appCfg = getConfig();
|
||||
|
||||
logger.info(`secretRotationQueue.process: [rotationDocument=${rotationId}]`);
|
||||
const secretRotation = await secretRotationDAL.findById(rotationId);
|
||||
const rotationProvider = rotationTemplates.find(({ name }) => name === secretRotation?.provider);
|
||||
@@ -225,6 +227,8 @@ export const secretRotationQueueFactory = ({
|
||||
if (provider.template.type === TProviderFunctionTypes.AWS) {
|
||||
if (provider.template.client === TAwsProviderSystems.IAM) {
|
||||
const client = new IAMClient({
|
||||
useFipsEndpoint: crypto.isFipsModeEnabled(),
|
||||
sha256: CustomAWSHasher,
|
||||
region: newCredential.inputs.manager_user_aws_region as string,
|
||||
credentials: {
|
||||
accessKeyId: newCredential.inputs.manager_user_access_key as string,
|
||||
@@ -365,15 +369,22 @@ export const secretRotationQueueFactory = ({
|
||||
throw new NotFoundError({
|
||||
message: `Project bot not found for project with ID '${secretRotation.projectId}'`
|
||||
});
|
||||
|
||||
const encryptedSecrets = rotationOutputs.map(({ key: outputKey, secretId }) => ({
|
||||
secretId,
|
||||
value: encryptSymmetric128BitHexKeyUTF8(
|
||||
typeof newCredential.outputs[outputKey] === "object"
|
||||
? JSON.stringify(newCredential.outputs[outputKey])
|
||||
: String(newCredential.outputs[outputKey]),
|
||||
botKey
|
||||
)
|
||||
value: crypto
|
||||
.encryption()
|
||||
.symmetric()
|
||||
.encrypt({
|
||||
plaintext:
|
||||
typeof newCredential.outputs[outputKey] === "object"
|
||||
? JSON.stringify(newCredential.outputs[outputKey])
|
||||
: String(newCredential.outputs[outputKey]),
|
||||
key: botKey,
|
||||
keySize: SymmetricKeySize.Bits128
|
||||
})
|
||||
}));
|
||||
|
||||
// map the final values to output keys in the board
|
||||
await secretRotationDAL.transaction(async (tx) => {
|
||||
await secretRotationDAL.updateById(
|
||||
|
||||
@@ -2,7 +2,7 @@ import { ForbiddenError, subject } from "@casl/ability";
|
||||
import Ajv from "ajv";
|
||||
|
||||
import { ProjectVersion, TableName } from "@app/db/schemas";
|
||||
import { decryptSymmetric128BitHexKeyUTF8 } from "@app/lib/crypto/encryption";
|
||||
import { crypto, SymmetricKeySize } from "@app/lib/crypto/cryptography";
|
||||
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
||||
import { TProjectPermission } from "@app/lib/types";
|
||||
import { TKmsServiceFactory } from "@app/services/kms/kms-service";
|
||||
@@ -227,6 +227,7 @@ export const secretRotationServiceFactory = ({
|
||||
|
||||
if (!botKey) throw new NotFoundError({ message: `Project bot not found for project with ID '${projectId}'` });
|
||||
const docs = await secretRotationDAL.find({ projectId });
|
||||
|
||||
return docs.map((el) => ({
|
||||
...el,
|
||||
outputs: el.outputs.map((output) => ({
|
||||
@@ -234,11 +235,12 @@ export const secretRotationServiceFactory = ({
|
||||
secret: {
|
||||
id: output.secret.id,
|
||||
version: output.secret.version,
|
||||
secretKey: decryptSymmetric128BitHexKeyUTF8({
|
||||
secretKey: crypto.encryption().symmetric().decrypt({
|
||||
ciphertext: output.secret.secretKeyCiphertext,
|
||||
iv: output.secret.secretKeyIV,
|
||||
tag: output.secret.secretKeyTag,
|
||||
key: botKey
|
||||
key: botKey,
|
||||
keySize: SymmetricKeySize.Bits128
|
||||
})
|
||||
}
|
||||
}))
|
||||
|
||||
+2
-3
@@ -1,8 +1,7 @@
|
||||
import crypto from "crypto";
|
||||
|
||||
import { TSecretScanningV2DALFactory } from "@app/ee/services/secret-scanning-v2/secret-scanning-v2-dal";
|
||||
import { SecretScanningDataSource } from "@app/ee/services/secret-scanning-v2/secret-scanning-v2-enums";
|
||||
import { TSecretScanningV2QueueServiceFactory } from "@app/ee/services/secret-scanning-v2/secret-scanning-v2-queue";
|
||||
import { crypto } from "@app/lib/crypto";
|
||||
import { logger } from "@app/lib/logger";
|
||||
import { TKmsServiceFactory } from "@app/services/kms/kms-service";
|
||||
import { KmsDataKey } from "@app/services/kms/kms-types";
|
||||
@@ -67,7 +66,7 @@ export const bitbucketSecretScanningService = (
|
||||
|
||||
const credentials = JSON.parse(decryptedCredentials.toString()) as TBitbucketDataSourceCredentials;
|
||||
|
||||
const hmac = crypto.createHmac("sha256", credentials.webhookSecret);
|
||||
const hmac = crypto.nativeCrypto.createHmac("sha256", credentials.webhookSecret);
|
||||
hmac.update(bodyString);
|
||||
const calculatedSignature = hmac.digest("hex");
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import crypto from "node:crypto";
|
||||
|
||||
import { ForbiddenError } from "@casl/ability";
|
||||
import { WebhookEventMap } from "@octokit/webhooks-types";
|
||||
import { ProbotOctokit } from "probot";
|
||||
@@ -7,6 +5,7 @@ import { ProbotOctokit } from "probot";
|
||||
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||
import { getConfig } from "@app/lib/config/env";
|
||||
import { crypto } from "@app/lib/crypto/cryptography";
|
||||
import { NotFoundError } from "@app/lib/errors";
|
||||
|
||||
import { TGitAppDALFactory } from "./git-app-dal";
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import { ForbiddenError } from "@casl/ability";
|
||||
|
||||
import { TableName, TSecretTagJunctionInsert, TSecretV2TagJunctionInsert } from "@app/db/schemas";
|
||||
import { decryptSymmetric128BitHexKeyUTF8 } from "@app/lib/crypto";
|
||||
import { crypto, SymmetricKeySize } from "@app/lib/crypto/cryptography";
|
||||
import { InternalServerError, NotFoundError } from "@app/lib/errors";
|
||||
import { groupBy } from "@app/lib/fn";
|
||||
import { logger } from "@app/lib/logger";
|
||||
@@ -233,14 +233,16 @@ export const secretSnapshotServiceFactory = ({
|
||||
const { botKey } = await projectBotService.getBotKey(snapshot.projectId);
|
||||
if (!botKey)
|
||||
throw new NotFoundError({ message: `Project bot key not found for project with ID '${snapshot.projectId}'` });
|
||||
|
||||
snapshotDetails = {
|
||||
...encryptedSnapshotDetails,
|
||||
secretVersions: encryptedSnapshotDetails.secretVersions.map((el) => {
|
||||
const secretKey = decryptSymmetric128BitHexKeyUTF8({
|
||||
const secretKey = crypto.encryption().symmetric().decrypt({
|
||||
ciphertext: el.secretKeyCiphertext,
|
||||
iv: el.secretKeyIV,
|
||||
tag: el.secretKeyTag,
|
||||
key: botKey
|
||||
key: botKey,
|
||||
keySize: SymmetricKeySize.Bits128
|
||||
});
|
||||
|
||||
const canReadValue = hasSecretReadValueOrDescribePermission(
|
||||
@@ -257,11 +259,12 @@ export const secretSnapshotServiceFactory = ({
|
||||
let secretValue = "";
|
||||
|
||||
if (canReadValue) {
|
||||
secretValue = decryptSymmetric128BitHexKeyUTF8({
|
||||
secretValue = crypto.encryption().symmetric().decrypt({
|
||||
ciphertext: el.secretValueCiphertext,
|
||||
iv: el.secretValueIV,
|
||||
tag: el.secretValueTag,
|
||||
key: botKey
|
||||
key: botKey,
|
||||
keySize: SymmetricKeySize.Bits128
|
||||
});
|
||||
} else {
|
||||
secretValue = INFISICAL_SECRET_VALUE_HIDDEN_MASK;
|
||||
@@ -274,11 +277,12 @@ export const secretSnapshotServiceFactory = ({
|
||||
secretValue,
|
||||
secretComment:
|
||||
el.secretCommentTag && el.secretCommentIV && el.secretCommentCiphertext
|
||||
? decryptSymmetric128BitHexKeyUTF8({
|
||||
? crypto.encryption().symmetric().decrypt({
|
||||
ciphertext: el.secretCommentCiphertext,
|
||||
iv: el.secretCommentIV,
|
||||
tag: el.secretCommentTag,
|
||||
key: botKey
|
||||
key: botKey,
|
||||
keySize: SymmetricKeySize.Bits128
|
||||
})
|
||||
: ""
|
||||
};
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { execFile } from "child_process";
|
||||
import crypto from "crypto";
|
||||
import { promises as fs } from "fs";
|
||||
import { Knex } from "knex";
|
||||
import os from "os";
|
||||
@@ -9,6 +8,7 @@ import { promisify } from "util";
|
||||
|
||||
import { TSshCertificateTemplates } from "@app/db/schemas";
|
||||
import { SshCertKeyAlgorithm } from "@app/ee/services/ssh-certificate/ssh-certificate-types";
|
||||
import { crypto } from "@app/lib/crypto/cryptography";
|
||||
import { BadRequestError } from "@app/lib/errors";
|
||||
import { ms } from "@app/lib/ms";
|
||||
import { CharacterType, characterValidator } from "@app/lib/validator/validate-string";
|
||||
|
||||
Reference in New Issue
Block a user