/* This file is part of GNU Taler (C) 2022-2024 Taler Systems S.A. GNU Taler is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Taler; see the file COPYING. If not, see */ import { EncryptionNonce, LockedAccount, OfficerAccount, OfficerId, SigningKey, createEddsaKeyPair, decodeCrock, decryptWithDerivedKey, eddsaGetPublic, encodeCrock, encryptWithDerivedKey, getRandomBytesF, kdf, stringToBytes, } from "@gnu-taler/taler-util"; /** * Restore previous session and unlock account with password * * @param salt string from which crypto params will be derived * @param key secured private key * @param password password for the private key * @returns */ export async function unlockOfficerAccount( account: LockedAccount, password: string, ): Promise { const rawKey = decodeCrock(account); const rawPassword = stringToBytes(password); const signingKey = (await decryptWithDerivedKey( rawKey, rawPassword, password, ).catch((e) => { throw new UnwrapKeyError(e instanceof Error ? e.message : String(e)); })) as SigningKey; const publicKey = eddsaGetPublic(signingKey); const accountId = encodeCrock(publicKey) as OfficerId; return { id: accountId, signingKey }; } /** * Create new account (secured private key) * secured with the given password * * @param sessionId * @param password * @returns */ 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, stringToBytes("aml-officer"), extraNonce, localRnd) : localRnd; const protectedPrivKey = await encryptWithDerivedKey( mergedRnd, key, eddsaPriv, password, ); const signingKey = eddsaPriv as SigningKey; const accountId = encodeCrock(eddsaPub) as OfficerId; const safe = encodeCrock(protectedPrivKey) as LockedAccount; return { id: accountId, signingKey, safe }; } export class UnwrapKeyError extends Error { public cause: string; constructor(cause: string) { super(`Recovering private key failed on: ${cause}`); this.cause = cause; } }