aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Housley <housley@vigilsec.com>2019-11-03 16:43:39 -0500
committerIlya Etingof <etingof@gmail.com>2019-11-03 22:43:39 +0100
commita99e2ecd831fbbea1f2869b68d708fb5ddf60fd7 (patch)
tree193cf3ac4a94e75cf7d93baa83db92020a70774f
parent2e6acd120f89a18945b5ae49c9710f9cc90c1bda (diff)
downloadpyasn1-modules-a99e2ecd831fbbea1f2869b68d708fb5ddf60fd7.tar.gz
Add support for RFC 5916 (#98)
-rw-r--r--CHANGES.txt1
-rw-r--r--pyasn1_modules/rfc5916.py35
-rw-r--r--tests/__main__.py1
-rw-r--r--tests/test_rfc5916.py110
4 files changed, 147 insertions, 0 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index c898fa5..9b38f43 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -23,6 +23,7 @@ Revision 0.2.8, released XX-XX-2019
service names in certificates
- Added RFC5924 providing Extended Key Usage for Session Initiation
Protocol (SIP) in X.509 certificates
+- Added RFC5916 providing Device Owner Attribute
Revision 0.2.7, released 09-10-2019
-----------------------------------
diff --git a/pyasn1_modules/rfc5916.py b/pyasn1_modules/rfc5916.py
new file mode 100644
index 0000000..ac23c86
--- /dev/null
+++ b/pyasn1_modules/rfc5916.py
@@ -0,0 +1,35 @@
+#
+# 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
+#
+# Device Owner Attribute
+#
+# ASN.1 source from:
+# https://www.rfc-editor.org/rfc/rfc5916.txt
+#
+
+from pyasn1.type import univ
+
+from pyasn1_modules import rfc5280
+
+
+# Device Owner Attribute
+
+id_deviceOwner = univ.ObjectIdentifier((2, 16, 840, 1, 101, 2, 1, 5, 69))
+
+at_deviceOwner = rfc5280.Attribute()
+at_deviceOwner['type'] = id_deviceOwner
+at_deviceOwner['values'][0] = univ.ObjectIdentifier()
+
+
+# Add to the map of Attribute Type OIDs to Attributes in rfc5280.py.
+
+_certificateAttributesMapUpdate = {
+ id_deviceOwner: univ.ObjectIdentifier(),
+}
+
+rfc5280.certificateAttributesMap.update(_certificateAttributesMapUpdate)
diff --git a/tests/__main__.py b/tests/__main__.py
index 2d0337c..9b75c65 100644
--- a/tests/__main__.py
+++ b/tests/__main__.py
@@ -50,6 +50,7 @@ suite = unittest.TestLoader().loadTestsFromNames(
'tests.test_rfc5751.suite',
'tests.test_rfc5914.suite',
'tests.test_rfc5915.suite',
+ 'tests.test_rfc5916.suite',
'tests.test_rfc5924.suite',
'tests.test_rfc5934.suite',
'tests.test_rfc5940.suite',
diff --git a/tests/test_rfc5916.py b/tests/test_rfc5916.py
new file mode 100644
index 0000000..2e7ba7f
--- /dev/null
+++ b/tests/test_rfc5916.py
@@ -0,0 +1,110 @@
+#
+# 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 rfc5280
+from pyasn1_modules import rfc5916
+
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
+
+
+class DeviceCertTestCase(unittest.TestCase):
+ cert_pem_text = """\
+MIICpzCCAiygAwIBAgIJAKWzVCgbsG5FMAoGCCqGSM49BAMDMD8xCzAJBgNVBAYT
+AlVTMQswCQYDVQQIDAJWQTEQMA4GA1UEBwwHSGVybmRvbjERMA8GA1UECgwIQm9n
+dXMgQ0EwHhcNMTkxMDMxMTQwMDE1WhcNMjAxMDMwMTQwMDE1WjB4MQswCQYDVQQG
+EwJVUzELMAkGA1UECBMCVkExEDAOBgNVBAcTB0hlcm5kb24xEDAOBgNVBAoTB0V4
+YW1wbGUxGjAYBgNVBAsTEURldmljZSBPcGVyYXRpb25zMRwwGgYDVQQDExNleDEy
+MzQ1LmV4YW1wbGUuY29tMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE7Lje3glS2qYl
+5x6N9TOlD4CbnzfFeJQfbDaCa3vexEiwE0apuAP+4L5fqOsYeZC970iNW+z3PdUs
+GzkKDC2cCVy8nIxQ3mWhNQDvavT3iz5OGSwa1GjSXRFbGn2x9QjNo4G6MIG3MEIG
+CWCGSAGG+EIBDQQ1FjNUaGlzIGNlcnRpZmljYXRlIGNhbm5vdCBiZSB0cnVzdGVk
+IGZvciBhbnkgcHVycG9zZS4wHQYDVR0OBBYEFPTQN1kXEM5Rd4hNvQL5HyA+o2No
+MB8GA1UdIwQYMBaAFPI12zQE2qVV8r1pA5mwYuziFQjBMAsGA1UdDwQEAwIHgDAk
+BgNVHQkEHTAbMBkGCWCGSAFlAgEFRTEMBgorBgEEAYGsYDAYMAoGCCqGSM49BAMD
+A2kAMGYCMQCt6AceOEIwXFKFHIV8+wTK/vgs7ZYSA6jhXUpzNtzZw1xh9NxVUhmx
+pogu5Q9Vp28CMQC5YVF8dShC1tk9YImRftiVl8C6pbj//1K/+MwmR6nRk/WU+hKl
++Qsc5Goi6At471s=
+"""
+
+ def setUp(self):
+ self.asn1Spec = rfc5280.Certificate()
+
+ def testDerCodec(self):
+ substrate = pem.readBase64fromText(self.cert_pem_text)
+ asn1Object, rest = der_decode(substrate, asn1Spec=self.asn1Spec)
+ assert not rest
+ assert asn1Object.prettyPrint()
+ assert der_encode(asn1Object) == substrate
+
+ found_dev_owner = False
+ der_dev_own_oid = der_encode(univ.ObjectIdentifier('1.3.6.1.4.1.22112.48.24'))
+
+ for extn in asn1Object['tbsCertificate']['extensions']:
+ if extn['extnID'] == rfc5280.id_ce_subjectDirectoryAttributes:
+ assert extn['extnID'] in rfc5280.certificateExtensionsMap.keys()
+ ev, rest = der_decode(extn['extnValue'],
+ asn1Spec=rfc5280.certificateExtensionsMap[extn['extnID']])
+ assert not rest
+ assert ev.prettyPrint()
+ assert der_encode(ev) == extn['extnValue']
+
+ for attr in ev:
+ if attr['type'] == rfc5916.id_deviceOwner:
+ assert attr['values'][0] == der_dev_own_oid
+ found_dev_owner = True
+
+ assert found_dev_owner
+
+ def testOpenTypes(self):
+ substrate = pem.readBase64fromText(self.cert_pem_text)
+ asn1Object, rest = der_decode(substrate,
+ asn1Spec=self.asn1Spec,
+ decodeOpenTypes=True)
+ assert not rest
+ assert asn1Object.prettyPrint()
+ assert der_encode(asn1Object) == substrate
+
+ found_dev_owner = False
+ dev_own_oid = univ.ObjectIdentifier('1.3.6.1.4.1.22112.48.24')
+
+ for extn in asn1Object['tbsCertificate']['extensions']:
+ if extn['extnID'] == rfc5280.id_ce_subjectDirectoryAttributes:
+ assert extn['extnID'] in rfc5280.certificateExtensionsMap.keys()
+ ev, rest = der_decode(extn['extnValue'],
+ asn1Spec=rfc5280.certificateExtensionsMap[extn['extnID']],
+ decodeOpenTypes=True)
+ assert not rest
+ assert ev.prettyPrint()
+ assert der_encode(ev) == extn['extnValue']
+
+ for attr in ev:
+ if attr['type'] == rfc5916.id_deviceOwner:
+ assert attr['values'][0] == dev_own_oid
+ found_dev_owner = True
+
+ assert found_dev_owner
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+ import sys
+
+ result = unittest.TextTestRunner(verbosity=2).run(suite)
+ sys.exit(not result.wasSuccessful())