From 22cd5aa88de3ae3934d0a268cb2d823f52980f19 Mon Sep 17 00:00:00 2001 From: Tilen Komel Date: Fri, 23 Aug 2024 18:33:13 +0200 Subject: [PATCH] Add key generation --- .../PageComponents/Config/Security.tsx | 45 ++++++++++--------- src/core/utils/x25519.ts | 9 ++++ 2 files changed, 32 insertions(+), 22 deletions(-) create mode 100644 src/core/utils/x25519.ts diff --git a/src/components/PageComponents/Config/Security.tsx b/src/components/PageComponents/Config/Security.tsx index a82ed980..9c770f43 100644 --- a/src/components/PageComponents/Config/Security.tsx +++ b/src/components/PageComponents/Config/Security.tsx @@ -1,4 +1,8 @@ import { DynamicForm } from "@app/components/Form/DynamicForm.js"; +import { + getX25519PrivateKey, + getX25519PublicKey, +} from "@app/core/utils/x25519"; import type { SecurityValidation } from "@app/validation/config/security.js"; import { useDevice } from "@core/stores/deviceStore.js"; import { Protobuf } from "@meshtastic/js"; @@ -50,22 +54,25 @@ export const Security = (): JSX.Element => { ); }; - const clickEvent = ( - setKey: (value: React.SetStateAction) => void, - bitCount: number, - setValidationText: ( - value: React.SetStateAction, - ) => void, - ) => { - setKey( + const privateKeyClickEvent = () => { + const privateKey = getX25519PrivateKey(); + const publicKey = getX25519PublicKey(privateKey); + + setPrivateKey(fromByteArray(privateKey)); + setPublicKey(fromByteArray(publicKey)); + setPrivateKeyValidationText(undefined); + }; + + const adminKeyClickEvent = () => { + setAdminKey( btoa( cryptoRandomString({ - length: bitCount ?? 0, + length: adminKeyBitCount ?? 0, type: "alphanumeric", }), ), ); - setValidationText(undefined); + setAdminKeyValidationText(undefined); }; const validatePass = ( @@ -129,17 +136,13 @@ export const Security = (): JSX.Element => { name: "privateKey", label: "Private Key", description: "Used to create a shared key with a remote device", + bits: [{ text: "128 bit", value: "16", key: "bit128" }], validationText: privateKeyValidationText, devicePSKBitCount: privateKeyBitCount, inputChange: privateKeyInputChangeEvent, selectChange: privateKeySelectChangeEvent, hide: !privateKeyVisible, - buttonClick: () => - clickEvent( - setPrivateKey, - privateKeyBitCount, - setPrivateKeyValidationText, - ), + buttonClick: privateKeyClickEvent, disabledBy: [ { fieldName: "adminChannelEnabled", @@ -161,6 +164,9 @@ export const Security = (): JSX.Element => { description: "Sent out to other nodes on the mesh to allow them to compute a shared secret key", disabledBy: [{ fieldName: "always" }], + properties: { + value: publicKey, + }, }, ], }, @@ -193,12 +199,7 @@ export const Security = (): JSX.Element => { inputChange: adminKeyInputChangeEvent, selectChange: adminKeySelectChangeEvent, hide: !adminKeyVisible, - buttonClick: () => - clickEvent( - setAdminKey, - adminKeyBitCount, - setAdminKeyValidationText, - ), + buttonClick: adminKeyClickEvent, disabledBy: [{ fieldName: "adminChannelEnabled" }], properties: { value: adminKey, diff --git a/src/core/utils/x25519.ts b/src/core/utils/x25519.ts new file mode 100644 index 00000000..d9ae20b5 --- /dev/null +++ b/src/core/utils/x25519.ts @@ -0,0 +1,9 @@ +import { x25519 } from "@noble/curves/ed25519"; + +export function getX25519PrivateKey(): Uint8Array { + return x25519.utils.randomPrivateKey(); +} + +export function getX25519PublicKey(privateKey: Uint8Array): Uint8Array { + return x25519.getPublicKey(privateKey); +}