1# 2# This file is part of pyasn1-modules software. 3# 4# Created by Russ Housley 5# Copyright (c) 2019, Vigil Security, LLC 6# License: http://snmplabs.com/pyasn1/license.html 7# 8 9import sys 10 11from pyasn1.codec.der.decoder import decode as der_decode 12from pyasn1.codec.der.encoder import encode as der_encode 13 14from pyasn1.compat.octets import str2octs 15 16from pyasn1_modules import pem 17from pyasn1_modules import rfc2634 18from pyasn1_modules import rfc4073 19from pyasn1_modules import rfc5652 20 21try: 22 import unittest2 as unittest 23except ImportError: 24 import unittest 25 26 27class ContentCollectionTestCase(unittest.TestCase): 28 pem_text = """\ 29MIIG/QYLKoZIhvcNAQkQAROgggbsMIIG6DCCAWcGCyqGSIb3DQEJEAEUoIIBVjCC 30AVIwgfEGCSqGSIb3DQEHAaCB4wSB4ENvbnRlbnQtVHlwZTogdGV4dC9wbGFpbgoK 31UkZDIDQwNzMsIHB1Ymxpc2hlZCBpbiBNYXkgMjAwNSwgZGVzY3JpYmVzIGEgY29u 32dmVudGlvbiBmb3IgdXNpbmcgdGhlCkNyeXB0b2dyYXBoaWMgTWVzc2FnZSBTeW50 33YXggKENNUykgdG8gcHJvdGVjdCBhIGNvbnRlbnQgY29sbGVjdGlvbi4gIElmCmRl 34c2lyZWQsIGF0dHJpYnV0ZXMgY2FuIGJlIGFzc29jaWF0ZWQgd2l0aCB0aGUgY29u 35dGVudC4KMFwwMwYLKoZIhvcNAQkQAgQxJDAiDBVBYnN0cmFjdCBmb3IgUkZDIDQw 36NzMGCSqGSIb3DQEHATAlBgsqhkiG9w0BCRACBzEWBBSkLSXBiRWvbwnJKb4EGb1X 37FwCa3zCCBXkGCyqGSIb3DQEJEAEUoIIFaDCCBWQwggT9BgkqhkiG9w0BBwGgggTu 38BIIE6kNvbnRlbnQtVHlwZTogdGV4dC9wbGFpbgoKVGhlIGZvbGxvd2luZyBBU04u 39MSBtb2R1bGUgZGVmaW5lcyB0aGUgc3RydWN0dXJlcyB0aGF0IGFyZSBuZWVkZWQg 40dG8KaW1wbGVtZW50IHRoZSBzcGVjaWZpY2F0aW9uIGluIFJGQyA0MDczLiAgSXQg 41aXMgZXhwZWN0ZWQgdG8gYmUgdXNlZCBpbgpjb25qdW5jdGlvbiB3aXRoIHRoZSBB 42U04uMSBtb2R1bGVzIGluIFJGQyA1NjUyIGFuZCBSRkMgMzI3NC4KCiAgIENvbnRl 43bnRDb2xsZWN0aW9uTW9kdWxlCiAgICAgeyBpc28oMSkgbWVtYmVyLWJvZHkoMikg 44dXMoODQwKSByc2Fkc2koMTEzNTQ5KSBwa2NzKDEpCiAgICAgICBwa2NzLTkoOSkg 45c21pbWUoMTYpIG1vZHVsZXMoMCkgMjYgfQoKICAgREVGSU5JVElPTlMgSU1QTElD 46SVQgVEFHUyA6Oj0KICAgQkVHSU4KCiAgIElNUE9SVFMKICAgICBBdHRyaWJ1dGUs 47IENvbnRlbnRJbmZvCiAgICAgICBGUk9NIENyeXB0b2dyYXBoaWNNZXNzYWdlU3lu 48dGF4MjAwNCAtLSBbQ01TXQogICAgICAgICB7IGlzbygxKSBtZW1iZXItYm9keSgy 49KSB1cyg4NDApIHJzYWRzaSgxMTM1NDkpCiAgICAgICAgICAgcGtjcygxKSBwa2Nz 50LTkoOSkgc21pbWUoMTYpIG1vZHVsZXMoMCkgY21zLTIwMDEoMTQpIH07CgoKICAg 51LS0gQ29udGVudCBDb2xsZWN0aW9uIENvbnRlbnQgVHlwZSBhbmQgT2JqZWN0IElk 52ZW50aWZpZXIKCiAgIGlkLWN0LWNvbnRlbnRDb2xsZWN0aW9uIE9CSkVDVCBJREVO 53VElGSUVSIDo6PSB7CiAgICAgICAgICAgaXNvKDEpIG1lbWJlci1ib2R5KDIpIHVz 54KDg0MCkgcnNhZHNpKDExMzU0OSkgcGtjcygxKQogICAgICAgICAgIHBrY3M5KDkp 55IHNtaW1lKDE2KSBjdCgxKSAxOSB9CgogICBDb250ZW50Q29sbGVjdGlvbiA6Oj0g 56U0VRVUVOQ0UgU0laRSAoMS4uTUFYKSBPRiBDb250ZW50SW5mbwoKICAgLS0gQ29u 57dGVudCBXaXRoIEF0dHJpYnV0ZXMgQ29udGVudCBUeXBlIGFuZCBPYmplY3QgSWRl 58bnRpZmllcgoKICAgaWQtY3QtY29udGVudFdpdGhBdHRycyBPQkpFQ1QgSURFTlRJ 59RklFUiA6Oj0gewogICAgICAgICAgIGlzbygxKSBtZW1iZXItYm9keSgyKSB1cyg4 60NDApIHJzYWRzaSgxMTM1NDkpIHBrY3MoMSkKICAgICAgICAgICBwa2NzOSg5KSBz 61bWltZSgxNikgY3QoMSkgMjAgfQoKICAgQ29udGVudFdpdGhBdHRyaWJ1dGVzIDo6 62PSBTRVFVRU5DRSB7CiAgICAgICBjb250ZW50ICAgICBDb250ZW50SW5mbywKICAg 63ICAgIGF0dHJzICAgICAgIFNFUVVFTkNFIFNJWkUgKDEuLk1BWCkgT0YgQXR0cmli 64dXRlIH0KCiAgIEVORAowYTA4BgsqhkiG9w0BCRACBDEpMCcMGkFTTi4xIE1vZHVs 65ZSBmcm9tIFJGQyA0MDczBgkqhkiG9w0BBwEwJQYLKoZIhvcNAQkQAgcxFgQUMbeK 66buWO3egPDL8Kf7tBhzjIKLw= 67""" 68 69 def setUp(self): 70 self.asn1Spec = rfc5652.ContentInfo() 71 72 def testDerCodec(self): 73 74 def test_layer(substrate, content_type): 75 asn1Object, rest = der_decode(substrate, asn1Spec=layers[content_type]) 76 assert not rest 77 assert asn1Object.prettyPrint() 78 assert der_encode(asn1Object) == substrate 79 80 if content_type == rfc4073.id_ct_contentWithAttrs: 81 for attr in asn1Object['attrs']: 82 assert attr['attrType'] in rfc5652.cmsAttributesMap.keys() 83 84 return asn1Object 85 86 layers = rfc5652.cmsContentTypesMap 87 88 getNextLayer = { 89 rfc5652.id_ct_contentInfo: lambda x: x['contentType'], 90 rfc4073.id_ct_contentCollection: lambda x: x[0]['contentType'], 91 rfc4073.id_ct_contentWithAttrs: lambda x: x['content']['contentType'], 92 rfc5652.id_data: lambda x: None, 93 } 94 95 getNextSubstrate = { 96 rfc5652.id_ct_contentInfo: lambda x: x['content'], 97 rfc4073.id_ct_contentCollection: lambda x: x[0]['content'], 98 rfc4073.id_ct_contentWithAttrs: lambda x: x['content']['content'], 99 rfc5652.id_data: lambda x: None, 100 } 101 102 substrate = pem.readBase64fromText(self.pem_text) 103 104 this_layer = rfc5652.id_ct_contentInfo 105 while this_layer != rfc5652.id_data: 106 if this_layer == rfc4073.id_ct_contentCollection: 107 asn1Object = test_layer(substrate, this_layer) 108 for ci in asn1Object: 109 substrate = ci['content'] 110 this_layer = ci['contentType'] 111 while this_layer != rfc5652.id_data: 112 asn1Object = test_layer(substrate, this_layer) 113 substrate = getNextSubstrate[this_layer](asn1Object) 114 this_layer = getNextLayer[this_layer](asn1Object) 115 else: 116 asn1Object = test_layer(substrate, this_layer) 117 substrate = getNextSubstrate[this_layer](asn1Object) 118 this_layer = getNextLayer[this_layer](asn1Object) 119 120 def testOpenTypes(self): 121 substrate = pem.readBase64fromText(self.pem_text) 122 asn1Object, rest = der_decode(substrate, 123 asn1Spec=rfc5652.ContentInfo(), 124 decodeOpenTypes=True) 125 assert not rest 126 assert asn1Object.prettyPrint() 127 assert der_encode(asn1Object) == substrate 128 129 assert asn1Object['contentType'] == rfc4073.id_ct_contentCollection 130 for ci in asn1Object['content']: 131 assert ci['contentType'] in rfc5652.cmsContentTypesMap.keys() 132 assert ci['contentType'] == rfc4073.id_ct_contentWithAttrs 133 next_ci = ci['content']['content'] 134 assert next_ci['contentType'] in rfc5652.cmsContentTypesMap.keys() 135 assert next_ci['contentType'] == rfc5652.id_data 136 assert str2octs('Content-Type: text') in next_ci['content'] 137 138 for attr in ci['content']['attrs']: 139 assert attr['attrType'] in rfc5652.cmsAttributesMap.keys() 140 if attr['attrType'] == rfc2634.id_aa_contentHint: 141 assert 'RFC 4073' in attr['attrValues'][0]['contentDescription'] 142 143 144suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) 145 146if __name__ == '__main__': 147 import sys 148 149 result = unittest.TextTestRunner(verbosity=2).run(suite) 150 sys.exit(not result.wasSuccessful())