gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-core] branch master updated: anastasis-core: crypto fixes


From: gnunet
Subject: [taler-wallet-core] branch master updated: anastasis-core: crypto fixes
Date: Tue, 19 Oct 2021 18:39:49 +0200

This is an automated email from the git hooks/post-receive script.

dold pushed a commit to branch master
in repository wallet-core.

The following commit(s) were added to refs/heads/master by this push:
     new 26738d14 anastasis-core: crypto fixes
26738d14 is described below

commit 26738d14f1d60d9aa7471d0be267d286a4644069
Author: Florian Dold <florian@dold.me>
AuthorDate: Tue Oct 19 18:39:38 2021 +0200

    anastasis-core: crypto fixes
---
 packages/anastasis-core/src/crypto.ts        | 10 ++--
 packages/anastasis-core/src/index.ts         | 73 +++++++++++++++++++++++++---
 packages/anastasis-core/src/reducer-types.ts | 12 +++--
 packages/taler-util/src/nacl-fast.ts         |  4 +-
 4 files changed, 78 insertions(+), 21 deletions(-)

diff --git a/packages/anastasis-core/src/crypto.ts 
b/packages/anastasis-core/src/crypto.ts
index 32cf470c..1332f849 100644
--- a/packages/anastasis-core/src/crypto.ts
+++ b/packages/anastasis-core/src/crypto.ts
@@ -66,16 +66,12 @@ export function accountKeypairDerive(userId: 
UserIdentifier): AccountKeyPair {
   // FIXME: the KDF invocation looks fishy, but that's what the C code 
presently does.
   const d = kdfKw({
     outputLength: 32,
-    ikm: stringToBytes("ver"),
-    salt: decodeCrock(userId),
+    ikm: decodeCrock(userId),
+    info: stringToBytes("ver"),
   });
-  // FIXME: This bit twiddling seems wrong/unnecessary.
-  d[0] &= 248;
-  d[31] &= 127;
-  d[31] |= 64;
   const pair = crypto_sign_keyPair_fromSeed(d);
   return {
-    priv: encodeCrock(pair.secretKey),
+    priv: encodeCrock(d),
     pub: encodeCrock(pair.publicKey),
   };
 }
