diff options
Diffstat (limited to 'packages/exchange-backoffice-ui/src/pages/Officer.tsx')
-rw-r--r-- | packages/exchange-backoffice-ui/src/pages/Officer.tsx | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/packages/exchange-backoffice-ui/src/pages/Officer.tsx b/packages/exchange-backoffice-ui/src/pages/Officer.tsx new file mode 100644 index 000000000..c72ca0720 --- /dev/null +++ b/packages/exchange-backoffice-ui/src/pages/Officer.tsx @@ -0,0 +1,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); +} |