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>
This commit is contained in:
Brad Fitzpatrick 2016-11-30 16:39:40 +00:00
Родитель ede567c8e0
Коммит 21853a76e0
2 изменённых файлов: 18 добавлений и 3 удалений

Просмотреть файл

@ -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

Просмотреть файл

@ -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")