ragger 1.40.4__py3-none-any.whl → 1.41.0__py3-none-any.whl
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.
- ragger/__version__.py +2 -2
- ragger/backend/interface.py +2 -1
- ragger/backend/speculos.py +5 -4
- ragger/backend/stub.py +3 -2
- ragger/error.py +137 -0
- {ragger-1.40.4.dist-info → ragger-1.41.0.dist-info}/METADATA +1 -1
- {ragger-1.40.4.dist-info → ragger-1.41.0.dist-info}/RECORD +10 -10
- {ragger-1.40.4.dist-info → ragger-1.41.0.dist-info}/WHEEL +0 -0
- {ragger-1.40.4.dist-info → ragger-1.41.0.dist-info}/licenses/LICENSE +0 -0
- {ragger-1.40.4.dist-info → ragger-1.41.0.dist-info}/top_level.txt +0 -0
ragger/__version__.py
CHANGED
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '1.
|
|
32
|
-
__version_tuple__ = version_tuple = (1,
|
|
31
|
+
__version__ = version = '1.41.0'
|
|
32
|
+
__version_tuple__ = version_tuple = (1, 41, 0)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
ragger/backend/interface.py
CHANGED
|
@@ -25,6 +25,7 @@ from warnings import warn
|
|
|
25
25
|
from ragger.firmware import DEPRECATION_MESSAGE, Firmware
|
|
26
26
|
from ragger.logger import get_default_logger, get_apdu_logger, set_apdu_logger_file
|
|
27
27
|
from ragger.utils import pack_APDU, RAPDU, Crop
|
|
28
|
+
from ragger.error import StatusWords
|
|
28
29
|
|
|
29
30
|
|
|
30
31
|
class RaisePolicy(Enum):
|
|
@@ -130,7 +131,7 @@ class BackendInterface(ABC):
|
|
|
130
131
|
"""
|
|
131
132
|
return ((self.raise_policy == RaisePolicy.RAISE_ALL)
|
|
132
133
|
or ((self.raise_policy == RaisePolicy.RAISE_ALL_BUT_0x9000) and
|
|
133
|
-
(rapdu.status !=
|
|
134
|
+
(rapdu.status != StatusWords.SWO_SUCCESS))
|
|
134
135
|
or ((self.raise_policy == RaisePolicy.RAISE_CUSTOM) and
|
|
135
136
|
(rapdu.status not in self.whitelisted_status)))
|
|
136
137
|
|
ragger/backend/speculos.py
CHANGED
|
@@ -31,7 +31,7 @@ from ledgered.devices import Device
|
|
|
31
31
|
from speculos.client import SpeculosClient, screenshot_equal, ApduResponse, ApduException
|
|
32
32
|
from speculos.mcu.seproxyhal import TICKER_DELAY
|
|
33
33
|
|
|
34
|
-
from ragger.error import ExceptionRAPDU
|
|
34
|
+
from ragger.error import StatusWords, ExceptionRAPDU
|
|
35
35
|
from ragger.logger import get_default_logger
|
|
36
36
|
from ragger.utils import RAPDU, Crop
|
|
37
37
|
from .interface import BackendInterface, GraphicalLibrary
|
|
@@ -198,17 +198,18 @@ class SpeculosBackend(BackendInterface):
|
|
|
198
198
|
@raise_policy_enforcer
|
|
199
199
|
def receive(self) -> RAPDU:
|
|
200
200
|
assert self._pending is not None
|
|
201
|
-
result = RAPDU(
|
|
201
|
+
result = RAPDU(StatusWords.SWO_SUCCESS, self._pending.receive())
|
|
202
202
|
return result
|
|
203
203
|
|
|
204
204
|
@raise_policy_enforcer
|
|
205
205
|
def exchange_raw(self, data: bytes = b"", tick_timeout: int = 5 * 60 * 10) -> RAPDU:
|
|
206
206
|
self.apdu_logger.info("=> %s", data.hex())
|
|
207
|
-
return RAPDU(
|
|
207
|
+
return RAPDU(StatusWords.SWO_SUCCESS,
|
|
208
|
+
self._client._apdu_exchange(data, tick_timeout=tick_timeout))
|
|
208
209
|
|
|
209
210
|
@raise_policy_enforcer
|
|
210
211
|
def _get_last_async_response(self, response) -> RAPDU:
|
|
211
|
-
return RAPDU(
|
|
212
|
+
return RAPDU(StatusWords.SWO_SUCCESS, response.receive())
|
|
212
213
|
|
|
213
214
|
@contextmanager
|
|
214
215
|
def exchange_async_raw(self, data: bytes = b"") -> Generator[bool, None, None]:
|
ragger/backend/stub.py
CHANGED
|
@@ -18,6 +18,7 @@ from pathlib import Path
|
|
|
18
18
|
from types import TracebackType
|
|
19
19
|
from typing import Any, Generator, Optional, Type
|
|
20
20
|
|
|
21
|
+
from ragger.error import StatusWords
|
|
21
22
|
from ragger.utils.structs import Crop, RAPDU
|
|
22
23
|
from .interface import BackendInterface
|
|
23
24
|
|
|
@@ -45,10 +46,10 @@ class StubBackend(BackendInterface):
|
|
|
45
46
|
pass
|
|
46
47
|
|
|
47
48
|
def receive(self) -> RAPDU:
|
|
48
|
-
return RAPDU(
|
|
49
|
+
return RAPDU(StatusWords.SWO_SUCCESS, b"")
|
|
49
50
|
|
|
50
51
|
def exchange_raw(self, data: bytes = b"", tick_timeout: int = 5 * 60 * 10) -> RAPDU:
|
|
51
|
-
return RAPDU(
|
|
52
|
+
return RAPDU(StatusWords.SWO_SUCCESS, b"")
|
|
52
53
|
|
|
53
54
|
@contextmanager
|
|
54
55
|
def exchange_async_raw(self, data: bytes = b"") -> Generator[None, None, None]:
|
ragger/error.py
CHANGED
|
@@ -14,6 +14,143 @@
|
|
|
14
14
|
limitations under the License.
|
|
15
15
|
"""
|
|
16
16
|
from dataclasses import dataclass
|
|
17
|
+
from enum import IntEnum
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class StatusWords(IntEnum):
|
|
21
|
+
"""ISO7816 Status Words for APDU responses.
|
|
22
|
+
|
|
23
|
+
Refer to:
|
|
24
|
+
- SDK https://github.com/LedgerHQ/ledger-secure-sdk/blob/master/include/status_words.h
|
|
25
|
+
- https://www.eftlab.com/knowledge-base/complete-list-of-apdu-responses
|
|
26
|
+
|
|
27
|
+
Notes:
|
|
28
|
+
- The SWO codes are defined based on the ISO/IEC 7816-4 standard for smart cards.
|
|
29
|
+
|
|
30
|
+
- 61XX and 6CXX are different.
|
|
31
|
+
When a command returns 61XX, its process is normally completed,
|
|
32
|
+
and it indicates the number of available bytes;
|
|
33
|
+
it then expects a GET RESPONSE command with the appropriate length.
|
|
34
|
+
When a command returns 6CXX, its process has been aborted,
|
|
35
|
+
and it expects the command to be reissued.
|
|
36
|
+
As mentioned above, 61XX indicates a normal completion,
|
|
37
|
+
and 6CXX is considered as a transport error (defined in ISO7817-3).
|
|
38
|
+
|
|
39
|
+
- Except for 63XX and 65XX, which warn that the persistent content has been changed,
|
|
40
|
+
other status word should be used when the persistent content of the application is unchanged.
|
|
41
|
+
|
|
42
|
+
- Status words 67XX, 6BXX, 6DXX, 6EXX, and 6FXX, where XX is not 0, are proprietary status words,
|
|
43
|
+
as well as 9YYY, where YYY is not 000.
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
# 61 -- Normal processing, lower byte indicates the amount of data to be retrieved
|
|
47
|
+
SWO_RESPONSE_BYTES_AVAILABLE = 0x6100
|
|
48
|
+
|
|
49
|
+
# 62 -- Warning, the state of persistent memory is unchanged
|
|
50
|
+
SWO_DATA_MAY_BE_CORRUPTED = 0x6281
|
|
51
|
+
SWO_EOF_REACHED_BEFORE_LE = 0x6282
|
|
52
|
+
SWO_SELECTED_FILE_INVALIDATED = 0x6283
|
|
53
|
+
SWO_FILE_INVALID = 0x6284
|
|
54
|
+
SWO_NO_INPUT_DATA_AVAILABLE = 0x6285
|
|
55
|
+
|
|
56
|
+
# 63 -- Warning, the state of persistent memory is changed
|
|
57
|
+
SWO_CARD_KEY_NOT_SUPPORTED = 0x6382
|
|
58
|
+
SWO_READER_KEY_NOT_SUPPORTED = 0x6383
|
|
59
|
+
SWO_PLAINTEXT_TRANS_NOT_SUPPORTED = 0x6384
|
|
60
|
+
SWO_SECURED_TRANS_NOT_SUPPORTED = 0x6385
|
|
61
|
+
SWO_VOLATILE_MEM_NOT_AVAILABLE = 0x6386
|
|
62
|
+
SWO_NON_VOLATILE_MEM_NOT_AVAILABLE = 0x6387
|
|
63
|
+
SWO_KEY_NUMBER_INVALID = 0x6388
|
|
64
|
+
SWO_KEY_LENGTH_INCORRECT = 0x6389
|
|
65
|
+
SWO_VERIFY_FAILED = 0x63C0 # lower 4-bits indicates the number of attempts left
|
|
66
|
+
SWO_MORE_DATA_EXPECTED = 0x63F1
|
|
67
|
+
|
|
68
|
+
# 64 -- Execution error, the state of persistent memory is unchanged
|
|
69
|
+
SWO_EXECUTION_ERROR = 0x6400
|
|
70
|
+
SWO_COMMAND_TIMEOUT = 0x6401
|
|
71
|
+
|
|
72
|
+
# 65 -- Execution error, the state of persistent memory is changed
|
|
73
|
+
SWO_MEMORY_WRITE_ERROR = 0x6501
|
|
74
|
+
SWO_MEMORY_FAILURE = 0x6581
|
|
75
|
+
|
|
76
|
+
# 66 -- Security-related issues
|
|
77
|
+
SWO_SECURITY_ISSUE = 0x6600
|
|
78
|
+
SWO_RECEIVE_ERROR_PARITY = 0x6601
|
|
79
|
+
SWO_WRONG_CHECKSUM = 0x6602
|
|
80
|
+
SWO_INCORRECT_PADDING = 0x6669
|
|
81
|
+
|
|
82
|
+
# 67 -- Transport error. The length is incorrect
|
|
83
|
+
SWO_WRONG_LENGTH = 0x6700
|
|
84
|
+
|
|
85
|
+
# 68 -- Functions in CLA not supported
|
|
86
|
+
SWO_NOT_SUPPORTED_ERROR_NO_INFO = 0x6800
|
|
87
|
+
SWO_LOGICAL_CHANNEL_NOT_SUPPORTED = 0x6881
|
|
88
|
+
SWO_SECURE_MESSAGING_NOT_SUPPORTED = 0x6882
|
|
89
|
+
SWO_LAST_COMMAND_OF_CHAIN_EXPECTED = 0x6883
|
|
90
|
+
SWO_COMMAND_CHAINING_NOT_SUPPORTED = 0x6884
|
|
91
|
+
|
|
92
|
+
# 69 -- Command not allowed
|
|
93
|
+
SWO_COMMAND_ERROR_NO_INFO = 0x6900
|
|
94
|
+
SWO_COMMAND_NOT_ACCEPTED = 0x6901
|
|
95
|
+
SWO_COMMAND_NOT_ALLOWED = 0x6980
|
|
96
|
+
SWO_SUBCOMMAND_NOT_ALLOWED = 0x6981
|
|
97
|
+
SWO_SECURITY_CONDITION_NOT_SATISFIED = 0x6982
|
|
98
|
+
SWO_AUTH_METHOD_BLOCKED = 0x6983
|
|
99
|
+
SWO_REFERENCED_DATA_BLOCKED = 0x6984
|
|
100
|
+
SWO_CONDITIONS_NOT_SATISFIED = 0x6985
|
|
101
|
+
SWO_COMMAND_NOT_ALLOWED_EF = 0x6986
|
|
102
|
+
SWO_EXPECTED_SECURE_MSG_OBJ_MISSING = 0x6987
|
|
103
|
+
SWO_INCORRECT_SECURE_MSG_DATA_OBJ = 0x6988
|
|
104
|
+
SWO_PERMISSION_DENIED = 0x69F0
|
|
105
|
+
SWO_MISSING_PRIVILEGES = 0x69F1
|
|
106
|
+
|
|
107
|
+
# 6A -- Wrong parameters (with details)
|
|
108
|
+
SWO_PARAMETER_ERROR_NO_INFO = 0x6A00
|
|
109
|
+
SWO_INCORRECT_DATA = 0x6A80
|
|
110
|
+
SWO_FUNCTION_NOT_SUPPORTED = 0x6A81
|
|
111
|
+
SWO_FILE_NOT_FOUND = 0x6A82
|
|
112
|
+
SWO_RECORD_NOT_FOUND = 0x6A83
|
|
113
|
+
SWO_INSUFFICIENT_MEMORY = 0x6A84
|
|
114
|
+
SWO_INCONSISTENT_TLV_STRUCT = 0x6A85
|
|
115
|
+
SWO_INCORRECT_P1_P2 = 0x6A86
|
|
116
|
+
SWO_WRONG_DATA_LENGTH = 0x6A87
|
|
117
|
+
SWO_REFERENCED_DATA_NOT_FOUND = 0x6A88
|
|
118
|
+
SWO_FILE_ALREADY_EXISTS = 0x6A89
|
|
119
|
+
SWO_DF_NAME_ALREADY_EXISTS = 0x6A8A
|
|
120
|
+
SWO_WRONG_PARAMETER_VALUE = 0x6AF0
|
|
121
|
+
|
|
122
|
+
# 6B -- Wrong parameters P1-P2
|
|
123
|
+
SWO_WRONG_P1_P2 = 0x6B00
|
|
124
|
+
|
|
125
|
+
# 6C -- Wrong Le field. lower byte indicates the appropriate length
|
|
126
|
+
SWO_INCORRECT_P3_LENGTH = 0x6C00
|
|
127
|
+
|
|
128
|
+
# 6D -- The instruction code is not supported
|
|
129
|
+
SWO_INVALID_INS = 0x6D00
|
|
130
|
+
|
|
131
|
+
# 6E -- The instruction class is not supported
|
|
132
|
+
SWO_INVALID_CLA = 0x6E00
|
|
133
|
+
|
|
134
|
+
# 6F -- No precise diagnosis is given
|
|
135
|
+
SWO_UNKNOWN = 0x6F00
|
|
136
|
+
|
|
137
|
+
# 9- --
|
|
138
|
+
SWO_SUCCESS = 0x9000
|
|
139
|
+
SWO_BUSY = 0x9001
|
|
140
|
+
SWO_PIN_NOT_SUCCESFULLY_VERIFIED = 0x9004
|
|
141
|
+
SWO_RESULT_OK = 0x9100
|
|
142
|
+
SWO_STATES_STATUS_WRONG = 0x9101
|
|
143
|
+
SWO_TRANSACTION_LIMIT_REACHED = 0x9102
|
|
144
|
+
SWO_INSUFFICIENT_MEM_FOR_CMD = 0x910E
|
|
145
|
+
SWO_COMMAND_CODE_NOT_SUPPORTED = 0x911C
|
|
146
|
+
SWO_INVALID_KEY_NUMBER = 0x9140
|
|
147
|
+
SWO_WRONG_LENGTH_FOR_INS = 0x917E
|
|
148
|
+
SWO_NO_EF_SELECTED = 0x9400
|
|
149
|
+
SWO_ADDRESS_RANGE_EXCEEDED = 0x9402
|
|
150
|
+
SWO_FID_NOT_FOUND = 0x9404
|
|
151
|
+
SWO_PARSE_ERROR = 0x9405
|
|
152
|
+
SWO_NO_PIN_DEFINED = 0x9802
|
|
153
|
+
SWO_ACCESS_CONDITION_NOT_FULFILLED = 0x9804
|
|
17
154
|
|
|
18
155
|
|
|
19
156
|
@dataclass
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
ragger/__init__.py,sha256=Vbk78M7VtDVMTu02zYQquYSTxtgbieknkvr3uXONrig,713
|
|
2
|
-
ragger/__version__.py,sha256=
|
|
3
|
-
ragger/error.py,sha256=
|
|
2
|
+
ragger/__version__.py,sha256=E1ZnJIkHAjOyZueq2FTrD7-A-X_nF3GK9RHXFfxJOQQ,706
|
|
3
|
+
ragger/error.py,sha256=G81LOe38jUDV6EzdFc_foKVsMxk09q6N5--0M63qya0,6279
|
|
4
4
|
ragger/logger.py,sha256=XF3DsHDLGOHAG7cqVj_7BQlHKj9J8zw8A9soFHIydc8,2457
|
|
5
5
|
ragger/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
6
|
ragger/backend/__init__.py,sha256=IQlMre2Pi5QWyYBTROMTbKuonNRUODKrrhj5UxcqQx4,1930
|
|
7
|
-
ragger/backend/interface.py,sha256=
|
|
7
|
+
ragger/backend/interface.py,sha256=P_Uk0qXz8xrgy9m6mMaY7HWz_gg9dlYvarjmYpv_6EQ,21539
|
|
8
8
|
ragger/backend/ledgercomm.py,sha256=XhG2GszkfjrJTPAECqUJ35PCkDs9mHnVn4ThbQZhQPg,3882
|
|
9
9
|
ragger/backend/ledgerwallet.py,sha256=b8p6vTPCddAfIk9uT9bJbPqE8e4UqfL3w10ufqPdROc,3733
|
|
10
10
|
ragger/backend/physical_backend.py,sha256=Y5BRhsKliqCyYFFce7D7swRlT3dkwsXptrUq3zm2Oks,5955
|
|
11
|
-
ragger/backend/speculos.py,sha256=
|
|
12
|
-
ragger/backend/stub.py,sha256=
|
|
11
|
+
ragger/backend/speculos.py,sha256=n83w4RevwHzFz-iF-Qo_tLCEckqxiP8e7PQ3wGMD21U,16138
|
|
12
|
+
ragger/backend/stub.py,sha256=OIn4pIdnBuhgmCAAjGlVTEuWtaCLyCtVLVO-VTAEBRs,3284
|
|
13
13
|
ragger/bip/__init__.py,sha256=7gY5V8gkJfct1g4OgaLg8bNpgoITGaqU9gTKC4tHbAM,920
|
|
14
14
|
ragger/bip/path.py,sha256=uX69L3U8vteIHJy_PE5yPloGaiiYYMq_jLbBSENiRqs,1709
|
|
15
15
|
ragger/bip/seed.py,sha256=yKGM_fkFCh6hNAl7vOMrEv5kEoQoDmVPhBCIMtO8dNk,1758
|
|
@@ -50,8 +50,8 @@ ragger/utils/__init__.py,sha256=PUabSv1qx0XyKWovIxvGBI71sd3O3bKp3gCsUxlWm1E,997
|
|
|
50
50
|
ragger/utils/misc.py,sha256=_ft_CrwEcZ-VVZCBG-_QjYQuTZn-Fht36k3C6BXhHOs,6930
|
|
51
51
|
ragger/utils/packing.py,sha256=2xaRR-FhwVfknP74ZGo-O4JTE6R0HpNqhxKJ9aMrns4,766
|
|
52
52
|
ragger/utils/structs.py,sha256=JMfuX5u-4gSZfqH0SER05B15-mj0YyHjnxLAgxAYtAM,1413
|
|
53
|
-
ragger-1.
|
|
54
|
-
ragger-1.
|
|
55
|
-
ragger-1.
|
|
56
|
-
ragger-1.
|
|
57
|
-
ragger-1.
|
|
53
|
+
ragger-1.41.0.dist-info/licenses/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
|
|
54
|
+
ragger-1.41.0.dist-info/METADATA,sha256=aW_QcwGG5g4ig6mypqRa7AzL-4-kW1yXoQYEWqRRmQ4,10660
|
|
55
|
+
ragger-1.41.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
56
|
+
ragger-1.41.0.dist-info/top_level.txt,sha256=kqJEoAZ6qn0T3iuVa-710gBK7Ik1euCwNwBbyFraRQg,7
|
|
57
|
+
ragger-1.41.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|