// Copyright 2019 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/hmac"
	"crypto/rand"
	"crypto/sha256"
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/base64"
	"encoding/json"
	"encoding/pem"
	"errors"
	"fmt"
	"io/ioutil"
	"math/big"
	"net/http"
	"net/http/httptest"
	"reflect"
	"strings"
	"sync"
	"testing"
	"time"
)

// While contents of this file is pertinent only to RFC8555,
// it is complementary to the tests in the other _test.go files
// many of which are valid for both pre- and RFC8555.
// This will make it easier to clean up the tests once non-RFC compliant
// code is removed.

func TestRFC_Discover(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"
		authz       = "https://example.com/acme/new-authz"
		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("Content-Type", "application/json")
		fmt.Fprintf(w, `{
			"newNonce": %q,
			"newAccount": %q,
			"newOrder": %q,
			"newAuthz": %q,
			"revokeCert": %q,
			"keyChange": %q,
			"meta": {
				"termsOfService": %q,
				"website": %q,
				"caaIdentities": [%q],
				"externalAccountRequired": true
			}
		}`, nonce, reg, order, authz, revoke, keychange, metaTerms, metaWebsite, metaCAA)
	}))
	defer ts.Close()
	c := &Client{DirectoryURL: ts.URL}
	dir, err := c.Discover(context.Background())
	if err != nil {
		t.Fatal(err)
	}
	if dir.NonceURL != nonce {
		t.Errorf("dir.NonceURL = %q; want %q", dir.NonceURL, nonce)
	}
	if dir.RegURL != reg {
		t.Errorf("dir.RegURL = %q; want %q", dir.RegURL, reg)
	}
	if dir.OrderURL != order {
		t.Errorf("dir.OrderURL = %q; want %q", dir.OrderURL, order)
	}
	if dir.AuthzURL != authz {
		t.Errorf("dir.AuthzURL = %q; want %q", dir.AuthzURL, authz)
	}
	if dir.RevokeURL != revoke {
		t.Errorf("dir.RevokeURL = %q; want %q", dir.RevokeURL, revoke)
	}
	if dir.KeyChangeURL != keychange {
		t.Errorf("dir.KeyChangeURL = %q; want %q", dir.KeyChangeURL, keychange)
	}
	if dir.Terms != metaTerms {
		t.Errorf("dir.Terms = %q; want %q", dir.Terms, metaTerms)
	}
	if dir.Website != metaWebsite {
		t.Errorf("dir.Website = %q; want %q", dir.Website, metaWebsite)
	}
	if len(dir.CAA) == 0 || dir.CAA[0] != metaCAA {
		t.Errorf("dir.CAA = %q; want [%q]", dir.CAA, metaCAA)
	}
	if !dir.ExternalAccountRequired {
		t.Error("dir.Meta.ExternalAccountRequired is false")
	}
}

func TestRFC_popNonce(t *testing.T) {
	var count int
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// The Client uses only Directory.NonceURL when specified.
		// Expect no other URL paths.
		if r.URL.Path != "/new-nonce" {
			t.Errorf("r.URL.Path = %q; want /new-nonce", r.URL.Path)
		}
		if count > 0 {
			w.WriteHeader(http.StatusTooManyRequests)
			return
		}
		count++
		w.Header().Set("Replay-Nonce", "second")
	}))
	cl := &Client{
		DirectoryURL: ts.URL,
		dir:          &Directory{NonceURL: ts.URL + "/new-nonce"},
	}
	cl.addNonce(http.Header{"Replay-Nonce": {"first"}})

	for i, nonce := range []string{"first", "second"} {
		v, err := cl.popNonce(context.Background(), "")
		if err != nil {
			t.Errorf("%d: cl.popNonce: %v", i, err)
		}
		if v != nonce {
			t.Errorf("%d: cl.popNonce = %q; want %q", i, v, nonce)
		}
	}
	// No more nonces and server replies with an error past first nonce fetch.
	// Expected to fail.
	if _, err := cl.popNonce(context.Background(), ""); err == nil {
		t.Error("last cl.popNonce returned nil error")
	}
}

