"use strict";
/** @module client/session */
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SecretStoreSessionClient = void 0;
const axios_1 = __importDefault(require("axios"));
const utils_1 = require("../utils");
const error_1 = require("./error");
/**
* @description Client for Secret Store session API. Uses [axios]{@link https://github.com/axios/axios}
* for making requests which is freely configurable.
*
* @memberof module:client/session
* @class
*/
class SecretStoreSessionClient {
/**
* @param {string} ssEndpointUrl The endpoint URL where a Secret Store node is listening for incoming session requests.
* @param {AxiosRequestConfig} [requestConfig] Additional request configuration params. Note: 'url', 'method' and 'data'
* fields are overwritten.
*/
constructor(ssEndpointUrl, requestConfig = {}) {
if (!ssEndpointUrl) {
throw new Error(`Secret Store endpoint URL was not given`);
}
this.url = ssEndpointUrl.endsWith('/') ? ssEndpointUrl.slice(0, -1) : ssEndpointUrl;
this.requestConfig = requestConfig;
}
async _send(method, url, body = undefined) {
try {
const response = await axios_1.default({
...this.requestConfig,
url,
method,
data: body
});
return response.data;
}
catch (error) {
if (error.isAxiosError) {
const { response } = error;
throw new error_1.SecretStoreSessionError(`${response.statusText} (${response.status}): ${utils_1.removeEnclosingDQuotes(response.data)}`, response.config);
}
throw error;
}
}
/**
* @description Generates server keys.
*
* More information can be found [here]{@link https://openethereum.github.io/wiki/Secret-Store.html#server-key-generation-session}.
*
* @param {string} serverKeyID The server key ID of your choosing. If you’re planning to link document key to this server key later,
* it would be good to use document contents hash as this identifier. Otherwise, it could be a random value.
* In both cases, please note that this value is unique and cannot be changed later.
* @param {string} signedServerKeyID The server key ID, signed with author’s private key. Only the author of a server key could bind
* document key to this server key later. This signature could be generated by `secretstore_signRawHash` RPC method.
* @param {number} threshold The key threshold value. Please consider the
* [guidelines]{@link https://openethereum.github.io/wiki/Secret-Store.html#server-key-generation-session} when choosing this value.
* @returns {Promise<string>} The hex-encoded public portion of the server key.
*/
async generateServerKey(serverKeyID, signedServerKeyID, threshold) {
const url = `${this.url}/shadow/${utils_1.remove0x(serverKeyID)}/${utils_1.remove0x(signedServerKeyID)}/${threshold}`;
return utils_1.removeEnclosingDQuotes(await this._send('post', url));
}
/**
* @description Retrieves the public portion of an already generated server key.
*
* Useable after a [successful server key generation session]{@link https://openethereum.github.io/wiki/Secret-Store.html#server-key-generation-session}
* performed by the same user who generated the server key.
*
* @param {string} serverKeyID The ID of previously generated server key.
* @param {string} signedServerKeyID The hex-encoded server key ID, signed by the same entity (author) that has signed the server key ID in server key generation session.
* @returns {Promise<string>} The hex-encoded public portion of the server key.
*/
async retrieveServerKeyPublic(serverKeyID, signedServerKeyID) {
const url = `${this.url}/server/${utils_1.remove0x(serverKeyID)}/${utils_1.remove0x(signedServerKeyID)}`;
return utils_1.removeEnclosingDQuotes(await this._send('get', url));
}
/**
* @description Binds an externally-generated document key to a server key.
*
* Useable after a [server key generation session]{@link https://openethereum.github.io/wiki/Secret-Store#server-key-generation-session}.
* More information can be found [here]{@link https://openethereum.github.io/wiki/Secret-Store#document-key-storing-session}.
*
* @param {string} serverKeyID The hex-encoded server key ID, the same that was used in the server key generation session.
* @param {string} signedServerKeyID The hex-encoded server key ID, signed by the same entity (author) that has signed the server key id in the server key generation session.
* @param {string | ExternallyEncryptedDocumentKey} commonPointOrKey The hex-encoded common point portion of the externally encrypted document key,
* or the externally encrypted document key object (with public server key, using special procedure).
* @param {string} [encryptedPoint] The hex-encoded encrypted point portion of the externally encrypted document key (wtih public server key, using special procedure).
* @returns {Promise<string>} Empty string if everything was OK (status code 200).
*/
async storeDocumentKey(serverKeyID, signedServerKeyID, commonPointOrKey, encryptedPoint) {
if (!commonPointOrKey) {
throw new Error('No document key parameters were given');
}
let cp;
let ep;
if (typeof commonPointOrKey === 'string' || commonPointOrKey instanceof String) {
if (!encryptedPoint) {
throw new Error(`Common point was given but no encrypted point (${encryptedPoint})`);
}
cp = utils_1.remove0x(commonPointOrKey);
ep = utils_1.remove0x(encryptedPoint);
}
else {
cp = utils_1.remove0x(commonPointOrKey.common_point);
ep = utils_1.remove0x(commonPointOrKey.encrypted_point);
}
const url = `${this.url}/shadow/${utils_1.remove0x(serverKeyID)}/${utils_1.remove0x(signedServerKeyID)}/${cp}/${ep}`;
return this._send('post', url);
}
/**
* @description Generating server and document keys by one of the participating nodes with one call.
*
* You can generate both keys simultaneously, but if you’re not trusting the Secret Store nodes, it is advised
* to run separate server key generation and document key storing sessions.
* More information can be found [here]{@link https://openethereum.github.io/wiki/Secret-Store#server-and-document-key-generation-session}.
*
* @param {string} serverKeyID The server key ID of your choosing. It would be good to use document contents hash as this identifier.
* Otherwise, it could be a random value. In both cases, please note that this value is unique and cannot be changed later.
* @param {string} signedServerKeyID The server key ID, signed with author’s private key.
* @param {number} threshold The key threshold value. Please consider the
* [guidelines]{@link https://openethereum.github.io/wiki/Secret-Store.html#server-key-generation-session} when choosing this value.
* @returns {Promise<string>} The hex-encoded document key, encrypted with requester’s public key (ECIES encryption is used).
*/
async generateServerAndDocumentKey(serverKeyID, signedServerKeyID, threshold) {
const url = `${this.url}/${utils_1.remove0x(serverKeyID)}/${utils_1.remove0x(signedServerKeyID)}/${threshold}`;
return utils_1.removeEnclosingDQuotes(await this._send('post', url));
}
/**
* @description Fetches the document key from the secret store.
*
* This session is a preferable way of retrieving the previously generated document key. During document key shadow retrieval
* session, document key is not reconstructed on any node, but it requires Secret Store client either to have access to Parity RPCs,
* or to run some EC calculations to decrypt the document key.
*
* Please note that the requester must have permission to access this key. Permissions are often managed by a permissioning contract.
*
* More information can be found [here]{@link https://openethereum.github.io/wiki/Secret-Store#document-key-shadow-retrieval-session}.
*
* @param {string} serverKeyID The ID of previously generated server key, to which the document key has been bound.
* @param {string} signedServerKeyID The server key ID, signed with the private key of requester, having access to the server key.
* @returns {Promise<DocumentKeyPortions>} The object containing the hex-encoded decrypted_secret, common_point and decrypt_shadows fields.
* To reconstruct the document key, Secret Store client must pass these values to a secretstore_shadowDecrypt RPC call.
*/
async shadowRetrieveDocumentKey(serverKeyID, signedServerKeyID) {
const url = `${this.url}/shadow/${utils_1.remove0x(serverKeyID)}/${utils_1.remove0x(signedServerKeyID)}`;
return this._send('get', url);
}
/**
* @description Fetches the document key from the Secret Store.
*
* This is the lighter version of the [document key shadow retrieval session]{@link https://openethereum.github.io/wiki/Secret-Store#document-key-shadow-retrieval-session},
* which returns the final document key (encrypted with the requester's public key).
* You must have enough trust in the Secret Store nodes for this. During document key shadow retrieval
* session, document key is not reconstructed on any node, but it requires the Secret Store client
* either to have access to Parity RPCs, or to run some EC calculations to decrypt the document key.
*
* Please note that the requester must have permission to access this key. Permissions are often managed by a permissioning contract.
*
* More information can be found [here]{@link https://openethereum.github.io/wiki/Secret-Store#document-key-retrieval-session}.
*
* @param {string} serverKeyID The ID of previously generated server key, to which document key has been bound.
* @param {string} signedServerKeyID The server key ID, signed with the private key of requester, having access to the server key.
* @returns {Promise<string>} The hex-encoded document key, encrypted with requester's public key (ECIES encryption is used).
*/
async retrieveDocumentKey(serverKeyID, signedServerKeyID) {
const url = `${this.url}/${utils_1.remove0x(serverKeyID)}/${utils_1.remove0x(signedServerKeyID)}`;
return utils_1.removeEnclosingDQuotes(await this._send('get', url));
}
/**
* @description Schnorr signing session, for computing Schnorr signature of a given 256-bit message hash.
*
* More information can be found [here]{@link https://openethereum.github.io/wiki/Secret-Store#schnorr-signing-session}.
*
* @param {string} serverKeyID The previously generated hex-encoded server key ID.
* @param {string} signedServerKeyID The hex-encoded, previously generated server key ID, signed with the private key of requester, having access to the server key.
* @param {string} messageHash The 256-bit hash of the message that needs to be signed.
* @returns {Promise<string>} The hex-encoded Schnorr signature (serialized as c || s),
* encrypted with requester's public key (ECIES encryption is used).
*/
async signSchnorr(serverKeyID, signedServerKeyID, messageHash) {
const url = `${this.url}/schnorr/${utils_1.remove0x(serverKeyID)}/${utils_1.remove0x(signedServerKeyID)}/${messageHash}`;
return utils_1.removeEnclosingDQuotes(await this._send('get', url));
}
/**
* @description ECDSA signing session, for computing ECDSA signature of a given 256-bit message hash.
*
* More information can be found [here]{@link https://openethereum.github.io/wiki/Secret-Store#ecdsa-signing-session}.
*
* @param {string} serverKeyID The previously generated hex-encoded server key ID.
* @param {string} signedServerKeyID The hex-encoded, previously generated server key ID signed with the private key of requester, having access to the server key.
* @param {string} messageHash The 256-bit hash of the message that needs to be signed.
* @returns {Promise<string>} The hex-encoded ECDSA signature (serialized as r || s || v ), encrypted with requester public key (ECIES encryption is used).
*/
async signEcdsa(serverKeyID, signedServerKeyID, messageHash) {
const url = `${this.url}/ecdsa/${utils_1.remove0x(serverKeyID)}/${utils_1.remove0x(signedServerKeyID)}/${messageHash}`;
return utils_1.removeEnclosingDQuotes(await this._send('get', url));
}
/**
*
* @description Node set change session.
*
* Please follow [the description]{@link https://openethereum.github.io/wiki/Secret-Store-Configuration.html#changing-the-configuration-of-a-set-of-servers}
* on how to perform this session.
*
* Requires all added, removed and stable nodes to be online for the duration
* of the session. Before starting the session, you’ll need to generate two administrator’s
* signatures: old set signature and new set signature. To generate these signatures,
* the Secret Store RPC methods should be used: serversSetHash and signRawHash.
*
* @param {string[]} nodeIDsNewSet Node IDs of the *new set*.
* @param {string} signatureOldSet ECDSA signature of all online node IDs *keccak(ordered_list(staying + added + removing))*.
* @param {string} signatureNewSet ECDSA signature of node IDs that should stay in the Secret Store cluster after the session ends *keccak(ordered_list(staying + added))*.
* @returns {Promise<string>} Empty string if everything was OK (status code 200).
*/
async nodesSetChange(nodeIDsNewSet, signatureOldSet, signatureNewSet) {
const url = `${this.url}/admin/servers_set_change/${utils_1.remove0x(signatureOldSet)}/${utils_1.remove0x(signatureNewSet)}`;
const body = JSON.stringify(nodeIDsNewSet);
return utils_1.removeEnclosingDQuotes(await this._send('post', url, body));
}
}
exports.SecretStoreSessionClient = SecretStoreSessionClient;
//# sourceMappingURL=session.js.map