// Copyright 2015 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 acme

import (
	"bytes"
	"context"
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/base64"
	"encoding/hex"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"math/big"
	"net/http"
	"net/http/httptest"
	"reflect"
	"testing"
	"time"
)

// newTestClient creates a client with a non-nil Directory so that it skips
// the discovery which is otherwise done on the first call of almost every
// exported method.
func newTestClient() *Client {
	return &Client{
		Key: testKeyEC,
		dir: &Directory{}, // skip discovery
	}
}

// Decodes a JWS-encoded request and unmarshals the decoded JSON into a provided
// interface.
func decodeJWSRequest(t *testing.T, v interface{}, r io.Reader) {
	// Decode request
	var req struct{ Payload string }
	if err := json.NewDecoder(r).Decode(&req); err != nil {
		t.Fatal(err)
	}
	payload, err := base64.RawURLEncoding.DecodeString(req.Payload)
	if err != nil {
		t.Fatal(err)
	}
	err = json.Unmarshal(payload, v)
	if err != nil {
		t.Fatal(err)
	}
}

type jwsHead struct {
	Alg   string
	Nonce string
	URL   string            `json:"url"`
	KID   string            `json:"kid"`
	JWK   map[string]string `json:"jwk"`
}

func decodeJWSHead(r io.Reader) (*jwsHead, error) {
	var req struct{ Protected string }
	if err := json.NewDecoder(r).Decode(&req); err != nil {
		return nil, err
	}
	b, err := base64.RawURLEncoding.DecodeString(req.Protected)
	if err != nil {
		return nil, err
	}
	var head jwsHead
	if err := json.Unmarshal(b, &head); err != nil {
		return nil, err
	}
	return &head, nil
}

func TestRegisterWithoutKey(t *testing.T) {
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.Method == "HEAD" {
			w.Header().Set("Replay-Nonce", "test-nonce")
			return
		}
		w.WriteHeader(http.StatusCreated)
		fmt.Fprint(w, `{}`)
	}))
	defer ts.Close()
	// First verify that using a complete client results in success.
	c := Client{
		Key:          testKeyEC,
		DirectoryURL: ts.URL,
		dir:          &Directory{RegURL: ts.URL},
	}
	if _, err := c.Register(context.Background(), &Account{}, AcceptTOS); err != nil {
		t.Fatalf("c.Register() = %v; want success with a complete test client", err)
	}
	c.Key = nil
	if _, err := c.Register(context.Background(), &Account{}, AcceptTOS); err == nil {
		t.Error("c.Register() from client without key succeeded, wanted error")
	}
}

