diff options
author | Russ Housley <housley@vigilsec.com> | 2019-05-31 13:53:36 -0400 |
---|---|---|
committer | Ilya Etingof <etingof@gmail.com> | 2019-05-31 19:53:36 +0200 |
commit | 6a63d407e4b9db75aef551e6cfc69110b3b6a246 (patch) | |
tree | bf45450f7e7b745154c3b7bd8486167f75c820d7 | |
parent | 61b5149d1b1e50a212f64846ffc90a9222f51a83 (diff) | |
download | pyasn1-modules-6a63d407e4b9db75aef551e6cfc69110b3b6a246.tar.gz |
Add support for RFC 5940 (#41)
-rw-r--r-- | CHANGES.txt | 1 | ||||
-rw-r--r-- | pyasn1_modules/rfc5940.py | 46 | ||||
-rw-r--r-- | tests/__main__.py | 1 | ||||
-rw-r--r-- | tests/test_rfc5940.py | 98 |
4 files changed, 146 insertions, 0 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index 1b4652d..6a8526c 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -17,6 +17,7 @@ Revision 0.2.6, released XX-05-2019 - Added RFC4073 providing Multiple Contents protection with CMS - Added RFC2634 providing Enhanced Security Services for S/MIME - Added RFC5915 providing Elliptic Curve Private Key +- Added RFC5940 providing CMS Revocation Information Choices Revision 0.2.5, released 24-04-2019 ----------------------------------- diff --git a/pyasn1_modules/rfc5940.py b/pyasn1_modules/rfc5940.py new file mode 100644 index 0000000..1998e26 --- /dev/null +++ b/pyasn1_modules/rfc5940.py @@ -0,0 +1,46 @@ +# +# This file is part of pyasn1-modules software. +# +# Created by Russ Housley with assistance from asn1ate v.0.6.0. +# +# Copyright (c) 2019, Vigil Security, LLC +# License: http://snmplabs.com/pyasn1/license.html +# +# Additional CMS Revocation Information Choices +# +# ASN.1 source from: +# https://www.rfc-editor.org/rfc/rfc5940.txt +# + +from pyasn1.type import namedtype +from pyasn1.type import tag +from pyasn1.type import univ + +from pyasn1_modules import rfc2560 +from pyasn1_modules import rfc5652 + + +# RevocationInfoChoice for OCSP response: +# The OID is included in otherRevInfoFormat, and +# signed OCSPResponse is included in otherRevInfo + +id_ri_ocsp_response = univ.ObjectIdentifier('1.3.6.1.5.5.7.16.2') + +OCSPResponse = rfc2560.OCSPResponse + + +# RevocationInfoChoice for SCVP request/response: +# The OID is included in otherRevInfoFormat, and +# SCVPReqRes is included in otherRevInfo + +id_ri_scvp = univ.ObjectIdentifier('1.3.6.1.5.5.7.16.4') + +ContentInfo = rfc5652.ContentInfo + +class SCVPReqRes(univ.Sequence): + pass + +SCVPReqRes.componentType = namedtype.NamedTypes( + namedtype.OptionalNamedType('request', ContentInfo().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), + namedtype.NamedType('response', ContentInfo()) +) diff --git a/tests/__main__.py b/tests/__main__.py index a76ce57..f337377 100644 --- a/tests/__main__.py +++ b/tests/__main__.py @@ -37,6 +37,7 @@ suite = unittest.TestLoader().loadTestsFromNames( 'tests.test_rfc5649.suite', 'tests.test_rfc5652.suite', 'tests.test_rfc5915.suite', + 'tests.test_rfc5940.suite', 'tests.test_rfc5958.suite', 'tests.test_rfc6019.suite', 'tests.test_rfc8103.suite', diff --git a/tests/test_rfc5940.py b/tests/test_rfc5940.py new file mode 100644 index 0000000..f95be05 --- /dev/null +++ b/tests/test_rfc5940.py @@ -0,0 +1,98 @@ +# +# This file is part of pyasn1-modules software. +# +# 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 rfc2560 +from pyasn1_modules import rfc5940 +from pyasn1_modules import rfc5652 +from pyasn1_modules import rfc5280 + +try: + import unittest2 as unittest +except ImportError: + import unittest + + +class CRLandOCSPResponseTestCase(unittest.TestCase): + pem_text = """\ +MIIHWQYJKoZIhvcNAQcCoIIHSjCCB0YCAQExDTALBglghkgBZQMEAgEwUwYJKoZI +hvcNAQcBoEYERENvbnRlbnQtVHlwZTogdGV4dC9wbGFpbg0KDQpXYXRzb24sIGNv +bWUgaGVyZSAtIEkgd2FudCB0byBzZWUgeW91Lg0KoIIBaDCCAWQwggEKoAMCAQIC +CQClWUKCJkwnGTAKBggqhkjOPQQDAjAkMRQwEgYDVQQKDAtleGFtcGxlLm9yZzEM +MAoGA1UEAwwDQm9iMB4XDTE3MTIyMDIzMDc0OVoXDTE4MTIyMDIzMDc0OVowJDEU +MBIGA1UECgwLZXhhbXBsZS5vcmcxDDAKBgNVBAMMA0JvYjBZMBMGByqGSM49AgEG +CCqGSM49AwEHA0IABIZP//xT8ah2ymmxfidIegeccVKuGxN+OTuvGq69EnQ8fUFD +ov2KNw8Cup0DtzAfHaZOMFWUu2+Vy3H6SLbQo4OjJTAjMCEGA1UdEQEB/wQXMBWG +E3NpcDpib2JAZXhhbXBsZS5vcmcwCgYIKoZIzj0EAwIDSAAwRQIhALIkjJJAKCI4 +nsklf2TM/RBvuguWwRkHMDTVGxAvczlsAiAVjrFR8IW5vS4EzyePDVIua7b+Tzb3 +THcQsVpPR53kDaGCBGQwggIbMIIBAwIBATANBgkqhkiG9w0BAQsFADBsMQswCQYD +VQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGln +aWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBS +b290IENBFw0xOTA1MDIyMjE1NTRaFw0xOTA1MjMyMjE1NTRaMDEwLwIQDPWCOBgZ +nlb4K9ZS7Sft6RcNMTgxMDI1MTYxMTM4WjAMMAoGA1UdFQQDCgEAoDAwLjAfBgNV +HSMEGDAWgBSxPsNpA/i/RwHUmCYaCALvY2QrwzALBgNVHRQEBAICAcQwDQYJKoZI +hvcNAQELBQADggEBABPO3OA0OkQZ+RLVxz/cNx5uNVEO416oOePkN0A4DxFztf33 +7caS4OyfS9Wyu1j5yUdWJVpAKXSQeN95MqHkpSpYDssuqbuYjv8ViJfseGBgtXTc +zUzzNeNdY2uxMbCxuhmPkgacAo1lx9LkK2ScYHWVbfFRF1UQ/dcmavaZsEOBNuLW +OxQYA9MqfVNAymHe7vPqwm/8IY2FbHe9HsiJZfGxNWMDP5lmJiXmpntTeDQ2Ujdi +yXwGGKjyiSTFk2jVRutrGINufaoA/f7eCmIb4UDPbpMjVfD215dW8eBKouypCVoE +vmCSSTacdiBI2yOluvMN0PzvPve0ECAE+D4em9ahggJBBggrBgEFBQcQAjCCAjMK +AQCgggIsMIICKAYJKwYBBQUHMAEBBIICGTCCAhUwZqEgMB4xHDAJBgNVBAYTAlJV +MA8GA1UEAx4IAFQAZQBzAHQYEzIwMTkwNTA5MTU1MDQ4LjI1OVowLTArMBIwBwYF +Kw4DAhoEAQEEAQECAQGAABgTMjAxOTA1MDkxNTUwNDguMjYxWjAKBggqhkjOPQQD +AgNJADBGAiEAujFVH+NvuTLYa8RW3pvWSUwZfjOW5H5171JI+/50BjcCIQDhwige +wl+ts6TIvhU+CFoOipQBNKyKXKh7ngJkUtpZ86CCAVIwggFOMIIBSjCB8aADAgEC +AgEBMAoGCCqGSM49BAMCMB4xHDAJBgNVBAYTAlJVMA8GA1UEAx4IAFQAZQBzAHQw +HhcNMTkwMjAxMDUwMDAwWhcNMjIwMjAxMDUwMDAwWjAeMRwwCQYDVQQGEwJSVTAP +BgNVBAMeCABUAGUAcwB0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEM0jxEYgg +RxC/r87uV/h6iZ8BAdHT/6fxRuzG0PRMIlFBy38skFUXJJulKV9JW16YJqOkVsqv +xwMM61z7p1vQ/qMgMB4wDwYDVR0TBAgwBgEB/wIBAzALBgNVHQ8EBAMCAAYwCgYI +KoZIzj0EAwIDSAAwRQIhAIdpCt5g89ofSADXmBD3KXQGnTghwbAMeWrKXqTGww+x +AiAl8NQgfUk4xMymZ3VtCLJ2MdczDps4Zh2KPOqAR5fZAjGCAQcwggEDAgEBMDEw +JDEUMBIGA1UECgwLZXhhbXBsZS5vcmcxDDAKBgNVBAMMA0JvYgIJAKVZQoImTCcZ +MAsGCWCGSAFlAwQCAaBpMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZI +hvcNAQkFMQ8XDTE5MDEyNDIzNTI1NlowLwYJKoZIhvcNAQkEMSIEIO93j8lA1ebc +JXb0elmbMSYZWp8aInra81+iLAUNjRlaMAoGCCqGSM49BAMCBEcwRQIhAPeI7URq +tw//LB/6TAN0/Qh3/WHukXwxRbOJpnYVx0b6AiB3lK3FfwBhx4S5YSPMblS7goJl +ttTMEpl2prH8bbwo1g== +""" + + def setUp(self): + self.asn1Spec = rfc5652.ContentInfo() + + 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 + + assert asn1Object['contentType'] == rfc5652.id_signedData + inner, rest = der_decode(asn1Object['content'], asn1Spec=rfc5652.SignedData()) + assert inner.prettyPrint() + + assert inner['encapContentInfo']['eContentType'] == rfc5652.id_data + assert inner['encapContentInfo']['eContent'] + assert inner['crls'][0]['crl']['tbsCertList']['version'] == rfc5280.Version(value='v2') + assert inner['crls'][1]['other']['otherRevInfoFormat'] == rfc5940.id_ri_ocsp_response + + ocspr, rest = der_decode(inner['crls'][1]['other']['otherRevInfo'], asn1Spec=rfc5940.OCSPResponse()) + assert ocspr.prettyPrint() + assert ocspr['responseStatus'] == rfc2560.OCSPResponseStatus(value='successful') + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite) |