浏览代码

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>
Brad Fitzpatrick 9 年之前
父节点
当前提交
21853a76e0
共有 2 个文件被更改,包括 18 次插入3 次删除
  1. 1 0
      acme/autocert/autocert.go
  2. 17 3
      acme/autocert/autocert_test.go

+ 1 - 0
acme/autocert/autocert.go

@@ -187,6 +187,7 @@ func (m *Manager) GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate,
 	}
 
 	// regular domain
+	name = strings.TrimSuffix(name, ".") // golang.org/issue/18114
 	cert, err := m.cert(name)
 	if err == nil {
 		return cert, nil

+ 17 - 3
acme/autocert/autocert_test.go

@@ -108,6 +108,14 @@ func decodePayload(v interface{}, r io.Reader) error {
 }
 
 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 @@ func TestGetCertificate(t *testing.T) {
 			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 @@ func TestGetCertificate(t *testing.T) {
 	// 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")