Skip to content

Commit fa3c953

Browse files
committed
refactor: move getSalt api to kernal to reuse as a common trusted key
1 parent 2bda1cc commit fa3c953

File tree

2 files changed

+62
-2
lines changed

2 files changed

+62
-2
lines changed

src/phoenix/trust_ring.js

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,65 @@ async function _portCredentials() {
369369
}
370370
}
371371

372+
const FALLBACK_SALT = 'fallback-salt-2f309322-b32d-4d59-85b4-2baef666a9f4';
373+
let currentSalt;
374+
375+
/**
376+
* Attempt to get or create the trusted key (salt) from the credential store.
377+
* Returns the salt string on success, or null if getCredential throws.
378+
*/
379+
async function _getTrustedKeyInternal() {
380+
try {
381+
let salt = await getCredential(SIGNATURE_SALT_KEY);
382+
if (!salt) {
383+
// Generate and store new salt
384+
salt = crypto.randomUUID();
385+
await setCredential(SIGNATURE_SALT_KEY, salt);
386+
}
387+
return salt;
388+
} catch (error) {
389+
console.error("Error in _getTrustedKeyInternal:", error);
390+
return null;
391+
}
392+
}
393+
394+
const MAX_SALT_RETRIES = 2;
395+
396+
/**
397+
* Get per-user trusted key (salt) for signature generation, creating and persisting one if it doesn't exist.
398+
* Used for signing cached data to prevent tampering.
399+
*/
400+
async function getTrustedKey() {
401+
if (currentSalt) {
402+
return currentSalt;
403+
}
404+
405+
if (Phoenix.isNativeApp) {
406+
// Native app: use credential store with retries
407+
let salt = await _getTrustedKeyInternal();
408+
const Metrics = window.Metrics;
409+
for (let i = 0; i < MAX_SALT_RETRIES && !salt; i++) {
410+
console.warn(`Retrying _getTrustedKeyInternal (attempt ${i + 2})`);
411+
Metrics && Metrics.countEvent(Metrics.EVENT_TYPE.AUTH, "saltGet", "retry");
412+
salt = await _getTrustedKeyInternal();
413+
}
414+
if (salt) {
415+
currentSalt = salt;
416+
return salt;
417+
}
418+
// All retries exhausted, fall back
419+
console.error("All salt retrieval attempts failed, using fallback salt");
420+
Metrics && Metrics.countEvent(Metrics.EVENT_TYPE.AUTH, "saltGet", "Err");
421+
currentSalt = FALLBACK_SALT;
422+
return FALLBACK_SALT;
423+
}
424+
425+
// In browser app, there is no way to securely store salt without extensions being able to
426+
// read it. Return a static salt for basic integrity checking.
427+
currentSalt = FALLBACK_SALT;
428+
return FALLBACK_SALT;
429+
}
430+
372431
/**
373432
* Generates an SHA-256 hash signature of the provided data string combined with a salt.
374433
*
@@ -418,7 +477,8 @@ window.KernalModeTrust = {
418477
dismantleKeyring,
419478
generateDataSignature,
420479
validateDataSignature,
421-
reinstallCreds
480+
reinstallCreds,
481+
getTrustedKey
422482
};
423483
// Pass the trust ring reference to phoenix-builder (MCP) before it is
424484
// nuked from window. The builder needs dismantleKeyring() for reload.

tracking-repos.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"phoenixPro": {
3-
"commitID": "05032be3c0db6c84375423c02b2c7663d1eba125"
3+
"commitID": "836c3e159891a0c72dda128cc0a2ee27f06cf113"
44
}
55
}

0 commit comments

Comments
 (0)