func TestRFC_postKID(t *testing.T) {
	var ts *httptest.Server
	ts = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		switch r.URL.Path {
		case "/new-nonce":
			w.Header().Set("Replay-Nonce", "nonce")
		case "/new-account":
			w.Header().Set("Location", "/account-1")
			w.Write([]byte(`{"status":"valid"}`))
		case "/post":
			b, _ := ioutil.ReadAll(r.Body) // check err later in decodeJWSxxx
			head, err := decodeJWSHead(bytes.NewReader(b))
			if err != nil {
				t.Errorf("decodeJWSHead: %v", err)
				return
			}
			if head.KID != "/account-1" {
				t.Errorf("head.KID = %q; want /account-1", head.KID)
			}
			if len(head.JWK) != 0 {
				t.Errorf("head.JWK = %q; want zero map", head.JWK)
			}
			if v := ts.URL + "/post"; head.URL != v {
				t.Errorf("head.URL = %q; want %q", head.URL, v)
			}

			var payload struct{ Msg string }
			decodeJWSRequest(t, &payload, bytes.NewReader(b))
			if payload.Msg != "ping" {
				t.Errorf("payload.Msg = %q; want ping", payload.Msg)
			}
			w.Write([]byte("pong"))
		default:
			t.Errorf("unhandled %s %s", r.Method, r.URL)
			w.WriteHeader(http.StatusBadRequest)
		}
	}))
	defer ts.Close()

	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	cl := &Client{
		Key:          testKey,
		DirectoryURL: ts.URL,
		dir: &Directory{
			NonceURL: ts.URL + "/new-nonce",
			RegURL:   ts.URL + "/new-account",
			OrderURL: "/force-rfc-mode",
		},
	}
	req := json.RawMessage(`{"msg":"ping"}`)
	res, err := cl.post(ctx, nil /* use kid */, ts.URL+"/post", req, wantStatus(http.StatusOK))
	if err != nil {
		t.Fatal(err)
	}
	defer res.Body.Close()
	b, _ := ioutil.ReadAll(res.Body) // don't care about err - just checking b
	if string(b) != "pong" {
		t.Errorf("res.Body = %q; want pong", b)
	}
}

// acmeServer simulates a subset of RFC8555 compliant CA.
//
// TODO: We also have x/crypto/acme/autocert/acmetest and startACMEServerStub in autocert_test.go.
// It feels like this acmeServer is a sweet spot between usefulness and added complexity.
// Also, acmetest and startACMEServerStub were both written for draft-02, no RFC support.
// The goal is to consolidate all into one ACME test server.
type acmeServer struct {
	ts      *httptest.Server
	handler map[string]http.HandlerFunc // keyed by r.URL.Path

	mu     sync.Mutex
	nnonce int
}

func newACMEServer() *acmeServer {
	return &acmeServer{handler: make(map[string]http.HandlerFunc)}
}

func (s *acmeServer) handle(path string, f func(http.ResponseWriter, *http.Request)) {
	s.handler[path] = http.HandlerFunc(f)
}

func (s *acmeServer) start() {
	s.ts = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")

		// Directory request.
		if r.URL.Path == "/" {
			fmt.Fprintf(w, `{
				"newNonce": %q,
				"newAccount": %q,
				"newOrder": %q,
				"newAuthz": %q,
				"revokeCert": %q,
				"keyChange": %q,
				"meta": {"termsOfService": %q}
				}`,
				s.url("/acme/new-nonce"),
				s.url("/acme/new-account"),
				s.url("/acme/new-order"),
				s.url("/acme/new-authz"),
				s.url("/acme/revoke-cert"),
				s.url("/acme/key-change"),
				s.url("/terms"),
			)
			return
		}

		// All other responses contain a nonce value unconditionally.
		w.Header().Set("Replay-Nonce", s.nonce())
		if r.URL.Path == "/acme/new-nonce" {
			return
		}

		h := s.handler[r.URL.Path]
		if h == nil {
			w.WriteHeader(http.StatusBadRequest)
			fmt.Fprintf(w, "Unhandled %s", r.URL.Path)
			return
		}
		h.ServeHTTP(w, r)
	}))
}

func (s *acmeServer) close() {
	s.ts.Close()
}

func (s *acmeServer) url(path string) string {
	return s.ts.URL + path
}

func (s *acmeServer) nonce() string {
	s.mu.Lock()
	defer s.mu.Unlock()
	s.nnonce++
	return fmt.Sprintf("nonce%d", s.nnonce)
}

func (s *acmeServer) error(w http.ResponseWriter, e *wireError) {
	w.WriteHeader(e.Status)
	json.NewEncoder(w).Encode(e)
}

