// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package autocert

import (
	"bytes"
	"context"
	"crypto"
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rand"
	"crypto/rsa"
	"crypto/tls"
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/asn1"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"html/template"
	"io"
	"io/ioutil"
	"math/big"
	"net/http"
	"net/http/httptest"
	"reflect"
	"strings"
	"sync"
	"testing"
	"time"

	"golang.org/x/crypto/acme"
	"golang.org/x/crypto/acme/autocert/internal/acmetest"
)

var (
	exampleDomain     = "example.org"
	exampleCertKey    = certKey{domain: exampleDomain}
	exampleCertKeyRSA = certKey{domain: exampleDomain, isRSA: true}
)

var discoTmpl = template.Must(template.New("disco").Parse(`{
	"new-reg": "{{.}}/new-reg",
	"new-authz": "{{.}}/new-authz",
	"new-cert": "{{.}}/new-cert"
}`))

var authzTmpl = template.Must(template.New("authz").Parse(`{
	"status": "pending",
	"challenges": [
		{
			"uri": "{{.}}/challenge/1",
			"type": "tls-sni-01",
			"token": "token-01"
		},
		{
			"uri": "{{.}}/challenge/2",
			"type": "tls-sni-02",
			"token": "token-02"
		},
		{
			"uri": "{{.}}/challenge/dns-01",
			"type": "dns-01",
			"token": "token-dns-01"
		},
		{
			"uri": "{{.}}/challenge/http-01",
			"type": "http-01",
			"token": "token-http-01"
		}
	]
}`))

type memCache struct {
	t       *testing.T
	mu      sync.Mutex
	keyData map[string][]byte
}

func (m *memCache) Get(ctx context.Context, key string) ([]byte, error) {
	m.mu.Lock()
	defer m.mu.Unlock()

	v, ok := m.keyData[key]
	if !ok {
		return nil, ErrCacheMiss
	}
	return v, nil
}

// filenameSafe returns whether all characters in s are printable ASCII
// and safe to use in a filename on most filesystems.
func filenameSafe(s string) bool {
	for _, c := range s {
		if c < 0x20 || c > 0x7E {
			return false
		}
		switch c {
		case '\\', '/', ':', '*', '?', '"', '<', '>', '|':
			return false
		}
	}
	return true
}

func (m *memCache) Put(ctx context.Context, key string, data []byte) error {
	if !filenameSafe(key) {
		m.t.Errorf("invalid characters in cache key %q", key)
	}

	m.mu.Lock()
	defer m.mu.Unlock()

	m.keyData[key] = data
	return nil
}

func (m *memCache) Delete(ctx context.Context, key string) error {
	m.mu.Lock()
	defer m.mu.Unlock()

	delete(m.keyData, key)
	return nil
}

func newMemCache(t *testing.T) *memCache {
	return &memCache{
		t:       t,
		keyData: make(map[string][]byte),
	}
}

func (m *memCache) numCerts() int {
	m.mu.Lock()
	defer m.mu.Unlock()

	res := 0
	for key := range m.keyData {
		if strings.HasSuffix(key, "+token") ||
			strings.HasSuffix(key, "+key") ||
			strings.HasSuffix(key, "+http-01") {
			continue
		}
		res++
	}
	return res
}

func dummyCert(pub interface{}, san ...string) ([]byte, error) {
	return dateDummyCert(pub, time.Now(), time.Now().Add(90*24*time.Hour), san...)
}

func dateDummyCert(pub interface{}, start, end time.Time, san ...string) ([]byte, error) {
	// use EC key to run faster on 386
	key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
	if err != nil {
		return nil, err
	}
	t := &x509.Certificate{
		SerialNumber:          big.NewInt(1),
		NotBefore:             start,
		NotAfter:              end,
		BasicConstraintsValid: true,
		KeyUsage:              x509.KeyUsageKeyEncipherment,
		DNSNames:              san,
	}
	if pub == nil {
		pub = &key.PublicKey
	}
	return x509.CreateCertificate(rand.Reader, t, t, pub, key)
}

func decodePayload(v interface{}, r io.Reader) error {
	var req struct{ Payload string }
	if err := json.NewDecoder(r).Decode(&req); err != nil {
		return err
	}
	payload, err := base64.RawURLEncoding.DecodeString(req.Payload)
	if err != nil {
		return err
	}
	return json.Unmarshal(payload, v)
}

func clientHelloInfo(sni string, ecdsaSupport bool) *tls.ClientHelloInfo {
	hello := &tls.ClientHelloInfo{
		ServerName:   sni,
		CipherSuites: []uint16{tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305},
	}
	if ecdsaSupport {
		hello.CipherSuites = append(hello.CipherSuites, tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305)
	}
	return hello
}

func TestGetCertificate(t *testing.T) {
	man := &Manager{Prompt: AcceptTOS}
	defer man.stopRenew()
	hello := clientHelloInfo("example.org", true)
	testGetCertificate(t, man, "example.org", hello)
}

