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:
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,