|
1 | 1 |
|
2 | 2 | # compatibility with Python 2.6, for that we need unittest2 package,
|
3 | 3 | # which is not available on 3.3 or 3.4
|
| 4 | +import warnings |
| 5 | +from binascii import hexlify |
4 | 6 | try:
|
5 | 7 | import unittest2 as unittest
|
6 | 8 | except ImportError:
|
7 | 9 | import unittest
|
8 |
| -from .der import remove_integer, UnexpectedDER, read_length, encode_bitstring,\ |
9 |
| - remove_bitstring |
10 | 10 | from six import b
|
| 11 | +import hypothesis.strategies as st |
| 12 | +from hypothesis import given, example |
11 | 13 | import pytest
|
12 |
| -import warnings |
13 | 14 | from ._compat import str_idx_as_int
|
| 15 | +from .curves import NIST256p, NIST224p |
| 16 | +from .der import remove_integer, UnexpectedDER, read_length, encode_bitstring,\ |
| 17 | + remove_bitstring, remove_object, encode_oid |
14 | 18 |
|
15 | 19 |
|
16 | 20 | class TestRemoveInteger(unittest.TestCase):
|
@@ -242,3 +246,139 @@ def test_bytes(self):
|
242 | 246 |
|
243 | 247 | def test_bytearray(self):
|
244 | 248 | self.assertEqual(115, str_idx_as_int(bytearray(b'str'), 0))
|
| 249 | + |
| 250 | + |
| 251 | +class TestEncodeOid(unittest.TestCase): |
| 252 | + def test_pub_key_oid(self): |
| 253 | + oid_ecPublicKey = encode_oid(1, 2, 840, 10045, 2, 1) |
| 254 | + self.assertEqual(hexlify(oid_ecPublicKey), b("06072a8648ce3d0201")) |
| 255 | + |
| 256 | + def test_nist224p_oid(self): |
| 257 | + self.assertEqual(hexlify(NIST224p.encoded_oid), b("06052b81040021")) |
| 258 | + |
| 259 | + def test_nist256p_oid(self): |
| 260 | + self.assertEqual(hexlify(NIST256p.encoded_oid), |
| 261 | + b"06082a8648ce3d030107") |
| 262 | + |
| 263 | + def test_large_second_subid(self): |
| 264 | + # from X.690, section 8.19.5 |
| 265 | + oid = encode_oid(2, 999, 3) |
| 266 | + self.assertEqual(oid, b'\x06\x03\x88\x37\x03') |
| 267 | + |
| 268 | + def test_with_two_subids(self): |
| 269 | + oid = encode_oid(2, 999) |
| 270 | + self.assertEqual(oid, b'\x06\x02\x88\x37') |
| 271 | + |
| 272 | + def test_zero_zero(self): |
| 273 | + oid = encode_oid(0, 0) |
| 274 | + self.assertEqual(oid, b'\x06\x01\x00') |
| 275 | + |
| 276 | + def test_with_wrong_types(self): |
| 277 | + with self.assertRaises((TypeError, AssertionError)): |
| 278 | + encode_oid(0, None) |
| 279 | + |
| 280 | + def test_with_small_first_large_second(self): |
| 281 | + with self.assertRaises(AssertionError): |
| 282 | + encode_oid(1, 40) |
| 283 | + |
| 284 | + def test_small_first_max_second(self): |
| 285 | + oid = encode_oid(1, 39) |
| 286 | + self.assertEqual(oid, b'\x06\x01\x4f') |
| 287 | + |
| 288 | + def test_with_invalid_first(self): |
| 289 | + with self.assertRaises(AssertionError): |
| 290 | + encode_oid(3, 39) |
| 291 | + |
| 292 | + |
| 293 | +class TestRemoveObject(unittest.TestCase): |
| 294 | + @classmethod |
| 295 | + def setUpClass(cls): |
| 296 | + cls.oid_ecPublicKey = encode_oid(1, 2, 840, 10045, 2, 1) |
| 297 | + |
| 298 | + def test_pub_key_oid(self): |
| 299 | + oid, rest = remove_object(self.oid_ecPublicKey) |
| 300 | + self.assertEqual(rest, b'') |
| 301 | + self.assertEqual(oid, (1, 2, 840, 10045, 2, 1)) |
| 302 | + |
| 303 | + def test_with_extra_bytes(self): |
| 304 | + oid, rest = remove_object(self.oid_ecPublicKey + b'more') |
| 305 | + self.assertEqual(rest, b'more') |
| 306 | + self.assertEqual(oid, (1, 2, 840, 10045, 2, 1)) |
| 307 | + |
| 308 | + def test_with_large_second_subid(self): |
| 309 | + # from X.690, section 8.19.5 |
| 310 | + oid, rest = remove_object(b'\x06\x03\x88\x37\x03') |
| 311 | + self.assertEqual(rest, b'') |
| 312 | + self.assertEqual(oid, (2, 999, 3)) |
| 313 | + |
| 314 | + def test_with_padded_first_subid(self): |
| 315 | + with self.assertRaises(UnexpectedDER): |
| 316 | + remove_object(b'\x06\x02\x80\x00') |
| 317 | + |
| 318 | + def test_with_padded_second_subid(self): |
| 319 | + with self.assertRaises(UnexpectedDER): |
| 320 | + remove_object(b'\x06\x04\x88\x37\x80\x01') |
| 321 | + |
| 322 | + def test_with_missing_last_byte_of_multi_byte(self): |
| 323 | + with self.assertRaises(UnexpectedDER): |
| 324 | + remove_object(b'\x06\x03\x88\x37\x83') |
| 325 | + |
| 326 | + def test_with_two_subids(self): |
| 327 | + oid, rest = remove_object(b'\x06\x02\x88\x37') |
| 328 | + self.assertEqual(rest, b'') |
| 329 | + self.assertEqual(oid, (2, 999)) |
| 330 | + |
| 331 | + def test_zero_zero(self): |
| 332 | + oid, rest = remove_object(b'\x06\x01\x00') |
| 333 | + self.assertEqual(rest, b'') |
| 334 | + self.assertEqual(oid, (0, 0)) |
| 335 | + |
| 336 | + def test_empty_string(self): |
| 337 | + with self.assertRaises(UnexpectedDER): |
| 338 | + remove_object(b'') |
| 339 | + |
| 340 | + def test_missing_length(self): |
| 341 | + with self.assertRaises(UnexpectedDER): |
| 342 | + remove_object(b'\x06') |
| 343 | + |
| 344 | + def test_empty_oid(self): |
| 345 | + with self.assertRaises(UnexpectedDER): |
| 346 | + remove_object(b'\x06\x00') |
| 347 | + |
| 348 | + def test_empty_oid_overflow(self): |
| 349 | + with self.assertRaises(UnexpectedDER): |
| 350 | + remove_object(b'\x06\x01') |
| 351 | + |
| 352 | + def test_with_wrong_type(self): |
| 353 | + with self.assertRaises(UnexpectedDER): |
| 354 | + remove_object(b'\x04\x02\x88\x37') |
| 355 | + |
| 356 | + def test_with_too_long_length(self): |
| 357 | + with self.assertRaises(UnexpectedDER): |
| 358 | + remove_object(b'\x06\x03\x88\x37') |
| 359 | + |
| 360 | + |
| 361 | +@st.composite |
| 362 | +def st_oid(draw, max_value=2**512, max_size=50): |
| 363 | + """ |
| 364 | + Hypothesis strategy that returns valid OBJECT IDENTIFIERs as tuples |
| 365 | +
|
| 366 | + :param max_value: maximum value of any single sub-identifier |
| 367 | + :param max_size: maximum length of the generated OID |
| 368 | + """ |
| 369 | + first = draw(st.integers(min_value=0, max_value=2)) |
| 370 | + if first < 2: |
| 371 | + second = draw(st.integers(min_value=0, max_value=39)) |
| 372 | + else: |
| 373 | + second = draw(st.integers(min_value=0, max_value=max_value)) |
| 374 | + rest = draw(st.lists(st.integers(min_value=0, max_value=max_value), |
| 375 | + max_size=max_size)) |
| 376 | + return (first, second) + tuple(rest) |
| 377 | + |
| 378 | + |
| 379 | +@given(st_oid()) |
| 380 | +def test_oids(ids): |
| 381 | + encoded_oid = encode_oid(*ids) |
| 382 | + decoded_oid, rest = remove_object(encoded_oid) |
| 383 | + assert rest == b'' |
| 384 | + assert decoded_oid == ids |
0 commit comments