gnunet-svn
[Top][All Lists]
Advanced

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

[taler-wallet-core] 01/02: anastasis-core: question hashing and policy e


From: gnunet
Subject: [taler-wallet-core] 01/02: anastasis-core: question hashing and policy expiration
Date: Tue, 19 Oct 2021 23:26:36 +0200

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

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

commit 5dc008939237c29fdfd146ddb1adc09054950459
Author: Florian Dold <florian@dold.me>
AuthorDate: Tue Oct 19 20:51:31 2021 +0200

    anastasis-core: question hashing and policy expiration
---
 packages/anastasis-core/src/crypto.ts        |  9 ++--
 packages/anastasis-core/src/index.ts         | 67 +++++++++++++++++++++-------
 packages/anastasis-core/src/reducer-types.ts |  3 +-
 3 files changed, 58 insertions(+), 21 deletions(-)

diff --git a/packages/anastasis-core/src/crypto.ts 
b/packages/anastasis-core/src/crypto.ts
index a5594288..f7cfa965 100644
--- a/packages/anastasis-core/src/crypto.ts
+++ b/packages/anastasis-core/src/crypto.ts
@@ -33,7 +33,10 @@ export type EddsaPublicKey = Flavor<string, 
"EddsaPublicKey">;
 export type EddsaPrivateKey = Flavor<string, "EddsaPrivateKey">;
 export type TruthUuid = Flavor<string, "TruthUuid">;
 export type SecureAnswerHash = Flavor<string, "SecureAnswerHash">;
-export type QuestionSalt = Flavor<string, "QuestionSalt">;
+/**
+ * Truth-specific randomness, also called question salt sometimes.
+ */
+export type TruthSalt = Flavor<string, "TruthSalt">;
 /**
  * Truth key, found in the recovery document.
  */
@@ -150,7 +153,7 @@ async function anastasisEncrypt(
   return encodeCrock(taConcat([nonceBuf, cipherText]));
 }
 
-const asOpaque = (x: string): OpaqueData => x;
+export const asOpaque = (x: string): OpaqueData => x;
 const asEncryptedKeyShare = (x: OpaqueData): EncryptedKeyShare => x as string;
 const asEncryptedTruth = (x: OpaqueData): EncryptedTruth => x as string;
 
