1# coding: utf-8 2from __future__ import unicode_literals, division, absolute_import, print_function 3 4import unittest 5import os 6import zlib 7import sys 8from datetime import datetime 9 10from asn1crypto import cms, util 11from ._unittest_compat import patch 12 13patch() 14 15if sys.version_info < (3,): 16 byte_cls = str 17else: 18 byte_cls = bytes 19 20tests_root = os.path.dirname(__file__) 21fixtures_dir = os.path.join(tests_root, 'fixtures') 22 23 24class ClearanceTests(unittest.TestCase): 25 26 def test_clearance_decode_bad_tagging(self): 27 rfc_3281_wrong_tagging = b'\x30\x08\x80\x02\x88\x37\x81\x02\x02\x4c' 28 # This test documents the fact that we can't deal with the "wrong" 29 # version of Clearance in RFC 3281 30 self.assertRaises( 31 ValueError, 32 lambda: cms.Clearance.load(rfc_3281_wrong_tagging).native 33 ) 34 35 def test_clearance_decode_correct_tagging(self): 36 correct_tagging = b'\x30\x08\x06\x02\x88\x37\x03\x02\x02\x4c' 37 clearance_obj = cms.Clearance.load(correct_tagging) 38 self.assertEqual( 39 util.OrderedDict([ 40 ('policy_id', '2.999'), 41 ('class_list', set(['secret', 'top_secret', 'unclassified'])), 42 ('security_categories', None) 43 ]), 44 clearance_obj.native 45 ) 46 47 48class CMSTests(unittest.TestCase): 49 50 def test_create_content_info_data(self): 51 data = cms.SignedData({ 52 'version': 'v1', 53 'encap_content_info': { 54 'content_type': 'data', 55 'content': b'Hello', 56 } 57 }) 58 info = data['encap_content_info'] 59 60 self.assertEqual('v1', data['version'].native) 61 self.assertEqual( 62 'data', 63 info['content_type'].native 64 ) 65 self.assertEqual( 66 b'Hello', 67 info['content'].native 68 ) 69 self.assertIsInstance(info, cms.ContentInfo) 70 71 def test_create_content_info_data_v2(self): 72 data = cms.SignedData({ 73 'version': 'v2', 74 'encap_content_info': { 75 'content_type': 'data', 76 'content': b'Hello', 77 } 78 }) 79 info = data['encap_content_info'] 80 81 self.assertEqual('v2', data['version'].native) 82 self.assertEqual( 83 'data', 84 info['content_type'].native 85 ) 86 self.assertEqual( 87 b'Hello', 88 info['content'].native 89 ) 90 self.assertIsInstance(info, cms.EncapsulatedContentInfo) 91 92 def test_parse_content_info_data(self): 93 with open(os.path.join(fixtures_dir, 'message.der'), 'rb') as f: 94 info = cms.ContentInfo.load(f.read()) 95 96 self.assertEqual( 97 'data', 98 info['content_type'].native 99 ) 100 self.assertEqual( 101 b'This is the message to encapsulate in PKCS#7/CMS\r\n', 102 info['content'].native 103 ) 104 105 def test_parse_content_info_compressed_data(self): 106 with open(os.path.join(fixtures_dir, 'cms-compressed.der'), 'rb') as f: 107 info = cms.ContentInfo.load(f.read()) 108 109 compressed_data = info['content'] 110 111 self.assertEqual( 112 'compressed_data', 113 info['content_type'].native 114 ) 115 self.assertEqual( 116 'v0', 117 compressed_data['version'].native 118 ) 119 self.assertEqual( 120 'zlib', 121 compressed_data['compression_algorithm']['algorithm'].native 122 ) 123 self.assertEqual( 124 None, 125 compressed_data['compression_algorithm']['parameters'].native 126 ) 127 self.assertEqual( 128 'data', 129 compressed_data['encap_content_info']['content_type'].native 130 ) 131 self.assertEqual( 132 b'\x78\x9C\x0B\xC9\xC8\x2C\x56\x00\xA2\x92\x8C\x54\x85\xDC\xD4\xE2\xE2\xC4\xF4\x54\x85\x92\x7C\x85\xD4\xBC' 133 b'\xE4\xC4\x82\xE2\xD2\x9C\xC4\x92\x54\x85\xCC\x3C\x85\x00\x6F\xE7\x60\x65\x73\x7D\x67\xDF\x60\x2E\x00\xB5' 134 b'\xCF\x10\x71', 135 compressed_data['encap_content_info']['content'].native 136 ) 137 self.assertEqual( 138 b'This is the message to encapsulate in PKCS#7/CMS\n', 139 compressed_data.decompressed 140 ) 141 142 def test_parse_content_info_indefinite(self): 143 with open(os.path.join(fixtures_dir, 'meca2_compressed.der'), 'rb') as f: 144 info = cms.ContentInfo.load(f.read()) 145 146 compressed_data = info['content'] 147 148 self.assertEqual( 149 'compressed_data', 150 info['content_type'].native 151 ) 152 self.assertEqual( 153 'v0', 154 compressed_data['version'].native 155 ) 156 self.assertEqual( 157 'zlib', 158 compressed_data['compression_algorithm']['algorithm'].native 159 ) 160 self.assertEqual( 161 None, 162 compressed_data['compression_algorithm']['parameters'].native 163 ) 164 self.assertEqual( 165 'data', 166 compressed_data['encap_content_info']['content_type'].native 167 ) 168 data = compressed_data['encap_content_info']['content'].native 169 self.assertIsInstance(zlib.decompress(data), byte_cls) 170 171 def test_parse_content_info_digested_data(self): 172 with open(os.path.join(fixtures_dir, 'cms-digested.der'), 'rb') as f: 173 info = cms.ContentInfo.load(f.read()) 174 175 digested_data = info['content'] 176 177 self.assertEqual( 178 'digested_data', 179 info['content_type'].native 180 ) 181 self.assertEqual( 182 'v0', 183 digested_data['version'].native 184 ) 185 self.assertEqual( 186 'sha1', 187 digested_data['digest_algorithm']['algorithm'].native 188 ) 189 self.assertEqual( 190 None, 191 digested_data['digest_algorithm']['parameters'].native 192 ) 193 self.assertEqual( 194 'data', 195 digested_data['encap_content_info']['content_type'].native 196 ) 197 self.assertEqual( 198 b'This is the message to encapsulate in PKCS#7/CMS\n', 199 digested_data['encap_content_info']['content'].native 200 ) 201 self.assertEqual( 202 b'\x53\xC9\xDB\xC1\x6D\xDB\x34\x3B\x28\x4E\xEF\xA6\x03\x0E\x02\x64\x79\x31\xAF\xFB', 203 digested_data['digest'].native 204 ) 205 206 def test_parse_content_info_encrypted_data(self): 207 with open(os.path.join(fixtures_dir, 'cms-encrypted.der'), 'rb') as f: 208 info = cms.ContentInfo.load(f.read()) 209 210 encrypted_data = info['content'] 211 encrypted_content_info = encrypted_data['encrypted_content_info'] 212 213 self.assertEqual( 214 'encrypted_data', 215 info['content_type'].native 216 ) 217 self.assertEqual( 218 'v0', 219 encrypted_data['version'].native 220 ) 221 self.assertEqual( 222 'data', 223 encrypted_content_info['content_type'].native 224 ) 225 self.assertEqual( 226 'aes128_cbc', 227 encrypted_content_info['content_encryption_algorithm']['algorithm'].native 228 ) 229 self.assertEqual( 230 'aes', 231 encrypted_content_info['content_encryption_algorithm'].encryption_cipher 232 ) 233 self.assertEqual( 234 'cbc', 235 encrypted_content_info['content_encryption_algorithm'].encryption_mode 236 ) 237 self.assertEqual( 238 16, 239 encrypted_content_info['content_encryption_algorithm'].key_length 240 ) 241 self.assertEqual( 242 16, 243 encrypted_content_info['content_encryption_algorithm'].encryption_block_size 244 ) 245 self.assertEqual( 246 b'\x1F\x34\x54\x9F\x7F\xB7\x06\xBD\x81\x57\x68\x84\x79\xB5\x2F\x6F', 247 encrypted_content_info['content_encryption_algorithm']['parameters'].native 248 ) 249 self.assertEqual( 250 b'\x80\xEE\x34\x8B\xFC\x04\x69\x4F\xBE\x15\x1C\x0C\x39\x2E\xF3\xEA\x8E\xEE\x17\x0D\x39\xC7\x4B\x6C\x4B' 251 b'\x13\xEF\x17\x82\x0D\xED\xBA\x6D\x2F\x3B\xAB\x4E\xEB\xF0\xDB\xD9\x6E\x1C\xC2\x3C\x1C\x4C\xFA\xF3\x98' 252 b'\x9B\x89\xBD\x48\x77\x07\xE2\x6B\x71\xCF\xB7\xFF\xCE\xA5', 253 encrypted_content_info['encrypted_content'].native 254 ) 255 256 def test_parse_content_info_enveloped_data(self): 257 with open(os.path.join(fixtures_dir, 'cms-enveloped.der'), 'rb') as f: 258 info = cms.ContentInfo.load(f.read()) 259 260 enveloped_data = info['content'] 261 encrypted_content_info = enveloped_data['encrypted_content_info'] 262 recipient = enveloped_data['recipient_infos'][0].chosen 263 264 self.assertEqual( 265 'enveloped_data', 266 info['content_type'].native 267 ) 268 self.assertEqual( 269 'v0', 270 enveloped_data['version'].native 271 ) 272 self.assertEqual( 273 None, 274 enveloped_data['originator_info'].native 275 ) 276 self.assertEqual( 277 1, 278 len(enveloped_data['recipient_infos']) 279 ) 280 self.assertEqual( 281 'v0', 282 recipient['version'].native 283 ) 284 self.assertEqual( 285 util.OrderedDict([ 286 ( 287 'issuer', 288 util.OrderedDict([ 289 ('country_name', 'US'), 290 ('state_or_province_name', 'Massachusetts'), 291 ('locality_name', 'Newbury'), 292 ('organization_name', 'Codex Non Sufficit LC'), 293 ('organizational_unit_name', 'Testing'), 294 ('common_name', 'Will Bond'), 295 ('email_address', 'will@codexns.io'), 296 ]) 297 ), 298 ( 299 'serial_number', 300 13683582341504654466 301 ) 302 ]), 303 recipient['rid'].native 304 ) 305 self.assertEqual( 306 'rsaes_pkcs1v15', 307 recipient['key_encryption_algorithm']['algorithm'].native 308 ) 309 self.assertEqual( 310 None, 311 recipient['key_encryption_algorithm']['parameters'].native 312 ) 313 self.assertEqual( 314 b'\x97\x0A\xFD\x3B\x5C\x27\x45\x69\xCC\xDD\x45\x9E\xA7\x3C\x07\x27\x35\x16\x20\x21\xE4\x6E\x1D\xF8' 315 b'\x5B\xE8\x7F\xD8\x40\x41\xE9\xF2\x92\xCD\xC8\xC5\x03\x95\xEC\x6C\x0B\x97\x71\x87\x86\x3C\xEB\x68' 316 b'\x84\x06\x4E\xE6\xD0\xC4\x7D\x32\xFE\xA6\x06\xC9\xD5\xE1\x8B\xDA\xBF\x96\x5C\x20\x15\x49\x64\x7A' 317 b'\xA2\x4C\xFF\x8B\x0D\xEA\x76\x35\x9B\x7C\x43\xF7\x21\x95\x26\xE7\x70\x30\x98\x5F\x0D\x5E\x4A\xCB' 318 b'\xAD\x47\xDF\x46\xDA\x1F\x0E\xE2\xFE\x3A\x40\xD9\xF2\xDC\x0C\x97\xD9\x91\xED\x34\x8D\xF3\x73\xB0' 319 b'\x90\xF9\xDD\x31\x4D\x37\x93\x81\xD3\x92\xCB\x72\x4A\xD6\x9D\x01\x82\x85\xD5\x1F\xE2\xAA\x32\x12' 320 b'\x82\x4E\x17\xF6\xAA\x58\xDE\xBD\x1B\x80\xAF\x61\xF1\x8A\xD1\x7F\x9D\x41\x6A\xC0\xE4\xC7\x7E\x17' 321 b'\xDC\x94\x33\xE9\x74\x7E\xE9\xF8\x5C\x30\x87\x9B\xD6\xF0\xE3\x4A\xB7\xE3\xCC\x51\x8A\xD4\x37\xF1' 322 b'\xF9\x33\xB5\xD6\x1F\x36\xC1\x6F\x91\xA8\x5F\xE2\x6B\x08\xC7\x9D\xE8\xFD\xDC\xE8\x78\xE0\xC0\xC7' 323 b'\xCF\xC5\xEE\x60\xEC\x54\xFF\x1A\x9C\xF7\x4E\x2C\xD0\x88\xDC\xC2\x1F\xDC\x8A\x37\x9B\x71\x20\xFF' 324 b'\xFD\x6C\xE5\xBA\x8C\xDF\x0E\x3F\x20\xC6\xCB\x08\xA7\x07\xDB\x83', 325 recipient['encrypted_key'].native 326 ) 327 self.assertEqual( 328 'data', 329 encrypted_content_info['content_type'].native 330 ) 331 self.assertEqual( 332 'tripledes_3key', 333 encrypted_content_info['content_encryption_algorithm']['algorithm'].native 334 ) 335 self.assertEqual( 336 'tripledes', 337 encrypted_content_info['content_encryption_algorithm'].encryption_cipher 338 ) 339 self.assertEqual( 340 'cbc', 341 encrypted_content_info['content_encryption_algorithm'].encryption_mode 342 ) 343 self.assertEqual( 344 24, 345 encrypted_content_info['content_encryption_algorithm'].key_length 346 ) 347 self.assertEqual( 348 8, 349 encrypted_content_info['content_encryption_algorithm'].encryption_block_size 350 ) 351 self.assertEqual( 352 b'\x52\x50\x98\xFA\x33\x88\xC7\x3C', 353 encrypted_content_info['content_encryption_algorithm']['parameters'].native 354 ) 355 self.assertEqual( 356 b'\xDC\x88\x55\x08\xE5\x67\x70\x49\x99\x54\xFD\xF8\x40\x7C\x38\xD5\x78\x1D\x6A\x95\x6D\x1E\xC4\x12' 357 b'\x39\xFE\xC0\x76\xDC\xF5\x79\x1A\x69\xA1\xB9\x40\x1E\xCF\xC8\x79\x3E\xF3\x38\xB4\x90\x00\x27\xD1' 358 b'\xB5\x64\xAB\x99\x51\x13\xF1\x0A', 359 encrypted_content_info['encrypted_content'].native 360 ) 361 self.assertEqual( 362 None, 363 enveloped_data['unprotected_attrs'].native 364 ) 365 366 def test_parse_content_info_cms_signed_data(self): 367 with open(os.path.join(fixtures_dir, 'cms-signed.der'), 'rb') as f: 368 info = cms.ContentInfo.load(f.read()) 369 370 signed_data = info['content'] 371 encap_content_info = signed_data['encap_content_info'] 372 373 self.assertEqual( 374 'signed_data', 375 info['content_type'].native 376 ) 377 self.assertEqual( 378 'v1', 379 signed_data['version'].native 380 ) 381 self.assertEqual( 382 [ 383 util.OrderedDict([ 384 ('algorithm', 'sha256'), 385 ('parameters', None), 386 ]) 387 ], 388 signed_data['digest_algorithms'].native 389 ) 390 self.assertEqual( 391 'data', 392 encap_content_info['content_type'].native 393 ) 394 self.assertEqual( 395 b'This is the message to encapsulate in PKCS#7/CMS\r\n', 396 encap_content_info['content'].native 397 ) 398 399 self.assertEqual( 400 1, 401 len(signed_data['certificates']) 402 ) 403 certificate = signed_data['certificates'][0] 404 with open(os.path.join(fixtures_dir, 'keys/test-der.crt'), 'rb') as f: 405 self.assertEqual( 406 f.read(), 407 certificate.dump() 408 ) 409 410 self.assertEqual( 411 1, 412 len(signed_data['signer_infos']) 413 ) 414 signer = signed_data['signer_infos'][0] 415 416 self.assertEqual( 417 'v1', 418 signer['version'].native 419 ) 420 self.assertEqual( 421 util.OrderedDict([ 422 ( 423 'issuer', 424 util.OrderedDict([ 425 ('country_name', 'US'), 426 ('state_or_province_name', 'Massachusetts'), 427 ('locality_name', 'Newbury'), 428 ('organization_name', 'Codex Non Sufficit LC'), 429 ('organizational_unit_name', 'Testing'), 430 ('common_name', 'Will Bond'), 431 ('email_address', 'will@codexns.io'), 432 ]) 433 ), 434 ( 435 'serial_number', 436 13683582341504654466 437 ) 438 ]), 439 signer['sid'].native 440 ) 441 self.assertEqual( 442 util.OrderedDict([ 443 ('algorithm', 'sha256'), 444 ('parameters', None), 445 ]), 446 signer['digest_algorithm'].native 447 ) 448 449 signed_attrs = signer['signed_attrs'] 450 451 self.assertEqual( 452 3, 453 len(signed_attrs) 454 ) 455 self.assertEqual( 456 'content_type', 457 signed_attrs[0]['type'].native 458 ) 459 self.assertEqual( 460 'data', 461 signed_attrs[0]['values'][0].native 462 ) 463 self.assertEqual( 464 'signing_time', 465 signed_attrs[1]['type'].native 466 ) 467 self.assertEqual( 468 datetime(2015, 5, 30, 13, 12, 38, tzinfo=util.timezone.utc), 469 signed_attrs[1]['values'][0].native 470 ) 471 self.assertEqual( 472 'message_digest', 473 signed_attrs[2]['type'].native 474 ) 475 self.assertEqual( 476 b'\xA1\x30\xE2\x87\x90\x5A\x58\x15\x7A\x44\x54\x7A\xB9\xBC\xAE\xD3\x00\xF3\xEC\x3E\x97\xFF' 477 b'\x03\x20\x79\x34\x9D\x62\xAA\x20\xA5\x1D', 478 signed_attrs[2]['values'][0].native 479 ) 480 481 self.assertEqual( 482 util.OrderedDict([ 483 ('algorithm', 'rsassa_pkcs1v15'), 484 ('parameters', None), 485 ]), 486 signer['signature_algorithm'].native 487 ) 488 self.assertEqual( 489 b'\xAC\x2F\xE3\x25\x39\x8F\xD3\xDF\x80\x4F\x0D\xBA\xB1\xEE\x99\x09\xA9\x21\xBB\xDF\x3C\x1E' 490 b'\x70\xDA\xDF\xC4\x0F\x1D\x10\x29\xBC\x94\xBE\xF8\xA8\xC2\x2D\x2A\x1F\x14\xBC\x4A\x5B\x66' 491 b'\x7F\x6F\xE4\xDF\x82\x4D\xD9\x3F\xEB\x89\xAA\x05\x1A\xE5\x58\xCE\xC4\x33\x53\x6E\xE4\x66' 492 b'\xF9\x21\xCF\x80\x35\x46\x88\xB5\x6A\xEA\x5C\x54\x49\x40\x31\xD6\xDC\x20\xD8\xA0\x63\x8C' 493 b'\xC1\xC3\xA1\x72\x5D\x0D\xCE\x43\xB1\x5C\xD8\x32\x3F\xA9\xE7\xBB\xD9\x56\xAE\xE7\xFB\x7C' 494 b'\x37\x32\x8B\x93\xC2\xC4\x47\xDD\x00\xFB\x1C\xEF\xC3\x68\x32\xDC\x06\x26\x17\x45\xF5\xB3' 495 b'\xDC\xD8\x5C\x2B\xC1\x8B\x97\x93\xB8\xF1\x85\xE2\x92\x3B\xC4\x6A\x6A\x89\xC5\x14\x51\x4A' 496 b'\x06\x11\x54\xB0\x29\x07\x75\xD8\xDF\x6B\xFB\x21\xE4\xA4\x09\x17\xAF\xAC\xA0\xF5\xC0\xFE' 497 b'\x7B\x03\x04\x40\x41\x57\xC4\xFD\x58\x1D\x10\x5E\xAC\x23\xAB\xAA\x80\x95\x96\x02\x71\x84' 498 b'\x9C\x0A\xBD\x54\xC4\xA2\x47\xAA\xE7\xC3\x09\x13\x6E\x26\x7D\x72\xAA\xA9\x0B\xF3\xCC\xC4' 499 b'\x48\xB4\x97\x14\x00\x47\x2A\x6B\xD3\x93\x3F\xD8\xFD\xAA\xB9\xFB\xFB\xD5\x09\x8D\x82\x8B' 500 b'\xDE\x0F\xED\x39\x6D\x7B\xDC\x76\x8B\xA6\x4E\x9B\x7A\xBA', 501 signer['signature'].native 502 ) 503 504 def test_parse_content_info_pkcs7_signed_data(self): 505 with open(os.path.join(fixtures_dir, 'pkcs7-signed.der'), 'rb') as f: 506 info = cms.ContentInfo.load(f.read()) 507 508 signed_data = info['content'] 509 encap_content_info = signed_data['encap_content_info'] 510 511 self.assertEqual( 512 'signed_data', 513 info['content_type'].native 514 ) 515 self.assertEqual( 516 'v1', 517 signed_data['version'].native 518 ) 519 self.assertEqual( 520 [ 521 util.OrderedDict([ 522 ('algorithm', 'sha256'), 523 ('parameters', None), 524 ]) 525 ], 526 signed_data['digest_algorithms'].native 527 ) 528 self.assertEqual( 529 'data', 530 encap_content_info['content_type'].native 531 ) 532 self.assertEqual( 533 b'This is the message to encapsulate in PKCS#7/CMS\n', 534 encap_content_info['content'].native 535 ) 536 537 self.assertEqual( 538 1, 539 len(signed_data['certificates']) 540 ) 541 certificate = signed_data['certificates'][0] 542 with open(os.path.join(fixtures_dir, 'keys/test-der.crt'), 'rb') as f: 543 self.assertEqual( 544 f.read(), 545 certificate.dump() 546 ) 547 548 self.assertEqual( 549 1, 550 len(signed_data['signer_infos']) 551 ) 552 signer = signed_data['signer_infos'][0] 553 554 self.assertEqual( 555 'v1', 556 signer['version'].native 557 ) 558 self.assertEqual( 559 util.OrderedDict([ 560 ( 561 'issuer', 562 util.OrderedDict([ 563 ('country_name', 'US'), 564 ('state_or_province_name', 'Massachusetts'), 565 ('locality_name', 'Newbury'), 566 ('organization_name', 'Codex Non Sufficit LC'), 567 ('organizational_unit_name', 'Testing'), 568 ('common_name', 'Will Bond'), 569 ('email_address', 'will@codexns.io'), 570 ]) 571 ), 572 ( 573 'serial_number', 574 13683582341504654466 575 ) 576 ]), 577 signer['sid'].native 578 ) 579 self.assertEqual( 580 util.OrderedDict([ 581 ('algorithm', 'sha256'), 582 ('parameters', None), 583 ]), 584 signer['digest_algorithm'].native 585 ) 586 587 signed_attrs = signer['signed_attrs'] 588 589 self.assertEqual( 590 4, 591 len(signed_attrs) 592 ) 593 self.assertEqual( 594 'content_type', 595 signed_attrs[0]['type'].native 596 ) 597 self.assertEqual( 598 'data', 599 signed_attrs[0]['values'][0].native 600 ) 601 self.assertEqual( 602 'signing_time', 603 signed_attrs[1]['type'].native 604 ) 605 self.assertEqual( 606 datetime(2015, 6, 3, 5, 55, 12, tzinfo=util.timezone.utc), 607 signed_attrs[1]['values'][0].native 608 ) 609 self.assertEqual( 610 'message_digest', 611 signed_attrs[2]['type'].native 612 ) 613 self.assertEqual( 614 b'\x52\x88\x25\x47\x15\x5B\x2D\x50\x44\x68\x05\x24\xC8\x71\x5A\xCC\x62\x28\x36\x17\xB7\x68' 615 b'\xEE\xA1\x12\x90\x96\x4F\x94\xAE\xDB\x79', 616 signed_attrs[2]['values'][0].native 617 ) 618 619 self.assertEqual( 620 util.OrderedDict([ 621 ('algorithm', 'rsassa_pkcs1v15'), 622 ('parameters', None), 623 ]), 624 signer['signature_algorithm'].native 625 ) 626 self.assertEqual( 627 b'\x43\x66\xEE\xF4\x6A\x02\x6F\xFE\x0D\xAE\xE6\xF3\x7A\x8F\x2C\x8E\x26\xB6\x25\x68\xEF\x5B' 628 b'\x4B\x4F\x9C\xE4\xE6\x71\x42\x22\xEC\x97\xFC\x53\xD9\xD6\x36\x1F\xA1\x32\x35\xFF\xA9\x95' 629 b'\x45\x50\x36\x36\x0C\x9A\x10\x6F\x06\xB6\x9D\x25\x10\x08\xF5\xF4\xE1\x68\x62\x60\xE5\xBF' 630 b'\xBD\xE2\x9F\xBD\x8A\x10\x29\x3B\xAF\xE7\xD6\x55\x7C\xEE\x3B\xFB\x93\x42\xE0\xB4\x4F\x89' 631 b'\xD0\x7B\x18\x51\x85\x90\x47\xF0\x5E\xE1\x15\x2C\xC1\x9A\xF1\x49\xE8\x11\x29\x17\x2E\x77' 632 b'\xD3\x35\x10\xAA\xCD\x32\x07\x32\x74\xCF\x2D\x89\xBD\xEF\xC7\xC9\xE7\xEC\x90\x44\xCE\x0B' 633 b'\xC5\x97\x00\x26\x67\x8A\x89\x5B\xFA\x46\xB2\x92\xD5\xCB\xA3\x52\x16\xDC\xF0\xF0\x79\xCB' 634 b'\x90\x93\x8E\x26\xB3\xEB\x8F\xBD\x54\x06\xD6\xB0\xA0\x04\x47\x7C\x63\xFC\x88\x5A\xE3\x81' 635 b'\xDF\x1E\x4D\x39\xFD\xF5\xA0\xE2\xD3\xAB\x13\xC1\xCF\x50\xB2\x0B\xC9\x36\xD6\xCB\xEA\x55' 636 b'\x39\x97\x8E\x34\x47\xE3\x6B\x44\x4A\x0E\x03\xAF\x41\xB2\x47\x2E\x26\xA3\x6B\x5F\xA1\x5C' 637 b'\x86\xA1\x96\x37\x02\xD3\x7C\x5F\xC1\xAF\x81\xE4\x1A\xD9\x87\x44\xB5\xB3\x5C\x45\x6C\xFF' 638 b'\x97\x4C\x3A\xB4\x2F\x5C\x2F\x86\x15\x51\x71\xA6\x27\x68', 639 signer['signature'].native 640 ) 641 642 def test_parse_cms_signed_date_indefinite_length(self): 643 with open(os.path.join(fixtures_dir, 'cms-signed-indefinite-length.der'), 'rb') as f: 644 info = cms.ContentInfo.load(f.read()) 645 signed_data = info['content'] 646 self.assertIsInstance(signed_data.native, util.OrderedDict) 647 648 def test_parse_content_info_cms_signed_digested_data(self): 649 with open(os.path.join(fixtures_dir, 'cms-signed-digested.der'), 'rb') as f: 650 info = cms.ContentInfo.load(f.read()) 651 652 signed_data = info['content'] 653 encap_content_info = signed_data['encap_content_info'] 654 655 self.assertEqual( 656 'signed_data', 657 info['content_type'].native 658 ) 659 self.assertEqual( 660 'v2', 661 signed_data['version'].native 662 ) 663 self.assertEqual( 664 [ 665 util.OrderedDict([ 666 ('algorithm', 'sha256'), 667 ('parameters', None), 668 ]) 669 ], 670 signed_data['digest_algorithms'].native 671 ) 672 self.assertEqual( 673 'digested_data', 674 encap_content_info['content_type'].native 675 ) 676 self.assertEqual( 677 util.OrderedDict([ 678 ('version', 'v0'), 679 ( 680 'digest_algorithm', 681 util.OrderedDict([ 682 ('algorithm', 'sha1'), 683 ('parameters', None), 684 ]) 685 ), 686 ( 687 'encap_content_info', 688 util.OrderedDict([ 689 ('content_type', 'data'), 690 ('content', b'This is the message to encapsulate in PKCS#7/CMS\n'), 691 ]) 692 ), 693 ( 694 'digest', 695 b'\x53\xC9\xDB\xC1\x6D\xDB\x34\x3B\x28\x4E\xEF\xA6\x03\x0E\x02\x64\x79\x31\xAF\xFB' 696 ) 697 ]), 698 encap_content_info['content'].native 699 ) 700 701 self.assertEqual( 702 1, 703 len(signed_data['certificates']) 704 ) 705 certificate = signed_data['certificates'][0] 706 with open(os.path.join(fixtures_dir, 'keys/test-der.crt'), 'rb') as f: 707 self.assertEqual( 708 f.read(), 709 certificate.dump() 710 ) 711 712 self.assertEqual( 713 1, 714 len(signed_data['signer_infos']) 715 ) 716 signer = signed_data['signer_infos'][0] 717 718 self.assertEqual( 719 'v1', 720 signer['version'].native 721 ) 722 self.assertEqual( 723 util.OrderedDict([ 724 ( 725 'issuer', 726 util.OrderedDict([ 727 ('country_name', 'US'), 728 ('state_or_province_name', 'Massachusetts'), 729 ('locality_name', 'Newbury'), 730 ('organization_name', 'Codex Non Sufficit LC'), 731 ('organizational_unit_name', 'Testing'), 732 ('common_name', 'Will Bond'), 733 ('email_address', 'will@codexns.io'), 734 ]) 735 ), 736 ( 737 'serial_number', 738 13683582341504654466 739 ) 740 ]), 741 signer['sid'].native 742 ) 743 self.assertEqual( 744 util.OrderedDict([ 745 ('algorithm', 'sha256'), 746 ('parameters', None), 747 ]), 748 signer['digest_algorithm'].native 749 ) 750 751 signed_attrs = signer['signed_attrs'] 752 753 self.assertEqual( 754 0, 755 len(signed_attrs) 756 ) 757 758 self.assertEqual( 759 util.OrderedDict([ 760 ('algorithm', 'rsassa_pkcs1v15'), 761 ('parameters', None), 762 ]), 763 signer['signature_algorithm'].native 764 ) 765 self.assertEqual( 766 b'\x70\xBC\x18\x82\x41\xD6\xD8\xE7\x5C\xDC\x42\x27\xA5\xA8\xAA\x8B\x16\x15\x61\x3A\xE5\x47' 767 b'\x53\xFD\x8F\x45\xA3\x82\xE2\x72\x44\x07\xD1\xCB\xBF\xB4\x85\x4A\x2A\x16\x19\xDE\xDC\x53' 768 b'\x15\xCF\x98\xEE\x5C\x0E\xDF\xDE\xC8\x79\xCE\x2B\x38\x61\x36\xB0\xA1\xCB\x94\xD6\x4F\xCD' 769 b'\x83\xEF\x0C\xC9\x23\xA0\x7B\x8B\x65\x40\x5C\x3D\xA8\x3E\xCC\x0D\x1F\x17\x23\xF3\x74\x9F' 770 b'\x7E\x88\xF8\xF3\xBE\x4E\x19\x95\x0F\xEB\x95\x55\x69\xB4\xAA\xC3\x2A\x36\x03\x93\x1C\xDC' 771 b'\xE5\x65\x3F\x4E\x5E\x03\xC8\x56\xD8\x57\x8F\xE8\x2D\x85\x32\xDA\xFD\x79\xD4\xDD\x88\xCA' 772 b'\xA3\x14\x41\xE4\x3B\x03\x88\x0E\x2B\x76\xDC\x44\x3D\x4D\xFF\xB2\xC8\xC3\x83\xB1\x33\x37' 773 b'\x53\x51\x33\x4B\xCA\x1A\xAD\x7E\x6A\xBC\x61\x8B\x84\xDB\x7F\xCF\x61\xB2\x1D\x21\x83\xCF' 774 b'\xB8\x3F\xC6\x98\xED\xD8\x66\x06\xCF\x03\x30\x96\x9D\xB4\x7A\x16\xDF\x6E\xA7\x30\xEB\x77' 775 b'\xF7\x40\x13\xFB\xF2\xAC\x41\x79\x9D\xDC\xC0\xED\x4B\x8B\x19\xEE\x05\x3D\x61\x20\x39\x7E' 776 b'\x80\x1D\x3A\x23\x69\x48\x43\x60\x8B\x3E\x63\xAD\x01\x7A\xDE\x6F\x01\xBA\x51\xF3\x4B\x14' 777 b'\xBF\x6B\x77\x1A\x32\xC2\x0C\x93\xCC\x35\xBC\x66\xC6\x69', 778 signer['signature'].native 779 ) 780 781 def test_parse_content_info_pkcs7_signed_digested_data(self): 782 with open(os.path.join(fixtures_dir, 'pkcs7-signed-digested.der'), 'rb') as f: 783 info = cms.ContentInfo.load(f.read()) 784 785 signed_data = info['content'] 786 encap_content_info = signed_data['encap_content_info'] 787 788 self.assertEqual( 789 'signed_data', 790 info['content_type'].native 791 ) 792 self.assertEqual( 793 'v1', 794 signed_data['version'].native 795 ) 796 self.assertEqual( 797 [ 798 util.OrderedDict([ 799 ('algorithm', 'sha256'), 800 ('parameters', None), 801 ]) 802 ], 803 signed_data['digest_algorithms'].native 804 ) 805 self.assertEqual( 806 'digested_data', 807 encap_content_info['content_type'].native 808 ) 809 self.assertEqual( 810 util.OrderedDict([ 811 ('version', 'v0'), 812 ( 813 'digest_algorithm', 814 util.OrderedDict([ 815 ('algorithm', 'sha1'), 816 ('parameters', None), 817 ]) 818 ), 819 ( 820 'encap_content_info', 821 util.OrderedDict([ 822 ('content_type', 'data'), 823 ('content', b'This is the message to encapsulate in PKCS#7/CMS\n'), 824 ]) 825 ), 826 ( 827 'digest', 828 b'\x53\xC9\xDB\xC1\x6D\xDB\x34\x3B\x28\x4E\xEF\xA6\x03\x0E\x02\x64\x79\x31\xAF\xFB' 829 ) 830 ]), 831 encap_content_info['content'].native 832 ) 833 834 self.assertEqual( 835 1, 836 len(signed_data['certificates']) 837 ) 838 certificate = signed_data['certificates'][0] 839 with open(os.path.join(fixtures_dir, 'keys/test-der.crt'), 'rb') as f: 840 self.assertEqual( 841 f.read(), 842 certificate.dump() 843 ) 844 845 self.assertEqual( 846 1, 847 len(signed_data['signer_infos']) 848 ) 849 signer = signed_data['signer_infos'][0] 850 851 self.assertEqual( 852 'v1', 853 signer['version'].native 854 ) 855 self.assertEqual( 856 util.OrderedDict([ 857 ( 858 'issuer', 859 util.OrderedDict([ 860 ('country_name', 'US'), 861 ('state_or_province_name', 'Massachusetts'), 862 ('locality_name', 'Newbury'), 863 ('organization_name', 'Codex Non Sufficit LC'), 864 ('organizational_unit_name', 'Testing'), 865 ('common_name', 'Will Bond'), 866 ('email_address', 'will@codexns.io'), 867 ]) 868 ), 869 ( 870 'serial_number', 871 13683582341504654466 872 ) 873 ]), 874 signer['sid'].native 875 ) 876 self.assertEqual( 877 util.OrderedDict([ 878 ('algorithm', 'sha256'), 879 ('parameters', None), 880 ]), 881 signer['digest_algorithm'].native 882 ) 883 884 signed_attrs = signer['signed_attrs'] 885 886 self.assertEqual( 887 0, 888 len(signed_attrs) 889 ) 890 891 self.assertEqual( 892 util.OrderedDict([ 893 ('algorithm', 'rsassa_pkcs1v15'), 894 ('parameters', None), 895 ]), 896 signer['signature_algorithm'].native 897 ) 898 self.assertEqual( 899 b'\x70\xBC\x18\x82\x41\xD6\xD8\xE7\x5C\xDC\x42\x27\xA5\xA8\xAA\x8B\x16\x15\x61\x3A\xE5\x47' 900 b'\x53\xFD\x8F\x45\xA3\x82\xE2\x72\x44\x07\xD1\xCB\xBF\xB4\x85\x4A\x2A\x16\x19\xDE\xDC\x53' 901 b'\x15\xCF\x98\xEE\x5C\x0E\xDF\xDE\xC8\x79\xCE\x2B\x38\x61\x36\xB0\xA1\xCB\x94\xD6\x4F\xCD' 902 b'\x83\xEF\x0C\xC9\x23\xA0\x7B\x8B\x65\x40\x5C\x3D\xA8\x3E\xCC\x0D\x1F\x17\x23\xF3\x74\x9F' 903 b'\x7E\x88\xF8\xF3\xBE\x4E\x19\x95\x0F\xEB\x95\x55\x69\xB4\xAA\xC3\x2A\x36\x03\x93\x1C\xDC' 904 b'\xE5\x65\x3F\x4E\x5E\x03\xC8\x56\xD8\x57\x8F\xE8\x2D\x85\x32\xDA\xFD\x79\xD4\xDD\x88\xCA' 905 b'\xA3\x14\x41\xE4\x3B\x03\x88\x0E\x2B\x76\xDC\x44\x3D\x4D\xFF\xB2\xC8\xC3\x83\xB1\x33\x37' 906 b'\x53\x51\x33\x4B\xCA\x1A\xAD\x7E\x6A\xBC\x61\x8B\x84\xDB\x7F\xCF\x61\xB2\x1D\x21\x83\xCF' 907 b'\xB8\x3F\xC6\x98\xED\xD8\x66\x06\xCF\x03\x30\x96\x9D\xB4\x7A\x16\xDF\x6E\xA7\x30\xEB\x77' 908 b'\xF7\x40\x13\xFB\xF2\xAC\x41\x79\x9D\xDC\xC0\xED\x4B\x8B\x19\xEE\x05\x3D\x61\x20\x39\x7E' 909 b'\x80\x1D\x3A\x23\x69\x48\x43\x60\x8B\x3E\x63\xAD\x01\x7A\xDE\x6F\x01\xBA\x51\xF3\x4B\x14' 910 b'\xBF\x6B\x77\x1A\x32\xC2\x0C\x93\xCC\x35\xBC\x66\xC6\x69', 911 signer['signature'].native 912 ) 913 914 def test_parse_content_info_smime_capabilities(self): 915 with open(os.path.join(fixtures_dir, 'smime-signature-generated-by-thunderbird.p7s'), 'rb') as f: 916 info = cms.ContentInfo.load(f.read()) 917 918 signed_attrs = info['content']['signer_infos'][0]['signed_attrs'] 919 920 self.assertEqual( 921 'smime_capabilities', 922 signed_attrs[3]['type'].native 923 ) 924 smime_capabilities = signed_attrs[3] 925 926 self.assertEqual( 927 1, 928 len(smime_capabilities['values']) 929 ) 930 self.assertEqual( 931 7, 932 len(smime_capabilities['values'][0]) 933 ) 934 self.assertEqual( 935 [capability.native for capability in smime_capabilities['values'][0]], 936 [ 937 util.OrderedDict([ 938 ('capability_id', 'aes256_cbc'), 939 ('parameters', None), 940 ]), 941 util.OrderedDict([ 942 ('capability_id', 'aes128_cbc'), 943 ('parameters', None), 944 ]), 945 util.OrderedDict([ 946 ('capability_id', 'tripledes_3key'), 947 ('parameters', None), 948 ]), 949 util.OrderedDict([ 950 ('capability_id', 'rc2'), 951 ('parameters', 128), 952 ]), 953 util.OrderedDict([ 954 ('capability_id', 'rc2'), 955 ('parameters', 64), 956 ]), 957 util.OrderedDict([ 958 ('capability_id', 'des'), 959 ('parameters', None), 960 ]), 961 util.OrderedDict([ 962 ('capability_id', 'rc2'), 963 ('parameters', 40), 964 ]), 965 ] 966 ) 967 968 def test_bad_teletex_inside_pkcs7(self): 969 with open(os.path.join(fixtures_dir, 'mozilla-generated-by-openssl.pkcs7.der'), 'rb') as f: 970 content = cms.ContentInfo.load(f.read())['content'] 971 self.assertEqual( 972 util.OrderedDict([ 973 ('organizational_unit_name', 'Testing'), 974 ('country_name', 'US'), 975 ('locality_name', 'Mountain View'), 976 ('organization_name', 'Addons Testing'), 977 ('state_or_province_name', 'CA'), 978 ('common_name', '{02b860db-e71f-48d2-a5a0-82072a93d33c}') 979 ]), 980 content['certificates'][0].chosen['tbs_certificate']['subject'].native 981 ) 982 983 def test_parse_attribute_cert(self): 984 # regression test for tagging issue in AttCertIssuer 985 986 with open(os.path.join(fixtures_dir, 'example-attr-cert.der'), 'rb') as f: 987 ac_bytes = f.read() 988 ac_parsed = cms.AttributeCertificateV2.load(ac_bytes) 989 self.assertEqual(ac_bytes, ac_parsed.dump(force=True)) 990 991 ac_info = ac_parsed['ac_info'] 992 self.assertIsInstance(ac_info['issuer'].chosen, cms.V2Form) 993 self.assertEqual(1, len(ac_info['issuer'].chosen['issuer_name'])) 994 995 def test_create_role_syntax(self): 996 rs = cms.RoleSyntax({'role_name': {'rfc822_name': 'test@example.com'}}) 997 self.assertEqual( 998 util.OrderedDict([ 999 ('role_authority', None), 1000 ('role_name', 'test@example.com') 1001 ]), 1002 rs.native 1003 ) 1004