diff --git a/packages/anastasis-core/src/index.ts 
b/packages/anastasis-core/src/index.ts
index 8921433b..7206f912 100644
--- a/packages/anastasis-core/src/index.ts
+++ b/packages/anastasis-core/src/index.ts
@@ -1,10 +1,14 @@
 import {
   AmountString,
+  buildSigPS,
   codecForGetExchangeWithdrawalInfo,
   decodeCrock,
+  eddsaSign,
   encodeCrock,
   getRandomBytes,
+  hash,
   TalerErrorCode,
+  TalerSignaturePurpose,
 } from "@gnu-taler/taler-util";
 import { anastasisData } from "./anastasis-data.js";
 import {
@@ -33,6 +37,7 @@ import {
   ReducerStateBackupUserAttributesCollecting,
   ReducerStateError,
   ReducerStateRecovery,
+  SuccessDetails,
 } from "./reducer-types.js";
 import fetchPonyfill from "fetch-ponyfill";
 import {
@@ -43,6 +48,7 @@ import {
   encryptTruth,
   PolicyKey,
   policyKeyDerive,
+  PolicySalt,
   UserIdentifier,
   userIdentifierDerive,
 } from "./crypto.js";
@@ -393,12 +399,17 @@ async function uploadSecret(
   const coreSecret = state.core_secret?.value!;
   // Truth key is `${methodIndex}/${providerUrl}`
   const truthMetadataMap: Record<string, TruthMetaData> = {};
+
   const policyKeys: PolicyKey[] = [];
+  const policySalts: PolicySalt[] = [];
+  // truth UUIDs for every policy.
+  const policyUuids: string[][] = [];
 
   for (let policyIndex = 0; policyIndex < policies.length; policyIndex++) {
     const pol = policies[policyIndex];
     const policySalt = encodeCrock(getRandomBytes(64));
     const keyShares: string[] = [];
+    const methUuids: string[] = [];
     for (let methIndex = 0; methIndex < pol.methods.length; methIndex++) {
       const meth = pol.methods[methIndex];
       const truthKey = `${meth.authentication_method}:${meth.provider}`;
@@ -416,10 +427,12 @@ async function uploadSecret(
         pol_method_index: methIndex,
         policy_index: policyIndex,
       };
+      methUuids.push(tm.uuid);
       truthMetadataMap[truthKey] = tm;
     }
     const policyKey = await policyKeyDerive(keyShares, policySalt);
     policyKeys.push(policyKey);
+    policySalts.push(policySalt);
   }
 
   const csr = await coreSecretEncrypt(policyKeys, coreSecret);
@@ -472,6 +485,13 @@ async function uploadSecret(
       body: JSON.stringify(tur),
     });
 
+    if (resp.status !== 204) {
+      return {
+        code: TalerErrorCode.ANASTASIS_REDUCER_NETWORK_FAILED,
+        hint: "could not upload policy",
+      };
+    }
+
     escrowMethods.push({
       escrow_type: authMethod.type,
       instructions: authMethod.instructions,
@@ -494,30 +514,56 @@ async function uploadSecret(
     policies: policies.map((x, i) => {
       return {
         master_key: csr.encMasterKeys[i],
-        // FIXME: ...
-        uuid: [],
-        salt: undefined as any,
+        uuid: policyUuids[i],
+        salt: policySalts[i],
       };
     }),
   };
 
+  const successDetails: SuccessDetails = {};
+
   for (const prov of state.policy_providers!) {
-    const uid = uidMap[prov.provider_url]
+    const uid = uidMap[prov.provider_url];
     const acctKeypair = accountKeypairDerive(uid);
     const encRecoveryDoc = await encryptRecoveryDocument(uid, rd);
-    // FIXME: Upload recovery document.
+    const bodyHash = hash(decodeCrock(encRecoveryDoc));
+    const sigPS = buildSigPS(TalerSignaturePurpose.ANASTASIS_POLICY_UPLOAD)
+      .put(bodyHash)
+      .build();
+    const sig = eddsaSign(sigPS, decodeCrock(acctKeypair.priv));
     const resp = await fetch(
       new URL(`policy/${acctKeypair.pub}`, prov.provider_url).href,
       {
         method: "POST",
+        headers: {
+          "Anastasis-Policy-Signature": encodeCrock(sig),
+          "If-None-Match": encodeCrock(bodyHash),
+        },
         body: decodeCrock(encRecoveryDoc),
       },
     );
+    if (resp.status !== 204) {
+      return {
+        code: TalerErrorCode.ANASTASIS_REDUCER_NETWORK_FAILED,
+        hint: "could not upload policy",
+      };
+    }
+    let policyVersion = 0;
+    console.log(resp);
+    console.log(resp.headers);
+    console.log(resp.headers.get("Anastasis-Version"));
+    try {
+      policyVersion = Number(resp.headers.get("Anastasis-Version") ?? "0");
+    } catch (e) {}
+    successDetails[prov.provider_url] = {
+      policy_version: policyVersion,
+    };
   }
 
   return {
-    code: 123,
-    hint: "not implemented",
+    ...state,
+    backup_state: BackupStates.BackupFinished,
+    success_details: successDetails,
   };
 }
 
@@ -703,6 +749,19 @@ export async function reduceAction(
       };
     }
   }
+  if (state.backup_state === BackupStates.BackupFinished) {
+    if (action === "back") {
+      return {
+        ...state,
+        backup_state: BackupStates.SecretEditing,
+      };
+    } else {
+      return {
+        code: TalerErrorCode.ANASTASIS_REDUCER_ACTION_INVALID,
+        hint: `Unsupported action '${action}'`,
+      };
+    }
+  }
   return {
     code: TalerErrorCode.ANASTASIS_REDUCER_ACTION_INVALID,
     hint: "Reducer action invalid",
diff --git a/packages/anastasis-core/src/reducer-types.ts 
b/packages/anastasis-core/src/reducer-types.ts
index 0d1754bd..1f4a2abe 100644
--- a/packages/anastasis-core/src/reducer-types.ts
+++ b/packages/anastasis-core/src/reducer-types.ts
@@ -27,6 +27,12 @@ export interface PolicyProvider {
   provider_url: string;
 }
 
+export interface SuccessDetails {
+  [provider_url: string]: {
+    policy_version: number;
+  };
+}
+
 export interface ReducerStateBackup {
   recovery_state?: undefined;
   backup_state: BackupStates;
@@ -47,11 +53,7 @@ export interface ReducerStateBackup {
    * and that are actually used in policies.
    */
   policy_providers?: PolicyProvider[];
-  success_details?: {
-    [provider_url: string]: {
-      policy_version: number;
-    };
-  };
+  success_details?: SuccessDetails;
   payments?: string[];
   policy_payment_requests?: {
     payto: string;
diff --git a/packages/taler-util/src/nacl-fast.ts 
b/packages/taler-util/src/nacl-fast.ts
index 6e721f32..500ac11c 100644
--- a/packages/taler-util/src/nacl-fast.ts
+++ b/packages/taler-util/src/nacl-fast.ts
@@ -2926,7 +2926,8 @@ export function crypto_sign_keyPair_fromSeed(
   secretKey: Uint8Array;
 } {
   checkArrayTypes(seed);
-  if (seed.length !== crypto_sign_SEEDBYTES) throw new Error("bad seed size");
+  if (seed.length !== crypto_sign_SEEDBYTES)
+    throw new Error(`bad seed size: ${seed.length}`);
   const pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);
   const sk = new Uint8Array(crypto_sign_SECRETKEYBYTES);
   for (let i = 0; i < 32; i++) sk[i] = seed[i];
@@ -3015,4 +3016,3 @@ export function secretbox_open(
   if (crypto_secretbox_open(m, c, c.length, nonce, key) !== 0) return 
undefined;
   return m.subarray(crypto_secretbox_ZEROBYTES);
 }
-

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]