From 457398b291c6d39bc98dc8ed14b47aba15790f30 Mon Sep 17 00:00:00 2001 From: Derrick Hammer Date: Sun, 18 Dec 2022 15:05:02 -0500 Subject: [PATCH] *Prune out old or unneeded code, some maybe be refactored back in as plugins or in a different form --- src/config.ts | 1 - src/index.ts | 2 - src/lib/file.ts | 445 --------------------------------------------- src/modules/ssl.ts | 151 --------------- 4 files changed, 599 deletions(-) delete mode 100644 src/lib/file.ts delete mode 100644 src/modules/ssl.ts diff --git a/src/config.ts b/src/config.ts index eb6b33e..41ec52f 100644 --- a/src/config.ts +++ b/src/config.ts @@ -31,7 +31,6 @@ config.inject({ logLevel: "info", pluginDir: path.resolve(configDir, "..", "plugins"), plugins: ["core"], - ssl: false, }); config.load({ diff --git a/src/index.ts b/src/index.ts index a2a7760..fe1a960 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,7 +4,6 @@ import { start as startApp } from "./modules/app"; import log from "loglevel"; import config from "./config.js"; import { loadPlugins } from "./modules/plugin.js"; -import { start as startSSl } from "./modules/ssl.js"; import { start as startSwarm } from "./modules/swarm.js"; import * as bip39 from "@scure/bip39"; import { wordlist } from "@scure/bip39/wordlists/english"; @@ -22,7 +21,6 @@ async function boot() { await loadPlugins(); await startApp(); await startRpc(); - await startSSl(); await startRelay(); } diff --git a/src/lib/file.ts b/src/lib/file.ts deleted file mode 100644 index 02db425..0000000 --- a/src/lib/file.ts +++ /dev/null @@ -1,445 +0,0 @@ -import type { Err, progressiveFetchResult } from "libskynet"; -// @ts-ignore -import { SkynetClient } from "@skynetlabs/skynet-nodejs"; -import type { - IndependentFileSmall, - IndependentFileSmallMetadata, -} from "@lumeweb/relay-types"; -import { - addContextToErr, - blake2b, - bufToHex, - ed25519Sign, - encodePrefixedBytes, - encodeU64, - defaultPortalList, - skylinkToResolverEntryData, - encryptFileSmall, - decryptFileSmall, - entryIDToSkylink, - deriveRegistryEntryID, - taggedRegistryEntryKeys, - namespaceInode, - deriveChildSeed, - bufToB64, -} from "libskynet"; - -import { readRegistryEntry, progressiveFetch, upload } from "libskynetnode"; - -const ERR_NOT_EXISTS = "DNE"; -const STD_FILENAME = "file"; - -async function overwriteRegistryEntry( - keypair: any, - datakey: Uint8Array, - data: Uint8Array, - revision: bigint -): Promise { - return new Promise((resolve, reject) => { - if (data.length > 86) { - reject("provided data is too large to fit in a registry entry"); - return; - } - - let [encodedRevision, errU64] = encodeU64(revision); - if (errU64 !== null) { - reject(addContextToErr(errU64, "unable to encode revision number")); - return; - } - - let datakeyHex = bufToHex(datakey); - let [encodedData, errEPB] = encodePrefixedBytes(data); - if (errEPB !== null) { - reject(addContextToErr(errEPB, "unable to encode the registry data")); - return; - } - let dataToSign = new Uint8Array(32 + 8 + data.length + 8); - dataToSign.set(datakey, 0); - dataToSign.set(encodedData, 32); - dataToSign.set(encodedRevision, 32 + 8 + data.length); - let sigHash = blake2b(dataToSign); - let [sig, errS] = ed25519Sign(sigHash, keypair.secretKey); - if (errS !== null) { - reject(addContextToErr(errS, "unable to produce signature")); - return; - } - - let postBody = { - publickey: { - algorithm: "ed25519", - key: Array.from(keypair.publicKey), - }, - datakey: datakeyHex, - revision: Number(revision), - data: Array.from(data), - signature: Array.from(sig), - }; - let fetchOpts = { - method: "post", - body: JSON.stringify(postBody), - }; - let endpoint = "/skynet/registry"; - - progressiveFetch( - endpoint, - fetchOpts, - defaultPortalList, - verifyRegistryWrite - ).then((result: progressiveFetchResult) => { - if (result.success === true) { - resolve(null); - return; - } - reject("unable to write registry entry\n" + JSON.stringify(result)); - }); - }); -} -async function verifyRegistryWrite(response: Response): Promise { - return new Promise((resolve) => { - if (!("status" in response)) { - resolve("response did not contain a status"); - return; - } - if (response.status === 204) { - resolve(null); - return; - } - resolve("unrecognized status"); - }); -} - -async function createIndependentFileSmall( - seed: Uint8Array, - userInode: string, - fileData: Uint8Array -): Promise<[IndependentFileSmall, Err]> { - return new Promise(async (resolve) => { - let [inode, errNI] = namespaceInode("IndependentFileSmall", userInode); - if (errNI !== null) { - resolve([{} as any, addContextToErr(errNI, "unable to namespace inode")]); - return; - } - - let [keypair, dataKey, errTREK] = taggedRegistryEntryKeys( - seed, - inode, - inode - ); - if (errTREK !== null) { - resolve([ - {} as any, - addContextToErr( - errTREK, - "unable to get registry entry for provided inode" - ), - ]); - return; - } - - let result; - try { - result = await readRegistryEntry(keypair.publicKey, dataKey); - } catch (e) { - result = { exists: false }; - } - if (result.exists === true) { - resolve([{} as any, "exists"]); - return; - } - - let encryptionKey = deriveChildSeed(seed, inode); - let metadata: IndependentFileSmallMetadata = { - largestHistoricSize: BigInt(fileData.length), - }; - - let revisionSeed = new Uint8Array(seed.length + 8); - revisionSeed.set(seed, 0); - let revisionKey = deriveChildSeed(revisionSeed, inode); - let revision = BigInt(revisionKey[0]) * 256n + BigInt(revisionKey[1]); - let [encryptedData, errEF] = encryptFileSmall( - encryptionKey, - inode, - revision, - metadata, - fileData, - metadata.largestHistoricSize - ); - if (errEF !== null) { - resolve([{} as any, addContextToErr(errEF, "unable to encrypt file")]); - return; - } - - let immutableSkylink; - - try { - immutableSkylink = await upload(encryptedData, { - Filename: STD_FILENAME, - }); - } catch (e) { - resolve([{} as any, addContextToErr(e, "upload failed")]); - return; - } - - let [entryData, errSTRED] = skylinkToResolverEntryData(immutableSkylink); - if (errSTRED !== null) { - resolve([ - {} as any, - addContextToErr( - errSTRED, - "couldn't create resovler link from upload skylink" - ), - ]); - return; - } - - try { - await overwriteRegistryEntry(keypair, dataKey, entryData, revision); - } catch (e: any) { - resolve([ - {} as any, - addContextToErr(e, "could not write to registry entry"), - ]); - return; - } - - let [entryID, errDREID] = deriveRegistryEntryID(keypair.publicKey, dataKey); - if (errDREID !== null) { - resolve([ - {} as any, - addContextToErr(errDREID, "could not compute entry id"), - ]); - return; - } - let skylink = entryIDToSkylink(entryID); - - let encStr = bufToB64(encryptionKey); - let viewKey = encStr + inode; - - let ifile: IndependentFileSmall = { - dataKey, - fileData, - inode, - keypair, - metadata, - revision, - seed, - - skylink, - viewKey, - - overwriteData: function (newData: Uint8Array): Promise { - return overwriteIndependentFileSmall(ifile, newData); - }, - readData: function (): Promise<[Uint8Array, Err]> { - return new Promise((resolve) => { - let data = new Uint8Array(ifile.fileData.length); - data.set(ifile.fileData, 0); - resolve([data, null]); - }); - }, - }; - resolve([ifile, null]); - }); -} - -async function openIndependentFileSmall( - seed: Uint8Array, - userInode: string -): Promise<[IndependentFileSmall, Err]> { - return new Promise(async (resolve) => { - let [inode, errNI] = namespaceInode("IndependentFileSmall", userInode); - if (errNI !== null) { - resolve([{} as any, addContextToErr(errNI, "unable to namespace inode")]); - return; - } - - let [keypair, dataKey, errTREK] = taggedRegistryEntryKeys( - seed, - inode, - inode - ); - if (errTREK !== null) { - resolve([ - {} as any, - addContextToErr( - errTREK, - "unable to get registry entry for provided inode" - ), - ]); - return; - } - - let result; - try { - result = await readRegistryEntry(keypair.publicKey, dataKey); - } catch (e: any) { - resolve([ - {} as any, - addContextToErr(e, "unable to read registry entry for file"), - ]); - return; - } - if (result.exists !== true) { - resolve([{} as any, ERR_NOT_EXISTS]); - return; - } - - let [entryID, errDREID] = deriveRegistryEntryID(keypair.publicKey, dataKey); - if (errDREID !== null) { - resolve([ - {} as any, - addContextToErr(errDREID, "unable to derive registry entry id"), - ]); - return; - } - let skylink = entryIDToSkylink(entryID); - - const client = new SkynetClient("https://web3portal.com"); - let encryptedData; - try { - encryptedData = await client.downloadData(skylink); - } catch (e: any) { - resolve([{} as any, addContextToErr(e, "unable to download file")]); - return; - } - - let encryptionKey = deriveChildSeed(seed, inode); - let [metadata, fileData, errDF] = decryptFileSmall( - encryptionKey, - inode, - encryptedData - ); - if (errDF !== null) { - resolve([{} as any, addContextToErr(errDF, "unable to decrypt file")]); - return; - } - - let encStr = bufToB64(encryptionKey); - let viewKey = encStr + inode; - - let ifile: IndependentFileSmall = { - dataKey, - fileData, - inode, - keypair, - metadata, - revision: result.revision!, - seed, - - skylink, - viewKey, - - overwriteData: function (newData: Uint8Array): Promise { - return overwriteIndependentFileSmall(ifile, newData); - }, - - readData: function (): Promise<[Uint8Array, Err]> { - return new Promise((resolve) => { - let data = new Uint8Array(ifile.fileData.length); - data.set(ifile.fileData, 0); - resolve([data, null]); - }); - }, - }; - resolve([ifile, null]); - }); -} -async function overwriteIndependentFileSmall( - file: IndependentFileSmall, - newData: Uint8Array -): Promise { - return new Promise(async (resolve) => { - // Create a new metadata for the file based on the current file - // metadata. Need to update the largest historic size. - let newMetadata: IndependentFileSmallMetadata = { - largestHistoricSize: BigInt(file.metadata.largestHistoricSize), - }; - if (BigInt(newData.length) > newMetadata.largestHistoricSize) { - newMetadata.largestHistoricSize = BigInt(newData.length); - } - - // Compute the new revision number for the file. This is done - // deterministically using the seed and the current revision number, so - // that multiple concurrent updates will end up with the same revision. - // We use a random number between 1 and 256 for our increment. - let [encodedRevision, errEU64] = encodeU64(file.revision); - if (errEU64 !== null) { - resolve(addContextToErr(errEU64, "unable to encode revision")); - return; - } - let revisionSeed = new Uint8Array( - file.seed.length + encodedRevision.length - ); - revisionSeed.set(file.seed, 0); - revisionSeed.set(encodedRevision, file.seed.length); - let revisionKey = deriveChildSeed(revisionSeed, file.inode); - let newRevision = file.revision + BigInt(revisionKey[0]) + 1n; - - // Get the encryption key. - let encryptionKey = deriveChildSeed(file.seed, file.inode); - - // Create a new encrypted blob for the data. - // - // NOTE: Need to supply the data that would be in place after a - // successful update, which means using the new metadata and revision - // number. - let [encryptedData, errEFS] = encryptFileSmall( - encryptionKey, - file.inode, - newRevision, - newMetadata, - newData, - newMetadata.largestHistoricSize - ); - if (errEFS !== null) { - resolve(addContextToErr(errEFS, "unable to encrypt updated file")); - return; - } - - // Upload the data to get the immutable link. - let skylink; - try { - skylink = await upload(encryptedData, { - Filename: STD_FILENAME, - }); - } catch (e) { - resolve(addContextToErr(e, "new data upload failed")); - return; - } - - // Write to the registry entry. - let [entryData, errSTRED] = skylinkToResolverEntryData(skylink); - if (errSTRED !== null) { - resolve( - addContextToErr( - errSTRED, - "could not create resolver link from upload skylink" - ) - ); - return; - } - try { - await overwriteRegistryEntry( - file.keypair, - file.dataKey, - entryData, - newRevision - ); - } catch (e: any) { - resolve(addContextToErr(e, "could not write to registry entry")); - return; - } - - // File update was successful, update the file metadata. - file.revision = newRevision; - file.metadata = newMetadata; - file.fileData = newData; - resolve(null); - }); -} - -export { - createIndependentFileSmall, - openIndependentFileSmall, - overwriteIndependentFileSmall, -}; diff --git a/src/modules/ssl.ts b/src/modules/ssl.ts deleted file mode 100644 index 82cfd9e..0000000 --- a/src/modules/ssl.ts +++ /dev/null @@ -1,151 +0,0 @@ -import tls from "tls"; -import { - createIndependentFileSmall, - openIndependentFileSmall, - overwriteIndependentFileSmall, -} from "../lib/file.js"; -// @ts-ignore -import promiseRetry from "promise-retry"; -import config from "../config.js"; -import log from "loglevel"; -import { getSeed } from "../lib/seed.js"; -import type { - IndependentFileSmall, - SavedSslData, - SslData, -} from "@lumeweb/relay-types"; - -let sslCtx: tls.SecureContext = tls.createSecureContext(); -let sslObject: SslData = {}; -let sslChecker: () => Promise; - -const FILE_CERT_NAME = "/lumeweb/relay/ssl.crt"; -const FILE_KEY_NAME = "/lumeweb/relay/ssl.key"; - -export function setSslContext(context: tls.SecureContext) { - sslCtx = context; -} - -export function getSslContext(): tls.SecureContext { - return sslCtx; -} - -export function setSsl( - cert: IndependentFileSmall | Uint8Array, - key: IndependentFileSmall | Uint8Array -): void { - cert = (cert as IndependentFileSmall)?.fileData || cert; - key = (key as IndependentFileSmall)?.fileData || key; - sslObject.cert = cert as Uint8Array; - sslObject.key = key as Uint8Array; - setSslContext( - tls.createSecureContext({ - cert: Buffer.from(cert), - key: Buffer.from(key), - }) - ); -} - -export function getSsl(): SslData { - return sslObject; -} - -export async function saveSSl(): Promise { - const seed = getSeed(); - - log.info(`Saving SSL Certificate for ${config.str("domain")}`); - - let oldCert = await getSslCert(); - let cert: any = getSsl()?.cert; - if (oldCert) { - await overwriteIndependentFileSmall( - oldCert as IndependentFileSmall, - Buffer.from(cert) - ); - } else { - await createIndependentFileSmall(seed, FILE_CERT_NAME, Buffer.from(cert)); - } - - let oldKey = await getSslKey(); - let key: any = getSsl()?.key; - - if (oldKey) { - await overwriteIndependentFileSmall( - oldKey as IndependentFileSmall, - Buffer.from(key) - ); - } else { - await createIndependentFileSmall(seed, FILE_KEY_NAME, Buffer.from(key)); - } - - log.info(`Saved SSL Certificate for ${config.str("domain")}`); -} - -export async function getSavedSsl( - retry = true -): Promise { - let retryOptions = retry ? {} : { retries: 0 }; - let sslCert: IndependentFileSmall | boolean = false; - let sslKey: IndependentFileSmall | boolean = false; - - try { - await promiseRetry(async (retry: any) => { - sslCert = await getSslCert(); - if (!sslCert) { - retry(); - } - }, retryOptions); - - await promiseRetry(async (retry: any) => { - sslKey = await getSslKey(); - if (!sslKey) { - retry(); - } - }, retryOptions); - } catch {} - - if (!sslCert || !sslKey) { - return false; - } - - return { - cert: sslCert as IndependentFileSmall, - key: sslKey as IndependentFileSmall, - }; -} - -async function getSslCert(): Promise { - return getSslFile(FILE_CERT_NAME); -} - -async function getSslKey(): Promise { - return getSslFile(FILE_KEY_NAME); -} - -async function getSslFile( - name: string -): Promise { - let seed = getSeed(); - - let [file, err] = await openIndependentFileSmall(seed, name); - - if (err) { - return false; - } - - return file; -} - -export function setSSlCheck(checker: () => Promise): void { - sslChecker = checker; -} - -export function getSslCheck(): () => Promise { - return sslChecker; -} - -export async function start() { - if (config.bool("ssl") && getSslCheck()) { - await getSslCheck()(); - } -}