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