func TestRFC_Register(t *testing.T) {
	const email = "mailto:user@example.org"

	s := newACMEServer()
	s.handle("/acme/new-account", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Location", s.url("/accounts/1"))
		w.WriteHeader(http.StatusCreated) // 201 means new account created
		fmt.Fprintf(w, `{
			"status": "valid",
			"contact": [%q],
			"orders": %q
		}`, email, s.url("/accounts/1/orders"))

		b, _ := ioutil.ReadAll(r.Body) // check err later in decodeJWSxxx
		head, err := decodeJWSHead(bytes.NewReader(b))
		if err != nil {
			t.Errorf("decodeJWSHead: %v", err)
			return
		}
		if len(head.JWK) == 0 {
			t.Error("head.JWK is empty")
		}

		var req struct{ Contact []string }
		decodeJWSRequest(t, &req, bytes.NewReader(b))
		if len(req.Contact) != 1 || req.Contact[0] != email {
			t.Errorf("req.Contact = %q; want [%q]", req.Contact, email)
		}
	})
	s.start()
	defer s.close()

	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	cl := &Client{
		Key:          testKeyEC,
		DirectoryURL: s.url("/"),
	}

	var didPrompt bool
	a := &Account{Contact: []string{email}}
	acct, err := cl.Register(ctx, a, func(tos string) bool {
		didPrompt = true
		terms := s.url("/terms")
		if tos != terms {
			t.Errorf("tos = %q; want %q", tos, terms)
		}
		return true
	})
	if err != nil {
		t.Fatal(err)
	}
	okAccount := &Account{
		URI:       s.url("/accounts/1"),
		Status:    StatusValid,
		Contact:   []string{email},
		OrdersURL: s.url("/accounts/1/orders"),
	}
	if !reflect.DeepEqual(acct, okAccount) {
		t.Errorf("acct = %+v; want %+v", acct, okAccount)
	}
	if !didPrompt {
		t.Error("tos prompt wasn't called")
	}
	if v := cl.accountKID(ctx); v != KeyID(okAccount.URI) {
		t.Errorf("account kid = %q; want %q", v, okAccount.URI)
	}
}

func TestRFC_RegisterExternalAccountBinding(t *testing.T) {
	eab := &ExternalAccountBinding{
		KID: "kid-1",
		Key: []byte("secret"),
	}

	type protected struct {
		Algorithm string `json:"alg"`
		KID       string `json:"kid"`
		URL       string `json:"url"`
	}
	const email = "mailto:user@example.org"

	s := newACMEServer()
	s.handle("/acme/new-account", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Location", s.url("/accounts/1"))
		if r.Method != "POST" {
			t.Errorf("r.Method = %q; want POST", r.Method)
		}

		var j struct {
			Protected              string
			Contact                []string
			TermsOfServiceAgreed   bool
			ExternalaccountBinding struct {
				Protected string
				Payload   string
				Signature string
			}
		}
		decodeJWSRequest(t, &j, r.Body)
		protData, err := base64.RawURLEncoding.DecodeString(j.ExternalaccountBinding.Protected)
		if err != nil {
			t.Fatal(err)
		}

		var prot protected
		err = json.Unmarshal(protData, &prot)
		if err != nil {
			t.Fatal(err)
		}

		if !reflect.DeepEqual(j.Contact, []string{email}) {
			t.Errorf("j.Contact = %v; want %v", j.Contact, []string{email})
		}
		if !j.TermsOfServiceAgreed {
			t.Error("j.TermsOfServiceAgreed = false; want true")
		}

		// Ensure same KID.
		if prot.KID != eab.KID {
			t.Errorf("j.ExternalAccountBinding.KID = %s; want %s", prot.KID, eab.KID)
		}
		// Ensure expected Algorithm.
		if prot.Algorithm != "HS256" {
			t.Errorf("j.ExternalAccountBinding.Alg = %s; want %s",
				prot.Algorithm, "HS256")
		}

		// Ensure same URL as outer JWS.
		url := fmt.Sprintf("http://%s/acme/new-account", r.Host)
		if prot.URL != url {
			t.Errorf("j.ExternalAccountBinding.URL = %s; want %s",
				prot.URL, url)
		}

		// Ensure payload is base64URL encoded string of JWK in outer JWS
		jwk, err := jwkEncode(testKeyEC.Public())
		if err != nil {
			t.Fatal(err)
		}
		decodedPayload, err := base64.RawURLEncoding.DecodeString(j.ExternalaccountBinding.Payload)
		if err != nil {
			t.Fatal(err)
		}
		if jwk != string(decodedPayload) {
			t.Errorf("j.ExternalAccountBinding.Payload = %s; want %s", decodedPayload, jwk)
		}

		// Check signature on inner external account binding JWS
		hmac := hmac.New(sha256.New, []byte("secret"))
		_, err = hmac.Write([]byte(j.ExternalaccountBinding.Protected + "." + j.ExternalaccountBinding.Payload))
		if err != nil {
			t.Fatal(err)
		}
		mac := hmac.Sum(nil)
		encodedMAC := base64.RawURLEncoding.EncodeToString(mac)

		if !bytes.Equal([]byte(encodedMAC), []byte(j.ExternalaccountBinding.Signature)) {
			t.Errorf("j.ExternalAccountBinding.Signature = %v; want %v",
				[]byte(j.ExternalaccountBinding.Signature), encodedMAC)
		}

		w.Header().Set("Location", s.url("/accounts/1"))
		w.WriteHeader(http.StatusCreated)
		b, _ := json.Marshal([]string{email})
		fmt.Fprintf(w, `{"status":"valid","orders":"%s","contact":%s}`, s.url("/accounts/1/orders"), b)
	})
	s.start()
	defer s.close()

	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	cl := &Client{
		Key:          testKeyEC,
		DirectoryURL: s.url("/"),
	}

	var didPrompt bool
	a := &Account{Contact: []string{email}, ExternalAccountBinding: eab}
	acct, err := cl.Register(ctx, a, func(tos string) bool {
		didPrompt = true
		terms := s.url("/terms")
		if tos != terms {
			t.Errorf("tos = %q; want %q", tos, terms)
		}
		return true
	})
	if err != nil {
		t.Fatal(err)
	}
	okAccount := &Account{
		URI:       s.url("/accounts/1"),
		Status:    StatusValid,
		Contact:   []string{email},
		OrdersURL: s.url("/accounts/1/orders"),
	}
	if !reflect.DeepEqual(acct, okAccount) {
		t.Errorf("acct = %+v; want %+v", acct, okAccount)
	}
	if !didPrompt {
		t.Error("tos prompt wasn't called")
	}
	if v := cl.accountKID(ctx); v != KeyID(okAccount.URI) {
		t.Errorf("account kid = %q; want %q", v, okAccount.URI)
	}
}

