Skip to content

Commit 217ece3

Browse files
committed
Treat bytearray/memoryview as bytes in cbor.encode
1 parent 73ed8f7 commit 217ece3

File tree

2 files changed

+67
-55
lines changed

2 files changed

+67
-55
lines changed

fido2/cbor.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
from __future__ import annotations
3838

3939
import struct
40+
from collections.abc import Buffer
4041
from typing import Any, Callable, Mapping, Sequence
4142

4243
CborType = int | bool | str | bytes | Sequence[Any] | Mapping[Any, Any]
@@ -93,7 +94,7 @@ def _dump_text(data: str) -> bytes:
9394
(bool, _dump_bool),
9495
(int, _dump_int),
9596
(str, _dump_text),
96-
(bytes, _dump_bytes),
97+
(Buffer, _dump_bytes),
9798
(Mapping, _dump_dict),
9899
(Sequence, _dump_list),
99100
]

tests/test_cbor.py

Lines changed: 65 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2828
# POSSIBILITY OF SUCH DAMAGE.
2929

30-
import unittest
30+
import pytest
3131

3232
from fido2 import cbor
3333

@@ -153,61 +153,72 @@ def cbor2hex(data):
153153
return cbor.encode(data).hex()
154154

155155

156-
class TestCborTestVectors(unittest.TestCase):
156+
@pytest.mark.parametrize("data,value", _TEST_VECTORS)
157+
def test_cbor_test_vectors(data, value):
157158
"""
158159
From https://github.com/cbor/test-vectors
159160
Unsupported values are commented out.
160161
"""
161-
162-
def test_vectors(self):
163-
for data, value in _TEST_VECTORS:
164-
try:
165-
self.assertEqual(cbor.decode_from(bytes.fromhex(data)), (value, b""))
166-
self.assertEqual(cbor.decode(bytes.fromhex(data)), value)
167-
self.assertEqual(cbor2hex(value), data)
168-
except Exception:
169-
print("\nERROR in test vector, %s" % data)
170-
raise
171-
172-
173-
class TestFidoCanonical(unittest.TestCase):
174-
"""
175-
As defined in section 6 of:
176-
https://fidoalliance.org/specs/fido-v2.0-ps-20170927/fido-client-to-authenticator-protocol-v2.0-ps-20170927.html
177-
"""
178-
179-
def test_integers(self):
180-
self.assertEqual(cbor2hex(0), "00")
181-
self.assertEqual(cbor2hex(0), "00")
182-
self.assertEqual(cbor2hex(23), "17")
183-
self.assertEqual(cbor2hex(24), "1818")
184-
self.assertEqual(cbor2hex(255), "18ff")
185-
self.assertEqual(cbor2hex(256), "190100")
186-
self.assertEqual(cbor2hex(65535), "19ffff")
187-
self.assertEqual(cbor2hex(65536), "1a00010000")
188-
self.assertEqual(cbor2hex(4294967295), "1affffffff")
189-
self.assertEqual(cbor2hex(4294967296), "1b0000000100000000")
190-
self.assertEqual(cbor2hex(-1), "20")
191-
self.assertEqual(cbor2hex(-24), "37")
192-
self.assertEqual(cbor2hex(-25), "3818")
193-
194-
def test_key_order(self):
195-
self.assertEqual(cbor2hex({"3": 0, b"2": 0, 1: 0}), "a30100413200613300")
196-
197-
self.assertEqual(cbor2hex({"3": 0, b"": 0, 256: 0}), "a3190100004000613300")
198-
199-
self.assertEqual(
200-
cbor2hex({4294967296: 0, 255: 0, 256: 0, 0: 0}),
162+
assert cbor.decode_from(bytes.fromhex(data)) == (value, b"")
163+
assert cbor.decode(bytes.fromhex(data)) == value
164+
assert cbor2hex(value) == data
165+
166+
167+
# FIDO Canonical tests
168+
# As defined in section 6 of:
169+
# https://fidoalliance.org/specs/fido-v2.0-ps-20170927/fido-client-to-authenticator-protocol-v2.0-ps-20170927.html
170+
171+
172+
@pytest.mark.parametrize(
173+
"value,expected",
174+
[
175+
(0, "00"),
176+
(23, "17"),
177+
(24, "1818"),
178+
(255, "18ff"),
179+
(256, "190100"),
180+
(65535, "19ffff"),
181+
(65536, "1a00010000"),
182+
(4294967295, "1affffffff"),
183+
(4294967296, "1b0000000100000000"),
184+
(-1, "20"),
185+
(-24, "37"),
186+
(-25, "3818"),
187+
],
188+
)
189+
def test_fido_canonical_integers(value, expected):
190+
assert cbor2hex(value) == expected
191+
192+
193+
@pytest.mark.parametrize(
194+
"value,expected",
195+
[
196+
({"3": 0, b"2": 0, 1: 0}, "a30100413200613300"),
197+
({"3": 0, b"": 0, 256: 0}, "a3190100004000613300"),
198+
(
199+
{4294967296: 0, 255: 0, 256: 0, 0: 0},
201200
"a4000018ff00190100001b000000010000000000",
202-
)
203-
204-
self.assertEqual(
205-
cbor2hex({b"22": 0, b"3": 0, b"111": 0}), "a3413300423232004331313100"
206-
)
207-
208-
self.assertEqual(
209-
cbor2hex({b"001": 0, b"003": 0, b"002": 0}),
210-
"a3433030310043303032004330303300",
211-
)
212-
213-
self.assertEqual(cbor2hex({True: 0, False: 0}), "a2f400f500")
201+
),
202+
({b"22": 0, b"3": 0, b"111": 0}, "a3413300423232004331313100"),
203+
({b"001": 0, b"003": 0, b"002": 0}, "a3433030310043303032004330303300"),
204+
({True: 0, False: 0}, "a2f400f500"),
205+
],
206+
)
207+
def test_fido_canonical_key_order(value, expected):
208+
assert cbor2hex(value) == expected
209+
210+
211+
@pytest.mark.parametrize(
212+
"value,expected",
213+
[
214+
(b"", "40"),
215+
(b"\x01\x02\x03\x04", "4401020304"),
216+
(bytearray(b""), "40"),
217+
(bytearray(b"\x01\x02\x03\x04"), "4401020304"),
218+
(memoryview(b""), "40"),
219+
(memoryview(b"\x01\x02\x03\x04"), "4401020304"),
220+
],
221+
)
222+
def test_bytes_like_encoding(value, expected):
223+
"""Test that bytearray and memoryview are encoded as bytes."""
224+
assert cbor2hex(value) == expected

0 commit comments

Comments
 (0)