@@ -216,7 +219,7 @@ export async function coreSecretEncrypt(
 export async function secureAnswerHash(
   answer: string,
   truthUuid: TruthUuid,
-  questionSalt: QuestionSalt,
+  questionSalt: TruthSalt,
 ): Promise<SecureAnswerHash> {
   const powResult = await argon2id({
     hashLength: 64,
diff --git a/packages/anastasis-core/src/index.ts 
b/packages/anastasis-core/src/index.ts
index 7206f912..d8071e99 100644
--- a/packages/anastasis-core/src/index.ts
+++ b/packages/anastasis-core/src/index.ts
@@ -1,14 +1,15 @@
 import {
   AmountString,
   buildSigPS,
-  codecForGetExchangeWithdrawalInfo,
   decodeCrock,
   eddsaSign,
   encodeCrock,
   getRandomBytes,
   hash,
+  stringToBytes,
   TalerErrorCode,
   TalerSignaturePurpose,
+  Timestamp,
 } from "@gnu-taler/taler-util";
 import { anastasisData } from "./anastasis-data.js";
 import {
@@ -42,13 +43,19 @@ import {
 import fetchPonyfill from "fetch-ponyfill";
 import {
   accountKeypairDerive,
+  asOpaque,
   coreSecretEncrypt,
   encryptKeyshare,
   encryptRecoveryDocument,
   encryptTruth,
+  OpaqueData,
   PolicyKey,
   policyKeyDerive,
   PolicySalt,
+  TruthSalt,
+  secureAnswerHash,
+  TruthKey,
+  TruthUuid,
   UserIdentifier,
   userIdentifierDerive,
 } from "./crypto.js";
@@ -100,13 +107,13 @@ interface EscrowMethod {
    */
   escrow_type: string;
 
-  // UUID of the escrow method (see /truth/ API below).
+  // UUID of the escrow method.
   // 16 bytes base32-crock encoded.
-  uuid: string;
+  uuid: TruthUuid;
 
   // Key used to encrypt the Truth this EscrowMethod is related to.
   // Client has to provide this key to the server when using /truth/.
-  truth_key: string;
+  truth_key: TruthKey;
 
   // Salt used to encrypt the truth on the Anastasis server.
   salt: string;
@@ -117,11 +124,6 @@ interface EscrowMethod {
 
   // The instructions to give to the user (i.e. the security question
   // if this is challenge-response).
-  // (Q: as string in base32 encoding?)
-  // (Q: what is the mime-type of this value?)
-  //
-  // The plaintext challenge is not revealed to the
-  // Anastasis server.
   instructions: string;
 }
 
@@ -388,7 +390,28 @@ interface TruthMetaData {
   /**
    * Truth-specific salt.
    */
-  salt: string;
+  truth_salt: string;
+}
+
+async function getTruthValue(
+  authMethod: AuthMethod,
+  truthUuid: string,
+  questionSalt: TruthSalt,
+): Promise<OpaqueData> {
+  switch (authMethod.type) {
+    case "question": {
+      return asOpaque(
+        await secureAnswerHash(authMethod.challenge, truthUuid, questionSalt),
+      );
+    }
+    case "sms":
+    case "email":
+    case "totp":
+    case "iban":
+      return encodeCrock(stringToBytes(authMethod.type));
+    default:
+      throw Error("unknown auth type");
+  }
 }
 
 async function uploadSecret(
@@ -421,7 +444,7 @@ async function uploadSecret(
       const tm: TruthMetaData = {
         key_share: keyShare,
         nonce: encodeCrock(getRandomBytes(24)),
-        salt: encodeCrock(getRandomBytes(16)),
+        truth_salt: encodeCrock(getRandomBytes(16)),
         truth_key: encodeCrock(getRandomBytes(32)),
         uuid: encodeCrock(getRandomBytes(32)),
         pol_method_index: methIndex,
@@ -459,13 +482,18 @@ async function uploadSecret(
     const provider = state.authentication_providers![
       meth.provider
     ] as AuthenticationProviderStatusOk;
+    const truthValue = await getTruthValue(authMethod, tm.uuid, tm.truth_salt);
     const encryptedTruth = await encryptTruth(
       tm.nonce,
       tm.truth_key,
-      authMethod.challenge,
+      truthValue,
     );
     const uid = uidMap[meth.provider];
-    const encryptedKeyShare = await encryptKeyshare(tm.key_share, uid, 
tm.salt);
+    const encryptedKeyShare = await encryptKeyshare(
+      tm.key_share,
+      uid,
+      tm.truth_salt,
+    );
     console.log(
       "encrypted key share len",
       decodeCrock(encryptedKeyShare).length,
@@ -496,7 +524,7 @@ async function uploadSecret(
       escrow_type: authMethod.type,
       instructions: authMethod.instructions,
       provider_salt: provider.salt,
-      salt: tm.salt,
+      salt: tm.truth_salt,
       truth_key: tm.truth_key,
       url: meth.provider,
       uuid: tm.uuid,
@@ -549,14 +577,19 @@ async function uploadSecret(
       };
     }
     let policyVersion = 0;
-    console.log(resp);
-    console.log(resp.headers);
-    console.log(resp.headers.get("Anastasis-Version"));
+    let policyExpiration: Timestamp = { t_ms: 0 };
     try {
       policyVersion = Number(resp.headers.get("Anastasis-Version") ?? "0");
     } catch (e) {}
+    try {
+      policyExpiration = {
+        t_ms:
+          1000 * Number(resp.headers.get("Anastasis-Policy-Expiration") ?? 
"0"),
+      };
+    } catch (e) {}
     successDetails[prov.provider_url] = {
       policy_version: policyVersion,
+      policy_expiration: policyExpiration,
     };
   }
 
diff --git a/packages/anastasis-core/src/reducer-types.ts 
b/packages/anastasis-core/src/reducer-types.ts
index 1f4a2abe..92b1c532 100644
--- a/packages/anastasis-core/src/reducer-types.ts
+++ b/packages/anastasis-core/src/reducer-types.ts
@@ -1,4 +1,4 @@
-import { Duration } from "@gnu-taler/taler-util";
+import { Duration, Timestamp } from "@gnu-taler/taler-util";
 
 export type ReducerState =
   | ReducerStateBackup
@@ -30,6 +30,7 @@ export interface PolicyProvider {
 export interface SuccessDetails {
   [provider_url: string]: {
     policy_version: number;
+    policy_expiration: Timestamp;
   };
 }
 

-- 
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]