func TestRFC_RegisterExisting(t *testing.T) {
	s := newACMEServer()
	s.handle("/acme/new-account", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Location", s.url("/accounts/1"))
		w.WriteHeader(http.StatusOK) // 200 means account already exists
		w.Write([]byte(`{"status": "valid"}`))
	})
	s.start()
	defer s.close()

	cl := &Client{Key: testKeyEC, DirectoryURL: s.url("/")}
	_, err := cl.Register(context.Background(), &Account{}, AcceptTOS)
	if err != ErrAccountAlreadyExists {
		t.Errorf("err = %v; want %v", err, ErrAccountAlreadyExists)
	}
	kid := KeyID(s.url("/accounts/1"))
	if v := cl.accountKID(context.Background()); v != kid {
		t.Errorf("account kid = %q; want %q", v, kid)
	}
}

func TestRFC_UpdateReg(t *testing.T) {
	const email = "mailto:user@example.org"

	s := newACMEServer()
	s.handle("/acme/new-account", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Location", s.url("/accounts/1"))
		w.WriteHeader(http.StatusOK)
		w.Write([]byte(`{"status": "valid"}`))
	})
	var didUpdate bool
	s.handle("/accounts/1", func(w http.ResponseWriter, r *http.Request) {
		didUpdate = true
		w.Header().Set("Location", s.url("/accounts/1"))
		w.WriteHeader(http.StatusOK)
		w.Write([]byte(`{"status": "valid"}`))

		b, _ := ioutil.ReadAll(r.Body) // check err later in decodeJWSxxx
		head, err := decodeJWSHead(bytes.NewReader(b))
		if err != nil {
			t.Errorf("decodeJWSHead: %v", err)
			return
		}
		if len(head.JWK) != 0 {
			t.Error("head.JWK is non-zero")
		}
		kid := s.url("/accounts/1")
		if head.KID != kid {
			t.Errorf("head.KID = %q; want %q", head.KID, kid)
		}

		var req struct{ Contact []string }
		decodeJWSRequest(t, &req, bytes.NewReader(b))
		if len(req.Contact) != 1 || req.Contact[0] != email {
			t.Errorf("req.Contact = %q; want [%q]", req.Contact, email)
		}
	})
	s.start()
	defer s.close()

	cl := &Client{Key: testKeyEC, DirectoryURL: s.url("/")}
	_, err := cl.UpdateReg(context.Background(), &Account{Contact: []string{email}})
	if err != nil {
		t.Error(err)
	}
	if !didUpdate {
		t.Error("UpdateReg didn't update the account")
	}
}

