summaryrefslogtreecommitdiff
path: root/packages/anastasis-core
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2021-10-18 21:48:22 +0200
committerFlorian Dold <florian@dold.me>2021-10-18 21:48:45 +0200
commit269022a526b670d602ca146f4df02850983bb72e (patch)
treee0a66e8b15ef305c99274c76964a119d0d9512ba /packages/anastasis-core
parent3a69f27412782872c1264e8a4dd1be13d57a8a80 (diff)
downloadwallet-core-269022a526b670d602ca146f4df02850983bb72e.tar.gz
wallet-core-269022a526b670d602ca146f4df02850983bb72e.tar.bz2
wallet-core-269022a526b670d602ca146f4df02850983bb72e.zip
move some more crypto to taler-util package
Diffstat (limited to 'packages/anastasis-core')
-rw-r--r--packages/anastasis-core/src/crypto.ts41
-rw-r--r--packages/anastasis-core/src/index.ts15
2 files changed, 55 insertions, 1 deletions
diff --git a/packages/anastasis-core/src/crypto.ts b/packages/anastasis-core/src/crypto.ts
index 5da3a4cce..32cf470c4 100644
--- a/packages/anastasis-core/src/crypto.ts
+++ b/packages/anastasis-core/src/crypto.ts
@@ -5,7 +5,9 @@ import {
encodeCrock,
getRandomBytes,
kdf,
+ kdfKw,
secretbox,
+ crypto_sign_keyPair_fromSeed,
stringToBytes,
} from "@gnu-taler/taler-util";
import { argon2id } from "hash-wasm";
@@ -25,6 +27,8 @@ export type EncryptedKeyShare = Flavor<string, "EncryptedKeyShare">;
export type EncryptedTruth = Flavor<string, "EncryptedTruth">;
export type EncryptedCoreSecret = Flavor<string, "EncryptedCoreSecret">;
export type EncryptedMasterKey = Flavor<string, "EncryptedMasterKey">;
+export type EddsaPublicKey = Flavor<string, "EddsaPublicKey">;
+export type EddsaPrivateKey = Flavor<string, "EddsaPrivateKey">;
/**
* Truth key, found in the recovery document.
*/
@@ -53,6 +57,43 @@ export async function userIdentifierDerive(
return encodeCrock(result);
}
+export interface AccountKeyPair {
+ priv: EddsaPrivateKey;
+ pub: EddsaPublicKey;
+}
+
+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),
+ });
+ // 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),
+ pub: encodeCrock(pair.publicKey),
+ };
+}
+
+export async function encryptRecoveryDocument(
+ userId: UserIdentifier,
+ recoveryDoc: any,
+): Promise<OpaqueData> {
+ const plaintext = stringToBytes(JSON.stringify(recoveryDoc));
+ const nonce = encodeCrock(getRandomBytes(nonceSize));
+ return anastasisEncrypt(
+ nonce,
+ asOpaque(userId),
+ encodeCrock(plaintext),
+ "erd",
+ );
+}
+
function taConcat(chunks: Uint8Array[]): Uint8Array {
let payloadLen = 0;
for (const c of chunks) {
diff --git a/packages/anastasis-core/src/index.ts b/packages/anastasis-core/src/index.ts
index f33a0be46..8921433b7 100644
--- a/packages/anastasis-core/src/index.ts
+++ b/packages/anastasis-core/src/index.ts
@@ -36,8 +36,10 @@ import {
} from "./reducer-types.js";
import fetchPonyfill from "fetch-ponyfill";
import {
+ accountKeypairDerive,
coreSecretEncrypt,
encryptKeyshare,
+ encryptRecoveryDocument,
encryptTruth,
PolicyKey,
policyKeyDerive,
@@ -492,14 +494,25 @@ async function uploadSecret(
policies: policies.map((x, i) => {
return {
master_key: csr.encMasterKeys[i],
+ // FIXME: ...
uuid: [],
- salt:
+ salt: undefined as any,
};
}),
};
for (const prov of state.policy_providers!) {
+ const uid = uidMap[prov.provider_url]
+ const acctKeypair = accountKeypairDerive(uid);
+ const encRecoveryDoc = await encryptRecoveryDocument(uid, rd);
// FIXME: Upload recovery document.
+ const resp = await fetch(
+ new URL(`policy/${acctKeypair.pub}`, prov.provider_url).href,
+ {
+ method: "POST",
+ body: decodeCrock(encRecoveryDoc),
+ },
+ );
}
return {