Support for UUID OIDs in X509v3 extensions
There seems to have been a regression in cryptography 38.0.0 where OIDs with a bit length exceeding 32 bits are no longer supported. More specifically, using a UUID OID (subtree 2.25) in a certificate's SAN extension causes parsing errors that were not present in version 37.0.4 and lower.
For comparison, this worked in version 37.0.4:
Python 3.10.12 (main, Mar 22 2024, 16:50:05) [GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cryptography
>>> import cryptography.x509
>>> cryptography.__version__
'37.0.4'
>>> cryptography.x509.ObjectIdentifier('2.25.223663413560230117710484359924050447509')
<ObjectIdentifier(oid=2.25.223663413560230117710484359924050447509, name=Unknown OID)>
While it fails in version 38.0.0:
Python 3.10.12 (main, Mar 22 2024, 16:50:05) [GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cryptography
>>> import cryptography.x509
>>> cryptography.__version__
'38.0.0'
>>> cryptography.x509.ObjectIdentifier('2.25.223663413560230117710484359924050447509')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: error parsing asn1 value: ParseError { kind: InvalidValue }
To paraphrase this related issue, OID maximum length is a messy topic. There is no real maximum depth/length limit for OIDs in general, but the X509v3 specification seems to only require support of OID arc lengths up to 28 bits.
In that sense, the current issue falls somewhere between a regression bug and a feature request: it would be nice if cryptography could again support OID arcs up to 128 bits, as this would allow support for OID subtree 2.25. Since OpenSSL supports these OIDs, and rust has a native u128 datatype, it seems doable, but I'm not equipped to perform an actual impact analysis.
For what it's worth, I also came across this study comparing UUID OID support across various implementations.
Version information (all packages installed in a virtual environment):
python3.10.12cryptography43.0.0 (same issue going back to 38.0.0)cffi1.16.0setuptools59.6.0
As you noted, we've come across this before. We actually widened arc support up to 63-bits, but we've so far chosen not to support the UUID arcs. Are they seeing adoption in a standard somewhere? What do people do in (very large) ecosystems like Go where 28-bit arc limits are enforced?
As you noted, we've come across this before. We actually widened arc support up to 63-bits, but we've so far chosen not to support the UUID arcs.
Is this 63-bit support implemented in a version that is yet to be released? In version 43.0.0 I'm still seeing the following behavior on anything exceeding 32 bits:
Python 3.10.12 (main, Mar 22 2024, 16:50:05) [GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cryptography
>>> import cryptography.x509
>>> cryptography.__version__
'43.0.0'
>>> cryptography.x509.ObjectIdentifier('2.25.4294967295') # largest uint32
<ObjectIdentifier(oid=2.25.4294967295, name=Unknown OID)>
>>> cryptography.x509.ObjectIdentifier('2.25.4294967296') # add one
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: error parsing asn1 value: ParseError { kind: InvalidValue }
Are they seeing adoption in a standard somewhere?
My research didn't really turn up a whole lot beyond what I already shared in my previous post. An organization named IHE seems to be recommending their use in the medical sphere, but perhaps not in an X509 context.
Other than that, they're convenient when you need an OID and going through the IANA PEN application is either inconvenient or impossible, e.g. when dynamically generating CAs/certificates on behalf of customers (the case we find ourselves in).
What do people do in (very large) ecosystems like Go where 28-bit arc limits are enforced?
I wouldn't be able to say. We just came across the first integration issue, and the customer organization happens to be using Python. I guess that if we come across a Go integration problem, I'll go to their GitHub page and try my "pretty please" approach there too 😀
Other than that, they're convenient when you need an OID and going through the IANA PEN application is either inconvenient or impossible, e.g. when dynamically generating CAs/certificates on behalf of customers (the case we find ourselves in).
Just out of curiosity: is there a reason you can't go through the PEN application once, and then assign sequential/bucket-delegated OIDs to your customers under your PEN arc?
(Edit: I ask because I went through it once, and it took them ~5 days to allocate me an arc. From there, I believe there are no sub-arc restrictions 🙂)
My mistake, we do still limit to 32-bit values. 63 bytes is the limit of a serialized DER representation.
I have the same problem when using genilib with Cloudlab
Cloudlab generates certificates with UUID OIDs, which used to work fine until the cryptography upgrade. I have been bugging them to migrate away from these certificates over the last years, with no success.
Other than that, they're convenient when you need an OID and going through the IANA PEN application is either inconvenient or impossible, e.g. when dynamically generating CAs/certificates on behalf of customers (the case we find ourselves in).
Just out of curiosity: is there a reason you can't go through the PEN application once, and then assign sequential/bucket-delegated OIDs to your customers under your PEN arc?
(Edit: I ask because I went through it once, and it took them ~5 days to allocate me an arc. From there, I believe there are no sub-arc restrictions 🙂)
Yeah, we're considering that option. Just needs a fair bit of refactoring and paperwork. (The paperwork mostly due to my employer's requirements...)
Previously discussed in https://github.com/pyca/cryptography/issues/6573 -- given other implementations have similar limitations, I'm disinclined towards supporting these.
After discussing with @reaperhulk, we'd be willing to take a PR (which would go to rust-asn1 in the first instance) which added support for 128-bit OID arcs.
After discussing with @reaperhulk, we'd be willing to take a PR (which would go to rust-asn1 in the first instance) which added support for 128-bit OID arcs.
I submitted a pull request: https://github.com/alex/rust-asn1/pull/484
Thanks!
On Wed, Oct 16, 2024 at 10:57 PM Robby Cornelissen @.***> wrote:
After discussing with @reaperhulk https://github.com/reaperhulk, we'd be willing to take a PR (which would go to rust-asn1 in the first instance) which added support for 128-bit OID arcs.
I submitted a pull request: alex/rust-asn1#484 https://github.com/alex/rust-asn1/pull/484
— Reply to this email directly, view it on GitHub https://github.com/pyca/cryptography/issues/11338#issuecomment-2418392218, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAAGBA5ZC4NQLCAPUV7HU3Z34RR5AVCNFSM6AAAAABLJ2UYOWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDIMJYGM4TEMRRHA . You are receiving this because you commented.Message ID: @.***>
-- All that is necessary for evil to succeed is for good people to do nothing.
If you want, I'll also submit a PR for this repository. I assume just bump the asn1 version to 0.18 and make changes to the test_oid_arc_too_large test?
diff --git a/tests/x509/test_x509.py b/tests/x509/test_x509.py
index b96c4dbfd..de6c91108 100644
--- a/tests/x509/test_x509.py
+++ b/tests/x509/test_x509.py
@@ -6056,10 +6056,11 @@ class TestObjectIdentifier:
x509.ObjectIdentifier("1.39.999")
x509.ObjectIdentifier("2.5.29.3")
x509.ObjectIdentifier("2.999.37.5.22.8")
+ x509.ObjectIdentifier(f"2.25.{2**128 - 1}")
def test_oid_arc_too_large(self):
with pytest.raises(ValueError):
- x509.ObjectIdentifier(f"2.25.{2**128 - 1}")
+ x509.ObjectIdentifier(f"2.25.{2**128}")
class TestName:
We'll need a rust-asn1 release first, but yes
On Thu, Oct 17, 2024 at 9:48 PM Robby Cornelissen @.***> wrote:
If you want, I'll also submit a PR for this repository. I assume just bump the asn1 version to 0.18 and make changes to the test_oid_arc_too_large test?
diff --git a/tests/x509/test_x509.py b/tests/x509/test_x509.py index b96c4dbfd..de6c91108 100644 --- a/tests/x509/test_x509.py +++ b/tests/x509/test_x509.py @@ -6056,10 +6056,11 @@ class TestObjectIdentifier: x509.ObjectIdentifier("1.39.999") x509.ObjectIdentifier("2.5.29.3") x509.ObjectIdentifier("2.999.37.5.22.8")
x509.ObjectIdentifier(f"2.25.{2**128 - 1}")def test_oid_arc_too_large(self): with pytest.raises(ValueError):
x509.ObjectIdentifier(f"2.25.{2**128 - 1}")
x509.ObjectIdentifier(f"2.25.{2**128}")class TestName:
— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>
-- All that is necessary for evil to succeed is for good people to do nothing.