acme/autocert: remove trailing dot from domain before requesting cert
Browsers can send an SNI name of "example.com." for
https://example.com./ but LetsEncrypt rejects the trailing dot.
Fixes golang/go#18114
Change-Id: Ie38e355e5b5566a7eb18f77a2449660e22e21b4c
Reviewed-on: https://go-review.googlesource.com/33711
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/acme/autocert/autocert.go b/acme/autocert/autocert.go
index 12c9010..877bfba 100644
--- a/acme/autocert/autocert.go
+++ b/acme/autocert/autocert.go
@@ -187,6 +187,7 @@
}
// regular domain
+ name = strings.TrimSuffix(name, ".") // golang.org/issue/18114
cert, err := m.cert(name)
if err == nil {
return cert, nil
diff --git a/acme/autocert/autocert_test.go b/acme/autocert/autocert_test.go
index 3a9daa1..295f702 100644
--- a/acme/autocert/autocert_test.go
+++ b/acme/autocert/autocert_test.go
@@ -108,6 +108,14 @@
}
func TestGetCertificate(t *testing.T) {
+ testGetCertificate(t, false)
+}
+
+func TestGetCertificate_trailingDot(t *testing.T) {
+ testGetCertificate(t, true)
+}
+
+func testGetCertificate(t *testing.T, trailingDot bool) {
const domain = "example.org"
man := &Manager{Prompt: AcceptTOS}
defer man.stopRenew()
@@ -167,6 +175,9 @@
if err != nil {
t.Fatalf("new-cert: CSR: %v", err)
}
+ if csr.Subject.CommonName != domain {
+ t.Errorf("CommonName in CSR = %q; want %q", csr.Subject.CommonName, domain)
+ }
der, err := dummyCert(csr.PublicKey, domain)
if err != nil {
t.Fatalf("new-cert: dummyCert: %v", err)
@@ -201,11 +212,14 @@
// simulate tls.Config.GetCertificate
var tlscert *tls.Certificate
done := make(chan struct{})
- go func() {
- hello := &tls.ClientHelloInfo{ServerName: domain}
+ go func(serverName string) {
+ if trailingDot {
+ serverName += "."
+ }
+ hello := &tls.ClientHelloInfo{ServerName: serverName}
tlscert, err = man.GetCertificate(hello)
close(done)
- }()
+ }(domain)
select {
case <-time.After(time.Minute):
t.Fatal("man.GetCertificate took too long to return")