func TestRFC_GetReg(t *testing.T) {
	s := newACMEServer()
	s.handle("/acme/new-account", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Location", s.url("/accounts/1"))
		w.WriteHeader(http.StatusOK)
		w.Write([]byte(`{"status": "valid"}`))

		head, err := decodeJWSHead(r.Body)
		if err != nil {
			t.Errorf("decodeJWSHead: %v", err)
			return
		}
		if len(head.JWK) == 0 {
			t.Error("head.JWK is empty")
		}
	})
	s.start()
	defer s.close()

	cl := &Client{Key: testKeyEC, DirectoryURL: s.url("/")}
	acct, err := cl.GetReg(context.Background(), "")
	if err != nil {
		t.Fatal(err)
	}
	okAccount := &Account{
		URI:    s.url("/accounts/1"),
		Status: StatusValid,
	}
	if !reflect.DeepEqual(acct, okAccount) {
		t.Errorf("acct = %+v; want %+v", acct, okAccount)
	}
}

func TestRFC_GetRegNoAccount(t *testing.T) {
	s := newACMEServer()
	s.handle("/acme/new-account", func(w http.ResponseWriter, r *http.Request) {
		s.error(w, &wireError{
			Status: http.StatusBadRequest,
			Type:   "urn:ietf:params:acme:error:accountDoesNotExist",
		})
	})
	s.start()
	defer s.close()

	cl := &Client{Key: testKeyEC, DirectoryURL: s.url("/")}
	if _, err := cl.GetReg(context.Background(), ""); err != ErrNoAccount {
		t.Errorf("err = %v; want %v", err, ErrNoAccount)
	}
}

func TestRFC_GetRegOtherError(t *testing.T) {
	s := newACMEServer()
	s.handle("/acme/new-account", func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(http.StatusBadRequest)
	})
	s.start()
	defer s.close()

	cl := &Client{Key: testKeyEC, DirectoryURL: s.url("/")}
	if _, err := cl.GetReg(context.Background(), ""); err == nil || err == ErrNoAccount {
		t.Errorf("GetReg: %v; want any other non-nil err", err)
	}
}

func TestRFC_AccountKeyRollover(t *testing.T) {
	s := newACMEServer()
	s.handle("/acme/new-account", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Location", s.url("/accounts/1"))
		w.WriteHeader(http.StatusOK)
		w.Write([]byte(`{"status": "valid"}`))
	})
	s.handle("/acme/key-change", func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(http.StatusOK)
	})
	s.start()
	defer s.close()

	cl := &Client{Key: testKeyEC, DirectoryURL: s.url("/")}
	if err := cl.AccountKeyRollover(context.Background(), testKeyEC384); err != nil {
		t.Errorf("AccountKeyRollover: %v, wanted no error", err)
	} else if cl.Key != testKeyEC384 {
		t.Error("AccountKeyRollover did not rotate the client key")
	}
}

