factom-identity-lib
Version:
Library to read and update Factom identities
92 lines (72 loc) • 2.92 kB
JavaScript
const { sha256d } = require('../crypto');
const { verify } = require('./common');
const { isValidServerIdentityChainId } = require('./validation');
const { VERSION_0 } = require('./constant');
async function getIdentityRootChain(cli, rootChainId) {
if (!isValidServerIdentityChainId(rootChainId)) {
throw new Error(`Invalid root chain id ${rootChainId}`);
}
const entries = await cli.getAllEntriesOfChain(rootChainId);
const extIds = entries[0].extIds;
if (
!extIds[0].equals(VERSION_0) ||
extIds[1].toString() !== 'Identity Chain' ||
extIds.length !== 7
) {
throw new Error('Invalid Root Factom Identity Chain');
}
const identityKeys = extractIdentityKeys(entries[0]);
const serverManagementSubchainId = extractServerManagementSubchainId(entries, identityKeys);
return { entries, identityKeys, serverManagementSubchainId };
}
async function getServerManagementSubchain(cli, serverManagementSubchainId, rootChainId) {
const entries = await cli.getAllEntriesOfChain(serverManagementSubchainId);
const extIds = entries[0].extIds;
if (
!extIds[0].equals(VERSION_0) ||
extIds[1].toString() !== 'Server Management' ||
extIds.length !== 4
) {
throw new Error('Invalid Server Management Subchain');
}
if (rootChainId && rootChainId !== extIds[2].toString('hex')) {
throw new Error(
"This Server Management Subchain' doesnt reference the Identity Root Chain Id provided"
);
}
return { entries };
}
/////////////////// Extractors ///////////////////////
function extractIdentityKeys(entry) {
const extIds = entry.extIds;
return [extIds[2], extIds[3], extIds[4], extIds[5]];
}
function extractServerManagementSubchainId(entries, identityKeys) {
const serverManagementSubchainEntry = entries.find(
e => e.extIds[1].toString() === 'Register Server Management'
);
if (!serverManagementSubchainEntry) {
throw new Error('No Server Managemenet Subchain registering entry found');
}
verifyServerManagementSubchainRegistration(serverManagementSubchainEntry, identityKeys[0]);
return serverManagementSubchainEntry.extIds[2];
}
function verifyServerManagementSubchainRegistration(entry, identityKey1) {
const extIds = entry.extIds;
if (
!extIds[0].equals(VERSION_0) ||
extIds[1].toString() !== 'Register Server Management' ||
extIds[2].length !== 32 ||
!sha256d(extIds[3]).equals(identityKey1)
) {
throw new Error('Invalid Server Managemenet Subchain registration');
}
const data = Buffer.concat(extIds.slice(0, 3));
if (!verify(extIds[3], data, extIds[4])) {
throw new Error('Invalid signature of the Server Managemenet Subchain registration');
}
}
module.exports = {
getIdentityRootChain,
getServerManagementSubchain
};