summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2020-04-07 14:12:29 +0530
committerFlorian Dold <florian.dold@gmail.com>2020-04-07 14:12:29 +0530
commit34eca9c51215485c70492d6edea3513ada1c8895 (patch)
tree51982ac8c0204d13df7e5834111d975ca0ec309d /src
parentfaba5e9db8e0d1fdc4845de6b504b4e2ea3ca72b (diff)
downloadwallet-core-34eca9c51215485c70492d6edea3513ada1c8895.tar.gz
wallet-core-34eca9c51215485c70492d6edea3513ada1c8895.tar.bz2
wallet-core-34eca9c51215485c70492d6edea3513ada1c8895.zip
always round timestamps before signature creation/verification
Diffstat (limited to 'src')
-rw-r--r--src/crypto/workers/cryptoImplementation.ts24
-rw-r--r--src/util/time.ts14
2 files changed, 27 insertions, 11 deletions
diff --git a/src/crypto/workers/cryptoImplementation.ts b/src/crypto/workers/cryptoImplementation.ts
index 96ad29bc0..de3b88bb8 100644
--- a/src/crypto/workers/cryptoImplementation.ts
+++ b/src/crypto/workers/cryptoImplementation.ts
@@ -64,7 +64,7 @@ import {
} from "../talerCrypto";
import { randomBytes } from "../primitives/nacl-fast";
import { kdf } from "../primitives/kdf";
-import { Timestamp, getTimestampNow } from "../../util/time";
+import { Timestamp, getTimestampNow, timestampTruncateToSecond } from "../../util/time";
enum SignaturePurpose {
RESERVE_WITHDRAW = 1200,
@@ -94,13 +94,15 @@ function amountToBuffer(amount: AmountJson): Uint8Array {
return u8buf;
}
-function timestampToBuffer(ts: Timestamp): Uint8Array {
+function timestampRoundedToBuffer(ts: Timestamp): Uint8Array {
const b = new ArrayBuffer(8);
const v = new DataView(b);
- const s = BigInt(ts.t_ms) * BigInt(1000);
+ const tsRounded = timestampTruncateToSecond(ts);
+ const s = BigInt(tsRounded.t_ms) * BigInt(1000);
v.setBigUint64(0, s);
return new Uint8Array(b);
}
+
class SignaturePurposeBuilder {
private chunks: Uint8Array[] = [];
@@ -245,8 +247,8 @@ export class CryptoImplementation {
isValidWireFee(type: string, wf: WireFee, masterPub: string): boolean {
const p = buildSigPS(SignaturePurpose.MASTER_WIRE_FEES)
.put(hash(stringToBytes(type + "\0")))
- .put(timestampToBuffer(wf.startStamp))
- .put(timestampToBuffer(wf.endStamp))
+ .put(timestampRoundedToBuffer(wf.startStamp))
+ .put(timestampRoundedToBuffer(wf.endStamp))
.put(amountToBuffer(wf.wireFee))
.put(amountToBuffer(wf.closingFee))
.build();
@@ -261,10 +263,10 @@ export class CryptoImplementation {
isValidDenom(denom: DenominationRecord, masterPub: string): boolean {
const p = buildSigPS(SignaturePurpose.MASTER_DENOMINATION_KEY_VALIDITY)
.put(decodeCrock(masterPub))
- .put(timestampToBuffer(denom.stampStart))
- .put(timestampToBuffer(denom.stampExpireWithdraw))
- .put(timestampToBuffer(denom.stampExpireDeposit))
- .put(timestampToBuffer(denom.stampExpireLegal))
+ .put(timestampRoundedToBuffer(denom.stampStart))
+ .put(timestampRoundedToBuffer(denom.stampExpireWithdraw))
+ .put(timestampRoundedToBuffer(denom.stampExpireDeposit))
+ .put(timestampRoundedToBuffer(denom.stampExpireLegal))
.put(amountToBuffer(denom.value))
.put(amountToBuffer(denom.feeWithdraw))
.put(amountToBuffer(denom.feeDeposit))
@@ -330,8 +332,8 @@ export class CryptoImplementation {
const d = buildSigPS(SignaturePurpose.WALLET_COIN_DEPOSIT)
.put(decodeCrock(depositInfo.contractTermsHash))
.put(decodeCrock(depositInfo.wireInfoHash))
- .put(timestampToBuffer(depositInfo.timestamp))
- .put(timestampToBuffer(depositInfo.refundDeadline))
+ .put(timestampRoundedToBuffer(depositInfo.timestamp))
+ .put(timestampRoundedToBuffer(depositInfo.refundDeadline))
.put(amountToBuffer(depositInfo.spendAmount))
.put(amountToBuffer(depositInfo.feeDeposit))
.put(decodeCrock(depositInfo.merchantPub))
diff --git a/src/util/time.ts b/src/util/time.ts
index ea4f8ca8d..f296aba12 100644
--- a/src/util/time.ts
+++ b/src/util/time.ts
@@ -49,6 +49,7 @@ export function getTimestampNow(): Timestamp {
export function getDurationRemaining(
deadline: Timestamp,
now = getTimestampNow(),
+
): Duration {
if (deadline.t_ms === "never") {
return { d_ms: "forever" };
@@ -72,6 +73,19 @@ export function timestampMin(t1: Timestamp, t2: Timestamp): Timestamp {
return { t_ms: Math.min(t1.t_ms, t2.t_ms) };
}
+/**
+ * Truncate a timestamp so that that it represents a multiple
+ * of seconds. The timestamp is always rounded down.
+ */
+export function timestampTruncateToSecond(t1: Timestamp): Timestamp {
+ if (t1.t_ms === "never") {
+ return { t_ms: "never" };
+ }
+ return {
+ t_ms: Math.floor(t1.t_ms / 1000) * 1000,
+ };
+}
+
export function durationMin(d1: Duration, d2: Duration): Duration {
if (d1.d_ms === "forever") {
return { d_ms: d2.d_ms };