func TestGetCertificate_trailingDot(t *testing.T) {
	man := &Manager{Prompt: AcceptTOS}
	defer man.stopRenew()
	hello := clientHelloInfo("example.org.", true)
	testGetCertificate(t, man, "example.org", hello)
}

func TestGetCertificate_ForceRSA(t *testing.T) {
	man := &Manager{
		Prompt:   AcceptTOS,
		Cache:    newMemCache(t),
		ForceRSA: true,
	}
	defer man.stopRenew()
	hello := clientHelloInfo(exampleDomain, true)
	testGetCertificate(t, man, exampleDomain, hello)

	// ForceRSA was deprecated and is now ignored.
	cert, err := man.cacheGet(context.Background(), exampleCertKey)
	if err != nil {
		t.Fatalf("man.cacheGet: %v", err)
	}
	if _, ok := cert.PrivateKey.(*ecdsa.PrivateKey); !ok {
		t.Errorf("cert.PrivateKey is %T; want *ecdsa.PrivateKey", cert.PrivateKey)
	}
}

func TestGetCertificate_nilPrompt(t *testing.T) {
	man := &Manager{}
	defer man.stopRenew()
	url, finish := startACMEServerStub(t, getCertificateFromManager(man, true), "example.org")
	defer finish()
	man.Client = &acme.Client{DirectoryURL: url}
	hello := clientHelloInfo("example.org", true)
	if _, err := man.GetCertificate(hello); err == nil {
		t.Error("got certificate for example.org; wanted error")
	}
}

func TestGetCertificate_expiredCache(t *testing.T) {
	// Make an expired cert and cache it.
	pk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
	if err != nil {
		t.Fatal(err)
	}
	tmpl := &x509.Certificate{
		SerialNumber: big.NewInt(1),
		Subject:      pkix.Name{CommonName: exampleDomain},
		NotAfter:     time.Now(),
	}
	pub, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, &pk.PublicKey, pk)
	if err != nil {
		t.Fatal(err)
	}
	tlscert := &tls.Certificate{
		Certificate: [][]byte{pub},
		PrivateKey:  pk,
	}

	man := &Manager{Prompt: AcceptTOS, Cache: newMemCache(t)}
	defer man.stopRenew()
	if err := man.cachePut(context.Background(), exampleCertKey, tlscert); err != nil {
		t.Fatalf("man.cachePut: %v", err)
	}

	// The expired cached cert should trigger a new cert issuance
	// and return without an error.
	hello := clientHelloInfo(exampleDomain, true)
	testGetCertificate(t, man, exampleDomain, hello)
}

func TestGetCertificate_failedAttempt(t *testing.T) {
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(http.StatusBadRequest)
	}))
	defer ts.Close()

	d := createCertRetryAfter
	f := testDidRemoveState
	defer func() {
		createCertRetryAfter = d
		testDidRemoveState = f
	}()
	createCertRetryAfter = 0
	done := make(chan struct{})
	testDidRemoveState = func(ck certKey) {
		if ck != exampleCertKey {
			t.Errorf("testDidRemoveState: domain = %v; want %v", ck, exampleCertKey)
		}
		close(done)
	}

	man := &Manager{
		Prompt: AcceptTOS,
		Client: &acme.Client{
			DirectoryURL: ts.URL,
		},
	}
	defer man.stopRenew()
	hello := clientHelloInfo(exampleDomain, true)
	if _, err := man.GetCertificate(hello); err == nil {
		t.Error("GetCertificate: err is nil")
	}
	select {
	case <-time.After(5 * time.Second):
		t.Errorf("took too long to remove the %q state", exampleCertKey)
	case <-done:
		man.stateMu.Lock()
		defer man.stateMu.Unlock()
		if v, exist := man.state[exampleCertKey]; exist {
			t.Errorf("state exists for %v: %+v", exampleCertKey, v)
		}
	}
}

// testGetCertificate_tokenCache tests the fallback of token certificate fetches
// to cache when Manager.certTokens misses. ecdsaSupport refers to the CA when
// verifying the certificate token.
func testGetCertificate_tokenCache(t *testing.T, ecdsaSupport bool) {
	man1 := &Manager{
		Cache:  newMemCache(t),
		Prompt: AcceptTOS,
	}
	defer man1.stopRenew()
	man2 := &Manager{
		Cache:  man1.Cache,
		Prompt: AcceptTOS,
	}
	defer man2.stopRenew()

	// Send the verification request to a different Manager from the one that
	// initiated the authorization, when they share caches.
	url, finish := startACMEServerStub(t, getCertificateFromManager(man2, ecdsaSupport), "example.org")
	defer finish()
	man1.Client = &acme.Client{DirectoryURL: url}
	hello := clientHelloInfo("example.org", true)
	if _, err := man1.GetCertificate(hello); err != nil {
		t.Error(err)
	}
	if _, err := man2.GetCertificate(hello); err != nil {
		t.Error(err)
	}
}

