diff --git a/web/packages/accounts/components/SignUp.tsx b/web/packages/accounts/components/SignUp.tsx index 0d2efef62c..9cda4607b1 100644 --- a/web/packages/accounts/components/SignUp.tsx +++ b/web/packages/accounts/components/SignUp.tsx @@ -1,8 +1,8 @@ import { sendOtt } from "@/accounts/api/user"; import { PasswordStrengthHint } from "@/accounts/components/PasswordStrength"; import { PAGES } from "@/accounts/constants/pages"; +import { generateKeyAndSRPAttributes } from "@/accounts/services/srp"; import { isWeakPassword } from "@/accounts/utils"; -import { generateKeyAndSRPAttributes } from "@/accounts/utils/srp"; import { FormPaperFooter, FormPaperTitle } from "@/base/components/FormPaper"; import { LoadingButton } from "@/base/components/mui/LoadingButton"; import log from "@/base/log"; diff --git a/web/packages/accounts/pages/change-password.tsx b/web/packages/accounts/pages/change-password.tsx index 4325352193..cf2643103a 100644 --- a/web/packages/accounts/pages/change-password.tsx +++ b/web/packages/accounts/pages/change-password.tsx @@ -8,11 +8,12 @@ import SetPasswordForm, { } from "@/accounts/components/SetPasswordForm"; import { PAGES } from "@/accounts/constants/pages"; import { + convertBase64ToBuffer, + convertBufferToBase64, generateSRPClient, generateSRPSetupAttributes, } from "@/accounts/services/srp"; import type { UpdatedKey } from "@/accounts/types/user"; -import { convertBase64ToBuffer, convertBufferToBase64 } from "@/accounts/utils"; import { FormPaper, FormPaperFooter, diff --git a/web/packages/accounts/pages/generate.tsx b/web/packages/accounts/pages/generate.tsx index 9e7544b4d9..6140360fdc 100644 --- a/web/packages/accounts/pages/generate.tsx +++ b/web/packages/accounts/pages/generate.tsx @@ -4,8 +4,10 @@ import SetPasswordForm, { type SetPasswordFormProps, } from "@/accounts/components/SetPasswordForm"; import { PAGES } from "@/accounts/constants/pages"; -import { configureSRP } from "@/accounts/services/srp"; -import { generateKeyAndSRPAttributes } from "@/accounts/utils/srp"; +import { + configureSRP, + generateKeyAndSRPAttributes, +} from "@/accounts/services/srp"; import { FormPaper, FormPaperFooter, diff --git a/web/packages/accounts/services/srp.ts b/web/packages/accounts/services/srp.ts index 319e3e8ef1..1e19b1d81b 100644 --- a/web/packages/accounts/services/srp.ts +++ b/web/packages/accounts/services/srp.ts @@ -3,6 +3,7 @@ import { sharedCryptoWorker } from "@/base/crypto"; import log from "@/base/log"; import { generateLoginSubKey } from "@ente/shared/crypto/helpers"; import { getToken } from "@ente/shared/storage/localStorage/helpers"; +import type { KeyAttributes } from "@ente/shared/user/types"; import { SRP, SrpClient } from "fast-srp-hap"; import { v4 as uuidv4 } from "uuid"; import type { SRPAttributes, SRPSetupAttributes } from "../api/srp"; @@ -12,7 +13,6 @@ import { startSRPSetup, verifySRPSession, } from "../api/srp"; -import { convertBase64ToBuffer, convertBufferToBase64 } from "../utils"; const SRP_PARAMS = SRP.params["4096"]; @@ -160,3 +160,69 @@ export const generateSRPClient = async ( }); }); }; + +export const convertBufferToBase64 = (buffer: Buffer) => { + return buffer.toString("base64"); +}; + +export const convertBase64ToBuffer = (base64: string) => { + return Buffer.from(base64, "base64"); +}; + +export async function generateKeyAndSRPAttributes(passphrase: string): Promise<{ + keyAttributes: KeyAttributes; + masterKey: string; + srpSetupAttributes: SRPSetupAttributes; +}> { + const cryptoWorker = await sharedCryptoWorker(); + const masterKey = await cryptoWorker.generateEncryptionKey(); + const recoveryKey = await cryptoWorker.generateEncryptionKey(); + const kekSalt = await cryptoWorker.generateSaltToDeriveKey(); + const kek = await cryptoWorker.deriveSensitiveKey(passphrase, kekSalt); + + const masterKeyEncryptedWithKek = await cryptoWorker.encryptToB64( + masterKey, + kek.key, + ); + const masterKeyEncryptedWithRecoveryKey = await cryptoWorker.encryptToB64( + masterKey, + recoveryKey, + ); + const recoveryKeyEncryptedWithMasterKey = await cryptoWorker.encryptToB64( + recoveryKey, + masterKey, + ); + + const keyPair = await cryptoWorker.generateKeyPair(); + const encryptedKeyPairAttributes = await cryptoWorker.encryptToB64( + keyPair.privateKey, + masterKey, + ); + + const loginSubKey = await generateLoginSubKey(kek.key); + + const srpSetupAttributes = await generateSRPSetupAttributes(loginSubKey); + + const keyAttributes: KeyAttributes = { + kekSalt, + encryptedKey: masterKeyEncryptedWithKek.encryptedData, + keyDecryptionNonce: masterKeyEncryptedWithKek.nonce, + publicKey: keyPair.publicKey, + encryptedSecretKey: encryptedKeyPairAttributes.encryptedData, + secretKeyDecryptionNonce: encryptedKeyPairAttributes.nonce, + opsLimit: kek.opsLimit, + memLimit: kek.memLimit, + masterKeyEncryptedWithRecoveryKey: + masterKeyEncryptedWithRecoveryKey.encryptedData, + masterKeyDecryptionNonce: masterKeyEncryptedWithRecoveryKey.nonce, + recoveryKeyEncryptedWithMasterKey: + recoveryKeyEncryptedWithMasterKey.encryptedData, + recoveryKeyDecryptionNonce: recoveryKeyEncryptedWithMasterKey.nonce, + }; + + return { + keyAttributes, + masterKey, + srpSetupAttributes, + }; +} diff --git a/web/packages/accounts/utils/index.ts b/web/packages/accounts/utils/index.ts index c2b5055447..7383354029 100644 --- a/web/packages/accounts/utils/index.ts +++ b/web/packages/accounts/utils/index.ts @@ -2,13 +2,6 @@ import zxcvbn from "zxcvbn"; export type PasswordStrength = "weak" | "moderate" | "strong"; -export const convertBufferToBase64 = (buffer: Buffer) => { - return buffer.toString("base64"); -}; - -export const convertBase64ToBuffer = (base64: string) => { - return Buffer.from(base64, "base64"); -}; export function estimatePasswordStrength(password: string): PasswordStrength { if (!password) { diff --git a/web/packages/accounts/utils/srp.ts b/web/packages/accounts/utils/srp.ts deleted file mode 100644 index 25f8430886..0000000000 --- a/web/packages/accounts/utils/srp.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { sharedCryptoWorker } from "@/base/crypto"; -import { generateLoginSubKey } from "@ente/shared/crypto/helpers"; -import type { KeyAttributes } from "@ente/shared/user/types"; -import type { SRPSetupAttributes } from "../api/srp"; -import { generateSRPSetupAttributes } from "../services/srp"; - -export async function generateKeyAndSRPAttributes(passphrase: string): Promise<{ - keyAttributes: KeyAttributes; - masterKey: string; - srpSetupAttributes: SRPSetupAttributes; -}> { - const cryptoWorker = await sharedCryptoWorker(); - const masterKey = await cryptoWorker.generateEncryptionKey(); - const recoveryKey = await cryptoWorker.generateEncryptionKey(); - const kekSalt = await cryptoWorker.generateSaltToDeriveKey(); - const kek = await cryptoWorker.deriveSensitiveKey(passphrase, kekSalt); - - const masterKeyEncryptedWithKek = await cryptoWorker.encryptToB64( - masterKey, - kek.key, - ); - const masterKeyEncryptedWithRecoveryKey = await cryptoWorker.encryptToB64( - masterKey, - recoveryKey, - ); - const recoveryKeyEncryptedWithMasterKey = await cryptoWorker.encryptToB64( - recoveryKey, - masterKey, - ); - - const keyPair = await cryptoWorker.generateKeyPair(); - const encryptedKeyPairAttributes = await cryptoWorker.encryptToB64( - keyPair.privateKey, - masterKey, - ); - - const loginSubKey = await generateLoginSubKey(kek.key); - - const srpSetupAttributes = await generateSRPSetupAttributes(loginSubKey); - - const keyAttributes: KeyAttributes = { - kekSalt, - encryptedKey: masterKeyEncryptedWithKek.encryptedData, - keyDecryptionNonce: masterKeyEncryptedWithKek.nonce, - publicKey: keyPair.publicKey, - encryptedSecretKey: encryptedKeyPairAttributes.encryptedData, - secretKeyDecryptionNonce: encryptedKeyPairAttributes.nonce, - opsLimit: kek.opsLimit, - memLimit: kek.memLimit, - masterKeyEncryptedWithRecoveryKey: - masterKeyEncryptedWithRecoveryKey.encryptedData, - masterKeyDecryptionNonce: masterKeyEncryptedWithRecoveryKey.nonce, - recoveryKeyEncryptedWithMasterKey: - recoveryKeyEncryptedWithMasterKey.encryptedData, - recoveryKeyDecryptionNonce: recoveryKeyEncryptedWithMasterKey.nonce, - }; - - return { - keyAttributes, - masterKey, - srpSetupAttributes, - }; -}