diff options
Diffstat (limited to 'packages/aml-backoffice-ui/src/account.ts')
-rw-r--r-- | packages/aml-backoffice-ui/src/account.ts | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/packages/aml-backoffice-ui/src/account.ts b/packages/aml-backoffice-ui/src/account.ts new file mode 100644 index 000000000..bd3c2003e --- /dev/null +++ b/packages/aml-backoffice-ui/src/account.ts @@ -0,0 +1,92 @@ +import { + bytesToString, + createEddsaKeyPair, + decodeCrock, + decryptWithDerivedKey, + eddsaGetPublic, + encodeCrock, + encryptWithDerivedKey, + getRandomBytesF, + stringToBytes, +} from "@gnu-taler/taler-util"; + +export interface Account { + accountId: AccountId; + signingKey: SigningKey; +} + +/** + * 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 unlockAccount( + account: LockedAccount, + password: string, +): Promise<Account> { + const rawKey = decodeCrock(account); + const rawPassword = stringToBytes(password); + + const signingKey = (await decryptWithDerivedKey( + rawKey, + rawPassword, + password, + ).catch((e: Error) => { + throw new UnwrapKeyError(e.message); + })) as SigningKey; + + const publicKey = eddsaGetPublic(signingKey); + + const accountId = encodeCrock(publicKey) as AccountId; + + return { accountId, signingKey }; +} + +declare const opaque_Account: unique symbol; +export type LockedAccount = string & { [opaque_Account]: true }; + +declare const opaque_AccountId: unique symbol; +export type AccountId = string & { [opaque_AccountId]: true }; + +declare const opaque_SigningKey: unique symbol; +export type SigningKey = Uint8Array & { [opaque_SigningKey]: true }; + +/** + * Create new account (secured private key) + * secured with the given password + * + * @param sessionId + * @param password + * @returns + */ +export async function createNewAccount( + password: string, +): Promise<Account & { safe: LockedAccount }> { + const { eddsaPriv, eddsaPub } = createEddsaKeyPair(); + + const key = stringToBytes(password); + + const protectedPrivKey = await encryptWithDerivedKey( + getRandomBytesF(24), + key, + eddsaPriv, + password, + ); + + const signingKey = eddsaPriv as SigningKey; + const accountId = encodeCrock(eddsaPub) as AccountId; + const safe = encodeCrock(protectedPrivKey) as LockedAccount; + + return { accountId, signingKey, safe }; +} + +export class UnwrapKeyError extends Error { + public cause: string; + constructor(cause: string) { + super(`Recovering private key failed on: ${cause}`); + this.cause = cause; + } +} |