feat: add encrypted communication mechanism to the kernel for the private key
This commit is contained in:
parent
6f4b9b7a4a
commit
cbc864c950
|
@ -31,8 +31,10 @@
|
||||||
"@lumeweb/libresolver": "^0.1.0-develop.1",
|
"@lumeweb/libresolver": "^0.1.0-develop.1",
|
||||||
"@lumeweb/libweb": "^0.2.0-develop.22",
|
"@lumeweb/libweb": "^0.2.0-develop.22",
|
||||||
"@lumeweb/tld-enum": "^0.1.0-develop.1",
|
"@lumeweb/tld-enum": "^0.1.0-develop.1",
|
||||||
|
"@noble/ciphers": "^0.1.4",
|
||||||
"@peculiar/webcrypto": "^1.4.3",
|
"@peculiar/webcrypto": "^1.4.3",
|
||||||
"@scure/bip39": "^1.2.1",
|
"@scure/bip39": "^1.2.1",
|
||||||
|
"ed25519-keygen": "^0.4.1",
|
||||||
"ejs": "^3.1.9",
|
"ejs": "^3.1.9",
|
||||||
"file-type": "^18.5.0",
|
"file-type": "^18.5.0",
|
||||||
"is-ipfs": "^8.0.1",
|
"is-ipfs": "^8.0.1",
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
import { bytesToHex, hexToBytes } from "@lumeweb/libweb";
|
||||||
|
import {
|
||||||
|
getCommunicationPubKey,
|
||||||
|
setFrontendCommunicationPubkey,
|
||||||
|
} from "../vars.js";
|
||||||
|
import { log } from "../util.js";
|
||||||
|
|
||||||
|
export default function (data: any) {
|
||||||
|
setFrontendCommunicationPubkey(hexToBytes(data));
|
||||||
|
|
||||||
|
return bytesToHex(getCommunicationPubKey());
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
import { secretbox } from "@noble/ciphers/salsa";
|
||||||
|
import { x25519 } from "@noble/curves/ed25519";
|
||||||
|
import {
|
||||||
|
getCommunicationKey,
|
||||||
|
getFrontendCommunicationPubkey,
|
||||||
|
setLoginComplete,
|
||||||
|
} from "../vars.js";
|
||||||
|
import { saveUserKey } from "../storage.js";
|
||||||
|
import { hexToBytes } from "@lumeweb/libweb";
|
||||||
|
|
||||||
|
export default function (data: any) {
|
||||||
|
const box = secretbox(
|
||||||
|
x25519.getSharedSecret(
|
||||||
|
getCommunicationKey(),
|
||||||
|
getFrontendCommunicationPubkey(),
|
||||||
|
),
|
||||||
|
hexToBytes(data.nonce),
|
||||||
|
);
|
||||||
|
const decryptedData = box.open(hexToBytes(data.data));
|
||||||
|
|
||||||
|
setLoginComplete(false);
|
||||||
|
|
||||||
|
saveUserKey(decryptedData);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -1,9 +1,12 @@
|
||||||
import { Client } from "@lumeweb/libportal";
|
import { Client } from "@lumeweb/libportal";
|
||||||
|
import { x25519 } from "@noble/curves/ed25519";
|
||||||
|
|
||||||
let loginComplete = false;
|
let loginComplete = false;
|
||||||
let logoutComplete = false;
|
let logoutComplete = false;
|
||||||
let kernelLoaded = "not yet";
|
let kernelLoaded = "not yet";
|
||||||
let bootloaderPortals: Client[] = [];
|
let bootloaderPortals: Client[] = [];
|
||||||
|
let communicationKey: Uint8Array;
|
||||||
|
let frontendCommunicationPubKey: Uint8Array;
|
||||||
|
|
||||||
var userKey: Uint8Array;
|
var userKey: Uint8Array;
|
||||||
|
|
||||||
|
@ -39,3 +42,23 @@ export function getUserKey() {
|
||||||
export function setBootloaderPortals(portals: Client[]) {
|
export function setBootloaderPortals(portals: Client[]) {
|
||||||
bootloaderPortals = portals;
|
bootloaderPortals = portals;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getCommunicationKey() {
|
||||||
|
if (!communicationKey) {
|
||||||
|
communicationKey = x25519.utils.randomPrivateKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
return communicationKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getCommunicationPubKey() {
|
||||||
|
return x25519.getPublicKey(getCommunicationKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getFrontendCommunicationPubkey() {
|
||||||
|
return frontendCommunicationPubKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setFrontendCommunicationPubkey(key: Uint8Array) {
|
||||||
|
frontendCommunicationPubKey = key;
|
||||||
|
}
|
||||||
|
|
|
@ -1,11 +1,22 @@
|
||||||
<script>
|
<script>
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
|
|
||||||
import * as bip39 from '@scure/bip39';
|
import * as bip39 from "@scure/bip39";
|
||||||
import { wordlist } from '@scure/bip39/wordlists/english';
|
import { wordlist } from "@scure/bip39/wordlists/english";
|
||||||
|
import browser from "webextension-polyfill";
|
||||||
|
|
||||||
import '../../styles/global.scss';
|
import "../../styles/global.scss";
|
||||||
import lumeLogo from '../../assets/lume-logo.png';
|
import lumeLogo from "../../assets/lume-logo.png";
|
||||||
|
import {
|
||||||
|
bytesToHex,
|
||||||
|
ed25519,
|
||||||
|
hexToBytes,
|
||||||
|
randomBytes,
|
||||||
|
} from "@lumeweb/libweb";
|
||||||
|
import { x25519 } from "@noble/curves/ed25519";
|
||||||
|
import { secretbox } from "@noble/ciphers/salsa";
|
||||||
|
import { HDKey } from "ed25519-keygen/hdkey";
|
||||||
|
const BIP44_PATH = "m/44'/1627'/0'/0'/0'";
|
||||||
|
|
||||||
let action;
|
let action;
|
||||||
let createAccountStep;
|
let createAccountStep;
|
||||||
|
@ -201,23 +212,54 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
const generatedKeySignIn = () => {
|
const generatedKeySignIn = () => {
|
||||||
const key = generatedKey.join(' ');
|
const seed = generatedKey.join(" ");
|
||||||
|
|
||||||
if(!bip39.validateMnemonic(key, wordlist)) {
|
if (!bip39.validateMnemonic(seed, wordlist)) {
|
||||||
alert('invalid key');
|
alert("invalid key");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
processSignIn(key);
|
processSignIn(seed);
|
||||||
};
|
};
|
||||||
|
|
||||||
const processSignIn = key => {
|
const processSignIn = async (wordSeed) => {
|
||||||
fadeOut = true;
|
const seed = await bip39.mnemonicToSeed(wordSeed);
|
||||||
|
const key = HDKey.fromMasterSeed(seed).derive(BIP44_PATH);
|
||||||
|
|
||||||
// use key here
|
let pubKey;
|
||||||
|
let privKey = x25519.utils.randomPrivateKey();
|
||||||
|
|
||||||
|
try {
|
||||||
|
pubKey = await browser.runtime.sendMessage({
|
||||||
|
method: "exchangeCommunicationKeys",
|
||||||
|
data: bytesToHex(x25519.getPublicKey(privKey)),
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
alert(`Failed to login: ${e.message}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pubKey) {
|
||||||
|
alert(`Failed to login: could not get communication key`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pubKey = hexToBytes(pubKey);
|
||||||
|
|
||||||
|
const secret = x25519.getSharedSecret(privKey, pubKey);
|
||||||
|
const nonce = randomBytes(24);
|
||||||
|
const box = secretbox(secret, nonce);
|
||||||
|
const ciphertext = box.seal(key.privateKey);
|
||||||
|
|
||||||
|
await browser.runtime.sendMessage({
|
||||||
|
method: "setLoginKey",
|
||||||
|
data: {
|
||||||
|
data: bytesToHex(ciphertext),
|
||||||
|
nonce: bytesToHex(nonce),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
window.setTimeout(() => {
|
window.setTimeout(() => {
|
||||||
window.location.href = '/dashboard.html';
|
window.location.href = "/dashboard.html";
|
||||||
}, 1000);
|
}, 1000);
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
Reference in New Issue