set gzip timestamp to 0 in backup blob
This commit is contained in:
parent
6c14268c1a
commit
eaced5ca63
@ -24,44 +24,54 @@
|
||||
/**
|
||||
* Imports.
|
||||
*/
|
||||
import { hash } from "../../crypto/primitives/nacl-fast.js";
|
||||
import {
|
||||
WalletBackupContentV1,
|
||||
BackupExchange,
|
||||
BackupCoin,
|
||||
BackupDenomination,
|
||||
BackupReserve,
|
||||
BackupPurchase,
|
||||
BackupProposal,
|
||||
BackupRefreshGroup,
|
||||
Amounts,
|
||||
BackupBackupProvider,
|
||||
BackupTip,
|
||||
BackupRecoupGroup,
|
||||
BackupWithdrawalGroup,
|
||||
BackupBackupProviderTerms,
|
||||
BackupCoin,
|
||||
BackupCoinSource,
|
||||
BackupCoinSourceType,
|
||||
BackupDenomination,
|
||||
BackupExchange,
|
||||
BackupExchangeDetails,
|
||||
BackupExchangeWireFee,
|
||||
BackupRefundItem,
|
||||
BackupRefundState,
|
||||
BackupProposal,
|
||||
BackupProposalStatus,
|
||||
BackupPurchase,
|
||||
BackupRecoupGroup,
|
||||
BackupRefreshGroup,
|
||||
BackupRefreshOldCoin,
|
||||
BackupRefreshSession,
|
||||
BackupExchangeDetails,
|
||||
BackupRefundItem,
|
||||
BackupRefundState,
|
||||
BackupReserve,
|
||||
BackupTip,
|
||||
BackupWithdrawalGroup,
|
||||
canonicalizeBaseUrl,
|
||||
canonicalJson,
|
||||
getTimestampNow,
|
||||
Logger,
|
||||
timestampToIsoString,
|
||||
WalletBackupContentV1,
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { InternalWalletState } from "../../common.js";
|
||||
import { provideBackupState, getWalletBackupState } from "./state.js";
|
||||
import { Amounts, getTimestampNow } from "@gnu-taler/taler-util";
|
||||
import { hash } from "../../crypto/primitives/nacl-fast.js";
|
||||
import {
|
||||
encodeCrock,
|
||||
getRandomBytes,
|
||||
stringToBytes,
|
||||
} from "../../crypto/talerCrypto.js";
|
||||
import {
|
||||
AbortStatus,
|
||||
CoinSourceType,
|
||||
CoinStatus,
|
||||
RefundState,
|
||||
AbortStatus,
|
||||
ProposalStatus,
|
||||
RefundState,
|
||||
WALLET_BACKUP_STATE_KEY,
|
||||
} from "../../db.js";
|
||||
import { encodeCrock, stringToBytes, getRandomBytes } from "../../crypto/talerCrypto.js";
|
||||
import { canonicalizeBaseUrl, canonicalJson } from "@gnu-taler/taler-util";
|
||||
import { getWalletBackupState, provideBackupState } from "./state.js";
|
||||
|
||||
const logger = new Logger("backup/export.ts");
|
||||
|
||||
export async function exportBackup(
|
||||
ws: InternalWalletState,
|
||||
@ -444,8 +454,10 @@ export async function exportBackup(
|
||||
});
|
||||
});
|
||||
|
||||
const ts = getTimestampNow();
|
||||
|
||||
if (!bs.lastBackupTimestamp) {
|
||||
bs.lastBackupTimestamp = getTimestampNow();
|
||||
bs.lastBackupTimestamp = ts;
|
||||
}
|
||||
|
||||
const backupBlob: WalletBackupContentV1 = {
|
||||
@ -469,18 +481,30 @@ export async function exportBackup(
|
||||
tombstones: [],
|
||||
};
|
||||
|
||||
// If the backup changed, we increment our clock.
|
||||
// If the backup changed, we change our nonce and timestamp.
|
||||
|
||||
let h = encodeCrock(hash(stringToBytes(canonicalJson(backupBlob))));
|
||||
if (h != bs.lastBackupPlainHash) {
|
||||
if (h !== bs.lastBackupPlainHash) {
|
||||
logger.trace(
|
||||
`plain backup hash changed (from ${bs.lastBackupPlainHash}to ${h})`,
|
||||
);
|
||||
bs.lastBackupTimestamp = ts;
|
||||
backupBlob.timestamp = ts;
|
||||
bs.lastBackupPlainHash = encodeCrock(
|
||||
hash(stringToBytes(canonicalJson(backupBlob))),
|
||||
);
|
||||
bs.lastBackupNonce = encodeCrock(getRandomBytes(32));
|
||||
logger.trace(
|
||||
`setting timestamp to ${timestampToIsoString(ts)} and nonce to ${
|
||||
bs.lastBackupNonce
|
||||
}`,
|
||||
);
|
||||
await tx.config.put({
|
||||
key: WALLET_BACKUP_STATE_KEY,
|
||||
value: bs,
|
||||
});
|
||||
} else {
|
||||
logger.trace("backup hash did not change");
|
||||
}
|
||||
|
||||
return backupBlob;
|
||||
|
@ -24,24 +24,39 @@
|
||||
/**
|
||||
* Imports.
|
||||
*/
|
||||
import { InternalWalletState } from "../../common.js";
|
||||
import {
|
||||
AmountString,
|
||||
BackupRecovery,
|
||||
buildCodecForObject,
|
||||
canonicalizeBaseUrl,
|
||||
canonicalJson,
|
||||
Codec,
|
||||
codecForAmountString,
|
||||
codecForBoolean,
|
||||
codecForNumber,
|
||||
codecForString,
|
||||
codecOptional,
|
||||
ConfirmPayResultType,
|
||||
durationFromSpec,
|
||||
getTimestampNow,
|
||||
j2s,
|
||||
Logger,
|
||||
PreparePayResultType,
|
||||
RecoveryLoadRequest,
|
||||
RecoveryMergeStrategy,
|
||||
TalerErrorDetails,
|
||||
Timestamp,
|
||||
timestampAddDuration,
|
||||
URL,
|
||||
WalletBackupContentV1,
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { gunzipSync, gzipSync } from "fflate";
|
||||
import { InternalWalletState } from "../../common.js";
|
||||
import { kdf } from "../../crypto/primitives/kdf.js";
|
||||
import {
|
||||
BackupProviderRecord,
|
||||
BackupProviderTerms,
|
||||
ConfigRecord,
|
||||
WalletBackupConfState,
|
||||
WALLET_BACKUP_STATE_KEY,
|
||||
} from "../../db.js";
|
||||
import {
|
||||
checkDbInvariant,
|
||||
checkLogicInvariant,
|
||||
} from "../../util/invariants.js";
|
||||
secretbox,
|
||||
secretbox_open,
|
||||
} from "../../crypto/primitives/nacl-fast.js";
|
||||
import {
|
||||
bytesToString,
|
||||
decodeCrock,
|
||||
@ -53,43 +68,24 @@ import {
|
||||
rsaBlind,
|
||||
stringToBytes,
|
||||
} from "../../crypto/talerCrypto.js";
|
||||
import { canonicalizeBaseUrl, canonicalJson, j2s } from "@gnu-taler/taler-util";
|
||||
import { CryptoApi } from "../../crypto/workers/cryptoApi.js";
|
||||
import {
|
||||
durationFromSpec,
|
||||
getTimestampNow,
|
||||
Timestamp,
|
||||
timestampAddDuration,
|
||||
URL
|
||||
} from "@gnu-taler/taler-util";
|
||||
import {
|
||||
buildCodecForObject,
|
||||
Codec,
|
||||
codecForBoolean,
|
||||
codecForNumber,
|
||||
codecForString,
|
||||
codecOptional,
|
||||
} from "@gnu-taler/taler-util";
|
||||
BackupProviderRecord,
|
||||
BackupProviderTerms,
|
||||
ConfigRecord,
|
||||
WalletBackupConfState,
|
||||
WALLET_BACKUP_STATE_KEY,
|
||||
} from "../../db.js";
|
||||
import {
|
||||
HttpResponseStatus,
|
||||
readSuccessResponseJsonOrThrow,
|
||||
readTalerErrorResponse,
|
||||
} from "../../util/http.js";
|
||||
import { Logger } from "@gnu-taler/taler-util";
|
||||
import { gunzipSync, gzipSync } from "fflate";
|
||||
import { kdf } from "../../crypto/primitives/kdf.js";
|
||||
import {
|
||||
checkDbInvariant,
|
||||
checkLogicInvariant,
|
||||
} from "../../util/invariants.js";
|
||||
import { initRetryInfo } from "../../util/retries.js";
|
||||
import {
|
||||
ConfirmPayResultType,
|
||||
PreparePayResultType,
|
||||
RecoveryLoadRequest,
|
||||
RecoveryMergeStrategy,
|
||||
TalerErrorDetails,
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { CryptoApi } from "../../crypto/workers/cryptoApi.js";
|
||||
import {
|
||||
secretbox,
|
||||
secretbox_open,
|
||||
} from "../../crypto/primitives/nacl-fast.js";
|
||||
import {
|
||||
checkPaymentByProposalId,
|
||||
confirmPay,
|
||||
@ -97,7 +93,7 @@ import {
|
||||
} from "../pay.js";
|
||||
import { exportBackup } from "./export.js";
|
||||
import { BackupCryptoPrecomputedData, importBackup } from "./import.js";
|
||||
import { provideBackupState, getWalletBackupState } from "./state.js";
|
||||
import { getWalletBackupState, provideBackupState } from "./state.js";
|
||||
|
||||
const logger = new Logger("operations/backup.ts");
|
||||
|
||||
@ -137,7 +133,9 @@ export async function encryptBackup(
|
||||
chunks.push(nonce);
|
||||
const backupJsonContent = canonicalJson(blob);
|
||||
logger.trace("backup JSON size", backupJsonContent.length);
|
||||
const compressedContent = gzipSync(stringToBytes(backupJsonContent));
|
||||
const compressedContent = gzipSync(stringToBytes(backupJsonContent), {
|
||||
mtime: 0,
|
||||
});
|
||||
const secret = deriveBlobSecret(config);
|
||||
const encrypted = secretbox(compressedContent, nonce.slice(0, 24), secret);
|
||||
chunks.push(encrypted);
|
||||
@ -261,7 +259,12 @@ async function runBackupCycleForProvider(
|
||||
backupJson,
|
||||
} = args;
|
||||
const accountKeyPair = deriveAccountKeyPair(backupConfig, provider.baseUrl);
|
||||
|
||||
const newHash = encodeCrock(currentBackupHash);
|
||||
const oldHash = provider.lastBackupHash;
|
||||
|
||||
logger.trace(`trying to upload backup to ${provider.baseUrl}`);
|
||||
logger.trace(`old hash ${oldHash}, new hash ${newHash}`);
|
||||
|
||||
const syncSig = await ws.cryptoApi.makeSyncSignature({
|
||||
newHash: encodeCrock(currentBackupHash),
|
||||
|
Loading…
Reference in New Issue
Block a user