215 lines
3.1 MiB
HTML
215 lines
3.1 MiB
HTML
|
<!DOCTYPE html>
|
||
|
<html lang="en" id="top">
|
||
|
<head>
|
||
|
<meta charset="UTF-8">
|
||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
|
<title>Communicating with Burgerauth...</title>
|
||
|
<style>
|
||
|
:root {
|
||
|
--border-color: #dadada;
|
||
|
--inoutdiv: #fafafa;
|
||
|
--text-color: #000000;
|
||
|
}
|
||
|
|
||
|
@media (prefers-color-scheme: dark) {
|
||
|
:root {
|
||
|
--border-color: #393b3d;
|
||
|
--text-color: #ffffff;
|
||
|
--inoutdiv: #2d2f31;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
body {
|
||
|
font-family: sans-serif;
|
||
|
}
|
||
|
|
||
|
.bg {
|
||
|
position: fixed;
|
||
|
z-index: -2;
|
||
|
top: 0;
|
||
|
left: 0;
|
||
|
width: 100%;
|
||
|
height: 100%;
|
||
|
object-fit: cover;
|
||
|
}
|
||
|
|
||
|
.inoutdiv {
|
||
|
border-radius: 8px;
|
||
|
margin: 10%;
|
||
|
padding: 30px;
|
||
|
border: solid 1px var(--border-color);
|
||
|
background-color: var(--inoutdiv);
|
||
|
color: var(--text-color);
|
||
|
}
|
||
|
|
||
|
p {
|
||
|
font-size: 15px;
|
||
|
}
|
||
|
|
||
|
h2 {
|
||
|
font-weight: 300;
|
||
|
}
|
||
|
</style>
|
||
|
<script>
|
||
|
/*
|
||
|
* Comment-removed and slightly simplified (nodeJS-specific calls and +0s removed) version of:
|
||
|
* js-xxhash (https://www.npmjs.com/package/js-xxhash)
|
||
|
* (c) Jason Dent (Jason3S)
|
||
|
* @license MIT
|
||
|
*/
|
||
|
|
||
|
"use strict";
|
||
|
const PRIME32_1 = 2654435761;
|
||
|
const PRIME32_2 = 2246822519;
|
||
|
const PRIME32_3 = 3266489917;
|
||
|
const PRIME32_4 = 668265263;
|
||
|
const PRIME32_5 = 374761393;
|
||
|
let encoder;
|
||
|
function xxHash32(input, seed = 0) {
|
||
|
const buffer = typeof input === 'string' ? (encoder ??= new TextEncoder()).encode(input) : input;
|
||
|
const b = buffer;
|
||
|
let acc = (seed + PRIME32_5) & 0xffffffff;
|
||
|
let offset = 0;
|
||
|
if (b.length >= 16) {
|
||
|
const accN = [
|
||
|
(seed + PRIME32_1 + PRIME32_2) & 0xffffffff,
|
||
|
(seed + PRIME32_2) & 0xffffffff,
|
||
|
(seed) & 0xffffffff,
|
||
|
(seed - PRIME32_1) & 0xffffffff,
|
||
|
];
|
||
|
const b = buffer;
|
||
|
const limit = b.length - 16;
|
||
|
let lane = 0;
|
||
|
for (offset = 0; (offset & 0xfffffff0) <= limit; offset += 4) {
|
||
|
const i = offset;
|
||
|
const laneN0 = b[i] + (b[i + 1] << 8);
|
||
|
const laneN1 = b[i + 2] + (b[i + 3] << 8);
|
||
|
const laneNP = laneN0 * PRIME32_2 + ((laneN1 * PRIME32_2) << 16);
|
||
|
let acc = (accN[lane] + laneNP) & 0xffffffff;
|
||
|
acc = (acc << 13) | (acc >>> 19);
|
||
|
const acc0 = acc & 0xffff;
|
||
|
const acc1 = acc >>> 16;
|
||
|
accN[lane] = (acc0 * PRIME32_1 + ((acc1 * PRIME32_1) << 16)) & 0xffffffff;
|
||
|
lane = (lane + 1) & 0x3;
|
||
|
}
|
||
|
acc =
|
||
|
(((accN[0] << 1) | (accN[0] >>> 31)) +
|
||
|
((accN[1] << 7) | (accN[1] >>> 25)) +
|
||
|
((accN[2] << 12) | (accN[2] >>> 20)) +
|
||
|
((accN[3] << 18) | (accN[3] >>> 14))) &
|
||
|
0xffffffff;
|
||
|
}
|
||
|
acc = (acc + buffer.length) & 0xffffffff;
|
||
|
const limit = buffer.length - 4;
|
||
|
for (; offset <= limit; offset += 4) {
|
||
|
const i = offset;
|
||
|
const laneN0 = b[i] + (b[i + 1] << 8);
|
||
|
const laneN1 = b[i + 2] + (b[i + 3] << 8);
|
||
|
const laneP = laneN0 * PRIME32_3 + ((laneN1 * PRIME32_3) << 16);
|
||
|
acc = (acc + laneP) & 0xffffffff;
|
||
|
acc = (acc << 17) | (acc >>> 15);
|
||
|
acc = ((acc & 0xffff) * PRIME32_4 + (((acc >>> 16) * PRIME32_4) << 16)) & 0xffffffff;
|
||
|
}
|
||
|
for (; offset < b.length; ++offset) {
|
||
|
const lane = b[offset];
|
||
|
acc = acc + lane * PRIME32_5;
|
||
|
acc = (acc << 11) | (acc >>> 21);
|
||
|
acc = ((acc & 0xffff) * PRIME32_1 + (((acc >>> 16) * PRIME32_1) << 16)) & 0xffffffff;
|
||
|
}
|
||
|
acc = acc ^ (acc >>> 15);
|
||
|
acc = (((acc & 0xffff) * PRIME32_2) & 0xffffffff) + (((acc >>> 16) * PRIME32_2) << 16);
|
||
|
acc = acc ^ (acc >>> 13);
|
||
|
acc = (((acc & 0xffff) * PRIME32_3) & 0xffffffff) + (((acc >>> 16) * PRIME32_3) << 16);
|
||
|
acc = acc ^ (acc >>> 16);
|
||
|
return acc < 0 ? acc + 4294967296 : acc;
|
||
|
}
|
||
|
</script>
|
||
|
<script>
|
||
|
function saveArrayBufferToLocalStorage(key, buffer) {
|
||
|
const base64String = arrayBufferToBase64(buffer);
|
||
|
localStorage.setItem(key, base64String);
|
||
|
}
|
||
|
|
||
|
function getArrayBufferFromLocalStorage(key) {
|
||
|
const base64String = localStorage.getItem(key);
|
||
|
if (base64String) {
|
||
|
return base64ToArrayBuffer(base64String);
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
function arrayBufferToBase64(buffer) {
|
||
|
const uint8Array = new Uint8Array(buffer);
|
||
|
return btoa(String.fromCharCode.apply(null, uint8Array)).replace(/\+/g, '~').replace(/\//g, '_').replace(/=+$/, '');
|
||
|
}
|
||
|
|
||
|
function base64ToArrayBuffer(base64) {
|
||
|
const binaryString = atob(base64.replace(/_/g, '/').replace(/~/g, '+'));
|
||
|
const length = binaryString.length;
|
||
|
const buffer = new ArrayBuffer(length);
|
||
|
const uint8Array = new Uint8Array(buffer);
|
||
|
for (let i = 0; i < length; i++) {
|
||
|
uint8Array[i] = binaryString.charCodeAt(i);
|
||
|
}
|
||
|
return buffer;
|
||
|
}
|
||
|
|
||
|
function generateKeyPair() {
|
||
|
return window.crypto.subtle.generateKey(
|
||
|
{
|
||
|
name: "RSA-OAEP",
|
||
|
modulusLength: 4096,
|
||
|
publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
|
||
|
hash: {name: "SHA-512"}
|
||
|
},
|
||
|
true,
|
||
|
["encrypt", "decrypt"]
|
||
|
);
|
||
|
}
|
||
|
|
||
|
async function main() {
|
||
|
document.getElementById("pagehash").innerText = "This page's hash is " + btoa(xxHash32(document.getElementById("top").outerHTML).toString())
|
||
|
|
||
|
const urlParams = new URLSearchParams(window.location.search);
|
||
|
const encodedData = urlParams.get('encoded');
|
||
|
const doNothing = urlParams.get('donothing');
|
||
|
let keyShareUri = "https://auth.hectabit.org/aeskeyshare"
|
||
|
if (localStorage.getItem("keyShareUri") !== null) {
|
||
|
keyShareUri = localStorage.getItem("keyShareUri")
|
||
|
}
|
||
|
if (doNothing !== "true") {
|
||
|
if (encodedData) {
|
||
|
const decodedData = base64ToArrayBuffer(encodedData);
|
||
|
const decryptedData = window.crypto.subtle.decrypt(
|
||
|
{
|
||
|
name: "RSA-OAEP"
|
||
|
},
|
||
|
await crypto.subtle.importKey("pkcs8", getArrayBufferFromLocalStorage("key"), {
|
||
|
name: "RSA-OAEP",
|
||
|
hash: {name: "SHA-512"}
|
||
|
}, true, ["decrypt"]),
|
||
|
decodedData
|
||
|
);
|
||
|
localStorage.setItem("DONOTSHARE-secretkey", new TextDecoder().decode(await decryptedData));
|
||
|
} else {
|
||
|
let keyPair = await generateKeyPair();
|
||
|
saveArrayBufferToLocalStorage("key", await crypto.subtle.exportKey("pkcs8", keyPair.privateKey));
|
||
|
window.location.replace(keyShareUri + "?pubkey=" + btoa(String.fromCharCode.apply(null, new Uint8Array(await crypto.subtle.exportKey("spki", keyPair.publicKey)))).replace(/\+/g, '~').replace(/\//g, '_').replace(/=+$/, '') + "&token=" + localStorage.getItem("BURGERAUTH-RDIR-TOKEN"));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
window.onload = main;
|
||
|
</script>
|
||
|
</head>
|
||
|
<body>
|
||
|
<img src="data:image/png;base64, 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
|
||
|
<div class="inoutdiv">
|
||
|
<h2>Communicating with Burgerauth, please wait...</h2>
|
||
|
<p>This page may have inconsistant styling due to an older version of the Burgerauth protocol. The current version is b1.0.0</p>
|
||
|
<p id="pagehash">This page's hash is loading...</p>
|
||
|
</div>
|
||
|
</body>
|
||
|
</html>
|
||
|
|