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