From 7fafbf8550ab9e8727274903ed96ae849cd24594 Mon Sep 17 00:00:00 2001 From: Russ Housley Date: Tue, 15 Oct 2019 10:54:03 -0400 Subject: Add tests for RFC 3852 and RFC 4211 (#83) --- CHANGES.txt | 2 +- tests/__main__.py | 2 + tests/test_rfc3852.py | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++ tests/test_rfc4211.py | 61 +++++++++++++++++++++++ 4 files changed, 195 insertions(+), 1 deletion(-) create mode 100644 tests/test_rfc3852.py create mode 100644 tests/test_rfc4211.py diff --git a/CHANGES.txt b/CHANGES.txt index 60267b8..346e2c8 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -5,7 +5,7 @@ Revision 0.2.8, released XX-XX-2019 - Improve test routines for modules that use certificate extensions - Added RFC7633 providing TLS Features Certificate Extension - Added RFC7229 providing OIDs for Test Certificate Policies -- Added test for RFC3280 and RFC3281 +- Added tests for RFC3280, RFC3281, RFC3852, and RFC4211 Revision 0.2.7, released 09-10-2019 ----------------------------------- diff --git a/tests/__main__.py b/tests/__main__.py index f892330..6c004b5 100644 --- a/tests/__main__.py +++ b/tests/__main__.py @@ -31,10 +31,12 @@ suite = unittest.TestLoader().loadTestsFromNames( 'tests.test_rfc3709.suite', 'tests.test_rfc3770.suite', 'tests.test_rfc3779.suite', + 'tests.test_rfc3852.suite', 'tests.test_rfc4055.suite', 'tests.test_rfc4073.suite', 'tests.test_rfc4108.suite', 'tests.test_rfc4210.suite', + 'tests.test_rfc4211.suite', 'tests.test_rfc5035.suite', 'tests.test_rfc5083.suite', 'tests.test_rfc5084.suite', diff --git a/tests/test_rfc3852.py b/tests/test_rfc3852.py new file mode 100644 index 0000000..94a618c --- /dev/null +++ b/tests/test_rfc3852.py @@ -0,0 +1,131 @@ +# +# 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 rfc3852 +from pyasn1_modules import rfc6402 + +try: + import unittest2 as unittest + +except ImportError: + import unittest + + +class ContentInfoTestCase(unittest.TestCase): + pem_text = """\ +MIIEJQYJKoZIhvcNAQcCoIIEFjCCBBICAQMxCzAJBgUrDgMCGgUAMIIDAgYIKwYBBQUHDAKgggL0 +BIIC8DCCAuwweDB2AgECBgorBgEEAYI3CgoBMWUwYwIBADADAgEBMVkwVwYJKwYBBAGCNxUUMUow +SAIBBQwZcGl0dWNoYTEuZW1lYS5ocHFjb3JwLm5ldAwMRU1FQVxwaXR1Y2hhDBpDTUNSZXFHZW5l +cmF0b3IudnNob3N0LmV4ZTCCAmqgggJmAgEBMIICXzCCAcgCAQAwADCBnzANBgkqhkiG9w0BAQEF +AAOBjQAwgYkCgYEA0jm7SSSm2wyEAzuNKtFZFJKo91SrJq9wQwEhEKHDavZwMQOm1rZ2PF8NWCEb +PqrhToQ7rtiGLSZa4dF4bzgmBqQ9aoSfEX4jISt31Vy+skHidXjHHpbsjT24NPhrZgANivL7CxD6 +Ft+s7qS1gL4HRm2twQkqSwOLrE/q2QeXl2UCAwEAAaCCAR0wGgYKKwYBBAGCNw0CAzEMFgo2LjIu +OTIwMC4yMD4GCSqGSIb3DQEJDjExMC8wHQYDVR0OBBYEFMW2skn88gxhONWZQA4sWGBDb68yMA4G +A1UdDwEB/wQEAwIHgDBXBgkrBgEEAYI3FRQxSjBIAgEFDBlwaXR1Y2hhMS5lbWVhLmhwcWNvcnAu +bmV0DAxFTUVBXHBpdHVjaGEMGkNNQ1JlcUdlbmVyYXRvci52c2hvc3QuZXhlMGYGCisGAQQBgjcN +AgIxWDBWAgECHk4ATQBpAGMAcgBvAHMAbwBmAHQAIABTAHQAcgBvAG4AZwAgAEMAcgB5AHAAdABv +AGcAcgBhAHAAaABpAGMAIABQAHIAbwB2AGkAZABlAHIDAQAwDQYJKoZIhvcNAQEFBQADgYEAJZlu +mxjtCxSOQi27jsVdd3y8NSIlzNv0b3LqmzvAly6L+CstXcnuG2MPQqPH9R7tbJonGUniBQO9sQ7C +KhYWj2gfhiEkSID82lV5chINVUFKoUlSiEhWr0tPGgvOaqdsKQcrHfzrsBbFkhDqrFSVy7Yivbnh +qYszKrOjJKiiCPMwADAAMYH5MIH2AgEDgBTFtrJJ/PIMYTjVmUAOLFhgQ2+vMjAJBgUrDgMCGgUA +oD4wFwYJKoZIhvcNAQkDMQoGCCsGAQUFBwwCMCMGCSqGSIb3DQEJBDEWBBTFTkK/OifaFjwqHiJu +xM7qXcg/VzANBgkqhkiG9w0BAQEFAASBgKfC6jOi1Wgy4xxDCQVK9+e5tktL8wE/j2cb9JSqq+aU +5UxEgXEw7q7BoYZCAzcxMRriGzakXr8aXHcgkRJ7XcFvLPUjpmGg9SOZ2sGW4zQdWAwImN/i8loc +xicQmJP+VoMHo/ZpjFY9fYCjNZUArgKsEwK/s+p9yrVVeB1Nf8Mn +""" + + def setUp(self): + self.asn1Spec = rfc3852.ContentInfo() + + def testDerCodec(self): + substrate = pem.readBase64fromText(self.pem_text) + + layers = { + rfc3852.id_ct_contentInfo: rfc3852.ContentInfo(), + rfc3852.id_signedData: rfc3852.SignedData(), + rfc6402.id_cct_PKIData: rfc6402.PKIData() + } + + getNextLayer = { + rfc3852.id_ct_contentInfo: lambda x: x['contentType'], + rfc3852.id_signedData: lambda x: x['encapContentInfo']['eContentType'], + rfc6402.id_cct_PKIData: lambda x: None + } + + getNextSubstrate = { + rfc3852.id_ct_contentInfo: lambda x: x['content'], + rfc3852.id_signedData: lambda x: x['encapContentInfo']['eContent'], + rfc6402.id_cct_PKIData: lambda x: None + } + + alg_oids = ( + univ.ObjectIdentifier('1.3.14.3.2.26'), + univ.ObjectIdentifier('1.2.840.113549.1.1.1'), + univ.ObjectIdentifier('1.2.840.113549.1.1.5'), + univ.ObjectIdentifier('1.2.840.113549.1.1.11'), + ) + + encoded_null = der_encode(univ.Null("")) + + next_layer = rfc3852.id_ct_contentInfo + + count = 0 + while next_layer: + asn1Object, rest = der_decode(substrate, asn1Spec=layers[next_layer]) + assert not rest + assert asn1Object.prettyPrint() + assert der_encode(asn1Object) == substrate + + if next_layer == rfc3852.id_signedData: + for d in asn1Object['digestAlgorithms']: + assert d['algorithm'] in alg_oids + assert d['parameters'] == encoded_null + count += 1 + + for si in asn1Object['signerInfos']: + assert si['digestAlgorithm']['algorithm'] in alg_oids + assert si['digestAlgorithm']['parameters'] == encoded_null + count += 1 + + assert si['signatureAlgorithm']['algorithm'] in alg_oids + assert si['signatureAlgorithm']['parameters'] == encoded_null + count += 1 + + if next_layer == rfc6402.id_cct_PKIData: + for req in asn1Object['reqSequence']: + cr = req['tcr']['certificationRequest'] + assert cr['signatureAlgorithm']['algorithm'] in alg_oids + assert cr['signatureAlgorithm']['parameters'] == encoded_null + count += 1 + + cri_spki = cr['certificationRequestInfo']['subjectPublicKeyInfo'] + assert cri_spki['algorithm']['algorithm'] in alg_oids + assert cri_spki['algorithm']['parameters'] == encoded_null + count += 1 + + substrate = getNextSubstrate[next_layer](asn1Object) + next_layer = getNextLayer[next_layer](asn1Object) + + assert count == 5 + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) diff --git a/tests/test_rfc4211.py b/tests/test_rfc4211.py new file mode 100644 index 0000000..f96cdcf --- /dev/null +++ b/tests/test_rfc4211.py @@ -0,0 +1,61 @@ +# +# 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_modules import pem +from pyasn1_modules import rfc4211 + +try: + import unittest2 as unittest + +except ImportError: + import unittest + + +class CertificateReqTestCase(unittest.TestCase): + pem_text = """\ +MIIBozCCAZ8wggEFAgUAwTnj2jCByoABAqURMA8xDTALBgNVBAMTBHVzZXKmgZ8w +DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJ6ZQ2cYbn/lFsmBOlRltbRbFQUvvE0Q +nbopOu1kC7Bmaaz7QTx8nxeiHi4m7uxCbGGxHNoGCt7EmdG8eZUBNAcHyGlXrJdm +0z3/uNEGiBHq+xB8FnFJCA5EIJ3RWFnlbu9otSITLxWK7c5+/NHmWM+yaeHD/f/h +rp01c/8qXZfZAgMBAAGpEDAOBgNVHQ8BAf8EBAMCBeAwLzASBgkrBgEFBQcFAQEM +BTExMTExMBkGCSsGAQUFBwUBAgwMc2VydmVyX21hZ2ljoYGTMA0GCSqGSIb3DQEB +BQUAA4GBAEI3KNEvTq/n1kNVhNhPkovk1AZxyJrN1u1+7Gkc4PLjWwjLOjcEVWt4 +AajUk/gkIJ6bbeO+fZlMjHfPSDKcD6AV2hN+n72QZwfzcw3icNvBG1el9EU4XfIm +xfu5YVWi81/fw8QQ6X6YGHFQkomLd7jxakVyjxSng9BhO6GpjJNF +""" + + def setUp(self): + self.asn1Spec = rfc4211.CertReqMessages() + + 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 + + count = 0 + for crm in asn1Object: + assert crm['certReq']['certTemplate']['version'] == 2 + count += 1 + + assert count == 1 + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + import sys + + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) -- cgit v1.2.3