From 583ed06a2b82cf7437b37b2fc1fd2c772d7de420 Mon Sep 17 00:00:00 2001 From: Navtej Date: Thu, 26 Mar 2026 21:05:23 +0000 Subject: crypto/x509/pkix: avoid quadratic string concatenation in RDNSequence.String MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RDNSequence.String builds its result using repeated s += ... inside nested loops, leading to O(N²) time and memory complexity. A certificate with many Subject or Issuer RDN entries can therefore cause excessive CPU and memory usage when String is called. Switch to strings.Builder to construct the output, reducing complexity to O(N) without changing behavior. This follows the same approach used to fix CVE-2025-61729 (HostnameError.Error), which addressed the same quadratic concatenation pattern. Change-Id: Id44303b5732081de9f01d186bc2b8ac66349a650 GitHub-Last-Rev: b0706c20655d1a263c3a989b76c0c25796c900df GitHub-Pull-Request: golang/go#78265 Reviewed-on: https://go-review.googlesource.com/c/go/+/757680 Reviewed-by: Navtej Kathuria US Reviewed-by: Daniel McCarney Reviewed-by: Roland Shoemaker Reviewed-by: Mateusz Poliwczak Reviewed-by: Junyang Shao LUCI-TryBot-Result: Go LUCI Auto-Submit: Mateusz Poliwczak --- src/crypto/x509/pkix/pkix.go | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/crypto/x509/pkix/pkix.go b/src/crypto/x509/pkix/pkix.go index dfc6abca65..18f746d14b 100644 --- a/src/crypto/x509/pkix/pkix.go +++ b/src/crypto/x509/pkix/pkix.go @@ -11,6 +11,7 @@ import ( "encoding/hex" "fmt" "math/big" + "strings" "time" ) @@ -38,15 +39,15 @@ var attributeTypeNames = map[string]string{ // String returns a string representation of the sequence r, // roughly following the RFC 2253 Distinguished Names syntax. func (r RDNSequence) String() string { - s := "" + var buf strings.Builder for i := 0; i < len(r); i++ { rdn := r[len(r)-1-i] if i > 0 { - s += "," + buf.WriteByte(',') } for j, tv := range rdn { if j > 0 { - s += "+" + buf.WriteByte('+') } oidString := tv.Type.String() @@ -54,7 +55,9 @@ func (r RDNSequence) String() string { if !ok { derBytes, err := asn1.Marshal(tv.Value) if err == nil { - s += oidString + "=#" + hex.EncodeToString(derBytes) + buf.WriteString(oidString) + buf.WriteString("=#") + buf.WriteString(hex.EncodeToString(derBytes)) continue // No value escaping necessary. } @@ -85,11 +88,13 @@ func (r RDNSequence) String() string { } } - s += typeName + "=" + string(escaped) + buf.WriteString(typeName) + buf.WriteByte('=') + buf.WriteString(string(escaped)) } } - return s + return buf.String() } type RelativeDistinguishedNameSET []AttributeTypeAndValue -- cgit v1.3