Skip to content

Commit

Permalink
feat: support simplified issuance for very long domain names at Let's…
Browse files Browse the repository at this point in the history
… Encrypt (#2054)

Co-authored-by: Fernandez Ludovic <ldez@users.noreply.github.com>
  • Loading branch information
MartinWeindel and ldez authored Jan 26, 2024
1 parent ad6e38e commit d263a28
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 9 deletions.
20 changes: 20 additions & 0 deletions certcrypto/crypto.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,26 @@ func ParsePEMCertificate(cert []byte) (*x509.Certificate, error) {
return x509.ParseCertificate(pemBlock.Bytes)
}

func GetCertificateMainDomain(cert *x509.Certificate) (string, error) {
return getMainDomain(cert.Subject, cert.DNSNames)
}

func GetCSRMainDomain(cert *x509.CertificateRequest) (string, error) {
return getMainDomain(cert.Subject, cert.DNSNames)
}

func getMainDomain(subject pkix.Name, dnsNames []string) (string, error) {
if subject.CommonName == "" && len(dnsNames) == 0 {
return "", errors.New("missing domain")
}

if subject.CommonName != "" {
return subject.CommonName, nil
}

return dnsNames[0], nil
}

func ExtractDomains(cert *x509.Certificate) []string {
var domains []string
if cert.Subject.CommonName != "" {
Expand Down
23 changes: 17 additions & 6 deletions certificate/certificates.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,16 +243,23 @@ func (c *Certifier) getForOrder(domains []string, order acme.ExtendedOrder, bund
}
}

// Determine certificate name(s) based on the authorization resources
commonName := domains[0]
commonName := ""
if len(domains[0]) <= 64 {
commonName = domains[0]
}

// RFC8555 Section 7.4 "Applying for Certificate Issuance"
// https://www.rfc-editor.org/rfc/rfc8555.html#section-7.4
// says:
// Clients SHOULD NOT make any assumptions about the sort order of
// "identifiers" or "authorizations" elements in the returned order
// object.
san := []string{commonName}

var san []string
if commonName != "" {
san = append(san, commonName)
}

for _, auth := range order.Identifiers {
if auth.Value != commonName {
san = append(san, auth.Value)
Expand All @@ -274,9 +281,8 @@ func (c *Certifier) getForCSR(domains []string, order acme.ExtendedOrder, bundle
return nil, err
}

commonName := domains[0]
certRes := &Resource{
Domain: commonName,
Domain: domains[0],
CertURL: respOrder.Certificate,
PrivateKey: privateKeyPem,
}
Expand Down Expand Up @@ -598,8 +604,13 @@ func (c *Certifier) Get(url string, bundle bool) (*Resource, error) {
return nil, err
}

domain, err := certcrypto.GetCertificateMainDomain(x509Certs[0])
if err != nil {
return nil, err
}

return &Resource{
Domain: x509Certs[0].Subject.CommonName,
Domain: domain,
Certificate: cert,
IssuerCertificate: issuer,
CertURL: url,
Expand Down
9 changes: 7 additions & 2 deletions cmd/cmd_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,15 @@ func listCertificates(ctx *cli.Context) error {
return err
}

name, err := certcrypto.GetCertificateMainDomain(pCert)
if err != nil {
return err
}

if names {
fmt.Println(pCert.Subject.CommonName)
fmt.Println(name)
} else {
fmt.Println(" Certificate Name:", pCert.Subject.CommonName)
fmt.Println(" Certificate Name:", name)
fmt.Println(" Domains:", strings.Join(pCert.DNSNames, ", "))
fmt.Println(" Expiry Date:", pCert.NotAfter)
fmt.Println(" Certificate Path:", filename)
Expand Down
5 changes: 4 additions & 1 deletion cmd/cmd_renew.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,10 @@ func renewForCSR(ctx *cli.Context, client *lego.Client, certsStorage *Certificat
log.Fatal(err)
}

domain := csr.Subject.CommonName
domain, err := certcrypto.GetCSRMainDomain(csr)
if err != nil {
log.Fatalf("Error: %v", err)
}

// load the cert resource from files.
// We store the certificate, private key and metadata in different files
Expand Down

0 comments on commit d263a28

Please sign in to comment.