gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-core] branch master updated: check contract terms signatur


From: gnunet
Subject: [taler-wallet-core] branch master updated: check contract terms signature, handle errors
Date: Tue, 03 Nov 2020 17:40:21 +0100

This is an automated email from the git hooks/post-receive script.

dold pushed a commit to branch master
in repository wallet-core.

The following commit(s) were added to refs/heads/master by this push:
     new dffb293f check contract terms signature, handle errors
dffb293f is described below

commit dffb293f2a3fa836ee007f19e36f873ed5d295e7
Author: Florian Dold <florian@dold.me>
AuthorDate: Tue Nov 3 17:39:30 2020 +0100

    check contract terms signature, handle errors
---
 packages/taler-wallet-core/src/TalerErrorCode.ts   |  7 ++++
 .../src/crypto/workers/cryptoApi.ts                | 14 ++++++++
 .../src/crypto/workers/cryptoImplementation.ts     | 13 ++++++++
 packages/taler-wallet-core/src/operations/pay.ts   | 38 +++++++++++++++++++++-
 packages/taler-wallet-core/src/types/dbTypes.ts    |  4 +++
 5 files changed, 75 insertions(+), 1 deletion(-)

diff --git a/packages/taler-wallet-core/src/TalerErrorCode.ts 
b/packages/taler-wallet-core/src/TalerErrorCode.ts
index bb97574b..239dc2bd 100644
--- a/packages/taler-wallet-core/src/TalerErrorCode.ts
+++ b/packages/taler-wallet-core/src/TalerErrorCode.ts
@@ -3307,6 +3307,13 @@ export enum TalerErrorCode {
    */
   WALLET_CONTRACT_TERMS_BASE_URL_MISMATCH = 7018,
 
+  /**
+   * The merchant's signature on the contract terms is invalid.
+   * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
+   * (A value of 0 indicates that the error is generated client-side).
+   */
+  WALLET_CONTRACT_TERMS_SIGNATURE_INVALID = 7019,
+
   /**
    * my comment
    * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR 
(500).
diff --git a/packages/taler-wallet-core/src/crypto/workers/cryptoApi.ts 
b/packages/taler-wallet-core/src/crypto/workers/cryptoApi.ts
index 44de6b67..286de5a1 100644
--- a/packages/taler-wallet-core/src/crypto/workers/cryptoApi.ts
+++ b/packages/taler-wallet-core/src/crypto/workers/cryptoApi.ts
@@ -398,6 +398,20 @@ export class CryptoApi {
     );
   }
 
+  isValidContractTermsSignature(
+    contractTermsHash: string,
+    sig: string,
+    merchantPub: string,
+  ): Promise<boolean> {
+    return this.doRpc<boolean>(
+      "isValidContractTermsSignature",
+      4,
+      contractTermsHash,
+      sig,
+      merchantPub,
+    );
+  }
+
   createRecoupRequest(coin: CoinRecord): Promise<RecoupRequest> {
     return this.doRpc<RecoupRequest>("createRecoupRequest", 1, coin);
   }
diff --git 
a/packages/taler-wallet-core/src/crypto/workers/cryptoImplementation.ts 
b/packages/taler-wallet-core/src/crypto/workers/cryptoImplementation.ts
index c39ebb44..46ac7c8a 100644
--- a/packages/taler-wallet-core/src/crypto/workers/cryptoImplementation.ts
+++ b/packages/taler-wallet-core/src/crypto/workers/cryptoImplementation.ts
@@ -80,6 +80,7 @@ enum SignaturePurpose {
   WALLET_COIN_MELT = 1202,
   TEST = 4242,
   MERCHANT_PAYMENT_OK = 1104,
+  MERCHANT_CONTRACT = 1101,
   WALLET_COIN_RECOUP = 1203,
   WALLET_COIN_LINK = 1204,
   EXCHANGE_CONFIRM_RECOUP = 1039,
@@ -297,6 +298,18 @@ export class CryptoImplementation {
     return eddsaVerify(p, decodeCrock(sig), decodeCrock(masterPub));
   }
 
+  isValidContractTermsSignature(
+    contractTermsHash: string,
+    sig: string,
+    merchantPub: string,
+  ): boolean {
+    const cthDec = decodeCrock(contractTermsHash);
+    const p = buildSigPS(SignaturePurpose.MERCHANT_CONTRACT)
+      .put(cthDec)
+      .build();
+    return eddsaVerify(p, decodeCrock(sig), decodeCrock(merchantPub));
+  }
+
   /**
    * Create a new EdDSA key pair.
    */
diff --git a/packages/taler-wallet-core/src/operations/pay.ts 
b/packages/taler-wallet-core/src/operations/pay.ts
index 0c45290f..6079ea08 100644
--- a/packages/taler-wallet-core/src/operations/pay.ts
+++ b/packages/taler-wallet-core/src/operations/pay.ts
@@ -58,6 +58,7 @@ import { Logger } from "../util/logging";
 import { parsePayUri } from "../util/taleruri";
 import {
   guardOperationException,
+  makeErrorDetails,
   OperationFailedAndReportedError,
   OperationFailedError,
 } from "./errors";
@@ -582,6 +583,19 @@ async function resetDownloadProposalRetry(
   });
 }
 
