diff options
author | Florian Dold <florian@dold.me> | 2021-11-04 16:53:04 +0100 |
---|---|---|
committer | Florian Dold <florian@dold.me> | 2021-11-04 16:53:11 +0100 |
commit | 6d6679e33849d551b9da07d5058dc09c474c66b7 (patch) | |
tree | 192410793b30057a0c52612f513c007ecabbfacc /packages/anastasis-core/src/index.ts | |
parent | 83622bd65a0ebd7c22555fb2cfdb542e20d044b9 (diff) | |
download | wallet-core-6d6679e33849d551b9da07d5058dc09c474c66b7.tar.xz |
anastasis-core: support pin-type answers
Diffstat (limited to 'packages/anastasis-core/src/index.ts')
-rw-r--r-- | packages/anastasis-core/src/index.ts | 68 |
1 files changed, 56 insertions, 12 deletions
diff --git a/packages/anastasis-core/src/index.ts b/packages/anastasis-core/src/index.ts index fd04eb4d7..4c8ac0d31 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, |