summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-core/src/crypto/cryptoImplementation.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/taler-wallet-core/src/crypto/cryptoImplementation.ts')
-rw-r--r--packages/taler-wallet-core/src/crypto/cryptoImplementation.ts62
1 files changed, 60 insertions, 2 deletions
diff --git a/packages/taler-wallet-core/src/crypto/cryptoImplementation.ts b/packages/taler-wallet-core/src/crypto/cryptoImplementation.ts
index bfc48d961..98bb6c9cb 100644
--- a/packages/taler-wallet-core/src/crypto/cryptoImplementation.ts
+++ b/packages/taler-wallet-core/src/crypto/cryptoImplementation.ts
@@ -51,6 +51,7 @@ import {
encryptContractForMerge,
ExchangeProtocolVersion,
getRandomBytes,
+ GlobalFees,
hash,
HashCodeString,
hashCoinEv,
@@ -74,6 +75,7 @@ import {
rsaVerify,
setupTipPlanchet,
stringToBytes,
+ TalerProtocolDuration,
TalerProtocolTimestamp,
TalerSignaturePurpose,
UnblindedSignature,
@@ -142,6 +144,10 @@ export interface TalerCryptoInterface {
isValidWireFee(req: WireFeeValidationRequest): Promise<ValidationResult>;
+ isValidGlobalFees(
+ req: GlobalFeesValidationRequest,
+ ): Promise<ValidationResult>;
+
isValidDenom(req: DenominationValidationRequest): Promise<ValidationResult>;
isValidWireAccount(
@@ -152,7 +158,7 @@ export interface TalerCryptoInterface {
req: ContractTermsValidationRequest,
): Promise<ValidationResult>;
- createEddsaKeypair(req: {}): Promise<EddsaKeypair>;
+ createEddsaKeypair(req: unknown): Promise<EddsaKeypair>;
eddsaGetPublic(req: EddsaGetPublicRequest): Promise<EddsaGetPublicResponse>;
@@ -283,12 +289,17 @@ export const nullCrypto: TalerCryptoInterface = {
): Promise<ValidationResult> {
throw new Error("Function not implemented.");
},
+ isValidGlobalFees: function (
+ req: GlobalFeesValidationRequest,
+ ): Promise<ValidationResult> {
+ throw new Error("Function not implemented.");
+ },
isValidContractTermsSignature: function (
req: ContractTermsValidationRequest,
): Promise<ValidationResult> {
throw new Error("Function not implemented.");
},
- createEddsaKeypair: function (req: {}): Promise<EddsaKeypair> {
+ createEddsaKeypair: function (req: unknown): Promise<EddsaKeypair> {
throw new Error("Function not implemented.");
},
eddsaGetPublic: function (req: EddsaGetPublicRequest): Promise<EddsaKeypair> {
@@ -484,6 +495,11 @@ export interface WireFeeValidationRequest {
masterPub: string;
}
+export interface GlobalFeesValidationRequest {
+ gf: GlobalFees;
+ masterPub: string;
+}
+
export interface DenominationValidationRequest {
denom: DenominationRecord;
masterPub: string;
@@ -888,6 +904,30 @@ export const nativeCryptoR: TalerCryptoInterfaceR = {
},
/**
+ * Check if a global fee is correctly signed.
+ */
+ async isValidGlobalFees(
+ tci: TalerCryptoInterfaceR,
+ req: GlobalFeesValidationRequest,
+ ): Promise<ValidationResult> {
+ const { gf, masterPub } = req;
+ const p = buildSigPS(TalerSignaturePurpose.GLOBAL_FEES)
+ .put(timestampRoundedToBuffer(gf.start_date))
+ .put(timestampRoundedToBuffer(gf.end_date))
+ .put(durationRoundedToBuffer(gf.purse_timeout))
+ .put(durationRoundedToBuffer(gf.account_kyc_timeout))
+ .put(durationRoundedToBuffer(gf.history_expiration))
+ .put(amountToBuffer(Amounts.parseOrThrow(gf.history_fee)))
+ .put(amountToBuffer(Amounts.parseOrThrow(gf.kyc_fee)))
+ .put(amountToBuffer(Amounts.parseOrThrow(gf.account_fee)))
+ .put(amountToBuffer(Amounts.parseOrThrow(gf.purse_fee)))
+ .put(bufferForUint32(gf.purse_account_limit))
+ .build();
+ const sig = decodeCrock(gf.master_sig);
+ const pub = decodeCrock(masterPub);
+ return { valid: eddsaVerify(p, sig, pub) };
+ },
+ /**
* Check if the signature of a denomination is valid.
*/
async isValidDenom(
@@ -1630,6 +1670,24 @@ function timestampRoundedToBuffer(ts: TalerProtocolTimestamp): Uint8Array {
return new Uint8Array(b);
}
+function durationRoundedToBuffer(ts: TalerProtocolDuration): Uint8Array {
+ const b = new ArrayBuffer(8);
+ const v = new DataView(b);
+ // The buffer we sign over represents the timestamp in microseconds.
+ if (typeof v.setBigUint64 !== "undefined") {
+ const s = BigInt(ts.d_us);
+ v.setBigUint64(0, s);
+ } else {
+ const s = ts.d_us === "forever" ? bigint.zero : bigint(ts.d_us);
+ const arr = s.toArray(2 ** 8).value;
+ let offset = 8 - arr.length;
+ for (let i = 0; i < arr.length; i++) {
+ v.setUint8(offset++, arr[i]);
+ }
+ }
+ return new Uint8Array(b);
+}
+
export interface EddsaSignRequest {
msg: string;
priv: string;