func TestAuthorize(t *testing.T) {
	tt := []struct{ typ, value string }{
		{"dns", "example.com"},
		{"ip", "1.2.3.4"},
	}
	for _, test := range tt {
		t.Run(test.typ, func(t *testing.T) {
			ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
				if r.Method == "HEAD" {
					w.Header().Set("Replay-Nonce", "test-nonce")
					return
				}
				if r.Method != "POST" {
					t.Errorf("r.Method = %q; want POST", r.Method)
				}

				var j struct {
					Resource   string
					Identifier struct {
						Type  string
						Value string
					}
				}
				decodeJWSRequest(t, &j, r.Body)

				// Test request
				if j.Resource != "new-authz" {
					t.Errorf("j.Resource = %q; want new-authz", j.Resource)
				}
				if j.Identifier.Type != test.typ {
					t.Errorf("j.Identifier.Type = %q; want %q", j.Identifier.Type, test.typ)
				}
				if j.Identifier.Value != test.value {
					t.Errorf("j.Identifier.Value = %q; want %q", j.Identifier.Value, test.value)
				}

				w.Header().Set("Location", "https://ca.tld/acme/auth/1")
				w.WriteHeader(http.StatusCreated)
				fmt.Fprintf(w, `{
					"identifier": {"type":%q,"value":%q},
					"status":"pending",
					"challenges":[
						{
							"type":"http-01",
							"status":"pending",
							"uri":"https://ca.tld/acme/challenge/publickey/id1",
							"token":"token1"
						},
						{
							"type":"tls-sni-01",
							"status":"pending",
							"uri":"https://ca.tld/acme/challenge/publickey/id2",
							"token":"token2"
						}
					],
					"combinations":[[0],[1]]
				}`, test.typ, test.value)
			}))
			defer ts.Close()

			var (
				auth *Authorization
				err  error
			)
			cl := Client{
				Key:          testKeyEC,
				DirectoryURL: ts.URL,
				dir:          &Directory{AuthzURL: ts.URL},
			}
			switch test.typ {
			case "dns":
				auth, err = cl.Authorize(context.Background(), test.value)
			case "ip":
				auth, err = cl.AuthorizeIP(context.Background(), test.value)
			default:
				t.Fatalf("unknown identifier type: %q", test.typ)
			}
			if err != nil {
				t.Fatal(err)
			}

			if auth.URI != "https://ca.tld/acme/auth/1" {
				t.Errorf("URI = %q; want https://ca.tld/acme/auth/1", auth.URI)
			}
			if auth.Status != "pending" {
				t.Errorf("Status = %q; want pending", auth.Status)
			}
			if auth.Identifier.Type != test.typ {
				t.Errorf("Identifier.Type = %q; want %q", auth.Identifier.Type, test.typ)
			}
			if auth.Identifier.Value != test.value {
				t.Errorf("Identifier.Value = %q; want %q", auth.Identifier.Value, test.value)
			}

			if n := len(auth.Challenges); n != 2 {
				t.Fatalf("len(auth.Challenges) = %d; want 2", n)
			}

			c := auth.Challenges[0]
			if c.Type != "http-01" {
				t.Errorf("c.Type = %q; want http-01", c.Type)
			}
			if c.URI != "https://ca.tld/acme/challenge/publickey/id1" {
				t.Errorf("c.URI = %q; want https://ca.tld/acme/challenge/publickey/id1", c.URI)
			}
			if c.Token != "token1" {
				t.Errorf("c.Token = %q; want token1", c.Token)
			}

			c = auth.Challenges[1]
			if c.Type != "tls-sni-01" {
				t.Errorf("c.Type = %q; want tls-sni-01", c.Type)
			}
			if c.URI != "https://ca.tld/acme/challenge/publickey/id2" {
				t.Errorf("c.URI = %q; want https://ca.tld/acme/challenge/publickey/id2", c.URI)
			}
			if c.Token != "token2" {
				t.Errorf("c.Token = %q; want token2", c.Token)
			}

			combs := [][]int{{0}, {1}}
			if !reflect.DeepEqual(auth.Combinations, combs) {
				t.Errorf("auth.Combinations: %+v\nwant: %+v\n", auth.Combinations, combs)
			}

		})
	}
}

func TestAuthorizeValid(t *testing.T) {
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.Method == "HEAD" {
			w.Header().Set("Replay-Nonce", "nonce")
			return
		}
		w.WriteHeader(http.StatusCreated)
		w.Write([]byte(`{"status":"valid"}`))
	}))
	defer ts.Close()
	client := Client{
		Key:          testKey,
		DirectoryURL: ts.URL,
		dir:          &Directory{AuthzURL: ts.URL},
	}
	_, err := client.Authorize(context.Background(), "example.com")
	if err != nil {
		t.Errorf("err = %v", err)
	}
}