func TestGetCertificate_tokenCache(t *testing.T) {
	t.Run("ecdsaSupport=true", func(t *testing.T) {
		testGetCertificate_tokenCache(t, true)
	})
	t.Run("ecdsaSupport=false", func(t *testing.T) {
		testGetCertificate_tokenCache(t, false)
	})
}

func TestGetCertificate_ecdsaVsRSA(t *testing.T) {
	cache := newMemCache(t)
	man := &Manager{Prompt: AcceptTOS, Cache: cache}
	defer man.stopRenew()
	url, finish := startACMEServerStub(t, getCertificateFromManager(man, true), "example.org")
	defer finish()
	man.Client = &acme.Client{DirectoryURL: url}

	cert, err := man.GetCertificate(clientHelloInfo("example.org", true))
	if err != nil {
		t.Error(err)
	}
	if _, ok := cert.Leaf.PublicKey.(*ecdsa.PublicKey); !ok {
		t.Error("an ECDSA client was served a non-ECDSA certificate")
	}

	cert, err = man.GetCertificate(clientHelloInfo("example.org", false))
	if err != nil {
		t.Error(err)
	}
	if _, ok := cert.Leaf.PublicKey.(*rsa.PublicKey); !ok {
		t.Error("a RSA client was served a non-RSA certificate")
	}

	if _, err := man.GetCertificate(clientHelloInfo("example.org", true)); err != nil {
		t.Error(err)
	}
	if _, err := man.GetCertificate(clientHelloInfo("example.org", false)); err != nil {
		t.Error(err)
	}
	if numCerts := cache.numCerts(); numCerts != 2 {
		t.Errorf("found %d certificates in cache; want %d", numCerts, 2)
	}
}

func TestGetCertificate_wrongCacheKeyType(t *testing.T) {
	cache := newMemCache(t)
	man := &Manager{Prompt: AcceptTOS, Cache: cache}
	defer man.stopRenew()
	url, finish := startACMEServerStub(t, getCertificateFromManager(man, true), exampleDomain)
	defer finish()
	man.Client = &acme.Client{DirectoryURL: url}

	// Make an RSA cert and cache it without suffix.
	pk, err := rsa.GenerateKey(rand.Reader, 512)
	if err != nil {
		t.Fatal(err)
	}
	tmpl := &x509.Certificate{
		SerialNumber: big.NewInt(1),
		Subject:      pkix.Name{CommonName: exampleDomain},
		NotAfter:     time.Now().Add(90 * 24 * time.Hour),
	}
	pub, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, &pk.PublicKey, pk)
	if err != nil {
		t.Fatal(err)
	}
	rsaCert := &tls.Certificate{
		Certificate: [][]byte{pub},
		PrivateKey:  pk,
	}
	if err := man.cachePut(context.Background(), exampleCertKey, rsaCert); err != nil {
		t.Fatalf("man.cachePut: %v", err)
	}

	// The RSA cached cert should be silently ignored and replaced.
	cert, err := man.GetCertificate(clientHelloInfo(exampleDomain, true))
	if err != nil {
		t.Error(err)
	}
	if _, ok := cert.Leaf.PublicKey.(*ecdsa.PublicKey); !ok {
		t.Error("an ECDSA client was served a non-ECDSA certificate")
	}
	if numCerts := cache.numCerts(); numCerts != 1 {
		t.Errorf("found %d certificates in cache; want %d", numCerts, 1)
	}
}

func getCertificateFromManager(man *Manager, ecdsaSupport bool) func(string) error {
	return func(sni string) error {
		_, err := man.GetCertificate(clientHelloInfo(sni, ecdsaSupport))
		return err
	}
}

