mirror of https://codeberg.org/pzp/pzp-db.git
102 lines
2.3 KiB
JavaScript
102 lines
2.3 KiB
JavaScript
const base58 = require('bs58')
|
|
const b4a = require('b4a')
|
|
const MsgV3 = require('./msg-v3')
|
|
|
|
/**
|
|
* @typedef {import('./index').RecPresent} RecPresent
|
|
* @typedef {import('ppppp-keypair').Keypair} Keypair
|
|
*
|
|
* @typedef {Buffer | Uint8Array} B4A
|
|
*
|
|
* @typedef {{
|
|
* name: string;
|
|
* setup?: (config: any, cb: any) => void;
|
|
* onReady?: (cb: any) => void;
|
|
* encrypt: (plaintext: B4A, opts: any) => B4A;
|
|
* decrypt: (ciphertext: B4A, opts: any) => B4A | null;
|
|
* }} EncryptionFormat
|
|
*/
|
|
|
|
/**
|
|
* @param {string} str
|
|
*/
|
|
function ciphertextStrToBuffer(str) {
|
|
const dot = str.indexOf('.')
|
|
return b4a.from(str.slice(0, dot), 'base64')
|
|
}
|
|
|
|
/**
|
|
* TODO: eventually get rid of this
|
|
* @param {Keypair} keypair
|
|
*/
|
|
function keypairToSSBKeys(keypair) {
|
|
const _public = b4a.from(base58.decode(keypair.public)).toString('base64')
|
|
const _private = b4a.from(base58.decode(keypair.private)).toString('base64')
|
|
return {
|
|
id: `@${_public}.ed25519`,
|
|
curve: keypair.curve,
|
|
public: _public,
|
|
private: _private,
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {RecPresent} rec
|
|
* @param {any} peer
|
|
* @param {any} config
|
|
* @returns {RecPresent}
|
|
*/
|
|
function decrypt(rec, peer, config) {
|
|
const msgEncrypted = rec.msg
|
|
const { data } = msgEncrypted
|
|
if (typeof data !== 'string') return rec
|
|
|
|
const encryptionFormat = peer.db.findEncryptionFormatFor(data)
|
|
if (!encryptionFormat) return rec
|
|
|
|
// Decrypt
|
|
const ciphertextBuf = ciphertextStrToBuffer(data)
|
|
const opts = { keys: keypairToSSBKeys(config.keypair) }
|
|
const plaintextBuf = encryptionFormat.decrypt(ciphertextBuf, opts)
|
|
if (!plaintextBuf) return rec
|
|
|
|
// Reconstruct KVT in JS encoding
|
|
const msgDecrypted = MsgV3.fromPlaintextBuffer(plaintextBuf, msgEncrypted)
|
|
|
|
return {
|
|
hash: rec.hash,
|
|
msg: msgDecrypted,
|
|
received: rec.received,
|
|
misc: {
|
|
...rec.misc,
|
|
private: true,
|
|
originalData: data,
|
|
encryptionFormat: encryptionFormat.name,
|
|
},
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {RecPresent} rec
|
|
*/
|
|
function reEncrypt(rec) {
|
|
return {
|
|
hash: rec.hash,
|
|
msg: { ...rec.msg, data: rec.misc.originalData },
|
|
received: rec.received,
|
|
...(rec.misc.size
|
|
? {
|
|
misc: {
|
|
offset: rec.misc.offset,
|
|
size: rec.misc.size,
|
|
},
|
|
}
|
|
: null),
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
decrypt,
|
|
reEncrypt,
|
|
}
|