func TestAuthorizeUnsupported(t *testing.T) {
	const (
		nonce       = "https://example.com/acme/new-nonce"
		reg         = "https://example.com/acme/new-acct"
		order       = "https://example.com/acme/new-order"
		revoke      = "https://example.com/acme/revoke-cert"
		keychange   = "https://example.com/acme/key-change"
		metaTerms   = "https://example.com/acme/terms/2017-5-30"
		metaWebsite = "https://www.example.com/"
		metaCAA     = "example.com"
	)
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Replay-Nonce", "nonce")
		if r.Method == http.MethodHead {
			return
		}
		switch r.URL.Path {
		case "/": // Directory
			w.Header().Set("Content-Type", "application/json")
			fmt.Fprintf(w, `{
                "newNonce": %q,
                "newAccount": %q,
                "newOrder": %q,
                "revokeCert": %q,
                "keyChange": %q,
                "meta": {
                    "termsOfService": %q,
                    "website": %q,
                    "caaIdentities": [%q],
                    "externalAccountRequired": true
                }
            }`, nonce, reg, order, revoke, keychange, metaTerms, metaWebsite, metaCAA)
			w.WriteHeader(http.StatusOK)
		case "/acme/new-authz":
			w.WriteHeader(http.StatusBadRequest)
		}
	}))
	defer ts.Close()
	client := &Client{Key: testKey, DirectoryURL: ts.URL}
	dir, err := client.Discover(context.Background())
	if err != nil {
		t.Fatal(err)
	}
	if dir.AuthzURL != "" {
		t.Fatalf("expected AuthzURL to be empty, got %q", dir.AuthzURL)
	}
	if _, err := client.Authorize(context.Background(), "example.com"); !errors.Is(err, errPreAuthorizationNotSupported) {
		t.Errorf("expected err to indicate pre-authorization is unsupported, got %+v", err)
	}
}

func TestWaitAuthorization(t *testing.T) {
	t.Run("wait loop", func(t *testing.T) {
		var count int
		authz, err := runWaitAuthorization(context.Background(), t, func(w http.ResponseWriter, r *http.Request) {
			count++
			w.Header().Set("Retry-After", "0")
			if count > 1 {
				fmt.Fprintf(w, `{"status":"valid"}`)
				return
			}
			fmt.Fprintf(w, `{"status":"pending"}`)
		})
		if err != nil {
			t.Fatalf("non-nil error: %v", err)
		}
		if authz == nil {
			t.Fatal("authz is nil")
		}
	})
	t.Run("invalid status", func(t *testing.T) {
		_, err := runWaitAuthorization(context.Background(), t, func(w http.ResponseWriter, r *http.Request) {
			fmt.Fprintf(w, `{"status":"invalid"}`)
		})
		if _, ok := err.(*AuthorizationError); !ok {
			t.Errorf("err is %v (%T); want non-nil *AuthorizationError", err, err)
		}
	})
	t.Run("invalid status with error returns the authorization error", func(t *testing.T) {
		_, err := runWaitAuthorization(context.Background(), t, func(w http.ResponseWriter, r *http.Request) {
			fmt.Fprintf(w, `{
				"type": "dns-01",
				"status": "invalid",
				"error": {
				  "type": "urn:ietf:params:acme:error:caa",
				  "detail": "CAA record for <domain> prevents issuance",
				  "status": 403
				},
				"url": "https://acme-v02.api.letsencrypt.org/acme/chall-v3/xxx/xxx",
				"token": "xxx",
				"validationRecord": [
				  {
					"hostname": "<domain>"
				  }
				]
			  }`)
		})

		want := &AuthorizationError{
			Errors: []error{
				(&wireError{
					Status: 403,
					Type:   "urn:ietf:params:acme:error:caa",
					Detail: "CAA record for <domain> prevents issuance",
				}).error(nil),
			},
		}

		_, ok := err.(*AuthorizationError)
		if !ok {
			t.Errorf("err is %T; want non-nil *AuthorizationError", err)
		}

		if err.Error() != want.Error() {
			t.Errorf("err is %v; want %v", err, want)
		}
	})
	t.Run("non-retriable error", func(t *testing.T) {
		const code = http.StatusBadRequest
		_, err := runWaitAuthorization(context.Background(), t, func(w http.ResponseWriter, r *http.Request) {
			w.WriteHeader(code)
		})
		res, ok := err.(*Error)
		if !ok {
			t.Fatalf("err is %v (%T); want a non-nil *Error", err, err)
		}
		if res.StatusCode != code {
			t.Errorf("res.StatusCode = %d; want %d", res.StatusCode, code)
		}
	})
	for _, code := range []int{http.StatusTooManyRequests, http.StatusInternalServerError} {
		t.Run(fmt.Sprintf("retriable %d error", code), func(t *testing.T) {
			var count int
			authz, err := runWaitAuthorization(context.Background(), t, func(w http.ResponseWriter, r *http.Request) {
				count++
				w.Header().Set("Retry-After", "0")
				if count > 1 {
					fmt.Fprintf(w, `{"status":"valid"}`)
					return
				}
				w.WriteHeader(code)
			})
			if err != nil {
				t.Fatalf("non-nil error: %v", err)
			}
			if authz == nil {
				t.Fatal("authz is nil")
			}
		})
	}
	t.Run("context cancel", func(t *testing.T) {
		ctx, cancel := context.WithCancel(context.Background())
		defer cancel()
		_, err := runWaitAuthorization(ctx, t, func(w http.ResponseWriter, r *http.Request) {
			w.Header().Set("Retry-After", "60")
			fmt.Fprintf(w, `{"status":"pending"}`)
			time.AfterFunc(1*time.Millisecond, cancel)
		})
		if err == nil {
			t.Error("err is nil")
		}
	})
}