func TestRFC_DeactivateReg(t *testing.T) {
	const email = "mailto:user@example.org"
	curStatus := StatusValid

	type account struct {
		Status    string   `json:"status"`
		Contact   []string `json:"contact"`
		AcceptTOS bool     `json:"termsOfServiceAgreed"`
		Orders    string   `json:"orders"`
	}

	s := newACMEServer()
	s.handle("/acme/new-account", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Location", s.url("/accounts/1"))
		w.WriteHeader(http.StatusOK) // 200 means existing account
		json.NewEncoder(w).Encode(account{
			Status:    curStatus,
			Contact:   []string{email},
			AcceptTOS: true,
			Orders:    s.url("/accounts/1/orders"),
		})

		b, _ := ioutil.ReadAll(r.Body) // check err later in decodeJWSxxx
		head, err := decodeJWSHead(bytes.NewReader(b))
		if err != nil {
			t.Errorf("decodeJWSHead: %v", err)
			return
		}
		if len(head.JWK) == 0 {
			t.Error("head.JWK is empty")
		}

		var req struct {
			Status       string   `json:"status"`
			Contact      []string `json:"contact"`
			AcceptTOS    bool     `json:"termsOfServiceAgreed"`
			OnlyExisting bool     `json:"onlyReturnExisting"`
		}
		decodeJWSRequest(t, &req, bytes.NewReader(b))
		if !req.OnlyExisting {
			t.Errorf("req.OnlyReturnExisting = %t; want = %t", req.OnlyExisting, true)
		}
	})
	s.handle("/accounts/1", func(w http.ResponseWriter, r *http.Request) {
		if curStatus == StatusValid {
			curStatus = StatusDeactivated
			w.WriteHeader(http.StatusOK)
		} else {
			s.error(w, &wireError{
				Status: http.StatusUnauthorized,
				Type:   "urn:ietf:params:acme:error:unauthorized",
			})
		}
		var req account
		b, _ := ioutil.ReadAll(r.Body) // check err later in decodeJWSxxx
		head, err := decodeJWSHead(bytes.NewReader(b))
		if err != nil {
			t.Errorf("decodeJWSHead: %v", err)
			return
		}
		if len(head.JWK) != 0 {
			t.Error("head.JWK is not empty")
		}
		if !strings.HasSuffix(head.KID, "/accounts/1") {
			t.Errorf("head.KID = %q; want suffix /accounts/1", head.KID)
		}

		decodeJWSRequest(t, &req, bytes.NewReader(b))
		if req.Status != StatusDeactivated {
			t.Errorf("req.Status = %q; want = %q", req.Status, StatusDeactivated)
		}
	})
	s.start()
	defer s.close()

	cl := &Client{Key: testKeyEC, DirectoryURL: s.url("/")}
	if err := cl.DeactivateReg(context.Background()); err != nil {
		t.Errorf("DeactivateReg: %v, wanted no error", err)
	}
	if err := cl.DeactivateReg(context.Background()); err == nil {
		t.Errorf("DeactivateReg: %v, wanted error for unauthorized", err)
	}
}

func TestRF_DeactivateRegNoAccount(t *testing.T) {
	s := newACMEServer()
	s.handle("/acme/new-account", func(w http.ResponseWriter, r *http.Request) {
		s.error(w, &wireError{
			Status: http.StatusBadRequest,
			Type:   "urn:ietf:params:acme:error:accountDoesNotExist",
		})
	})
	s.start()
	defer s.close()

	cl := &Client{Key: testKeyEC, DirectoryURL: s.url("/")}
	if err := cl.DeactivateReg(context.Background()); !errors.Is(err, ErrNoAccount) {
		t.Errorf("DeactivateReg: %v, wanted ErrNoAccount", err)
	}
}

func TestRFC_AuthorizeOrder(t *testing.T) {
	s := newACMEServer()
	s.handle("/acme/new-account", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Location", s.url("/accounts/1"))
		w.WriteHeader(http.StatusOK)
		w.Write([]byte(`{"status": "valid"}`))
	})
	s.handle("/acme/new-order", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Location", s.url("/orders/1"))
		w.WriteHeader(http.StatusCreated)
		fmt.Fprintf(w, `{
			"status": "pending",
			"expires": "2019-09-01T00:00:00Z",
			"notBefore": "2019-08-31T00:00:00Z",
			"notAfter": "2019-09-02T00:00:00Z",
			"identifiers": [{"type":"dns", "value":"example.org"}],
			"authorizations": [%q]
		}`, s.url("/authz/1"))
	})
	s.start()
	defer s.close()

	cl := &Client{Key: testKeyEC, DirectoryURL: s.url("/")}
	o, err := cl.AuthorizeOrder(context.Background(), DomainIDs("example.org"),
		WithOrderNotBefore(time.Date(2019, 8, 31, 0, 0, 0, 0, time.UTC)),
		WithOrderNotAfter(time.Date(2019, 9, 2, 0, 0, 0, 0, time.UTC)),
	)
	if err != nil {
		t.Fatal(err)
	}
	okOrder := &Order{
		URI:         s.url("/orders/1"),
		Status:      StatusPending,
		Expires:     time.Date(2019, 9, 1, 0, 0, 0, 0, time.UTC),
		NotBefore:   time.Date(2019, 8, 31, 0, 0, 0, 0, time.UTC),
		NotAfter:    time.Date(2019, 9, 2, 0, 0, 0, 0, time.UTC),
		Identifiers: []AuthzID{AuthzID{Type: "dns", Value: "example.org"}},
		AuthzURLs:   []string{s.url("/authz/1")},
	}
	if !reflect.DeepEqual(o, okOrder) {
		t.Errorf("AuthorizeOrder = %+v; want %+v", o, okOrder)
	}
}

