CVE-2023-29409 is a vulnerability impacting Go's crypto/tls library, which enables HTTPS and other secure connections. The issue lives in how the library handles RSA public keys in certificate chains. Essentially, allowing certificates with enormous RSA keys (much larger than practical needs) means a carefully crafted certificate chain could force a client or server to burn up a ton of CPU time — making it vulnerable to a denial of service (DoS) attack.

This post details how the bug works, how it was addressed, and what exposure you (or your servers) might face.

Why RSA Key Size Matters

Validating a certificate involves checking the signature with the public key, using algorithms that are increasingly slow as the key size increases. For context:

4096 bits is sometimes used for high-security keys.

- Larger RSA keys (like 16,384 or even 65,536 bits) drastically slow down cryptographic computations, especially signature verification — far beyond practical security needs.

If, during a TLS handshake, a certificate with a huge RSA key is used, your server or client could get stuck spending lots of CPU cycles validating the signature, meaning it could be easily attacked by excessive connections.

The Vulnerability In Action

Prior to the fix, Go’s crypto/tls and certificate validation layers placed no limit on the size of RSA keys encountered in certificates.

Attack scenario

1. An attacker sets up a certificate chain with a *very large* RSA key (for example, 131072 bits — that's 16KB!).
2. Attacker connects to a TLS client/server (like your Go-based web service).
3. During the TLS handshake, your server tries to verify the chain... and gets stuck in a long, CPU-intensive verification process.

Proof-of-Concept Code

Here’s an illustrative sketch (not a real attack), showing how a malicious certificate might trigger the bug:

package main

import (
    "crypto/rsa"
    "crypto/rand"
    "crypto/x509"
    "encoding/pem"
    "math/big"
    "os"
)

func main() {
    // This creates a ridiculously large RSA key (dangerous and slow)
    priv, _ := rsa.GenerateKey(rand.Reader, 16384) // 16,384 bits
    template := x509.Certificate{
        SerialNumber: big.NewInt(1),
    }
    derBytes, _ := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
    // Write certificate to file
    pem.Encode(os.Stdout, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
}


> NOTE: Generating such large keys is computationally expensive and serves no practical use. This code is for educational purposes only.

The Fix

Go 1.20.4, 1.19.9, and later restrict RSA public key sizes for certificates to at most 8192 bits. Anything larger is rejected during handshake with a clear error.

Key Points from the Security Advisory

- Go Security Advisory - GO-2023-1755 — original report.
- Go patch commit — see the size-check in the source.

The code (from the Go patch)

// Check key size
const maxRSAKeySize = 8192
if rsaKey.N.BitLen() > maxRSAKeySize {
    return errors.New("tls: RSA key size too large")
}

Public Exposure: Are Big Keys Out There?

Ideally, we would never see a normal web certificate with such a large key. The Go team surveyed all known publicly trusted certificates. Only three were spotted in the wild with >8192-bit RSA keys — all looked like *test* certificates, not real production use.

So, updating to the new limit is safe for almost everyone using the public web PKI.

Private PKIs (for example, giant internal corporate CA deployments) could theoretically encounter breakage, if someone issued keys above 8192 bits. But in practice, this is incredibly rare and leads only to extra-computational cost, not more security.

Exploiting CVE-2023-29409

While this vulnerability is not classic "remote code execution" or leaking secrets, it's very serious for resource exhaustion/DoS.

Watch the CPU usage spike as every connection forces a slow signature validation.

Real-world impact: If you're running Go-based services, they could be dogpiled by attackers via this method, causing denial of service by high CPU usage.

Update Go: Use at least Go 1.20.4 or Go 1.19.9+

2. Audit private certificates: If you run your own CA, double check you’re not using >8192 bit RSA keys.
3. Monitor TLS handshake performance: Unexpected spikes could signal large key attacks or other DoS attempts.

References

- Go Security Advisory - GO-2023-1755
- CVE-2023-29409 NIST Entry
- Go patch commit fixing large key DoS
- Discussion on the Go GitHub repo

Conclusion

CVE-2023-29409 illustrates how even subtle cryptographic parameter choices — like key size — can lead to real-world risks. The Go team's practical fix (8192-bit cap) ensures that web users stay safe, and anyone who *really* needs bigger keys for obscure reasons can always fork or patch code at their own risk. For almost everyone: keep those keys under 8192 bits, and update Go to stay safe.

Timeline

Published on: 08/02/2023 20:15:00 UTC
Last modified on: 08/31/2023 19:15:00 UTC