go-acme / lego

Let's Encrypt/ACME client and library written in Go
https://go-acme.github.io/lego/
MIT License
7.46k stars 986 forks source link

Don't create CSRs with a Common Name that is longer than 64 bytes #2049

Closed mcpherrinm closed 5 months ago

mcpherrinm commented 8 months ago

Welcome

What did you expect to see?

Lego creates CSRs by taking the first domain flag passed in and using it as the Common Name.

If that is longer than 64 bytes, Let's Encrypt (and potentially other CAs) reject the CSR as it is invalid.

If one of your names is shorter, you could ensure it is passed in first. But if all your names are too long, it always fails.

As a bigger ecosystem thing, the common name is going to start going away in more contexts, and it's likely that at some point in the future Let's Encrypt will start issuing certificates with no CN in the certificate if the CSR doesn't have one, or possibly even dropping CN support totally. There's no timeline for this, but I mention it as a direction this is likely to go in.

As a result, I would suggest the following changes:

  1. Don't put a CN in CSRs by default
  2. Add a flag to include a CSR if a user has some need for that.

The CN flag might not be required, so it's worth considering just omitting that.

What did you see instead?

urn:ietf:params:acme:error:badCSR :: Error finalizing order :: CN was longer than 64 bytes

How do you use lego?

Binary

Reproduction steps

works:

./lego -a --dns manual -d test.example.ca -d thisisthesongthatneverendsyesitgoesonandonmyfriends.somepeoplestartedsingingitnotknowingwhatitwas.andtheyllcontinuesingingitforeverjustbecause.example.ca run

doesn't work:

./lego -a --dns manual -d thisisthesongthatneverendsyesitgoesonandonmyfriends.somepeoplestartedsingingitnotknowingwhatitwas.andtheyllcontinuesingingitforeverjustbecause.example.ca -d test.example.ca  run

Version of lego

d51b5e408bff268bd3386c39a765be40e996c9b1 (current head)

Logs

```console 2023/11/08 14:49:15 Could not obtain certificates: error: one or more domains had a problem: thisisthesongthatneverendsyesitgoesonandonmyfriends.somepeoplestartedsingingitnotknowingwhatitwas.andtheyllcontinuesingingitforeverjustbecause.example.ca: acme: error: 400 :: POST :: https://acme-staging-v02.api.letsencrypt.org/acme/finalize/104658544/12129366254 :: urn:ietf:params:acme:error:badCSR :: Error finalizing order :: CN was longer than 64 bytes ```

Go environment (if applicable)

```console go version go1.20.1 linux/amd64 ```
dmke commented 7 months ago

(ignore this, I've misread the issue)

Previously DNS labels are generally limited to 63 characters ([RFC1034, Section 3.1](https://datatracker.ietf.org/doc/html/rfc1034#section-3.1)): > Each node has a label, which is zero to 63 octets in length. It shouldn't matter whether such a DNS label is part of the X509 subject, or if it's part of the DNS alternative names list - it's equally invalid.
mcpherrinm commented 7 months ago

A domain name is a list of labels. While each label is limited to 63 characters, a domain name can be longer.

The limitation on CN length is from RFC5280, appendix A.1: ub-common-name INTEGER ::= 64

dmke commented 7 months ago

Yep, that's where I had my mental disconnect. Thanks for pointing that out!