// startACMEServerStub runs an ACME server
// The domain argument is the expected domain name of a certificate request.
// TODO: Drop this in favour of x/crypto/acme/autocert/internal/acmetest.
func startACMEServerStub(t *testing.T, getCertificate func(string) error, domain string) (url string, finish func()) {
	// echo token-02 | shasum -a 256
	// then divide result in 2 parts separated by dot
	tokenCertName := "4e8eb87631187e9ff2153b56b13a4dec.13a35d002e485d60ff37354b32f665d9.token.acme.invalid"
	verifyTokenCert := func() {
		if err := getCertificate(tokenCertName); err != nil {
			t.Errorf("verifyTokenCert: GetCertificate(%q): %v", tokenCertName, err)
			return
		}
	}

	// ACME CA server stub
	var ca *httptest.Server
	ca = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Replay-Nonce", "nonce")
		if r.Method == "HEAD" {
			// a nonce request
			return
		}

		switch r.URL.Path {
		// discovery
		case "/":
			if err := discoTmpl.Execute(w, ca.URL); err != nil {
				t.Errorf("discoTmpl: %v", err)
			}
		// client key registration
		case "/new-reg":
			w.Write([]byte("{}"))
		// domain authorization
		case "/new-authz":
			w.Header().Set("Location", ca.URL+"/authz/1")
			w.WriteHeader(http.StatusCreated)
			if err := authzTmpl.Execute(w, ca.URL); err != nil {
				t.Errorf("authzTmpl: %v", err)
			}
		// accept tls-sni-02 challenge
		case "/challenge/2":
			verifyTokenCert()
			w.Write([]byte("{}"))
		// authorization status
		case "/authz/1":
			w.Write([]byte(`{"status": "valid"}`))
		// cert request
		case "/new-cert":
			var req struct {
				CSR string `json:"csr"`
			}
			decodePayload(&req, r.Body)
			b, _ := base64.RawURLEncoding.DecodeString(req.CSR)
			csr, err := x509.ParseCertificateRequest(b)
			if err != nil {
				t.Errorf("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.Errorf("new-cert: dummyCert: %v", err)
			}
			chainUp := fmt.Sprintf("<%s/ca-cert>; rel=up", ca.URL)
			w.Header().Set("Link", chainUp)
			w.WriteHeader(http.StatusCreated)
			w.Write(der)
		// CA chain cert
		case "/ca-cert":
			der, err := dummyCert(nil, "ca")
			if err != nil {
				t.Errorf("ca-cert: dummyCert: %v", err)
			}
			w.Write(der)
		default:
			t.Errorf("unrecognized r.URL.Path: %s", r.URL.Path)
		}
	}))
	finish = func() {
		ca.Close()

		// make sure token cert was removed
		cancel := make(chan struct{})
		done := make(chan struct{})
		go func() {
			defer close(done)
			tick := time.NewTicker(100 * time.Millisecond)
			defer tick.Stop()
			for {
				if err := getCertificate(tokenCertName); err != nil {
					return
				}
				select {
				case <-tick.C:
				case <-cancel:
					return
				}
			}
		}()
		select {
		case <-done:
		case <-time.After(5 * time.Second):
			close(cancel)
			t.Error("token cert was not removed")
			<-done
		}
	}
	return ca.URL, finish
}

// tests man.GetCertificate flow using the provided hello argument.
// The domain argument is the expected domain name of a certificate request.
func testGetCertificate(t *testing.T, man *Manager, domain string, hello *tls.ClientHelloInfo) {
	url, finish := startACMEServerStub(t, getCertificateFromManager(man, true), domain)
	defer finish()
	man.Client = &acme.Client{DirectoryURL: url}

	// simulate tls.Config.GetCertificate
	var tlscert *tls.Certificate
	var err error
	done := make(chan struct{})
	go func() {
		tlscert, err = man.GetCertificate(hello)
		close(done)
	}()
	select {
	case <-time.After(time.Minute):
		t.Fatal("man.GetCertificate took too long to return")
	case <-done:
	}
	if err != nil {
		t.Fatalf("man.GetCertificate: %v", err)
	}

	// verify the tlscert is the same we responded with from the CA stub
	if len(tlscert.Certificate) == 0 {
		t.Fatal("len(tlscert.Certificate) is 0")
	}
	cert, err := x509.ParseCertificate(tlscert.Certificate[0])
	if err != nil {
		t.Fatalf("x509.ParseCertificate: %v", err)
	}
	if len(cert.DNSNames) == 0 || cert.DNSNames[0] != domain {
		t.Errorf("cert.DNSNames = %v; want %q", cert.DNSNames, domain)
	}

}