func runWaitAuthorization(ctx context.Context, t *testing.T, h http.HandlerFunc) (*Authorization, error) {
	t.Helper()
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Replay-Nonce", fmt.Sprintf("bad-test-nonce-%v", time.Now().UnixNano()))
		h(w, r)
	}))
	defer ts.Close()

	client := &Client{
		Key:          testKey,
		DirectoryURL: ts.URL,
		dir:          &Directory{},
		KID:          "some-key-id", // set to avoid lookup attempt
	}
	return client.WaitAuthorization(ctx, ts.URL)
}

func TestRevokeAuthorization(t *testing.T) {
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.Method == "HEAD" {
			w.Header().Set("Replay-Nonce", "nonce")
			return
		}
		switch r.URL.Path {
		case "/1":
			var req struct {
				Resource string
				Status   string
				Delete   bool
			}
			decodeJWSRequest(t, &req, r.Body)
			if req.Resource != "authz" {
				t.Errorf("req.Resource = %q; want authz", req.Resource)
			}
			if req.Status != "deactivated" {
				t.Errorf("req.Status = %q; want deactivated", req.Status)
			}
			if !req.Delete {
				t.Errorf("req.Delete is false")
			}
		case "/2":
			w.WriteHeader(http.StatusBadRequest)
		}
	}))
	defer ts.Close()
	client := &Client{
		Key:          testKey,
		DirectoryURL: ts.URL,       // don't dial outside of localhost
		dir:          &Directory{}, // don't do discovery
	}
	ctx := context.Background()
	if err := client.RevokeAuthorization(ctx, ts.URL+"/1"); err != nil {
		t.Errorf("err = %v", err)
	}
	if client.RevokeAuthorization(ctx, ts.URL+"/2") == nil {
		t.Error("nil error")
	}
}

func TestFetchCertCancel(t *testing.T) {
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		<-r.Context().Done()
		w.Header().Set("Retry-After", "0")
		w.WriteHeader(http.StatusBadRequest)
	}))
	defer ts.Close()
	ctx, cancel := context.WithCancel(context.Background())
	done := make(chan struct{})
	var err error
	go func() {
		cl := newTestClient()
		_, err = cl.FetchCert(ctx, ts.URL, false)
		close(done)
	}()
	cancel()
	<-done
	if err != context.Canceled {
		t.Errorf("err = %v; want %v", err, context.Canceled)
	}
}

