Checkpoint argon2id test to generate blind index

This commit is contained in:
Tuan Dang
2023-04-15 15:21:44 +03:00
parent 3eb810b979
commit fcb677d990
8 changed files with 104 additions and 14 deletions

View File

@@ -1,7 +1,9 @@
import { Request, Response } from 'express';
import { Types } from 'mongoose';
import {
Secret
} from '../../models';
import crypto from 'crypto';
// TODO: modularize argon2id
import * as argon2 from 'argon2';
@@ -47,13 +49,32 @@ export const createSecret = async (req: Request, res: Response) => {
const {
workspaceId,
environment,
value
value,
type
} = req.body;
//
// use bot to encrypt value
// BotService.encryptSymmetric(value)
// use workspace salt
const randomBytes = crypto.randomBytes(16);
// generate blind index
// TODO 1: abstract away into create blind index function
// TODO 2: create a get blind index function
const secretBlindIndex = (await argon2.hash(secretName, {
type: argon2.argon2id,
salt: randomBytes,
saltLength: 16, // default 16 bytes
memoryCost: 65536, // default pool of 64 MiB per thread.
hashLength: 32,
parallelism: 1,
raw: true
})).toString('base64');
// const secret = await new Secret({
// workspace: new Types.ObjectId(workspaceId),
// environment,
// type,
// secretBlindIndex
// }).save();
return res.status(200).send({

View File

@@ -61,6 +61,9 @@ import {
environment as v2EnvironmentRouter,
tags as v2TagsRouter,
} from './routes/v2';
import {
secrets as v3SecretsRouter
} from './routes/v3';
import { healthCheck } from './routes/status';
import { getLogger } from './utils/logger';
import { RouteNotFoundError } from './utils/errors';
@@ -121,7 +124,7 @@ const main = async () => {
app.use('/api/v1/workspace', eeWorkspaceRouter);
app.use('/api/v1/action', eeActionRouter);
// v1 routes
// v1 routes (default)
app.use('/api/v1/signup', v1SignupRouter);
app.use('/api/v1/auth', v1AuthRouter);
app.use('/api/v1/bot', v1BotRouter);
@@ -140,7 +143,7 @@ const main = async () => {
app.use('/api/v1/integration', v1IntegrationRouter);
app.use('/api/v1/integration-auth', v1IntegrationAuthRouter);
// v2 routes
// v2 routes (improvements)
app.use('/api/v2/signup', v2SignupRouter);
app.use('/api/v2/auth', v2AuthRouter);
app.use('/api/v2/users', v2UsersRouter);
@@ -153,6 +156,9 @@ const main = async () => {
app.use('/api/v2/service-token', v2ServiceTokenDataRouter); // TODO: turn into plural route
app.use('/api/v2/service-accounts', v2ServiceAccountsRouter); // new
app.use('/api/v2/api-key', v2APIKeyDataRouter);
// v3 routes (experimental)
app.use('/api/v3/secrets', v3SecretsRouter);
// api docs
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerFile))

View File

@@ -9,6 +9,7 @@ import Membership, { IMembership } from './membership';
import MembershipOrg, { IMembershipOrg } from './membershipOrg';
import Organization, { IOrganization } from './organization';
import Secret, { ISecret } from './secret';
import SecretBlindIndexData, { ISecretBlindIndexData } from './secretBlindIndexData';
import ServiceToken, { IServiceToken } from './serviceToken';
import ServiceAccount, { IServiceAccount } from './serviceAccount'; // new
import ServiceAccountKey, { IServiceAccountKey } from './serviceAccountKey'; // new
@@ -45,6 +46,8 @@ export {
IOrganization,
Secret,
ISecret,
SecretBlindIndexData,
ISecretBlindIndexData,
ServiceToken,
IServiceToken,
ServiceAccount,

View File

@@ -1,4 +1,4 @@
import { Schema, model, Types } from 'mongoose';
import { Schema, model, Types, Document } from 'mongoose';
import {
SECRET_SHARED,
SECRET_PERSONAL,
@@ -11,6 +11,7 @@ export interface ISecret {
type: string;
user: Types.ObjectId;
environment: string;
secretBlindIndex?: string;
secretKeyCiphertext: string;
secretKeyIV: string;
secretKeyTag: string;
@@ -57,6 +58,9 @@ const secretSchema = new Schema<ISecret>(
type: String,
required: true
},
secretBlindIndex: {
type: String
},
secretKeyCiphertext: {
type: String,
required: true

View File

@@ -0,0 +1,25 @@
import { Schema, model, Types, Document } from 'mongoose';
export interface ISecretBlindIndexData {
_id: Types.ObjectId;
workspace: Types.ObjectId;
encryptedSalt: string;
}
const secretBlindIndexDataSchema = new Schema<ISecretBlindIndexData>(
{
workspace: {
type: Schema.Types.ObjectId,
ref: 'Workspace',
required: true
},
encryptedSalt: {
type: String,
required: true
}
}
);
const SecretBlindIndexData = model<ISecretBlindIndexData>('SecretBlindIndexData', secretBlindIndexDataSchema);
export default SecretBlindIndexData;

View File

@@ -0,0 +1,5 @@
import secrets from './secrets';
export {
secrets
}

View File

@@ -20,13 +20,13 @@ router.post(
'/:secretName',
body('workspaceId').exists().isString().trim(),
body('environment').exists().isString().trim(),
body('value').exists().isString().trim(),
body('secretKeyCiphertext').optional().isString().trim(),
body('secretKeyIV').optional().isString().trim(),
body('secretKeyTag').optional().isString().trim(),
body('secretValueCiphertext').optional().isString().trim(),
body('secretValueIV').optional().isString().trim(),
body('secretValueTag').optional().isString().trim(),
body('secretKeyCiphertext').exists().isString().trim(),
body('secretKeyIV').exists().isString().trim(),
body('secretKeyTag').exists().isString().trim(),
body('secretValueCiphertext').exists().isString().trim(),
body('secretValueIV').exists().isString().trim(),
body('secretValueTag').exists().isString().trim(),
validateRequest,
secretsController.createSecret
);

View File

@@ -0,0 +1,26 @@
// WIP
import { Types } from 'mongoose';
class SecretService {
static async createSecretBlindIndex({
secretName,
workspaceId,
}: {
secretName: string;
workspaceId: Types.ObjectId;
}) {
// TODO
return;
}
static async getSecretBlindIndex({
secretName,
workspaceId
}: {
secretName: string;
workspaceId: Types.ObjectId;
}) {
// TODO
return;
}
}