diff --git a/certcrypto/crypto.go b/certcrypto/crypto.go index 2d531630..4f5e17c5 100644 --- a/certcrypto/crypto.go +++ b/certcrypto/crypto.go @@ -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 != "" { diff --git a/certificate/certificates.go b/certificate/certificates.go index 2d0fa8d2..d6a7438c 100644 --- a/certificate/certificates.go +++ b/certificate/certificates.go @@ -243,8 +243,10 @@ 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 @@ -252,7 +254,12 @@ func (c *Certifier) getForOrder(domains []string, order acme.ExtendedOrder, bund // 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) @@ -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, } @@ -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, diff --git a/cmd/cmd_list.go b/cmd/cmd_list.go index 271e9299..71daaf88 100644 --- a/cmd/cmd_list.go +++ b/cmd/cmd_list.go @@ -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) diff --git a/cmd/cmd_renew.go b/cmd/cmd_renew.go index 68bb2bd8..70376def 100644 --- a/cmd/cmd_renew.go +++ b/cmd/cmd_renew.go @@ -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