func TestFetchCertDepth(t *testing.T) {
	var count byte
	var ts *httptest.Server
	ts = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		count++
		if count > maxChainLen+1 {
			t.Errorf("count = %d; want at most %d", count, maxChainLen+1)
			w.WriteHeader(http.StatusInternalServerError)
		}
		w.Header().Set("Link", fmt.Sprintf("<%s>;rel=up", ts.URL))
		w.Write([]byte{count})
	}))
	defer ts.Close()
	cl := newTestClient()
	_, err := cl.FetchCert(context.Background(), ts.URL, true)
	if err == nil {
		t.Errorf("err is nil")
	}
}

func TestFetchCertBreadth(t *testing.T) {
	var ts *httptest.Server
	ts = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		for i := 0; i < maxChainLen+1; i++ {
			w.Header().Add("Link", fmt.Sprintf("<%s>;rel=up", ts.URL))
		}
		w.Write([]byte{1})
	}))
	defer ts.Close()
	cl := newTestClient()
	_, err := cl.FetchCert(context.Background(), ts.URL, true)
	if err == nil {
		t.Errorf("err is nil")
	}
}

func TestFetchCertSize(t *testing.T) {
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		b := bytes.Repeat([]byte{1}, maxCertSize+1)
		w.Write(b)
	}))
	defer ts.Close()
	cl := newTestClient()
	_, err := cl.FetchCert(context.Background(), ts.URL, false)
	if err == nil {
		t.Errorf("err is nil")
	}
}

func TestNonce_add(t *testing.T) {
	var c Client
	c.addNonce(http.Header{"Replay-Nonce": {"nonce"}})
	c.addNonce(http.Header{"Replay-Nonce": {}})
	c.addNonce(http.Header{"Replay-Nonce": {"nonce"}})

	nonces := map[string]struct{}{"nonce": {}}
	if !reflect.DeepEqual(c.nonces, nonces) {
		t.Errorf("c.nonces = %q; want %q", c.nonces, nonces)
	}
}

func TestNonce_addMax(t *testing.T) {
	c := &Client{nonces: make(map[string]struct{})}
	for i := 0; i < maxNonces; i++ {
		c.nonces[fmt.Sprintf("%d", i)] = struct{}{}
	}
	c.addNonce(http.Header{"Replay-Nonce": {"nonce"}})
	if n := len(c.nonces); n != maxNonces {
		t.Errorf("len(c.nonces) = %d; want %d", n, maxNonces)
	}
}

func TestNonce_fetch(t *testing.T) {
	tests := []struct {
		code  int
		nonce string
	}{
		{http.StatusOK, "nonce1"},
		{http.StatusBadRequest, "nonce2"},
		{http.StatusOK, ""},
	}
	var i int
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.Method != "HEAD" {
			t.Errorf("%d: r.Method = %q; want HEAD", i, r.Method)
		}
		w.Header().Set("Replay-Nonce", tests[i].nonce)
		w.WriteHeader(tests[i].code)
	}))
	defer ts.Close()
	for ; i < len(tests); i++ {
		test := tests[i]
		c := newTestClient()
		n, err := c.fetchNonce(context.Background(), ts.URL)
		if n != test.nonce {
			t.Errorf("%d: n=%q; want %q", i, n, test.nonce)
		}
		switch {
		case err == nil && test.nonce == "":
			t.Errorf("%d: n=%q, err=%v; want non-nil error", i, n, err)
		case err != nil && test.nonce != "":
			t.Errorf("%d: n=%q, err=%v; want %q", i, n, err, test.nonce)
		}
	}
}

func TestNonce_fetchError(t *testing.T) {
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(http.StatusTooManyRequests)
	}))
	defer ts.Close()
	c := newTestClient()
	_, err := c.fetchNonce(context.Background(), ts.URL)
	e, ok := err.(*Error)
	if !ok {
		t.Fatalf("err is %T; want *Error", err)
	}
	if e.StatusCode != http.StatusTooManyRequests {
		t.Errorf("e.StatusCode = %d; want %d", e.StatusCode, http.StatusTooManyRequests)
	}
}

