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;
10 * Get key to verify the modulus
12 export const getModulusKey = (() => {
13 let cachedKeyReference: PublicKeyReference | undefined;
15 const get = async () => {
17 const keyReference = await CryptoProxy.importPublicKey({ armoredKey: SRP_MODULUS_KEY });
18 cachedKeyReference = keyReference;
19 return cachedKeyReference;
21 cachedKeyReference = undefined;
27 const isValidKeyReference =
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' })
34 if (isValidKeyReference) {
35 return cachedKeyReference as PublicKeyReference;
42 * Verify the modulus signature with the SRP public key
43 * @returns modulus value if verification is successful
44 * @throws on verification error
46 export const verifyModulus = async (publicKey: PublicKeyReference, modulus: string) => {
48 const { data: modulusData, verified = NOT_SIGNED } = await CryptoProxy.verifyCleartextMessage({
49 armoredCleartextMessage: modulus,
50 verificationKeys: publicKey,
53 if (verified !== SIGNED_AND_VALID) {
59 throw new Error('Unable to verify server identity');
64 * Verify modulus from the API and get the value.
66 export const verifyAndGetModulus = async (modulus: string) => {
67 const publicKey = await getModulusKey();
68 const modulusData = await verifyModulus(publicKey, modulus);
69 return binaryStringToArray(decodeBase64(modulusData));