gnunet-svn
[Top][All Lists]
Advanced

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

[taler-wallet-core] 02/03: anastasis-core: support pin-type answers


From: gnunet
Subject: [taler-wallet-core] 02/03: anastasis-core: support pin-type answers
Date: Thu, 04 Nov 2021 17:03:02 +0100

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

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

commit 6d6679e33849d551b9da07d5058dc09c474c66b7
Author: Florian Dold <florian@dold.me>
AuthorDate: Thu Nov 4 16:53:04 2021 +0100

    anastasis-core: support pin-type answers
---
 packages/anastasis-core/src/crypto.ts              |  5 ++
 packages/anastasis-core/src/index.ts               | 68 ++++++++++++++++++----
 .../anastasis-core/src/recovery-document-types.ts  | 13 ++++-
 packages/anastasis-core/src/reducer-types.ts       | 36 +++++++++++-
 4 files changed, 106 insertions(+), 16 deletions(-)

diff --git a/packages/anastasis-core/src/crypto.ts 
b/packages/anastasis-core/src/crypto.ts
index da833863..9689e4f2 100644
--- a/packages/anastasis-core/src/crypto.ts
+++ b/packages/anastasis-core/src/crypto.ts
@@ -10,6 +10,7 @@ import {
   crypto_sign_keyPair_fromSeed,
   stringToBytes,
   secretbox_open,
+  hash,
 } from "@gnu-taler/taler-util";
 import { gzipSync } from "fflate";
 import { argon2id } from "hash-wasm";
@@ -283,6 +284,10 @@ export async function coreSecretEncrypt(
   };
 }
 
