diff options
author | Ilya Etingof <etingof@gmail.com> | 2019-04-11 23:26:24 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-04-11 23:26:24 +0200 |
commit | a8945ec770b317a58ccb066cbef98c206011a1ab (patch) | |
tree | 21dc6fe041ae6fe27c7459320c217c1db15ab94a | |
parent | fa76703d4652ce0554e23f30e9061dda0093a630 (diff) | |
download | pyasn1-modules-a8945ec770b317a58ccb066cbef98c206011a1ab.tar.gz |
Add RFC3779 (#24)
-rw-r--r-- | pyasn1_modules/rfc3779.py | 112 | ||||
-rw-r--r-- | tests/__main__.py | 1 | ||||
-rw-r--r-- | tests/test_rfc3779.py | 81 |
3 files changed, 194 insertions, 0 deletions
diff --git a/pyasn1_modules/rfc3779.py b/pyasn1_modules/rfc3779.py new file mode 100644 index 0000000..aaf856e --- /dev/null +++ b/pyasn1_modules/rfc3779.py @@ -0,0 +1,112 @@ +# +# 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 +# +# X.509 Extensions for IP Addresses and AS Identifiers +# +# ASN.1 source from: +# https://www.rfc-editor.org/rfc/rfc3779.txt +# + + +from pyasn1.type import univ, char, namedtype, namedval, tag, constraint, useful + + +# IP Address Delegation Extension + +id_pe_ipAddrBlocks = univ.ObjectIdentifier('1.3.6.1.5.5.7.1.7') + + +class IPAddress(univ.BitString): + pass + + +class IPAddressRange(univ.Sequence): + pass + +IPAddressRange.componentType = namedtype.NamedTypes( + namedtype.NamedType('min', IPAddress()), + namedtype.NamedType('max', IPAddress()) +) + + +class IPAddressOrRange(univ.Choice): + pass + +IPAddressOrRange.componentType = namedtype.NamedTypes( + namedtype.NamedType('addressPrefix', IPAddress()), + namedtype.NamedType('addressRange', IPAddressRange()) +) + + +class IPAddressChoice(univ.Choice): + pass + +IPAddressChoice.componentType = namedtype.NamedTypes( + namedtype.NamedType('inherit', univ.Null()), + namedtype.NamedType('addressesOrRanges', univ.SequenceOf(componentType=IPAddressOrRange())) +) + + +class IPAddressFamily(univ.Sequence): + pass + +IPAddressFamily.componentType = namedtype.NamedTypes( + namedtype.NamedType('addressFamily', univ.OctetString().subtype(subtypeSpec=constraint.ValueSizeConstraint(2, 3))), + namedtype.NamedType('ipAddressChoice', IPAddressChoice()) +) + + +class IPAddrBlocks(univ.SequenceOf): + pass + +IPAddrBlocks.componentType = IPAddressFamily() + + +# Autonomous System Identifier Delegation Extension + +id_pe_autonomousSysIds = univ.ObjectIdentifier('1.3.6.1.5.5.7.1.8') + + +class ASId(univ.Integer): + pass + + +class ASRange(univ.Sequence): + pass + +ASRange.componentType = namedtype.NamedTypes( + namedtype.NamedType('min', ASId()), + namedtype.NamedType('max', ASId()) +) + + +class ASIdOrRange(univ.Choice): + pass + +ASIdOrRange.componentType = namedtype.NamedTypes( + namedtype.NamedType('id', ASId()), + namedtype.NamedType('range', ASRange()) +) + + +class ASIdentifierChoice(univ.Choice): + pass + +ASIdentifierChoice.componentType = namedtype.NamedTypes( + namedtype.NamedType('inherit', univ.Null()), + namedtype.NamedType('asIdsOrRanges', univ.SequenceOf(componentType=ASIdOrRange())) +) + + +class ASIdentifiers(univ.Sequence): + pass + +ASIdentifiers.componentType = namedtype.NamedTypes( + namedtype.OptionalNamedType('asnum', ASIdentifierChoice().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), + namedtype.OptionalNamedType('rdi', ASIdentifierChoice().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1))) +) diff --git a/tests/__main__.py b/tests/__main__.py index a276637..861c530 100644 --- a/tests/__main__.py +++ b/tests/__main__.py @@ -18,6 +18,7 @@ suite = unittest.TestLoader().loadTestsFromNames( 'tests.test_rfc2511.suite', 'tests.test_rfc2560.suite', 'tests.test_rfc2986.suite', + 'tests.test_rfc3779.suite', 'tests.test_rfc4210.suite', 'tests.test_rfc5208.suite', 'tests.test_rfc5280.suite', diff --git a/tests/test_rfc3779.py b/tests/test_rfc3779.py new file mode 100644 index 0000000..bebe06c --- /dev/null +++ b/tests/test_rfc3779.py @@ -0,0 +1,81 @@ +# +# 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 import decoder as der_decoder +from pyasn1.codec.der import encoder as der_encoder + +from pyasn1_modules import pem +from pyasn1_modules import rfc5280 +from pyasn1_modules import rfc3779 + +try: + import unittest2 as unittest +except ImportError: + import unittest + + +class CertificateExtnTestCase(unittest.TestCase): + pem_text = """\ +MIIECjCCAvKgAwIBAgICAMkwDQYJKoZIhvcNAQELBQAwFjEUMBIGA1UEAxMLcmlw +ZS1uY2MtdGEwIBcNMTcxMTI4MTQzOTU1WhgPMjExNzExMjgxNDM5NTVaMBYxFDAS +BgNVBAMTC3JpcGUtbmNjLXRhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEA0URYSGqUz2myBsOzeW1jQ6NsxNvlLMyhWknvnl8NiBCs/T/S2XuNKQNZ+wBZ +xIgPPV2pFBFeQAvoH/WK83HwA26V2siwm/MY2nKZ+Olw+wlpzlZ1p3Ipj2eNcKrm +it8BwBC8xImzuCGaV0jkRB0GZ0hoH6Ml03umLprRsn6v0xOP0+l6Qc1ZHMFVFb38 +5IQ7FQQTcVIxrdeMsoyJq9eMkE6DoclHhF/NlSllXubASQ9KUWqJ0+Ot3QCXr4LX +ECMfkpkVR2TZT+v5v658bHVs6ZxRD1b6Uk1uQKAyHUbn/tXvP8lrjAibGzVsXDT2 +L0x4Edx+QdixPgOji3gBMyL2VwIDAQABo4IBXjCCAVowHQYDVR0OBBYEFOhVKx/W +0aT35ATG2OVoDR68Fj/DMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEG +MIGxBggrBgEFBQcBCwSBpDCBoTA8BggrBgEFBQcwCoYwcnN5bmM6Ly9ycGtpLnJp +cGUubmV0L3JlcG9zaXRvcnkvcmlwZS1uY2MtdGEubWZ0MDIGCCsGAQUFBzANhiZo +dHRwczovL3JyZHAucmlwZS5uZXQvbm90aWZpY2F0aW9uLnhtbDAtBggrBgEFBQcw +BYYhcnN5bmM6Ly9ycGtpLnJpcGUubmV0L3JlcG9zaXRvcnkvMBgGA1UdIAEB/wQO +MAwwCgYIKwYBBQUHDgIwJwYIKwYBBQUHAQcBAf8EGDAWMAkEAgABMAMDAQAwCQQC +AAIwAwMBADAhBggrBgEFBQcBCAEB/wQSMBCgDjAMMAoCAQACBQD/////MA0GCSqG +SIb3DQEBCwUAA4IBAQAVgJjrZ3wFppC8Yk8D2xgzwSeWVT2vtYq96CQQsjaKb8nb +eVz3DwcS3a7RIsevrNVGo43k3AGymg1ki+AWJjvHvJ+tSzCbn5+X6Z7AfYTf2g37 +xINVDHru0PTQUargSMBAz/MBNpFG8KThtT7WbJrK4+f/lvx0m8QOlYm2a17iXS3A +GQJ6RHcq9ADscqGdumxmMMDjwED26bGaYdmru1hNIpwF//jVM/eRjBFoPHKFlx0k +Ld/yoCQNmx1kW+xANx4uyWxi/DYgSV7Oynq+C60OucW+d8tIhkblh8+YfrmukJds +V+vo2L72yerdbsP9xjqvhZrLKfsLZjYK4SdYYthi +""" + + def setUp(self): + self.asn1Spec = rfc5280.Certificate() + + def testDerCodec(self): + + substrate = pem.readBase64fromText(self.pem_text) + + asn1Object, rest = der_decoder.decode(substrate, asn1Spec=self.asn1Spec) + + assert not rest + assert asn1Object.prettyPrint() + assert der_encoder.encode(asn1Object) == substrate + + for extn in asn1Object['tbsCertificate']['extensions']: + + if extn['extnID'] == rfc3779.id_pe_ipAddrBlocks: + s = extn['extnValue'] + addr_blocks, rest = der_decoder.decode(s, rfc3779.IPAddrBlocks()) + assert not rest + assert addr_blocks.prettyPrint() + assert der_encoder.encode(addr_blocks) == s + + if extn['extnID'] == rfc3779.id_pe_autonomousSysIds: + s = extn['extnValue'] + as_ids, rest = der_decoder.decode(s, rfc3779.ASIdentifiers()) + assert not rest + assert as_ids.prettyPrint() + assert der_encoder.encode(as_ids) == s + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite) |