@trezor/connect
Version:
High-level javascript interface for Trezor hardware wallet.
83 lines • 3.44 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getFirmwareReleaseConfig = exports.RELEASES_URL_REMOTE = exports.RELEASES_URL_REMOTE_BASE = void 0;
const jws_1 = require("jws");
const env_utils_1 = require("@trezor/env-utils");
const assetUtils_1 = require("./assetUtils");
const JWS_SIGN_ALGORITHM = 'ES256';
const VERSION = 1;
const JWS_RELEASES_FILENAME_REMOTE = `releases.v${VERSION}.jws`;
exports.RELEASES_URL_REMOTE_BASE = 'https://data.trezor.io/suite/firmware';
exports.RELEASES_URL_REMOTE = {
production: `${exports.RELEASES_URL_REMOTE_BASE}/production/${JWS_RELEASES_FILENAME_REMOTE}`,
'test-unsigned': `${exports.RELEASES_URL_REMOTE_BASE}/unsigned/${JWS_RELEASES_FILENAME_REMOTE}`,
'test-signed': `${exports.RELEASES_URL_REMOTE_BASE}/signed/${JWS_RELEASES_FILENAME_REMOTE}`,
};
const FORCE_LOCAL_JWS = true;
const getReleaseJWS = async (firmwareUpdateSource = 'production') => {
if (FORCE_LOCAL_JWS) {
return {
releasesJws: assetUtils_1.firmwareReleaseConfigAssets.jws,
isRemote: false,
};
}
const remoteReleasesUrl = exports.RELEASES_URL_REMOTE[firmwareUpdateSource];
try {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 5000);
const response = await fetch(remoteReleasesUrl, {
signal: controller.signal,
});
clearTimeout(timeoutId);
if (!response.ok) {
throw new Error(response.statusText);
}
const releasesJws = await response.text();
return {
releasesJws,
isRemote: true,
};
}
catch (error) {
console.error(`Fetching of remote JWS config failed: ${error}`);
return {
releasesJws: assetUtils_1.firmwareReleaseConfigAssets.jws,
isRemote: false,
};
}
};
const getFirmwareReleaseConfig = async () => {
const { releasesJws, isRemote } = await getReleaseJWS();
const decodedJws = (0, jws_1.decode)(releasesJws);
if (!decodedJws) {
throw new Error('Decoding of releases failed.');
}
if (isRemote) {
const decodedJwsLocal = (0, jws_1.decode)(assetUtils_1.firmwareReleaseConfigAssets.jws);
if (decodedJwsLocal && decodedJwsLocal.payload.sequence > decodedJws.payload.sequence) {
throw new Error('Local firmware release config cannot have greater sequence than remote.');
}
}
const algorithmInHeader = decodedJws?.header.alg;
if (algorithmInHeader !== JWS_SIGN_ALGORITHM) {
throw Error(`Wrong algorithm in JWS config header: ${algorithmInHeader}`);
}
const JWSPublicKey = (0, env_utils_1.getJWSPublicKey)('firmware-release');
if (!JWSPublicKey) {
throw new Error('JWS public key is not defined!');
}
try {
const isAuthenticityValid = (0, jws_1.verify)(releasesJws, JWS_SIGN_ALGORITHM, JWSPublicKey);
if (!isAuthenticityValid) {
throw new Error('Config authenticity is invalid');
}
const releases = JSON.parse(decodedJws.payload);
return releases;
}
catch (error) {
console.error('Error validating:', error);
throw new Error(`Failed to validate release message: ${error.message}`);
}
};
exports.getFirmwareReleaseConfig = getFirmwareReleaseConfig;
//# sourceMappingURL=firmwareReleaseConfigUtils.js.map