@trezor/connect 9.1.3 → 9.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +36 -0
- package/README.md +3 -1
- package/lib/api/authenticateDevice.d.ts +7 -0
- package/lib/api/authenticateDevice.js +51 -0
- package/lib/api/bitcoin/TransactionComposer.js +1 -9
- package/lib/api/bitcoin/inputs.d.ts +2 -2
- package/lib/api/bitcoin/outputs.d.ts +2 -2
- package/lib/api/cardanoGetPublicKey.d.ts +6 -2
- package/lib/api/cardanoGetPublicKey.js +7 -1
- package/lib/api/checkFirmwareAuthenticity.js +9 -8
- package/lib/api/common/paramsValidator.js +46 -52
- package/lib/api/eos/eosSignTx.js +1 -1
- package/lib/api/ethereum/ethereumDefinitions.js +3 -2
- package/lib/api/firmware/getBinary.js +1 -1
- package/lib/api/firmware/verifyAuthenticityProof.d.ts +14 -0
- package/lib/api/firmware/verifyAuthenticityProof.js +103 -0
- package/lib/api/firmware/x509certificate.d.ts +73 -0
- package/lib/api/firmware/x509certificate.js +203 -0
- package/lib/api/firmwareUpdate.js +4 -4
- package/lib/api/getAccountInfo.d.ts +1 -1
- package/lib/api/getAccountInfo.js +6 -6
- package/lib/api/getFirmwareHash.js +1 -4
- package/lib/api/getPublicKey.d.ts +2 -1
- package/lib/api/getPublicKey.js +7 -1
- package/lib/api/index.d.ts +1 -0
- package/lib/api/index.js +4 -2
- package/lib/api/rebootToBootloader.js +1 -4
- package/lib/api/signTransaction.js +1 -1
- package/lib/core/AbstractMethod.d.ts +5 -4
- package/lib/core/AbstractMethod.js +13 -11
- package/lib/core/index.d.ts +3 -2
- package/lib/core/index.js +23 -12
- package/lib/core/method.d.ts +1 -1
- package/lib/data/DataManager.d.ts +53 -7
- package/lib/data/DataManager.js +4 -2
- package/lib/data/coinInfo.d.ts +5 -5
- package/lib/data/coinInfo.js +1 -1
- package/lib/data/config.d.ts +52 -6
- package/lib/data/config.js +39 -28
- package/lib/data/connectSettings.js +3 -0
- package/lib/data/deviceAuthenticityConfig.d.ts +15 -0
- package/lib/data/deviceAuthenticityConfig.js +26 -0
- package/lib/data/firmwareInfo.d.ts +3 -2
- package/lib/data/firmwareInfo.js +19 -11
- package/lib/data/models.d.ts +21 -0
- package/lib/data/models.js +24 -0
- package/lib/data/version.d.ts +1 -1
- package/lib/data/version.js +1 -1
- package/lib/device/Device.d.ts +5 -3
- package/lib/device/Device.js +37 -22
- package/lib/device/DeviceCommands.js +4 -4
- package/lib/device/DeviceList.d.ts +2 -1
- package/lib/device/DeviceList.js +10 -3
- package/lib/events/iframe.d.ts +7 -1
- package/lib/events/iframe.js +1 -0
- package/lib/events/ui-promise.d.ts +10 -2
- package/lib/factory.js +1 -0
- package/lib/types/api/authenticateDevice.d.ts +21 -0
- package/lib/types/api/authenticateDevice.js +3 -0
- package/lib/types/api/authorizeCoinjoin.d.ts +2 -2
- package/lib/types/api/binance/index.d.ts +2 -1
- package/lib/types/api/bitcoin/index.d.ts +6 -5
- package/lib/types/api/cardano/index.d.ts +12 -12
- package/lib/types/api/cipherKeyValue.d.ts +2 -2
- package/lib/types/api/eos/index.d.ts +3 -2
- package/lib/types/api/ethereum/index.d.ts +5 -4
- package/lib/types/api/getAccountInfo.d.ts +1 -0
- package/lib/types/api/getOwnershipId.d.ts +2 -2
- package/lib/types/api/getOwnershipProof.d.ts +2 -2
- package/lib/types/api/index.d.ts +2 -0
- package/lib/types/api/nem/index.d.ts +2 -1
- package/lib/types/api/ripple/index.d.ts +2 -1
- package/lib/types/api/stellar/index.d.ts +2 -1
- package/lib/types/api/tezos/index.d.ts +3 -2
- package/lib/types/api/unlockPath.d.ts +2 -2
- package/lib/types/coinInfo.d.ts +3 -2
- package/lib/types/device.d.ts +6 -0
- package/lib/types/firmware.d.ts +8 -4
- package/lib/types/index.d.ts +1 -0
- package/lib/types/params.d.ts +14 -2
- package/lib/utils/assetUtils.js +6 -4
- package/lib/utils/debug.d.ts +9 -3
- package/lib/utils/debug.js +50 -17
- package/lib/utils/deviceFeaturesUtils.js +7 -7
- package/lib/utils/pathUtils.d.ts +3 -3
- package/package.json +14 -13
- package/lib/utils/deferred.d.ts +0 -18
- package/lib/utils/deferred.js +0 -66
- package/lib/utils/versionUtils.d.ts +0 -8
- package/lib/utils/versionUtils.js +0 -75
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,39 @@
|
|
|
1
|
+
# 9.1.5
|
|
2
|
+
|
|
3
|
+
- feat(suite): T2B1 replace Model R name by official Trezor Safe 3 name (7460372ed1)
|
|
4
|
+
- feat(connect): add authenticateDevice method (45b99c0813, af907a296d, 249ddc358a)
|
|
5
|
+
- feat(connect): btg, dash, dgb, nmc, vrc no support for T2B1 (0819ff6fc1)
|
|
6
|
+
- feat(suite): support t2b1 firmware installation (9ef2bf627a)
|
|
7
|
+
- fix(connect): get firmware status and release after ensuring internal model (dca3333c2d)
|
|
8
|
+
- fix(connect-popup): webusb in popup if iframe is on same origin as host (e571971586)
|
|
9
|
+
- feat(connect-web): trust-issues query string param (b1b6e3f287)
|
|
10
|
+
- feat(connect-plugin-stellar): Update stellar-sdk and stellar-base (ee7e67db04)
|
|
11
|
+
- chore(connect): t1 emulator with pin (33c6ca58bf)
|
|
12
|
+
- fix(connect-popup): allow decimal custom fee entry (bf20f23f05, 8a8d93b5e8)
|
|
13
|
+
- feat(connect-explorer): add rebootToBootloader method (9996676358)
|
|
14
|
+
- fix(connect): wrong version format in discovery (19b13d1d4c)
|
|
15
|
+
- feat(connect-popup): logger in sharedworker collecting from all environments (732bc7d, 2521c7c, 6501dfa4fd)
|
|
16
|
+
- chore(connect): do not lowercase device color (7229b88c20)
|
|
17
|
+
|
|
18
|
+
# 9.1.4
|
|
19
|
+
|
|
20
|
+
- feat(connect-popup): add metamask extension id to known third party (f137b3e4d6)
|
|
21
|
+
- test(connect): composeTransaction fix doge fee (69a92483c6)
|
|
22
|
+
- refactor(connect): remove doge fee branch (c79f3f25d8)
|
|
23
|
+
- feat(transport): udp support for transport methods (65e617195c)
|
|
24
|
+
- fix(connect): accept signTransaction inputs/outputs with `address_n: string` (82910e0766)
|
|
25
|
+
- fix(connect-explorer, connect-popup): add favicon (cafb574ada, c6071123f3)
|
|
26
|
+
- feat(connect-popup): use trezor icons with display off from suite-data (1c806519a7)
|
|
27
|
+
- feat(connect): trezor color in device object (31535e2b0f)
|
|
28
|
+
- feat(connect): trezor name in device object (a0ecb66390)
|
|
29
|
+
- feat(connect-common): copy models.json from submodules (6d80197523)
|
|
30
|
+
- fix(connect-iframe): device event not propagating to host (d35e37863a)
|
|
31
|
+
- feat(connect, suite): unify no backup warning button text (375f3fa1a1)
|
|
32
|
+
- feat(connect): add suppressBackupWarning param to getPublicKey and getAccountInfo (2c2698d8af)
|
|
33
|
+
- fix(type-check): connect-web includes connect-iframe package.json (f9f576ab66)
|
|
34
|
+
- fix(connect-iframe): method.initAsync method superfluous call (37ace99a5d)
|
|
35
|
+
- fix(connect-iframe): define plugin in build to support analytics (c793ce358c)
|
|
36
|
+
|
|
1
37
|
# 9.1.3
|
|
2
38
|
|
|
3
39
|
- fix(connect): correct import of internal connect dependency (https://github.com/trezor/trezor-suite/issues/9389)
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @trezor/connect
|
|
2
2
|
|
|
3
|
-
API version 9.1.
|
|
3
|
+
API version 9.1.5
|
|
4
4
|
|
|
5
5
|
[](https://github.com/trezor/trezor-suite/actions/workflows/connect-test.yml)
|
|
6
6
|
[](https://www.npmjs.org/package/@trezor/connect)
|
|
@@ -47,6 +47,8 @@ Version 9 is available as `@trezor/connect` and `@trezor/connect-web` npm packag
|
|
|
47
47
|
|
|
48
48
|
New major version is released when there are breaking changes on API level. Previous major version will be maintained for 12 months and after this period it can be taken down without notice.
|
|
49
49
|
|
|
50
|
+
Current major version 9 is being developed on top of `develop` branch. When there is a new major version a new branch should be created (`v-<major-version>`) and mantained separately.
|
|
51
|
+
|
|
50
52
|
### Minor version
|
|
51
53
|
|
|
52
54
|
Minor versions are released when there are:
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { AbstractMethod } from '../core/AbstractMethod';
|
|
2
|
+
import { AuthenticateDeviceParams } from '../types/api/authenticateDevice';
|
|
3
|
+
export default class AuthenticateDevice extends AbstractMethod<'authenticateDevice', AuthenticateDeviceParams> {
|
|
4
|
+
init(): void;
|
|
5
|
+
run(): Promise<import("../types/api/authenticateDevice").AuthenticateDeviceResult>;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=authenticateDevice.d.ts.map
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const AbstractMethod_1 = require("../core/AbstractMethod");
|
|
4
|
+
const events_1 = require("../events");
|
|
5
|
+
const paramsValidator_1 = require("./common/paramsValidator");
|
|
6
|
+
const deviceAuthenticityConfig_1 = require("../data/deviceAuthenticityConfig");
|
|
7
|
+
const verifyAuthenticityProof_1 = require("./firmware/verifyAuthenticityProof");
|
|
8
|
+
class AuthenticateDevice extends AbstractMethod_1.AbstractMethod {
|
|
9
|
+
init() {
|
|
10
|
+
this.useEmptyPassphrase = true;
|
|
11
|
+
this.allowDeviceMode = [events_1.UI.INITIALIZE, events_1.UI.SEEDLESS];
|
|
12
|
+
this.requiredPermissions = ['management'];
|
|
13
|
+
this.useDeviceState = false;
|
|
14
|
+
this.firmwareRange = (0, paramsValidator_1.getFirmwareRange)(this.name, null, this.firmwareRange);
|
|
15
|
+
const { payload } = this;
|
|
16
|
+
(0, paramsValidator_1.validateParams)(payload, [
|
|
17
|
+
{ name: 'config', type: 'object' },
|
|
18
|
+
{ name: 'allowDebugKeys', type: 'boolean' },
|
|
19
|
+
]);
|
|
20
|
+
if (payload.config) {
|
|
21
|
+
(0, paramsValidator_1.validateParams)(payload.config, [{ name: 'timestamp', type: 'string', required: true }]);
|
|
22
|
+
(0, paramsValidator_1.validateParams)(payload.config.T2B1, [
|
|
23
|
+
{ name: 'rootPubKeys', type: 'array', required: true },
|
|
24
|
+
{ name: 'caPubKeys', type: 'array', required: true },
|
|
25
|
+
]);
|
|
26
|
+
}
|
|
27
|
+
this.params = {
|
|
28
|
+
config: payload.config,
|
|
29
|
+
allowDebugKeys: payload.allowDebugKeys,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
async run() {
|
|
33
|
+
const challenge = (0, verifyAuthenticityProof_1.getRandomChallenge)();
|
|
34
|
+
const { message } = await this.device
|
|
35
|
+
.getCommands()
|
|
36
|
+
.typedCall('AuthenticateDevice', 'AuthenticityProof', {
|
|
37
|
+
challenge: challenge.toString('hex'),
|
|
38
|
+
});
|
|
39
|
+
const config = this.params.config || deviceAuthenticityConfig_1.deviceAuthenticityConfig;
|
|
40
|
+
const valid = await (0, verifyAuthenticityProof_1.verifyAuthenticityProof)({
|
|
41
|
+
...message,
|
|
42
|
+
challenge,
|
|
43
|
+
config,
|
|
44
|
+
allowDebugKeys: this.params.allowDebugKeys,
|
|
45
|
+
deviceModel: this.device.features.internal_model,
|
|
46
|
+
});
|
|
47
|
+
return valid;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
exports.default = AuthenticateDevice;
|
|
51
|
+
//# sourceMappingURL=authenticateDevice.js.map
|
|
@@ -121,14 +121,6 @@ class TransactionComposer {
|
|
|
121
121
|
const changeAddress = addresses.change.find(a => !a.transfers) ||
|
|
122
122
|
addresses.change[addresses.change.length - 1];
|
|
123
123
|
const changeId = (0, pathUtils_1.getHDPath)(changeAddress.path).slice(-1)[0];
|
|
124
|
-
const enhancement = {
|
|
125
|
-
baseFee,
|
|
126
|
-
floorBaseFee: false,
|
|
127
|
-
dustOutputFee: 0,
|
|
128
|
-
};
|
|
129
|
-
if (coinInfo.shortcut === 'DOGE') {
|
|
130
|
-
enhancement.dustOutputFee = 1000000;
|
|
131
|
-
}
|
|
132
124
|
return (0, utxo_lib_1.composeTx)({
|
|
133
125
|
txType: account.type,
|
|
134
126
|
utxos: this.utxos,
|
|
@@ -142,7 +134,7 @@ class TransactionComposer {
|
|
|
142
134
|
changeId,
|
|
143
135
|
changeAddress: changeAddress.address,
|
|
144
136
|
dustThreshold: coinInfo.dustLimit,
|
|
145
|
-
|
|
137
|
+
baseFee,
|
|
146
138
|
});
|
|
147
139
|
}
|
|
148
140
|
dispose() {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { ComposedTxInput } from '@trezor/utxo-lib';
|
|
2
2
|
import type { TypedRawTransaction } from '@trezor/blockchain-link';
|
|
3
|
-
import type { BitcoinNetworkInfo } from '../../types';
|
|
3
|
+
import type { BitcoinNetworkInfo, ProtoWithDerivationPath } from '../../types';
|
|
4
4
|
import type { PROTO } from '../../constants';
|
|
5
|
-
export declare const validateTrezorInputs: (inputs: PROTO.TxInputType[], coinInfo: BitcoinNetworkInfo) => PROTO.TxInputType[];
|
|
5
|
+
export declare const validateTrezorInputs: (inputs: ProtoWithDerivationPath<PROTO.TxInputType>[], coinInfo: BitcoinNetworkInfo) => PROTO.TxInputType[];
|
|
6
6
|
export declare const enhanceTrezorInputs: (inputs: PROTO.TxInputType[], rawTxs: TypedRawTransaction[]) => void;
|
|
7
7
|
export declare const inputToTrezor: (input: ComposedTxInput, sequence: number) => PROTO.TxInputType;
|
|
8
8
|
//# sourceMappingURL=inputs.d.ts.map
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { ComposeOutput as UtxoLibOutput, ComposedTxOutput } from '@trezor/utxo-lib';
|
|
2
2
|
import { PROTO } from '../../constants';
|
|
3
|
-
import type { BitcoinNetworkInfo } from '../../types';
|
|
3
|
+
import type { BitcoinNetworkInfo, ProtoWithDerivationPath } from '../../types';
|
|
4
4
|
import type { ComposeOutput } from '../../types/api/composeTransaction';
|
|
5
|
-
export declare const validateTrezorOutputs: (outputs: PROTO.TxOutputType[], coinInfo: BitcoinNetworkInfo) => PROTO.TxOutputType[];
|
|
5
|
+
export declare const validateTrezorOutputs: (outputs: ProtoWithDerivationPath<PROTO.TxOutputType>[], coinInfo: BitcoinNetworkInfo) => PROTO.TxOutputType[];
|
|
6
6
|
export declare const validateHDOutput: (output: ComposeOutput, coinInfo: BitcoinNetworkInfo) => UtxoLibOutput;
|
|
7
7
|
export declare const outputToTrezor: (output: ComposedTxOutput, _coinInfo: BitcoinNetworkInfo) => PROTO.TxOutputType;
|
|
8
8
|
//# sourceMappingURL=outputs.d.ts.map
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import { PROTO } from '../constants';
|
|
2
2
|
import { AbstractMethod } from '../core/AbstractMethod';
|
|
3
|
-
|
|
3
|
+
interface Params extends PROTO.CardanoGetPublicKey {
|
|
4
|
+
suppressBackupWarning?: boolean;
|
|
5
|
+
}
|
|
6
|
+
export default class CardanoGetPublicKey extends AbstractMethod<'cardanoGetPublicKey', Params[]> {
|
|
4
7
|
hasBundle?: boolean;
|
|
5
8
|
confirmed?: boolean;
|
|
6
9
|
init(): void;
|
|
7
10
|
get info(): string;
|
|
8
11
|
confirmation(): Promise<boolean>;
|
|
9
|
-
noBackupConfirmation(): Promise<boolean>;
|
|
12
|
+
noBackupConfirmation(allowSuppression?: boolean): Promise<boolean>;
|
|
10
13
|
run(): Promise<import("..").CardanoPublicKey | import("..").CardanoPublicKey[]>;
|
|
11
14
|
}
|
|
15
|
+
export {};
|
|
12
16
|
//# sourceMappingURL=cardanoGetPublicKey.d.ts.map
|
|
@@ -20,6 +20,7 @@ class CardanoGetPublicKey extends AbstractMethod_1.AbstractMethod {
|
|
|
20
20
|
{ name: 'path', required: true },
|
|
21
21
|
{ name: 'derivationType', type: 'number' },
|
|
22
22
|
{ name: 'showOnTrezor', type: 'boolean' },
|
|
23
|
+
{ name: 'suppressBackupWarning', type: 'boolean' },
|
|
23
24
|
]);
|
|
24
25
|
const path = (0, pathUtils_1.validatePath)(batch.path, 3);
|
|
25
26
|
return {
|
|
@@ -28,6 +29,7 @@ class CardanoGetPublicKey extends AbstractMethod_1.AbstractMethod {
|
|
|
28
29
|
? batch.derivationType
|
|
29
30
|
: constants_1.PROTO.CardanoDerivationType.ICARUS_TREZOR,
|
|
30
31
|
show_display: typeof batch.showOnTrezor === 'boolean' ? batch.showOnTrezor : false,
|
|
32
|
+
suppress_backup_warning: batch.suppressBackupWarning,
|
|
31
33
|
};
|
|
32
34
|
});
|
|
33
35
|
}
|
|
@@ -54,7 +56,11 @@ class CardanoGetPublicKey extends AbstractMethod_1.AbstractMethod {
|
|
|
54
56
|
this.confirmed = uiResp.payload;
|
|
55
57
|
return this.confirmed;
|
|
56
58
|
}
|
|
57
|
-
async noBackupConfirmation() {
|
|
59
|
+
async noBackupConfirmation(allowSuppression) {
|
|
60
|
+
if (allowSuppression &&
|
|
61
|
+
this.params.every(batch => batch.suppressBackupWarning || !batch.show_display)) {
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
58
64
|
await this.getPopupPromise().promise;
|
|
59
65
|
const uiPromise = this.createUiPromise(events_1.UI.RECEIVE_CONFIRMATION);
|
|
60
66
|
this.postMessage((0, events_1.createUiMessage)(events_1.UI.REQUEST_CONFIRMATION, {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const
|
|
4
|
-
const randombytes_1 = tslib_1.__importDefault(require("randombytes"));
|
|
3
|
+
const crypto_1 = require("crypto");
|
|
5
4
|
const AbstractMethod_1 = require("../core/AbstractMethod");
|
|
6
5
|
const firmware_1 = require("./firmware");
|
|
7
6
|
const firmwareInfo_1 = require("../data/firmwareInfo");
|
|
@@ -15,20 +14,22 @@ class CheckFirmwareAuthenticity extends AbstractMethod_1.AbstractMethod {
|
|
|
15
14
|
this.useDeviceState = false;
|
|
16
15
|
}
|
|
17
16
|
async run() {
|
|
17
|
+
var _a;
|
|
18
18
|
const { device } = this;
|
|
19
|
-
const
|
|
20
|
-
const releases = (0, firmwareInfo_1.getReleases)(device.features.
|
|
21
|
-
const release = releases.find(release => release.version.join('.') ===
|
|
19
|
+
const firmwareVersion = `${device.features.major_version}.${device.features.minor_version}.${device.features.patch_version}`;
|
|
20
|
+
const releases = (0, firmwareInfo_1.getReleases)((_a = device.features) === null || _a === void 0 ? void 0 : _a.internal_model);
|
|
21
|
+
const release = releases.find(release => release.version.join('.') === firmwareVersion);
|
|
22
22
|
if (!release) {
|
|
23
23
|
throw constants_1.ERRORS.TypedError('Runtime', 'checkFirmwareAuthenticity: No release found for device firmware');
|
|
24
24
|
}
|
|
25
|
-
const
|
|
26
|
-
const
|
|
25
|
+
const deviceModelPath = `${device.features.internal_model}`.toLowerCase();
|
|
26
|
+
const baseUrl = `https://data.trezor.io/firmware/${deviceModelPath}`;
|
|
27
|
+
const fwUrl = `${baseUrl}/trezor-${deviceModelPath}-${firmwareVersion}${device.firmwareType === types_1.FirmwareType.BitcoinOnly ? '-bitcoinonly.bin' : '.bin'}`;
|
|
27
28
|
const fw = await (0, assets_1.httpRequest)(fwUrl, 'binary');
|
|
28
29
|
if (!fw) {
|
|
29
30
|
throw constants_1.ERRORS.TypedError('Runtime', 'checkFirmwareAuthenticity: firmware binary not found');
|
|
30
31
|
}
|
|
31
|
-
const { hash: expectedFirmwareHash, challenge } = (0, firmware_1.calculateFirmwareHash)(device.features.major_version, (0, firmware_1.stripFwHeaders)(fw), (0,
|
|
32
|
+
const { hash: expectedFirmwareHash, challenge } = (0, firmware_1.calculateFirmwareHash)(device.features.major_version, (0, firmware_1.stripFwHeaders)(fw), (0, crypto_1.randomBytes)(32));
|
|
32
33
|
const result = await this.device
|
|
33
34
|
.getCommands()
|
|
34
35
|
.typedCall('GetFirmwareHash', 'FirmwareHash', {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getFirmwareRange = exports.validateCoinPath = exports.validateParams = void 0;
|
|
4
|
+
const utils_1 = require("@trezor/utils");
|
|
4
5
|
const constants_1 = require("../../constants");
|
|
5
6
|
const pathUtils_1 = require("../../utils/pathUtils");
|
|
6
|
-
const versionUtils_1 = require("../../utils/versionUtils");
|
|
7
7
|
const config_1 = require("../../data/config");
|
|
8
8
|
const invalidParameter = (message) => constants_1.ERRORS.TypedError('Method_InvalidParameter', message);
|
|
9
9
|
function validateParams(params, schema) {
|
|
@@ -68,25 +68,22 @@ const validateCoinPath = (path, coinInfo) => {
|
|
|
68
68
|
};
|
|
69
69
|
exports.validateCoinPath = validateCoinPath;
|
|
70
70
|
const getFirmwareRange = (method, coinInfo, currentRange) => {
|
|
71
|
-
const
|
|
71
|
+
const range = JSON.parse(JSON.stringify(currentRange));
|
|
72
|
+
const models = Object.keys(range);
|
|
72
73
|
if (coinInfo) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
else if ((0, versionUtils_1.versionCompare)(coinInfo.support.trezor2, current['2'].min) > 0) {
|
|
83
|
-
current['2'].min = coinInfo.support.trezor2;
|
|
84
|
-
}
|
|
74
|
+
models.forEach(model => {
|
|
75
|
+
if (!coinInfo.support || typeof coinInfo.support[model] !== 'string') {
|
|
76
|
+
range[model].min = '0';
|
|
77
|
+
}
|
|
78
|
+
else if (range[model].min !== '0' &&
|
|
79
|
+
utils_1.versionUtils.isNewer(coinInfo.support[model], range[model].min)) {
|
|
80
|
+
range[model].min = coinInfo.support[model];
|
|
81
|
+
}
|
|
82
|
+
});
|
|
85
83
|
}
|
|
86
|
-
const coinType = coinInfo ? coinInfo.type
|
|
87
|
-
const shortcut = coinInfo ? coinInfo.shortcut.toLowerCase()
|
|
88
|
-
const
|
|
89
|
-
const ranges = supportedFirmware
|
|
84
|
+
const coinType = coinInfo === null || coinInfo === void 0 ? void 0 : coinInfo.type;
|
|
85
|
+
const shortcut = coinInfo === null || coinInfo === void 0 ? void 0 : coinInfo.shortcut.toLowerCase();
|
|
86
|
+
const configRules = config_1.config.supportedFirmware
|
|
90
87
|
.filter(rule => {
|
|
91
88
|
if (rule.methods) {
|
|
92
89
|
return rule.methods.includes(method);
|
|
@@ -96,45 +93,42 @@ const getFirmwareRange = (method, coinInfo, currentRange) => {
|
|
|
96
93
|
}
|
|
97
94
|
return true;
|
|
98
95
|
})
|
|
99
|
-
.filter(
|
|
100
|
-
if (
|
|
101
|
-
return
|
|
96
|
+
.filter(rule => {
|
|
97
|
+
if (rule.coinType) {
|
|
98
|
+
return rule.coinType === coinType;
|
|
102
99
|
}
|
|
103
|
-
if (
|
|
104
|
-
return (typeof
|
|
100
|
+
if (rule.coin) {
|
|
101
|
+
return (typeof rule.coin === 'string' ? [rule.coin] : rule.coin).includes(shortcut);
|
|
105
102
|
}
|
|
106
|
-
return
|
|
103
|
+
return rule.methods || rule.capabilities;
|
|
107
104
|
});
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
(0, versionUtils_1.versionCompare)(current['2'].max, t2) < 0) {
|
|
133
|
-
current['2'].max = t2;
|
|
134
|
-
}
|
|
105
|
+
configRules.forEach(rule => {
|
|
106
|
+
if (rule.min) {
|
|
107
|
+
models.forEach(model => {
|
|
108
|
+
const modelMin = rule.min[model];
|
|
109
|
+
if (modelMin) {
|
|
110
|
+
if (modelMin === '0' ||
|
|
111
|
+
range[model].min === '0' ||
|
|
112
|
+
!utils_1.versionUtils.isNewerOrEqual(range[model].min, modelMin)) {
|
|
113
|
+
range[model].min = modelMin;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
if (rule.max) {
|
|
119
|
+
models.forEach(model => {
|
|
120
|
+
const modelMax = rule.max[model];
|
|
121
|
+
if (modelMax) {
|
|
122
|
+
if (modelMax === '0' ||
|
|
123
|
+
range[model].max === '0' ||
|
|
124
|
+
!utils_1.versionUtils.isNewerOrEqual(range[model].max, modelMax)) {
|
|
125
|
+
range[model].max = modelMax;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
});
|
|
135
129
|
}
|
|
136
130
|
});
|
|
137
|
-
return
|
|
131
|
+
return range;
|
|
138
132
|
};
|
|
139
133
|
exports.getFirmwareRange = getFirmwareRange;
|
|
140
134
|
//# sourceMappingURL=paramsValidator.js.map
|
package/lib/api/eos/eosSignTx.js
CHANGED
|
@@ -102,7 +102,7 @@ const parseAuth = (a) => {
|
|
|
102
102
|
const key = Buffer.from(bs58.decode(pk.substring(len)));
|
|
103
103
|
return {
|
|
104
104
|
type: 0,
|
|
105
|
-
key: key.
|
|
105
|
+
key: key.subarray(0, key.length - 4).toString('hex'),
|
|
106
106
|
};
|
|
107
107
|
};
|
|
108
108
|
return {
|
|
@@ -93,8 +93,9 @@ const ethereumNetworkInfoFromDefinition = (definition) => ({
|
|
|
93
93
|
shortcut: definition.symbol,
|
|
94
94
|
support: {
|
|
95
95
|
connect: true,
|
|
96
|
-
|
|
97
|
-
|
|
96
|
+
T1B1: '1.6.2',
|
|
97
|
+
T2T1: '2.0.7',
|
|
98
|
+
T2B1: '2.6.1',
|
|
98
99
|
},
|
|
99
100
|
blockchainLink: undefined,
|
|
100
101
|
});
|
|
@@ -10,7 +10,7 @@ const getBinary = ({ features, releases, baseUrl, version, btcOnly, intermediary
|
|
|
10
10
|
throw new Error('Features of unexpected shape provided');
|
|
11
11
|
}
|
|
12
12
|
if (intermediaryVersion) {
|
|
13
|
-
return (0, assets_1.httpRequest)(`${baseUrl}/firmware/
|
|
13
|
+
return (0, assets_1.httpRequest)(`${baseUrl}/firmware/t1b1/trezor-t1b1-inter-v${intermediaryVersion}.bin`, 'binary');
|
|
14
14
|
}
|
|
15
15
|
const infoByBootloader = (0, firmwareInfo_1.getInfo)({ features, releases });
|
|
16
16
|
const releaseByFirmware = releases.find(r => version &&
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { PROTO } from '../../constants';
|
|
3
|
+
import { DeviceAuthenticityConfig } from '../../data/deviceAuthenticityConfig';
|
|
4
|
+
import { AuthenticateDeviceResult } from '../../types/api/authenticateDevice';
|
|
5
|
+
interface AuthenticityProofData extends PROTO.AuthenticityProof {
|
|
6
|
+
challenge: Buffer;
|
|
7
|
+
config: DeviceAuthenticityConfig;
|
|
8
|
+
allowDebugKeys?: boolean;
|
|
9
|
+
deviceModel: keyof typeof PROTO.DeviceModelInternal;
|
|
10
|
+
}
|
|
11
|
+
export declare const getRandomChallenge: () => Buffer;
|
|
12
|
+
export declare const verifyAuthenticityProof: ({ certificates, signature, challenge, config, allowDebugKeys, deviceModel, }: AuthenticityProofData) => Promise<AuthenticateDeviceResult>;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=verifyAuthenticityProof.d.ts.map
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.verifyAuthenticityProof = exports.getRandomChallenge = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const crypto = tslib_1.__importStar(require("crypto"));
|
|
6
|
+
const utils_1 = require("@trezor/utils");
|
|
7
|
+
const x509certificate_1 = require("./x509certificate");
|
|
8
|
+
const verifySignature = async (rawKey, data, signature) => {
|
|
9
|
+
const signer = crypto.createVerify('sha256');
|
|
10
|
+
signer.update(Buffer.from(data));
|
|
11
|
+
const SubtleCrypto = typeof window !== 'undefined' ? window.crypto.subtle : crypto.subtle;
|
|
12
|
+
if (!SubtleCrypto) {
|
|
13
|
+
throw new Error('SubtleCrypto not supported');
|
|
14
|
+
}
|
|
15
|
+
const ecPubKey = await SubtleCrypto.importKey('raw', rawKey, { name: 'ECDSA', namedCurve: 'P-256' }, true, ['verify']);
|
|
16
|
+
const spkiPubKey = await SubtleCrypto.exportKey('spki', ecPubKey);
|
|
17
|
+
const key = `-----BEGIN PUBLIC KEY-----\n${Buffer.from(spkiPubKey).toString('base64')}\n-----END PUBLIC KEY-----`;
|
|
18
|
+
return signer.verify({ key }, Buffer.from(signature));
|
|
19
|
+
};
|
|
20
|
+
const getRandomChallenge = () => crypto.randomBytes(32);
|
|
21
|
+
exports.getRandomChallenge = getRandomChallenge;
|
|
22
|
+
const verifyAuthenticityProof = async ({ certificates, signature, challenge, config, allowDebugKeys, deviceModel, }) => {
|
|
23
|
+
const modelConfig = config[deviceModel];
|
|
24
|
+
if (!modelConfig) {
|
|
25
|
+
throw new Error(`Pubkeys for ${deviceModel} not found in config`);
|
|
26
|
+
}
|
|
27
|
+
const { caPubKeys, debug } = modelConfig;
|
|
28
|
+
const caCert = (0, x509certificate_1.parseCertificate)(new Uint8Array(Buffer.from(certificates[1], 'hex')));
|
|
29
|
+
const caPubKey = Buffer.from(caCert.tbsCertificate.subjectPublicKeyInfo.bits.bytes).toString('hex');
|
|
30
|
+
const deviceCert = (0, x509certificate_1.parseCertificate)(new Uint8Array(Buffer.from(certificates[0], 'hex')));
|
|
31
|
+
const rootPubKeys = allowDebugKeys
|
|
32
|
+
? modelConfig.rootPubKeys.concat((debug === null || debug === void 0 ? void 0 : debug.rootPubKeys) || [])
|
|
33
|
+
: modelConfig.rootPubKeys;
|
|
34
|
+
const isCertSignedByRootPubkey = await Promise.all(rootPubKeys.map(rootPubKey => verifySignature(Buffer.from(rootPubKey, 'hex'), caCert.tbsCertificate.asn1.raw, caCert.signatureValue.bits.bytes)));
|
|
35
|
+
const rootPubKeyIndex = isCertSignedByRootPubkey.findIndex(valid => !!valid);
|
|
36
|
+
const rootPubKey = rootPubKeys[rootPubKeyIndex];
|
|
37
|
+
const isDebugRootPubKey = debug === null || debug === void 0 ? void 0 : debug.rootPubKeys.includes(rootPubKey);
|
|
38
|
+
const caCertValidityFrom = caCert.tbsCertificate.validity.from.getTime();
|
|
39
|
+
if (caCertValidityFrom > new Date().getTime()) {
|
|
40
|
+
throw new Error(`CA validity from ${caCertValidityFrom} cant't be in the future!`);
|
|
41
|
+
}
|
|
42
|
+
if (!rootPubKey) {
|
|
43
|
+
const configExpired = new Date(config.timestamp).getTime() < caCertValidityFrom;
|
|
44
|
+
return {
|
|
45
|
+
valid: false,
|
|
46
|
+
configExpired,
|
|
47
|
+
caPubKey,
|
|
48
|
+
error: 'ROOT_PUBKEY_NOT_FOUND',
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
const [subject] = deviceCert.tbsCertificate.subject;
|
|
52
|
+
if (!subject.parameters || subject.algorithm !== '2.5.4.3') {
|
|
53
|
+
throw new Error('Missing certificate subject');
|
|
54
|
+
}
|
|
55
|
+
const subjectValue = Buffer.from(subject.parameters.asn1.contents.subarray(0, 4)).toString();
|
|
56
|
+
if (subjectValue !== deviceModel) {
|
|
57
|
+
return {
|
|
58
|
+
valid: false,
|
|
59
|
+
caPubKey,
|
|
60
|
+
error: 'INVALID_DEVICE_MODEL',
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
const isDeviceCertValid = await verifySignature(Buffer.from(caCert.tbsCertificate.subjectPublicKeyInfo.bits.bytes), deviceCert.tbsCertificate.asn1.raw, deviceCert.signatureValue.bits.bytes);
|
|
64
|
+
const challengePrefix = Buffer.from('AuthenticateDevice:');
|
|
65
|
+
const prefixedChallenge = Buffer.concat([
|
|
66
|
+
utils_1.bufferUtils.getChunkSize(challengePrefix.length),
|
|
67
|
+
challengePrefix,
|
|
68
|
+
utils_1.bufferUtils.getChunkSize(challenge.length),
|
|
69
|
+
challenge,
|
|
70
|
+
]);
|
|
71
|
+
const isSignatureValid = await verifySignature(Buffer.from(deviceCert.tbsCertificate.subjectPublicKeyInfo.bits.bytes), prefixedChallenge, Buffer.from(signature, 'hex'));
|
|
72
|
+
if (rootPubKey && isDeviceCertValid && isSignatureValid) {
|
|
73
|
+
if ((!isDebugRootPubKey && !caPubKeys.includes(caPubKey)) ||
|
|
74
|
+
(isDebugRootPubKey && !(debug === null || debug === void 0 ? void 0 : debug.caPubKeys.includes(caPubKey)))) {
|
|
75
|
+
const configExpired = new Date(config.timestamp).getTime() < caCertValidityFrom;
|
|
76
|
+
return {
|
|
77
|
+
valid: false,
|
|
78
|
+
configExpired,
|
|
79
|
+
caPubKey,
|
|
80
|
+
error: 'CA_PUBKEY_NOT_FOUND',
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
valid: true,
|
|
85
|
+
caPubKey,
|
|
86
|
+
debugKey: isDebugRootPubKey,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
if (!isDeviceCertValid) {
|
|
90
|
+
return {
|
|
91
|
+
valid: false,
|
|
92
|
+
caPubKey,
|
|
93
|
+
error: 'INVALID_DEVICE_CERTIFICATE',
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
valid: false,
|
|
98
|
+
caPubKey,
|
|
99
|
+
error: 'INVALID_DEVICE_SIGNATURE',
|
|
100
|
+
};
|
|
101
|
+
};
|
|
102
|
+
exports.verifyAuthenticityProof = verifyAuthenticityProof;
|
|
103
|
+
//# sourceMappingURL=verifyAuthenticityProof.js.map
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
interface Asn1 {
|
|
2
|
+
cls: number;
|
|
3
|
+
tag: number;
|
|
4
|
+
structured: boolean;
|
|
5
|
+
byteLength: number;
|
|
6
|
+
contents: Uint8Array;
|
|
7
|
+
raw: Uint8Array;
|
|
8
|
+
}
|
|
9
|
+
export declare const parseName: (asn1: Asn1) => {
|
|
10
|
+
asn1: Asn1;
|
|
11
|
+
algorithm: string;
|
|
12
|
+
parameters: {
|
|
13
|
+
asn1: Asn1;
|
|
14
|
+
} | null;
|
|
15
|
+
}[];
|
|
16
|
+
export declare const parseCertificate: (byteArray: Uint8Array) => {
|
|
17
|
+
asn1: Asn1;
|
|
18
|
+
tbsCertificate: {
|
|
19
|
+
asn1: Asn1;
|
|
20
|
+
version: Asn1;
|
|
21
|
+
serialNumber: Asn1;
|
|
22
|
+
signature: {
|
|
23
|
+
asn1: Asn1;
|
|
24
|
+
algorithm: string;
|
|
25
|
+
parameters: {
|
|
26
|
+
asn1: Asn1;
|
|
27
|
+
} | null;
|
|
28
|
+
};
|
|
29
|
+
issuer: Asn1;
|
|
30
|
+
validity: {
|
|
31
|
+
from: Date;
|
|
32
|
+
to: Date;
|
|
33
|
+
};
|
|
34
|
+
subject: {
|
|
35
|
+
asn1: Asn1;
|
|
36
|
+
algorithm: string;
|
|
37
|
+
parameters: {
|
|
38
|
+
asn1: Asn1;
|
|
39
|
+
} | null;
|
|
40
|
+
}[];
|
|
41
|
+
subjectPublicKeyInfo: {
|
|
42
|
+
asn1: Asn1;
|
|
43
|
+
algorithm: {
|
|
44
|
+
asn1: Asn1;
|
|
45
|
+
algorithm: string;
|
|
46
|
+
parameters: {
|
|
47
|
+
asn1: Asn1;
|
|
48
|
+
} | null;
|
|
49
|
+
};
|
|
50
|
+
bits: {
|
|
51
|
+
unusedBits: number;
|
|
52
|
+
bytes: Uint8Array;
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
extensions: Asn1;
|
|
56
|
+
};
|
|
57
|
+
signatureAlgorithm: {
|
|
58
|
+
asn1: Asn1;
|
|
59
|
+
algorithm: string;
|
|
60
|
+
parameters: {
|
|
61
|
+
asn1: Asn1;
|
|
62
|
+
} | null;
|
|
63
|
+
};
|
|
64
|
+
signatureValue: {
|
|
65
|
+
asn1: Asn1;
|
|
66
|
+
bits: {
|
|
67
|
+
unusedBits: number;
|
|
68
|
+
bytes: Uint8Array;
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
export {};
|
|
73
|
+
//# sourceMappingURL=x509certificate.d.ts.map
|