func TestRFC_GetOrder(t *testing.T) {
	s := newACMEServer()
	s.handle("/acme/new-account", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Location", s.url("/accounts/1"))
		w.WriteHeader(http.StatusOK)
		w.Write([]byte(`{"status": "valid"}`))
	})
	s.handle("/orders/1", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Location", s.url("/orders/1"))
		w.WriteHeader(http.StatusOK)
		w.Write([]byte(`{
			"status": "invalid",
			"expires": "2019-09-01T00:00:00Z",
			"notBefore": "2019-08-31T00:00:00Z",
			"notAfter": "2019-09-02T00:00:00Z",
			"identifiers": [{"type":"dns", "value":"example.org"}],
			"authorizations": ["/authz/1"],
			"finalize": "/orders/1/fin",
			"certificate": "/orders/1/cert",
			"error": {"type": "badRequest"}
		}`))
	})
	s.start()
	defer s.close()

	cl := &Client{Key: testKeyEC, DirectoryURL: s.url("/")}
	o, err := cl.GetOrder(context.Background(), s.url("/orders/1"))
	if err != nil {
		t.Fatal(err)
	}
	okOrder := &Order{
		URI:         s.url("/orders/1"),
		Status:      StatusInvalid,
		Expires:     time.Date(2019, 9, 1, 0, 0, 0, 0, time.UTC),
		NotBefore:   time.Date(2019, 8, 31, 0, 0, 0, 0, time.UTC),
		NotAfter:    time.Date(2019, 9, 2, 0, 0, 0, 0, time.UTC),
		Identifiers: []AuthzID{AuthzID{Type: "dns", Value: "example.org"}},
		AuthzURLs:   []string{"/authz/1"},
		FinalizeURL: "/orders/1/fin",
		CertURL:     "/orders/1/cert",
		Error:       &Error{ProblemType: "badRequest"},
	}
	if !reflect.DeepEqual(o, okOrder) {
		t.Errorf("GetOrder = %+v\nwant %+v", o, okOrder)
	}
}

func TestRFC_WaitOrder(t *testing.T) {
	for _, st := range []string{StatusReady, StatusValid} {
		t.Run(st, func(t *testing.T) {
			testWaitOrderStatus(t, st)
		})
	}
}

func testWaitOrderStatus(t *testing.T, okStatus string) {
	s := newACMEServer()
	s.handle("/acme/new-account", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Location", s.url("/accounts/1"))
		w.WriteHeader(http.StatusOK)
		w.Write([]byte(`{"status": "valid"}`))
	})
	var count int
	s.handle("/orders/1", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Location", s.url("/orders/1"))
		w.WriteHeader(http.StatusOK)
		s := StatusPending
		if count > 0 {
			s = okStatus
		}
		fmt.Fprintf(w, `{"status": %q}`, s)
		count++
	})
	s.start()
	defer s.close()

	var order *Order
	var err error
	done := make(chan struct{})
	go func() {
		cl := &Client{Key: testKeyEC, DirectoryURL: s.url("/")}
		order, err = cl.WaitOrder(context.Background(), s.url("/orders/1"))
		close(done)
	}()
	select {
	case <-time.After(3 * time.Second):
		t.Fatal("WaitOrder took too long to return")
	case <-done:
		if err != nil {
			t.Fatalf("WaitOrder: %v", err)
		}
		if order.Status != okStatus {
			t.Errorf("order.Status = %q; want %q", order.Status, okStatus)
		}
	}
}

func TestRFC_WaitOrderError(t *testing.T) {
	s := newACMEServer()
	s.handle("/acme/new-account", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Location", s.url("/accounts/1"))
		w.WriteHeader(http.StatusOK)
		w.Write([]byte(`{"status": "valid"}`))
	})
	var count int
	s.handle("/orders/1", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Location", s.url("/orders/1"))
		w.WriteHeader(http.StatusOK)
		s := StatusPending
		if count > 0 {
			s = StatusInvalid
		}
		fmt.Fprintf(w, `{"status": %q}`, s)
		count++
	})
	s.start()
	defer s.close()

	var err error
	done := make(chan struct{})
	go func() {
		cl := &Client{Key: testKeyEC, DirectoryURL: s.url("/")}
		_, err = cl.WaitOrder(context.Background(), s.url("/orders/1"))
		close(done)
	}()
	select {
	case <-time.After(3 * time.Second):
		t.Fatal("WaitOrder took too long to return")
	case <-done:
		if err == nil {
			t.Fatal("WaitOrder returned nil error")
		}
		e, ok := err.(*OrderError)
		if !ok {
			t.Fatalf("err = %v (%T); want OrderError", err, err)
		}
		if e.OrderURL != s.url("/orders/1") {
			t.Errorf("e.OrderURL = %q; want %q", e.OrderURL, s.url("/orders/1"))
		}
		if e.Status != StatusInvalid {
			t.Errorf("e.Status = %q; want %q", e.Status, StatusInvalid)
		}
	}
}