func TestVerifyHTTP01(t *testing.T) {
	var (
		http01 http.Handler

		authzCount      int // num. of created authorizations
		didAcceptHTTP01 bool
	)

	verifyHTTPToken := func() {
		r := httptest.NewRequest("GET", "/.well-known/acme-challenge/token-http-01", nil)
		w := httptest.NewRecorder()
		http01.ServeHTTP(w, r)
		if w.Code != http.StatusOK {
			t.Errorf("http token: w.Code = %d; want %d", w.Code, http.StatusOK)
		}
		if v := w.Body.String(); !strings.HasPrefix(v, "token-http-01.") {
			t.Errorf("http token value = %q; want 'token-http-01.' prefix", v)
		}
	}

	// ACME CA server stub, only the needed bits.
	// TODO: Replace this with x/crypto/acme/autocert/internal/acmetest.
	var ca *httptest.Server
	ca = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Replay-Nonce", "nonce")
		if r.Method == "HEAD" {
			// a nonce request
			return
		}

		switch r.URL.Path {
		// Discovery.
		case "/":
			if err := discoTmpl.Execute(w, ca.URL); err != nil {
				t.Errorf("discoTmpl: %v", err)
			}
		// Client key registration.
		case "/new-reg":
			w.Write([]byte("{}"))
		// New domain authorization.
		case "/new-authz":
			authzCount++
			w.Header().Set("Location", fmt.Sprintf("%s/authz/%d", ca.URL, authzCount))
			w.WriteHeader(http.StatusCreated)
			if err := authzTmpl.Execute(w, ca.URL); err != nil {
				t.Errorf("authzTmpl: %v", err)
			}
		// Accept tls-sni-02.
		case "/challenge/2":
			w.Write([]byte("{}"))
		// Reject tls-sni-01.
		case "/challenge/1":
			http.Error(w, "won't accept tls-sni-01", http.StatusBadRequest)
		// Should not accept dns-01.
		case "/challenge/dns-01":
			t.Errorf("dns-01 challenge was accepted")
			http.Error(w, "won't accept dns-01", http.StatusBadRequest)
		// Accept http-01.
		case "/challenge/http-01":
			didAcceptHTTP01 = true
			verifyHTTPToken()
			w.Write([]byte("{}"))
		// Authorization statuses.
		// Make tls-sni-xxx invalid.
		case "/authz/1", "/authz/2":
			w.Write([]byte(`{"status": "invalid"}`))
		case "/authz/3", "/authz/4":
			w.Write([]byte(`{"status": "valid"}`))
		default:
			http.NotFound(w, r)
			t.Errorf("unrecognized r.URL.Path: %s", r.URL.Path)
		}
	}))
	defer ca.Close()

	m := &Manager{
		Client: &acme.Client{
			DirectoryURL: ca.URL,
		},
	}
	http01 = m.HTTPHandler(nil)
	ctx := context.Background()
	client, err := m.acmeClient(ctx)
	if err != nil {
		t.Fatalf("m.acmeClient: %v", err)
	}
	if err := m.verify(ctx, client, "example.org"); err != nil {
		t.Errorf("m.verify: %v", err)
	}
	// Only tls-sni-01, tls-sni-02 and http-01 must be accepted
	// The dns-01 challenge is unsupported.
	if authzCount != 3 {
		t.Errorf("authzCount = %d; want 3", authzCount)
	}
	if !didAcceptHTTP01 {
		t.Error("did not accept http-01 challenge")
	}
}

func TestRevokeFailedAuthz(t *testing.T) {
	// Prefill authorization URIs expected to be revoked.
	// The challenges are selected in a specific order,
	// each tried within a newly created authorization.
	// This means each authorization URI corresponds to a different challenge type.
	revokedAuthz := map[string]bool{
		"/authz/0": false, // tls-sni-02
		"/authz/1": false, // tls-sni-01
		"/authz/2": false, // no viable challenge, but authz is created
	}

	var authzCount int          // num. of created authorizations
	var revokeCount int         // num. of revoked authorizations
	done := make(chan struct{}) // closed when revokeCount is 3

	// ACME CA server stub, only the needed bits.
	// TODO: Replace this with x/crypto/acme/autocert/internal/acmetest.
	var ca *httptest.Server
	ca = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Replay-Nonce", "nonce")
		if r.Method == "HEAD" {
			// a nonce request
			return
		}

		switch r.URL.Path {
		// Discovery.
		case "/":
			if err := discoTmpl.Execute(w, ca.URL); err != nil {
				t.Errorf("discoTmpl: %v", err)
			}
		// Client key registration.
		case "/new-reg":
			w.Write([]byte("{}"))
		// New domain authorization.
		case "/new-authz":
			w.Header().Set("Location", fmt.Sprintf("%s/authz/%d", ca.URL, authzCount))
			w.WriteHeader(http.StatusCreated)
			if err := authzTmpl.Execute(w, ca.URL); err != nil {
				t.Errorf("authzTmpl: %v", err)
			}
			authzCount++
		// tls-sni-02 challenge "accept" request.
		case "/challenge/2":
			// Refuse.
			http.Error(w, "won't accept tls-sni-02 challenge", http.StatusBadRequest)
		// tls-sni-01 challenge "accept" request.
		case "/challenge/1":
			// Accept but the authorization will be "expired".
			w.Write([]byte("{}"))
		// Authorization requests.
		case "/authz/0", "/authz/1", "/authz/2":
			// Revocation requests.
			if r.Method == "POST" {
				var req struct{ Status string }
				if err := decodePayload(&req, r.Body); err != nil {
					t.Errorf("%s: decodePayload: %v", r.URL, err)
				}
				switch req.Status {
				case "deactivated":
					revokedAuthz[r.URL.Path] = true
					revokeCount++
					if revokeCount >= 3 {
						// Last authorization is revoked.
						defer close(done)
					}
				default:
					t.Errorf("%s: req.Status = %q; want 'deactivated'", r.URL, req.Status)
				}
				w.Write([]byte(`{"status": "invalid"}`))
				return
			}
			// Authorization status requests.
			// Simulate abandoned authorization, deleted by the CA.
			w.WriteHeader(http.StatusNotFound)
		default:
			http.NotFound(w, r)
			t.Errorf("unrecognized r.URL.Path: %s", r.URL.Path)
		}
	}))
	defer ca.Close()

	m := &Manager{
		Client: &acme.Client{DirectoryURL: ca.URL},
	}
	// Should fail and revoke 3 authorizations.
	// The first 2 are tsl-sni-02 and tls-sni-01 challenges.
	// The third time an authorization is created but no viable challenge is found.
	// See revokedAuthz above for more explanation.
	if _, err := m.createCert(context.Background(), exampleCertKey); err == nil {
		t.Errorf("m.createCert returned nil error")
	}
	select {
	case <-time.After(3 * time.Second):
		t.Error("revocations took too long")
	case <-done:
		// revokeCount is at least 3.
	}
	for uri, ok := range revokedAuthz {
		if !ok {
			t.Errorf("%q authorization was not revoked", uri)
		}
	}
}

