aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2022-09-01 22:26:22 +0200
committerFlorian Dold <florian@dold.me>2022-09-01 22:26:22 +0200
commitec43b6a5bf4f8064aaad7fc303a10c7f585a110e (patch)
tree1dbeabf78bc911a651c42a202b0c39e1c6906ccf
parentd6a172c4a00b615dce31630bf65e6d62b30f608e (diff)
wallet-core: fix issue with crock encoding of age restrictions
-rw-r--r--packages/taler-util/src/talerCrypto.ts46
-rw-r--r--packages/taler-util/src/talerTypes.ts28
-rw-r--r--packages/taler-wallet-core/src/crypto/cryptoImplementation.ts6
-rw-r--r--packages/taler-wallet-core/src/operations/withdraw.ts10
-rw-r--r--packages/taler-wallet-core/src/util/coinSelection.ts13
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;
}