func TestNonce_popWhenEmpty(t *testing.T) {
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.Method != "HEAD" {
			t.Errorf("r.Method = %q; want HEAD", r.Method)
		}
		switch r.URL.Path {
		case "/dir-with-nonce":
			w.Header().Set("Replay-Nonce", "dirnonce")
		case "/new-nonce":
			w.Header().Set("Replay-Nonce", "newnonce")
		case "/dir-no-nonce", "/empty":
			// No nonce in the header.
		default:
			t.Errorf("Unknown URL: %s", r.URL)
		}
	}))
	defer ts.Close()
	ctx := context.Background()

	tt := []struct {
		dirURL, popURL, nonce string
		wantOK                bool
	}{
		{ts.URL + "/dir-with-nonce", ts.URL + "/new-nonce", "dirnonce", true},
		{ts.URL + "/dir-no-nonce", ts.URL + "/new-nonce", "newnonce", true},
		{ts.URL + "/dir-no-nonce", ts.URL + "/empty", "", false},
	}
	for _, test := range tt {
		t.Run(fmt.Sprintf("nonce:%s wantOK:%v", test.nonce, test.wantOK), func(t *testing.T) {
			c := Client{DirectoryURL: test.dirURL}
			v, err := c.popNonce(ctx, test.popURL)
			if !test.wantOK {
				if err == nil {
					t.Fatalf("c.popNonce(%q) returned nil error", test.popURL)
				}
				return
			}
			if err != nil {
				t.Fatalf("c.popNonce(%q): %v", test.popURL, err)
			}
			if v != test.nonce {
				t.Errorf("c.popNonce(%q) = %q; want %q", test.popURL, v, test.nonce)
			}
		})
	}
}

func TestLinkHeader(t *testing.T) {
	h := http.Header{"Link": {
		`<https://example.com/acme/new-authz>;rel="next"`,
		`<https://example.com/acme/recover-reg>; rel=recover`,
		`<https://example.com/acme/terms>; foo=bar; rel="terms-of-service"`,
		`<dup>;rel="next"`,
	}}
	tests := []struct {
		rel string
		out []string
	}{
		{"next", []string{"https://example.com/acme/new-authz", "dup"}},
		{"recover", []string{"https://example.com/acme/recover-reg"}},
		{"terms-of-service", []string{"https://example.com/acme/terms"}},
		{"empty", nil},
	}
	for i, test := range tests {
		if v := linkHeader(h, test.rel); !reflect.DeepEqual(v, test.out) {
			t.Errorf("%d: linkHeader(%q): %v; want %v", i, test.rel, v, test.out)
		}
	}
}

func TestTLSALPN01ChallengeCert(t *testing.T) {
	const (
		token   = "evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ-PCt92wr-oA"
		keyAuth = "evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ-PCt92wr-oA." + testKeyECThumbprint
		// echo -n <token.testKeyECThumbprint> | shasum -a 256
		h      = "0420dbbd5eefe7b4d06eb9d1d9f5acb4c7cda27d320e4b30332f0b6cb441734ad7b0"
		domain = "example.com"
	)

	extValue, err := hex.DecodeString(h)
	if err != nil {
		t.Fatal(err)
	}

	tlscert, err := newTestClient().TLSALPN01ChallengeCert(token, domain)
	if err != nil {
		t.Fatal(err)
	}

	if n := len(tlscert.Certificate); n != 1 {
		t.Fatalf("len(tlscert.Certificate) = %d; want 1", n)
	}
	cert, err := x509.ParseCertificate(tlscert.Certificate[0])
	if err != nil {
		t.Fatal(err)
	}
	names := []string{domain}
	if !reflect.DeepEqual(cert.DNSNames, names) {
		t.Fatalf("cert.DNSNames = %v;\nwant %v", cert.DNSNames, names)
	}
	if cn := cert.Subject.CommonName; cn != domain {
		t.Errorf("CommonName = %q; want %q", cn, domain)
	}
	acmeExts := []pkix.Extension{}
	for _, ext := range cert.Extensions {
		if idPeACMEIdentifier.Equal(ext.Id) {
			acmeExts = append(acmeExts, ext)
		}
	}
	if len(acmeExts) != 1 {
		t.Errorf("acmeExts = %v; want exactly one", acmeExts)
	}
	if !acmeExts[0].Critical {
		t.Errorf("acmeExt.Critical = %v; want true", acmeExts[0].Critical)
	}
	if bytes.Compare(acmeExts[0].Value, extValue) != 0 {
		t.Errorf("acmeExt.Value = %v; want %v", acmeExts[0].Value, extValue)
	}

}

