From 5c93f15157b4fc9d0fefb6bb2a9956592ebb1ec9 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Mon, 21 Feb 2022 12:40:51 +0100 Subject: towards implementing breaking exchange protocol changes --- .../taler-wallet-core/src/crypto/cryptoTypes.ts | 29 +-- .../src/crypto/workers/cryptoApi.ts | 3 +- .../src/crypto/workers/cryptoImplementation.ts | 237 ++++++++++----------- packages/taler-wallet-core/src/db.ts | 47 ++-- .../src/operations/backup/import.ts | 3 +- .../src/operations/backup/index.ts | 62 +++--- .../taler-wallet-core/src/operations/deposits.ts | 66 ++---- .../taler-wallet-core/src/operations/exchanges.ts | 10 +- packages/taler-wallet-core/src/operations/pay.ts | 10 +- .../taler-wallet-core/src/operations/refresh.ts | 43 +--- packages/taler-wallet-core/src/operations/tip.ts | 44 +--- .../src/operations/withdraw.test.ts | 14 +- .../taler-wallet-core/src/operations/withdraw.ts | 29 +-- .../src/util/coinSelection.test.ts | 14 +- 14 files changed, 224 insertions(+), 387 deletions(-) (limited to 'packages/taler-wallet-core/src') diff --git a/packages/taler-wallet-core/src/crypto/cryptoTypes.ts b/packages/taler-wallet-core/src/crypto/cryptoTypes.ts index 93a7cd1c4..94abb8f7c 100644 --- a/packages/taler-wallet-core/src/crypto/cryptoTypes.ts +++ b/packages/taler-wallet-core/src/crypto/cryptoTypes.ts @@ -30,8 +30,10 @@ import { AmountJson, AmountString, + CoinEnvelope, DenominationPubKey, ExchangeProtocolVersion, + RefreshPlanchetInfo, UnblindedSignature, } from "@gnu-taler/taler-util"; @@ -74,32 +76,7 @@ export interface DerivedRefreshSession { /** * Planchets for each cut-and-choose instance. */ - planchetsForGammas: { - /** - * Public key for the coin. - */ - publicKey: string; - - /** - * Private key for the coin. - */ - privateKey: string; - - /** - * Blinded public key. - */ - coinEv: string; - - /** - * Hash of the blinded public key. - */ - coinEvHash: string; - - /** - * Blinding key used. - */ - blindingKey: string; - }[][]; + planchetsForGammas: RefreshPlanchetInfo[][]; /** * The transfer keys, kappa of them. diff --git a/packages/taler-wallet-core/src/crypto/workers/cryptoApi.ts b/packages/taler-wallet-core/src/crypto/workers/cryptoApi.ts index 29c2553a5..16446bb9e 100644 --- a/packages/taler-wallet-core/src/crypto/workers/cryptoApi.ts +++ b/packages/taler-wallet-core/src/crypto/workers/cryptoApi.ts @@ -28,6 +28,7 @@ import { CryptoWorker } from "./cryptoWorkerInterface.js"; import { CoinDepositPermission, + CoinEnvelope, RecoupRefreshRequest, RecoupRequest, } from "@gnu-taler/taler-util"; @@ -452,7 +453,7 @@ export class CryptoApi { newDenomHash: string, oldCoinPub: string, transferPub: string, - coinEv: string, + coinEv: CoinEnvelope, ): Promise { return this.doRpc( "signCoinLink", diff --git a/packages/taler-wallet-core/src/crypto/workers/cryptoImplementation.ts b/packages/taler-wallet-core/src/crypto/workers/cryptoImplementation.ts index bff2e0eb5..9f6d82348 100644 --- a/packages/taler-wallet-core/src/crypto/workers/cryptoImplementation.ts +++ b/packages/taler-wallet-core/src/crypto/workers/cryptoImplementation.ts @@ -26,19 +26,49 @@ // FIXME: Crypto should not use DB Types! import { - AmountJson, Amounts, BenchmarkResult, buildSigPS, - CoinDepositPermission, createEddsaKeyPair, createHashContext, decodeCrock, - DenomKeyType, DepositInfo, eddsaGetPublic, eddsaSign, eddsaVerify, - encodeCrock, ExchangeProtocolVersion, - FreshCoin, hash, hashDenomPub, kdf, keyExchangeEcdheEddsa, - // Logger, - MakeSyncSignatureRequest, PlanchetCreationRequest, PlanchetCreationResult, - randomBytes, RecoupRefreshRequest, + AmountJson, + Amounts, + BenchmarkResult, + buildSigPS, + CoinDepositPermission, + CoinEnvelope, + createEddsaKeyPair, + createHashContext, + decodeCrock, + DenomKeyType, + DepositInfo, + eddsaGetPublic, + eddsaSign, + eddsaVerify, + encodeCrock, + ExchangeProtocolVersion, + FreshCoin, + hash, + HashCodeString, + hashCoinEv, + hashCoinEvInner, + hashDenomPub, + keyExchangeEcdheEddsa, + Logger, + MakeSyncSignatureRequest, + PlanchetCreationRequest, + PlanchetCreationResult, + randomBytes, + RecoupRefreshRequest, RecoupRequest, - RefreshPlanchetInfo, rsaBlind, rsaUnblind, rsaVerify, setupRefreshPlanchet, + RefreshPlanchetInfo, + rsaBlind, + rsaUnblind, + rsaVerify, + setupRefreshPlanchet, setupRefreshTransferPub, setupTipPlanchet, - setupWithdrawPlanchet, stringToBytes, TalerSignaturePurpose, Timestamp, timestampTruncateToSecond + setupWithdrawPlanchet, + stringToBytes, + TalerSignaturePurpose, + Timestamp, + timestampTruncateToSecond, + typedArrayConcat, } from "@gnu-taler/taler-util"; import bigint from "big-integer"; import { DenominationRecord, WireFee } from "../../db.js"; @@ -50,10 +80,10 @@ import { DerivedTipPlanchet, DeriveRefreshSessionRequest, DeriveTipRequest, - SignTrackTransactionRequest + SignTrackTransactionRequest, } from "../cryptoTypes.js"; -// const logger = new Logger("cryptoImplementation.ts"); +const logger = new Logger("cryptoImplementation.ts"); function amountToBuffer(amount: AmountJson): Uint8Array { const buffer = new ArrayBuffer(8 + 4 + 12); @@ -130,7 +160,7 @@ async function myEddsaSign( export class CryptoImplementation { static enableTracing = false; - constructor(private primitiveWorker?: PrimitiveWorker) { } + constructor(private primitiveWorker?: PrimitiveWorker) {} /** * Create a pre-coin of the given denomination to be withdrawn from then given @@ -139,26 +169,26 @@ export class CryptoImplementation { async createPlanchet( req: PlanchetCreationRequest, ): Promise { - if ( - req.denomPub.cipher === DenomKeyType.Rsa || - req.denomPub.cipher === DenomKeyType.LegacyRsa - ) { + const denomPub = req.denomPub; + if (denomPub.cipher === DenomKeyType.Rsa) { const reservePub = decodeCrock(req.reservePub); - const denomPubRsa = decodeCrock(req.denomPub.rsa_public_key); + const denomPubRsa = decodeCrock(denomPub.rsa_public_key); const derivedPlanchet = setupWithdrawPlanchet( decodeCrock(req.secretSeed), req.coinIndex, ); const coinPubHash = hash(derivedPlanchet.coinPub); const ev = rsaBlind(coinPubHash, derivedPlanchet.bks, denomPubRsa); + const coinEv: CoinEnvelope = { + cipher: DenomKeyType.Rsa, + rsa_blinded_planchet: encodeCrock(ev), + }; const amountWithFee = Amounts.add(req.value, req.feeWithdraw).amount; const denomPubHash = hashDenomPub(req.denomPub); - const evHash = hash(ev); - + const evHash = hashCoinEv(coinEv, encodeCrock(denomPubHash)); const withdrawRequest = buildSigPS( TalerSignaturePurpose.WALLET_RESERVE_WITHDRAW, ) - .put(reservePub) .put(amountToBuffer(amountWithFee)) .put(denomPubHash) .put(evHash) @@ -171,14 +201,11 @@ export class CryptoImplementation { const planchet: PlanchetCreationResult = { blindingKey: encodeCrock(derivedPlanchet.bks), - coinEv: encodeCrock(ev), + coinEv, coinPriv: encodeCrock(derivedPlanchet.coinPriv), coinPub: encodeCrock(derivedPlanchet.coinPub), coinValue: req.value, - denomPub: { - cipher: req.denomPub.cipher, - rsa_public_key: encodeCrock(denomPubRsa), - }, + denomPub, denomPubHash: encodeCrock(denomPubHash), reservePub: encodeCrock(reservePub), withdrawSig: sigResult.sig, @@ -194,11 +221,8 @@ export class CryptoImplementation { * Create a planchet used for tipping, including the private keys. */ createTipPlanchet(req: DeriveTipRequest): DerivedTipPlanchet { - if ( - req.denomPub.cipher !== DenomKeyType.Rsa && - req.denomPub.cipher !== DenomKeyType.LegacyRsa - ) { - throw Error("unsupported cipher"); + if (req.denomPub.cipher !== DenomKeyType.Rsa) { + throw Error(`unsupported cipher (${req.denomPub.cipher})`); } const fc = setupTipPlanchet(decodeCrock(req.secretSeed), req.planchetIndex); const denomPub = decodeCrock(req.denomPub.rsa_public_key); @@ -236,15 +260,7 @@ export class CryptoImplementation { const coinPriv = decodeCrock(req.coinPriv); const coinSig = eddsaSign(p, coinPriv); - if (req.denomPub.cipher === DenomKeyType.LegacyRsa) { - const paybackRequest: RecoupRequest = { - coin_blind_key_secret: req.blindingKey, - coin_sig: encodeCrock(coinSig), - denom_pub_hash: req.denomPubHash, - denom_sig: req.denomSig.rsa_signature, - }; - return paybackRequest; - } else { + if (req.denomPub.cipher === DenomKeyType.Rsa) { const paybackRequest: RecoupRequest = { coin_blind_key_secret: req.blindingKey, coin_sig: encodeCrock(coinSig), @@ -252,6 +268,8 @@ export class CryptoImplementation { denom_sig: req.denomSig, }; return paybackRequest; + } else { + throw new Error(); } } @@ -268,15 +286,7 @@ export class CryptoImplementation { const coinPriv = decodeCrock(req.coinPriv); const coinSig = eddsaSign(p, coinPriv); - if (req.denomPub.cipher === DenomKeyType.LegacyRsa) { - const recoupRequest: RecoupRefreshRequest = { - coin_blind_key_secret: req.blindingKey, - coin_sig: encodeCrock(coinSig), - denom_pub_hash: req.denomPubHash, - denom_sig: req.denomSig.rsa_signature, - }; - return recoupRequest; - } else { + if (req.denomPub.cipher === DenomKeyType.Rsa) { const recoupRequest: RecoupRefreshRequest = { coin_blind_key_secret: req.blindingKey, coin_sig: encodeCrock(coinSig), @@ -284,6 +294,8 @@ export class CryptoImplementation { denom_sig: req.denomSig, }; return recoupRequest; + } else { + throw new Error(); } } @@ -364,26 +376,11 @@ export class CryptoImplementation { sig: string, masterPub: string, ): boolean { - if (versionCurrent === ExchangeProtocolVersion.V12) { - const paytoHash = hash(stringToBytes(paytoUri + "\0")); - const p = buildSigPS(TalerSignaturePurpose.MASTER_WIRE_DETAILS) - .put(paytoHash) - .build(); - return eddsaVerify(p, decodeCrock(sig), decodeCrock(masterPub)); - } else if (versionCurrent === ExchangeProtocolVersion.V9) { - const h = kdf( - 64, - stringToBytes("exchange-wire-signature"), - stringToBytes(paytoUri + "\0"), - new Uint8Array(0), - ); - const p = buildSigPS(TalerSignaturePurpose.MASTER_WIRE_DETAILS) - .put(h) - .build(); - return eddsaVerify(p, decodeCrock(sig), decodeCrock(masterPub)); - } else { - throw Error(`unsupported version (${versionCurrent})`); - } + const paytoHash = hash(stringToBytes(paytoUri + "\0")); + const p = buildSigPS(TalerSignaturePurpose.MASTER_WIRE_DETAILS) + .put(paytoHash) + .build(); + return eddsaVerify(p, decodeCrock(sig), decodeCrock(masterPub)); } isValidContractTermsSignature( @@ -444,10 +441,12 @@ export class CryptoImplementation { ): Promise { // FIXME: put extensions here if used const hExt = new Uint8Array(64); + const hAgeCommitment = new Uint8Array(32); let d: Uint8Array; if (depositInfo.denomKeyType === DenomKeyType.Rsa) { d = buildSigPS(TalerSignaturePurpose.WALLET_COIN_DEPOSIT) .put(decodeCrock(depositInfo.contractTermsHash)) + .put(hAgeCommitment) .put(hExt) .put(decodeCrock(depositInfo.wireInfoHash)) .put(decodeCrock(depositInfo.denomPubHash)) @@ -457,18 +456,6 @@ export class CryptoImplementation { .put(amountToBuffer(depositInfo.feeDeposit)) .put(decodeCrock(depositInfo.merchantPub)) .build(); - } else if (depositInfo.denomKeyType === DenomKeyType.LegacyRsa) { - d = buildSigPS(TalerSignaturePurpose.WALLET_COIN_DEPOSIT) - .put(decodeCrock(depositInfo.contractTermsHash)) - .put(decodeCrock(depositInfo.wireInfoHash)) - .put(decodeCrock(depositInfo.denomPubHash)) - .put(timestampRoundedToBuffer(depositInfo.timestamp)) - .put(timestampRoundedToBuffer(depositInfo.refundDeadline)) - .put(amountToBuffer(depositInfo.spendAmount)) - .put(amountToBuffer(depositInfo.feeDeposit)) - .put(decodeCrock(depositInfo.merchantPub)) - .put(decodeCrock(depositInfo.coinPub)) - .build(); } else { throw Error("unsupported exchange protocol version"); } @@ -490,18 +477,10 @@ export class CryptoImplementation { }, }; return s; - } else if (depositInfo.denomKeyType === DenomKeyType.LegacyRsa) { - const s: CoinDepositPermission = { - coin_pub: depositInfo.coinPub, - coin_sig: coinSigRes.sig, - contribution: Amounts.stringify(depositInfo.spendAmount), - h_denom: depositInfo.denomPubHash, - exchange_url: depositInfo.exchangeBaseUrl, - ub_sig: depositInfo.denomSig.rsa_signature, - }; - return s; } else { - throw Error("unsupported merchant protocol version"); + throw Error( + `unsupported denomination cipher (${depositInfo.denomKeyType})`, + ); } } @@ -551,17 +530,18 @@ export class CryptoImplementation { for (const denomSel of newCoinDenoms) { for (let i = 0; i < denomSel.count; i++) { - if (denomSel.denomPub.cipher === DenomKeyType.LegacyRsa) { - const r = decodeCrock(denomSel.denomPub.rsa_public_key); - sessionHc.update(r); + if (denomSel.denomPub.cipher === DenomKeyType.Rsa) { + const denomPubHash = hashDenomPub(denomSel.denomPub); + sessionHc.update(denomPubHash); } else { - sessionHc.update(hashDenomPub(denomSel.denomPub)); + throw new Error(); } } } sessionHc.update(decodeCrock(meltCoinPub)); sessionHc.update(amountToBuffer(valueWithFee)); + for (let i = 0; i < kappa; i++) { const planchets: RefreshPlanchetInfo[] = []; for (let j = 0; j < newCoinDenoms.length; j++) { @@ -594,24 +574,29 @@ export class CryptoImplementation { coinPub = fresh.coinPub; blindingFactor = fresh.bks; } - const pubHash = hash(coinPub); - if ( - denomSel.denomPub.cipher !== DenomKeyType.Rsa && - denomSel.denomPub.cipher !== DenomKeyType.LegacyRsa - ) { + const coinPubHash = hash(coinPub); + if (denomSel.denomPub.cipher !== DenomKeyType.Rsa) { throw Error("unsupported cipher, can't create refresh session"); } - const denomPub = decodeCrock(denomSel.denomPub.rsa_public_key); - const ev = rsaBlind(pubHash, blindingFactor, denomPub); + const rsaDenomPub = decodeCrock(denomSel.denomPub.rsa_public_key); + const ev = rsaBlind(coinPubHash, blindingFactor, rsaDenomPub); + const coinEv: CoinEnvelope = { + cipher: DenomKeyType.Rsa, + rsa_blinded_planchet: encodeCrock(ev), + }; + const coinEvHash = hashCoinEv( + coinEv, + encodeCrock(hashDenomPub(denomSel.denomPub)), + ); const planchet: RefreshPlanchetInfo = { blindingKey: encodeCrock(blindingFactor), - coinEv: encodeCrock(ev), - privateKey: encodeCrock(coinPriv), - publicKey: encodeCrock(coinPub), - coinEvHash: encodeCrock(hash(ev)), + coinEv, + coinPriv: encodeCrock(coinPriv), + coinPub: encodeCrock(coinPub), + coinEvHash: encodeCrock(coinEvHash), }; planchets.push(planchet); - sessionHc.update(ev); + hashCoinEvInner(coinEv, sessionHc); } } planchetsForGammas.push(planchets); @@ -619,26 +604,15 @@ export class CryptoImplementation { const sessionHash = sessionHc.finish(); let confirmData: Uint8Array; - if (req.exchangeProtocolVersion === ExchangeProtocolVersion.V9) { - confirmData = buildSigPS(TalerSignaturePurpose.WALLET_COIN_MELT) - .put(sessionHash) - .put(decodeCrock(meltCoinDenomPubHash)) - .put(amountToBuffer(valueWithFee)) - .put(amountToBuffer(meltFee)) - .put(decodeCrock(meltCoinPub)) - .build(); - } else if (req.exchangeProtocolVersion === ExchangeProtocolVersion.V12) { - confirmData = buildSigPS(TalerSignaturePurpose.WALLET_COIN_MELT) - .put(sessionHash) - .put(decodeCrock(meltCoinDenomPubHash)) - .put(amountToBuffer(valueWithFee)) - .put(amountToBuffer(meltFee)) - .build(); - } else { - throw Error( - `Exchange protocol version (${req.exchangeProtocolVersion}) not supported`, - ); - } + // FIXME: fill in age commitment + const hAgeCommitment = new Uint8Array(32); + confirmData = buildSigPS(TalerSignaturePurpose.WALLET_COIN_MELT) + .put(sessionHash) + .put(decodeCrock(meltCoinDenomPubHash)) + .put(hAgeCommitment) + .put(amountToBuffer(valueWithFee)) + .put(amountToBuffer(meltFee)) + .build(); const confirmSigResp = await myEddsaSign(this.primitiveWorker, { msg: encodeCrock(confirmData), @@ -678,12 +652,15 @@ export class CryptoImplementation { newDenomHash: string, oldCoinPub: string, transferPub: string, - coinEv: string, + coinEv: CoinEnvelope, ): Promise { - const coinEvHash = hash(decodeCrock(coinEv)); + const coinEvHash = hashCoinEv(coinEv, newDenomHash); + // FIXME: fill in + const hAgeCommitment = new Uint8Array(32); const coinLink = buildSigPS(TalerSignaturePurpose.WALLET_COIN_LINK) .put(decodeCrock(newDenomHash)) .put(decodeCrock(transferPub)) + .put(hAgeCommitment) .put(coinEvHash) .build(); const sig = await myEddsaSign(this.primitiveWorker, { diff --git a/packages/taler-wallet-core/src/db.ts b/packages/taler-wallet-core/src/db.ts index 7f7dd10ff..410311530 100644 --- a/packages/taler-wallet-core/src/db.ts +++ b/packages/taler-wallet-core/src/db.ts @@ -38,6 +38,7 @@ import { TalerErrorDetails, Timestamp, UnblindedSignature, + CoinEnvelope, } from "@gnu-taler/taler-util"; import { RetryInfo } from "./util/retries.js"; import { PayCoinSelection } from "./util/coinSelection.js"; @@ -602,7 +603,7 @@ export interface PlanchetRecord { withdrawSig: string; - coinEv: string; + coinEv: CoinEnvelope; coinEvHash: string; @@ -1154,7 +1155,6 @@ export interface WalletContractData { timestamp: Timestamp; wireMethod: string; wireInfoHash: string; - wireInfoLegacyHash?: string; maxDepositFee: AmountJson; } @@ -1294,9 +1294,9 @@ export const WALLET_BACKUP_STATE_KEY = "walletBackupState"; */ export type ConfigRecord = | { - key: typeof WALLET_BACKUP_STATE_KEY; - value: WalletBackupConfState; - } + key: typeof WALLET_BACKUP_STATE_KEY; + value: WalletBackupConfState; + } | { key: "currencyDefaultsApplied"; value: boolean }; export interface WalletBackupConfState { @@ -1392,9 +1392,9 @@ export interface WithdrawalGroupRecord { /** * UID of the denomination selection. - * + * * Used for merging backups. - * + * * FIXME: Should this not also include a timestamp for more logical merging? */ denomSelUid: string; @@ -1480,17 +1480,17 @@ export enum BackupProviderStateTag { export type BackupProviderState = | { - tag: BackupProviderStateTag.Provisional; - } + tag: BackupProviderStateTag.Provisional; + } | { - tag: BackupProviderStateTag.Ready; - nextBackupTimestamp: Timestamp; - } + tag: BackupProviderStateTag.Ready; + nextBackupTimestamp: Timestamp; + } | { - tag: BackupProviderStateTag.Retrying; - retryInfo: RetryInfo; - lastError?: TalerErrorDetails; - }; + tag: BackupProviderStateTag.Retrying; + retryInfo: RetryInfo; + lastError?: TalerErrorDetails; + }; export interface BackupProviderTerms { supportedProtocolVersion: string; @@ -1875,9 +1875,9 @@ export function exportDb(db: IDBDatabase): Promise { } export interface DatabaseDump { - name: string, - stores: { [s: string]: any }, - version: string, + name: string; + stores: { [s: string]: any }; + version: string; } export function importDb(db: IDBDatabase, dump: DatabaseDump): Promise { @@ -1891,12 +1891,11 @@ export function importDb(db: IDBDatabase, dump: DatabaseDump): Promise { const name = db.objectStoreNames[i]; const storeDump = dump.stores[name]; if (!storeDump) continue; - Object.keys(storeDump).forEach(async key => { - const value = storeDump[key] + Object.keys(storeDump).forEach(async (key) => { + const value = storeDump[key]; if (!value) return; - tx.objectStore(name).put(value) - }) - + tx.objectStore(name).put(value); + }); } }); } diff --git a/packages/taler-wallet-core/src/operations/backup/import.ts b/packages/taler-wallet-core/src/operations/backup/import.ts index 9f63441dd..21b10a945 100644 --- a/packages/taler-wallet-core/src/operations/backup/import.ts +++ b/packages/taler-wallet-core/src/operations/backup/import.ts @@ -337,8 +337,7 @@ export async function importBackup( for (const backupDenomination of backupExchangeDetails.denominations) { if ( - backupDenomination.denom_pub.cipher !== DenomKeyType.Rsa && - backupDenomination.denom_pub.cipher !== DenomKeyType.LegacyRsa + backupDenomination.denom_pub.cipher !== DenomKeyType.Rsa ) { throw Error("unsupported cipher"); } diff --git a/packages/taler-wallet-core/src/operations/backup/index.ts b/packages/taler-wallet-core/src/operations/backup/index.ts index e3950ef90..5eb248611 100644 --- a/packages/taler-wallet-core/src/operations/backup/index.ts +++ b/packages/taler-wallet-core/src/operations/backup/index.ts @@ -168,10 +168,7 @@ async function computeBackupCryptoData( }; for (const backupExchangeDetails of backupContent.exchange_details) { for (const backupDenom of backupExchangeDetails.denominations) { - if ( - backupDenom.denom_pub.cipher !== DenomKeyType.Rsa && - backupDenom.denom_pub.cipher !== DenomKeyType.LegacyRsa - ) { + if (backupDenom.denom_pub.cipher !== DenomKeyType.Rsa) { throw Error("unsupported cipher"); } for (const backupCoin of backupDenom.coins) { @@ -192,18 +189,14 @@ async function computeBackupCryptoData( LibtoolVersion.compare(backupExchangeDetails.protocol_version, "9") ?.compatible ) { - cryptoData.rsaDenomPubToHash[ - backupDenom.denom_pub.rsa_public_key - ] = encodeCrock( - hash(decodeCrock(backupDenom.denom_pub.rsa_public_key)), - ); + cryptoData.rsaDenomPubToHash[backupDenom.denom_pub.rsa_public_key] = + encodeCrock(hash(decodeCrock(backupDenom.denom_pub.rsa_public_key))); } else if ( LibtoolVersion.compare(backupExchangeDetails.protocol_version, "10") ?.compatible ) { - cryptoData.rsaDenomPubToHash[ - backupDenom.denom_pub.rsa_public_key - ] = encodeCrock(hashDenomPub(backupDenom.denom_pub)); + cryptoData.rsaDenomPubToHash[backupDenom.denom_pub.rsa_public_key] = + encodeCrock(hashDenomPub(backupDenom.denom_pub)); } else { throw Error("unsupported exchange protocol version"); } @@ -220,9 +213,8 @@ async function computeBackupCryptoData( ); const noncePub = encodeCrock(eddsaGetPublic(decodeCrock(prop.nonce_priv))); cryptoData.proposalNoncePrivToPub[prop.nonce_priv] = noncePub; - cryptoData.proposalIdToContractTermsHash[ - prop.proposal_id - ] = contractTermsHash; + cryptoData.proposalIdToContractTermsHash[prop.proposal_id] = + contractTermsHash; } for (const purch of backupContent.purchases) { const contractTermsHash = await cryptoApi.hashString( @@ -230,9 +222,8 @@ async function computeBackupCryptoData( ); const noncePub = encodeCrock(eddsaGetPublic(decodeCrock(purch.nonce_priv))); cryptoData.proposalNoncePrivToPub[purch.nonce_priv] = noncePub; - cryptoData.proposalIdToContractTermsHash[ - purch.proposal_id - ] = contractTermsHash; + cryptoData.proposalIdToContractTermsHash[purch.proposal_id] = + contractTermsHash; } return cryptoData; } @@ -548,10 +539,11 @@ export interface RemoveBackupProviderRequest { provider: string; } -export const codecForRemoveBackupProvider = (): Codec => - buildCodecForObject() - .property("provider", codecForString()) - .build("RemoveBackupProviderRequest"); +export const codecForRemoveBackupProvider = + (): Codec => + buildCodecForObject() + .property("provider", codecForString()) + .build("RemoveBackupProviderRequest"); export async function removeBackupProvider( ws: InternalWalletState, @@ -619,12 +611,13 @@ interface SyncTermsOfServiceResponse { version: string; } -const codecForSyncTermsOfServiceResponse = (): Codec => - buildCodecForObject() - .property("storage_limit_in_megabytes", codecForNumber()) - .property("annual_fee", codecForAmountString()) - .property("version", codecForString()) - .build("SyncTermsOfServiceResponse"); +const codecForSyncTermsOfServiceResponse = + (): Codec => + buildCodecForObject() + .property("storage_limit_in_megabytes", codecForNumber()) + .property("annual_fee", codecForAmountString()) + .property("version", codecForString()) + .build("SyncTermsOfServiceResponse"); export interface AddBackupProviderRequest { backupProviderBaseUrl: string; @@ -637,12 +630,13 @@ export interface AddBackupProviderRequest { activate?: boolean; } -export const codecForAddBackupProviderRequest = (): Codec => - buildCodecForObject() - .property("backupProviderBaseUrl", codecForString()) - .property("name", codecForString()) - .property("activate", codecOptional(codecForBoolean())) - .build("AddBackupProviderRequest"); +export const codecForAddBackupProviderRequest = + (): Codec => + buildCodecForObject() + .property("backupProviderBaseUrl", codecForString()) + .property("name", codecForString()) + .property("activate", codecOptional(codecForBoolean())) + .build("AddBackupProviderRequest"); export async function addBackupProvider( ws: InternalWalletState, diff --git a/packages/taler-wallet-core/src/operations/deposits.ts b/packages/taler-wallet-core/src/operations/deposits.ts index 8a5b35732..25b9cb92d 100644 --- a/packages/taler-wallet-core/src/operations/deposits.ts +++ b/packages/taler-wallet-core/src/operations/deposits.ts @@ -27,7 +27,11 @@ import { CreateDepositGroupRequest, CreateDepositGroupResponse, DenomKeyType, - durationFromSpec, encodeCrock, GetFeeForDepositRequest, getRandomBytes, getTimestampNow, + durationFromSpec, + encodeCrock, + GetFeeForDepositRequest, + getRandomBytes, + getTimestampNow, Logger, NotificationType, parsePaytoUri, @@ -38,7 +42,7 @@ import { timestampTruncateToSecond, TrackDepositGroupRequest, TrackDepositGroupResponse, - URL + URL, } from "@gnu-taler/taler-util"; import { InternalWalletState } from "../common.js"; import { DepositGroupRecord, OperationStatus } from "../db.js"; @@ -54,7 +58,7 @@ import { getCandidatePayCoins, getTotalPaymentCost, hashWire, - hashWireLegacy + hashWireLegacy, } from "./pay.js"; import { getTotalRefreshCost } from "./refresh.js"; @@ -199,47 +203,21 @@ async function processDepositGroupImpl( } const perm = depositPermissions[i]; let requestBody: any; - if ( - typeof perm.ub_sig === "string" || - perm.ub_sig.cipher === DenomKeyType.LegacyRsa - ) { - // Legacy request - logger.info("creating legacy deposit request"); - const wireHash = hashWireLegacy( - depositGroup.wire.payto_uri, - depositGroup.wire.salt, - ); - requestBody = { - contribution: Amounts.stringify(perm.contribution), - wire: depositGroup.wire, - h_wire: wireHash, - h_contract_terms: depositGroup.contractTermsHash, - ub_sig: perm.ub_sig, - timestamp: depositGroup.contractTermsRaw.timestamp, - wire_transfer_deadline: - depositGroup.contractTermsRaw.wire_transfer_deadline, - refund_deadline: depositGroup.contractTermsRaw.refund_deadline, - coin_sig: perm.coin_sig, - denom_pub_hash: perm.h_denom, - merchant_pub: depositGroup.merchantPub, - }; - } else { - logger.info("creating v10 deposit request"); - requestBody = { - contribution: Amounts.stringify(perm.contribution), - merchant_payto_uri: depositGroup.wire.payto_uri, - wire_salt: depositGroup.wire.salt, - h_contract_terms: depositGroup.contractTermsHash, - ub_sig: perm.ub_sig, - timestamp: depositGroup.contractTermsRaw.timestamp, - wire_transfer_deadline: - depositGroup.contractTermsRaw.wire_transfer_deadline, - refund_deadline: depositGroup.contractTermsRaw.refund_deadline, - coin_sig: perm.coin_sig, - denom_pub_hash: perm.h_denom, - merchant_pub: depositGroup.merchantPub, - }; - } + logger.info("creating v10 deposit request"); + requestBody = { + contribution: Amounts.stringify(perm.contribution), + merchant_payto_uri: depositGroup.wire.payto_uri, + wire_salt: depositGroup.wire.salt, + h_contract_terms: depositGroup.contractTermsHash, + ub_sig: perm.ub_sig, + timestamp: depositGroup.contractTermsRaw.timestamp, + wire_transfer_deadline: + depositGroup.contractTermsRaw.wire_transfer_deadline, + refund_deadline: depositGroup.contractTermsRaw.refund_deadline, + coin_sig: perm.coin_sig, + denom_pub_hash: perm.h_denom, + merchant_pub: depositGroup.merchantPub, + }; const url = new URL(`coins/${perm.coin_pub}/deposit`, perm.exchange_url); logger.info(`depositing to ${url}`); const httpResp = await ws.http.postJson(url.href, requestBody); diff --git a/packages/taler-wallet-core/src/operations/exchanges.ts b/packages/taler-wallet-core/src/operations/exchanges.ts index 87200c2f9..c50afc215 100644 --- a/packages/taler-wallet-core/src/operations/exchanges.ts +++ b/packages/taler-wallet-core/src/operations/exchanges.ts @@ -83,15 +83,7 @@ function denominationRecordFromKeys( denomIn: ExchangeDenomination, ): DenominationRecord { let denomPub: DenominationPubKey; - // We support exchange protocol v9 and v10. - if (typeof denomIn.denom_pub === "string") { - denomPub = { - cipher: DenomKeyType.LegacyRsa, - rsa_public_key: denomIn.denom_pub, - }; - } else { - denomPub = denomIn.denom_pub; - } + denomPub = denomIn.denom_pub; const denomPubHash = encodeCrock(hashDenomPub(denomPub)); const d: DenominationRecord = { denomPub, diff --git a/packages/taler-wallet-core/src/operations/pay.ts b/packages/taler-wallet-core/src/operations/pay.ts index 8f0727c8b..4870d446a 100644 --- a/packages/taler-wallet-core/src/operations/pay.ts +++ b/packages/taler-wallet-core/src/operations/pay.ts @@ -606,7 +606,6 @@ export function extractContractData( timestamp: parsedContractTerms.timestamp, wireMethod: parsedContractTerms.wire_method, wireInfoHash: parsedContractTerms.h_wire, - wireInfoLegacyHash: parsedContractTerms.h_wire_legacy, maxDepositFee: Amounts.parseOrThrow(parsedContractTerms.max_fee), merchant: parsedContractTerms.merchant, products: parsedContractTerms.products, @@ -1515,14 +1514,7 @@ export async function generateDepositPermissions( for (let i = 0; i < payCoinSel.coinPubs.length; i++) { const { coin, denom } = coinWithDenom[i]; let wireInfoHash: string; - if ( - coin.denomPub.cipher === DenomKeyType.LegacyRsa && - contractData.wireInfoLegacyHash - ) { - wireInfoHash = contractData.wireInfoLegacyHash; - } else { - wireInfoHash = contractData.wireInfoHash; - } + wireInfoHash = contractData.wireInfoHash; const dp = await ws.cryptoApi.signDepositPermission({ coinPriv: coin.coinPriv, coinPub: coin.coinPub, diff --git a/packages/taler-wallet-core/src/operations/refresh.ts b/packages/taler-wallet-core/src/operations/refresh.ts index 1e5dd68a8..ba4cb697d 100644 --- a/packages/taler-wallet-core/src/operations/refresh.ts +++ b/packages/taler-wallet-core/src/operations/refresh.ts @@ -18,8 +18,10 @@ import { DenomKeyType, encodeCrock, ExchangeProtocolVersion, + ExchangeRefreshRevealRequest, getRandomBytes, HttpStatusCode, + j2s, } from "@gnu-taler/taler-util"; import { CoinRecord, @@ -369,10 +371,6 @@ async function refreshMelt( let exchangeProtocolVersion: ExchangeProtocolVersion; switch (d.oldDenom.denomPub.cipher) { - case DenomKeyType.LegacyRsa: { - exchangeProtocolVersion = ExchangeProtocolVersion.V9; - break; - } case DenomKeyType.Rsa: { exchangeProtocolVersion = ExchangeProtocolVersion.V12; break; @@ -397,16 +395,7 @@ async function refreshMelt( oldCoin.exchangeBaseUrl, ); let meltReqBody: any; - if (oldCoin.denomPub.cipher === DenomKeyType.LegacyRsa) { - meltReqBody = { - coin_pub: oldCoin.coinPub, - confirm_sig: derived.confirmSig, - denom_pub_hash: oldCoin.denomPubHash, - denom_sig: oldCoin.denomSig.rsa_signature, - rc: derived.hash, - value_with_fee: Amounts.stringify(derived.meltValueWithFee), - }; - } else { + if (oldCoin.denomPub.cipher === DenomKeyType.Rsa) { meltReqBody = { coin_pub: oldCoin.coinPub, confirm_sig: derived.confirmSig, @@ -569,10 +558,6 @@ async function refreshReveal( let exchangeProtocolVersion: ExchangeProtocolVersion; switch (d.oldDenom.denomPub.cipher) { - case DenomKeyType.LegacyRsa: { - exchangeProtocolVersion = ExchangeProtocolVersion.V9; - break; - } case DenomKeyType.Rsa: { exchangeProtocolVersion = ExchangeProtocolVersion.V12; break; @@ -600,7 +585,6 @@ async function refreshReveal( throw Error("refresh index error"); } - const evs = planchets.map((x: RefreshPlanchetInfo) => x.coinEv); const newDenomsFlat: string[] = []; const linkSigs: string[] = []; @@ -620,10 +604,9 @@ async function refreshReveal( } } - const req = { - coin_evs: evs, + const req: ExchangeRefreshRevealRequest = { + coin_evs: planchets.map((x) => x.coinEv), new_denoms_h: newDenomsFlat, - rc: derived.hash, transfer_privs: privs, transfer_pub: derived.transferPubs[norevealIndex], link_sigs: linkSigs, @@ -666,20 +649,14 @@ async function refreshReveal( continue; } const pc = derived.planchetsForGammas[norevealIndex][newCoinIndex]; - if ( - denom.denomPub.cipher !== DenomKeyType.Rsa && - denom.denomPub.cipher !== DenomKeyType.LegacyRsa - ) { + if (denom.denomPub.cipher !== DenomKeyType.Rsa) { throw Error("cipher unsupported"); } const evSig = reveal.ev_sigs[newCoinIndex].ev_sig; let rsaSig: string; if (typeof evSig === "string") { rsaSig = evSig; - } else if ( - evSig.cipher === DenomKeyType.Rsa || - evSig.cipher === DenomKeyType.LegacyRsa - ) { + } else if (evSig.cipher === DenomKeyType.Rsa) { rsaSig = evSig.blinded_rsa_signature; } else { throw Error("unsupported cipher"); @@ -691,8 +668,8 @@ async function refreshReveal( ); const coin: CoinRecord = { blindingKey: pc.blindingKey, - coinPriv: pc.privateKey, - coinPub: pc.publicKey, + coinPriv: pc.coinPriv, + coinPub: pc.coinPub, currentAmount: denom.value, denomPub: denom.denomPub, denomPubHash: denom.denomPubHash, @@ -707,7 +684,7 @@ async function refreshReveal( oldCoinPub: refreshGroup.oldCoinPubs[coinIndex], }, suspended: false, - coinEvHash: pc.coinEv, + coinEvHash: pc.coinEvHash, }; coins.push(coin); diff --git a/packages/taler-wallet-core/src/operations/tip.ts b/packages/taler-wallet-core/src/operations/tip.ts index f985d8aad..039fb64a1 100644 --- a/packages/taler-wallet-core/src/operations/tip.ts +++ b/packages/taler-wallet-core/src/operations/tip.ts @@ -306,37 +306,13 @@ async function processTipImpl( // FIXME: Maybe we want to signal to the caller that the transient error happened? return; } - - // FIXME: Do this earlier? - const merchantInfo = await ws.merchantOps.getMerchantInfo( - ws, - tipRecord.merchantBaseUrl, - ); - let blindedSigs: BlindedDenominationSignature[] = []; - if (merchantInfo.protocolVersionCurrent === MerchantProtocolVersion.V3) { - const response = await readSuccessResponseJsonOrThrow( - merchantResp, - codecForMerchantTipResponseV2(), - ); - blindedSigs = response.blind_sigs.map((x) => x.blind_sig); - } else if ( - merchantInfo.protocolVersionCurrent === MerchantProtocolVersion.V1 - ) { - const response = await readSuccessResponseJsonOrThrow( - merchantResp, - codecForMerchantTipResponseV1(), - ); - blindedSigs = response.blind_sigs.map((x) => ({ - cipher: DenomKeyType.Rsa, - blinded_rsa_signature: x.blind_sig, - })); - } else { - throw Error( - `unsupported merchant protocol version (${merchantInfo.protocolVersionCurrent})`, - ); - } + const response = await readSuccessResponseJsonOrThrow( + merchantResp, + codecForMerchantTipResponseV2(), + ); + blindedSigs = response.blind_sigs.map((x) => x.blind_sig); if (blindedSigs.length !== planchets.length) { throw Error("number of tip responses does not match requested planchets"); @@ -352,17 +328,11 @@ async function processTipImpl( const planchet = planchets[i]; checkLogicInvariant(!!planchet); - if ( - denom.denomPub.cipher !== DenomKeyType.Rsa && - denom.denomPub.cipher !== DenomKeyType.LegacyRsa - ) { + if (denom.denomPub.cipher !== DenomKeyType.Rsa) { throw Error("unsupported cipher"); } - if ( - blindedSig.cipher !== DenomKeyType.Rsa && - blindedSig.cipher !== DenomKeyType.LegacyRsa - ) { + if (blindedSig.cipher !== DenomKeyType.Rsa) { throw Error("unsupported cipher"); } diff --git a/packages/taler-wallet-core/src/operations/withdraw.test.ts b/packages/taler-wallet-core/src/operations/withdraw.test.ts index 2c890a121..02540848a 100644 --- a/packages/taler-wallet-core/src/operations/withdraw.test.ts +++ b/packages/taler-wallet-core/src/operations/withdraw.test.ts @@ -14,7 +14,7 @@ GNU Taler; see the file COPYING. If not, see */ -import { Amounts } from "@gnu-taler/taler-util"; +import { Amounts, DenomKeyType } from "@gnu-taler/taler-util"; import test from "ava"; import { DenominationRecord, DenominationVerificationStatus } from "../db.js"; import { selectWithdrawalDenominations } from "./withdraw.js"; @@ -29,7 +29,7 @@ test("withdrawal selection bug repro", (t) => { const denoms: DenominationRecord[] = [ { denomPub: { - cipher: 1, + cipher: DenomKeyType.Rsa, rsa_public_key: "040000XT67C8KBD6B75TTQ3SK8FWXMNQW4372T3BDDGPAMB9RFCA03638W8T3F71WFEFK9NP32VKYVNFXPYRWQ1N1HDKV5J0DFEKHBPJCYSWCBJDRNWD7G8BN8PT97FA9AMV75MYEK4X54D1HGJ207JSVJBGFCATSPNTEYNHEQF1F220W00TBZR1HNPDQFD56FG0DJQ9KGHM8EC33H6AY9YN9CNX5R3Z4TZ4Q23W47SBHB13H6W74FQJG1F50X38VRSC4SR8RWBAFB7S4K8D2H4NMRFSQT892A3T0BTBW7HM5C0H2CK6FRKG31F7W9WP1S29013K5CXYE55CT8TH6N8J9B780R42Y5S3ZB6J6E9H76XBPSGH4TGYSR2VZRB98J417KCQMZKX1BB67E7W5KVE37TC9SJ904002", }, @@ -83,7 +83,7 @@ test("withdrawal selection bug repro", (t) => { }, { denomPub: { - cipher: 1, + cipher: DenomKeyType.Rsa, rsa_public_key: "040000Y63CF78QFPKRY77BRK9P557Q1GQWX3NCZ3HSYSK0Z7TT0KGRA7N4SKBKEHSTVHX1Z9DNXMJR4EXSY1TXCKV0GJ3T3YYC6Z0JNMJFVYQAV4FX5J90NZH1N33MZTV8HS9SMNAA9S6K73G4P99GYBB01B0P6M1KXZ5JRDR7VWBR3MEJHHGJ6QBMCJR3NWJRE3WJW9PRY8QPQ2S7KFWTWRESH2DBXCXWBD2SRN6P9YX8GRAEMFEGXC9V5GVJTEMH6ZDGNXFPWZE3JVJ2Q4N9GDYKBCHZCJ7M7M2RJ9ZV4Y64NAN9BT6XDC68215GKKRHTW1BBF1MYY6AR3JCTT9HYAM923RMVQR3TAEB7SDX8J76XRZWYH3AGJCZAQGMN5C8SSH9AHQ9RNQJQ15CN45R37X4YNFJV904002", }, @@ -138,7 +138,7 @@ test("withdrawal selection bug repro", (t) => { }, { denomPub: { - cipher: 1, + cipher: DenomKeyType.Rsa, rsa_public_key: "040000YDESWC2B962DA4WK356SC50MA3N9KV0ZSGY3RC48JCTY258W909C7EEMT5BTC5KZ5T4CERCZ141P9QF87EK2BD1XEEM5GB07MB3H19WE4CQGAS8X84JBWN83PQGQXVMWE5HFA992KMGHC566GT9ZS2QPHZB6X89C4A80Z663PYAAPXP728VHAKATGNNBQ01ZZ2XD1CH9Y38YZBSPJ4K7GB2J76GBCYAVD9ENHDVWXJAXYRPBX4KSS5TXRR3K5NEN9ZV3AJD2V65K7ABRZDF5D5V1FJZZMNJ5XZ4FEREEKEBV9TDFPGJTKDEHEC60K3DN24DAATRESDJ1ZYYSYSRCAT4BT2B62ARGVMJTT5N2R126DRW9TGRWCW0ZAF2N2WET1H4NJEW77X0QT46Z5R3MZ0XPHD04002", }, @@ -192,7 +192,7 @@ test("withdrawal selection bug repro", (t) => { }, { denomPub: { - cipher: 1, + cipher: DenomKeyType.Rsa, rsa_public_key: "040000YG3T1ADB8DVA6BD3EPV6ZHSHTDW35DEN4VH1AE6CSB7P1PSDTNTJG866PHF6QB1CCWYCVRGA0FVBJ9Q0G7KV7AD9010GDYBQH0NNPHW744MTNXVXWBGGGRGQGYK4DTYN1DSWQ1FZNDSZZPB5BEKG2PDJ93NX2JTN06Y8QMS2G734Z9XHC10EENBG2KVB7EJ3CM8PV1T32RC7AY62F3496E8D8KRHJQQTT67DSGMNKK86QXVDTYW677FG27DP20E8XY3M6FQD53NDJ1WWES91401MV1A3VXVPGC76GZVDD62W3WTJ1YMKHTTA3MRXX3VEAAH3XTKDN1ER7X6CZPMYTF8VK735VP2B2TZGTF28TTW4FZS32SBS64APCDF6SZQ427N5538TJC7SRE71YSP5ET8GS904002", }, @@ -247,7 +247,7 @@ test("withdrawal selection bug repro", (t) => { }, { denomPub: { - cipher: 1, + cipher: DenomKeyType.Rsa, rsa_public_key: "040000ZC0G60E9QQ5PD81TSDWD9GV5Y6P8Z05NSPA696DP07NGQQVSRQXBA76Q6PRB0YFX295RG4MTQJXAZZ860ET307HSC2X37XAVGQXRVB8Q4F1V7NP5ZEVKTX75DZK1QRAVHEZGQYKSSH6DBCJNQF6V9WNQF3GEYVA4KCBHA7JF772KHXM9642C28Z0AS4XXXV2PABAN5C8CHYD5H7JDFNK3920W5Q69X0BS84XZ4RE2PW6HM1WZ6KGZ3MKWWWCPKQ1FSFABRBWKAB09PF563BEBXKY6M38QETPH5EDWGANHD0SC3QV0WXYVB7BNHNNQ0J5BNV56K563SYHM4E5ND260YRJSYA1GN5YSW2B1J5T1A1EBNYF2DN6JNJKWXWEQ42G5YS17ZSZ5EWDRA9QKV8EGTCNAD04002", }, @@ -301,7 +301,7 @@ test("withdrawal selection bug repro", (t) => { }, { denomPub: { - cipher: 1, + cipher: DenomKeyType.Rsa, rsa_public_key: "040000ZSK2PMVY6E3NBQ52KXMW029M60F4BWYTDS0FZSD0PE53CNZ9H6TM3GQK1WRTEKQ5GRWJ1J9DY6Y42SP47QVT1XD1G0W05SQ5F3F7P5KSWR0FJBJ9NZBXQEVN8Q4JRC94X3JJ3XV3KBYTZ2HTDFV28C3H2SRR0XGNZB4FY85NDZF1G4AEYJJ9QB3C0V8H70YB8RV3FKTNH7XS4K4HFNZHJ5H9VMX5SM9Z2DX37HA5WFH0E2MJBVVF2BWWA5M0HPPSB365RAE2AMD42Q65A96WD80X27SB2ZNQZ8WX0K13FWF85GZ6YNYAJGE1KGN06JDEKE9QD68Z651D7XE8V6664TVVC8M68S7WD0DSXMJQKQ0BNJXNDE29Q7MRX6DA3RW0PZ44B3TKRK0294FPVZTNSTA6XF04002", }, diff --git a/packages/taler-wallet-core/src/operations/withdraw.ts b/packages/taler-wallet-core/src/operations/withdraw.ts index 79220089b..731e9b3aa 100644 --- a/packages/taler-wallet-core/src/operations/withdraw.ts +++ b/packages/taler-wallet-core/src/operations/withdraw.ts @@ -43,6 +43,7 @@ import { DenomKeyType, LibtoolVersion, UnblindedSignature, + ExchangeWithdrawRequest, } from "@gnu-taler/taler-util"; import { CoinRecord, @@ -497,9 +498,8 @@ async function processPlanchetExchangeRequest( `processing planchet #${coinIdx} in withdrawal ${withdrawalGroup.withdrawalGroupId}`, ); - const reqBody: any = { + const reqBody: ExchangeWithdrawRequest = { denom_pub_hash: planchet.denomPubHash, - reserve_pub: planchet.reservePub, reserve_sig: planchet.withdrawSig, coin_ev: planchet.coinEv, }; @@ -580,28 +580,12 @@ async function processPlanchetVerifyAndStoreCoin( const { planchet, exchangeBaseUrl } = d; const planchetDenomPub = planchet.denomPub; - if ( - planchetDenomPub.cipher !== DenomKeyType.Rsa && - planchetDenomPub.cipher !== DenomKeyType.LegacyRsa - ) { + if (planchetDenomPub.cipher !== DenomKeyType.Rsa) { throw Error(`cipher (${planchetDenomPub.cipher}) not supported`); } let evSig = resp.ev_sig; - if (typeof resp.ev_sig === "string") { - evSig = { - cipher: DenomKeyType.LegacyRsa, - blinded_rsa_signature: resp.ev_sig, - }; - } else { - evSig = resp.ev_sig; - } - if ( - !( - evSig.cipher === DenomKeyType.Rsa || - evSig.cipher === DenomKeyType.LegacyRsa - ) - ) { + if (!(evSig.cipher === DenomKeyType.Rsa)) { throw Error("unsupported cipher"); } @@ -639,10 +623,7 @@ async function processPlanchetVerifyAndStoreCoin( } let denomSig: UnblindedSignature; - if ( - planchet.denomPub.cipher === DenomKeyType.LegacyRsa || - planchet.denomPub.cipher === DenomKeyType.Rsa - ) { + if (planchet.denomPub.cipher === DenomKeyType.Rsa) { denomSig = { cipher: planchet.denomPub.cipher, rsa_signature: denomSigRsa, diff --git a/packages/taler-wallet-core/src/util/coinSelection.test.ts b/packages/taler-wallet-core/src/util/coinSelection.test.ts index 49f8d1635..1675a9a35 100644 --- a/packages/taler-wallet-core/src/util/coinSelection.test.ts +++ b/packages/taler-wallet-core/src/util/coinSelection.test.ts @@ -18,7 +18,7 @@ * Imports. */ import test from "ava"; -import { AmountJson, Amounts } from "@gnu-taler/taler-util"; +import { AmountJson, Amounts, DenomKeyType } from "@gnu-taler/taler-util"; import { AvailableCoinInfo, selectPayCoins } from "./coinSelection.js"; function a(x: string): AmountJson { @@ -34,7 +34,7 @@ function fakeAci(current: string, feeDeposit: string): AvailableCoinInfo { availableAmount: a(current), coinPub: "foobar", denomPub: { - cipher: 1, + cipher: DenomKeyType.Rsa, rsa_public_key: "foobar", }, feeDeposit: a(feeDeposit), @@ -47,7 +47,7 @@ test("it should be able to pay if merchant takes the fees", (t) => { fakeAci("EUR:1.0", "EUR:0.1"), fakeAci("EUR:1.0", "EUR:0.0"), ]; - acis.forEach((x, i) => x.coinPub = String(i)); + acis.forEach((x, i) => (x.coinPub = String(i))); const res = selectPayCoins({ candidates: { @@ -75,7 +75,7 @@ test("it should take the last two coins if it pays less fees", (t) => { // Merchant covers the fee, this one shouldn't be used fakeAci("EUR:1.0", "EUR:0.0"), ]; - acis.forEach((x, i) => x.coinPub = String(i)); + acis.forEach((x, i) => (x.coinPub = String(i))); const res = selectPayCoins({ candidates: { @@ -102,8 +102,8 @@ test("it should take the last coins if the merchant doest not take all the fee", fakeAci("EUR:1.0", "EUR:0.5"), // this coin should be selected instead of previous one with fee fakeAci("EUR:1.0", "EUR:0.0"), - ] - acis.forEach((x, i) => x.coinPub = String(i)); + ]; + acis.forEach((x, i) => (x.coinPub = String(i))); const res = selectPayCoins({ candidates: { @@ -221,7 +221,7 @@ test("it should use the coins that spent less relative fee", (t) => { fakeAci("EUR:0.05", "EUR:0.05"), fakeAci("EUR:0.05", "EUR:0.05"), ]; - acis.forEach((x, i) => x.coinPub = String(i)); + acis.forEach((x, i) => (x.coinPub = String(i))); const res = selectPayCoins({ candidates: { -- cgit v1.2.3