func TestRFC_CreateOrderCert(t *testing.T) {
	q := &x509.CertificateRequest{
		Subject: pkix.Name{CommonName: "example.org"},
	}
	csr, err := x509.CreateCertificateRequest(rand.Reader, q, testKeyEC)
	if err != nil {
		t.Fatal(err)
	}

	tmpl := &x509.Certificate{SerialNumber: big.NewInt(1)}
	leaf, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, &testKeyEC.PublicKey, testKeyEC)
	if err != nil {
		t.Fatal(err)
	}

	s := newACMEServer()
	s.handle("/acme/new-account", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Location", s.url("/accounts/1"))
		w.Write([]byte(`{"status": "valid"}`))
	})
	var count int
	s.handle("/pleaseissue", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Location", s.url("/pleaseissue"))
		st := StatusProcessing
		if count > 0 {
			st = StatusValid
		}
		fmt.Fprintf(w, `{"status":%q, "certificate":%q}`, st, s.url("/crt"))
		count++
	})
	s.handle("/crt", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/pem-certificate-chain")
		pem.Encode(w, &pem.Block{Type: "CERTIFICATE", Bytes: leaf})
	})
	s.start()
	defer s.close()
	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
	defer cancel()

	cl := &Client{Key: testKeyEC, DirectoryURL: s.url("/")}
	cert, curl, err := cl.CreateOrderCert(ctx, s.url("/pleaseissue"), csr, true)
	if err != nil {
		t.Fatalf("CreateOrderCert: %v", err)
	}
	if _, err := x509.ParseCertificate(cert[0]); err != nil {
		t.Errorf("ParseCertificate: %v", err)
	}
	if !reflect.DeepEqual(cert[0], leaf) {
		t.Errorf("cert and leaf bytes don't match")
	}
	if u := s.url("/crt"); curl != u {
		t.Errorf("curl = %q; want %q", curl, u)
	}
}

func TestRFC_AlreadyRevokedCert(t *testing.T) {
	s := newACMEServer()
	s.handle("/acme/revoke-cert", func(w http.ResponseWriter, r *http.Request) {
		s.error(w, &wireError{
			Status: http.StatusBadRequest,
			Type:   "urn:ietf:params:acme:error:alreadyRevoked",
		})
	})
	s.start()
	defer s.close()

	cl := &Client{Key: testKeyEC, DirectoryURL: s.url("/")}
	err := cl.RevokeCert(context.Background(), testKeyEC, []byte{0}, CRLReasonUnspecified)
	if err != nil {
		t.Fatalf("RevokeCert: %v", err)
	}
}

func TestRFC_ListCertAlternates(t *testing.T) {
	s := newACMEServer()
	s.handle("/crt", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/pem-certificate-chain")
		w.Header().Add("Link", `<https://example.com/crt/2>;rel="alternate"`)
		w.Header().Add("Link", `<https://example.com/crt/3>; rel="alternate"`)
		w.Header().Add("Link", `<https://example.com/acme>; rel="index"`)
	})
	s.handle("/crt2", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/pem-certificate-chain")
	})
	s.start()
	defer s.close()

	cl := &Client{Key: testKeyEC, DirectoryURL: s.url("/")}
	crts, err := cl.ListCertAlternates(context.Background(), s.url("/crt"))
	if err != nil {
		t.Fatalf("ListCertAlternates: %v", err)
	}
	want := []string{"https://example.com/crt/2", "https://example.com/crt/3"}
	if !reflect.DeepEqual(crts, want) {
		t.Errorf("ListCertAlternates(/crt): %v; want %v", crts, want)
	}
	crts, err = cl.ListCertAlternates(context.Background(), s.url("/crt2"))
	if err != nil {
		t.Fatalf("ListCertAlternates: %v", err)
	}
	if crts != nil {
		t.Errorf("ListCertAlternates(/crt2): %v; want nil", crts)
	}
}
