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 rfc7292 19 20try: 21 import unittest2 as unittest 22except ImportError: 23 import unittest 24 25 26class PKCS12TestCase(unittest.TestCase): 27 pfx_pem_text = """\ 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 75""" 76 77 def setUp(self): 78 self.asn1Spec = rfc7292.PFX() 79 80 def testDerCodec(self): 81 substrate = pem.readBase64fromText(self.pfx_pem_text) 82 asn1Object, rest = der_decode(substrate, asn1Spec=self.asn1Spec) 83 assert not rest 84 assert asn1Object.prettyPrint() 85 assert der_encode(asn1Object) == substrate 86 87 assert asn1Object['version'] == univ.Integer(3) 88 oid = asn1Object['macData']['mac']['digestAlgorithm']['algorithm'] 89 assert oid == univ.ObjectIdentifier('1.3.14.3.2.26') 90 md_hex = asn1Object['macData']['mac']['digest'].prettyPrint() 91 assert md_hex == '0xa5608ffdf651d132b90701aeaaf4ddd3e76e88a7' 92 93 assert asn1Object['authSafe']['contentType'] == rfc5652.id_data 94 data, rest = der_decode(asn1Object['authSafe']['content'], 95 asn1Spec=univ.OctetString()) 96 assert not rest 97 98 authsafe, rest = der_decode(data, asn1Spec=rfc7292.AuthenticatedSafe()) 99 assert not rest 100 assert authsafe.prettyPrint() 101 assert der_encode(authsafe) == data 102 103 for ci in authsafe: 104 assert ci['contentType'] == rfc5652.id_data 105 data, rest = der_decode(ci['content'], asn1Spec=univ.OctetString()) 106 assert not rest 107 108 sc, rest = der_decode(data, asn1Spec=rfc7292.SafeContents()) 109 assert not rest 110 assert sc.prettyPrint() 111 assert der_encode(sc) == data 112 113 for sb in sc: 114 if sb['bagId'] in rfc7292.pkcs12BagTypeMap: 115 bv, rest = der_decode(sb['bagValue'], 116 asn1Spec=rfc7292.pkcs12BagTypeMap[sb['bagId']]) 117 assert not rest 118 assert bv.prettyPrint() 119 assert der_encode(bv) == sb['bagValue'] 120 121 for attr in sb['bagAttributes']: 122 if attr['attrType'] in rfc5652.cmsAttributesMap: 123 av, rest = der_decode(attr['attrValues'][0], 124 asn1Spec=rfc5652.cmsAttributesMap[attr['attrType']]) 125 assert not rest 126 assert av.prettyPrint() 127 assert der_encode(av) == attr['attrValues'][0] 128 129 def testOpenTypes(self): 130 substrate = pem.readBase64fromText(self.pfx_pem_text) 131 asn1Object, rest = der_decode(substrate, 132 asn1Spec=self.asn1Spec, 133 decodeOpenTypes=True 134 ) 135 assert not rest 136 assert asn1Object.prettyPrint() 137 assert der_encode(asn1Object) == substrate 138 139 digest_alg = asn1Object['macData']['mac']['digestAlgorithm'] 140 assert not digest_alg['parameters'].hasValue() 141 142 authsafe, rest = der_decode(asn1Object['authSafe']['content'], 143 asn1Spec=rfc7292.AuthenticatedSafe(), 144 decodeOpenTypes=True 145 ) 146 assert not rest 147 assert authsafe.prettyPrint() 148 assert der_encode(authsafe) == asn1Object['authSafe']['content'] 149 150 for ci in authsafe: 151 assert ci['contentType'] == rfc5652.id_data 152 sc, rest = der_decode(ci['content'], 153 asn1Spec=rfc7292.SafeContents(), 154 decodeOpenTypes=True 155 ) 156 assert not rest 157 assert sc.prettyPrint() 158 assert der_encode(sc) == ci['content'] 159 160 for sb in sc: 161 if sb['bagId'] == rfc7292.id_pkcs8ShroudedKeyBag: 162 bv = sb['bagValue'] 163 enc_alg = bv['encryptionAlgorithm']['algorithm'] 164 assert enc_alg == rfc7292.pbeWithSHAAnd3_KeyTripleDES_CBC 165 enc_alg_param = bv['encryptionAlgorithm']['parameters'] 166 assert enc_alg_param['iterations'] == 2000 167 168 169suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) 170 171if __name__ == '__main__': 172 unittest.TextTestRunner(verbosity=2).run(suite) 173