1
0
Fork 0
mirror of https://github.com/sussy-code/smov.git synced 2025-01-17 01:51:24 +01:00

Fix seed generation, add code signing and fix Base64

This commit is contained in:
William Oldham 2023-11-05 10:36:06 +00:00
parent df85861cf2
commit 791923e78c
5 changed files with 32 additions and 32 deletions

View file

@ -7,6 +7,7 @@
"@formkit/auto-animate": "^0.7.0", "@formkit/auto-animate": "^0.7.0",
"@headlessui/react": "^1.5.0", "@headlessui/react": "^1.5.0",
"@movie-web/providers": "^1.0.4", "@movie-web/providers": "^1.0.4",
"@noble/hashes": "^1.3.2",
"@react-spring/web": "^9.7.1", "@react-spring/web": "^9.7.1",
"@scure/bip39": "^1.2.1", "@scure/bip39": "^1.2.1",
"@sozialhelden/ietf-language-tags": "^5.4.2", "@sozialhelden/ietf-language-tags": "^5.4.2",
@ -33,7 +34,6 @@
"react-use": "^17.4.0", "react-use": "^17.4.0",
"slugify": "^1.6.6", "slugify": "^1.6.6",
"subsrt-ts": "^2.1.1", "subsrt-ts": "^2.1.1",
"universal-base64url": "^1.1.0",
"unzipit": "^1.4.3", "unzipit": "^1.4.3",
"zustand": "^4.3.9" "zustand": "^4.3.9"
}, },

View file

@ -20,6 +20,9 @@ dependencies:
'@movie-web/providers': '@movie-web/providers':
specifier: ^1.0.4 specifier: ^1.0.4
version: 1.0.4 version: 1.0.4
'@noble/hashes':
specifier: ^1.3.2
version: 1.3.2
'@react-spring/web': '@react-spring/web':
specifier: ^9.7.1 specifier: ^9.7.1
version: 9.7.3(react-dom@17.0.2)(react@17.0.2) version: 9.7.3(react-dom@17.0.2)(react@17.0.2)
@ -98,9 +101,6 @@ dependencies:
subsrt-ts: subsrt-ts:
specifier: ^2.1.1 specifier: ^2.1.1
version: 2.1.1 version: 2.1.1
universal-base64url:
specifier: ^1.1.0
version: 1.1.0
unzipit: unzipit:
specifier: ^1.4.3 specifier: ^1.4.3
version: 1.4.3 version: 1.4.3
@ -6150,16 +6150,6 @@ packages:
crypto-random-string: 2.0.0 crypto-random-string: 2.0.0
dev: true dev: true
/universal-base64@2.1.0:
resolution: {integrity: sha512-WeOkACVnIXJZr/qlv7++Rl1zuZOHN96v2yS5oleUuv8eJOs5j9M5U3xQEIoWqn1OzIuIcgw0fswxWnUVGDfW6g==}
dev: false
/universal-base64url@1.1.0:
resolution: {integrity: sha512-qWv2+8KCaAWdpqqXwU8W0Yj9pflYDXP37/a3kec6Y4Je7bYzgIfxEVRjZWeLR67be7iot1lGCy5Nuo+xB0fojA==}
dependencies:
universal-base64: 2.1.0
dev: false
/universalify@0.2.0: /universalify@0.2.0:
resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==}
engines: {node: '>= 4.0.0'} engines: {node: '>= 4.0.0'}

View file

@ -1,13 +1,14 @@
import { pbkdf2Async } from "@noble/hashes/pbkdf2";
import { sha256 } from "@noble/hashes/sha256";
import { generateMnemonic } from "@scure/bip39"; import { generateMnemonic } from "@scure/bip39";
import { wordlist } from "@scure/bip39/wordlists/english"; import { wordlist } from "@scure/bip39/wordlists/english";
import forge from "node-forge"; import forge from "node-forge";
import { encode } from "universal-base64url";
async function seedFromMnemonic(mnemonic: string) { async function seedFromMnemonic(mnemonic: string) {
const md = forge.md.sha256.create(); return pbkdf2Async(sha256, mnemonic, "mnemonic", {
md.update(mnemonic); c: 2048,
// TODO this is probably not correct dkLen: 32,
return md.digest().toHex(); });
} }
export async function keysFromMenmonic(mnemonic: string) { export async function keysFromMenmonic(mnemonic: string) {
@ -28,13 +29,19 @@ export function genMnemonic(): string {
} }
export async function signCode( export async function signCode(
_code: string, code: string,
_privateKey: forge.pki.ed25519.NativeBuffer privateKey: forge.pki.ed25519.NativeBuffer
): Promise<Uint8Array> { ): Promise<forge.pki.ed25519.NativeBuffer> {
// TODO add real signature return forge.pki.ed25519.sign({
return new Uint8Array(); encoding: "utf8",
message: code,
privateKey,
});
} }
export function bytesToBase64Url(bytes: Uint8Array): string { export function bytesToBase64Url(bytes: Uint8Array): string {
return encode(String.fromCodePoint(...bytes)); return btoa(String.fromCodePoint(...bytes))
.replace(/\//g, "_")
.replace(/\+/g, "-")
.replace(/=+$/, "");
} }

View file

@ -1,7 +1,11 @@
import { ofetch } from "ofetch"; import { ofetch } from "ofetch";
import { SessionResponse, UserResponse } from "@/backend/accounts/auth"; import { SessionResponse, UserResponse } from "@/backend/accounts/auth";
import { keysFromMenmonic, signCode } from "@/backend/accounts/crypto"; import {
bytesToBase64Url,
keysFromMenmonic as keysFromMnemonic,
signCode,
} from "@/backend/accounts/crypto";
export interface ChallengeTokenResponse { export interface ChallengeTokenResponse {
challenge: string; challenge: string;
@ -55,10 +59,10 @@ export async function registerAccount(
} }
export async function signChallenge(mnemonic: string, challengeCode: string) { export async function signChallenge(mnemonic: string, challengeCode: string) {
const keys = await keysFromMenmonic(mnemonic); const keys = await keysFromMnemonic(mnemonic);
const signature = await signCode(challengeCode, keys.privateKey); const signature = await signCode(challengeCode, keys.privateKey);
return { return {
publicKey: keys.publicKey, publicKey: bytesToBase64Url(keys.publicKey),
signature, signature: bytesToBase64Url(signature),
}; };
} }

View file

@ -1,7 +1,6 @@
import { useState } from "react"; import { useState } from "react";
import { useAsyncFn } from "react-use"; import { useAsyncFn } from "react-use";
import { bytesToBase64Url } from "@/backend/accounts/crypto";
import { import {
getRegisterChallengeToken, getRegisterChallengeToken,
registerAccount, registerAccount,
@ -37,9 +36,9 @@ export function VerifyPassphrase(props: VerifyPassphraseProps) {
const registerResult = await registerAccount(url, { const registerResult = await registerAccount(url, {
challenge: { challenge: {
code: challenge, code: challenge,
signature: bytesToBase64Url(keys.signature), signature: keys.signature,
}, },
publicKey: bytesToBase64Url(keys.publicKey), publicKey: keys.publicKey,
device: props.profile.device, device: props.profile.device,
profile: props.profile.profile, profile: props.profile.profile,
}); });