]> Cypherpunks repositories - gostls13.git/commitdiff
crypto/x509: add ExtKeyUsage.OID method
authorRoland Shoemaker <roland@golang.org>
Wed, 26 Nov 2025 17:21:13 +0000 (09:21 -0800)
committerGopher Robot <gobot@golang.org>
Wed, 26 Nov 2025 22:21:13 +0000 (14:21 -0800)
And OIDFromASN1OID for converting between asn1.ObjectIdentifier and OID.

Fixes #75325

Change-Id: I3b84dce54346d88aab731ffe30d0fef07b014f04
Reviewed-on: https://go-review.googlesource.com/c/go/+/724761
Reviewed-by: Neal Patel <nealpatel@google.com>
Auto-Submit: Roland Shoemaker <roland@golang.org>
Commit-Queue: Neal Patel <nealpatel@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

api/next/75325.txt [new file with mode: 0644]
doc/next/6-stdlib/99-minor/crypto/x509/75325.md [new file with mode: 0644]
src/crypto/x509/oid.go
src/crypto/x509/oid_test.go
src/crypto/x509/x509.go
src/crypto/x509/x509_test.go

diff --git a/api/next/75325.txt b/api/next/75325.txt
new file mode 100644 (file)
index 0000000..dc241ef
--- /dev/null
@@ -0,0 +1,2 @@
+pkg crypto/x509, func OIDFromASN1OID(asn1.ObjectIdentifier) (OID, error) #75325
+pkg crypto/x509, method (ExtKeyUsage) OID() OID #75325
diff --git a/doc/next/6-stdlib/99-minor/crypto/x509/75325.md b/doc/next/6-stdlib/99-minor/crypto/x509/75325.md
new file mode 100644 (file)
index 0000000..a133e66
--- /dev/null
@@ -0,0 +1,4 @@
+The [ExtKeyUsage] type now has an OID method that returns the corresponding OID for the EKU.
+
+The new [OIDFromASN1OID] function allows converting an [encoding/asn1.ObjectIdentifier] into
+an [OID].
\ No newline at end of file
index c60daa7540c830b51b168effcdc1353a0fb15112..8bf19a1433318b2c7bb006d78e53ac0dea596fe5 100644 (file)
@@ -393,3 +393,15 @@ func (oid OID) toASN1OID() (asn1.ObjectIdentifier, bool) {
 
        return out, true
 }
+
+// OIDFromASN1OID creates a new OID using asn1OID.
+func OIDFromASN1OID(asn1OID asn1.ObjectIdentifier) (OID, error) {
+       uint64OID := make([]uint64, 0, len(asn1OID))
+       for _, component := range asn1OID {
+               if component < 0 {
+                       return OID{}, errors.New("x509: OID components must be non-negative")
+               }
+               uint64OID = append(uint64OID, uint64(component))
+       }
+       return OIDFromInts(uint64OID)
+}
index ce3a0672a6aa7ca5e3cad8d36aebe2baf2a1c770..efc71fc2dc78e7ef1ccddd1c9f30fa9bd1d48871 100644 (file)
@@ -343,3 +343,27 @@ func BenchmarkOIDMarshalUnmarshalText(b *testing.B) {
                }
        }
 }
+
+func TestOIDFromASN1OID(t *testing.T) {
+       negativeComponentOID := asn1.ObjectIdentifier{-1}
+       _, err := OIDFromASN1OID(negativeComponentOID)
+       if err == nil || err.Error() != "x509: OID components must be non-negative" {
+               t.Fatalf("OIDFromASN1OID() = %v; want = \"x509: OID components must be non-negative\"", err)
+       }
+
+       shortOID := asn1.ObjectIdentifier{1}
+       _, err = OIDFromASN1OID(shortOID)
+       if err == nil || err != errInvalidOID {
+               t.Fatalf("OIDFromASN1OID() = %v; want = %q", err, errInvalidOID)
+       }
+       invalidOIDFirstComponent := asn1.ObjectIdentifier{255, 1}
+       _, err = OIDFromASN1OID(invalidOIDFirstComponent)
+       if err == nil || err != errInvalidOID {
+               t.Fatalf("OIDFromASN1OID() = %v; want = %q", err, errInvalidOID)
+       }
+       invalidOIDSecondComponent := asn1.ObjectIdentifier{1, 255}
+       _, err = OIDFromASN1OID(invalidOIDSecondComponent)
+       if err == nil || err != errInvalidOID {
+               t.Fatalf("OIDFromASN1OID() = %v; want = %q", err, errInvalidOID)
+       }
+}
index 85e8fceedcb767fdde28e4bd9ed890471a9a866d..7953b615f50d564cfbcd029afc7606eeff6355a1 100644 (file)
@@ -687,6 +687,19 @@ func oidFromExtKeyUsage(eku ExtKeyUsage) (oid asn1.ObjectIdentifier, ok bool) {
        return
 }
 
+// OID returns the ASN.1 object identifier of the EKU.
+func (eku ExtKeyUsage) OID() OID {
+       asn1OID, ok := oidFromExtKeyUsage(eku)
+       if !ok {
+               panic("x509: internal error: known ExtKeyUsage has no OID")
+       }
+       oid, err := OIDFromASN1OID(asn1OID)
+       if err != nil {
+               panic("x509: internal error: known ExtKeyUsage has invalid OID")
+       }
+       return oid
+}
+
 // A Certificate represents an X.509 certificate.
 type Certificate struct {
        Raw                     []byte // Complete ASN.1 DER content (certificate, signature algorithm and signature).
index 98f3f7941c8d63b265673bfc5a28707eb12dff99..183ee303faec985e961edb564f3e45734ce37985 100644 (file)
@@ -4263,3 +4263,12 @@ func TestCreateCertificateNegativeMaxPathLength(t *testing.T) {
                t.Fatalf(`CreateCertificate() = %v; want = "x509: invalid MaxPathLen, must be greater or equal to -1"`, err)
        }
 }
+
+func TestEKUOIDS(t *testing.T) {
+       for _, eku := range extKeyUsageOIDs {
+               oid := eku.extKeyUsage.OID()
+               if !oid.EqualASN1OID(eku.oid) {
+                       t.Errorf("extKeyUsage %v: expected OID %v, got %v", eku.extKeyUsage, eku.oid, oid)
+               }
+       }
+}