func TestTLSChallengeCertOpt(t *testing.T) {
	key, err := rsa.GenerateKey(rand.Reader, 1024)
	if err != nil {
		t.Fatal(err)
	}
	domain := "example.com"
	tmpl := &x509.Certificate{
		SerialNumber: big.NewInt(2),
		Subject:      pkix.Name{Organization: []string{"Test"}},
		DNSNames:     []string{"should-be-overwritten"},
	}
	opts := []CertOption{WithKey(key), WithTemplate(tmpl)}

	client := newTestClient()
	cert, err := client.TLSALPN01ChallengeCert("token", domain, opts...)
	if err != nil {
		t.Fatal(err)
	}

	// verify generated cert private key
	tlskey, ok := cert.PrivateKey.(*rsa.PrivateKey)
	if !ok {
		t.Fatalf("tlscert.PrivateKey is %T; want *rsa.PrivateKey", cert.PrivateKey)
	}
	if tlskey.D.Cmp(key.D) != 0 {
		t.Errorf("tlskey.D = %v; want %v", tlskey.D, key.D)
	}
	// verify generated cert public key
	x509Cert, err := x509.ParseCertificate(cert.Certificate[0])
	if err != nil {
		t.Fatal(err)
	}
	tlspub, ok := x509Cert.PublicKey.(*rsa.PublicKey)
	if !ok {
		t.Fatalf("x509Cert.PublicKey is %T; want *rsa.PublicKey", x509Cert.PublicKey)
	}
	if tlspub.N.Cmp(key.N) != 0 {
		t.Errorf("tlspub.N = %v; want %v", tlspub.N, key.N)
	}
	// verify template option
	sn := big.NewInt(2)
	if x509Cert.SerialNumber.Cmp(sn) != 0 {
		t.Errorf("SerialNumber = %v; want %v", x509Cert.SerialNumber, sn)
	}
	org := []string{"Test"}
	if !reflect.DeepEqual(x509Cert.Subject.Organization, org) {
		t.Errorf("Subject.Organization = %+v; want %+v", x509Cert.Subject.Organization, org)
	}
	for _, v := range x509Cert.DNSNames {
		if v != domain {
			t.Errorf("invalid DNSNames element: %q", v)
		}
	}
}

func TestHTTP01Challenge(t *testing.T) {
	const (
		token = "xxx"
		// thumbprint is precomputed for testKeyEC in jws_test.go
		value   = token + "." + testKeyECThumbprint
		urlpath = "/.well-known/acme-challenge/" + token
	)
	client := newTestClient()
	val, err := client.HTTP01ChallengeResponse(token)
	if err != nil {
		t.Fatal(err)
	}
	if val != value {
		t.Errorf("val = %q; want %q", val, value)
	}
	if path := client.HTTP01ChallengePath(token); path != urlpath {
		t.Errorf("path = %q; want %q", path, urlpath)
	}
}

func TestDNS01ChallengeRecord(t *testing.T) {
	// echo -n xxx.<testKeyECThumbprint> | \
	//      openssl dgst -binary -sha256 | \
	//      base64 | tr -d '=' | tr '/+' '_-'
	const value = "8DERMexQ5VcdJ_prpPiA0mVdp7imgbCgjsG4SqqNMIo"

	val, err := newTestClient().DNS01ChallengeRecord("xxx")
	if err != nil {
		t.Fatal(err)
	}
	if val != value {
		t.Errorf("val = %q; want %q", val, value)
	}
}
