diff --git a/holo-key-manager-extension/scripts/helpers.ts b/holo-key-manager-extension/scripts/helpers.ts index b3630c9..84bc72e 100644 --- a/holo-key-manager-extension/scripts/helpers.ts +++ b/holo-key-manager-extension/scripts/helpers.ts @@ -4,7 +4,7 @@ import { seedBundleReady, UnlockedSeedBundle } from '@holochain/hc-seed-bundle'; -import { AUTHENTICATED_APPS_LIST, SESSION } from '@shared/const'; +import { AUTHENTICATED_APPS_LIST, DEEP_KEY_AGENT_OFFSET, SESSION } from '@shared/const'; import { base64ToUint8Array, uint8ArrayToBase64 } from '@shared/helpers'; import { getDeviceKey, storageService } from '@shared/services'; import { @@ -41,7 +41,7 @@ export const signMessageLogic = async ({ message, happId, session }: SignMessage const pw = new TextEncoder().encode(session); const keyUnlocked = cipherList[0].unlock(parseSecret(pw)); - const appKey = keyUnlocked.derive(index); + const appKey = keyUnlocked.derive(index + DEEP_KEY_AGENT_OFFSET); const uIntArrayMessage = base64ToUint8Array(message); diff --git a/holo-key-manager-extension/src/lib/const/index.ts b/holo-key-manager-extension/src/lib/const/index.ts new file mode 100644 index 0000000..29b4a01 --- /dev/null +++ b/holo-key-manager-extension/src/lib/const/index.ts @@ -0,0 +1,2 @@ +export const KEY_INDEX = 0; +export const DEEP_KEY_INDEX = 0; diff --git a/holo-key-manager-extension/src/lib/helpers/queries.ts b/holo-key-manager-extension/src/lib/helpers/queries.ts index f3b1b8a..9433970 100644 --- a/holo-key-manager-extension/src/lib/helpers/queries.ts +++ b/holo-key-manager-extension/src/lib/helpers/queries.ts @@ -2,6 +2,7 @@ import { encodeHashToBase64 } from '@holochain/client'; import { encode } from '@msgpack/msgpack'; import type { QueryClient } from '@tanstack/svelte-query'; +import { DEEP_KEY_INDEX, KEY_INDEX } from '$const'; import { createGetKeysObjectParams, getKeys, unlockKey } from '$services'; import { AUTHENTICATED_APPS_LIST, @@ -36,12 +37,12 @@ export const getPassword = async () => { }; export const fetchKeys = async () => { - const devicePubKey = await getDevicePubKeyWithExternalEncoding(); + const { pubKey } = await getDeepKeyAgentPubKeyWithExternalEncoding(); const getKeysParams = createGetKeysObjectParams({ - deepkeyAgent: devicePubKey.pubKey, + deepkeyAgent: pubKey, timestamp: Date.now() }); - const signedMessage = await signWithDevicePubKey(getKeysParams); + const signedMessage = await signWithDeepKeyAgent(getKeysParams); return await getKeys(getKeysParams, signedMessage.signature); }; @@ -83,16 +84,6 @@ export const getExtensionSession = async () => { return parsedResponse.data.payload; }; -const getSessionAndKey = async () => { - const session = await getExtensionSession(); - if (!session) { - throw new Error('Session data not found'); - } - const encryptedDeviceKey = await getDeviceKey(); - const keyUnlocked = await unlockKey(encryptedDeviceKey, session); - return keyUnlocked; -}; - const validatePubKey = (signPubKey: Uint8Array, encoder: (key: Uint8Array) => string) => { const validatedSchema = PubKeySchema.safeParse({ pubKey: encoder(signPubKey) @@ -110,21 +101,26 @@ const validatePubKeyWithExternalEncoding = (signPubKey: Uint8Array) => { return validatePubKey(extendedSignPubKey, encodeHashToBase64); }; -export const getDevicePubKeyWithExternalEncoding = async () => { - const keyUnlocked = await getSessionAndKey(); - const { signPubKey } = keyUnlocked; +const deriveAppKey = async (index: number) => { + const session = await getExtensionSession(); + if (!session) { + throw new Error('Session data not found'); + } + const encryptedDeviceKey = await getDeviceKey(); + const keyUnlocked = await unlockKey(encryptedDeviceKey, session); + const agent = keyUnlocked.derive(index); keyUnlocked.zero(); - return validatePubKeyWithExternalEncoding(signPubKey); + const appKey = agent.derive(KEY_INDEX); + agent.zero(); + return appKey; }; -export const signWithDevicePubKey = async (payload: object) => { - const keyUnlocked = await getSessionAndKey(); - +export const signWithDeepKeyAgent = async (payload: object) => { + const deepKeyAgent = await deriveAppKey(DEEP_KEY_INDEX); const encodedPayload = encode(payload, { useBigInt64: true }); - const signature = keyUnlocked.sign(encodedPayload); - - keyUnlocked.zero(); + const signature = deepKeyAgent.sign(encodedPayload); + deepKeyAgent.zero(); const validatedSchema = SuccessMessageSignedSchema.safeParse({ signature: encodeHashToBase64(signature) @@ -137,14 +133,21 @@ export const signWithDevicePubKey = async (payload: object) => { return validatedSchema.data; }; -const deriveSignPubKeyBase = async (newIndex: number, validator: (key: Uint8Array) => PubKey) => { - const keyUnlocked = await getSessionAndKey(); - const { signPubKey } = keyUnlocked.derive(newIndex); - keyUnlocked.zero(); - return validator(signPubKey); +export const getDeepKeyAgentPubKeyWithExternalEncoding = async () => { + const appKey = await deriveAppKey(DEEP_KEY_INDEX); + const validatedPubKey = validatePubKeyWithExternalEncoding(appKey.signPubKey); + appKey.zero(); + return validatedPubKey; +}; + +const deriveSignPubKeyBase = async (index: number, validator: (key: Uint8Array) => PubKey) => { + const appKey = await deriveAppKey(index); + const validatedPubKey = validator(appKey.signPubKey); + appKey.zero(); + return validatedPubKey; }; -export const deriveSignPubKey = async (newIndex: number) => - deriveSignPubKeyBase(newIndex, validatePubKeyWithBase64); -export const deriveSignPubKeyWithExternalEncoding = async (newIndex: number) => - deriveSignPubKeyBase(newIndex, validatePubKeyWithExternalEncoding); +export const deriveSignPubKey = async (index: number) => + deriveSignPubKeyBase(index, validatePubKeyWithBase64); +export const deriveSignPubKeyWithExternalEncoding = async (index: number) => + deriveSignPubKeyBase(index, validatePubKeyWithExternalEncoding); diff --git a/holo-key-manager-extension/src/lib/queries/applicationQueries.ts b/holo-key-manager-extension/src/lib/queries/applicationQueries.ts index 1527c14..a76974e 100644 --- a/holo-key-manager-extension/src/lib/queries/applicationQueries.ts +++ b/holo-key-manager-extension/src/lib/queries/applicationQueries.ts @@ -5,12 +5,13 @@ import { deriveSignPubKeyWithExternalEncoding, fetchAuthenticatedAppsList, fetchKeys, - getDevicePubKeyWithExternalEncoding, + getDeepKeyAgentPubKeyWithExternalEncoding, handleSuccess, sendMessageAndHandleResponse, - signWithDevicePubKey + signWithDeepKeyAgent } from '$helpers'; import { createRegisterKeyBody, registerKey } from '$services'; +import { DEEP_KEY_AGENT_OFFSET } from '$shared/const'; import { APPLICATION_KEYS, APPLICATION_SIGNED_IN_KEY, @@ -39,9 +40,9 @@ export function createApplicationKeyMutation(queryClient: QueryClient) { }) => { const currentParsedAuthenticatedAppsListData = await fetchAuthenticatedAppsList(); - const newIndex = mutationData.currentAppsList.length; + const newIndex = mutationData.currentAppsList.length + DEEP_KEY_AGENT_OFFSET; - const devicePubKeyExternal = await getDevicePubKeyWithExternalEncoding(); + const devicePubKeyExternal = await getDeepKeyAgentPubKeyWithExternalEncoding(); const pubKeyObjectExternal = await deriveSignPubKeyWithExternalEncoding(newIndex); @@ -59,7 +60,7 @@ export function createApplicationKeyMutation(queryClient: QueryClient) { happUiUrl: mutationData.happUiUrl }); - const signedPostMessage = await signWithDevicePubKey(registerKeyBody); + const signedPostMessage = await signWithDeepKeyAgent(registerKeyBody); await registerKey(registerKeyBody, signedPostMessage.signature); @@ -121,7 +122,7 @@ export function createSignInWithKeyMutation(queryClient: QueryClient) { (app) => app.happId === happId && app.keyName === keyName ); - const pubKey = await deriveSignPubKey(index); + const pubKey = await deriveSignPubKey(index + DEEP_KEY_AGENT_OFFSET); storageService.set({ key: AUTHENTICATED_APPS_LIST, diff --git a/holo-key-manager-extension/static/manifest.json b/holo-key-manager-extension/static/manifest.json index 803acdf..db3a57e 100644 --- a/holo-key-manager-extension/static/manifest.json +++ b/holo-key-manager-extension/static/manifest.json @@ -1,7 +1,7 @@ { "name": "Holo key manager", "description": "A browser extension to manage holo keys", - "version": "0.0.68", + "version": "0.0.69", "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiAtKvbHNTN3O2BLRZH7RkLczaMLenSeZu+YP+KomPQPZ18nt4DY9boIN/+GWts7gCzEeQq59l8edGdF2P7xAbsRxYR88+zFEbxMtIyfyqJZIlzXwnvPJkwGu/S6arNtX48K7q1+xnJEE7VyeYSj6/i2LR+LmPigCzY9JCP7+SmWVeYbdm3kZmReK0ecfh15RXSNjZpXJUgrbea/RVxweggYKnmhhOUBmuJSCLoWTXIuJPBMwGQK1O2GKBqHOq94bPVSF7j+4WzSpPan70ZZJX/reFsOFE/idfFN6wbizjR1Ne50Po03kudEmfQgoqUhVpd0wP8A3YbqE7ODdZcCPPwIDAQAB", "manifest_version": 3, "action": { diff --git a/holo-key-manager-extension/tests/index.test.ts b/holo-key-manager-extension/tests/index.test.ts index aaaa4fb..1e4af9a 100644 --- a/holo-key-manager-extension/tests/index.test.ts +++ b/holo-key-manager-extension/tests/index.test.ts @@ -110,25 +110,10 @@ describe('transformDataToIndexedArray', () => { happLogo: 'https://example.com/logo.png', happUiUrl: 'https://example.com/description.html' } - }, - { - newKey: 'uhCAkzSOTorctsWN-ASn7s-FxI6Av9VkXFvi5Vdq4boJyO8jzPkZu', - appName: 'Cloud Console', - installedAppId: 'uhCkkJlEYXJyglP3ECCNBobeeEp-z85CVm_SsViHpxDyPK6Mzzkyp', - appIndex: 0, - metadata: { keyName: 'key 1', happUiUrl: 'https://cloud-console.holo.host/' } } ]; const expectedOutput = [ - { - happId: 'uhCkkJlEYXJyglP3ECCNBobeeEp-z85CVm_SsViHpxDyPK6Mzzkyp', - happName: 'Cloud Console', - happLogo: undefined, - newKey: 'uhCAkzSOTorctsWN-ASn7s-FxI6Av9VkXFvi5Vdq4boJyO8jzPkZu', - keyName: 'key 1', - happUiUrl: 'https://cloud-console.holo.host/' - }, { happId: 'uhCkkSwHw3d3yz-tg26QxvY0ZZyO85pbmhQXYDwj4mdnQrQx4uF6L', happName: 'Cloud Console', diff --git a/shared/const/app.ts b/shared/const/app.ts index 779605c..ed237da 100644 --- a/shared/const/app.ts +++ b/shared/const/app.ts @@ -3,6 +3,7 @@ export const HOLO_KEY_MANAGER_APP_ID = 'holo-key-manager'; export const SENDER_WEBAPP = 'webapp'; export const SENDER_EXTENSION = 'extension'; export const SENDER_BACKGROUND_SCRIPT = 'background-script'; +export const DEEP_KEY_AGENT_OFFSET = 1; export const HOLO_KEY_MANAGER_EXTENSION_MARKER_ID = 'user-holo-key-manager-extension-marker';