UNPKG

@trezor/connect

Version:

High-level javascript interface for Trezor hardware wallet.

83 lines 3.44 kB
"use strict"; 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