summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-core
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2021-09-17 15:48:33 -0300
committerSebastian <sebasjm@gmail.com>2021-09-17 15:49:07 -0300
commit315b167bee240e625beea731df6472a971b46cb2 (patch)
tree098557be6106622844ad5d59dce7e0c64bb22bcc /packages/taler-wallet-core
parent490620ad04a677fa220cbe77dc0bea29b6e80c12 (diff)
downloadwallet-core-315b167bee240e625beea731df6472a971b46cb2.tar.gz
wallet-core-315b167bee240e625beea731df6472a971b46cb2.tar.bz2
wallet-core-315b167bee240e625beea731df6472a971b46cb2.zip
issue #5860
Diffstat (limited to 'packages/taler-wallet-core')
-rw-r--r--packages/taler-wallet-core/src/crypto/workers/cryptoApi.ts6
-rw-r--r--packages/taler-wallet-core/src/crypto/workers/cryptoImplementation.ts11
-rw-r--r--packages/taler-wallet-core/src/operations/pay.ts20
3 files changed, 32 insertions, 5 deletions
diff --git a/packages/taler-wallet-core/src/crypto/workers/cryptoApi.ts b/packages/taler-wallet-core/src/crypto/workers/cryptoApi.ts
index da92e83c6..6bace01a3 100644
--- a/packages/taler-wallet-core/src/crypto/workers/cryptoApi.ts
+++ b/packages/taler-wallet-core/src/crypto/workers/cryptoApi.ts
@@ -213,7 +213,7 @@ export class CryptoApi {
ws.w = null;
}
} catch (e) {
- logger.error(e);
+ logger.error(e as string);
}
if (ws.currentWorkItem !== null) {
ws.currentWorkItem.reject(e);
@@ -379,6 +379,10 @@ export class CryptoApi {
return this.doRpc<{ priv: string; pub: string }>("createEddsaKeypair", 1);
}
+ eddsaGetPublic(key: string): Promise<{ priv: string; pub: string }> {
+ return this.doRpc<{ priv: string; pub: string }>("eddsaGetPublic", 1, key);
+ }
+
rsaUnblind(sig: string, bk: string, pk: string): Promise<string> {
return this.doRpc<string>("rsaUnblind", 4, sig, bk, pk);
}
diff --git a/packages/taler-wallet-core/src/crypto/workers/cryptoImplementation.ts b/packages/taler-wallet-core/src/crypto/workers/cryptoImplementation.ts
index e1580a7d1..7112964db 100644
--- a/packages/taler-wallet-core/src/crypto/workers/cryptoImplementation.ts
+++ b/packages/taler-wallet-core/src/crypto/workers/cryptoImplementation.ts
@@ -62,6 +62,7 @@ import {
setupRefreshTransferPub,
setupTipPlanchet,
setupWithdrawPlanchet,
+ eddsaGetPublic,
} from "../talerCrypto.js";
import { randomBytes } from "../primitives/nacl-fast.js";
import { kdf } from "../primitives/kdf.js";
@@ -141,7 +142,7 @@ function timestampRoundedToBuffer(ts: Timestamp): Uint8Array {
class SignaturePurposeBuilder {
private chunks: Uint8Array[] = [];
- constructor(private purposeNum: number) {}
+ constructor(private purposeNum: number) { }
put(bytes: Uint8Array): SignaturePurposeBuilder {
this.chunks.push(Uint8Array.from(bytes));
@@ -170,7 +171,6 @@ class SignaturePurposeBuilder {
function buildSigPS(purposeNum: number): SignaturePurposeBuilder {
return new SignaturePurposeBuilder(purposeNum);
}
-
export class CryptoImplementation {
static enableTracing = false;
@@ -361,6 +361,13 @@ export class CryptoImplementation {
};
}
+ eddsaGetPublic(key: string): { priv: string; pub: string } {
+ return {
+ priv: key,
+ pub: encodeCrock(eddsaGetPublic(decodeCrock(key)))
+ }
+ }
+
/**
* Unblind a blindly signed value.
*/
diff --git a/packages/taler-wallet-core/src/operations/pay.ts b/packages/taler-wallet-core/src/operations/pay.ts
index 9a7b0d069..970aa46ff 100644
--- a/packages/taler-wallet-core/src/operations/pay.ts
+++ b/packages/taler-wallet-core/src/operations/pay.ts
@@ -875,7 +875,9 @@ async function startDownloadProposal(
orderId: string,
sessionId: string | undefined,
claimToken: string | undefined,
+ noncePriv: string | undefined,
): Promise<string> {
+
const oldProposal = await ws.db
.mktx((x) => ({ proposals: x.proposals }))
.runReadOnly(async (tx) => {
@@ -884,12 +886,20 @@ async function startDownloadProposal(
orderId,
]);
});
- if (oldProposal) {
+
+ /**
+ * If we have already claimed this proposal with the same sessionId
+ * nonce and claim token, reuse it.
+ */
+ if (oldProposal &&
+ oldProposal.downloadSessionId === sessionId &&
+ oldProposal.noncePriv === noncePriv &&
+ oldProposal.claimToken === claimToken) {
await processDownloadProposal(ws, oldProposal.proposalId);
return oldProposal.proposalId;
}
- const { priv, pub } = await ws.cryptoApi.createEddsaKeypair();
+ const { priv, pub } = await (noncePriv ? ws.cryptoApi.eddsaGetPublic(noncePriv) : ws.cryptoApi.createEddsaKeypair());
const proposalId = encodeCrock(getRandomBytes(32));
const proposalRecord: ProposalRecord = {
@@ -1405,6 +1415,7 @@ export async function checkPaymentByProposalId(
status: PreparePayResultType.InsufficientBalance,
contractTerms: d.contractTermsRaw,
proposalId: proposal.proposalId,
+ noncePriv: proposal.noncePriv,
amountRaw: Amounts.stringify(d.contractData.amount),
};
}
@@ -1417,6 +1428,7 @@ export async function checkPaymentByProposalId(
status: PreparePayResultType.PaymentPossible,
contractTerms: d.contractTermsRaw,
proposalId: proposal.proposalId,
+ noncePriv: proposal.noncePriv,
amountEffective: Amounts.stringify(totalCost),
amountRaw: Amounts.stringify(res.paymentAmount),
contractTermsHash: d.contractData.contractTermsHash,
@@ -1453,6 +1465,7 @@ export async function checkPaymentByProposalId(
amountRaw: Amounts.stringify(purchase.download.contractData.amount),
amountEffective: Amounts.stringify(purchase.totalPayCost),
proposalId,
+ noncePriv: proposal.noncePriv,
};
} else if (!purchase.timestampFirstSuccessfulPay) {
return {
@@ -1463,6 +1476,7 @@ export async function checkPaymentByProposalId(
amountRaw: Amounts.stringify(purchase.download.contractData.amount),
amountEffective: Amounts.stringify(purchase.totalPayCost),
proposalId,
+ noncePriv: proposal.noncePriv,
};
} else {
const paid = !purchase.paymentSubmitPending;
@@ -1475,6 +1489,7 @@ export async function checkPaymentByProposalId(
amountEffective: Amounts.stringify(purchase.totalPayCost),
...(paid ? { nextUrl: purchase.download.contractData.orderId } : {}),
proposalId,
+ noncePriv: proposal.noncePriv,
};
}
}
@@ -1507,6 +1522,7 @@ export async function preparePayForUri(
uriResult.orderId,
uriResult.sessionId,
uriResult.claimToken,
+ uriResult.noncePriv,
);
return checkPaymentByProposalId(ws, proposalId, uriResult.sessionId);