func TestHTTPHandlerDefaultFallback(t *testing.T) {
	tt := []struct {
		method, url  string
		wantCode     int
		wantLocation string
	}{
		{"GET", "http://example.org", 302, "https://example.org/"},
		{"GET", "http://example.org/foo", 302, "https://example.org/foo"},
		{"GET", "http://example.org/foo/bar/", 302, "https://example.org/foo/bar/"},
		{"GET", "http://example.org/?a=b", 302, "https://example.org/?a=b"},
		{"GET", "http://example.org/foo?a=b", 302, "https://example.org/foo?a=b"},
		{"GET", "http://example.org:80/foo?a=b", 302, "https://example.org:443/foo?a=b"},
		{"GET", "http://example.org:80/foo%20bar", 302, "https://example.org:443/foo%20bar"},
		{"GET", "http://[2602:d1:xxxx::c60a]:1234", 302, "https://[2602:d1:xxxx::c60a]:443/"},
		{"GET", "http://[2602:d1:xxxx::c60a]", 302, "https://[2602:d1:xxxx::c60a]/"},
		{"GET", "http://[2602:d1:xxxx::c60a]/foo?a=b", 302, "https://[2602:d1:xxxx::c60a]/foo?a=b"},
		{"HEAD", "http://example.org", 302, "https://example.org/"},
		{"HEAD", "http://example.org/foo", 302, "https://example.org/foo"},
		{"HEAD", "http://example.org/foo/bar/", 302, "https://example.org/foo/bar/"},
		{"HEAD", "http://example.org/?a=b", 302, "https://example.org/?a=b"},
		{"HEAD", "http://example.org/foo?a=b", 302, "https://example.org/foo?a=b"},
		{"POST", "http://example.org", 400, ""},
		{"PUT", "http://example.org", 400, ""},
		{"GET", "http://example.org/.well-known/acme-challenge/x", 404, ""},
	}
	var m Manager
	h := m.HTTPHandler(nil)
	for i, test := range tt {
		r := httptest.NewRequest(test.method, test.url, nil)
		w := httptest.NewRecorder()
		h.ServeHTTP(w, r)
		if w.Code != test.wantCode {
			t.Errorf("%d: w.Code = %d; want %d", i, w.Code, test.wantCode)
			t.Errorf("%d: body: %s", i, w.Body.Bytes())
		}
		if v := w.Header().Get("Location"); v != test.wantLocation {
			t.Errorf("%d: Location = %q; want %q", i, v, test.wantLocation)
		}
	}
}

func TestAccountKeyCache(t *testing.T) {
	m := Manager{Cache: newMemCache(t)}
	ctx := context.Background()
	k1, err := m.accountKey(ctx)
	if err != nil {
		t.Fatal(err)
	}
	k2, err := m.accountKey(ctx)
	if err != nil {
		t.Fatal(err)
	}
	if !reflect.DeepEqual(k1, k2) {
		t.Errorf("account keys don't match: k1 = %#v; k2 = %#v", k1, k2)
	}
}

func TestCache(t *testing.T) {
	ecdsaKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
	if err != nil {
		t.Fatal(err)
	}
	cert, err := dummyCert(ecdsaKey.Public(), exampleDomain)
	if err != nil {
		t.Fatal(err)
	}
	ecdsaCert := &tls.Certificate{
		Certificate: [][]byte{cert},
		PrivateKey:  ecdsaKey,
	}

	rsaKey, err := rsa.GenerateKey(rand.Reader, 512)
	if err != nil {
		t.Fatal(err)
	}
	cert, err = dummyCert(rsaKey.Public(), exampleDomain)
	if err != nil {
		t.Fatal(err)
	}
	rsaCert := &tls.Certificate{
		Certificate: [][]byte{cert},
		PrivateKey:  rsaKey,
	}

	man := &Manager{Cache: newMemCache(t)}
	defer man.stopRenew()
	ctx := context.Background()

	if err := man.cachePut(ctx, exampleCertKey, ecdsaCert); err != nil {
		t.Fatalf("man.cachePut: %v", err)
	}
	if err := man.cachePut(ctx, exampleCertKeyRSA, rsaCert); err != nil {
		t.Fatalf("man.cachePut: %v", err)
	}

	res, err := man.cacheGet(ctx, exampleCertKey)
	if err != nil {
		t.Fatalf("man.cacheGet: %v", err)
	}
	if res == nil || !bytes.Equal(res.Certificate[0], ecdsaCert.Certificate[0]) {
		t.Errorf("man.cacheGet = %+v; want %+v", res, ecdsaCert)
	}

	res, err = man.cacheGet(ctx, exampleCertKeyRSA)
	if err != nil {
		t.Fatalf("man.cacheGet: %v", err)
	}
	if res == nil || !bytes.Equal(res.Certificate[0], rsaCert.Certificate[0]) {
		t.Errorf("man.cacheGet = %+v; want %+v", res, rsaCert)
	}
}

