diff options
author | Florian Dold <florian@dold.me> | 2022-09-01 22:26:22 +0200 |
---|---|---|
committer | Florian Dold <florian@dold.me> | 2022-09-01 22:26:22 +0200 |
commit | ec43b6a5bf4f8064aaad7fc303a10c7f585a110e (patch) | |
tree | 1dbeabf78bc911a651c42a202b0c39e1c6906ccf | |
parent | d6a172c4a00b615dce31630bf65e6d62b30f608e (diff) |
wallet-core: fix issue with crock encoding of age restrictions
-rw-r--r-- | packages/taler-util/src/talerCrypto.ts | 46 | ||||
-rw-r--r-- | packages/taler-util/src/talerTypes.ts | 28 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/crypto/cryptoImplementation.ts | 6 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/operations/withdraw.ts | 10 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/util/coinSelection.ts | 13 |
5 files changed, 63 insertions, 40 deletions
diff --git a/packages/taler-util/src/talerCrypto.ts b/packages/taler-util/src/talerCrypto.ts index d7734707a..8d2e41793 100644 --- a/packages/taler-util/src/talerCrypto.ts +++ b/packages/taler-util/src/talerCrypto.ts @@ -857,6 +857,13 @@ export type Edx25519PublicKey = FlavorP<Uint8Array, "Edx25519PublicKey", 32>; export type Edx25519PrivateKey = FlavorP<Uint8Array, "Edx25519PrivateKey", 64>; export type Edx25519Signature = FlavorP<Uint8Array, "Edx25519Signature", 64>; +export type Edx25519PublicKeyEnc = FlavorP<string, "Edx25519PublicKeyEnc", 32>; +export type Edx25519PrivateKeyEnc = FlavorP< + string, + "Edx25519PrivateKeyEnc", + 64 +>; + /** * Convert a big integer to a fixed-size, little-endian array. */ @@ -958,7 +965,7 @@ export interface AgeCommitment { /** * Public keys, one for each age group specified in the age mask. */ - publicKeys: Edx25519PublicKey[]; + publicKeys: Edx25519PublicKeyEnc[]; } export interface AgeProof { @@ -966,7 +973,7 @@ export interface AgeProof { * Private keys. Typically smaller than the number of public keys, * because we drop private keys from age groups that are restricted. */ - privateKeys: Edx25519PrivateKey[]; + privateKeys: Edx25519PrivateKeyEnc[]; } export interface AgeCommitmentProof { @@ -984,7 +991,7 @@ export namespace AgeRestriction { export function hashCommitment(ac: AgeCommitment): HashCodeString { const hc = new nacl.HashState(); for (const pub of ac.publicKeys) { - hc.update(pub); + hc.update(decodeCrock(pub)); } return encodeCrock(hc.finish().subarray(0, 32)); } @@ -1042,10 +1049,10 @@ export namespace AgeRestriction { return { commitment: { mask: ageMask, - publicKeys: pubs, + publicKeys: pubs.map((x) => encodeCrock(x)), }, proof: { - privateKeys: privs, + privateKeys: privs.map((x) => encodeCrock(x)), }, }; } @@ -1062,8 +1069,11 @@ export namespace AgeRestriction { return false; } for (let i = 0; i < c1.publicKeys.length; i++) { - const k1 = c1.publicKeys[i]; - const k2 = await Edx25519.publicKeyDerive(c2.publicKeys[i], salt); + const k1 = decodeCrock(c1.publicKeys[i]); + const k2 = await Edx25519.publicKeyDerive( + decodeCrock(c2.publicKeys[i]), + salt, + ); if (k1 != k2) { return false; } @@ -1079,20 +1089,22 @@ export namespace AgeRestriction { const newPubs: Edx25519PublicKey[] = []; for (const oldPub of commitmentProof.commitment.publicKeys) { - newPubs.push(await Edx25519.publicKeyDerive(oldPub, salt)); + newPubs.push(await Edx25519.publicKeyDerive(decodeCrock(oldPub), salt)); } for (const oldPriv of commitmentProof.proof.privateKeys) { - newPrivs.push(await Edx25519.privateKeyDerive(oldPriv, salt)); + newPrivs.push( + await Edx25519.privateKeyDerive(decodeCrock(oldPriv), salt), + ); } return { commitment: { mask: commitmentProof.commitment.mask, - publicKeys: newPubs, + publicKeys: newPubs.map((x) => encodeCrock(x)), }, proof: { - privateKeys: newPrivs, + privateKeys: newPrivs.map((x) => encodeCrock(x)), }, }; } @@ -1112,7 +1124,11 @@ export namespace AgeRestriction { } const priv = commitmentProof.proof.privateKeys[group - 1]; const pub = commitmentProof.commitment.publicKeys[group - 1]; - const sig = nacl.crypto_edx25519_sign_detached(d, priv, pub); + const sig = nacl.crypto_edx25519_sign_detached( + d, + decodeCrock(priv), + decodeCrock(pub), + ); return sig; } @@ -1131,7 +1147,11 @@ export namespace AgeRestriction { return true; } const pub = commitment.publicKeys[group - 1]; - return nacl.crypto_edx25519_sign_detached_verify(d, decodeCrock(sig), pub); + return nacl.crypto_edx25519_sign_detached_verify( + d, + decodeCrock(sig), + decodeCrock(pub), + ); } } diff --git a/packages/taler-util/src/talerTypes.ts b/packages/taler-util/src/talerTypes.ts index e36236085..014631ad7 100644 --- a/packages/taler-util/src/talerTypes.ts +++ b/packages/taler-util/src/talerTypes.ts @@ -25,29 +25,29 @@ * Imports. */ +import { codecForAmountString } from "./amounts.js"; import { buildCodecForObject, - codecForString, - codecForList, - codecOptional, + buildCodecForUnion, + Codec, codecForAny, - codecForNumber, codecForBoolean, - codecForMap, - Codec, codecForConstNumber, - buildCodecForUnion, codecForConstString, + codecForList, + codecForMap, + codecForNumber, + codecForString, + codecOptional, } from "./codec.js"; +import { strcmp } from "./helpers.js"; +import { AgeCommitmentProof, Edx25519PublicKeyEnc } from "./talerCrypto.js"; import { - codecForTimestamp, codecForDuration, - TalerProtocolTimestamp, + codecForTimestamp, TalerProtocolDuration, + TalerProtocolTimestamp, } from "./time.js"; -import { codecForAmountString } from "./amounts.js"; -import { strcmp } from "./helpers.js"; -import { AgeCommitmentProof, Edx25519PublicKey } from "./talerCrypto.js"; /** * Denomination as found in the /keys response from the exchange. @@ -287,7 +287,7 @@ export interface CoinDepositPermission { minimum_age_sig?: EddsaSignatureString; - age_commitment?: Edx25519PublicKey[]; + age_commitment?: Edx25519PublicKeyEnc[]; } /** @@ -1755,7 +1755,7 @@ export interface ExchangeRefreshRevealRequest { * the client MUST provide the original age commitment, i.e. the vector * of public keys. */ - old_age_commitment?: Edx25519PublicKey[]; + old_age_commitment?: Edx25519PublicKeyEnc[]; } export interface DepositSuccess { diff --git a/packages/taler-wallet-core/src/crypto/cryptoImplementation.ts b/packages/taler-wallet-core/src/crypto/cryptoImplementation.ts index 2f39f7806..f0a5cba2b 100644 --- a/packages/taler-wallet-core/src/crypto/cryptoImplementation.ts +++ b/packages/taler-wallet-core/src/crypto/cryptoImplementation.ts @@ -1084,7 +1084,7 @@ export const nativeCryptoR: TalerCryptoInterfaceR = { s.age_commitment = depositInfo.ageCommitmentProof?.commitment.publicKeys; } else if (depositInfo.ageCommitmentProof) { - (s as any).h_age_commitment = hAgeCommitment; + (s as any).h_age_commitment = encodeCrock(hAgeCommitment); } return s; @@ -1518,9 +1518,7 @@ export const nativeCryptoR: TalerCryptoInterfaceR = { }); logger.info(`payto URI: ${req.reservePayto}`); - logger.info( - `signing WALLET_PURSE_MERGE over ${encodeCrock(mergeSigBlob)}`, - ); + logger.info(`signing WALLET_PURSE_MERGE over ${encodeCrock(mergeSigBlob)}`); const reserveSigBlob = buildSigPS( TalerSignaturePurpose.WALLET_ACCOUNT_MERGE, diff --git a/packages/taler-wallet-core/src/operations/withdraw.ts b/packages/taler-wallet-core/src/operations/withdraw.ts index 1a73dc01c..9678258f0 100644 --- a/packages/taler-wallet-core/src/operations/withdraw.ts +++ b/packages/taler-wallet-core/src/operations/withdraw.ts @@ -242,7 +242,7 @@ export function selectWithdrawalDenominations( for (const d of denoms) { let count = 0; const cost = Amounts.add(d.value, d.feeWithdraw).amount; - for (; ;) { + for (;;) { if (Amounts.cmp(remaining, cost) < 0) { break; } @@ -903,7 +903,8 @@ export async function updateWithdrawalDenoms( denom.verificationStatus === DenominationVerificationStatus.Unverified ) { logger.trace( - `Validating denomination (${current + 1}/${denominations.length + `Validating denomination (${current + 1}/${ + denominations.length }) signature of ${denom.denomPubHash}`, ); let valid = false; @@ -1030,7 +1031,7 @@ async function queryReserve( if ( resp.status === 404 && result.talerErrorResponse.code === - TalerErrorCode.EXCHANGE_RESERVES_STATUS_UNKNOWN + TalerErrorCode.EXCHANGE_RESERVES_STATUS_UNKNOWN ) { ws.notify({ type: NotificationType.ReserveNotYetFound, @@ -1336,7 +1337,7 @@ export async function getExchangeWithdrawalInfo( ) { logger.warn( `wallet's support for exchange protocol version ${WALLET_EXCHANGE_PROTOCOL_VERSION} might be outdated ` + - `(exchange has ${exchangeDetails.protocolVersion}), checking for updates`, + `(exchange has ${exchangeDetails.protocolVersion}), checking for updates`, ); } } @@ -1869,6 +1870,7 @@ export async function acceptWithdrawalFromUri( confirmUrl: withdrawInfo.confirmTransferUrl, }, }, + restrictAge: req.restrictAge, forcedDenomSel: req.forcedDenomSel, reserveStatus: ReserveRecordStatus.RegisteringBank, }); diff --git a/packages/taler-wallet-core/src/util/coinSelection.ts b/packages/taler-wallet-core/src/util/coinSelection.ts index b3439067e..97e25abd3 100644 --- a/packages/taler-wallet-core/src/util/coinSelection.ts +++ b/packages/taler-wallet-core/src/util/coinSelection.ts @@ -291,11 +291,14 @@ export function selectPayCoins( aci.denomPub.age_mask, req.requiredMinimumAge, ); - if (!aci.ageCommitmentProof) { - // No age restriction, can't use for this payment - continue; - } - if (aci.ageCommitmentProof.proof.privateKeys.length < index) { + // if (!aci.ageCommitmentProof) { + // // No age restriction, can't use for this payment + // continue; + // } + if ( + aci.ageCommitmentProof && + aci.ageCommitmentProof.proof.privateKeys.length < index + ) { // Available age proofs to low, can't use for this payment continue; } |