+async function failProposalPermanently(
+  ws: InternalWalletState,
+  proposalId: string,
+  err: TalerErrorDetails,
+): Promise<void> {
+  await ws.db.mutate(Stores.proposals, proposalId, (x) => {
+    x.retryInfo.active = false;
+    x.lastError = err;
+    x.proposalStatus = ProposalStatus.PERMANENTLY_FAILED;
+    return x;
+  });
+}
+
 function getProposalRequestTimeout(proposal: ProposalRecord): Duration {
   return durationMax(
     { d_ms: 60000 },
@@ -663,13 +677,33 @@ async function processDownloadProposalImpl(
   const parsedContractTerms = codecForContractTerms().decode(
     proposalResp.contract_terms,
   );
+
+  const sigValid = await ws.cryptoApi.isValidContractTermsSignature(
+    contractTermsHash,
+    proposalResp.sig,
+    parsedContractTerms.merchant_pub,
+  );
+
+  if (!sigValid) {
+    const err = makeErrorDetails(
+      TalerErrorCode.WALLET_CONTRACT_TERMS_SIGNATURE_INVALID,
+      "merchant's signature on contract terms is invalid",
+      {
+        merchantPub: parsedContractTerms.merchant_pub,
+        orderId: parsedContractTerms.order_id,
+      },
+    );
+    await failProposalPermanently(ws, proposalId, err);
+    throw new OperationFailedAndReportedError(err);
+  }
+
   const fulfillmentUrl = parsedContractTerms.fulfillment_url;
 
   const baseUrlForDownload = proposal.merchantBaseUrl;
   const baseUrlFromContractTerms = parsedContractTerms.merchant_base_url;
 
   if (baseUrlForDownload !== baseUrlFromContractTerms) {
-    throw OperationFailedAndReportedError.fromCode(
+    const err = makeErrorDetails(
       TalerErrorCode.WALLET_CONTRACT_TERMS_BASE_URL_MISMATCH,
       "merchant base URL mismatch",
       {
@@ -677,6 +711,8 @@ async function processDownloadProposalImpl(
         baseUrlFromContractTerms,
       },
     );
+    await failProposalPermanently(ws, proposalId, err);
+    throw new OperationFailedAndReportedError(err);
   }
 
   await ws.db.runWithWriteTransaction(
diff --git a/packages/taler-wallet-core/src/types/dbTypes.ts 
b/packages/taler-wallet-core/src/types/dbTypes.ts
index 4cd98cac..8f6c22f2 100644
--- a/packages/taler-wallet-core/src/types/dbTypes.ts
+++ b/packages/taler-wallet-core/src/types/dbTypes.ts
@@ -813,6 +813,10 @@ export enum ProposalStatus {
    * The user has rejected the proposal.
    */
   REFUSED = "refused",
+  /**
+   * Downloading or processing the proposal has failed permanently.
+   */
+  PERMANENTLY_FAILED = "permanently-failed",
   /**
    * Downloaded proposal was detected as a re-purchase.
    */

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]