func TestHostWhitelist(t *testing.T) {
	policy := HostWhitelist("example.com", "example.org", "*.example.net")
	tt := []struct {
		host  string
		allow bool
	}{
		{"example.com", true},
		{"example.org", true},
		{"one.example.com", false},
		{"two.example.org", false},
		{"three.example.net", false},
		{"dummy", false},
	}
	for i, test := range tt {
		err := policy(nil, test.host)
		if err != nil && test.allow {
			t.Errorf("%d: policy(%q): %v; want nil", i, test.host, err)
		}
		if err == nil && !test.allow {
			t.Errorf("%d: policy(%q): nil; want an error", i, test.host)
		}
	}
}

func TestValidCert(t *testing.T) {
	key1, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
	if err != nil {
		t.Fatal(err)
	}
	key2, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
	if err != nil {
		t.Fatal(err)
	}
	key3, err := rsa.GenerateKey(rand.Reader, 512)
	if err != nil {
		t.Fatal(err)
	}
	cert1, err := dummyCert(key1.Public(), "example.org")
	if err != nil {
		t.Fatal(err)
	}
	cert2, err := dummyCert(key2.Public(), "example.org")
	if err != nil {
		t.Fatal(err)
	}
	cert3, err := dummyCert(key3.Public(), "example.org")
	if err != nil {
		t.Fatal(err)
	}
	now := time.Now()
	early, err := dateDummyCert(key1.Public(), now.Add(time.Hour), now.Add(2*time.Hour), "example.org")
	if err != nil {
		t.Fatal(err)
	}
	expired, err := dateDummyCert(key1.Public(), now.Add(-2*time.Hour), now.Add(-time.Hour), "example.org")
	if err != nil {
		t.Fatal(err)
	}

	tt := []struct {
		ck   certKey
		key  crypto.Signer
		cert [][]byte
		ok   bool
	}{
		{certKey{domain: "example.org"}, key1, [][]byte{cert1}, true},
		{certKey{domain: "example.org", isRSA: true}, key3, [][]byte{cert3}, true},
		{certKey{domain: "example.org"}, key1, [][]byte{cert1, cert2, cert3}, true},
		{certKey{domain: "example.org"}, key1, [][]byte{cert1, {1}}, false},
		{certKey{domain: "example.org"}, key1, [][]byte{{1}}, false},
		{certKey{domain: "example.org"}, key1, [][]byte{cert2}, false},
		{certKey{domain: "example.org"}, key2, [][]byte{cert1}, false},
		{certKey{domain: "example.org"}, key1, [][]byte{cert3}, false},
		{certKey{domain: "example.org"}, key3, [][]byte{cert1}, false},
		{certKey{domain: "example.net"}, key1, [][]byte{cert1}, false},
		{certKey{domain: "example.org"}, key1, [][]byte{early}, false},
		{certKey{domain: "example.org"}, key1, [][]byte{expired}, false},
		{certKey{domain: "example.org", isRSA: true}, key1, [][]byte{cert1}, false},
		{certKey{domain: "example.org"}, key3, [][]byte{cert3}, false},
	}
	for i, test := range tt {
		leaf, err := validCert(test.ck, test.cert, test.key, now)
		if err != nil && test.ok {
			t.Errorf("%d: err = %v", i, err)
		}
		if err == nil && !test.ok {
			t.Errorf("%d: err is nil", i)
		}
		if err == nil && test.ok && leaf == nil {
			t.Errorf("%d: leaf is nil", i)
		}
	}
}

type cacheGetFunc func(ctx context.Context, key string) ([]byte, error)

func (f cacheGetFunc) Get(ctx context.Context, key string) ([]byte, error) {
	return f(ctx, key)
}

func (f cacheGetFunc) Put(ctx context.Context, key string, data []byte) error {
	return fmt.Errorf("unsupported Put of %q = %q", key, data)
}

func (f cacheGetFunc) Delete(ctx context.Context, key string) error {
	return fmt.Errorf("unsupported Delete of %q", key)
}

