summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-core
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2021-04-14 14:36:46 +0200
committerFlorian Dold <florian@dold.me>2021-04-14 14:36:46 +0200
commit14f13250a01ad15d9fb1ba956fc5409c7f76a2fa (patch)
tree6a8a17f197661663d0ea051f283ee15ef6c8bdf5 /packages/taler-wallet-core
parent2645fe3f9bef67b8319bab56ca11e55aa586aedf (diff)
downloadwallet-core-14f13250a01ad15d9fb1ba956fc5409c7f76a2fa.tar.gz
wallet-core-14f13250a01ad15d9fb1ba956fc5409c7f76a2fa.tar.bz2
wallet-core-14f13250a01ad15d9fb1ba956fc5409c7f76a2fa.zip
forgettable information validation WIP
Diffstat (limited to 'packages/taler-wallet-core')
-rw-r--r--packages/taler-wallet-core/src/operations/pay.ts38
-rw-r--r--packages/taler-wallet-core/src/util/contractTerms.ts9
2 files changed, 44 insertions, 3 deletions
diff --git a/packages/taler-wallet-core/src/operations/pay.ts b/packages/taler-wallet-core/src/operations/pay.ts
index 1e93f413b..12cefdc8b 100644
--- a/packages/taler-wallet-core/src/operations/pay.ts
+++ b/packages/taler-wallet-core/src/operations/pay.ts
@@ -93,6 +93,7 @@ import {
} from "../util/retries.js";
import { getTotalRefreshCost, createRefreshGroup } from "./refresh.js";
import { InternalWalletState, EXCHANGE_COINS_LOCK } from "./state.js";
+import { ContractTermsUtil } from "../util/contractTerms.js";
/**
* Logger.
@@ -655,14 +656,45 @@ async function processDownloadProposalImpl(
// as the coded to parse them doesn't necessarily round-trip.
// We need this raw JSON to compute the contract terms hash.
- const contractTermsHash = await ws.cryptoApi.hashString(
- canonicalJson(proposalResp.contract_terms),
+ // FIXME: Do better error handling, check if the
+ // contract terms have all their forgettable information still
+ // present. The wallet should never accept contract terms
+ // with missing information from the merchant.
+
+ const isWellFormed = ContractTermsUtil.validateForgettable(
+ proposalResp.contract_terms,
);
- const parsedContractTerms = codecForContractTerms().decode(
+ if (!isWellFormed) {
+ const err = makeErrorDetails(
+ TalerErrorCode.WALLET_CONTRACT_TERMS_MALFORMED,
+ "validation for well-formedness failed",
+ {},
+ );
+ await failProposalPermanently(ws, proposalId, err);
+ throw new OperationFailedAndReportedError(err);
+ }
+
+ const contractTermsHash = ContractTermsUtil.hashContractTerms(
proposalResp.contract_terms,
);
+ let parsedContractTerms: ContractTerms;
+
+ try {
+ parsedContractTerms = codecForContractTerms().decode(
+ proposalResp.contract_terms,
+ );
+ } catch (e) {
+ const err = makeErrorDetails(
+ TalerErrorCode.WALLET_CONTRACT_TERMS_MALFORMED,
+ "schema validation failed",
+ {},
+ );
+ await failProposalPermanently(ws, proposalId, err);
+ throw new OperationFailedAndReportedError(err);
+ }
+
const sigValid = await ws.cryptoApi.isValidContractTermsSignature(
contractTermsHash,
proposalResp.sig,
diff --git a/packages/taler-wallet-core/src/util/contractTerms.ts b/packages/taler-wallet-core/src/util/contractTerms.ts
index 78fc8f19b..cf61cc05f 100644
--- a/packages/taler-wallet-core/src/util/contractTerms.ts
+++ b/packages/taler-wallet-core/src/util/contractTerms.ts
@@ -216,6 +216,15 @@ export namespace ContractTermsUtil {
}
/**
+ * Check that no forgettable information has been forgotten.
+ *
+ * Must only be called on an object already validated with validateForgettable.
+ */
+ export function validateNothingForgotten(contractTerms: any): boolean {
+ throw Error("not implemented yet");
+ }
+
+ /**
* Hash a contract terms object. Forgettable fields
* are scrubbed and JSON canonicalization is applied
* before hashing.