mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-08 10:28:00 +00:00
Implement nonce gen and check
This commit is contained in:
@@ -5,6 +5,7 @@ import { BadRequestError, NotFoundError, UnauthorizedError } from "@app/lib/erro
|
|||||||
import { logger } from "@app/lib/logger";
|
import { logger } from "@app/lib/logger";
|
||||||
import { TCertificateProfileDALFactory } from "@app/services/certificate-profile/certificate-profile-dal";
|
import { TCertificateProfileDALFactory } from "@app/services/certificate-profile/certificate-profile-dal";
|
||||||
|
|
||||||
|
import { KeyStorePrefixes, TKeyStoreFactory } from "@app/keystore/keystore";
|
||||||
import { ActorType } from "@app/services/auth/auth-type";
|
import { ActorType } from "@app/services/auth/auth-type";
|
||||||
import {
|
import {
|
||||||
EnrollmentType,
|
EnrollmentType,
|
||||||
@@ -29,6 +30,7 @@ import { TPkiAcmeChallengeDALFactory } from "./pki-acme-challenge-dal";
|
|||||||
import {
|
import {
|
||||||
AcmeAccountDoesNotExistError,
|
AcmeAccountDoesNotExistError,
|
||||||
AcmeBadCSRError,
|
AcmeBadCSRError,
|
||||||
|
AcmeBadNonceError,
|
||||||
AcmeBadPublicKeyError,
|
AcmeBadPublicKeyError,
|
||||||
AcmeError,
|
AcmeError,
|
||||||
AcmeExternalAccountRequiredError,
|
AcmeExternalAccountRequiredError,
|
||||||
@@ -87,6 +89,7 @@ type TPkiAcmeServiceFactoryDep = {
|
|||||||
TPkiAcmeChallengeDALFactory,
|
TPkiAcmeChallengeDALFactory,
|
||||||
"create" | "transaction" | "updateById" | "findByAccountAuthAndChallengeId" | "findByIdForChallengeValidation"
|
"create" | "transaction" | "updateById" | "findByAccountAuthAndChallengeId" | "findByIdForChallengeValidation"
|
||||||
>;
|
>;
|
||||||
|
keyStore: Pick<TKeyStoreFactory, "getItem" | "setItemWithExpiry" | "deleteItem">;
|
||||||
kmsService: Pick<TKmsServiceFactory, "decryptWithKmsKey" | "generateKmsKey">;
|
kmsService: Pick<TKmsServiceFactory, "decryptWithKmsKey" | "generateKmsKey">;
|
||||||
certificateV3Service: Pick<TCertificateV3ServiceFactory, "signCertificateFromProfile">;
|
certificateV3Service: Pick<TCertificateV3ServiceFactory, "signCertificateFromProfile">;
|
||||||
acmeChallengeService: TPkiAcmeChallengeServiceFactory;
|
acmeChallengeService: TPkiAcmeChallengeServiceFactory;
|
||||||
@@ -100,6 +103,7 @@ export const pkiAcmeServiceFactory = ({
|
|||||||
acmeAuthDAL,
|
acmeAuthDAL,
|
||||||
acmeOrderAuthDAL,
|
acmeOrderAuthDAL,
|
||||||
acmeChallengeDAL,
|
acmeChallengeDAL,
|
||||||
|
keyStore,
|
||||||
kmsService,
|
kmsService,
|
||||||
certificateV3Service,
|
certificateV3Service,
|
||||||
acmeChallengeService
|
acmeChallengeService
|
||||||
@@ -157,6 +161,14 @@ export const pkiAcmeServiceFactory = ({
|
|||||||
if (new URL(protectedHeader.url).href !== url.href) {
|
if (new URL(protectedHeader.url).href !== url.href) {
|
||||||
throw new AcmeUnauthorizedError({ detail: "URL mismatch in the protected header" });
|
throw new AcmeUnauthorizedError({ detail: "URL mismatch in the protected header" });
|
||||||
}
|
}
|
||||||
|
if (!protectedHeader.nonce) {
|
||||||
|
throw new AcmeMalformedError({ detail: "Nonce is required in the protected header" });
|
||||||
|
}
|
||||||
|
const deleted = await keyStore.deleteItem(KeyStorePrefixes.PkiAcmeNonce(protectedHeader.nonce));
|
||||||
|
if (deleted !== 1) {
|
||||||
|
throw new AcmeBadNonceError({ detail: "Invalid nonce" });
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: consume the nonce here
|
// TODO: consume the nonce here
|
||||||
const decoder = new TextDecoder();
|
const decoder = new TextDecoder();
|
||||||
const textPayload = decoder.decode(rawPayload);
|
const textPayload = decoder.decode(rawPayload);
|
||||||
@@ -285,10 +297,17 @@ export const pkiAcmeServiceFactory = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const getAcmeNewNonce = async (profileId: string): Promise<string> => {
|
const getAcmeNewNonce = async (profileId: string): Promise<string> => {
|
||||||
const profile = await validateAcmeProfile(profileId);
|
await validateAcmeProfile(profileId);
|
||||||
// FIXME: Implement ACME new nonce generation
|
const nonce = crypto.randomBytes(32).toString("base64url");
|
||||||
// Generate a new nonce, store it, and return it
|
const nonceKey = KeyStorePrefixes.PkiAcmeNonce(nonce);
|
||||||
return "FIXME-generate-nonce";
|
await keyStore.setItemWithExpiry(
|
||||||
|
nonceKey,
|
||||||
|
// Expire in 5 minutes.
|
||||||
|
// TODO: read config from the profile to get the expiration time instead
|
||||||
|
60 * 5,
|
||||||
|
nonce
|
||||||
|
);
|
||||||
|
return nonce;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** --------------------------------------------------------------
|
/** --------------------------------------------------------------
|
||||||
|
|||||||
@@ -77,7 +77,9 @@ export const KeyStorePrefixes = {
|
|||||||
UserProjectPermissionPattern: (userId: string) => `project-permission:*:*:USER:${userId}:*` as const,
|
UserProjectPermissionPattern: (userId: string) => `project-permission:*:*:USER:${userId}:*` as const,
|
||||||
IdentityProjectPermissionPattern: (identityId: string) => `project-permission:*:*:IDENTITY:${identityId}:*` as const,
|
IdentityProjectPermissionPattern: (identityId: string) => `project-permission:*:*:IDENTITY:${identityId}:*` as const,
|
||||||
GroupMemberProjectPermissionPattern: (projectId: string, groupId: string) =>
|
GroupMemberProjectPermissionPattern: (projectId: string, groupId: string) =>
|
||||||
`group-member-project-permission:${projectId}:${groupId}:*` as const
|
`group-member-project-permission:${projectId}:${groupId}:*` as const,
|
||||||
|
|
||||||
|
PkiAcmeNonce: (nonce: string) => `pki-acme-nonce:${nonce}` as const
|
||||||
};
|
};
|
||||||
|
|
||||||
export const KeyStoreTtls = {
|
export const KeyStoreTtls = {
|
||||||
|
|||||||
Reference in New Issue
Block a user