File: ledgerWrapper.py

package info (click to toggle)
btchip-python 0.1.32-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 392 kB
  • sloc: python: 2,343; javascript: 223; xml: 25; sh: 9; makefile: 3
file content (92 lines) | stat: -rw-r--r-- 3,224 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
"""
*******************************************************************************
*   BTChip Bitcoin Hardware Wallet Python API
*   (c) 2014 BTChip - 1BTChip7VfTnrPra5jqci7ejnMguuHogTn
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
*   Unless required by applicable law or agreed to in writing, software
*   distributed under the License is distributed on an "AS IS" BASIS,
*   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*   limitations under the License.
********************************************************************************
"""

import struct
from .btchipException import BTChipException

def wrapCommandAPDU(channel, command, packetSize):
	if packetSize < 3:
		raise BTChipException("Can't handle Ledger framing with less than 3 bytes for the report")
	sequenceIdx = 0		
	offset = 0
	result = struct.pack(">HBHH", channel, 0x05, sequenceIdx, len(command))
	sequenceIdx = sequenceIdx + 1
	if len(command) > packetSize - 7:
		blockSize = packetSize - 7
	else:
		blockSize = len(command)
	result += command[offset : offset + blockSize]
	offset = offset + blockSize
	while offset != len(command):
		result += struct.pack(">HBH", channel, 0x05, sequenceIdx)
		sequenceIdx = sequenceIdx + 1
		if (len(command) - offset) > packetSize - 5:
			blockSize = packetSize - 5
		else:
			blockSize = len(command) - offset
		result += command[offset : offset + blockSize]
		offset = offset + blockSize
	while (len(result) % packetSize) != 0:
		result += b"\x00"
	return bytearray(result)

def unwrapResponseAPDU(channel, data, packetSize):
	sequenceIdx = 0		
	offset = 0
	if ((data is None) or (len(data) < 7 + 5)):
		return None
	if struct.unpack(">H", data[offset : offset + 2])[0] != channel:
		raise BTChipException("Invalid channel")
	offset += 2
	if data[offset] != 0x05:
		raise BTChipException("Invalid tag")
	offset += 1
	if struct.unpack(">H", data[offset : offset + 2])[0] != sequenceIdx:
		raise BTChipException("Invalid sequence")
	offset += 2
	responseLength = struct.unpack(">H", data[offset : offset + 2])[0]
	offset += 2
	if len(data) < 7 + responseLength:
		return None
	if responseLength > packetSize - 7:
		blockSize = packetSize - 7
	else:
		blockSize = responseLength
	result = data[offset : offset + blockSize]
	offset += blockSize
	while (len(result) != responseLength):
		sequenceIdx = sequenceIdx + 1
		if (offset == len(data)):
			return None
		if struct.unpack(">H", data[offset : offset + 2])[0] != channel:
			raise BTChipException("Invalid channel")
		offset += 2
		if data[offset] != 0x05:
			raise BTChipException("Invalid tag")
		offset += 1
		if struct.unpack(">H", data[offset : offset + 2])[0] != sequenceIdx:
			raise BTChipException("Invalid sequence")
		offset += 2
		if (responseLength - len(result)) > packetSize - 5:
			blockSize = packetSize - 5
		else:
			blockSize = responseLength - len(result)
		result += data[offset : offset + blockSize]
		offset += blockSize
	return bytearray(result)