chore(protocol): return protocol-v2 messageType as number

This commit is contained in:
Szymon Lesisz
2025-12-09 13:17:55 +01:00
committed by Szymon Lesisz
parent 94abe76af8
commit 4c3f7116d0
9 changed files with 19 additions and 45 deletions

View File

@@ -9,9 +9,6 @@ export const getHeaders: TransportProtocol['getHeaders'] = () => [Buffer.alloc(0
// it is because bridge does some parts of the protocol itself (like chunking)
export const encode: TransportProtocol['encode'] = (data, options) => {
const { messageType } = options;
if (typeof messageType === 'string') {
throw new Error(`Unsupported message type ${messageType}`);
}
const encodedBuffer = Buffer.alloc(HEADER_SIZE + data.length);

View File

@@ -18,10 +18,6 @@ export const getHeaders: TransportProtocol['getHeaders'] = () => {
export const encode: TransportProtocol['encode'] = (data, options) => {
const { messageType } = options;
if (typeof messageType === 'string') {
throw new Error(`Unsupported message type ${messageType}`);
}
const fullSize = HEADER_SIZE + data.length;
const encodedBuffer = Buffer.alloc(fullSize);

View File

@@ -1,6 +1,5 @@
export const HEADER_SIZE = 1 + 2; // 1: control_byte + 2: channel
export const MESSAGE_LEN_SIZE = 2;
export const MESSAGE_TYPE = 'TrezorHostProtocolMessage';
// https://github.com/trezor/trezor-firmware/blob/dc7dccfa6c6121333f732c39565878fc46e67085/core/src/trezor/wire/thp/__init__.py
export const THP_CONTROL_BYTE = {

View File

@@ -1,5 +1,5 @@
import * as ERRORS from '../errors';
import { HEADER_SIZE, MESSAGE_LEN_SIZE, MESSAGE_TYPE, THP_CONTROL_BYTE } from './constants';
import { HEADER_SIZE, MESSAGE_LEN_SIZE, THP_CONTROL_BYTE } from './constants';
import { getHeaders } from './encode';
import { TransportProtocolDecode } from '../types';
@@ -56,7 +56,7 @@ export const decode: TransportProtocolDecode = bytes => {
header,
chunkHeader,
length: buffer.readUint16BE(HEADER_SIZE),
messageType: MESSAGE_TYPE, // will be decoded by `protocol-thp`, TODO messageType
messageType,
payload: buffer.subarray(HEADER_SIZE + MESSAGE_LEN_SIZE),
};
};

View File

@@ -1,5 +1,5 @@
import * as ERRORS from '../errors';
import { HEADER_SIZE, MESSAGE_LEN_SIZE, MESSAGE_TYPE, THP_CONTROL_BYTE } from './constants';
import { HEADER_SIZE, MESSAGE_LEN_SIZE, THP_CONTROL_BYTE } from './constants';
import { TransportProtocol } from '../types';
const getChunkHeader = (data: Buffer) => {
@@ -22,18 +22,12 @@ export const getHeaders: TransportProtocol['getHeaders'] = data => {
// encode `protocol-thp` message
export const encode: TransportProtocol['encode'] = (data, options) => {
if (options.messageType === MESSAGE_TYPE) {
if (!options.header || options.header.byteLength !== HEADER_SIZE) {
throw new Error(
`${options.messageType} unexpected header ${options.header?.toString('hex')}`,
);
}
const length = Buffer.alloc(MESSAGE_LEN_SIZE);
length.writeUInt16BE(data.length);
return Buffer.concat([options.header, length, data]);
if (!options.header || options.header.byteLength !== HEADER_SIZE) {
throw new Error(ERRORS.PROTOCOL_MALFORMED);
}
throw new Error(`Use protocol-thp.encode for messageType ${options.messageType}`);
const length = Buffer.alloc(MESSAGE_LEN_SIZE);
length.writeUInt16BE(data.length);
return Buffer.concat([options.header, length, data]);
};

View File

@@ -8,12 +8,12 @@ export type { ThpState, ThpStateSerialized, ThpChannelState } from './protocol-t
export type TransportProtocolDecode = (bytes: Buffer) => {
header: Buffer;
length: number;
messageType: number | string;
messageType: number;
payload: Buffer;
};
export interface TransportProtocolEncodeOptions {
messageType: number | string;
messageType: number;
header?: Buffer;
}

View File

@@ -12,11 +12,6 @@ describe('protocol-bridge', () => {
expect(result.subarray(0, 6).toString('hex')).toEqual('003700000173');
expect(result.readUint32BE(2)).toEqual(371);
expect(result.length).toEqual(371 + 6);
// fail to encode unsupported messageType (string)
expect(() => bridge.encode(Buffer.alloc(64), { messageType: 'Initialize' })).toThrow(
'Unsupported message type Initialize',
);
});
it('decode', () => {

View File

@@ -13,11 +13,6 @@ describe('protocol-v1', () => {
expect(result.length).toEqual(371 + HEADER_SIZE);
expect(result.subarray(0, HEADER_SIZE).toString('hex')).toEqual('3f2323003700000173');
expect(result.subarray(HEADER_SIZE).toString('hex')).toEqual('a3'.repeat(371));
// fail to encode unsupported messageType (string)
expect(() => v1.encode(Buffer.alloc(64), { messageType: 'Initialize' })).toThrow(
'Unsupported message type Initialize',
);
});
it('decode', () => {

View File

@@ -1,7 +1,8 @@
import { decode, encode, getHeaders } from '../src/protocol-v2';
import { THP_CONTROL_BYTE } from '../src/protocol-v2/constants';
describe('protocol-v2', () => {
it('encode/decode TrezorHostProtocolMessage', () => {
it('encode/decode v2 message', () => {
// ThpCreateNewSession message
const data = Buffer.from(
'04123800230003e80a0870617373313233341000a0a1a2a3a4a5a6a7a8a9b0b1b2b3b4b504db712b',
@@ -9,7 +10,7 @@ describe('protocol-v2', () => {
);
const decoded = decode(data);
expect(decoded.messageType).toEqual('TrezorHostProtocolMessage');
expect(decoded.messageType).toEqual(THP_CONTROL_BYTE.ENCRYPTED);
expect(decoded.header).toEqual(data.subarray(0, 3));
expect(decoded.length).toEqual(35);
expect(decoded.payload).toEqual(data.subarray(5, 5 + 35));
@@ -20,23 +21,20 @@ describe('protocol-v2', () => {
it('encode with error', () => {
expect(() => encode(Buffer.alloc(0), { messageType: 1 })).toThrow(
'Use protocol-thp.encode',
);
expect(() => encode(Buffer.alloc(0), { messageType: 'TrezorHostProtocolMessage' })).toThrow(
'unexpected header undefined',
'Malformed protocol format',
);
expect(() =>
encode(Buffer.alloc(0), {
messageType: 'TrezorHostProtocolMessage',
messageType: 1,
header: Buffer.alloc(1),
}),
).toThrow('unexpected header 00');
).toThrow('Malformed protocol format');
expect(() =>
encode(Buffer.alloc(0), {
messageType: 'TrezorHostProtocolMessage',
messageType: 1,
header: Buffer.alloc(4),
}),
).toThrow('unexpected header 00000000');
).toThrow('Malformed protocol format');
});
it('decode with error', () => {