mirror of https://github.com/Yubico/python-fido2
201 lines
6.6 KiB
Python
201 lines
6.6 KiB
Python
|
# coding=utf-8
|
||
|
|
||
|
# Copyright (c) 2013 Yubico AB
|
||
|
# All rights reserved.
|
||
|
#
|
||
|
# Redistribution and use in source and binary forms, with or
|
||
|
# without modification, are permitted provided that the following
|
||
|
# conditions are met:
|
||
|
#
|
||
|
# 1. Redistributions of source code must retain the above copyright
|
||
|
# notice, this list of conditions and the following disclaimer.
|
||
|
# 2. Redistributions in binary form must reproduce the above
|
||
|
# copyright notice, this list of conditions and the following
|
||
|
# disclaimer in the documentation and/or other materials provided
|
||
|
# with the distribution.
|
||
|
#
|
||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||
|
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||
|
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||
|
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||
|
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||
|
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||
|
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||
|
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||
|
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||
|
# POSSIBILITY OF SUCH DAMAGE.
|
||
|
|
||
|
|
||
|
from __future__ import unicode_literals
|
||
|
|
||
|
from fido_host import cbor
|
||
|
from binascii import a2b_hex, b2a_hex
|
||
|
import unittest
|
||
|
|
||
|
|
||
|
_TEST_VECTORS = [
|
||
|
('00', 0),
|
||
|
('01', 1),
|
||
|
('0a', 10),
|
||
|
('17', 23),
|
||
|
('1818', 24),
|
||
|
('1819', 25),
|
||
|
('1864', 100),
|
||
|
('1903e8', 1000),
|
||
|
('1a000f4240', 1000000),
|
||
|
('1b000000e8d4a51000', 1000000000000),
|
||
|
('1bffffffffffffffff', 18446744073709551615),
|
||
|
# ('c249010000000000000000', 18446744073709551616),
|
||
|
('3bffffffffffffffff', -18446744073709551616),
|
||
|
# ('c349010000000000000000', -18446744073709551617),
|
||
|
('20', -1),
|
||
|
('29', -10),
|
||
|
('3863', -100),
|
||
|
('3903e7', -1000),
|
||
|
# ('f90000', 0.0),
|
||
|
# ('f98000', -0.0),
|
||
|
# ('f93c00', 1.0),
|
||
|
# ('fb3ff199999999999a', 1.1),
|
||
|
# ('f93e00', 1.5),
|
||
|
# ('f97bff', 65504.0),
|
||
|
# ('fa47c35000', 100000.0),
|
||
|
# ('fa7f7fffff', 3.4028234663852886e+38),
|
||
|
# ('fb7e37e43c8800759c', 1e+300),
|
||
|
# ('f90001', 5.960464477539063e-08),
|
||
|
# ('f90400', 6.103515625e-05),
|
||
|
# ('f9c400', -4.0),
|
||
|
# ('fbc010666666666666', -4.1),
|
||
|
# ('f97c00', None),
|
||
|
# ('f97e00', None),
|
||
|
# ('f9fc00', None),
|
||
|
# ('fa7f800000', None),
|
||
|
# ('fa7fc00000', None),
|
||
|
# ('faff800000', None),
|
||
|
# ('fb7ff0000000000000', None),
|
||
|
# ('fb7ff8000000000000', None),
|
||
|
# ('fbfff0000000000000', None),
|
||
|
('f4', False),
|
||
|
('f5', True),
|
||
|
# ('f6', None),
|
||
|
# ('f7', None),
|
||
|
# ('f0', None),
|
||
|
# ('f818', None),
|
||
|
# ('f8ff', None),
|
||
|
# ('c074323031332d30332d32315432303a30343a30305a', None),
|
||
|
# ('c11a514b67b0', None),
|
||
|
# ('c1fb41d452d9ec200000', None),
|
||
|
# ('d74401020304', None),
|
||
|
# ('d818456449455446', None),
|
||
|
# ('d82076687474703a2f2f7777772e6578616d706c652e636f6d', None),
|
||
|
('40', b''),
|
||
|
('4401020304', b'\1\2\3\4'),
|
||
|
('60', ''),
|
||
|
('6161', 'a'),
|
||
|
('6449455446', 'IETF'),
|
||
|
('62225c', '"\\'),
|
||
|
('62c3bc', 'ü'),
|
||
|
('63e6b0b4', '水'),
|
||
|
('64f0908591', '𐅑'),
|
||
|
('80', []),
|
||
|
('83010203', [1, 2, 3]),
|
||
|
('8301820203820405', [1, [2, 3], [4, 5]]),
|
||
|
('98190102030405060708090a0b0c0d0e0f101112131415161718181819', [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]), # noqa
|
||
|
('a0', {}),
|
||
|
('a201020304', {1: 2, 3: 4}),
|
||
|
('a26161016162820203', {'a': 1, 'b': [2, 3]}),
|
||
|
('826161a161626163', ['a', {'b': 'c'}]),
|
||
|
('a56161614161626142616361436164614461656145', {'c': 'C', 'd': 'D', 'a': 'A', 'b': 'B', 'e': 'E'}), # noqa
|
||
|
# ('5f42010243030405ff', None),
|
||
|
# ('7f657374726561646d696e67ff', 'streaming'),
|
||
|
# ('9fff', []),
|
||
|
# ('9f018202039f0405ffff', [1, [2, 3], [4, 5]]),
|
||
|
# ('9f01820203820405ff', [1, [2, 3], [4, 5]]),
|
||
|
# ('83018202039f0405ff', [1, [2, 3], [4, 5]]),
|
||
|
# ('83019f0203ff820405', [1, [2, 3], [4, 5]]),
|
||
|
# ('9f0102030405060708090a0b0c0d0e0f101112131415161718181819ff', [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]), # noqa
|
||
|
# ('bf61610161629f0203ffff', {'a': 1, 'b': [2, 3]}),
|
||
|
# ('826161bf61626163ff', ['a', {'b': 'c'}]),
|
||
|
# ('bf6346756ef563416d7421ff', {'Amt': -2, 'Fun': True}),
|
||
|
]
|
||
|
|
||
|
|
||
|
def cbor2hex(data):
|
||
|
return b2a_hex(cbor.dumps(data)).decode()
|
||
|
|
||
|
|
||
|
class TestCborTestVectors(unittest.TestCase):
|
||
|
"""
|
||
|
From https://github.com/cbor/test-vectors
|
||
|
Unsupported values are commented out.
|
||
|
"""
|
||
|
|
||
|
def test_vectors(self):
|
||
|
for (data, value) in _TEST_VECTORS:
|
||
|
try:
|
||
|
self.assertEqual(cbor.loads(a2b_hex(data)), (value, b''))
|
||
|
self.assertEqual(cbor2hex(value), data)
|
||
|
except Exception:
|
||
|
print('\nERROR in test vector, %s' % data)
|
||
|
raise
|
||
|
|
||
|
|
||
|
class TestFidoCanonical(unittest.TestCase):
|
||
|
"""
|
||
|
As defined in section 6 of:
|
||
|
https://fidoalliance.org/specs/fido-v2.0-ps-20170927/fido-client-to-authenticator-protocol-v2.0-ps-20170927.html
|
||
|
"""
|
||
|
|
||
|
def test_integers(self):
|
||
|
self.assertEqual(cbor2hex(0), '00')
|
||
|
self.assertEqual(cbor2hex(0), '00')
|
||
|
self.assertEqual(cbor2hex(23), '17')
|
||
|
self.assertEqual(cbor2hex(24), '1818')
|
||
|
self.assertEqual(cbor2hex(255), '18ff')
|
||
|
self.assertEqual(cbor2hex(256), '190100')
|
||
|
self.assertEqual(cbor2hex(65535), '19ffff')
|
||
|
self.assertEqual(cbor2hex(65536), '1a00010000')
|
||
|
self.assertEqual(cbor2hex(4294967295), '1affffffff')
|
||
|
self.assertEqual(cbor2hex(4294967296), '1b0000000100000000')
|
||
|
self.assertEqual(cbor2hex(-1), '20')
|
||
|
self.assertEqual(cbor2hex(-24), '37')
|
||
|
self.assertEqual(cbor2hex(-25), '3818')
|
||
|
|
||
|
def test_key_order(self):
|
||
|
self.assertEqual(cbor2hex({
|
||
|
'3': 0,
|
||
|
b'2': 0,
|
||
|
1: 0
|
||
|
}), 'a30100413200613300')
|
||
|
|
||
|
self.assertEqual(cbor2hex({
|
||
|
'3': 0,
|
||
|
b'': 0,
|
||
|
256: 0
|
||
|
}), 'a3190100004000613300')
|
||
|
|
||
|
self.assertEqual(cbor2hex({
|
||
|
4294967296: 0,
|
||
|
255: 0,
|
||
|
256: 0,
|
||
|
0: 0
|
||
|
}), 'a4000018ff00190100001b000000010000000000')
|
||
|
|
||
|
self.assertEqual(cbor2hex({
|
||
|
b'22': 0,
|
||
|
b'3': 0,
|
||
|
b'111': 0
|
||
|
}), 'a3413300423232004331313100')
|
||
|
|
||
|
self.assertEqual(cbor2hex({
|
||
|
b'001': 0,
|
||
|
b'003': 0,
|
||
|
b'002': 0
|
||
|
}), 'a3433030310043303032004330303300')
|
||
|
|
||
|
self.assertEqual(cbor2hex({
|
||
|
True: 0,
|
||
|
False: 0
|
||
|
}), 'a2f400f500')
|