Merge branch 'INDA-330-pii-update' into 'main'
[ProtonMail-WebClient.git] / packages / srp / lib / utils / modulus.ts
blobd5e8f49632937ac5a9637f2adf2713dc97dab7ef
1 import type { PublicKeyReference } from '@proton/crypto';
2 import { CryptoProxy } from '@proton/crypto';
3 import { binaryStringToArray, decodeBase64 } from '@proton/crypto/lib/utils';
5 import { SRP_MODULUS_KEY, VERIFICATION_STATUS } from '../constants';
7 const { NOT_SIGNED, SIGNED_AND_VALID } = VERIFICATION_STATUS;
9 /**
10  * Get key to verify the modulus
11  */
12 export const getModulusKey = (() => {
13     let cachedKeyReference: PublicKeyReference | undefined;
15     const get = async () => {
16         try {
17             const keyReference = await CryptoProxy.importPublicKey({ armoredKey: SRP_MODULUS_KEY });
18             cachedKeyReference = keyReference;
19             return cachedKeyReference;
20         } catch (e) {
21             cachedKeyReference = undefined;
22             throw e;
23         }
24     };
26     return async () => {
27         const isValidKeyReference =
28             cachedKeyReference &&
29             // after logging out, the key store is cleared, and the key reference becomes invalid.
30             // try and export the key to see if it's still valid
31             (await CryptoProxy.exportPublicKey({ key: cachedKeyReference, format: 'binary' })
32                 .then(() => true)
33                 .catch(() => false));
34         if (isValidKeyReference) {
35             return cachedKeyReference as PublicKeyReference;
36         }
37         return get();
38     };
39 })();
41 /**
42  * Verify the modulus signature with the SRP public key
43  * @returns modulus value if verification is successful
44  * @throws on verification error
45  */
46 export const verifyModulus = async (publicKey: PublicKeyReference, modulus: string) => {
47     try {
48         const { data: modulusData, verified = NOT_SIGNED } = await CryptoProxy.verifyCleartextMessage({
49             armoredCleartextMessage: modulus,
50             verificationKeys: publicKey,
51         });
53         if (verified !== SIGNED_AND_VALID) {
54             throw new Error();
55         }
57         return modulusData;
58     } catch (e) {
59         throw new Error('Unable to verify server identity');
60     }
63 /**
64  * Verify modulus from the API and get the value.
65  */
66 export const verifyAndGetModulus = async (modulus: string) => {
67     const publicKey = await getModulusKey();
68     const modulusData = await verifyModulus(publicKey, modulus);
69     return binaryStringToArray(decodeBase64(modulusData));