From 4e6631071e1f69db697334cccba77e09f393507e Mon Sep 17 00:00:00 2001 From: Sebastian Date: Wed, 27 Dec 2023 15:59:46 -0300 Subject: use seed from exchange --- packages/aml-backoffice-ui/src/context/config.ts | 3 ++- packages/aml-backoffice-ui/src/hooks/useOfficer.ts | 25 ++++++++++++++-------- .../taler-util/src/http-client/officer-account.ts | 10 ++++++++- packages/taler-util/src/taler-crypto.ts | 7 +++--- 4 files changed, 30 insertions(+), 15 deletions(-) (limited to 'packages') diff --git a/packages/aml-backoffice-ui/src/context/config.ts b/packages/aml-backoffice-ui/src/context/config.ts index 2df7ff40d..ba16482be 100644 --- a/packages/aml-backoffice-ui/src/context/config.ts +++ b/packages/aml-backoffice-ui/src/context/config.ts @@ -29,11 +29,12 @@ export type Type = { url: URL, config: TalerExchangeApi.ExchangeVersionResponse, api: TalerExchangeHttpClient, -}; +} | undefined; const Context = createContext(undefined as any); export const useExchangeApiContext = (): Type => useContext(Context); +export const useMaybeExchangeApiContext = (): Type | undefined => useContext(Context); export function ExchangeApiContextTesting({ config, children }: { config: TalerExchangeApi.ExchangeVersionResponse, children?: ComponentChildren; }): VNode { return h(Context.Provider, { diff --git a/packages/aml-backoffice-ui/src/hooks/useOfficer.ts b/packages/aml-backoffice-ui/src/hooks/useOfficer.ts index 64cf79cc9..fe989f3eb 100644 --- a/packages/aml-backoffice-ui/src/hooks/useOfficer.ts +++ b/packages/aml-backoffice-ui/src/hooks/useOfficer.ts @@ -20,6 +20,7 @@ import { useMemoryStorage, } from "@gnu-taler/web-util/browser"; import { useMemo } from "preact/hooks"; +import { useExchangeApiContext, useMaybeExchangeApiContext } from "../context/config.js"; export interface Officer { account: LockedAccount; @@ -35,9 +36,9 @@ type OfficerAccountString = { export const codecForOfficerAccount = (): Codec => buildCodecForObject() - .property("id", codecForString()) // FIXME - .property("strKey", codecForString()) // FIXME - .build("OfficerAccount"); + .property("id", codecForString()) // FIXME + .property("strKey", codecForString()) // FIXME + .build("OfficerAccount"); export const codecForOfficer = (): Codec => buildCodecForObject() @@ -68,6 +69,7 @@ const DEV_ACCOUNT_KEY = buildStorageKey("account-dev", codecForOfficerAccount()) const ACCOUNT_KEY = "account"; export function useOfficer(): OfficerState { + const exchangeContext = useMaybeExchangeApiContext(); // dev account, is save when reloaded. const accountStorage = useLocalStorage(DEV_ACCOUNT_KEY); const account = useMemo(() => { @@ -78,19 +80,24 @@ export function useOfficer(): OfficerState { } }, [accountStorage.value]) - + // const accountStorage = useMemoryStorage(ACCOUNT_KEY); // const account = accountStorage.value; - const officerStorage = useLocalStorage(OFFICER_KEY); + const officerStorage = useLocalStorage(OFFICER_KEY); const officer = officerStorage.value; - if (officer === undefined) { return { state: "not-found", create: async (pwd: string) => { - const { id, safe, signingKey } = await createNewOfficerAccount(pwd); + if (!exchangeContext) return; + const req = await fetch(new URL("seed", exchangeContext.api.baseUrl).href) + const b = await req.blob() + const ar = await b.arrayBuffer() + const uintar = new Uint8Array(ar) + + const { id, safe, signingKey } = await createNewOfficerAccount(pwd, uintar); officerStorage.update({ account: safe, when: AbsoluteTime.now(), @@ -98,7 +105,7 @@ export function useOfficer(): OfficerState { // accountStorage.update({ id, signingKey }); const strKey = encodeCrock(signingKey) - accountStorage.update({id, strKey }) + accountStorage.update({ id, strKey }) }, }; } @@ -112,7 +119,7 @@ export function useOfficer(): OfficerState { tryUnlock: async (pwd: string) => { const ac = await unlockOfficerAccount(officer.account, pwd); // accountStorage.update(ac); - accountStorage.update({id: ac.id, strKey: encodeCrock(ac.signingKey)}) + accountStorage.update({ id: ac.id, strKey: encodeCrock(ac.signingKey) }) }, }; } diff --git a/packages/taler-util/src/http-client/officer-account.ts b/packages/taler-util/src/http-client/officer-account.ts index 4b2529e20..76477f398 100644 --- a/packages/taler-util/src/http-client/officer-account.ts +++ b/packages/taler-util/src/http-client/officer-account.ts @@ -1,4 +1,5 @@ import { + EncryptionNonce, LockedAccount, OfficerAccount, OfficerId, @@ -10,6 +11,7 @@ import { encodeCrock, encryptWithDerivedKey, getRandomBytesF, + kdf, stringToBytes } from "@gnu-taler/taler-util"; @@ -53,13 +55,19 @@ export async function unlockOfficerAccount( */ export async function createNewOfficerAccount( password: string, + extraNonce: EncryptionNonce, ): Promise { const { eddsaPriv, eddsaPub } = createEddsaKeyPair(); const key = stringToBytes(password); + const localRnd = getRandomBytesF(24) + const mergedRnd: EncryptionNonce = extraNonce ? + kdf(24, extraNonce, localRnd) : + localRnd; + const protectedPrivKey = await encryptWithDerivedKey( - getRandomBytesF(24), + mergedRnd, key, eddsaPriv, password, diff --git a/packages/taler-util/src/taler-crypto.ts b/packages/taler-util/src/taler-crypto.ts index 8f8b2ceac..a20bcfecf 100644 --- a/packages/taler-util/src/taler-crypto.ts +++ b/packages/taler-util/src/taler-crypto.ts @@ -844,8 +844,7 @@ export function hashDenomPub(pub: DenominationPubKey): Uint8Array { return hash(uint8ArrayBuf); } else { throw Error( - `unsupported cipher (${ - (pub as DenominationPubKey).cipher + `unsupported cipher (${(pub as DenominationPubKey).cipher }), unable to hash`, ); } @@ -1024,7 +1023,7 @@ export enum WalletAccountMergeFlags { export class SignaturePurposeBuilder { private chunks: Uint8Array[] = []; - constructor(private purposeNum: number) {} + constructor(private purposeNum: number) { } put(bytes: Uint8Array): SignaturePurposeBuilder { this.chunks.push(Uint8Array.from(bytes)); @@ -1435,7 +1434,7 @@ export namespace AgeRestriction { } // FIXME: make it a branded type! -type EncryptionNonce = FlavorP; +export type EncryptionNonce = FlavorP; async function deriveKey( keySeed: OpaqueData, -- cgit v1.2.3