func TestManagerGetCertificateBogusSNI(t *testing.T) {
	m := Manager{
		Prompt: AcceptTOS,
		Cache: cacheGetFunc(func(ctx context.Context, key string) ([]byte, error) {
			return nil, fmt.Errorf("cache.Get of %s", key)
		}),
	}
	tests := []struct {
		name    string
		wantErr string
	}{
		{"foo.com", "cache.Get of foo.com"},
		{"foo.com.", "cache.Get of foo.com"},
		{`a\b.com`, "acme/autocert: server name contains invalid character"},
		{`a/b.com`, "acme/autocert: server name contains invalid character"},
		{"", "acme/autocert: missing server name"},
		{"foo", "acme/autocert: server name component count invalid"},
		{".foo", "acme/autocert: server name component count invalid"},
		{"foo.", "acme/autocert: server name component count invalid"},
		{"fo.o", "cache.Get of fo.o"},
	}
	for _, tt := range tests {
		_, err := m.GetCertificate(clientHelloInfo(tt.name, true))
		got := fmt.Sprint(err)
		if got != tt.wantErr {
			t.Errorf("GetCertificate(SNI = %q) = %q; want %q", tt.name, got, tt.wantErr)
		}
	}
}

func TestCertRequest(t *testing.T) {
	key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
	if err != nil {
		t.Fatal(err)
	}
	// An extension from RFC7633. Any will do.
	ext := pkix.Extension{
		Id:    asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1},
		Value: []byte("dummy"),
	}
	b, err := certRequest(key, "example.org", []pkix.Extension{ext}, "san.example.org")
	if err != nil {
		t.Fatalf("certRequest: %v", err)
	}
	r, err := x509.ParseCertificateRequest(b)
	if err != nil {
		t.Fatalf("ParseCertificateRequest: %v", err)
	}
	var found bool
	for _, v := range r.Extensions {
		if v.Id.Equal(ext.Id) {
			found = true
			break
		}
	}
	if !found {
		t.Errorf("want %v in Extensions: %v", ext, r.Extensions)
	}
}

func TestSupportsECDSA(t *testing.T) {
	tests := []struct {
		CipherSuites     []uint16
		SignatureSchemes []tls.SignatureScheme
		SupportedCurves  []tls.CurveID
		ecdsaOk          bool
	}{
		{[]uint16{
			tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
		}, nil, nil, false},
		{[]uint16{
			tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
		}, nil, nil, true},

		// SignatureSchemes limits, not extends, CipherSuites
		{[]uint16{
			tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
		}, []tls.SignatureScheme{
			tls.PKCS1WithSHA256, tls.ECDSAWithP256AndSHA256,
		}, nil, false},
		{[]uint16{
			tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
		}, []tls.SignatureScheme{
			tls.PKCS1WithSHA256,
		}, nil, false},
		{[]uint16{
			tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
		}, []tls.SignatureScheme{
			tls.PKCS1WithSHA256, tls.ECDSAWithP256AndSHA256,
		}, nil, true},

		{[]uint16{
			tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
		}, []tls.SignatureScheme{
			tls.PKCS1WithSHA256, tls.ECDSAWithP256AndSHA256,
		}, []tls.CurveID{
			tls.CurveP521,
		}, false},
		{[]uint16{
			tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
		}, []tls.SignatureScheme{
			tls.PKCS1WithSHA256, tls.ECDSAWithP256AndSHA256,
		}, []tls.CurveID{
			tls.CurveP256,
			tls.CurveP521,
		}, true},
	}
	for i, tt := range tests {
		result := supportsECDSA(&tls.ClientHelloInfo{
			CipherSuites:     tt.CipherSuites,
			SignatureSchemes: tt.SignatureSchemes,
			SupportedCurves:  tt.SupportedCurves,
		})
		if result != tt.ecdsaOk {
			t.Errorf("%d: supportsECDSA = %v; want %v", i, result, tt.ecdsaOk)
		}
	}
}

// TODO: add same end-to-end for http-01 challenge type.
func TestEndToEnd(t *testing.T) {
	const domain = "example.org"

	// ACME CA server
	ca := acmetest.NewCAServer([]string{"tls-alpn-01"}, []string{domain})
	defer ca.Close()

	// User dummy server.
	m := &Manager{
		Prompt: AcceptTOS,
		Client: &acme.Client{DirectoryURL: ca.URL},
	}
	us := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("OK"))
	}))
	us.TLS = &tls.Config{
		NextProtos: []string{"http/1.1", acme.ALPNProto},
		GetCertificate: func(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
			cert, err := m.GetCertificate(hello)
			if err != nil {
				t.Errorf("m.GetCertificate: %v", err)
			}
			return cert, err
		},
	}
	us.StartTLS()
	defer us.Close()
	// In TLS-ALPN challenge verification, CA connects to the domain:443 in question.
	// Because the domain won't resolve in tests, we need to tell the CA
	// where to dial to instead.
	ca.Resolve(domain, strings.TrimPrefix(us.URL, "https://"))

	// A client visiting user dummy server.
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{
			RootCAs:    ca.Roots,
			ServerName: domain,
		},
	}
	client := &http.Client{Transport: tr}
	res, err := client.Get(us.URL)
	if err != nil {
		t.Logf("CA errors: %v", ca.Errors())
		t.Fatal(err)
	}
	defer res.Body.Close()
	b, err := ioutil.ReadAll(res.Body)
	if err != nil {
		t.Fatal(err)
	}
	if v := string(b); v != "OK" {
		t.Errorf("user server response: %q; want 'OK'", v)
	}
}
