taler-typescript-core

Wallet core logic and WebUIs for various components
Log | Files | Refs | Submodules | README | LICENSE

commit 496fb2697ed65a699f759ef12281b51f66c43e51
parent 6d9021a18dc673d63206f6531da31e147e571550
Author: Florian Dold <dold@taler.net>
Date:   Thu, 20 Aug 2026 19:06:44 +0200

wallet-core: bind mailbox metadata to its address

Diffstat:
Apackages/taler-wallet-core/src/mailbox.test.ts | 47+++++++++++++++++++++++++++++++++++++++++++++++
Mpackages/taler-wallet-core/src/mailbox.ts | 16++++++++++++++++
2 files changed, 63 insertions(+), 0 deletions(-)

diff --git a/packages/taler-wallet-core/src/mailbox.test.ts b/packages/taler-wallet-core/src/mailbox.test.ts @@ -0,0 +1,47 @@ +/* + This file is part of GNU Taler + (C) 2026 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 <http://www.gnu.org/licenses/> + */ + +import { + createEddsaKeyPair, + encodeCrock, + MailboxMetadata, + sha512, + TalerProtocolTimestamp, +} from "@gnu-taler/taler-util"; +import assert from "node:assert"; +import { test } from "node:test"; +import { mailboxMetadataMatchesAddress } from "./mailbox.js"; + +test("mailbox metadata is bound to the requested address", () => { + const keys = createEddsaKeyPair(); + const metadata: MailboxMetadata = { + signing_key: encodeCrock(keys.eddsaPub) as any, + signing_key_type: "EdDSA", + encryption_key: encodeCrock(new Uint8Array(32)), + encryption_key_type: "X25519", + expiration: TalerProtocolTimestamp.never(), + }; + const address = encodeCrock(sha512(keys.eddsaPub)); + + assert.strictEqual(mailboxMetadataMatchesAddress(address, metadata), true); + assert.strictEqual( + mailboxMetadataMatchesAddress( + encodeCrock(sha512(new Uint8Array(32))), + metadata, + ), + false, + ); +}); diff --git a/packages/taler-wallet-core/src/mailbox.ts b/packages/taler-wallet-core/src/mailbox.ts @@ -63,6 +63,15 @@ import { WalletExecutionContext } from "./wallet.js"; const logger = new Logger("mailbox.ts"); +export function mailboxMetadataMatchesAddress( + mailboxAddress: string, + metadata: MailboxMetadata, +): boolean { + return ( + encodeCrock(sha512(decodeCrock(metadata.signing_key))) === mailboxAddress + ); +} + /** * Add message to the database. */ @@ -449,6 +458,13 @@ export async function sendTalerUriMessage( "could not read the keys of the recipient's mailbox", ); } + if (!mailboxMetadataMatchesAddress(req.contact.mailboxAddress, keys)) { + throw TalerError.fromDetail( + TalerErrorCode.WALLET_MAILBOX_UNAVAILABLE, + { mailboxBaseUrl: req.contact.mailboxBaseUri }, + "the mailbox service returned keys for a different mailbox address", + ); + } const encryptedMessage = encryptTalerUriMessage( decodeCrock(keys.encryption_key), req.talerUri,