@toruslabs/metadata-helpers
Version:
Helper methods for metadata
114 lines (110 loc) • 4.87 kB
JavaScript
'use strict';
var eccrypto = require('@toruslabs/eccrypto');
var utils = require('./utils.js');
const WEBAUTHN_TORUS_SHARE = "webauthn_torus_share";
const WEBAUTHN_DEVICE_SHARE = "webauthn_device_share";
function encParamsHexToBuf(encParamsHex) {
return {
iv: Buffer.from(encParamsHex.iv, "hex"),
ephemPublicKey: Buffer.from(encParamsHex.ephemPublicKey, "hex"),
ciphertext: Buffer.from(encParamsHex.ciphertext, "hex"),
mac: Buffer.from(encParamsHex.mac, "hex")
};
}
function encParamsBufToHex(encParams) {
return {
iv: Buffer.from(encParams.iv).toString("hex"),
ephemPublicKey: Buffer.from(encParams.ephemPublicKey).toString("hex"),
ciphertext: Buffer.from(encParams.ciphertext).toString("hex"),
mac: Buffer.from(encParams.mac).toString("hex")
};
}
async function encryptData(privKeyHex, d) {
const serializedDec = JSON.stringify(d);
const serializedBuf = Buffer.from(serializedDec, "utf-8");
const encParams = await eccrypto.encrypt(eccrypto.getPublic(Buffer.from(privKeyHex, "hex")), serializedBuf);
const encParamsHex = encParamsBufToHex(encParams);
const sData = JSON.stringify(encParamsHex);
return sData;
}
async function decryptData(privKeyHex, d) {
const encParamsHex = JSON.parse(d);
const encParams = encParamsHexToBuf(encParamsHex);
const keyPair = utils.ec.keyFromPrivate(privKeyHex);
const serializedBuf = await eccrypto.decrypt(Buffer.from(keyPair.getPrivate().toString("hex", 64), "hex"), encParams);
const serializedDec = serializedBuf.toString("utf-8");
const data = JSON.parse(serializedDec);
return data;
}
async function getAndDecryptData(m, privKeyHex, namespace) {
const keyPair = utils.ec.keyFromPrivate(privKeyHex, "hex");
const pubKey = keyPair.getPublic();
const serializedData = await m.getMetadata({
pub_key_X: pubKey.getX().toString(16, 64),
pub_key_Y: pubKey.getY().toString(16, 64)
}, namespace);
if (!serializedData) {
return null;
}
const data = await decryptData(privKeyHex, serializedData);
return data;
}
async function encryptAndSetData(m, privKeyHex, d, namespace) {
const sData = await encryptData(privKeyHex, d);
const metadataParams = m.generateMetadataParams(sData, privKeyHex);
await m.setMetadata(metadataParams, namespace);
}
async function setTorusShare(m, webAuthnPubKey, webAuthnRefHex, subspace, subspaceData) {
const refKeyPair = utils.ec.keyFromPrivate(webAuthnRefHex);
const privKey = refKeyPair.getPrivate();
const pubKey = utils.ec.keyFromPublic({
x: webAuthnPubKey.pub_key_X,
y: webAuthnPubKey.pub_key_Y
});
const data = await getAndDecryptData(m, webAuthnRefHex, WEBAUTHN_TORUS_SHARE);
let d = {};
if (data) d = data;
const serializedSubspaceData = JSON.stringify(subspaceData);
const serializedSubspaceDataBuf = Buffer.from(serializedSubspaceData, "utf-8");
const encSubspaceData = await eccrypto.encrypt(Buffer.from(pubKey.getPublic("hex"), "hex"), serializedSubspaceDataBuf);
const encSubspaceDataHex = encParamsBufToHex(encSubspaceData);
d[subspace] = encSubspaceDataHex;
await encryptAndSetData(m, privKey.toString("hex", 64), d, WEBAUTHN_TORUS_SHARE);
}
async function setDeviceShare(m, webAuthnRefHex, subspace, subspaceData) {
const keyPair = utils.ec.keyFromPrivate(webAuthnRefHex);
const privKey = keyPair.getPrivate();
const data = await getAndDecryptData(m, webAuthnRefHex, WEBAUTHN_DEVICE_SHARE);
let d = {};
if (data) d = data;
d[subspace] = subspaceData;
await encryptAndSetData(m, privKey.toString("hex", 64), d, WEBAUTHN_DEVICE_SHARE);
}
async function getTorusShare(m, webAuthnKeyHex, webAuthnRefHex, subspace) {
const data = await getAndDecryptData(m, webAuthnRefHex, WEBAUTHN_TORUS_SHARE);
if (!data) return null;
const encParamsHex = data[subspace];
if (!encParamsHex) return null;
const encParams = encParamsHexToBuf(encParamsHex);
const keyPair = utils.ec.keyFromPrivate(webAuthnKeyHex);
const privKey = keyPair.getPrivate();
const serializedSubspaceDataBuf = await eccrypto.decrypt(Buffer.from(privKey.toString("hex", 64), "hex"), encParams);
const serializedSubspaceData = serializedSubspaceDataBuf.toString("utf-8");
const subspaceData = JSON.parse(serializedSubspaceData);
return subspaceData;
}
async function getDeviceShare(m, webAuthnRefHex, subspace) {
const data = await getAndDecryptData(m, webAuthnRefHex, WEBAUTHN_DEVICE_SHARE);
if (data) return data[subspace];
return null;
}
exports.decryptData = decryptData;
exports.encParamsBufToHex = encParamsBufToHex;
exports.encParamsHexToBuf = encParamsHexToBuf;
exports.encryptAndSetData = encryptAndSetData;
exports.encryptData = encryptData;
exports.getAndDecryptData = getAndDecryptData;
exports.getDeviceShare = getDeviceShare;
exports.getTorusShare = getTorusShare;
exports.setDeviceShare = setDeviceShare;
exports.setTorusShare = setTorusShare;