• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.type import univ
15
16from pyasn1_modules import pem
17from pyasn1_modules import rfc5652
18from pyasn1_modules import rfc7191
19
20try:
21    import unittest2 as unittest
22except ImportError:
23    import unittest
24
25
26class ReceiptRequestTestCase(unittest.TestCase):
27    message1_pem_text = """\
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
59"""
60
61    def setUp(self):
62        self.asn1Spec = rfc5652.ContentInfo()
63
64    def testDerCodec(self):
65        substrate = pem.readBase64fromText(self.message1_pem_text)
66        asn1Object, rest = der_decode (substrate, asn1Spec=self.asn1Spec)
67        assert not rest
68        assert asn1Object.prettyPrint()
69        assert der_encode(asn1Object) == substrate
70
71        assert asn1Object['contentType'] == rfc5652.id_signedData
72        sd, rest = der_decode (asn1Object['content'],
73            asn1Spec=rfc5652.SignedData())
74
75        for sa in sd['signerInfos'][0]['signedAttrs']:
76            sat = sa['attrType']
77            sav0 = sa['attrValues'][0]
78
79            if sat == rfc7191.id_aa_KP_keyPkgIdAndReceiptReq:
80                sav, rest = der_decode(sav0,
81                    asn1Spec=rfc7191.KeyPkgIdentifierAndReceiptReq())
82                assert not rest
83                assert sav.prettyPrint()
84                assert der_encode(sav) == sav0
85
86                package_id_pem_text = "J7icVjsWIlGdF4cceb+siG3f+D0="
87                package_id = pem.readBase64fromText(package_id_pem_text)
88                assert sav['pkgID'] == package_id
89
90    def testOpenTypes(self):
91        substrate = pem.readBase64fromText(self.message1_pem_text)
92        rfc5652.cmsAttributesMap.update(rfc7191.cmsAttributesMapUpdate)
93        asn1Object, rest = der_decode (substrate,
94                                       asn1Spec=self.asn1Spec,
95                                       decodeOpenTypes=True)
96        assert not rest
97        assert asn1Object.prettyPrint()
98        assert der_encode(asn1Object) == substrate
99
100        assert asn1Object['contentType'] == rfc5652.id_signedData
101        v3 = rfc5652.CMSVersion().subtype(value='v3')
102        assert asn1Object['content']['version'] == v3
103
104        for sa in asn1Object['content']['signerInfos'][0]['signedAttrs']:
105            if sa['attrType'] == rfc7191.id_aa_KP_keyPkgIdAndReceiptReq:
106                package_id_pem_text = "J7icVjsWIlGdF4cceb+siG3f+D0="
107                package_id = pem.readBase64fromText(package_id_pem_text)
108                assert sa['attrValues'][0]['pkgID'] == package_id
109
110
111class ReceiptTestCase(unittest.TestCase):
112    message2_pem_text = """\
113MIIEdAYJKoZIhvcNAQcCoIIEZTCCBGECAQMxDTALBglghkgBZQMEAgIwgawGCmCGSAFlAgEC
114TgOggZ0EgZowgZcEFCe4nFY7FiJRnReHHHm/rIht3/g9MH8GCWCGSAFlAgEQAARyMHAxCzAJ
115BgNVBAYTAlVTMQswCQYDVQQIEwJWQTEQMA4GA1UEBxMHSGVybmRvbjEQMA4GA1UEChMHRXhh
116bXBsZTEOMAwGA1UEAxMFQWxpY2UxIDAeBgkqhkiG9w0BCQEWEWFsaWNlQGV4YW1wbGUuY29t
117oIICfDCCAngwggH+oAMCAQICCQCls1QoG7BuOzAKBggqhkjOPQQDAzA/MQswCQYDVQQGEwJV
118UzELMAkGA1UECAwCVkExEDAOBgNVBAcMB0hlcm5kb24xETAPBgNVBAoMCEJvZ3VzIENBMB4X
119DTE5MDUyOTE0NDU0MVoXDTIwMDUyODE0NDU0MVowcDELMAkGA1UEBhMCVVMxCzAJBgNVBAgT
120AlZBMRAwDgYDVQQHEwdIZXJuZG9uMRAwDgYDVQQKEwdFeGFtcGxlMQ4wDAYDVQQDEwVBbGlj
121ZTEgMB4GCSqGSIb3DQEJARYRYWxpY2VAZXhhbXBsZS5jb20wdjAQBgcqhkjOPQIBBgUrgQQA
122IgNiAAT4zZ8HL+xEDpXWkoWp5xFMTz4u4Ae1nF6zXCYlmsEGD5vPu5hl9hDEjd1UHRgJIPoy
1233fJcWWeZ8FHCirICtuMgFisNscG/aTwKyDYOFDuqz/C2jyEwqgWCRyxyohuJXtmjgZQwgZEw
124CwYDVR0PBAQDAgeAMEIGCWCGSAGG+EIBDQQ1FjNUaGlzIGNlcnRpZmljYXRlIGNhbm5vdCBi
125ZSB0cnVzdGVkIGZvciBhbnkgcHVycG9zZS4wHQYDVR0OBBYEFMS6Wg4+euM8gbD0Aqpouxbg
126lg41MB8GA1UdIwQYMBaAFPI12zQE2qVV8r1pA5mwYuziFQjBMAoGCCqGSM49BAMDA2gAMGUC
127MGO5H9E1uAveRGGaf48lN4pov2yH+hCAc5hOAuZKe/f40MKSF8q4w2ij+0euSaKFiAIxAL3g
128xp6sMitCmLQgOH6/RBIC/2syJ97y0KVp9da0PDAvwxLugCHTKZPjjpSLPHHc9TGCARwwggEY
129AgEDgBTEuloOPnrjPIGw9AKqaLsW4JYONTALBglghkgBZQMEAgKgejAZBgkqhkiG9w0BCQMx
130DAYKYIZIAWUCAQJOAzAcBgkqhkiG9w0BCQUxDxcNMTkwNjEzMTYxNjA4WjA/BgkqhkiG9w0B
131CQQxMgQwQSWYpq4jwhMkmS0as0JL3gjYxKLgDfzP2ndTNsAY0m9p8Igp8ZcK4+5n9fXJ43vU
132MAoGCCqGSM49BAMDBGgwZgIxAMfq2EJ5pSl9tGOEVJEgZitc266ljrOg5GDjkd2d089qw1A3
133bUcOYuCdivgxVuhlAgIxAPR9JavxziwCbVyBUWOAiKKYfglTgG3AwNmrKDj0NtXUQ9qDmGAc
1346L+EAY2P5OVB8Q==
135"""
136
137    def setUp(self):
138        self.asn1Spec = rfc5652.ContentInfo()
139
140    def testDerCodec(self):
141        substrate = pem.readBase64fromText(self.message2_pem_text)
142        asn1Object, rest = der_decode (substrate, asn1Spec=self.asn1Spec)
143        assert not rest
144        assert asn1Object.prettyPrint()
145        assert der_encode(asn1Object) == substrate
146
147        assert asn1Object['contentType'] == rfc5652.id_signedData
148        sd, rest = der_decode (asn1Object['content'],
149            asn1Spec=rfc5652.SignedData())
150        assert not rest
151        assert sd.prettyPrint()
152        assert der_encode(sd) == asn1Object['content']
153
154        oid = sd['encapContentInfo']['eContentType']
155        assert oid == rfc7191.id_ct_KP_keyPackageReceipt
156        receipt, rest = der_decode(sd['encapContentInfo']['eContent'],
157            asn1Spec=rfc7191.KeyPackageReceipt())
158        assert not rest
159        assert receipt.prettyPrint()
160        assert der_encode(receipt) == sd['encapContentInfo']['eContent']
161
162        package_id_pem_text = "J7icVjsWIlGdF4cceb+siG3f+D0="
163        package_id = pem.readBase64fromText(package_id_pem_text)
164        assert receipt['receiptOf']['pkgID'] == package_id
165
166    def testOpenTypes(self):
167        substrate = pem.readBase64fromText(self.message2_pem_text)
168        rfc5652.cmsContentTypesMap.update(rfc7191.cmsContentTypesMapUpdate)
169        rfc5652.cmsAttributesMap.update(rfc7191.cmsAttributesMapUpdate)
170        asn1Object, rest = der_decode (substrate,
171                                       asn1Spec=self.asn1Spec,
172                                       decodeOpenTypes=True)
173        assert not rest
174        assert asn1Object.prettyPrint()
175        assert der_encode(asn1Object) == substrate
176
177        assert asn1Object['contentType'] == rfc5652.id_signedData
178        v3 = rfc5652.CMSVersion().subtype(value='v3')
179        assert asn1Object['content']['version'] == v3
180
181        for sa in asn1Object['content']['signerInfos'][0]['signedAttrs']:
182            assert sa['attrType'] in rfc5652.cmsAttributesMap.keys()
183            if sa['attrType'] == rfc5652.id_messageDigest:
184                assert '0x412598a6ae2' in sa['attrValues'][0].prettyPrint()
185
186        ct_oid = asn1Object['content']['encapContentInfo']['eContentType']
187        assert ct_oid in rfc5652.cmsContentTypesMap
188        assert ct_oid == rfc7191.id_ct_KP_keyPackageReceipt
189
190        # Since receipt is inside an OCTET STRING, decodeOpenTypes=True cannot
191        # automatically decode it
192        sd_eci = asn1Object['content']['encapContentInfo']
193        receipt, rest = der_decode(sd_eci['eContent'],
194            asn1Spec=rfc5652.cmsContentTypesMap[sd_eci['eContentType']])
195        package_id_pem_text = "J7icVjsWIlGdF4cceb+siG3f+D0="
196        package_id = pem.readBase64fromText(package_id_pem_text)
197        assert receipt['receiptOf']['pkgID'] == package_id
198
199class ErrorTestCase(unittest.TestCase):
200    message3_pem_text = """\
201MIIEbwYJKoZIhvcNAQcCoIIEYDCCBFwCAQMxDTALBglghkgBZQMEAgIwga0GCmCGSAFlAgEC
202TgaggZ4EgZswgZigFgQUJ7icVjsWIlGdF4cceb+siG3f+D0wewYJYIZIAWUCARAABG4wbDEL
203MAkGA1UEBhMCVVMxCzAJBgNVBAgTAlZBMRAwDgYDVQQHEwdIZXJuZG9uMRAwDgYDVQQKEwdF
204eGFtcGxlMQwwCgYDVQQDEwNCb2IxHjAcBgkqhkiG9w0BCQEWD2JvYkBleGFtcGxlLmNvbQoB
205CqCCAncwggJzMIIB+qADAgECAgkApbNUKBuwbjwwCgYIKoZIzj0EAwMwPzELMAkGA1UEBhMC
206VVMxCzAJBgNVBAgMAlZBMRAwDgYDVQQHDAdIZXJuZG9uMREwDwYDVQQKDAhCb2d1cyBDQTAe
207Fw0xOTA1MjkxOTIwMTNaFw0yMDA1MjgxOTIwMTNaMGwxCzAJBgNVBAYTAlVTMQswCQYDVQQI
208EwJWQTEQMA4GA1UEBxMHSGVybmRvbjEQMA4GA1UEChMHRXhhbXBsZTEMMAoGA1UEAxMDQm9i
209MR4wHAYJKoZIhvcNAQkBFg9ib2JAZXhhbXBsZS5jb20wdjAQBgcqhkjOPQIBBgUrgQQAIgNi
210AAQxpGJVLxa83xhyal+rvmMFs4xS6Q19cCDoAvQkkFe0gUC4glxlWWQuf/FvLCRwwscr877D
2111FZRBrYKPD6Hxv/UKX6Aimou0TnnxsPk98zZpikn9gTrJn2cF9NCzvPVMfmjgZQwgZEwCwYD
212VR0PBAQDAgeAMEIGCWCGSAGG+EIBDQQ1FjNUaGlzIGNlcnRpZmljYXRlIGNhbm5vdCBiZSB0
213cnVzdGVkIGZvciBhbnkgcHVycG9zZS4wHQYDVR0OBBYEFMprZnLeLJtXf5iO4sMq02aOwhql
214MB8GA1UdIwQYMBaAFPI12zQE2qVV8r1pA5mwYuziFQjBMAoGCCqGSM49BAMDA2cAMGQCMBVu
215hLo58RhCiYsOLZFSR3vWHPDCJBnO1vE1uixqEjONHxlBoeGN2MmWs/9PppcHCwIwN9HB5jPc
216J7gTjA9+ipCe+qkztmV+Gy2NBAY6xYC0gh+pb+X5OAI7y7HdctXp+PfrMYIBGzCCARcCAQOA
217FMprZnLeLJtXf5iO4sMq02aOwhqlMAsGCWCGSAFlAwQCAqB6MBkGCSqGSIb3DQEJAzEMBgpg
218hkgBZQIBAk4GMBwGCSqGSIb3DQEJBTEPFw0xOTA2MTMxNjE2MDhaMD8GCSqGSIb3DQEJBDEy
219BDCgXFTUc3ZInjt+MWYkYmXYERk4FgErEZNILlWgVl7Z9pImgLObIpdrGqGPt06/VkwwCgYI
220KoZIzj0EAwMEZzBlAjEAsjJ3iWRUteMKBVsjaYeN6TG9NITRTOpRVkSVq55DcnhwS9g9lu8D
221iNF8uKtW/lk0AjA7z2q40N0lamXkSU7ECasiWOYV1X4cWGiQwMZDKknBPDqXqB6Es6p4J+qe
2220V6+BtY=
223"""
224
225    def setUp(self):
226        self.asn1Spec = rfc5652.ContentInfo()
227
228    def testDerCodec(self):
229        substrate = pem.readBase64fromText(self.message3_pem_text)
230        asn1Object, rest = der_decode (substrate, asn1Spec=self.asn1Spec)
231        assert not rest
232        assert asn1Object.prettyPrint()
233        assert der_encode(asn1Object) == substrate
234
235        assert asn1Object['contentType'] == rfc5652.id_signedData
236        sd, rest = der_decode (asn1Object['content'],
237            asn1Spec=rfc5652.SignedData())
238        assert not rest
239        assert sd.prettyPrint()
240        assert der_encode(sd) == asn1Object['content']
241
242        oid = sd['encapContentInfo']['eContentType']
243        assert oid == rfc7191.id_ct_KP_keyPackageError
244        kpe, rest = der_decode(sd['encapContentInfo']['eContent'],
245            asn1Spec=rfc7191.KeyPackageError())
246        assert not rest
247        assert kpe.prettyPrint()
248        assert der_encode(kpe) == sd['encapContentInfo']['eContent']
249
250        package_id_pem_text = "J7icVjsWIlGdF4cceb+siG3f+D0="
251        package_id = pem.readBase64fromText(package_id_pem_text)
252        assert kpe['errorOf']['pkgID'] == package_id
253        assert kpe['errorCode'] == rfc7191.EnumeratedErrorCode(value=10)
254
255    def testOpenTypes(self):
256        substrate = pem.readBase64fromText(self.message3_pem_text)
257        rfc5652.cmsContentTypesMap.update(rfc7191.cmsContentTypesMapUpdate)
258        rfc5652.cmsAttributesMap.update(rfc7191.cmsAttributesMapUpdate)
259        asn1Object, rest = der_decode (substrate,
260                                       asn1Spec=self.asn1Spec,
261                                       decodeOpenTypes=True)
262        assert not rest
263        assert asn1Object.prettyPrint()
264        assert der_encode(asn1Object) == substrate
265
266        assert asn1Object['contentType'] == rfc5652.id_signedData
267        v3 = rfc5652.CMSVersion().subtype(value='v3')
268        assert asn1Object['content']['version'] == v3
269
270        for sa in asn1Object['content']['signerInfos'][0]['signedAttrs']:
271            assert sa['attrType'] in rfc5652.cmsAttributesMap.keys()
272            if sa['attrType'] == rfc5652.id_messageDigest:
273                assert '0xa05c54d4737' in sa['attrValues'][0].prettyPrint()
274
275        ct_oid = asn1Object['content']['encapContentInfo']['eContentType']
276        assert ct_oid in rfc5652.cmsContentTypesMap.keys()
277        assert ct_oid == rfc7191.id_ct_KP_keyPackageError
278
279        # Since receipt is inside an OCTET STRING, decodeOpenTypes=True cannot
280        # automatically decode it
281        sd_eci = asn1Object['content']['encapContentInfo']
282        kpe, rest = der_decode(sd_eci['eContent'],
283            asn1Spec=rfc5652.cmsContentTypesMap[sd_eci['eContentType']])
284        package_id_pem_text = "J7icVjsWIlGdF4cceb+siG3f+D0="
285        package_id = pem.readBase64fromText(package_id_pem_text)
286        assert kpe['errorOf']['pkgID'] == package_id
287        assert kpe['errorCode'] == rfc7191.EnumeratedErrorCode(value=10)
288
289
290suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
291
292if __name__ == '__main__':
293    import sys
294
295    result = unittest.TextTestRunner(verbosity=2).run(suite)
296    sys.exit(not result.wasSuccessful())
297