WIP: initial work for Anastasis in qtart
This commit is contained in:
parent
0b60602833
commit
ef51ba983f
@ -23,7 +23,6 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@gnu-taler/taler-util": "workspace:*",
|
"@gnu-taler/taler-util": "workspace:*",
|
||||||
"fflate": "^0.7.4",
|
"fflate": "^0.7.4",
|
||||||
"hash-wasm": "^4.9.0",
|
|
||||||
"tslib": "^2.5.3"
|
"tslib": "^2.5.3"
|
||||||
},
|
},
|
||||||
"ava": {
|
"ava": {
|
||||||
|
@ -26,8 +26,8 @@ import {
|
|||||||
secretbox_open,
|
secretbox_open,
|
||||||
hash,
|
hash,
|
||||||
bytesToString,
|
bytesToString,
|
||||||
|
hashArgon2id,
|
||||||
} from "@gnu-taler/taler-util";
|
} from "@gnu-taler/taler-util";
|
||||||
import { argon2id } from "hash-wasm";
|
|
||||||
|
|
||||||
export type Flavor<T, FlavorT extends string> = T & {
|
export type Flavor<T, FlavorT extends string> = T & {
|
||||||
_flavor?: `anastasis.${FlavorT}`;
|
_flavor?: `anastasis.${FlavorT}`;
|
||||||
@ -71,15 +71,13 @@ export async function userIdentifierDerive(
|
|||||||
): Promise<UserIdentifier> {
|
): Promise<UserIdentifier> {
|
||||||
const canonIdData = canonicalJson(idData);
|
const canonIdData = canonicalJson(idData);
|
||||||
const hashInput = stringToBytes(canonIdData);
|
const hashInput = stringToBytes(canonIdData);
|
||||||
const result = await argon2id({
|
const result = await hashArgon2id(
|
||||||
hashLength: 64,
|
hashInput, // password
|
||||||
iterations: 3,
|
decodeCrock(serverSalt), // salt
|
||||||
memorySize: 1024 /* kibibytes */,
|
3, // iterations
|
||||||
parallelism: 1,
|
1024, // memoryLimit (kibibytes)
|
||||||
password: hashInput,
|
64, // hashLength
|
||||||
salt: decodeCrock(serverSalt),
|
);
|
||||||
outputType: "binary",
|
|
||||||
});
|
|
||||||
return encodeCrock(result);
|
return encodeCrock(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -343,15 +341,13 @@ export async function secureAnswerHash(
|
|||||||
truthUuid: TruthUuid,
|
truthUuid: TruthUuid,
|
||||||
questionSalt: TruthSalt,
|
questionSalt: TruthSalt,
|
||||||
): Promise<SecureAnswerHash> {
|
): Promise<SecureAnswerHash> {
|
||||||
const powResult = await argon2id({
|
const powResult = await hashArgon2id(
|
||||||
hashLength: 64,
|
stringToBytes(answer), // password
|
||||||
iterations: 3,
|
decodeCrock(questionSalt), // salt
|
||||||
memorySize: 1024 /* kibibytes */,
|
3, // iterations
|
||||||
parallelism: 1,
|
1024, // memorySize (kibibytes)
|
||||||
password: stringToBytes(answer),
|
64, // hashLength
|
||||||
salt: decodeCrock(questionSalt),
|
);
|
||||||
outputType: "binary",
|
|
||||||
});
|
|
||||||
const kdfResult = kdfKw({
|
const kdfResult = kdfKw({
|
||||||
outputLength: 64,
|
outputLength: 64,
|
||||||
salt: decodeCrock(truthUuid),
|
salt: decodeCrock(truthUuid),
|
||||||
|
@ -69,7 +69,8 @@
|
|||||||
"big-integer": "^1.6.51",
|
"big-integer": "^1.6.51",
|
||||||
"fflate": "^0.7.4",
|
"fflate": "^0.7.4",
|
||||||
"jed": "^1.1.1",
|
"jed": "^1.1.1",
|
||||||
"tslib": "^2.5.3"
|
"tslib": "^2.5.3",
|
||||||
|
"hash-wasm": "^4.9.0"
|
||||||
},
|
},
|
||||||
"ava": {
|
"ava": {
|
||||||
"files": [
|
"files": [
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
import * as nacl from "./nacl-fast.js";
|
import * as nacl from "./nacl-fast.js";
|
||||||
import { hmacSha256, hmacSha512 } from "./kdf.js";
|
import { hmacSha256, hmacSha512 } from "./kdf.js";
|
||||||
import bigint from "big-integer";
|
import bigint from "big-integer";
|
||||||
|
import { argon2id } from "hash-wasm";
|
||||||
import {
|
import {
|
||||||
CoinEnvelope,
|
CoinEnvelope,
|
||||||
CoinPublicKeyString,
|
CoinPublicKeyString,
|
||||||
@ -69,6 +70,13 @@ interface NativeTartLib {
|
|||||||
encodeCrock(buf: Uint8Array | ArrayBuffer): string;
|
encodeCrock(buf: Uint8Array | ArrayBuffer): string;
|
||||||
decodeCrock(str: string): Uint8Array;
|
decodeCrock(str: string): Uint8Array;
|
||||||
hash(buf: Uint8Array): Uint8Array;
|
hash(buf: Uint8Array): Uint8Array;
|
||||||
|
hashArgon2id(
|
||||||
|
password: Uint8Array,
|
||||||
|
salt: Uint8Array,
|
||||||
|
iterations: number,
|
||||||
|
memorySize: number,
|
||||||
|
hashLength: number,
|
||||||
|
): Uint8Array;
|
||||||
eddsaGetPublic(buf: Uint8Array): Uint8Array;
|
eddsaGetPublic(buf: Uint8Array): Uint8Array;
|
||||||
ecdheGetPublic(buf: Uint8Array): Uint8Array;
|
ecdheGetPublic(buf: Uint8Array): Uint8Array;
|
||||||
eddsaSign(msg: Uint8Array, priv: Uint8Array): Uint8Array;
|
eddsaSign(msg: Uint8Array, priv: Uint8Array): Uint8Array;
|
||||||
@ -253,6 +261,33 @@ export function decodeCrock(encoded: string): Uint8Array {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function hashArgon2id(
|
||||||
|
password: Uint8Array,
|
||||||
|
salt: Uint8Array,
|
||||||
|
iterations: number,
|
||||||
|
memorySize: number,
|
||||||
|
hashLength: number,
|
||||||
|
): Promise<Uint8Array> {
|
||||||
|
if (tart) {
|
||||||
|
return tart.hashArgon2id(
|
||||||
|
password,
|
||||||
|
salt,
|
||||||
|
iterations,
|
||||||
|
memorySize,
|
||||||
|
hashLength,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return await argon2id({
|
||||||
|
password: password,
|
||||||
|
salt: salt,
|
||||||
|
iterations: iterations,
|
||||||
|
memorySize: memorySize,
|
||||||
|
hashLength: hashLength,
|
||||||
|
parallelism: 1,
|
||||||
|
outputType: "binary",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function eddsaGetPublic(eddsaPriv: Uint8Array): Uint8Array {
|
export function eddsaGetPublic(eddsaPriv: Uint8Array): Uint8Array {
|
||||||
if (tart) {
|
if (tart) {
|
||||||
return tart.eddsaGetPublic(eddsaPriv);
|
return tart.eddsaGetPublic(eddsaPriv);
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
"@gnu-taler/idb-bridge": "workspace:*",
|
"@gnu-taler/idb-bridge": "workspace:*",
|
||||||
"@gnu-taler/taler-util": "workspace:*",
|
"@gnu-taler/taler-util": "workspace:*",
|
||||||
"@gnu-taler/taler-wallet-core": "workspace:*",
|
"@gnu-taler/taler-wallet-core": "workspace:*",
|
||||||
|
"@gnu-taler/anastasis-core": "workspace:*",
|
||||||
"tslib": "^2.5.3"
|
"tslib": "^2.5.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -41,6 +41,10 @@ import {
|
|||||||
Wallet,
|
Wallet,
|
||||||
WalletApiOperation,
|
WalletApiOperation,
|
||||||
} from "@gnu-taler/taler-wallet-core";
|
} from "@gnu-taler/taler-wallet-core";
|
||||||
|
import {
|
||||||
|
reduceAction,
|
||||||
|
ReducerState,
|
||||||
|
} from "@gnu-taler/anastasis-core";
|
||||||
|
|
||||||
setGlobalLogLevelFromString("trace");
|
setGlobalLogLevelFromString("trace");
|
||||||
|
|
||||||
@ -169,6 +173,25 @@ class NativeWalletMessageHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle an Anastasis request from the native app.
|
||||||
|
*/
|
||||||
|
async function handleAnastasisRequest(
|
||||||
|
state: ReducerState,
|
||||||
|
action: string,
|
||||||
|
id: string,
|
||||||
|
args: any,
|
||||||
|
): Promise<CoreApiResponse> {
|
||||||
|
// For now, this will return "success" even if the wrapped Anastasis
|
||||||
|
// response is a ReducerStateError.
|
||||||
|
return {
|
||||||
|
type: "response",
|
||||||
|
id,
|
||||||
|
operation: "anastasis",
|
||||||
|
result: await reduceAction(state, action, args),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function installNativeWalletListener(): void {
|
export function installNativeWalletListener(): void {
|
||||||
setGlobalLogLevelFromString("trace");
|
setGlobalLogLevelFromString("trace");
|
||||||
const handler = new NativeWalletMessageHandler();
|
const handler = new NativeWalletMessageHandler();
|
||||||
@ -190,7 +213,13 @@ export function installNativeWalletListener(): void {
|
|||||||
|
|
||||||
let respMsg: CoreApiResponse;
|
let respMsg: CoreApiResponse;
|
||||||
try {
|
try {
|
||||||
respMsg = await handler.handleMessage(operation, id, msg.args ?? {});
|
if (msg.operation === "anastasis") {
|
||||||
|
// TODO: do some input validation here
|
||||||
|
let req = msg.args ?? {};
|
||||||
|
respMsg = await handleAnastasisRequest(req.state, req.action, id, req.args ?? {});
|
||||||
|
} else {
|
||||||
|
respMsg = await handler.handleMessage(operation, id, msg.args ?? {});
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
respMsg = {
|
respMsg = {
|
||||||
type: "error",
|
type: "error",
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
lockfileVersion: '6.1'
|
lockfileVersion: '6.0'
|
||||||
|
|
||||||
settings:
|
settings:
|
||||||
autoInstallPeers: true
|
autoInstallPeers: true
|
||||||
@ -120,9 +120,6 @@ importers:
|
|||||||
fflate:
|
fflate:
|
||||||
specifier: ^0.7.4
|
specifier: ^0.7.4
|
||||||
version: 0.7.4
|
version: 0.7.4
|
||||||
hash-wasm:
|
|
||||||
specifier: ^4.9.0
|
|
||||||
version: 4.9.0
|
|
||||||
tslib:
|
tslib:
|
||||||
specifier: ^2.5.3
|
specifier: ^2.5.3
|
||||||
version: 2.5.3
|
version: 2.5.3
|
||||||
@ -581,6 +578,9 @@ importers:
|
|||||||
fflate:
|
fflate:
|
||||||
specifier: ^0.7.4
|
specifier: ^0.7.4
|
||||||
version: 0.7.4
|
version: 0.7.4
|
||||||
|
hash-wasm:
|
||||||
|
specifier: ^4.9.0
|
||||||
|
version: 4.9.0
|
||||||
jed:
|
jed:
|
||||||
specifier: ^1.1.1
|
specifier: ^1.1.1
|
||||||
version: 1.1.1
|
version: 1.1.1
|
||||||
@ -716,6 +716,9 @@ importers:
|
|||||||
|
|
||||||
packages/taler-wallet-embedded:
|
packages/taler-wallet-embedded:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
'@gnu-taler/anastasis-core':
|
||||||
|
specifier: workspace:*
|
||||||
|
version: link:../anastasis-core
|
||||||
'@gnu-taler/idb-bridge':
|
'@gnu-taler/idb-bridge':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../idb-bridge
|
version: link:../idb-bridge
|
||||||
|
Loading…
Reference in New Issue
Block a user