aboutsummaryrefslogtreecommitdiff
path: root/packages/exchange-backoffice-ui/src/pages/Officer.tsx
blob: c72ca0720555927a2e9f6ea0374c20bbbdd0f6c4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import { useLocalStorage } from "@gnu-taler/web-util/browser";
import { h } from "preact";
import { useEffect, useState } from "preact/hooks";

const oldKey =
  "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDPQVq8F0Ce6kTXKQ5Ea2fZRoap6poFYs0FOln8o8+ehGI8rDdMBzNU3pLIlOMKs/vKvhDNMG4m4xxb92wDbvefDxkxaEkbRSZnRiJd4MIbh8Lx8zvFbLp03rkXu9KPN8IprKOXxgN7xbxm0KKcu03rtqLiOvC1gMqja2LMIPCi32nyNneduszHZ57d+CqIKZdVnaqAcXOSMAQsVoEq2joBOeIaSAnIJHg+T8HQ+VcLV8Y722jhX/bH84IyEMup9e7mhgVFnHgINc77c6TONH8H+dHlXCQ+hMPGw9wM+wgpJgIDzrhIN+QSjn283EOXD6z6dpiWBdEYfJRLHwEWk8wNAgMBAAECggEAB/anZrMasQsoXP9qBG1Uvq+r4fXZODFtK5vBNGi+RAWAhCX2iU3SMPB3wbby0wj1DlESR91qBhrTjqG+/TzIzUxLuARyoVZysiTVkjeIzdJVcRgwU5bTbUUs5da6MaA/WNGWMZvoALFUMBEpMQ4uDCC8OSbG8/prDtoZSuWjHrxBhsqSyIoJ3Q0iPQxPT0ShC9d5T56QuhsRQeRIWhQVtFlytXl1lqEbqljhIEOzkvS5QOcXcS3OBo/Nvdit+vi9kkLuiP8z2p6WAiVZCgCXfffNH3EEbQG/BEpIOynkchiDy1L31mFRFk1oYJRs9xD8+oF/N75GhlmYO7IbxeHw0wKBgQDnYZWjGlRM2oHpeiPSII5m9rC7qohO0ImxqifYZPp47vdRMbBWrdbxX68SqdzGfSzXcDPLfBAObG4QR8Xol1LMNJUT9og9pERZHgob+yWkTd68lLSdxfCJEKRJaDmD8dHgSrBYe86ADUeAj+fC4dycYXH//fwed1gt/G8iXtdU9wKBgQDlTp9752+tEh9fMlUdINbZXmGbjHBrZMTnAYJI509iJLIvJvYroU5TvRMsp+rACDc2Zy2nbsaCM5Xzd5wUxRBvF+PiBCFoi7c/EBaLCtb9+vyXtHAIHtzHeYUP/1cq7MOdTwrWvZqzIoW6xm7L9HRX/5i+n+rVUSxnzYIxgTlaGwKBgQC0INgpXbn7CrDQXnG8h/PUXIBB2QS8tsQ7N8hFQndr5j1LTG+HS1ZmGqNk2DAzpgdewM7RvweQ8wDMU9PSutuOdfEI1YhC1LsQ1b3xApfPTX/1N59UpGAZlIcRTr5X5c4J2ptmhxu/vJbJkz5ODR997q6dJ9E6tpZDVp3+F+9zCQKBgQCrp+OzuVjcUoixltgoagDrz7951fQCMPlFhNenA6FlctsAeUYm+yXLgersrvcIsh3C2BJRGJf5t+w0ygFJewwGXff1pensfUq8Jqr5gy/WCSE135lOOuxDVzDI/Pif5YW6KQWQI3e/ScSaQRmIDINbrLcHXGdLMOzw9+LSdE4eqQKBgQDe86MfzwMLPoDH07WC09dCcoIUSYMThYrFwUK3qgEiYaJMZJvdAIwr12szVwVRYIX4wHBObFsQZLTaY5+O/REnze6Q1AQa2H6eH1TalC1r6jBS5/LhIrVWl/0VSdsUIe41tc8xPDWrm9hmLeJLZk+xb5/hAm3REsDM1Iif9O7zzg==";
export function Officer() {
  const storage = useLocalStorage("officer");
  const [keys, setKeys] = useState({ priv: "", pub: "" });
  useEffect(() => {
    loadPreviousSession(oldKey).then((keys) =>
      setKeys(keys ?? { priv: "", pub: "" }),
    );
    // generateNewId().then((keys) => setKeys(keys));
  }, []);

  console.log(keys.pub);
  console.log(keys.priv);
  return (
    <div>
      <div>Officer</div>
      <h1 class="my-2 text-3xl font-bold tracking-tight text-gray-900 ">
        Public key
      </h1>
      <div>
        -----BEGIN PUBLIC KEY-----
        <p class="mt-6 leading-8 text-gray-700 break-all">{keys.pub}</p>
        -----END PUBLIC KEY-----
      </div>
      <h1 class="my-2 text-3xl font-bold tracking-tight text-gray-900 ">
        Private key
      </h1>
      <div>
        -----BEGIN PRIVATE KEY-----
        <p class="mt-6 leading-8 text-gray-700 break-all">{keys.priv}</p>
        -----END PRIVATE KEY-----
      </div>
    </div>
  );
}

const rsaAlgorithm: RsaHashedKeyGenParams = {
  name: "RSA-OAEP",
  modulusLength: 2048,
  publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
  hash: "SHA-256",
};

async function generateNewId() {
  const key = await crypto.subtle.generateKey(rsaAlgorithm, true, [
    "encrypt",
    "decrypt",
  ]);

  if (key instanceof CryptoKey) {
    throw Error("unexpected key without pair");
  }
  const { privateKey, publicKey } = key;
  const privRaw = await crypto.subtle.exportKey("pkcs8", privateKey);

  const pubRaw = await crypto.subtle.exportKey("spki", publicKey);

  const priv = btoa(ab2str(privRaw));

  const pub = btoa(ab2str(pubRaw));
  return { priv, pub };
}

async function loadPreviousSession(priv: string) {
  const key = str2ab(window.atob(priv));
  const privateKey = await window.crypto.subtle
    .importKey("pkcs8", key, rsaAlgorithm, true, ["decrypt"])
    .catch(throwErrorWithStack);

  if (!privateKey) return undefined;

  // export private key to JWK
  const jwk = await crypto.subtle
    .exportKey("jwk", privateKey)
    .catch(throwErrorWithStack);

  // remove private data from JWK
  delete jwk.d;
  delete jwk.dp;
  delete jwk.dq;
  delete jwk.q;
  delete jwk.qi;
  jwk.key_ops = ["encrypt"];

  const publicKey = await crypto.subtle
    .importKey("jwk", jwk, rsaAlgorithm, true, ["encrypt"])
    .catch(throwErrorWithStack);

  const pubRaw = await crypto.subtle
    .exportKey("spki", publicKey)
    .catch(throwErrorWithStack);

  const pub = btoa(ab2str(pubRaw));

  return { priv, pub };
}

function ab2str(buf: ArrayBuffer) {
  return String.fromCharCode.apply(null, Array.from(new Uint8Array(buf)));
}
function str2ab(str: string) {
  const buf = new ArrayBuffer(str.length);
  const bufView = new Uint8Array(buf);
  for (let i = 0, strLen = str.length; i < strLen; i++) {
    bufView[i] = str.charCodeAt(i);
  }
  return buf;
}
function throwErrorWithStack(e: Error): never {
  throw new Error(e.message);
}