diff options
author | Florian Dold <florian@dold.me> | 2021-04-14 14:36:46 +0200 |
---|---|---|
committer | Florian Dold <florian@dold.me> | 2021-04-14 14:36:46 +0200 |
commit | 14f13250a01ad15d9fb1ba956fc5409c7f76a2fa (patch) | |
tree | 6a8a17f197661663d0ea051f283ee15ef6c8bdf5 /packages/taler-wallet-core | |
parent | 2645fe3f9bef67b8319bab56ca11e55aa586aedf (diff) | |
download | wallet-core-14f13250a01ad15d9fb1ba956fc5409c7f76a2fa.tar.xz |
forgettable information validation WIP
Diffstat (limited to 'packages/taler-wallet-core')
-rw-r--r-- | packages/taler-wallet-core/src/operations/pay.ts | 38 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/util/contractTerms.ts | 9 |
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. |