diff options
Diffstat (limited to 'tests/test_rfc2985.py')
-rw-r--r-- | tests/test_rfc2985.py | 299 |
1 files changed, 299 insertions, 0 deletions
diff --git a/tests/test_rfc2985.py b/tests/test_rfc2985.py new file mode 100644 index 0000000..f95ede8 --- /dev/null +++ b/tests/test_rfc2985.py @@ -0,0 +1,299 @@ +# +# This file is part of pyasn1-modules software. +# +# Created by Russ Housley +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# +import sys + +from pyasn1.codec.der.decoder import decode as der_decode +from pyasn1.codec.der.encoder import encode as der_encode + +from pyasn1.type import univ + +from pyasn1_modules import pem +from pyasn1_modules import rfc2985 +from pyasn1_modules import rfc5280 +from pyasn1_modules import rfc5652 +from pyasn1_modules import rfc7292 + + +try: + import unittest2 as unittest + +except ImportError: + import unittest + + +class PKCS9AttrsTestCase(unittest.TestCase): + pem_text = """\ +MYIQjzAOBgNVBEExBwwFQWxpY2UwDwYIKwYBBQUHCQMxAxMBTTAQBgNVBAUxCRMH +QjQ4LTAwNzAQBggrBgEFBQcJBDEEEwJVUzAQBggrBgEFBQcJBTEEEwJVUzARBgoq +hkiG9w0BCRkEMQMCATAwFAYJKoZIhvcNAQkCMQcWBUFsaWNlMBgGCiqGSIb3DQEJ +GQMxCgQIUTeqnHYky4AwHAYJKoZIhvcNAQkPMQ8wDTALBglghkgBZQMEAS0wHQYI +KwYBBQUHCQExERgPMjAxOTA4MDMxMjAwMDBaMB0GCCsGAQUFBwkCMREMD0hlcm5k +b24sIFZBLCBVUzApBgkqhkiG9w0BCRQxHB4aAEYAcgBpAGUAbgBkAGwAeQAgAE4A +YQBtAGUwLwYJKoZIhvcNAQkIMSITIDEyMyBVbmtub3duIFdheSwgTm93aGVyZSwg +VkEsIFVTMIGZBgoqhkiG9w0BCRkCMYGKMIGHMAsGCWCGSAFlAwQBLQR4VsJb7t4l +IqjJCT54rqkbCJsBPE17YQJeEYvyA4M1aDIUU5GnCgEhctgMiDPWGMvaSziixdIg +aU/0zvWvYCm8UwPvBBwMtm9X5NDvk9p4nXbGAT8E/OsV1SYWVvwRJwYak0yWWexM +HSixw1Ljh2nb0fIbqwLOeMmIMIIEsQYKKoZIhvcNAQkZBTGCBKEwggSdBgkqhkiG +9w0BBwKgggSOMIIEigIBATENMAsGCWCGSAFlAwQCAjBRBgkqhkiG9w0BBwGgRARC +Q29udGVudC1UeXBlOiB0ZXh0L3BsYWluDQoNCldhdHNvbiwgY29tZSBoZXJlIC0g +SSB3YW50IHRvIHNlZSB5b3UuoIICfDCCAngwggH+oAMCAQICCQCls1QoG7BuOzAK +BggqhkjOPQQDAzA/MQswCQYDVQQGEwJVUzELMAkGA1UECAwCVkExEDAOBgNVBAcM +B0hlcm5kb24xETAPBgNVBAoMCEJvZ3VzIENBMB4XDTE5MDUyOTE0NDU0MVoXDTIw +MDUyODE0NDU0MVowcDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlZBMRAwDgYDVQQH +EwdIZXJuZG9uMRAwDgYDVQQKEwdFeGFtcGxlMQ4wDAYDVQQDEwVBbGljZTEgMB4G +CSqGSIb3DQEJARYRYWxpY2VAZXhhbXBsZS5jb20wdjAQBgcqhkjOPQIBBgUrgQQA +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 +9t33YdzJaFbz+8jb88xtf454Rvur66Cew/4GYX9u1Zef0DF9So1ay3IicpOf5emo +VWIwg4bh7bELi78i/MbdWtNZQcXimykfeTsYH8Q4u+1uxHS5pwEWWwKiUnLQVpZP +2ut255TdgSIhEILwsaLVelRrx/lp14EpY355FOusXiju6g14aWfBnt5udvuTXxDQ +ZHPPNNk+gwzgvvTey98T941hYUctjg0NApJiB66bfrlYB9mkc5ftg5zqhEasYH5C +4ajKKRNMM7zGlwSZvy8PPhnAeE3Q9LTnos0l4ygjQD/kMlvd7XSLW3GUzjyxtkG4 +gQh6LGvnafAbgu7GpcapKEppN86sXEePHiQjj92n103+TxMYWwtaO4iAwkjqdEdt +avEHcXRcpdqC0st6nUwPAPAC4LKJbZgLQnNG+wlWIiCMMD56IdfQ7r/zGIr13MxC +kjNNUdISoWWE5GnQMYHbMBMGCSqGSIb3DQEJFTEGBAQBAAAAMFcGCSqGSIb3DQEJ +FDFKHkgAMwBmADcAMQBhAGYANgA1AC0AMQA2ADgANwAtADQANAA0AGEALQA5AGYA +NAA2AC0AYwA4AGIAZQAxADkANABjADMAZQA4AGUwawYJKwYBBAGCNxEBMV4eXABN +AGkAYwByAG8AcwBvAGYAdAAgAEUAbgBoAGEAbgBjAGUAZAAgAEMAcgB5AHAAdABv +AGcAcgBhAHAAaABpAGMAIABQAHIAbwB2AGkAZABlAHIAIAB2ADEALgAwMIIDaAYJ +KoZIhvcNAQcBoIIDWQSCA1UwggNRMIIDTQYLKoZIhvcNAQwKAQOgggMlMIIDIQYK +KoZIhvcNAQkWAaCCAxEEggMNMIIDCTCCAfGgAwIBAgIQNu32hzqhCKdHATXzboyI +ETANBgkqhkiG9w0BAQUFADAUMRIwEAYDVQQDEwlhbm9ueW1vdXMwIBcNMTYwNzE5 +MjIwMDAxWhgPMjExNjA2MjUyMjAwMDFaMBQxEjAQBgNVBAMTCWFub255bW91czCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALy2sEJMGNdcDg6BI7mdFM5T +lPzo5sKBzvUnagK5SKBJ11xMPN5toPTBzICB/XTWEB3AwpD0O+srSca+bsUAyedS +5V4BNp8qCyEu5RNRR8qPHheJ/guhLT96/gGI4jlrUyUhFntPkLKODxu+7KanMy6K +dD+PVE8shXRUZTYe4PG64/c7z3wapnf4XoCXkJRzCY5f3MKz3Ul039kVnTlJcikd +C7I9I9RflXLwXVl4nxUbeeRt6Z8WVWS4pCq+14v2aVPvP3mtVmAYHedRkvS04Hrx +4xx98D3NSSw6Z5OLkzqOcFw15fYmH2NLdhh34gSWJmaaCBAbuQ+1rx/42p7MvvsC +AwEAAaNVMFMwFQYDVR0lBA4wDAYKKwYBBAGCNwoDBDAvBgNVHREEKDAmoCQGCisG +AQQBgjcUAgOgFgwUYW5vbnltb3VzQHdpbmRvd3MteAAwCQYDVR0TBAIwADANBgkq +hkiG9w0BAQUFAAOCAQEAuH7iqY0/MLozwFb39ILYAJDHE+HToZBQbHQP4YtienrU +Stk60rIp0WH65lam7m/JhgAcItc/tV1L8mEnLrvvKcA+NeIL8sDOtM28azvgcOi0 +P3roeLLLRCuiykUaKmUcZEDm9cDYKIpJf7QetWQ3uuGTk9iRzpH79x2ix35BnyWQ +Rr3INZzmX/+9YRvPBXKYl/89F/w1ORYArpI9XtjfuPWaGQmM4f1WRHE2t3qRyKFF +ri7QiZdpcSx5zvsRHSyjfUMoKs+b6upk+P01lIhg/ewwYngGab+fZhF15pTNN2hx +8PdNGcrGzrkNKCmJKrWCa2xczuMA+z8SCuC1tYTKmDEVMBMGCSqGSIb3DQEJFTEG +BAQBAAAAMDswHzAHBgUrDgMCGgQUpWCP/fZR0TK5BwGuqvTd0+duiKcEFJTubF2k +HktMK+isIjxOTk4yJTOOAgIH0A== +""" + + def setUp(self): + self.asn1Spec = rfc2985.AttributeSet() + + def testDerCodec(self): + substrate = pem.readBase64fromText(self.pem_text) + asn1Object, rest = der_decode(substrate, asn1Spec=self.asn1Spec) + assert not rest + assert asn1Object.prettyPrint() + assert der_encode(asn1Object) == substrate + + openTypesMap = { + rfc2985.pkcs_9_at_smimeCapabilities: rfc2985.SMIMECapabilities(), + } + openTypesMap.update(rfc5280.certificateAttributesMap) + openTypesMap.update(rfc5652.cmsAttributesMap) + + for attr in asn1Object: + assert attr['type'] in openTypesMap.keys() + av, rest = der_decode(attr['values'][0], + asn1Spec=openTypesMap[attr['type']]) + assert not rest + assert av.prettyPrint() + assert der_encode(av) == attr['values'][0] + + if attr['type'] == rfc2985.pkcs_9_at_userPKCS12: + assert av['version'] == univ.Integer(3) + assert av['authSafe']['contentType'] == rfc5652.id_data + outdata, rest = der_decode(av['authSafe']['content'], + asn1Spec=univ.OctetString()) + assert not rest + authsafe, rest = der_decode(outdata, + asn1Spec=rfc7292.AuthenticatedSafe()) + assert not rest + + for ci in authsafe: + assert ci['contentType'] == rfc5652.id_data + indata, rest = der_decode(ci['content'], + asn1Spec=univ.OctetString()) + assert not rest + sc, rest = der_decode(indata, + asn1Spec=rfc7292.SafeContents()) + assert not rest + + for sb in sc: + if sb['bagId'] in rfc7292.pkcs12BagTypeMap: + bv, rest = der_decode(sb['bagValue'], + asn1Spec=rfc7292.pkcs12BagTypeMap[sb['bagId']]) + assert not rest + + for bagattr in sb['bagAttributes']: + if bagattr['attrType'] in openTypesMap: + inav, rest = der_decode(bagattr['attrValues'][0], + asn1Spec=openTypesMap[bagattr['attrType']]) + assert not rest + + if bagattr['attrType'] == rfc2985.pkcs_9_at_friendlyName: + assert inav == "3f71af65-1687-444a-9f46-c8be194c3e8e" + + if bagattr['attrType'] == rfc2985.pkcs_9_at_localKeyId: + assert inav == univ.OctetString(hexValue='01000000') + + if attr['type'] == rfc2985.pkcs_9_at_pkcs7PDU: + ci, rest = der_decode(attr['values'][0], + asn1Spec=rfc5652.ContentInfo()) + assert not rest + assert ci['contentType'] == rfc5652.id_signedData + + sd, rest = der_decode(ci['content'], + asn1Spec=rfc5652.SignedData()) + assert not rest + assert sd['version'] == 1 + + for si in sd['signerInfos']: + assert si['version'] == 1 + + for siattr in si['signedAttrs']: + if siattr['attrType'] in openTypesMap: + siav, rest = der_decode(siattr['attrValues'][0], + asn1Spec=openTypesMap[siattr['attrType']]) + assert not rest + + if siattr['attrType'] == rfc2985.pkcs_9_at_contentType: + assert siav == rfc5652.id_data + + if siattr['attrType'] == rfc2985.pkcs_9_at_messageDigest: + assert siav.prettyPrint()[2:10] == 'b6e422a4' + + if siattr['attrType'] == rfc2985.pkcs_9_at_signingTime: + assert siav['utcTime'] == '190529182319Z' + + for choices in sd['certificates']: + for rdn in choices[0]['tbsCertificate']['subject']['rdnSequence']: + if rdn[0]['type'] in openTypesMap: + nv, rest = der_decode(rdn[0]['value'], + asn1Spec=openTypesMap[rdn[0]['type']]) + assert not rest + + if rdn[0]['type'] == rfc2985.pkcs_9_at_emailAddress: + assert nv == 'alice@example.com' + + def testOpenTypes(self): + openTypesMap = { + rfc2985.pkcs_9_at_smimeCapabilities: rfc2985.SMIMECapabilities(), + } + openTypesMap.update(rfc5280.certificateAttributesMap) + openTypesMap.update(rfc5652.cmsAttributesMap) + + substrate = pem.readBase64fromText(self.pem_text) + asn1Object, rest = der_decode(substrate, + asn1Spec=self.asn1Spec, + openTypes=openTypesMap, + decodeOpenTypes=True) + assert not rest + assert asn1Object.prettyPrint() + assert der_encode(asn1Object) == substrate + + for attr in asn1Object: + assert attr['type'] in openTypesMap.keys() + + if attr['type'] == rfc2985.pkcs_9_at_userPKCS12: + assert attr['values'][0]['version'] == univ.Integer(3) + assert attr['values'][0]['authSafe']['contentType'] == rfc5652.id_data + authsafe, rest = der_decode(attr['values'][0]['authSafe']['content'], + asn1Spec=rfc7292.AuthenticatedSafe()) + assert not rest + + for ci in authsafe: + assert ci['contentType'] == rfc5652.id_data + indata, rest = der_decode(ci['content'], + asn1Spec=univ.OctetString()) + assert not rest + + sc, rest = der_decode(indata, + asn1Spec=rfc7292.SafeContents(), + decodeOpenTypes=True) + assert not rest + + for sb in sc: + if sb['bagId'] in rfc7292.pkcs12BagTypeMap: + for bagattr in sb['bagAttributes']: + if bagattr['attrType'] in openTypesMap: + + if bagattr['attrType'] == rfc2985.pkcs_9_at_friendlyName: + assert bagattr['attrValues'][0] == "3f71af65-1687-444a-9f46-c8be194c3e8e" + + if bagattr['attrType'] == rfc2985.pkcs_9_at_localKeyId: + assert bagattr['attrValues'][0] == univ.OctetString(hexValue='01000000') + + if attr['type'] == rfc2985.pkcs_9_at_pkcs7PDU: + assert attr['values'][0]['contentType'] == rfc5652.id_signedData + assert attr['values'][0]['content']['version'] == 1 + + for si in attr['values'][0]['content']['signerInfos']: + assert si['version'] == 1 + + for siattr in si['signedAttrs']: + if siattr['attrType'] in openTypesMap: + + if siattr['attrType'] == rfc2985.pkcs_9_at_contentType: + assert siattr['attrValues'][0] == rfc5652.id_data + + if siattr['attrType'] == rfc2985.pkcs_9_at_messageDigest: + assert siattr['attrValues'][0].prettyPrint()[2:10] == 'b6e422a4' + + if siattr['attrType'] == rfc2985.pkcs_9_at_signingTime: + assert siattr['attrValues'][0]['utcTime'] == '190529182319Z' + + for choices in attr['values'][0]['content']['certificates']: + for rdn in choices[0]['tbsCertificate']['subject']['rdnSequence']: + if rdn[0]['type'] in openTypesMap: + if rdn[0]['type'] == rfc2985.pkcs_9_at_emailAddress: + assert rdn[0]['value'] == 'alice@example.com' + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite) |