+export async function pinAnswerHash(pin: number): Promise<SecureAnswerHash> {
+  return encodeCrock(hash(stringToBytes(pin.toString())));
+}
+
 export async function secureAnswerHash(
   answer: string,
   truthUuid: TruthUuid,
diff --git a/packages/anastasis-core/src/index.ts 
b/packages/anastasis-core/src/index.ts
index fd04eb4d..4c8ac0d3 100644
--- a/packages/anastasis-core/src/index.ts
+++ b/packages/anastasis-core/src/index.ts
@@ -86,11 +86,19 @@ import {
   decryptKeyShare,
   KeyShare,
   coreSecretRecover,
+  pinAnswerHash,
 } from "./crypto.js";
 import { unzlibSync, zlibSync } from "fflate";
-import { EscrowMethod, RecoveryDocument } from "./recovery-document-types.js";
+import {
+  ChallengeType,
+  EscrowMethod,
+  RecoveryDocument,
+} from "./recovery-document-types.js";
 import { ProviderInfo, suggestPolicies } from "./policy-suggestion.js";
-import { ChallengeFeedback, ChallengeFeedbackStatus } from 
"./challenge-feedback-types.js";
+import {
+  ChallengeFeedback,
+  ChallengeFeedbackStatus,
+} from "./challenge-feedback-types.js";
 
 const { fetch } = fetchPonyfill({});
 
@@ -473,7 +481,7 @@ async function uploadSecret(
     }
 
     escrowMethods.push({
-      escrow_type: authMethod.type,
+      escrow_type: authMethod.type as any,
       instructions: authMethod.instructions,
       provider_salt: provider.salt,
       truth_salt: tm.truth_salt,
@@ -697,11 +705,43 @@ async function requestTruth(
   const url = new URL(`/truth/${truth.uuid}`, truth.url);
 
   if (solveRequest) {
-    // FIXME: This isn't correct for non-question truth responses.
-    url.searchParams.set(
-      "response",
-      await secureAnswerHash(solveRequest.answer, truth.uuid, 
truth.truth_salt),
-    );
+    let respHash: string;
+    switch (truth.escrow_type) {
+      case ChallengeType.Question:
+        if ("answer" in solveRequest) {
+          respHash = await secureAnswerHash(
+            solveRequest.answer,
+            truth.uuid,
+            truth.truth_salt,
+          );
+        } else {
+          throw Error("unsupported answer request");
+        }
+        break;
+      case ChallengeType.Email:
+      case ChallengeType.Sms:
+      case ChallengeType.Post:
+      case ChallengeType.Totp: {
+        if ("answer" in solveRequest) {
+          const s = solveRequest.answer.trim().replace(/^A-/, "");
+          let pin: number;
+          try {
+            pin = Number.parseInt(s);
+          } catch (e) {
+            throw Error("invalid pin format");
+          }
+          respHash = await pinAnswerHash(pin);
+        } else if ("pin" in solveRequest) {
+          respHash = await pinAnswerHash(solveRequest.pin);
+        } else {
+          throw Error("unsupported answer request");
+        }
+        break;
+      }
+      default:
+        throw Error("unsupported challenge type");
+    }
+    url.searchParams.set("response", respHash);
   }
 
   const resp = await fetch(url.href, {
@@ -711,10 +751,14 @@ async function requestTruth(
   });
 
   if (resp.status === HttpStatusCode.Ok) {
-    const answerSalt =
-      solveRequest && truth.escrow_type === "question"
-        ? solveRequest.answer
-        : undefined;
+    let answerSalt: string | undefined = undefined;
+    if (
+      solveRequest &&
+      truth.escrow_type === "question" &&
+      "answer" in solveRequest
+    ) {
+      answerSalt = solveRequest.answer;
+    }
 
     const userId = await userIdentifierDerive(
       state.identity_attributes,
diff --git a/packages/anastasis-core/src/recovery-document-types.ts 
b/packages/anastasis-core/src/recovery-document-types.ts
index 74003ccb..3dc4481f 100644
--- a/packages/anastasis-core/src/recovery-document-types.ts
+++ b/packages/anastasis-core/src/recovery-document-types.ts
@@ -1,5 +1,14 @@
 import { TruthKey, TruthSalt, TruthUuid } from "./crypto.js";
 
+export enum ChallengeType {
+  Question = "question",
+  Sms = "sms",
+  Email = "email",
+  Post = "post",
+  Totp = "totp",
+  Iban = "iban",
+}
+
 export interface RecoveryDocument {
   /**
    * Human-readable name of the secret
@@ -9,7 +18,7 @@ export interface RecoveryDocument {
 
   /**
    * Encrypted core secret.
-   * 
+   *
    * Variable-size length, base32-crock encoded.
    */
   encrypted_core_secret: string;
@@ -56,7 +65,7 @@ export interface EscrowMethod {
   /**
    * Type of the escrow method (e.g. security question, SMS etc.).
    */
-  escrow_type: string;
+  escrow_type: ChallengeType;
 
   /**
    * UUID of the escrow method.
diff --git a/packages/anastasis-core/src/reducer-types.ts 
b/packages/anastasis-core/src/reducer-types.ts
index e0d311e8..19f7d431 100644
--- a/packages/anastasis-core/src/reducer-types.ts
+++ b/packages/anastasis-core/src/reducer-types.ts
@@ -312,12 +312,44 @@ export interface ActionArgsSelectChallenge {
   uuid: string;
 }
 
-export type ActionArgsSolveChallengeRequest = SolveChallengeAnswerRequest;
-
+export type ActionArgsSolveChallengeRequest =
+  | SolveChallengeAnswerRequest
+  | SolveChallengePinRequest
+  | SolveChallengeHashRequest;
+
+/**
+ * Answer to a challenge.
+ *
+ * For "question" challenges, this is a string with the answer.
+ *
+ * For "sms" / "email" / "post" this is a numeric code with optionally
+ * the "A-" prefix.
+ */
 export interface SolveChallengeAnswerRequest {
   answer: string;
 }
 
+/**
+ * Answer to a challenge that requires a numeric response.
+ *
+ * XXX: Should be deprecated in favor of just "answer".
+ */
+export interface SolveChallengePinRequest {
+  pin: number;
+}
+
+/**
+ * Answer to a challenge by directly providing the hash.
+ *
+ * XXX: When / why is this even used?
+ */
+ export interface SolveChallengeHashRequest {
+  /**
+   * Base32-crock encoded hash code.
+   */
+  hash: string;
+}
+
 export interface PolicyMember {
   authentication_method: number;
   provider: string;

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