...

Source file src/github.com/letsencrypt/boulder/ra/ra_test.go

Documentation: github.com/letsencrypt/boulder/ra

     1  package ra
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"crypto/ecdsa"
     7  	"crypto/elliptic"
     8  	"crypto/rand"
     9  	"crypto/rsa"
    10  	"crypto/sha256"
    11  	"crypto/x509"
    12  	"crypto/x509/pkix"
    13  	"encoding/json"
    14  	"encoding/pem"
    15  	"errors"
    16  	"fmt"
    17  	"math/big"
    18  	mrand "math/rand"
    19  	"net"
    20  	"regexp"
    21  	"strconv"
    22  	"strings"
    23  	"sync"
    24  	"testing"
    25  	"time"
    26  
    27  	ctasn1 "github.com/google/certificate-transparency-go/asn1"
    28  	ctx509 "github.com/google/certificate-transparency-go/x509"
    29  	ctpkix "github.com/google/certificate-transparency-go/x509/pkix"
    30  	"github.com/jmhodges/clock"
    31  	"github.com/prometheus/client_golang/prometheus"
    32  	"github.com/weppos/publicsuffix-go/publicsuffix"
    33  	"golang.org/x/crypto/ocsp"
    34  	"google.golang.org/grpc"
    35  	"google.golang.org/protobuf/types/known/emptypb"
    36  	"google.golang.org/protobuf/types/known/timestamppb"
    37  	"gopkg.in/go-jose/go-jose.v2"
    38  
    39  	akamaipb "github.com/letsencrypt/boulder/akamai/proto"
    40  	capb "github.com/letsencrypt/boulder/ca/proto"
    41  	"github.com/letsencrypt/boulder/config"
    42  	"github.com/letsencrypt/boulder/core"
    43  	corepb "github.com/letsencrypt/boulder/core/proto"
    44  	"github.com/letsencrypt/boulder/ctpolicy"
    45  	"github.com/letsencrypt/boulder/ctpolicy/loglist"
    46  	berrors "github.com/letsencrypt/boulder/errors"
    47  	"github.com/letsencrypt/boulder/goodkey"
    48  	bgrpc "github.com/letsencrypt/boulder/grpc"
    49  	"github.com/letsencrypt/boulder/identifier"
    50  	"github.com/letsencrypt/boulder/issuance"
    51  	blog "github.com/letsencrypt/boulder/log"
    52  	"github.com/letsencrypt/boulder/metrics"
    53  	"github.com/letsencrypt/boulder/mocks"
    54  	"github.com/letsencrypt/boulder/policy"
    55  	pubpb "github.com/letsencrypt/boulder/publisher/proto"
    56  	rapb "github.com/letsencrypt/boulder/ra/proto"
    57  	"github.com/letsencrypt/boulder/ratelimit"
    58  	"github.com/letsencrypt/boulder/ratelimits"
    59  	"github.com/letsencrypt/boulder/sa"
    60  	sapb "github.com/letsencrypt/boulder/sa/proto"
    61  	"github.com/letsencrypt/boulder/test"
    62  	isa "github.com/letsencrypt/boulder/test/inmem/sa"
    63  	"github.com/letsencrypt/boulder/test/vars"
    64  	vapb "github.com/letsencrypt/boulder/va/proto"
    65  )
    66  
    67  func TestImplementation(t *testing.T) {
    68  	test.AssertImplementsGRPCServer(t, &RegistrationAuthorityImpl{}, rapb.UnimplementedRegistrationAuthorityServer{})
    69  }
    70  
    71  func createPendingAuthorization(t *testing.T, sa sapb.StorageAuthorityClient, domain string, exp time.Time) *corepb.Authorization {
    72  	t.Helper()
    73  
    74  	authz := core.Authorization{
    75  		Identifier:     identifier.DNSIdentifier(domain),
    76  		RegistrationID: Registration.Id,
    77  		Status:         "pending",
    78  		Expires:        &exp,
    79  		Challenges: []core.Challenge{
    80  			{
    81  				Token:  core.NewToken(),
    82  				Type:   core.ChallengeTypeHTTP01,
    83  				Status: core.StatusPending,
    84  			},
    85  			{
    86  				Token:  core.NewToken(),
    87  				Type:   core.ChallengeTypeDNS01,
    88  				Status: core.StatusPending,
    89  			},
    90  			{
    91  				Token:  core.NewToken(),
    92  				Type:   core.ChallengeTypeTLSALPN01,
    93  				Status: core.StatusPending,
    94  			},
    95  		},
    96  	}
    97  	authzPB, err := bgrpc.AuthzToPB(authz)
    98  	test.AssertNotError(t, err, "AuthzToPB failed")
    99  
   100  	res, err := sa.NewOrderAndAuthzs(context.Background(), &sapb.NewOrderAndAuthzsRequest{
   101  		NewOrder: &sapb.NewOrderRequest{
   102  			RegistrationID: Registration.Id,
   103  			ExpiresNS:      exp.UnixNano(),
   104  			Expires:        timestamppb.New(exp),
   105  			Names:          []string{domain},
   106  		},
   107  		NewAuthzs: []*corepb.Authorization{authzPB},
   108  	})
   109  	test.AssertNotError(t, err, "sa.NewOrderAndAuthzs failed")
   110  
   111  	return getAuthorization(t, fmt.Sprint(res.V2Authorizations[0]), sa)
   112  }
   113  
   114  func createFinalizedAuthorization(t *testing.T, sa sapb.StorageAuthorityClient, domain string, exp time.Time, chall core.AcmeChallenge, attemptedAt time.Time) int64 {
   115  	t.Helper()
   116  	pending := createPendingAuthorization(t, sa, domain, exp)
   117  	pendingID, err := strconv.ParseInt(pending.Id, 10, 64)
   118  	test.AssertNotError(t, err, "strconv.ParseInt failed")
   119  	_, err = sa.FinalizeAuthorization2(context.Background(), &sapb.FinalizeAuthorizationRequest{
   120  		Id:            pendingID,
   121  		Status:        "valid",
   122  		ExpiresNS:     exp.UnixNano(),
   123  		Expires:       timestamppb.New(exp),
   124  		Attempted:     string(chall),
   125  		AttemptedAtNS: attemptedAt.UnixNano(),
   126  		AttemptedAt:   timestamppb.New(attemptedAt),
   127  	})
   128  	test.AssertNotError(t, err, "sa.FinalizeAuthorizations2 failed")
   129  	return pendingID
   130  }
   131  
   132  func getAuthorization(t *testing.T, id string, sa sapb.StorageAuthorityClient) *corepb.Authorization {
   133  	t.Helper()
   134  	idInt, err := strconv.ParseInt(id, 10, 64)
   135  	test.AssertNotError(t, err, "strconv.ParseInt failed")
   136  	dbAuthz, err := sa.GetAuthorization2(ctx, &sapb.AuthorizationID2{Id: idInt})
   137  	test.AssertNotError(t, err, "Could not fetch authorization from database")
   138  	return dbAuthz
   139  }
   140  
   141  func dnsChallIdx(t *testing.T, challenges []*corepb.Challenge) int64 {
   142  	t.Helper()
   143  	var challIdx int64
   144  	var set bool
   145  	for i, ch := range challenges {
   146  		if core.AcmeChallenge(ch.Type) == core.ChallengeTypeDNS01 {
   147  			challIdx = int64(i)
   148  			set = true
   149  			break
   150  		}
   151  	}
   152  	if !set {
   153  		t.Errorf("dnsChallIdx didn't find challenge of type DNS-01")
   154  	}
   155  	return challIdx
   156  }
   157  
   158  func numAuthorizations(o *corepb.Order) int {
   159  	return len(o.V2Authorizations)
   160  }
   161  
   162  type DummyValidationAuthority struct {
   163  	request      chan *vapb.PerformValidationRequest
   164  	ResultError  error
   165  	ResultReturn *vapb.ValidationResult
   166  }
   167  
   168  func (dva *DummyValidationAuthority) PerformValidation(ctx context.Context, req *vapb.PerformValidationRequest, _ ...grpc.CallOption) (*vapb.ValidationResult, error) {
   169  	dva.request <- req
   170  	return dva.ResultReturn, dva.ResultError
   171  }
   172  
   173  var (
   174  	// These values we simulate from the client
   175  	AccountKeyJSONA = []byte(`{
   176  		"kty":"RSA",
   177  		"n":"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw",
   178  		"e":"AQAB"
   179  	}`)
   180  	AccountKeyA = jose.JSONWebKey{}
   181  
   182  	AccountKeyJSONB = []byte(`{
   183  		"kty":"RSA",
   184  		"n":"z8bp-jPtHt4lKBqepeKF28g_QAEOuEsCIou6sZ9ndsQsEjxEOQxQ0xNOQezsKa63eogw8YS3vzjUcPP5BJuVzfPfGd5NVUdT-vSSwxk3wvk_jtNqhrpcoG0elRPQfMVsQWmxCAXCVRz3xbcFI8GTe-syynG3l-g1IzYIIZVNI6jdljCZML1HOMTTW4f7uJJ8mM-08oQCeHbr5ejK7O2yMSSYxW03zY-Tj1iVEebROeMv6IEEJNFSS4yM-hLpNAqVuQxFGetwtwjDMC1Drs1dTWrPuUAAjKGrP151z1_dE74M5evpAhZUmpKv1hY-x85DC6N0hFPgowsanmTNNiV75w",
   185  		"e":"AQAB"
   186  	}`)
   187  	AccountKeyB = jose.JSONWebKey{}
   188  
   189  	AccountKeyJSONC = []byte(`{
   190  		"kty":"RSA",
   191  		"n":"rFH5kUBZrlPj73epjJjyCxzVzZuV--JjKgapoqm9pOuOt20BUTdHqVfC2oDclqM7HFhkkX9OSJMTHgZ7WaVqZv9u1X2yjdx9oVmMLuspX7EytW_ZKDZSzL-sCOFCuQAuYKkLbsdcA3eHBK_lwc4zwdeHFMKIulNvLqckkqYB9s8GpgNXBDIQ8GjR5HuJke_WUNjYHSd8jY1LU9swKWsLQe2YoQUz_ekQvBvBCoaFEtrtRaSJKNLIVDObXFr2TLIiFiM0Em90kK01-eQ7ZiruZTKomll64bRFPoNo4_uwubddg3xTqur2vdF3NyhTrYdvAgTem4uC0PFjEQ1bK_djBQ",
   192  		"e":"AQAB"
   193  	}`)
   194  	AccountKeyC = jose.JSONWebKey{}
   195  
   196  	// These values we simulate from the client
   197  	AccountPrivateKeyJSON = []byte(`{
   198  		"kty":"RSA",
   199  		"n":"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw",
   200  		"e":"AQAB",
   201  		"d":"X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2vv7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoAC8Q",
   202  		"p":"83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs",
   203  		"q":"3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3vobLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelxk",
   204  		"dp":"G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA77Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0",
   205  		"dq":"s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cgk",
   206  		"qi":"GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_mHZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU"
   207  	}`)
   208  	AccountPrivateKey = jose.JSONWebKey{}
   209  
   210  	ShortKeyJSON = []byte(`{
   211  		"e": "AQAB",
   212  		"kty": "RSA",
   213  		"n": "tSwgy3ORGvc7YJI9B2qqkelZRUC6F1S5NwXFvM4w5-M0TsxbFsH5UH6adigV0jzsDJ5imAechcSoOhAh9POceCbPN1sTNwLpNbOLiQQ7RD5mY_"
   214  		}`)
   215  
   216  	ShortKey = jose.JSONWebKey{}
   217  
   218  	ResponseIndex = 0
   219  
   220  	ExampleCSR = &x509.CertificateRequest{}
   221  
   222  	Registration = &corepb.Registration{Id: 1}
   223  
   224  	Identifier = "not-example.com"
   225  
   226  	log = blog.UseMock()
   227  )
   228  
   229  var testKeyPolicy = goodkey.KeyPolicy{
   230  	AllowRSA:           true,
   231  	AllowECDSANISTP256: true,
   232  	AllowECDSANISTP384: true,
   233  }
   234  
   235  var ctx = context.Background()
   236  
   237  // dummyRateLimitConfig satisfies the rl.RateLimitConfig interface while
   238  // allowing easy mocking of the individual RateLimitPolicy's
   239  type dummyRateLimitConfig struct {
   240  	CertificatesPerNamePolicy             ratelimit.RateLimitPolicy
   241  	RegistrationsPerIPPolicy              ratelimit.RateLimitPolicy
   242  	RegistrationsPerIPRangePolicy         ratelimit.RateLimitPolicy
   243  	PendingAuthorizationsPerAccountPolicy ratelimit.RateLimitPolicy
   244  	NewOrdersPerAccountPolicy             ratelimit.RateLimitPolicy
   245  	InvalidAuthorizationsPerAccountPolicy ratelimit.RateLimitPolicy
   246  	CertificatesPerFQDNSetPolicy          ratelimit.RateLimitPolicy
   247  	CertificatesPerFQDNSetFastPolicy      ratelimit.RateLimitPolicy
   248  }
   249  
   250  func (r *dummyRateLimitConfig) CertificatesPerName() ratelimit.RateLimitPolicy {
   251  	return r.CertificatesPerNamePolicy
   252  }
   253  
   254  func (r *dummyRateLimitConfig) RegistrationsPerIP() ratelimit.RateLimitPolicy {
   255  	return r.RegistrationsPerIPPolicy
   256  }
   257  
   258  func (r *dummyRateLimitConfig) RegistrationsPerIPRange() ratelimit.RateLimitPolicy {
   259  	return r.RegistrationsPerIPRangePolicy
   260  }
   261  
   262  func (r *dummyRateLimitConfig) PendingAuthorizationsPerAccount() ratelimit.RateLimitPolicy {
   263  	return r.PendingAuthorizationsPerAccountPolicy
   264  }
   265  
   266  func (r *dummyRateLimitConfig) NewOrdersPerAccount() ratelimit.RateLimitPolicy {
   267  	return r.NewOrdersPerAccountPolicy
   268  }
   269  
   270  func (r *dummyRateLimitConfig) InvalidAuthorizationsPerAccount() ratelimit.RateLimitPolicy {
   271  	return r.InvalidAuthorizationsPerAccountPolicy
   272  }
   273  
   274  func (r *dummyRateLimitConfig) CertificatesPerFQDNSet() ratelimit.RateLimitPolicy {
   275  	return r.CertificatesPerFQDNSetPolicy
   276  }
   277  
   278  func (r *dummyRateLimitConfig) CertificatesPerFQDNSetFast() ratelimit.RateLimitPolicy {
   279  	return r.CertificatesPerFQDNSetFastPolicy
   280  }
   281  
   282  func (r *dummyRateLimitConfig) LoadPolicies(contents []byte) error {
   283  	return nil // NOP - unrequired behaviour for this mock
   284  }
   285  
   286  func parseAndMarshalIP(t *testing.T, ip string) []byte {
   287  	ipBytes, err := net.ParseIP(ip).MarshalText()
   288  	test.AssertNotError(t, err, "failed to marshal ip")
   289  	return ipBytes
   290  }
   291  
   292  func newAcctKey(t *testing.T) []byte {
   293  	key := &jose.JSONWebKey{Key: testKey()}
   294  	acctKey, err := key.MarshalJSON()
   295  	test.AssertNotError(t, err, "failed to marshal account key")
   296  	return acctKey
   297  }
   298  
   299  func initAuthorities(t *testing.T) (*DummyValidationAuthority, sapb.StorageAuthorityClient, *RegistrationAuthorityImpl, clock.FakeClock, func()) {
   300  	err := json.Unmarshal(AccountKeyJSONA, &AccountKeyA)
   301  	test.AssertNotError(t, err, "Failed to unmarshal public JWK")
   302  	err = json.Unmarshal(AccountKeyJSONB, &AccountKeyB)
   303  	test.AssertNotError(t, err, "Failed to unmarshal public JWK")
   304  	err = json.Unmarshal(AccountKeyJSONC, &AccountKeyC)
   305  	test.AssertNotError(t, err, "Failed to unmarshal public JWK")
   306  
   307  	err = json.Unmarshal(AccountPrivateKeyJSON, &AccountPrivateKey)
   308  	test.AssertNotError(t, err, "Failed to unmarshal private JWK")
   309  
   310  	err = json.Unmarshal(ShortKeyJSON, &ShortKey)
   311  	test.AssertNotError(t, err, "Failed to unmarshal JWK")
   312  
   313  	fc := clock.NewFake()
   314  	// Set to some non-zero time.
   315  	fc.Set(time.Date(2015, 3, 4, 5, 0, 0, 0, time.UTC))
   316  
   317  	dbMap, err := sa.DBMapForTest(vars.DBConnSA)
   318  	if err != nil {
   319  		t.Fatalf("Failed to create dbMap: %s", err)
   320  	}
   321  	ssa, err := sa.NewSQLStorageAuthority(dbMap, dbMap, nil, 1, 0, fc, log, metrics.NoopRegisterer)
   322  	if err != nil {
   323  		t.Fatalf("Failed to create SA: %s", err)
   324  	}
   325  	sa := &isa.SA{Impl: ssa}
   326  
   327  	saDBCleanUp := test.ResetBoulderTestDatabase(t)
   328  
   329  	va := &DummyValidationAuthority{request: make(chan *vapb.PerformValidationRequest, 1)}
   330  
   331  	pa, err := policy.New(map[core.AcmeChallenge]bool{
   332  		core.ChallengeTypeHTTP01: true,
   333  		core.ChallengeTypeDNS01:  true,
   334  	}, blog.NewMock())
   335  	test.AssertNotError(t, err, "Couldn't create PA")
   336  	err = pa.LoadHostnamePolicyFile("../test/hostname-policy.yaml")
   337  	test.AssertNotError(t, err, "Couldn't set hostname policy")
   338  
   339  	stats := metrics.NoopRegisterer
   340  
   341  	ca := &mocks.MockCA{
   342  		PEM: eeCertPEM,
   343  	}
   344  	cleanUp := func() {
   345  		saDBCleanUp()
   346  	}
   347  
   348  	block, _ := pem.Decode(CSRPEM)
   349  	ExampleCSR, _ = x509.ParseCertificateRequest(block.Bytes)
   350  
   351  	initialIP, err := net.ParseIP("3.2.3.3").MarshalText()
   352  	test.AssertNotError(t, err, "Couldn't create initial IP")
   353  	Registration, _ = ssa.NewRegistration(ctx, &corepb.Registration{
   354  		Key:       AccountKeyJSONA,
   355  		InitialIP: initialIP,
   356  		Status:    string(core.StatusValid),
   357  	})
   358  
   359  	ctp := ctpolicy.New(&mocks.PublisherClient{}, loglist.List{
   360  		"OperA": {
   361  			"LogA1": {Url: "UrlA1", Key: "KeyA1"},
   362  		},
   363  		"OperB": {
   364  			"LogB1": {Url: "UrlB1", Key: "KeyB1"},
   365  		},
   366  	}, nil, nil, 0, log, metrics.NoopRegisterer)
   367  
   368  	ra := NewRegistrationAuthorityImpl(
   369  		fc, log, stats,
   370  		1, testKeyPolicy, 100,
   371  		300*24*time.Hour, 7*24*time.Hour,
   372  		nil, noopCAA{},
   373  		0, 5*time.Minute,
   374  		ctp, nil, nil)
   375  	ra.SA = sa
   376  	ra.VA = va
   377  	ra.CA = ca
   378  	ra.OCSP = &mocks.MockOCSPGenerator{}
   379  	ra.PA = pa
   380  	return va, sa, ra, fc, cleanUp
   381  }
   382  
   383  func TestValidateContacts(t *testing.T) {
   384  	_, _, ra, _, cleanUp := initAuthorities(t)
   385  	defer cleanUp()
   386  
   387  	ansible := "ansible:earth.sol.milkyway.laniakea/letsencrypt"
   388  	validEmail := "mailto:admin@email.com"
   389  	otherValidEmail := "mailto:other-admin@email.com"
   390  	malformedEmail := "mailto:admin.com"
   391  	nonASCII := "mailto:seƱor@email.com"
   392  	unparsable := "mailto:a@email.com, b@email.com"
   393  	forbidden := "mailto:a@example.org"
   394  
   395  	err := ra.validateContacts([]string{})
   396  	test.AssertNotError(t, err, "No Contacts")
   397  
   398  	err = ra.validateContacts([]string{validEmail, otherValidEmail})
   399  	test.AssertError(t, err, "Too Many Contacts")
   400  
   401  	err = ra.validateContacts([]string{validEmail})
   402  	test.AssertNotError(t, err, "Valid Email")
   403  
   404  	err = ra.validateContacts([]string{malformedEmail})
   405  	test.AssertError(t, err, "Malformed Email")
   406  
   407  	err = ra.validateContacts([]string{ansible})
   408  	test.AssertError(t, err, "Unknown scheme")
   409  
   410  	err = ra.validateContacts([]string{""})
   411  	test.AssertError(t, err, "Empty URL")
   412  
   413  	err = ra.validateContacts([]string{nonASCII})
   414  	test.AssertError(t, err, "Non ASCII email")
   415  
   416  	err = ra.validateContacts([]string{unparsable})
   417  	test.AssertError(t, err, "Unparsable email")
   418  
   419  	err = ra.validateContacts([]string{forbidden})
   420  	test.AssertError(t, err, "Forbidden email")
   421  
   422  	err = ra.validateContacts([]string{"mailto:admin@localhost"})
   423  	test.AssertError(t, err, "Forbidden email")
   424  
   425  	err = ra.validateContacts([]string{"mailto:admin@example.not.a.iana.suffix"})
   426  	test.AssertError(t, err, "Forbidden email")
   427  
   428  	err = ra.validateContacts([]string{"mailto:admin@1.2.3.4"})
   429  	test.AssertError(t, err, "Forbidden email")
   430  
   431  	err = ra.validateContacts([]string{"mailto:admin@[1.2.3.4]"})
   432  	test.AssertError(t, err, "Forbidden email")
   433  
   434  	err = ra.validateContacts([]string{"mailto:admin@a.com?no-reminder-emails"})
   435  	test.AssertError(t, err, "No hfields in email")
   436  
   437  	err = ra.validateContacts([]string{"mailto:example@a.com?"})
   438  	test.AssertError(t, err, "No hfields in email")
   439  
   440  	err = ra.validateContacts([]string{"mailto:example@a.com#"})
   441  	test.AssertError(t, err, "No fragment")
   442  
   443  	err = ra.validateContacts([]string{"mailto:example@a.com#optional"})
   444  	test.AssertError(t, err, "No fragment")
   445  
   446  	// The registrations.contact field is VARCHAR(191). 175 'a' characters plus
   447  	// the prefix "mailto:" and the suffix "@a.com" makes exactly 191 bytes of
   448  	// encoded JSON. The correct size to hit our maximum DB field length.
   449  	var longStringBuf strings.Builder
   450  	longStringBuf.WriteString("mailto:")
   451  	for i := 0; i < 175; i++ {
   452  		longStringBuf.WriteRune('a')
   453  	}
   454  	longStringBuf.WriteString("@a.com")
   455  
   456  	err = ra.validateContacts([]string{longStringBuf.String()})
   457  	test.AssertError(t, err, "Too long contacts")
   458  }
   459  
   460  func TestNewRegistration(t *testing.T) {
   461  	_, sa, ra, _, cleanUp := initAuthorities(t)
   462  	defer cleanUp()
   463  	mailto := "mailto:foo@letsencrypt.org"
   464  	acctKeyB, err := AccountKeyB.MarshalJSON()
   465  	test.AssertNotError(t, err, "failed to marshal account key")
   466  	input := &corepb.Registration{
   467  		Contact:         []string{mailto},
   468  		ContactsPresent: true,
   469  		Key:             acctKeyB,
   470  		InitialIP:       parseAndMarshalIP(t, "7.6.6.5"),
   471  	}
   472  
   473  	result, err := ra.NewRegistration(ctx, input)
   474  	if err != nil {
   475  		t.Fatalf("could not create new registration: %s", err)
   476  	}
   477  	test.AssertByteEquals(t, result.Key, acctKeyB)
   478  	test.Assert(t, len(result.Contact) == 1, "Wrong number of contacts")
   479  	test.Assert(t, mailto == (result.Contact)[0], "Contact didn't match")
   480  	test.Assert(t, result.Agreement == "", "Agreement didn't default empty")
   481  
   482  	reg, err := sa.GetRegistration(ctx, &sapb.RegistrationID{Id: result.Id})
   483  	test.AssertNotError(t, err, "Failed to retrieve registration")
   484  	test.AssertByteEquals(t, reg.Key, acctKeyB)
   485  }
   486  
   487  func TestNewRegistrationContactsPresent(t *testing.T) {
   488  	_, _, ra, _, cleanUp := initAuthorities(t)
   489  	defer cleanUp()
   490  	testCases := []struct {
   491  		Name        string
   492  		Reg         *corepb.Registration
   493  		ExpectedErr error
   494  	}{
   495  		{
   496  			Name: "No contacts provided by client ContactsPresent false",
   497  			Reg: &corepb.Registration{
   498  				Key:       newAcctKey(t),
   499  				InitialIP: parseAndMarshalIP(t, "7.6.6.5"),
   500  			},
   501  			ExpectedErr: nil,
   502  		},
   503  		{
   504  			Name: "Empty contact provided by client ContactsPresent true",
   505  			Reg: &corepb.Registration{
   506  				Contact:         []string{},
   507  				ContactsPresent: true,
   508  				Key:             newAcctKey(t),
   509  				InitialIP:       parseAndMarshalIP(t, "7.6.6.4"),
   510  			},
   511  			ExpectedErr: nil,
   512  		},
   513  		{
   514  			Name: "Valid contact provided by client ContactsPresent true",
   515  			Reg: &corepb.Registration{
   516  				Contact:         []string{"mailto:foo@letsencrypt.org"},
   517  				ContactsPresent: true,
   518  				Key:             newAcctKey(t),
   519  				InitialIP:       parseAndMarshalIP(t, "7.6.4.3"),
   520  			},
   521  			ExpectedErr: nil,
   522  		},
   523  		{
   524  			Name: "Valid contact provided by client ContactsPresent false",
   525  			Reg: &corepb.Registration{
   526  				Contact:         []string{"mailto:foo@letsencrypt.org"},
   527  				ContactsPresent: false,
   528  				Key:             newAcctKey(t),
   529  				InitialIP:       parseAndMarshalIP(t, "7.6.6.2"),
   530  			},
   531  			ExpectedErr: fmt.Errorf("account contacts present but contactsPresent false"),
   532  		},
   533  	}
   534  	// For each test case we check that the NewRegistration works as
   535  	// intended with variations of Contact and ContactsPresent fields
   536  	for _, tc := range testCases {
   537  		t.Run(tc.Name, func(t *testing.T) {
   538  			// Create new registration
   539  			_, err := ra.NewRegistration(ctx, tc.Reg)
   540  			// Check error output
   541  			if tc.ExpectedErr == nil {
   542  				test.AssertNotError(t, err, "expected no error for NewRegistration")
   543  			} else {
   544  				test.AssertError(t, err, "expected error for NewRegistration")
   545  				test.AssertEquals(t, err.Error(), tc.ExpectedErr.Error())
   546  			}
   547  		})
   548  	}
   549  }
   550  
   551  type mockSAFailsNewRegistration struct {
   552  	mocks.StorageAuthority
   553  }
   554  
   555  func (sa *mockSAFailsNewRegistration) NewRegistration(_ context.Context, _ *corepb.Registration, _ ...grpc.CallOption) (*corepb.Registration, error) {
   556  	return &corepb.Registration{}, fmt.Errorf("too bad")
   557  }
   558  
   559  func TestNewRegistrationSAFailure(t *testing.T) {
   560  	_, _, ra, _, cleanUp := initAuthorities(t)
   561  	defer cleanUp()
   562  	ra.SA = &mockSAFailsNewRegistration{}
   563  	acctKeyB, err := AccountKeyB.MarshalJSON()
   564  	test.AssertNotError(t, err, "failed to marshal account key")
   565  	input := corepb.Registration{
   566  		Contact:         []string{"mailto:test@example.com"},
   567  		ContactsPresent: true,
   568  		Key:             acctKeyB,
   569  		InitialIP:       parseAndMarshalIP(t, "7.6.6.5"),
   570  	}
   571  	result, err := ra.NewRegistration(ctx, &input)
   572  	if err == nil {
   573  		t.Fatalf("NewRegistration should have failed when SA.NewRegistration failed %#v", result.Key)
   574  	}
   575  }
   576  
   577  func TestNewRegistrationNoFieldOverwrite(t *testing.T) {
   578  	_, _, ra, _, cleanUp := initAuthorities(t)
   579  	defer cleanUp()
   580  	mailto := "mailto:foo@letsencrypt.org"
   581  	acctKeyC, err := AccountKeyC.MarshalJSON()
   582  	test.AssertNotError(t, err, "failed to marshal account key")
   583  	input := &corepb.Registration{
   584  		Id:              23,
   585  		Key:             acctKeyC,
   586  		Contact:         []string{mailto},
   587  		ContactsPresent: true,
   588  		Agreement:       "I agreed",
   589  		InitialIP:       parseAndMarshalIP(t, "5.0.5.0"),
   590  	}
   591  
   592  	result, err := ra.NewRegistration(ctx, input)
   593  	test.AssertNotError(t, err, "Could not create new registration")
   594  	test.Assert(t, result.Id != 23, "ID shouldn't be set by user")
   595  	// TODO: Enable this test case once we validate terms agreement.
   596  	//test.Assert(t, result.Agreement != "I agreed", "Agreement shouldn't be set with invalid URL")
   597  }
   598  
   599  func TestNewRegistrationBadKey(t *testing.T) {
   600  	_, _, ra, _, cleanUp := initAuthorities(t)
   601  	defer cleanUp()
   602  	mailto := "mailto:foo@letsencrypt.org"
   603  	shortKey, err := ShortKey.MarshalJSON()
   604  	test.AssertNotError(t, err, "failed to marshal account key")
   605  	input := &corepb.Registration{
   606  		Contact:         []string{mailto},
   607  		ContactsPresent: true,
   608  		Key:             shortKey,
   609  	}
   610  	_, err = ra.NewRegistration(ctx, input)
   611  	test.AssertError(t, err, "Should have rejected authorization with short key")
   612  }
   613  
   614  // testKey returns a random 2048 bit RSA public key for test registrations
   615  func testKey() *rsa.PublicKey {
   616  	key, _ := rsa.GenerateKey(rand.Reader, 2048)
   617  	return &key.PublicKey
   618  }
   619  
   620  func TestNewRegistrationRateLimit(t *testing.T) {
   621  	_, _, ra, _, cleanUp := initAuthorities(t)
   622  	defer cleanUp()
   623  
   624  	// Specify a dummy rate limit policy that allows 1 registration per exact IP
   625  	// match, and 2 per range.
   626  	ra.rlPolicies = &dummyRateLimitConfig{
   627  		RegistrationsPerIPPolicy: ratelimit.RateLimitPolicy{
   628  			Threshold: 1,
   629  			Window:    config.Duration{Duration: 24 * 90 * time.Hour},
   630  		},
   631  		RegistrationsPerIPRangePolicy: ratelimit.RateLimitPolicy{
   632  			Threshold: 2,
   633  			Window:    config.Duration{Duration: 24 * 90 * time.Hour},
   634  		},
   635  	}
   636  
   637  	// Create one registration for an IPv4 address
   638  	mailto := "mailto:foo@letsencrypt.org"
   639  	reg := &corepb.Registration{
   640  		Contact:         []string{mailto},
   641  		ContactsPresent: true,
   642  		Key:             newAcctKey(t),
   643  		InitialIP:       parseAndMarshalIP(t, "7.6.6.5"),
   644  	}
   645  	// There should be no errors - it is within the RegistrationsPerIP rate limit
   646  	_, err := ra.NewRegistration(ctx, reg)
   647  	test.AssertNotError(t, err, "Unexpected error adding new IPv4 registration")
   648  	test.AssertMetricWithLabelsEquals(t, ra.rlCheckLatency, prometheus.Labels{"limit": ratelimit.RegistrationsPerIP, "decision": ratelimits.Allowed}, 1)
   649  	// There are no overrides for this IP, so the override usage gauge should
   650  	// contain 0 entries with labels matching it.
   651  	test.AssertMetricWithLabelsEquals(t, ra.rlOverrideUsageGauge, prometheus.Labels{"limit": ratelimit.RegistrationsPerIP, "override_key": "7.6.6.5"}, 0)
   652  
   653  	// Create another registration for the same IPv4 address by changing the key
   654  	reg.Key = newAcctKey(t)
   655  
   656  	// There should be an error since a 2nd registration will exceed the
   657  	// RegistrationsPerIP rate limit
   658  	_, err = ra.NewRegistration(ctx, reg)
   659  	test.AssertError(t, err, "No error adding duplicate IPv4 registration")
   660  	test.AssertEquals(t, err.Error(), "too many registrations for this IP: see https://letsencrypt.org/docs/too-many-registrations-for-this-ip/")
   661  	test.AssertMetricWithLabelsEquals(t, ra.rlCheckLatency, prometheus.Labels{"limit": ratelimit.RegistrationsPerIP, "decision": ratelimits.Denied}, 1)
   662  
   663  	// Create a registration for an IPv6 address
   664  	reg.Key = newAcctKey(t)
   665  	reg.InitialIP = parseAndMarshalIP(t, "2001:cdba:1234:5678:9101:1121:3257:9652")
   666  
   667  	// There should be no errors - it is within the RegistrationsPerIP rate limit
   668  	_, err = ra.NewRegistration(ctx, reg)
   669  	test.AssertNotError(t, err, "Unexpected error adding a new IPv6 registration")
   670  	test.AssertMetricWithLabelsEquals(t, ra.rlCheckLatency, prometheus.Labels{"limit": ratelimit.RegistrationsPerIP, "decision": ratelimits.Allowed}, 2)
   671  
   672  	// Create a 2nd registration for the IPv6 address by changing the key
   673  	reg.Key = newAcctKey(t)
   674  
   675  	// There should be an error since a 2nd reg for the same IPv6 address will
   676  	// exceed the RegistrationsPerIP rate limit
   677  	_, err = ra.NewRegistration(ctx, reg)
   678  	test.AssertError(t, err, "No error adding duplicate IPv6 registration")
   679  	test.AssertEquals(t, err.Error(), "too many registrations for this IP: see https://letsencrypt.org/docs/too-many-registrations-for-this-ip/")
   680  	test.AssertMetricWithLabelsEquals(t, ra.rlCheckLatency, prometheus.Labels{"limit": ratelimit.RegistrationsPerIP, "decision": ratelimits.Denied}, 2)
   681  
   682  	// Create a registration for an IPv6 address in the same /48
   683  	reg.Key = newAcctKey(t)
   684  	reg.InitialIP = parseAndMarshalIP(t, "2001:cdba:1234:5678:9101:1121:3257:9653")
   685  
   686  	// There should be no errors since two IPv6 addresses in the same /48 is
   687  	// within the RegistrationsPerIPRange limit
   688  	_, err = ra.NewRegistration(ctx, reg)
   689  	test.AssertNotError(t, err, "Unexpected error adding second IPv6 registration in the same /48")
   690  	test.AssertMetricWithLabelsEquals(t, ra.rlCheckLatency, prometheus.Labels{"limit": ratelimit.RegistrationsPerIPRange, "decision": ratelimits.Allowed}, 2)
   691  
   692  	// Create a registration for yet another IPv6 address in the same /48
   693  	reg.Key = newAcctKey(t)
   694  	reg.InitialIP = parseAndMarshalIP(t, "2001:cdba:1234:5678:9101:1121:3257:9654")
   695  
   696  	// There should be an error since three registrations within the same IPv6
   697  	// /48 is outside of the RegistrationsPerIPRange limit
   698  	_, err = ra.NewRegistration(ctx, reg)
   699  	test.AssertError(t, err, "No error adding a third IPv6 registration in the same /48")
   700  	test.AssertEquals(t, err.Error(), "too many registrations for this IP range: see https://letsencrypt.org/docs/rate-limits/")
   701  	test.AssertMetricWithLabelsEquals(t, ra.rlCheckLatency, prometheus.Labels{"limit": ratelimit.RegistrationsPerIPRange, "decision": ratelimits.Denied}, 1)
   702  }
   703  
   704  func TestRegistrationsPerIPOverrideUsage(t *testing.T) {
   705  	_, _, ra, _, cleanUp := initAuthorities(t)
   706  	defer cleanUp()
   707  
   708  	regIP := net.ParseIP("4.5.6.7")
   709  	rlp := ratelimit.RateLimitPolicy{
   710  		Threshold: 2,
   711  		Window:    config.Duration{Duration: 23 * time.Hour},
   712  		Overrides: map[string]int64{
   713  			regIP.String(): 3,
   714  		},
   715  	}
   716  
   717  	mockCounterAlwaysTwo := func(context.Context, *sapb.CountRegistrationsByIPRequest, ...grpc.CallOption) (*sapb.Count, error) {
   718  		return &sapb.Count{Count: 2}, nil
   719  	}
   720  
   721  	// No error expected, the count of existing registrations for "4.5.6.7"
   722  	// should be 1 below the threshold.
   723  	err := ra.checkRegistrationIPLimit(ctx, rlp, regIP, mockCounterAlwaysTwo)
   724  	test.AssertNotError(t, err, "Unexpected error checking RegistrationsPerIPRange limit")
   725  
   726  	// Expecting ~66% of the override for "4.5.6.7" to be utilized.
   727  	test.AssertMetricWithLabelsEquals(t, ra.rlOverrideUsageGauge, prometheus.Labels{"limit": ratelimit.RegistrationsPerIP, "override_key": regIP.String()}, 0.6666666666666666)
   728  
   729  	mockCounterAlwaysThree := func(context.Context, *sapb.CountRegistrationsByIPRequest, ...grpc.CallOption) (*sapb.Count, error) {
   730  		return &sapb.Count{Count: 3}, nil
   731  	}
   732  
   733  	// Error expected, the count of existing registrations for "4.5.6.7" should
   734  	// be exactly at the threshold.
   735  	err = ra.checkRegistrationIPLimit(ctx, rlp, regIP, mockCounterAlwaysThree)
   736  	test.AssertError(t, err, "Expected error checking RegistrationsPerIPRange limit")
   737  
   738  	// Expecting 100% of the override for "4.5.6.7" to be utilized.
   739  	test.AssertMetricWithLabelsEquals(t, ra.rlOverrideUsageGauge, prometheus.Labels{"limit": ratelimit.RegistrationsPerIP, "override_key": regIP.String()}, 1)
   740  }
   741  
   742  type NoUpdateSA struct {
   743  	mocks.StorageAuthority
   744  }
   745  
   746  func (sa NoUpdateSA) UpdateRegistration(_ context.Context, _ *corepb.Registration, _ ...grpc.CallOption) (*emptypb.Empty, error) {
   747  	return nil, fmt.Errorf("UpdateRegistration() is mocked to always error")
   748  }
   749  
   750  func TestUpdateRegistrationSame(t *testing.T) {
   751  	_, _, ra, _, cleanUp := initAuthorities(t)
   752  	defer cleanUp()
   753  	mailto := "mailto:foo@letsencrypt.org"
   754  
   755  	// Make a new registration with AccountKeyC and a Contact
   756  	acctKeyC, err := AccountKeyC.MarshalJSON()
   757  	test.AssertNotError(t, err, "failed to marshal account key")
   758  	reg := &corepb.Registration{
   759  		Key:             acctKeyC,
   760  		Contact:         []string{mailto},
   761  		ContactsPresent: true,
   762  		Agreement:       "I agreed",
   763  		InitialIP:       parseAndMarshalIP(t, "5.0.5.0"),
   764  	}
   765  	result, err := ra.NewRegistration(ctx, reg)
   766  	test.AssertNotError(t, err, "Could not create new registration")
   767  
   768  	// Switch to a mock SA that will always error if UpdateRegistration() is called
   769  	ra.SA = &NoUpdateSA{}
   770  
   771  	// Make an update to the registration with the same Contact & Agreement values.
   772  	updateSame := &corepb.Registration{
   773  		Id:              result.Id,
   774  		Key:             acctKeyC,
   775  		Contact:         []string{mailto},
   776  		ContactsPresent: true,
   777  		Agreement:       "I agreed",
   778  	}
   779  
   780  	// The update operation should *not* error, even with the NoUpdateSA because
   781  	// UpdateRegistration() should not be called when the update content doesn't
   782  	// actually differ from the existing content
   783  	_, err = ra.UpdateRegistration(ctx, &rapb.UpdateRegistrationRequest{Base: result, Update: updateSame})
   784  	test.AssertNotError(t, err, "Error updating registration")
   785  }
   786  
   787  func TestPerformValidationExpired(t *testing.T) {
   788  	_, sa, ra, fc, cleanUp := initAuthorities(t)
   789  	defer cleanUp()
   790  
   791  	authz := createPendingAuthorization(t, sa, Identifier, fc.Now().Add(-2*time.Hour))
   792  
   793  	_, err := ra.PerformValidation(ctx, &rapb.PerformValidationRequest{
   794  		Authz:          authz,
   795  		ChallengeIndex: int64(ResponseIndex),
   796  	})
   797  	test.AssertError(t, err, "Updated expired authorization")
   798  }
   799  
   800  func TestPerformValidationAlreadyValid(t *testing.T) {
   801  	va, _, ra, _, cleanUp := initAuthorities(t)
   802  	defer cleanUp()
   803  
   804  	// Create a finalized authorization
   805  	exp := ra.clk.Now().Add(365 * 24 * time.Hour)
   806  	authz := core.Authorization{
   807  		ID:             "1337",
   808  		Identifier:     identifier.DNSIdentifier("not-example.com"),
   809  		RegistrationID: 1,
   810  		Status:         "valid",
   811  		Expires:        &exp,
   812  		Challenges: []core.Challenge{
   813  			{
   814  				Token:  core.NewToken(),
   815  				Type:   core.ChallengeTypeHTTP01,
   816  				Status: core.StatusPending,
   817  			},
   818  		},
   819  	}
   820  	authzPB, err := bgrpc.AuthzToPB(authz)
   821  	test.AssertNotError(t, err, "bgrpc.AuthzToPB failed")
   822  
   823  	va.ResultReturn = &vapb.ValidationResult{
   824  		Records: []*corepb.ValidationRecord{
   825  			{
   826  				AddressUsed: []byte("192.168.0.1"),
   827  				Hostname:    "example.com",
   828  				Port:        "8080",
   829  				Url:         "http://example.com/",
   830  			},
   831  		},
   832  		Problems: nil,
   833  	}
   834  
   835  	// A subsequent call to perform validation should return nil due
   836  	// to being short-circuited because of valid authz reuse.
   837  	val, err := ra.PerformValidation(ctx, &rapb.PerformValidationRequest{
   838  		Authz:          authzPB,
   839  		ChallengeIndex: int64(ResponseIndex),
   840  	})
   841  	test.Assert(t, core.AcmeStatus(val.Status) == core.StatusValid, "Validation should have been valid")
   842  	test.AssertNotError(t, err, "Error was not nil, but should have been nil")
   843  }
   844  
   845  func TestPerformValidationSuccess(t *testing.T) {
   846  	va, sa, ra, fc, cleanUp := initAuthorities(t)
   847  	defer cleanUp()
   848  
   849  	// We know this is OK because of TestNewAuthorization
   850  	authzPB := createPendingAuthorization(t, sa, Identifier, fc.Now().Add(12*time.Hour))
   851  
   852  	va.ResultReturn = &vapb.ValidationResult{
   853  		Records: []*corepb.ValidationRecord{
   854  			{
   855  				AddressUsed: []byte("192.168.0.1"),
   856  				Hostname:    "example.com",
   857  				Port:        "8080",
   858  				Url:         "http://example.com/",
   859  			},
   860  		},
   861  		Problems: nil,
   862  	}
   863  
   864  	now := fc.Now()
   865  	challIdx := dnsChallIdx(t, authzPB.Challenges)
   866  	authzPB, err := ra.PerformValidation(ctx, &rapb.PerformValidationRequest{
   867  		Authz:          authzPB,
   868  		ChallengeIndex: challIdx,
   869  	})
   870  	test.AssertNotError(t, err, "PerformValidation failed")
   871  
   872  	var vaRequest *vapb.PerformValidationRequest
   873  	select {
   874  	case r := <-va.request:
   875  		vaRequest = r
   876  	case <-time.After(time.Second):
   877  		t.Fatal("Timed out waiting for DummyValidationAuthority.PerformValidation to complete")
   878  	}
   879  
   880  	// Verify that the VA got the request, and it's the same as the others
   881  	test.AssertEquals(t, authzPB.Challenges[challIdx].Type, vaRequest.Challenge.Type)
   882  	test.AssertEquals(t, authzPB.Challenges[challIdx].Token, vaRequest.Challenge.Token)
   883  
   884  	// Sleep so the RA has a chance to write to the SA
   885  	time.Sleep(100 * time.Millisecond)
   886  
   887  	dbAuthzPB := getAuthorization(t, authzPB.Id, sa)
   888  	t.Log("dbAuthz:", dbAuthzPB)
   889  
   890  	// Verify that the responses are reflected
   891  	challIdx = dnsChallIdx(t, dbAuthzPB.Challenges)
   892  	challenge, err := bgrpc.PBToChallenge(dbAuthzPB.Challenges[challIdx])
   893  	test.AssertNotError(t, err, "Failed to marshall corepb.Challenge to core.Challenge.")
   894  
   895  	test.AssertNotNil(t, vaRequest.Challenge, "Request passed to VA has no challenge")
   896  	test.Assert(t, challenge.Status == core.StatusValid, "challenge was not marked as valid")
   897  
   898  	// The DB authz's expiry should be equal to the current time plus the
   899  	// configured authorization lifetime
   900  	test.AssertEquals(t, dbAuthzPB.ExpiresNS, now.Add(ra.authorizationLifetime).UnixNano())
   901  	test.AssertEquals(t, dbAuthzPB.Expires.AsTime(), now.Add(ra.authorizationLifetime))
   902  
   903  	// Check that validated timestamp was recorded, stored, and retrieved
   904  	expectedValidated := fc.Now()
   905  	test.Assert(t, *challenge.Validated == expectedValidated, "Validated timestamp incorrect or missing")
   906  }
   907  
   908  func TestPerformValidationVAError(t *testing.T) {
   909  	va, sa, ra, fc, cleanUp := initAuthorities(t)
   910  	defer cleanUp()
   911  
   912  	authzPB := createPendingAuthorization(t, sa, Identifier, fc.Now().Add(12*time.Hour))
   913  
   914  	va.ResultError = fmt.Errorf("Something went wrong")
   915  
   916  	challIdx := dnsChallIdx(t, authzPB.Challenges)
   917  	authzPB, err := ra.PerformValidation(ctx, &rapb.PerformValidationRequest{
   918  		Authz:          authzPB,
   919  		ChallengeIndex: challIdx,
   920  	})
   921  
   922  	test.AssertNotError(t, err, "PerformValidation completely failed")
   923  
   924  	var vaRequest *vapb.PerformValidationRequest
   925  	select {
   926  	case r := <-va.request:
   927  		vaRequest = r
   928  	case <-time.After(time.Second):
   929  		t.Fatal("Timed out waiting for DummyValidationAuthority.PerformValidation to complete")
   930  	}
   931  
   932  	// Verify that the VA got the request, and it's the same as the others
   933  	test.AssertEquals(t, authzPB.Challenges[challIdx].Type, vaRequest.Challenge.Type)
   934  	test.AssertEquals(t, authzPB.Challenges[challIdx].Token, vaRequest.Challenge.Token)
   935  
   936  	// Sleep so the RA has a chance to write to the SA
   937  	time.Sleep(100 * time.Millisecond)
   938  
   939  	dbAuthzPB := getAuthorization(t, authzPB.Id, sa)
   940  	t.Log("dbAuthz:", dbAuthzPB)
   941  
   942  	// Verify that the responses are reflected
   943  	challIdx = dnsChallIdx(t, dbAuthzPB.Challenges)
   944  	challenge, err := bgrpc.PBToChallenge(dbAuthzPB.Challenges[challIdx])
   945  	test.AssertNotError(t, err, "Failed to marshall corepb.Challenge to core.Challenge.")
   946  	test.Assert(t, challenge.Status == core.StatusInvalid, "challenge was not marked as invalid")
   947  	test.AssertContains(t, challenge.Error.Error(), "Could not communicate with VA")
   948  	test.Assert(t, challenge.ValidationRecord == nil, "challenge had a ValidationRecord")
   949  
   950  	// Check that validated timestamp was recorded, stored, and retrieved
   951  	expectedValidated := fc.Now()
   952  	test.Assert(t, *challenge.Validated == expectedValidated, "Validated timestamp incorrect or missing")
   953  }
   954  
   955  func TestCertificateKeyNotEqualAccountKey(t *testing.T) {
   956  	_, sa, ra, _, cleanUp := initAuthorities(t)
   957  	defer cleanUp()
   958  
   959  	exp := ra.clk.Now().Add(365 * 24 * time.Hour)
   960  
   961  	authzID := createFinalizedAuthorization(t, sa, "www.example.com", exp, core.ChallengeTypeHTTP01, ra.clk.Now())
   962  
   963  	order, err := sa.NewOrderAndAuthzs(context.Background(), &sapb.NewOrderAndAuthzsRequest{
   964  		NewOrder: &sapb.NewOrderRequest{
   965  			RegistrationID:   Registration.Id,
   966  			ExpiresNS:        exp.UnixNano(),
   967  			Expires:          timestamppb.New(exp),
   968  			Names:            []string{"www.example.com"},
   969  			V2Authorizations: []int64{authzID},
   970  		},
   971  	})
   972  	test.AssertNotError(t, err, "Could not add test order with finalized authz IDs, ready status")
   973  
   974  	csrBytes, err := x509.CreateCertificateRequest(rand.Reader, &x509.CertificateRequest{
   975  		// Registration has key == AccountKeyA
   976  		PublicKey:          AccountKeyA.Key,
   977  		SignatureAlgorithm: x509.SHA256WithRSA,
   978  		DNSNames:           []string{"www.example.com"},
   979  	}, AccountPrivateKey.Key)
   980  	test.AssertNotError(t, err, "Failed to sign CSR")
   981  
   982  	_, err = ra.FinalizeOrder(ctx, &rapb.FinalizeOrderRequest{
   983  		Order: &corepb.Order{
   984  			Status:         string(core.StatusReady),
   985  			Names:          []string{"www.example.com"},
   986  			Id:             order.Id,
   987  			RegistrationID: Registration.Id,
   988  		},
   989  		Csr: csrBytes,
   990  	})
   991  	test.AssertError(t, err, "Should have rejected cert with key = account key")
   992  	test.AssertEquals(t, err.Error(), "certificate public key must be different than account key")
   993  }
   994  
   995  func TestNewOrderRateLimiting(t *testing.T) {
   996  	_, _, ra, fc, cleanUp := initAuthorities(t)
   997  	defer cleanUp()
   998  	ra.orderLifetime = 5 * 24 * time.Hour
   999  
  1000  	rateLimitDuration := 5 * time.Minute
  1001  
  1002  	// Create a dummy rate limit config that sets a NewOrdersPerAccount rate
  1003  	// limit with a very low threshold/short window
  1004  	ra.rlPolicies = &dummyRateLimitConfig{
  1005  		NewOrdersPerAccountPolicy: ratelimit.RateLimitPolicy{
  1006  			Threshold: 1,
  1007  			Window:    config.Duration{Duration: rateLimitDuration},
  1008  		},
  1009  	}
  1010  
  1011  	orderOne := &rapb.NewOrderRequest{
  1012  		RegistrationID: Registration.Id,
  1013  		Names:          []string{"first.example.com"},
  1014  	}
  1015  	orderTwo := &rapb.NewOrderRequest{
  1016  		RegistrationID: Registration.Id,
  1017  		Names:          []string{"second.example.com"},
  1018  	}
  1019  
  1020  	// To start, it should be possible to create a new order
  1021  	_, err := ra.NewOrder(ctx, orderOne)
  1022  	test.AssertNotError(t, err, "NewOrder for orderOne failed")
  1023  
  1024  	// Advance the clock 1s to separate the orders in time
  1025  	fc.Add(time.Second)
  1026  
  1027  	// Creating an order immediately after the first with different names
  1028  	// should fail
  1029  	_, err = ra.NewOrder(ctx, orderTwo)
  1030  	test.AssertError(t, err, "NewOrder for orderTwo succeeded, should have been ratelimited")
  1031  
  1032  	// Creating the first order again should succeed because of order reuse, no
  1033  	// new pending order is produced.
  1034  	_, err = ra.NewOrder(ctx, orderOne)
  1035  	test.AssertNotError(t, err, "Reuse of orderOne failed")
  1036  
  1037  	// Advancing the clock by 2 * the rate limit duration should allow orderTwo to
  1038  	// succeed
  1039  	fc.Add(2 * rateLimitDuration)
  1040  	_, err = ra.NewOrder(ctx, orderTwo)
  1041  	test.AssertNotError(t, err, "NewOrder for orderTwo failed after advancing clock")
  1042  }
  1043  
  1044  // TestEarlyOrderRateLimiting tests that NewOrder applies the certificates per
  1045  // name/per FQDN rate limits against the order names.
  1046  func TestEarlyOrderRateLimiting(t *testing.T) {
  1047  	_, _, ra, _, cleanUp := initAuthorities(t)
  1048  	defer cleanUp()
  1049  	ra.orderLifetime = 5 * 24 * time.Hour
  1050  
  1051  	rateLimitDuration := 5 * time.Minute
  1052  
  1053  	domain := "early-ratelimit-example.com"
  1054  
  1055  	// Set a mock RL policy with a CertificatesPerName threshold for the domain
  1056  	// name so low if it were enforced it would prevent a new order for any names.
  1057  	ra.rlPolicies = &dummyRateLimitConfig{
  1058  		CertificatesPerNamePolicy: ratelimit.RateLimitPolicy{
  1059  			Threshold: 10,
  1060  			Window:    config.Duration{Duration: rateLimitDuration},
  1061  			// Setting the Threshold to 0 skips applying the rate limit. Setting an
  1062  			// override to 0 does the trick.
  1063  			Overrides: map[string]int64{
  1064  				domain: 0,
  1065  			},
  1066  		},
  1067  		NewOrdersPerAccountPolicy: ratelimit.RateLimitPolicy{
  1068  			Threshold: 10,
  1069  			Window:    config.Duration{Duration: rateLimitDuration},
  1070  		},
  1071  	}
  1072  
  1073  	// Request an order for the test domain
  1074  	newOrder := &rapb.NewOrderRequest{
  1075  		RegistrationID: Registration.Id,
  1076  		Names:          []string{domain},
  1077  	}
  1078  
  1079  	// With the feature flag enabled the NewOrder request should fail because of
  1080  	// the CertificatesPerNamePolicy.
  1081  	_, err := ra.NewOrder(ctx, newOrder)
  1082  	test.AssertError(t, err, "NewOrder did not apply cert rate limits with feature flag enabled")
  1083  
  1084  	var bErr *berrors.BoulderError
  1085  	test.Assert(t, errors.As(err, &bErr), "NewOrder did not return a boulder error")
  1086  	test.AssertEquals(t, bErr.RetryAfter, rateLimitDuration)
  1087  
  1088  	// The err should be the expected rate limit error
  1089  	expected := "too many certificates already issued for \"early-ratelimit-example.com\". Retry after 2015-03-04T05:05:00Z: see https://letsencrypt.org/docs/rate-limits/"
  1090  	test.AssertEquals(t, bErr.Error(), expected)
  1091  }
  1092  
  1093  func TestAuthzFailedRateLimitingNewOrder(t *testing.T) {
  1094  	_, _, ra, _, cleanUp := initAuthorities(t)
  1095  	defer cleanUp()
  1096  
  1097  	ra.rlPolicies = &dummyRateLimitConfig{
  1098  		InvalidAuthorizationsPerAccountPolicy: ratelimit.RateLimitPolicy{
  1099  			Threshold: 1,
  1100  			Window:    config.Duration{Duration: 1 * time.Hour},
  1101  		},
  1102  	}
  1103  
  1104  	testcase := func() {
  1105  		limit := ra.rlPolicies.InvalidAuthorizationsPerAccount()
  1106  		ra.SA = &mockInvalidAuthorizationsAuthority{domainWithFailures: "all.i.do.is.lose.com"}
  1107  		err := ra.checkInvalidAuthorizationLimits(ctx, Registration.Id,
  1108  			[]string{"charlie.brown.com", "all.i.do.is.lose.com"}, limit)
  1109  		test.AssertError(t, err, "checkInvalidAuthorizationLimits did not encounter expected rate limit error")
  1110  		test.AssertEquals(t, err.Error(), "too many failed authorizations recently: see https://letsencrypt.org/docs/failed-validation-limit/")
  1111  	}
  1112  
  1113  	testcase()
  1114  }
  1115  
  1116  func TestDomainsForRateLimiting(t *testing.T) {
  1117  	domains := domainsForRateLimiting([]string{})
  1118  	test.AssertEquals(t, len(domains), 0)
  1119  
  1120  	domains = domainsForRateLimiting([]string{"www.example.com", "example.com"})
  1121  	test.AssertDeepEquals(t, domains, []string{"example.com"})
  1122  
  1123  	domains = domainsForRateLimiting([]string{"www.example.com", "example.com", "www.example.co.uk"})
  1124  	test.AssertDeepEquals(t, domains, []string{"example.co.uk", "example.com"})
  1125  
  1126  	domains = domainsForRateLimiting([]string{"www.example.com", "example.com", "www.example.co.uk", "co.uk"})
  1127  	test.AssertDeepEquals(t, domains, []string{"co.uk", "example.co.uk", "example.com"})
  1128  
  1129  	domains = domainsForRateLimiting([]string{"foo.bar.baz.www.example.com", "baz.example.com"})
  1130  	test.AssertDeepEquals(t, domains, []string{"example.com"})
  1131  
  1132  	domains = domainsForRateLimiting([]string{"github.io", "foo.github.io", "bar.github.io"})
  1133  	test.AssertDeepEquals(t, domains, []string{"bar.github.io", "foo.github.io", "github.io"})
  1134  }
  1135  
  1136  type mockSAWithNameCounts struct {
  1137  	mocks.StorageAuthority
  1138  	nameCounts *sapb.CountByNames
  1139  	t          *testing.T
  1140  	clk        clock.FakeClock
  1141  }
  1142  
  1143  func (m mockSAWithNameCounts) CountCertificatesByNames(ctx context.Context, req *sapb.CountCertificatesByNamesRequest, _ ...grpc.CallOption) (*sapb.CountByNames, error) {
  1144  	expectedLatest := m.clk.Now()
  1145  	if req.Range.LatestNS != expectedLatest.UnixNano() {
  1146  		m.t.Errorf("incorrect latestNS: got '%d', expected '%d'", req.Range.LatestNS, expectedLatest.UnixNano())
  1147  	}
  1148  	if req.Range.Latest.AsTime() != expectedLatest {
  1149  		m.t.Errorf("incorrect latest: got '%v', expected '%v'", req.Range.Latest.AsTime(), expectedLatest)
  1150  	}
  1151  	expectedEarliest := m.clk.Now().Add(-23 * time.Hour)
  1152  	if req.Range.EarliestNS != expectedEarliest.UnixNano() {
  1153  		m.t.Errorf("incorrect earliestNS: got '%d', expected '%d'", req.Range.EarliestNS, expectedEarliest.UnixNano())
  1154  	}
  1155  	if req.Range.Earliest.AsTime() != expectedEarliest {
  1156  		m.t.Errorf("incorrect earliest: got '%v', expected '%v'", req.Range.Earliest.AsTime(), expectedEarliest)
  1157  	}
  1158  	counts := make(map[string]int64)
  1159  	for _, name := range req.Names {
  1160  		if count, ok := m.nameCounts.Counts[name]; ok {
  1161  			counts[name] = count
  1162  		}
  1163  	}
  1164  	return &sapb.CountByNames{Counts: counts}, nil
  1165  }
  1166  
  1167  func TestCheckCertificatesPerNameLimit(t *testing.T) {
  1168  	_, _, ra, fc, cleanUp := initAuthorities(t)
  1169  	defer cleanUp()
  1170  
  1171  	rlp := ratelimit.RateLimitPolicy{
  1172  		Threshold: 3,
  1173  		Window:    config.Duration{Duration: 23 * time.Hour},
  1174  		Overrides: map[string]int64{
  1175  			"bigissuer.com":     100,
  1176  			"smallissuer.co.uk": 1,
  1177  		},
  1178  	}
  1179  
  1180  	mockSA := &mockSAWithNameCounts{
  1181  		nameCounts: &sapb.CountByNames{Counts: map[string]int64{"example.com": 1}},
  1182  		clk:        fc,
  1183  		t:          t,
  1184  	}
  1185  
  1186  	ra.SA = mockSA
  1187  
  1188  	// One base domain, below threshold
  1189  	err := ra.checkCertificatesPerNameLimit(ctx, []string{"www.example.com", "example.com"}, rlp, 99)
  1190  	test.AssertNotError(t, err, "rate limited example.com incorrectly")
  1191  
  1192  	// Two base domains, one above threshold, one below
  1193  	mockSA.nameCounts.Counts["example.com"] = 10
  1194  	mockSA.nameCounts.Counts["good-example.com"] = 1
  1195  	err = ra.checkCertificatesPerNameLimit(ctx, []string{"www.example.com", "example.com", "good-example.com"}, rlp, 99)
  1196  	test.AssertError(t, err, "incorrectly failed to rate limit example.com")
  1197  	test.AssertErrorIs(t, err, berrors.RateLimit)
  1198  	// There are no overrides for "example.com", so the override usage gauge
  1199  	// should contain 0 entries with labels matching it.
  1200  	test.AssertMetricWithLabelsEquals(t, ra.rlOverrideUsageGauge, prometheus.Labels{"limit": ratelimit.CertificatesPerName, "override_key": "example.com"}, 0)
  1201  	// Verify it has no sub errors as there is only one bad name
  1202  	test.AssertEquals(t, err.Error(), "too many certificates already issued for \"example.com\". Retry after 1970-01-01T23:00:00Z: see https://letsencrypt.org/docs/rate-limits/")
  1203  	var bErr *berrors.BoulderError
  1204  	test.AssertErrorWraps(t, err, &bErr)
  1205  	test.AssertEquals(t, len(bErr.SubErrors), 0)
  1206  
  1207  	// Three base domains, two above threshold, one below
  1208  	mockSA.nameCounts.Counts["example.com"] = 10
  1209  	mockSA.nameCounts.Counts["other-example.com"] = 10
  1210  	mockSA.nameCounts.Counts["good-example.com"] = 1
  1211  	err = ra.checkCertificatesPerNameLimit(ctx, []string{"example.com", "other-example.com", "good-example.com"}, rlp, 99)
  1212  	test.AssertError(t, err, "incorrectly failed to rate limit example.com, other-example.com")
  1213  	test.AssertErrorIs(t, err, berrors.RateLimit)
  1214  	// Verify it has two sub errors as there are two bad names
  1215  	test.AssertEquals(t, err.Error(), "too many certificates already issued for multiple names (\"example.com\" and 2 others). Retry after 1970-01-01T23:00:00Z: see https://letsencrypt.org/docs/rate-limits/")
  1216  	test.AssertErrorWraps(t, err, &bErr)
  1217  	test.AssertEquals(t, len(bErr.SubErrors), 2)
  1218  
  1219  	// SA misbehaved and didn't send back a count for every input name
  1220  	err = ra.checkCertificatesPerNameLimit(ctx, []string{"zombo.com", "www.example.com", "example.com"}, rlp, 99)
  1221  	test.AssertError(t, err, "incorrectly failed to error on misbehaving SA")
  1222  
  1223  	// Two base domains, one above threshold but with an override.
  1224  	mockSA.nameCounts.Counts["example.com"] = 0
  1225  	mockSA.nameCounts.Counts["bigissuer.com"] = 50
  1226  	err = ra.checkCertificatesPerNameLimit(ctx, []string{"www.example.com", "subdomain.bigissuer.com"}, rlp, 99)
  1227  	test.AssertNotError(t, err, "incorrectly rate limited bigissuer")
  1228  	// "bigissuer.com" has an override of 100 and they've issued 50. We do
  1229  	// not count issuance that has yet to occur, so we expect to see 50%
  1230  	// utilization.
  1231  	test.AssertMetricWithLabelsEquals(t, ra.rlOverrideUsageGauge, prometheus.Labels{"limit": ratelimit.CertificatesPerName, "override_key": "bigissuer.com"}, .5)
  1232  
  1233  	// Two base domains, one above its override
  1234  	mockSA.nameCounts.Counts["example.com"] = 10
  1235  	mockSA.nameCounts.Counts["bigissuer.com"] = 100
  1236  	err = ra.checkCertificatesPerNameLimit(ctx, []string{"www.example.com", "subdomain.bigissuer.com"}, rlp, 99)
  1237  	test.AssertError(t, err, "incorrectly failed to rate limit bigissuer")
  1238  	test.AssertErrorIs(t, err, berrors.RateLimit)
  1239  	// "bigissuer.com" has an override of 100 and they've issued 100. So we
  1240  	// expect to see 100% utilization.
  1241  	test.AssertMetricWithLabelsEquals(t, ra.rlOverrideUsageGauge, prometheus.Labels{"limit": ratelimit.CertificatesPerName, "override_key": "bigissuer.com"}, 1)
  1242  
  1243  	// One base domain, above its override (which is below threshold)
  1244  	mockSA.nameCounts.Counts["smallissuer.co.uk"] = 1
  1245  	err = ra.checkCertificatesPerNameLimit(ctx, []string{"www.smallissuer.co.uk"}, rlp, 99)
  1246  	test.AssertError(t, err, "incorrectly failed to rate limit smallissuer")
  1247  	test.AssertErrorIs(t, err, berrors.RateLimit)
  1248  	// "smallissuer.co.uk" has an override of 1 and they've issued 1. So we
  1249  	// expect to see 100% utilization.
  1250  	test.AssertMetricWithLabelsEquals(t, ra.rlOverrideUsageGauge, prometheus.Labels{"limit": ratelimit.CertificatesPerName, "override_key": "smallissuer.co.uk"}, 1)
  1251  }
  1252  
  1253  // TestCheckExactCertificateLimit tests that the duplicate certificate limit
  1254  // applied to FQDN sets is respected.
  1255  func TestCheckExactCertificateLimit(t *testing.T) {
  1256  	_, _, ra, _, cleanUp := initAuthorities(t)
  1257  	defer cleanUp()
  1258  
  1259  	// Create a rate limit with a small threshold
  1260  	const dupeCertLimit = 3
  1261  	rlp := ratelimit.RateLimitPolicy{
  1262  		Threshold: dupeCertLimit,
  1263  		Window:    config.Duration{Duration: 24 * time.Hour},
  1264  	}
  1265  
  1266  	// Create a mock SA that has a count of already issued certificates for some
  1267  	// test names
  1268  	firstIssuanceTimestamp := ra.clk.Now().Add(-rlp.Window.Duration)
  1269  	fITS2 := firstIssuanceTimestamp.Add(time.Hour * 23)
  1270  	fITS3 := firstIssuanceTimestamp.Add(time.Hour * 16)
  1271  	fITS4 := firstIssuanceTimestamp.Add(time.Hour * 8)
  1272  	issuanceTimestampsNS := []int64{
  1273  		fITS2.UnixNano(),
  1274  		fITS3.UnixNano(),
  1275  		fITS4.UnixNano(),
  1276  		firstIssuanceTimestamp.UnixNano(),
  1277  	}
  1278  	issuanceTimestamps := []*timestamppb.Timestamp{
  1279  		timestamppb.New(fITS2),
  1280  		timestamppb.New(fITS3),
  1281  		timestamppb.New(fITS4),
  1282  		timestamppb.New(firstIssuanceTimestamp),
  1283  	}
  1284  	// Our window is 24 hours and our threshold is 3 issuance. If our most
  1285  	// recent issuance was 1 hour ago, we expect the next token to be available
  1286  	// 8 hours from issuance time or 7 hours from now.
  1287  	expectRetryAfterNS := time.Unix(0, issuanceTimestampsNS[0]).Add(time.Hour * 8).Format(time.RFC3339)
  1288  	expectRetryAfter := issuanceTimestamps[0].AsTime().Add(time.Hour * 8).Format(time.RFC3339)
  1289  	test.AssertEquals(t, expectRetryAfterNS, expectRetryAfter)
  1290  	ra.SA = &mockSAWithFQDNSet{
  1291  		issuanceTimestamps: map[string]*sapb.Timestamps{
  1292  			"none.example.com":          {TimestampsNS: []int64{}, Timestamps: []*timestamppb.Timestamp{}},
  1293  			"under.example.com":         {TimestampsNS: issuanceTimestampsNS[3:3], Timestamps: issuanceTimestamps[3:3]},
  1294  			"equalbutvalid.example.com": {TimestampsNS: issuanceTimestampsNS[1:3], Timestamps: issuanceTimestamps[1:3]},
  1295  			"over.example.com":          {TimestampsNS: issuanceTimestampsNS[0:3], Timestamps: issuanceTimestamps[0:3]},
  1296  		},
  1297  		t: t,
  1298  	}
  1299  
  1300  	testCases := []struct {
  1301  		Name        string
  1302  		Domain      string
  1303  		ExpectedErr error
  1304  	}{
  1305  		{
  1306  			Name:        "FQDN set issuances none",
  1307  			Domain:      "none.example.com",
  1308  			ExpectedErr: nil,
  1309  		},
  1310  		{
  1311  			Name:        "FQDN set issuances less than limit",
  1312  			Domain:      "under.example.com",
  1313  			ExpectedErr: nil,
  1314  		},
  1315  		{
  1316  			Name:        "FQDN set issuances equal to limit",
  1317  			Domain:      "equalbutvalid.example.com",
  1318  			ExpectedErr: nil,
  1319  		},
  1320  		{
  1321  			Name:   "FQDN set issuances above limit NS",
  1322  			Domain: "over.example.com",
  1323  			ExpectedErr: fmt.Errorf(
  1324  				"too many certificates (3) already issued for this exact set of domains in the last 24 hours: over.example.com, retry after %s: see https://letsencrypt.org/docs/duplicate-certificate-limit/",
  1325  				expectRetryAfterNS,
  1326  			),
  1327  		},
  1328  		{
  1329  			Name:   "FQDN set issuances above limit",
  1330  			Domain: "over.example.com",
  1331  			ExpectedErr: fmt.Errorf(
  1332  				"too many certificates (3) already issued for this exact set of domains in the last 24 hours: over.example.com, retry after %s: see https://letsencrypt.org/docs/duplicate-certificate-limit/",
  1333  				expectRetryAfter,
  1334  			),
  1335  		},
  1336  	}
  1337  
  1338  	// For each test case we check that the certificatesPerFQDNSetLimit is applied
  1339  	// as we expect
  1340  	for _, tc := range testCases {
  1341  		t.Run(tc.Name, func(t *testing.T) {
  1342  			result := ra.checkCertificatesPerFQDNSetLimit(ctx, []string{tc.Domain}, rlp, 0)
  1343  			if tc.ExpectedErr == nil {
  1344  				test.AssertNotError(t, result, fmt.Sprintf("Expected no error for %q", tc.Domain))
  1345  			} else {
  1346  				test.AssertError(t, result, fmt.Sprintf("Expected error for %q", tc.Domain))
  1347  				test.AssertEquals(t, result.Error(), tc.ExpectedErr.Error())
  1348  			}
  1349  		})
  1350  	}
  1351  }
  1352  
  1353  func TestRegistrationUpdate(t *testing.T) {
  1354  	oldURL := "http://old.invalid"
  1355  	newURL := "http://new.invalid"
  1356  	base := &corepb.Registration{
  1357  		Id:        1,
  1358  		Contact:   []string{oldURL},
  1359  		Agreement: "",
  1360  	}
  1361  	update := &corepb.Registration{
  1362  		Contact:         []string{newURL},
  1363  		ContactsPresent: true,
  1364  		Agreement:       "totally!",
  1365  	}
  1366  
  1367  	res, changed := mergeUpdate(base, update)
  1368  	test.AssertEquals(t, changed, true)
  1369  	test.AssertEquals(t, res.Contact[0], update.Contact[0])
  1370  	test.AssertEquals(t, res.Agreement, update.Agreement)
  1371  
  1372  	// Make sure that a `MergeUpdate` call with an empty string doesn't produce an
  1373  	// error and results in a change to the base reg.
  1374  	emptyUpdate := &corepb.Registration{
  1375  		Contact:         []string{""},
  1376  		ContactsPresent: true,
  1377  		Agreement:       "totally!",
  1378  	}
  1379  	_, changed = mergeUpdate(res, emptyUpdate)
  1380  	test.AssertEquals(t, changed, true)
  1381  }
  1382  
  1383  func TestRegistrationContactUpdate(t *testing.T) {
  1384  	contactURL := "mailto://example@example.com"
  1385  
  1386  	// Test that a registration contact can be removed by updating with an empty
  1387  	// Contact slice.
  1388  	base := &corepb.Registration{
  1389  		Id:        1,
  1390  		Contact:   []string{contactURL},
  1391  		Agreement: "totally!",
  1392  	}
  1393  	update := &corepb.Registration{
  1394  		Id:              1,
  1395  		Contact:         []string{},
  1396  		ContactsPresent: true,
  1397  		Agreement:       "totally!",
  1398  	}
  1399  	res, changed := mergeUpdate(base, update)
  1400  	test.AssertEquals(t, changed, true)
  1401  	test.Assert(t, len(res.Contact) == 0, "Contact was not deleted in update")
  1402  
  1403  	// Test that a registration contact isn't changed when an update is performed
  1404  	// with no Contact field
  1405  	base = &corepb.Registration{
  1406  		Id:        1,
  1407  		Contact:   []string{contactURL},
  1408  		Agreement: "totally!",
  1409  	}
  1410  	update = &corepb.Registration{
  1411  		Id:        1,
  1412  		Agreement: "totally!",
  1413  	}
  1414  	res, changed = mergeUpdate(base, update)
  1415  	test.AssertEquals(t, changed, false)
  1416  	test.Assert(t, len(res.Contact) == 1, "len(Contact) was updated unexpectedly")
  1417  	test.Assert(t, (res.Contact)[0] == contactURL, "Contact was changed unexpectedly")
  1418  }
  1419  
  1420  func TestRegistrationKeyUpdate(t *testing.T) {
  1421  	oldKey, err := rsa.GenerateKey(rand.Reader, 512)
  1422  	test.AssertNotError(t, err, "rsa.GenerateKey() for oldKey failed")
  1423  	oldKeyJSON, err := jose.JSONWebKey{Key: oldKey}.MarshalJSON()
  1424  	test.AssertNotError(t, err, "MarshalJSON for oldKey failed")
  1425  
  1426  	base := &corepb.Registration{Key: oldKeyJSON}
  1427  	update := &corepb.Registration{}
  1428  	_, changed := mergeUpdate(base, update)
  1429  	test.Assert(t, !changed, "mergeUpdate changed the key with empty update")
  1430  
  1431  	newKey, err := rsa.GenerateKey(rand.Reader, 1024)
  1432  	test.AssertNotError(t, err, "rsa.GenerateKey() for newKey failed")
  1433  	newKeyJSON, err := jose.JSONWebKey{Key: newKey}.MarshalJSON()
  1434  	test.AssertNotError(t, err, "MarshalJSON for newKey failed")
  1435  
  1436  	update = &corepb.Registration{Key: newKeyJSON}
  1437  	res, changed := mergeUpdate(base, update)
  1438  	test.Assert(t, changed, "mergeUpdate didn't change the key with non-empty update")
  1439  	test.AssertByteEquals(t, res.Key, update.Key)
  1440  }
  1441  
  1442  // A mockSAWithFQDNSet is a mock StorageAuthority that supports
  1443  // CountCertificatesByName as well as FQDNSetExists. This allows testing
  1444  // checkCertificatesPerNameRateLimit's FQDN exemption logic.
  1445  type mockSAWithFQDNSet struct {
  1446  	mocks.StorageAuthority
  1447  	fqdnSet            map[string]bool
  1448  	issuanceTimestamps map[string]*sapb.Timestamps
  1449  
  1450  	t *testing.T
  1451  }
  1452  
  1453  // Construct the FQDN Set key the same way as the SA (by using
  1454  // `core.UniqueLowerNames`, joining the names with a `,` and hashing them)
  1455  // but return a string so it can be used as a key in m.fqdnSet.
  1456  func (m mockSAWithFQDNSet) hashNames(names []string) string {
  1457  	names = core.UniqueLowerNames(names)
  1458  	hash := sha256.Sum256([]byte(strings.Join(names, ",")))
  1459  	return string(hash[:])
  1460  }
  1461  
  1462  // Add a set of domain names to the FQDN set
  1463  func (m mockSAWithFQDNSet) addFQDNSet(names []string) {
  1464  	hash := m.hashNames(names)
  1465  	m.fqdnSet[hash] = true
  1466  }
  1467  
  1468  // Search for a set of domain names in the FQDN set map
  1469  func (m mockSAWithFQDNSet) FQDNSetExists(_ context.Context, req *sapb.FQDNSetExistsRequest, _ ...grpc.CallOption) (*sapb.Exists, error) {
  1470  	hash := m.hashNames(req.Domains)
  1471  	if _, exists := m.fqdnSet[hash]; exists {
  1472  		return &sapb.Exists{Exists: true}, nil
  1473  	}
  1474  	return &sapb.Exists{Exists: false}, nil
  1475  }
  1476  
  1477  // Return a map of domain -> certificate count.
  1478  func (m mockSAWithFQDNSet) CountCertificatesByNames(ctx context.Context, req *sapb.CountCertificatesByNamesRequest, _ ...grpc.CallOption) (*sapb.CountByNames, error) {
  1479  	counts := make(map[string]int64)
  1480  	for _, name := range req.Names {
  1481  		entry, ok := m.issuanceTimestamps[name]
  1482  		if ok {
  1483  			counts[name] = int64(len(entry.TimestampsNS))
  1484  		}
  1485  	}
  1486  	return &sapb.CountByNames{Counts: counts}, nil
  1487  }
  1488  
  1489  func (m mockSAWithFQDNSet) CountFQDNSets(_ context.Context, req *sapb.CountFQDNSetsRequest, _ ...grpc.CallOption) (*sapb.Count, error) {
  1490  	var total int64
  1491  	for _, name := range req.Domains {
  1492  		entry, ok := m.issuanceTimestamps[name]
  1493  		if ok {
  1494  			total += int64(len(entry.TimestampsNS))
  1495  		}
  1496  	}
  1497  	return &sapb.Count{Count: total}, nil
  1498  }
  1499  
  1500  func (m mockSAWithFQDNSet) FQDNSetTimestampsForWindow(_ context.Context, req *sapb.CountFQDNSetsRequest, _ ...grpc.CallOption) (*sapb.Timestamps, error) {
  1501  	if len(req.Domains) == 1 {
  1502  		return m.issuanceTimestamps[req.Domains[0]], nil
  1503  	} else {
  1504  		return nil, fmt.Errorf("FQDNSetTimestampsForWindow mock only supports a single domain")
  1505  	}
  1506  }
  1507  
  1508  // Tests for boulder issue 1925[0] - that the `checkCertificatesPerNameLimit`
  1509  // properly honours the FQDNSet exemption. E.g. that if a set of domains has
  1510  // reached the certificates per name rate limit policy threshold but the exact
  1511  // same set of FQDN's was previously issued, then it should not be considered
  1512  // over the certificates per name limit.
  1513  //
  1514  // [0] https://github.com/letsencrypt/boulder/issues/1925
  1515  func TestCheckFQDNSetRateLimitOverride(t *testing.T) {
  1516  	_, _, ra, _, cleanUp := initAuthorities(t)
  1517  	defer cleanUp()
  1518  
  1519  	// Simple policy that only allows 1 certificate per name.
  1520  	certsPerNamePolicy := ratelimit.RateLimitPolicy{
  1521  		Threshold: 1,
  1522  		Window:    config.Duration{Duration: 24 * time.Hour},
  1523  	}
  1524  
  1525  	// Create a mock SA that has both name counts and an FQDN set
  1526  	now := ra.clk.Now()
  1527  	tsNS := now.UnixNano()
  1528  	ts := timestamppb.New(now)
  1529  	mockSA := &mockSAWithFQDNSet{
  1530  		issuanceTimestamps: map[string]*sapb.Timestamps{
  1531  			"example.com": {TimestampsNS: []int64{tsNS, tsNS}, Timestamps: []*timestamppb.Timestamp{ts, ts}},
  1532  			"zombo.com":   {TimestampsNS: []int64{tsNS, tsNS}, Timestamps: []*timestamppb.Timestamp{ts, ts}},
  1533  		},
  1534  		fqdnSet: map[string]bool{},
  1535  		t:       t,
  1536  	}
  1537  	ra.SA = mockSA
  1538  
  1539  	// First check that without a pre-existing FQDN set that the provided set of
  1540  	// names is rate limited due to being over the certificates per name limit for
  1541  	// "example.com" and "zombo.com"
  1542  	err := ra.checkCertificatesPerNameLimit(ctx, []string{"www.example.com", "example.com", "www.zombo.com"}, certsPerNamePolicy, 99)
  1543  	test.AssertError(t, err, "certificate per name rate limit not applied correctly")
  1544  
  1545  	// Now add a FQDN set entry for these domains
  1546  	mockSA.addFQDNSet([]string{"www.example.com", "example.com", "www.zombo.com"})
  1547  
  1548  	// A subsequent check against the certificates per name limit should now be OK
  1549  	// - there exists a FQDN set and so the exemption to this particular limit
  1550  	// comes into effect.
  1551  	err = ra.checkCertificatesPerNameLimit(ctx, []string{"www.example.com", "example.com", "www.zombo.com"}, certsPerNamePolicy, 99)
  1552  	test.AssertNotError(t, err, "FQDN set certificate per name exemption not applied correctly")
  1553  }
  1554  
  1555  // TestExactPublicSuffixCertLimit tests the behaviour of issue #2681 with and
  1556  // without the feature flag for the fix enabled.
  1557  // See https://github.com/letsencrypt/boulder/issues/2681
  1558  func TestExactPublicSuffixCertLimit(t *testing.T) {
  1559  	_, _, ra, fc, cleanUp := initAuthorities(t)
  1560  	defer cleanUp()
  1561  
  1562  	// Simple policy that only allows 2 certificates per name.
  1563  	certsPerNamePolicy := ratelimit.RateLimitPolicy{
  1564  		Threshold: 2,
  1565  		Window:    config.Duration{Duration: 23 * time.Hour},
  1566  	}
  1567  
  1568  	// We use "dedyn.io" and "dynv6.net" domains for the test on the implicit
  1569  	// assumption that both domains are present on the public suffix list.
  1570  	// Quickly verify that this is true before continuing with the rest of the test.
  1571  	_, err := publicsuffix.Domain("dedyn.io")
  1572  	test.AssertError(t, err, "dedyn.io was not on the public suffix list, invaliding the test")
  1573  	_, err = publicsuffix.Domain("dynv6.net")
  1574  	test.AssertError(t, err, "dynv6.net was not on the public suffix list, invaliding the test")
  1575  
  1576  	// Back the mock SA with counts as if so far we have issued the following
  1577  	// certificates for the following domains:
  1578  	//   - test.dedyn.io (once)
  1579  	//   - test2.dedyn.io (once)
  1580  	//   - dynv6.net (twice)
  1581  	mockSA := &mockSAWithNameCounts{
  1582  		nameCounts: &sapb.CountByNames{
  1583  			Counts: map[string]int64{
  1584  				"test.dedyn.io":  1,
  1585  				"test2.dedyn.io": 1,
  1586  				"test3.dedyn.io": 0,
  1587  				"dedyn.io":       0,
  1588  				"dynv6.net":      2,
  1589  			},
  1590  		},
  1591  		clk: fc,
  1592  		t:   t,
  1593  	}
  1594  	ra.SA = mockSA
  1595  
  1596  	// Trying to issue for "test3.dedyn.io" and "dedyn.io" should succeed because
  1597  	// test3.dedyn.io has no certificates and "dedyn.io" is an exact public suffix
  1598  	// match with no certificates issued for it.
  1599  	err = ra.checkCertificatesPerNameLimit(ctx, []string{"test3.dedyn.io", "dedyn.io"}, certsPerNamePolicy, 99)
  1600  	test.AssertNotError(t, err, "certificate per name rate limit not applied correctly")
  1601  
  1602  	// Trying to issue for "test3.dedyn.io" and "dynv6.net" should fail because
  1603  	// "dynv6.net" is an exact public suffic match with 2 certificates issued for
  1604  	// it.
  1605  	err = ra.checkCertificatesPerNameLimit(ctx, []string{"test3.dedyn.io", "dynv6.net"}, certsPerNamePolicy, 99)
  1606  	test.AssertError(t, err, "certificate per name rate limit not applied correctly")
  1607  }
  1608  
  1609  func TestDeactivateAuthorization(t *testing.T) {
  1610  	_, sa, ra, _, cleanUp := initAuthorities(t)
  1611  	defer cleanUp()
  1612  
  1613  	exp := ra.clk.Now().Add(365 * 24 * time.Hour)
  1614  	authzID := createFinalizedAuthorization(t, sa, "not-example.com", exp, core.ChallengeTypeHTTP01, ra.clk.Now())
  1615  	dbAuthzPB := getAuthorization(t, fmt.Sprint(authzID), sa)
  1616  	_, err := ra.DeactivateAuthorization(ctx, dbAuthzPB)
  1617  	test.AssertNotError(t, err, "Could not deactivate authorization")
  1618  	deact, err := sa.GetAuthorization2(ctx, &sapb.AuthorizationID2{Id: authzID})
  1619  	test.AssertNotError(t, err, "Could not get deactivated authorization with ID "+dbAuthzPB.Id)
  1620  	test.AssertEquals(t, deact.Status, string(core.StatusDeactivated))
  1621  }
  1622  
  1623  func TestDeactivateRegistration(t *testing.T) {
  1624  	_, _, ra, _, cleanUp := initAuthorities(t)
  1625  	defer cleanUp()
  1626  
  1627  	// Deactivate failure because incomplete registration provided
  1628  	_, err := ra.DeactivateRegistration(context.Background(), &corepb.Registration{})
  1629  	test.AssertDeepEquals(t, err, fmt.Errorf("incomplete gRPC request message"))
  1630  
  1631  	// Deactivate failure because registration status already deactivated
  1632  	_, err = ra.DeactivateRegistration(context.Background(),
  1633  		&corepb.Registration{Id: 1, Status: string(core.StatusDeactivated)})
  1634  	test.AssertError(t, err, "DeactivateRegistration failed with a non-valid registration")
  1635  
  1636  	// Deactivate success with valid registration
  1637  	_, err = ra.DeactivateRegistration(context.Background(),
  1638  		&corepb.Registration{Id: 1, Status: string(core.StatusValid)})
  1639  	test.AssertNotError(t, err, "DeactivateRegistration failed")
  1640  
  1641  	// Check db to make sure account is deactivated
  1642  	dbReg, err := ra.SA.GetRegistration(context.Background(), &sapb.RegistrationID{Id: 1})
  1643  	test.AssertNotError(t, err, "GetRegistration failed")
  1644  	test.AssertEquals(t, dbReg.Status, string(core.StatusDeactivated))
  1645  }
  1646  
  1647  // noopCAA implements caaChecker, always returning nil
  1648  type noopCAA struct{}
  1649  
  1650  func (cr noopCAA) IsCAAValid(
  1651  	ctx context.Context,
  1652  	in *vapb.IsCAAValidRequest,
  1653  	opts ...grpc.CallOption,
  1654  ) (*vapb.IsCAAValidResponse, error) {
  1655  	return &vapb.IsCAAValidResponse{}, nil
  1656  }
  1657  
  1658  // caaRecorder implements caaChecker, always returning nil, but recording the
  1659  // names it was called for.
  1660  type caaRecorder struct {
  1661  	sync.Mutex
  1662  	names map[string]bool
  1663  }
  1664  
  1665  func (cr *caaRecorder) IsCAAValid(
  1666  	ctx context.Context,
  1667  	in *vapb.IsCAAValidRequest,
  1668  	opts ...grpc.CallOption,
  1669  ) (*vapb.IsCAAValidResponse, error) {
  1670  	cr.Lock()
  1671  	defer cr.Unlock()
  1672  	cr.names[in.Domain] = true
  1673  	return &vapb.IsCAAValidResponse{}, nil
  1674  }
  1675  
  1676  // Test that the right set of domain names have their CAA rechecked, based on
  1677  // their `Validated` (attemptedAt in the database) timestamp.
  1678  func TestRecheckCAADates(t *testing.T) {
  1679  	_, _, ra, fc, cleanUp := initAuthorities(t)
  1680  	defer cleanUp()
  1681  	recorder := &caaRecorder{names: make(map[string]bool)}
  1682  	ra.caa = recorder
  1683  	ra.authorizationLifetime = 15 * time.Hour
  1684  
  1685  	recentValidated := fc.Now().Add(-1 * time.Hour)
  1686  	recentExpires := fc.Now().Add(15 * time.Hour)
  1687  	olderValidated := fc.Now().Add(-8 * time.Hour)
  1688  	olderExpires := fc.Now().Add(5 * time.Hour)
  1689  	makeIdentifier := func(name string) identifier.ACMEIdentifier {
  1690  		return identifier.ACMEIdentifier{
  1691  			Type:  identifier.DNS,
  1692  			Value: name,
  1693  		}
  1694  	}
  1695  
  1696  	authzs := map[string]*core.Authorization{
  1697  		"recent.com": {
  1698  			Identifier: makeIdentifier("recent.com"),
  1699  			Expires:    &recentExpires,
  1700  			Challenges: []core.Challenge{
  1701  				{
  1702  					Status:    core.StatusValid,
  1703  					Type:      core.ChallengeTypeHTTP01,
  1704  					Token:     "exampleToken",
  1705  					Validated: &recentValidated,
  1706  				},
  1707  			},
  1708  		},
  1709  		"older.com": {
  1710  			Identifier: makeIdentifier("older.com"),
  1711  			Expires:    &olderExpires,
  1712  			Challenges: []core.Challenge{
  1713  				{
  1714  					Status:    core.StatusValid,
  1715  					Type:      core.ChallengeTypeHTTP01,
  1716  					Token:     "exampleToken",
  1717  					Validated: &olderValidated,
  1718  				},
  1719  			},
  1720  		},
  1721  		"older2.com": {
  1722  			Identifier: makeIdentifier("older2.com"),
  1723  			Expires:    &olderExpires,
  1724  			Challenges: []core.Challenge{
  1725  				{
  1726  					Status:    core.StatusValid,
  1727  					Type:      core.ChallengeTypeHTTP01,
  1728  					Token:     "exampleToken",
  1729  					Validated: &olderValidated,
  1730  				},
  1731  			},
  1732  		},
  1733  		"wildcard.com": {
  1734  			Identifier: makeIdentifier("wildcard.com"),
  1735  			Expires:    &olderExpires,
  1736  			Challenges: []core.Challenge{
  1737  				{
  1738  					Status:    core.StatusValid,
  1739  					Type:      core.ChallengeTypeHTTP01,
  1740  					Token:     "exampleToken",
  1741  					Validated: &olderValidated,
  1742  				},
  1743  			},
  1744  		},
  1745  		"*.wildcard.com": {
  1746  			Identifier: makeIdentifier("*.wildcard.com"),
  1747  			Expires:    &olderExpires,
  1748  			Challenges: []core.Challenge{
  1749  				{
  1750  					Status:    core.StatusValid,
  1751  					Type:      core.ChallengeTypeHTTP01,
  1752  					Token:     "exampleToken",
  1753  					Validated: &olderValidated,
  1754  				},
  1755  			},
  1756  		},
  1757  		"twochallenges.com": {
  1758  			ID:         "twochal",
  1759  			Identifier: makeIdentifier("twochallenges.com"),
  1760  			Expires:    &recentExpires,
  1761  			Challenges: []core.Challenge{
  1762  				{
  1763  					Status:    core.StatusValid,
  1764  					Type:      core.ChallengeTypeHTTP01,
  1765  					Token:     "exampleToken",
  1766  					Validated: &olderValidated,
  1767  				},
  1768  				{
  1769  					Status:    core.StatusValid,
  1770  					Type:      core.ChallengeTypeDNS01,
  1771  					Token:     "exampleToken",
  1772  					Validated: &olderValidated,
  1773  				},
  1774  			},
  1775  		},
  1776  		"nochallenges.com": {
  1777  			ID:         "nochal",
  1778  			Identifier: makeIdentifier("nochallenges.com"),
  1779  			Expires:    &recentExpires,
  1780  			Challenges: []core.Challenge{},
  1781  		},
  1782  		"novalidationtime.com": {
  1783  			ID:         "noval",
  1784  			Identifier: makeIdentifier("novalidationtime.com"),
  1785  			Expires:    &recentExpires,
  1786  			Challenges: []core.Challenge{
  1787  				{
  1788  					Status:    core.StatusValid,
  1789  					Type:      core.ChallengeTypeHTTP01,
  1790  					Token:     "exampleToken",
  1791  					Validated: nil,
  1792  				},
  1793  			},
  1794  		},
  1795  	}
  1796  
  1797  	// NOTE: The names provided here correspond to authorizations in the
  1798  	// `mockSAWithRecentAndOlder`
  1799  	names := []string{"recent.com", "older.com", "older2.com", "wildcard.com", "*.wildcard.com"}
  1800  	err := ra.checkAuthorizationsCAA(context.Background(), Registration.Id, names, authzs, fc.Now())
  1801  	// We expect that there is no error rechecking authorizations for these names
  1802  	if err != nil {
  1803  		t.Errorf("expected nil err, got %s", err)
  1804  	}
  1805  
  1806  	// Should error if a authorization has `!= 1` challenge
  1807  	err = ra.checkAuthorizationsCAA(context.Background(), Registration.Id, []string{"twochallenges.com"}, authzs, fc.Now())
  1808  	test.AssertEquals(t, err.Error(), "authorization has incorrect number of challenges. 1 expected, 2 found for: id twochal")
  1809  
  1810  	// Should error if a authorization has `!= 1` challenge
  1811  	err = ra.checkAuthorizationsCAA(context.Background(), Registration.Id, []string{"nochallenges.com"}, authzs, fc.Now())
  1812  	test.AssertEquals(t, err.Error(), "authorization has incorrect number of challenges. 1 expected, 0 found for: id nochal")
  1813  
  1814  	// Should error if authorization's challenge has no validated timestamp
  1815  	err = ra.checkAuthorizationsCAA(context.Background(), Registration.Id, []string{"novalidationtime.com"}, authzs, fc.Now())
  1816  	test.AssertEquals(t, err.Error(), "authorization's challenge has no validated timestamp for: id noval")
  1817  
  1818  	// Test to make sure the authorization lifetime codepath was not used
  1819  	// to determine if CAA needed recheck.
  1820  	test.AssertMetricWithLabelsEquals(t, ra.recheckCAAUsedAuthzLifetime, prometheus.Labels{}, 0)
  1821  
  1822  	// We expect that "recent.com" is not checked because its mock authorization
  1823  	// isn't expired
  1824  	if _, present := recorder.names["recent.com"]; present {
  1825  		t.Errorf("Rechecked CAA unnecessarily for recent.com")
  1826  	}
  1827  
  1828  	// We expect that "older.com" is checked
  1829  	if _, present := recorder.names["older.com"]; !present {
  1830  		t.Errorf("Failed to recheck CAA for older.com")
  1831  	}
  1832  
  1833  	// We expect that "older2.com" is checked
  1834  	if _, present := recorder.names["older2.com"]; !present {
  1835  		t.Errorf("Failed to recheck CAA for older2.com")
  1836  	}
  1837  
  1838  	// We expect that the "wildcard.com" domain (without the `*.` prefix) is checked.
  1839  	if _, present := recorder.names["wildcard.com"]; !present {
  1840  		t.Errorf("Failed to recheck CAA for wildcard.com")
  1841  	}
  1842  
  1843  	// We expect that "*.wildcard.com" is checked (with the `*.` prefix, because
  1844  	// it is stripped at a lower layer than we are testing)
  1845  	if _, present := recorder.names["*.wildcard.com"]; !present {
  1846  		t.Errorf("Failed to recheck CAA for *.wildcard.com")
  1847  	}
  1848  }
  1849  
  1850  type caaFailer struct{}
  1851  
  1852  func (cf *caaFailer) IsCAAValid(
  1853  	ctx context.Context,
  1854  	in *vapb.IsCAAValidRequest,
  1855  	opts ...grpc.CallOption,
  1856  ) (*vapb.IsCAAValidResponse, error) {
  1857  	cvrpb := &vapb.IsCAAValidResponse{}
  1858  	switch in.Domain {
  1859  	case "a.com":
  1860  		cvrpb.Problem = &corepb.ProblemDetails{
  1861  			Detail: "CAA invalid for a.com",
  1862  		}
  1863  	case "c.com":
  1864  		cvrpb.Problem = &corepb.ProblemDetails{
  1865  			Detail: "CAA invalid for c.com",
  1866  		}
  1867  	case "d.com":
  1868  		return nil, fmt.Errorf("Error checking CAA for d.com")
  1869  	}
  1870  	return cvrpb, nil
  1871  }
  1872  
  1873  func TestRecheckCAAEmpty(t *testing.T) {
  1874  	_, _, ra, _, cleanUp := initAuthorities(t)
  1875  	defer cleanUp()
  1876  	err := ra.recheckCAA(context.Background(), nil)
  1877  	test.AssertNotError(t, err, "expected nil")
  1878  }
  1879  
  1880  func makeHTTP01Authorization(domain string) *core.Authorization {
  1881  	return &core.Authorization{
  1882  		Identifier: identifier.ACMEIdentifier{Type: identifier.DNS, Value: domain},
  1883  		Challenges: []core.Challenge{{Status: core.StatusValid, Type: core.ChallengeTypeHTTP01}},
  1884  	}
  1885  }
  1886  
  1887  func TestRecheckCAASuccess(t *testing.T) {
  1888  	_, _, ra, _, cleanUp := initAuthorities(t)
  1889  	defer cleanUp()
  1890  	authzs := []*core.Authorization{
  1891  		makeHTTP01Authorization("a.com"),
  1892  		makeHTTP01Authorization("b.com"),
  1893  		makeHTTP01Authorization("c.com"),
  1894  	}
  1895  	err := ra.recheckCAA(context.Background(), authzs)
  1896  	test.AssertNotError(t, err, "expected nil")
  1897  }
  1898  
  1899  func TestRecheckCAAFail(t *testing.T) {
  1900  	_, _, ra, _, cleanUp := initAuthorities(t)
  1901  	defer cleanUp()
  1902  	ra.caa = &caaFailer{}
  1903  	authzs := []*core.Authorization{
  1904  		makeHTTP01Authorization("a.com"),
  1905  		makeHTTP01Authorization("b.com"),
  1906  		makeHTTP01Authorization("c.com"),
  1907  	}
  1908  	err := ra.recheckCAA(context.Background(), authzs)
  1909  
  1910  	test.AssertError(t, err, "expected err, got nil")
  1911  	var berr *berrors.BoulderError
  1912  	test.AssertErrorWraps(t, err, &berr)
  1913  	test.AssertErrorIs(t, berr, berrors.CAA)
  1914  	test.AssertEquals(t, len(berr.SubErrors), 2)
  1915  
  1916  	// We don't know whether the asynchronous a.com or c.com CAA recheck will fail
  1917  	// first. Whichever does will be mentioned in the top level problem detail.
  1918  	expectedDetailRegex := regexp.MustCompile(
  1919  		`Rechecking CAA for "(?:a\.com|c\.com)" and 1 more identifiers failed. Refer to sub-problems for more information`,
  1920  	)
  1921  	if !expectedDetailRegex.MatchString(berr.Detail) {
  1922  		t.Errorf("expected suberror detail to match expected regex, got %q", err)
  1923  	}
  1924  
  1925  	// There should be a sub error for both a.com and c.com with the correct type
  1926  	subErrMap := make(map[string]berrors.SubBoulderError, len(berr.SubErrors))
  1927  	for _, subErr := range berr.SubErrors {
  1928  		subErrMap[subErr.Identifier.Value] = subErr
  1929  	}
  1930  	subErrA, foundA := subErrMap["a.com"]
  1931  	subErrB, foundB := subErrMap["c.com"]
  1932  	test.AssertEquals(t, foundA, true)
  1933  	test.AssertEquals(t, foundB, true)
  1934  	test.AssertEquals(t, subErrA.Type, berrors.CAA)
  1935  	test.AssertEquals(t, subErrB.Type, berrors.CAA)
  1936  
  1937  	// Recheck CAA with just one bad authz
  1938  	authzs = []*core.Authorization{
  1939  		makeHTTP01Authorization("a.com"),
  1940  	}
  1941  	err = ra.recheckCAA(context.Background(), authzs)
  1942  	// It should error
  1943  	test.AssertError(t, err, "expected err from recheckCAA")
  1944  	// It should be a berror
  1945  	test.AssertErrorWraps(t, err, &berr)
  1946  	// There should be *no* suberrors because there was only one overall error
  1947  	test.AssertEquals(t, len(berr.SubErrors), 0)
  1948  }
  1949  
  1950  func TestRecheckCAAInternalServerError(t *testing.T) {
  1951  	_, _, ra, _, cleanUp := initAuthorities(t)
  1952  	defer cleanUp()
  1953  	ra.caa = &caaFailer{}
  1954  	authzs := []*core.Authorization{
  1955  		makeHTTP01Authorization("a.com"),
  1956  		makeHTTP01Authorization("b.com"),
  1957  		makeHTTP01Authorization("d.com"),
  1958  	}
  1959  	err := ra.recheckCAA(context.Background(), authzs)
  1960  	test.AssertError(t, err, "expected err, got nil")
  1961  	test.AssertErrorIs(t, err, berrors.InternalServer)
  1962  }
  1963  
  1964  func TestNewOrder(t *testing.T) {
  1965  	_, _, ra, fc, cleanUp := initAuthorities(t)
  1966  	defer cleanUp()
  1967  	ra.orderLifetime = time.Hour
  1968  
  1969  	now := fc.Now()
  1970  	orderA, err := ra.NewOrder(context.Background(), &rapb.NewOrderRequest{
  1971  		RegistrationID: Registration.Id,
  1972  		Names:          []string{"b.com", "a.com", "a.com", "C.COM"},
  1973  	})
  1974  	test.AssertNotError(t, err, "ra.NewOrder failed")
  1975  	test.AssertEquals(t, orderA.RegistrationID, int64(1))
  1976  	test.AssertEquals(t, orderA.ExpiresNS, now.Add(time.Hour).UnixNano())
  1977  	test.AssertEquals(t, orderA.Expires.AsTime(), now.Add(time.Hour))
  1978  	test.AssertEquals(t, len(orderA.Names), 3)
  1979  	// We expect the order names to have been sorted, deduped, and lowercased
  1980  	test.AssertDeepEquals(t, orderA.Names, []string{"a.com", "b.com", "c.com"})
  1981  	test.AssertEquals(t, orderA.Id, int64(1))
  1982  	test.AssertEquals(t, numAuthorizations(orderA), 3)
  1983  
  1984  	// Reuse all existing authorizations
  1985  	now = fc.Now()
  1986  	orderB, err := ra.NewOrder(context.Background(), &rapb.NewOrderRequest{
  1987  		RegistrationID: Registration.Id,
  1988  		Names:          []string{"b.com", "a.com", "C.COM"},
  1989  	})
  1990  	test.AssertNotError(t, err, "ra.NewOrder failed")
  1991  	test.AssertEquals(t, orderB.RegistrationID, int64(1))
  1992  	test.AssertEquals(t, orderB.ExpiresNS, now.Add(time.Hour).UnixNano())
  1993  	test.AssertEquals(t, orderB.Expires.AsTime(), now.Add(time.Hour))
  1994  	// We expect orderB's ID to match orderA's because of pending order reuse
  1995  	test.AssertEquals(t, orderB.Id, orderA.Id)
  1996  	test.AssertEquals(t, len(orderB.Names), 3)
  1997  	test.AssertDeepEquals(t, orderB.Names, []string{"a.com", "b.com", "c.com"})
  1998  	test.AssertEquals(t, numAuthorizations(orderB), 3)
  1999  	test.AssertDeepEquals(t, orderB.V2Authorizations, orderA.V2Authorizations)
  2000  
  2001  	// Reuse all of the existing authorizations from the previous order and
  2002  	// add a new one
  2003  	orderA.Names = append(orderA.Names, "d.com")
  2004  	now = fc.Now()
  2005  	orderC, err := ra.NewOrder(context.Background(), &rapb.NewOrderRequest{
  2006  		RegistrationID: Registration.Id,
  2007  		Names:          orderA.Names,
  2008  	})
  2009  	test.AssertNotError(t, err, "ra.NewOrder failed")
  2010  	test.AssertEquals(t, orderC.RegistrationID, int64(1))
  2011  	test.AssertEquals(t, orderC.ExpiresNS, now.Add(time.Hour).UnixNano())
  2012  	test.AssertEquals(t, orderC.Expires.AsTime(), now.Add(time.Hour))
  2013  	test.AssertEquals(t, len(orderC.Names), 4)
  2014  	test.AssertDeepEquals(t, orderC.Names, []string{"a.com", "b.com", "c.com", "d.com"})
  2015  	// We expect orderC's ID to not match orderA/orderB's because it is for
  2016  	// a different set of names
  2017  	test.AssertNotEquals(t, orderC.Id, orderA.Id)
  2018  	test.AssertEquals(t, numAuthorizations(orderC), 4)
  2019  	// Abuse the order of the queries used to extract the reused authorizations
  2020  	existing := orderC.V2Authorizations[:3]
  2021  	test.AssertDeepEquals(t, existing, orderA.V2Authorizations)
  2022  
  2023  	_, err = ra.NewOrder(context.Background(), &rapb.NewOrderRequest{
  2024  		RegistrationID: Registration.Id,
  2025  		Names:          []string{"a"},
  2026  	})
  2027  	test.AssertError(t, err, "NewOrder with invalid names did not error")
  2028  	test.AssertEquals(t, err.Error(), "Cannot issue for \"a\": Domain name needs at least one dot")
  2029  }
  2030  
  2031  // TestNewOrderReuse tests that subsequent requests by an ACME account to create
  2032  // an identical order results in only one order being created & subsequently
  2033  // reused.
  2034  func TestNewOrderReuse(t *testing.T) {
  2035  	_, _, ra, fc, cleanUp := initAuthorities(t)
  2036  	defer cleanUp()
  2037  
  2038  	ctx := context.Background()
  2039  	names := []string{"zombo.com", "welcome.to.zombo.com"}
  2040  
  2041  	// Configure the RA to use a short order lifetime
  2042  	ra.orderLifetime = time.Hour
  2043  	// Create a var with two times the order lifetime to reference later
  2044  	doubleLifetime := ra.orderLifetime * 2
  2045  
  2046  	// Create an initial request with regA and names
  2047  	orderReq := &rapb.NewOrderRequest{
  2048  		RegistrationID: Registration.Id,
  2049  		Names:          names,
  2050  	}
  2051  
  2052  	// Create a second registration to reference
  2053  	acctKeyB, err := AccountKeyB.MarshalJSON()
  2054  	test.AssertNotError(t, err, "failed to marshal account key")
  2055  	input := &corepb.Registration{
  2056  		Key:       acctKeyB,
  2057  		InitialIP: parseAndMarshalIP(t, "42.42.42.42"),
  2058  	}
  2059  	secondReg, err := ra.NewRegistration(ctx, input)
  2060  	test.AssertNotError(t, err, "Error creating a second test registration")
  2061  	// First, add an order with `names` for regA
  2062  	firstOrder, err := ra.NewOrder(context.Background(), orderReq)
  2063  	// It shouldn't fail
  2064  	test.AssertNotError(t, err, "Adding an initial order for regA failed")
  2065  	// It should have an ID
  2066  	test.AssertNotNil(t, firstOrder.Id, "Initial order had a nil ID")
  2067  
  2068  	testCases := []struct {
  2069  		Name         string
  2070  		OrderReq     *rapb.NewOrderRequest
  2071  		ExpectReuse  bool
  2072  		AdvanceClock *time.Duration
  2073  	}{
  2074  		{
  2075  			Name:     "Duplicate order, same regID",
  2076  			OrderReq: orderReq,
  2077  			// We expect reuse since the order matches firstOrder
  2078  			ExpectReuse: true,
  2079  		},
  2080  		{
  2081  			Name: "Subset of order names, same regID",
  2082  			OrderReq: &rapb.NewOrderRequest{
  2083  				RegistrationID: Registration.Id,
  2084  				Names:          []string{names[1]},
  2085  			},
  2086  			// We do not expect reuse because the order names don't match firstOrder
  2087  			ExpectReuse: false,
  2088  		},
  2089  		{
  2090  			Name: "Duplicate order, different regID",
  2091  			OrderReq: &rapb.NewOrderRequest{
  2092  				RegistrationID: secondReg.Id,
  2093  				Names:          names,
  2094  			},
  2095  			// We do not expect reuse because the order regID differs from firstOrder
  2096  			ExpectReuse: false,
  2097  		},
  2098  		{
  2099  			Name:         "Duplicate order, same regID, first expired",
  2100  			OrderReq:     orderReq,
  2101  			AdvanceClock: &doubleLifetime,
  2102  			// We do not expect reuse because firstOrder has expired
  2103  			ExpectReuse: true,
  2104  		},
  2105  	}
  2106  
  2107  	for _, tc := range testCases {
  2108  		t.Run(tc.Name, func(t *testing.T) {
  2109  			// If the testcase specifies, advance the clock before adding the order
  2110  			if tc.AdvanceClock != nil {
  2111  				_ = fc.Now().Add(*tc.AdvanceClock)
  2112  			}
  2113  			// Add the order for the test request
  2114  			order, err := ra.NewOrder(ctx, tc.OrderReq)
  2115  			// It shouldn't fail
  2116  			test.AssertNotError(t, err, "NewOrder returned an unexpected error")
  2117  			// The order should not have a nil ID
  2118  			test.AssertNotNil(t, order.Id, "NewOrder returned an order with a nil Id")
  2119  
  2120  			if tc.ExpectReuse {
  2121  				// If we expected order reuse for this testcase assert that the order
  2122  				// has the same ID as the firstOrder
  2123  				test.AssertEquals(t, firstOrder.Id, order.Id)
  2124  			} else {
  2125  				// Otherwise assert that the order doesn't have the same ID as the
  2126  				// firstOrder
  2127  				test.AssertNotEquals(t, firstOrder.Id, order.Id)
  2128  			}
  2129  		})
  2130  	}
  2131  }
  2132  
  2133  func TestNewOrderReuseInvalidAuthz(t *testing.T) {
  2134  	_, _, ra, _, cleanUp := initAuthorities(t)
  2135  	defer cleanUp()
  2136  
  2137  	ctx := context.Background()
  2138  	names := []string{"zombo.com"}
  2139  
  2140  	// Create an initial request with regA and names
  2141  	orderReq := &rapb.NewOrderRequest{
  2142  		RegistrationID: Registration.Id,
  2143  		Names:          names,
  2144  	}
  2145  
  2146  	// First, add an order with `names` for regA
  2147  	order, err := ra.NewOrder(ctx, orderReq)
  2148  	// It shouldn't fail
  2149  	test.AssertNotError(t, err, "Adding an initial order for regA failed")
  2150  	// It should have an ID
  2151  	test.AssertNotNil(t, order.Id, "Initial order had a nil ID")
  2152  	// It should have one authorization
  2153  	test.AssertEquals(t, numAuthorizations(order), 1)
  2154  
  2155  	now := ra.clk.Now()
  2156  	_, err = ra.SA.FinalizeAuthorization2(ctx, &sapb.FinalizeAuthorizationRequest{
  2157  		Id:            order.V2Authorizations[0],
  2158  		Status:        string(core.StatusInvalid),
  2159  		ExpiresNS:     order.ExpiresNS,
  2160  		Expires:       order.Expires,
  2161  		Attempted:     string(core.ChallengeTypeDNS01),
  2162  		AttemptedAtNS: now.UnixNano(),
  2163  		AttemptedAt:   timestamppb.New(now),
  2164  	})
  2165  	test.AssertNotError(t, err, "FinalizeAuthorization2 failed")
  2166  
  2167  	// The order associated with the authz should now be invalid
  2168  	updatedOrder, err := ra.SA.GetOrder(ctx, &sapb.OrderRequest{Id: order.Id})
  2169  	test.AssertNotError(t, err, "Error getting order to check status")
  2170  	test.AssertEquals(t, updatedOrder.Status, "invalid")
  2171  
  2172  	// Create a second order for the same names/regID
  2173  	secondOrder, err := ra.NewOrder(ctx, orderReq)
  2174  	// It shouldn't fail
  2175  	test.AssertNotError(t, err, "Adding an initial order for regA failed")
  2176  	// It should have a different ID than the first now-invalid order
  2177  	test.AssertNotEquals(t, secondOrder.Id, order.Id)
  2178  	// It should be status pending
  2179  	test.AssertEquals(t, secondOrder.Status, "pending")
  2180  	test.AssertEquals(t, numAuthorizations(secondOrder), 1)
  2181  	// It should have a different authorization than the first order's now-invalid authorization
  2182  	test.AssertNotEquals(t, secondOrder.V2Authorizations[0], order.V2Authorizations[0])
  2183  }
  2184  
  2185  // mockSACountPendingFails has a CountPendingAuthorizations2 implementation
  2186  // that always returns error
  2187  type mockSACountPendingFails struct {
  2188  	mocks.StorageAuthority
  2189  }
  2190  
  2191  func (mock *mockSACountPendingFails) CountPendingAuthorizations2(ctx context.Context, req *sapb.RegistrationID, _ ...grpc.CallOption) (*sapb.Count, error) {
  2192  	return nil, errors.New("counting is slow and boring")
  2193  }
  2194  
  2195  // Ensure that we don't bother to call the SA to count pending authorizations
  2196  // when an "unlimited" limit is set.
  2197  func TestPendingAuthorizationsUnlimited(t *testing.T) {
  2198  	_, _, ra, _, cleanUp := initAuthorities(t)
  2199  	defer cleanUp()
  2200  
  2201  	ra.rlPolicies = &dummyRateLimitConfig{
  2202  		PendingAuthorizationsPerAccountPolicy: ratelimit.RateLimitPolicy{
  2203  			Threshold: 1,
  2204  			Window:    config.Duration{Duration: 24 * time.Hour},
  2205  			RegistrationOverrides: map[int64]int64{
  2206  				13: -1,
  2207  			},
  2208  		},
  2209  	}
  2210  
  2211  	ra.SA = &mockSACountPendingFails{}
  2212  
  2213  	limit := ra.rlPolicies.PendingAuthorizationsPerAccount()
  2214  	err := ra.checkPendingAuthorizationLimit(context.Background(), 13, limit)
  2215  	test.AssertNotError(t, err, "checking pending authorization limit")
  2216  }
  2217  
  2218  // Test that the failed authorizations limit is checked before authz reuse.
  2219  func TestNewOrderCheckFailedAuthorizationsFirst(t *testing.T) {
  2220  	_, _, ra, _, cleanUp := initAuthorities(t)
  2221  	defer cleanUp()
  2222  
  2223  	// Create an order (and thus a pending authz) for example.com
  2224  	ctx := context.Background()
  2225  	order, err := ra.NewOrder(ctx, &rapb.NewOrderRequest{
  2226  		RegistrationID: Registration.Id,
  2227  		Names:          []string{"example.com"},
  2228  	})
  2229  	test.AssertNotError(t, err, "adding an initial order for regA")
  2230  	test.AssertNotNil(t, order.Id, "initial order had a nil ID")
  2231  	test.AssertEquals(t, numAuthorizations(order), 1)
  2232  
  2233  	// Now treat example.com as if it had a recent failure.
  2234  	ra.SA = &mockInvalidPlusValidAuthzAuthority{mockInvalidAuthorizationsAuthority{domainWithFailures: "example.com"}}
  2235  	// Set a very restrictive police for invalid authorizations - one failure
  2236  	// and you're done for a day.
  2237  	ra.rlPolicies = &dummyRateLimitConfig{
  2238  		InvalidAuthorizationsPerAccountPolicy: ratelimit.RateLimitPolicy{
  2239  			Threshold: 1,
  2240  			Window:    config.Duration{Duration: 24 * time.Hour},
  2241  		},
  2242  	}
  2243  
  2244  	// Creating an order for example.com should error with the "too many failed
  2245  	// authorizations recently" error.
  2246  	_, err = ra.NewOrder(ctx, &rapb.NewOrderRequest{
  2247  		RegistrationID: Registration.Id,
  2248  		Names:          []string{"example.com"},
  2249  	})
  2250  
  2251  	test.AssertError(t, err, "expected error for domain with too many failures")
  2252  	test.AssertEquals(t, err.Error(), "too many failed authorizations recently: see https://letsencrypt.org/docs/failed-validation-limit/")
  2253  }
  2254  
  2255  // mockSAUnsafeAuthzReuse has a GetAuthorizations implementation that returns
  2256  // an HTTP-01 validated wildcard authz.
  2257  type mockSAUnsafeAuthzReuse struct {
  2258  	mocks.StorageAuthority
  2259  }
  2260  
  2261  func authzMapToPB(m map[string]*core.Authorization) (*sapb.Authorizations, error) {
  2262  	resp := &sapb.Authorizations{}
  2263  	for k, v := range m {
  2264  		authzPB, err := bgrpc.AuthzToPB(*v)
  2265  		if err != nil {
  2266  			return nil, err
  2267  		}
  2268  		resp.Authz = append(resp.Authz, &sapb.Authorizations_MapElement{Domain: k, Authz: authzPB})
  2269  	}
  2270  	return resp, nil
  2271  }
  2272  
  2273  // GetAuthorizations2 returns a _bizarre_ authorization for "*.zombo.com" that
  2274  // was validated by HTTP-01. This should never happen in real life since the
  2275  // name is a wildcard. We use this mock to test that we reject this bizarre
  2276  // situation correctly.
  2277  func (msa *mockSAUnsafeAuthzReuse) GetAuthorizations2(ctx context.Context, req *sapb.GetAuthorizationsRequest, _ ...grpc.CallOption) (*sapb.Authorizations, error) {
  2278  	expires := time.Now()
  2279  	authzs := map[string]*core.Authorization{
  2280  		"*.zombo.com": {
  2281  			// A static fake ID we can check for in a unit test
  2282  			ID:             "1",
  2283  			Identifier:     identifier.DNSIdentifier("*.zombo.com"),
  2284  			RegistrationID: req.RegistrationID,
  2285  			// Authz is valid
  2286  			Status:  "valid",
  2287  			Expires: &expires,
  2288  			Challenges: []core.Challenge{
  2289  				// HTTP-01 challenge is valid
  2290  				{
  2291  					Type:   core.ChallengeTypeHTTP01, // The dreaded HTTP-01! X__X
  2292  					Status: core.StatusValid,
  2293  				},
  2294  				// DNS-01 challenge is pending
  2295  				{
  2296  					Type:   core.ChallengeTypeDNS01,
  2297  					Status: core.StatusPending,
  2298  				},
  2299  			},
  2300  		},
  2301  		"zombo.com": {
  2302  			// A static fake ID we can check for in a unit test
  2303  			ID:             "2",
  2304  			Identifier:     identifier.DNSIdentifier("zombo.com"),
  2305  			RegistrationID: req.RegistrationID,
  2306  			// Authz is valid
  2307  			Status:  "valid",
  2308  			Expires: &expires,
  2309  			Challenges: []core.Challenge{
  2310  				// HTTP-01 challenge is valid
  2311  				{
  2312  					Type:   core.ChallengeTypeHTTP01,
  2313  					Status: core.StatusValid,
  2314  				},
  2315  				// DNS-01 challenge is pending
  2316  				{
  2317  					Type:   core.ChallengeTypeDNS01,
  2318  					Status: core.StatusPending,
  2319  				},
  2320  			},
  2321  		},
  2322  	}
  2323  	return authzMapToPB(authzs)
  2324  
  2325  }
  2326  
  2327  func (msa *mockSAUnsafeAuthzReuse) NewOrderAndAuthzs(ctx context.Context, req *sapb.NewOrderAndAuthzsRequest, _ ...grpc.CallOption) (*corepb.Order, error) {
  2328  	for range req.NewAuthzs {
  2329  		req.NewOrder.V2Authorizations = append(req.NewOrder.V2Authorizations, mrand.Int63())
  2330  	}
  2331  	return msa.StorageAuthority.NewOrderAndAuthzs(ctx, req)
  2332  }
  2333  
  2334  // TestNewOrderAuthzReuseSafety checks that the RA's safety check for reusing an
  2335  // authorization for a new-order request with a wildcard name works correctly.
  2336  // We want to ensure that we never reuse a non-Wildcard authorization (e.g. one
  2337  // with more than just a DNS-01 challenge) for a wildcard name. See Issue #3420
  2338  // for background - this safety check was previously broken!
  2339  // https://github.com/letsencrypt/boulder/issues/3420
  2340  func TestNewOrderAuthzReuseSafety(t *testing.T) {
  2341  	_, _, ra, _, cleanUp := initAuthorities(t)
  2342  	defer cleanUp()
  2343  
  2344  	ctx := context.Background()
  2345  	names := []string{"*.zombo.com"}
  2346  
  2347  	// Use a mock SA that always returns a valid HTTP-01 authz for the name
  2348  	// "zombo.com"
  2349  	ra.SA = &mockSAUnsafeAuthzReuse{}
  2350  
  2351  	// Create an initial request with regA and names
  2352  	orderReq := &rapb.NewOrderRequest{
  2353  		RegistrationID: Registration.Id,
  2354  		Names:          names,
  2355  	}
  2356  
  2357  	// Create an order for that request
  2358  	order, err := ra.NewOrder(ctx, orderReq)
  2359  	// It shouldn't fail
  2360  	test.AssertNotError(t, err, "Adding an initial order for regA failed")
  2361  	test.AssertEquals(t, numAuthorizations(order), 1)
  2362  	// It should *not* be the bad authorization!
  2363  	test.AssertNotEquals(t, order.V2Authorizations[0], int64(1))
  2364  }
  2365  
  2366  func TestNewOrderWildcard(t *testing.T) {
  2367  	_, _, ra, _, cleanUp := initAuthorities(t)
  2368  	defer cleanUp()
  2369  	ra.orderLifetime = time.Hour
  2370  
  2371  	orderNames := []string{"example.com", "*.welcome.zombo.com"}
  2372  	wildcardOrderRequest := &rapb.NewOrderRequest{
  2373  		RegistrationID: Registration.Id,
  2374  		Names:          orderNames,
  2375  	}
  2376  
  2377  	order, err := ra.NewOrder(context.Background(), wildcardOrderRequest)
  2378  	test.AssertNotError(t, err, "NewOrder failed for a wildcard order request")
  2379  
  2380  	// We expect the order to be pending
  2381  	test.AssertEquals(t, order.Status, string(core.StatusPending))
  2382  	// We expect the order to have two names
  2383  	test.AssertEquals(t, len(order.Names), 2)
  2384  	// We expect the order to have the names we requested
  2385  	test.AssertDeepEquals(t,
  2386  		core.UniqueLowerNames(order.Names),
  2387  		core.UniqueLowerNames(orderNames))
  2388  	test.AssertEquals(t, numAuthorizations(order), 2)
  2389  
  2390  	// Check each of the authz IDs in the order
  2391  	for _, authzID := range order.V2Authorizations {
  2392  		// We should be able to retrieve the authz from the db without error
  2393  		authzID := authzID
  2394  		authzPB, err := ra.SA.GetAuthorization2(ctx, &sapb.AuthorizationID2{Id: authzID})
  2395  		test.AssertNotError(t, err, "sa.GetAuthorization2 failed")
  2396  		authz, err := bgrpc.PBToAuthz(authzPB)
  2397  		test.AssertNotError(t, err, "bgrpc.PBToAuthz failed")
  2398  
  2399  		// We expect the authz is in Pending status
  2400  		test.AssertEquals(t, authz.Status, core.StatusPending)
  2401  
  2402  		name := authz.Identifier.Value
  2403  		switch name {
  2404  		case "*.welcome.zombo.com":
  2405  			// If the authz is for *.welcome.zombo.com, we expect that it only has one
  2406  			// pending challenge with DNS-01 type
  2407  			test.AssertEquals(t, len(authz.Challenges), 1)
  2408  			test.AssertEquals(t, authz.Challenges[0].Status, core.StatusPending)
  2409  			test.AssertEquals(t, authz.Challenges[0].Type, core.ChallengeTypeDNS01)
  2410  		case "example.com":
  2411  			// If the authz is for example.com, we expect it has normal challenges
  2412  			test.AssertEquals(t, len(authz.Challenges), 2)
  2413  		default:
  2414  			t.Fatalf("Received an authorization for a name not requested: %q", name)
  2415  		}
  2416  	}
  2417  
  2418  	// An order for a base domain and a wildcard for the same base domain should
  2419  	// return just 2 authz's, one for the wildcard with a DNS-01
  2420  	// challenge and one for the base domain with the normal challenges.
  2421  	orderNames = []string{"zombo.com", "*.zombo.com"}
  2422  	wildcardOrderRequest = &rapb.NewOrderRequest{
  2423  		RegistrationID: Registration.Id,
  2424  		Names:          orderNames,
  2425  	}
  2426  	order, err = ra.NewOrder(context.Background(), wildcardOrderRequest)
  2427  	test.AssertNotError(t, err, "NewOrder failed for a wildcard order request")
  2428  
  2429  	// We expect the order to be pending
  2430  	test.AssertEquals(t, order.Status, string(core.StatusPending))
  2431  	// We expect the order to have two names
  2432  	test.AssertEquals(t, len(order.Names), 2)
  2433  	// We expect the order to have the names we requested
  2434  	test.AssertDeepEquals(t,
  2435  		core.UniqueLowerNames(order.Names),
  2436  		core.UniqueLowerNames(orderNames))
  2437  	test.AssertEquals(t, numAuthorizations(order), 2)
  2438  
  2439  	for _, authzID := range order.V2Authorizations {
  2440  		// We should be able to retrieve the authz from the db without error
  2441  		authzID := authzID
  2442  		authzPB, err := ra.SA.GetAuthorization2(ctx, &sapb.AuthorizationID2{Id: authzID})
  2443  		test.AssertNotError(t, err, "sa.GetAuthorization2 failed")
  2444  		authz, err := bgrpc.PBToAuthz(authzPB)
  2445  		test.AssertNotError(t, err, "bgrpc.PBToAuthz failed")
  2446  		// We expect the authz is in Pending status
  2447  		test.AssertEquals(t, authz.Status, core.StatusPending)
  2448  		switch authz.Identifier.Value {
  2449  		case "zombo.com":
  2450  			// We expect that the base domain identifier auth has the normal number of
  2451  			// challenges
  2452  			test.AssertEquals(t, len(authz.Challenges), 2)
  2453  		case "*.zombo.com":
  2454  			// We expect that the wildcard identifier auth has only a pending
  2455  			// DNS-01 type challenge
  2456  			test.AssertEquals(t, len(authz.Challenges), 1)
  2457  			test.AssertEquals(t, authz.Challenges[0].Status, core.StatusPending)
  2458  			test.AssertEquals(t, authz.Challenges[0].Type, core.ChallengeTypeDNS01)
  2459  		default:
  2460  			t.Fatal("Unexpected authorization value returned from new-order")
  2461  		}
  2462  	}
  2463  
  2464  	// Make an order for a single domain, no wildcards. This will create a new
  2465  	// pending authz for the domain
  2466  	normalOrderReq := &rapb.NewOrderRequest{
  2467  		RegistrationID: Registration.Id,
  2468  		Names:          []string{"everything.is.possible.zombo.com"},
  2469  	}
  2470  	normalOrder, err := ra.NewOrder(context.Background(), normalOrderReq)
  2471  	test.AssertNotError(t, err, "NewOrder failed for a normal non-wildcard order")
  2472  
  2473  	test.AssertEquals(t, numAuthorizations(normalOrder), 1)
  2474  	// We expect the order is in Pending status
  2475  	test.AssertEquals(t, order.Status, string(core.StatusPending))
  2476  	var authz core.Authorization
  2477  	authzPB, err := ra.SA.GetAuthorization2(ctx, &sapb.AuthorizationID2{Id: normalOrder.V2Authorizations[0]})
  2478  	test.AssertNotError(t, err, "sa.GetAuthorization2 failed")
  2479  	authz, err = bgrpc.PBToAuthz(authzPB)
  2480  	test.AssertNotError(t, err, "bgrpc.PBToAuthz failed")
  2481  	// We expect the authz is in Pending status
  2482  	test.AssertEquals(t, authz.Status, core.StatusPending)
  2483  	// We expect the authz is for the identifier the correct domain
  2484  	test.AssertEquals(t, authz.Identifier.Value, "everything.is.possible.zombo.com")
  2485  	// We expect the authz has the normal # of challenges
  2486  	test.AssertEquals(t, len(authz.Challenges), 2)
  2487  
  2488  	// Now submit an order request for a wildcard of the domain we just created an
  2489  	// order for. We should **NOT** reuse the authorization from the previous
  2490  	// order since we now require a DNS-01 challenge for the `*.` prefixed name.
  2491  	orderNames = []string{"*.everything.is.possible.zombo.com"}
  2492  	wildcardOrderRequest = &rapb.NewOrderRequest{
  2493  		RegistrationID: Registration.Id,
  2494  		Names:          orderNames,
  2495  	}
  2496  	order, err = ra.NewOrder(context.Background(), wildcardOrderRequest)
  2497  	test.AssertNotError(t, err, "NewOrder failed for a wildcard order request")
  2498  	// We expect the order is in Pending status
  2499  	test.AssertEquals(t, order.Status, string(core.StatusPending))
  2500  	test.AssertEquals(t, numAuthorizations(order), 1)
  2501  	// The authz should be a different ID than the previous authz
  2502  	test.AssertNotEquals(t, order.V2Authorizations[0], normalOrder.V2Authorizations[0])
  2503  	// We expect the authorization is available
  2504  	authzPB, err = ra.SA.GetAuthorization2(ctx, &sapb.AuthorizationID2{Id: order.V2Authorizations[0]})
  2505  	test.AssertNotError(t, err, "sa.GetAuthorization2 failed")
  2506  	authz, err = bgrpc.PBToAuthz(authzPB)
  2507  	test.AssertNotError(t, err, "bgrpc.PBToAuthz failed")
  2508  	// We expect the authz is in Pending status
  2509  	test.AssertEquals(t, authz.Status, core.StatusPending)
  2510  	// We expect the authz is for a identifier with the correct domain
  2511  	test.AssertEquals(t, authz.Identifier.Value, "*.everything.is.possible.zombo.com")
  2512  	// We expect the authz has only one challenge
  2513  	test.AssertEquals(t, len(authz.Challenges), 1)
  2514  	// We expect the one challenge is pending
  2515  	test.AssertEquals(t, authz.Challenges[0].Status, core.StatusPending)
  2516  	// We expect that the one challenge is a DNS01 type challenge
  2517  	test.AssertEquals(t, authz.Challenges[0].Type, core.ChallengeTypeDNS01)
  2518  
  2519  	// Submit an identical wildcard order request
  2520  	dupeOrder, err := ra.NewOrder(context.Background(), wildcardOrderRequest)
  2521  	test.AssertNotError(t, err, "NewOrder failed for a wildcard order request")
  2522  	// We expect the order is in Pending status
  2523  	test.AssertEquals(t, dupeOrder.Status, string(core.StatusPending))
  2524  	test.AssertEquals(t, numAuthorizations(dupeOrder), 1)
  2525  	// The authz should be the same ID as the previous order's authz. We already
  2526  	// checked that order.Authorizations[0] only has a DNS-01 challenge above so
  2527  	// we don't need to recheck that here.
  2528  	test.AssertEquals(t, dupeOrder.V2Authorizations[0], order.V2Authorizations[0])
  2529  }
  2530  
  2531  // mockSANearExpiredAuthz is a mock SA that always returns an authz near expiry
  2532  // to test orders expiry calculations
  2533  type mockSANearExpiredAuthz struct {
  2534  	mocks.StorageAuthority
  2535  	expiry time.Time
  2536  }
  2537  
  2538  // GetAuthorizations2 is a mock that always returns a valid authorization for
  2539  // "zombo.com" very near to expiry
  2540  func (msa *mockSANearExpiredAuthz) GetAuthorizations2(ctx context.Context, req *sapb.GetAuthorizationsRequest, _ ...grpc.CallOption) (*sapb.Authorizations, error) {
  2541  	authzs := map[string]*core.Authorization{
  2542  		"zombo.com": {
  2543  			// A static fake ID we can check for in a unit test
  2544  			ID:             "1",
  2545  			Identifier:     identifier.DNSIdentifier("zombo.com"),
  2546  			RegistrationID: req.RegistrationID,
  2547  			Expires:        &msa.expiry,
  2548  			Status:         "valid",
  2549  			Challenges: []core.Challenge{
  2550  				{
  2551  					Type:   core.ChallengeTypeHTTP01,
  2552  					Status: core.StatusValid,
  2553  				},
  2554  			},
  2555  		},
  2556  	}
  2557  	return authzMapToPB(authzs)
  2558  }
  2559  
  2560  func TestNewOrderExpiry(t *testing.T) {
  2561  	_, _, ra, clk, cleanUp := initAuthorities(t)
  2562  	defer cleanUp()
  2563  
  2564  	ctx := context.Background()
  2565  	names := []string{"zombo.com"}
  2566  
  2567  	// Set the order lifetime to 48 hours.
  2568  	ra.orderLifetime = 48 * time.Hour
  2569  
  2570  	// Use an expiry that is sooner than the configured order expiry but greater
  2571  	// than 24 hours away.
  2572  	fakeAuthzExpires := clk.Now().Add(35 * time.Hour)
  2573  
  2574  	// Use a mock SA that always returns a soon-to-be-expired valid authz for
  2575  	// "zombo.com".
  2576  	ra.SA = &mockSANearExpiredAuthz{expiry: fakeAuthzExpires}
  2577  
  2578  	// Create an initial request with regA and names
  2579  	orderReq := &rapb.NewOrderRequest{
  2580  		RegistrationID: Registration.Id,
  2581  		Names:          names,
  2582  	}
  2583  
  2584  	// Create an order for that request
  2585  	order, err := ra.NewOrder(ctx, orderReq)
  2586  	// It shouldn't fail
  2587  	test.AssertNotError(t, err, "Adding an order for regA failed")
  2588  	test.AssertEquals(t, numAuthorizations(order), 1)
  2589  	// It should be the fake near-expired-authz authz
  2590  	test.AssertEquals(t, order.V2Authorizations[0], int64(1))
  2591  	// The order's expiry should be the fake authz's expiry since it is sooner
  2592  	// than the order's own expiry.
  2593  	test.AssertEquals(t, order.ExpiresNS, fakeAuthzExpires.UnixNano())
  2594  
  2595  	// Set the order lifetime to be lower than the fakeAuthzLifetime
  2596  	ra.orderLifetime = 12 * time.Hour
  2597  	expectedOrderExpiry := clk.Now().Add(ra.orderLifetime).UnixNano()
  2598  	// Create the order again
  2599  	order, err = ra.NewOrder(ctx, orderReq)
  2600  	// It shouldn't fail
  2601  	test.AssertNotError(t, err, "Adding an order for regA failed")
  2602  	test.AssertEquals(t, numAuthorizations(order), 1)
  2603  	// It should be the fake near-expired-authz authz
  2604  	test.AssertEquals(t, order.V2Authorizations[0], int64(1))
  2605  	// The order's expiry should be the order's own expiry since it is sooner than
  2606  	// the fake authz's expiry.
  2607  	test.AssertEquals(t, order.ExpiresNS, expectedOrderExpiry)
  2608  }
  2609  
  2610  func TestFinalizeOrder(t *testing.T) {
  2611  	_, sa, ra, fc, cleanUp := initAuthorities(t)
  2612  	defer cleanUp()
  2613  	ra.orderLifetime = time.Hour
  2614  
  2615  	// Create one finalized authorization for not-example.com and one finalized
  2616  	// authorization for www.not-example.org
  2617  	now := ra.clk.Now()
  2618  	exp := now.Add(365 * 24 * time.Hour)
  2619  	authzIDA := createFinalizedAuthorization(t, sa, "not-example.com", exp, core.ChallengeTypeHTTP01, ra.clk.Now())
  2620  	authzIDB := createFinalizedAuthorization(t, sa, "www.not-example.com", exp, core.ChallengeTypeHTTP01, ra.clk.Now())
  2621  
  2622  	testKey, err := rsa.GenerateKey(rand.Reader, 2048)
  2623  	test.AssertNotError(t, err, "error generating test key")
  2624  
  2625  	policyForbidCSR, err := x509.CreateCertificateRequest(rand.Reader, &x509.CertificateRequest{
  2626  		PublicKey:          testKey.PublicKey,
  2627  		SignatureAlgorithm: x509.SHA256WithRSA,
  2628  		DNSNames:           []string{"example.org"},
  2629  	}, testKey)
  2630  	test.AssertNotError(t, err, "Error creating policy forbid CSR")
  2631  
  2632  	oneDomainCSR, err := x509.CreateCertificateRequest(rand.Reader, &x509.CertificateRequest{
  2633  		PublicKey:          testKey.PublicKey,
  2634  		SignatureAlgorithm: x509.SHA256WithRSA,
  2635  		DNSNames:           []string{"a.com"},
  2636  	}, testKey)
  2637  	test.AssertNotError(t, err, "Error creating CSR with one DNS name")
  2638  
  2639  	twoDomainCSR, err := x509.CreateCertificateRequest(rand.Reader, &x509.CertificateRequest{
  2640  		PublicKey:          testKey.PublicKey,
  2641  		SignatureAlgorithm: x509.SHA256WithRSA,
  2642  		DNSNames:           []string{"a.com", "b.com"},
  2643  	}, testKey)
  2644  	test.AssertNotError(t, err, "Error creating CSR with two DNS names")
  2645  
  2646  	validCSR, err := x509.CreateCertificateRequest(rand.Reader, &x509.CertificateRequest{
  2647  		PublicKey:          testKey.Public(),
  2648  		SignatureAlgorithm: x509.SHA256WithRSA,
  2649  		DNSNames:           []string{"not-example.com", "www.not-example.com"},
  2650  	}, testKey)
  2651  	test.AssertNotError(t, err, "Error creating CSR with authorized names")
  2652  
  2653  	expectedCert := &x509.Certificate{
  2654  		SerialNumber:          big.NewInt(0),
  2655  		Subject:               pkix.Name{CommonName: "not-example.com"},
  2656  		DNSNames:              []string{"not-example.com", "www.not-example.com"},
  2657  		PublicKey:             testKey.Public(),
  2658  		NotBefore:             fc.Now(),
  2659  		BasicConstraintsValid: true,
  2660  		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
  2661  	}
  2662  	certDER, err := x509.CreateCertificate(rand.Reader, expectedCert, expectedCert, testKey.Public(), testKey)
  2663  	test.AssertNotError(t, err, "failed to construct test certificate")
  2664  	ra.CA.(*mocks.MockCA).PEM = pem.EncodeToMemory(&pem.Block{Bytes: certDER, Type: "CERTIFICATE"})
  2665  
  2666  	fakeRegID := int64(0xB00)
  2667  
  2668  	// NOTE(@cpu): We use unique `names` for each of these orders because
  2669  	// otherwise only *one* order is created & reused. The first test case to
  2670  	// finalize the order will put it into processing state and the other tests
  2671  	// will fail because you can't finalize an order that is already being
  2672  	// processed.
  2673  	// Add a new order for the fake reg ID
  2674  	fakeRegOrder, err := ra.NewOrder(context.Background(), &rapb.NewOrderRequest{
  2675  		RegistrationID: Registration.Id,
  2676  		Names:          []string{"001.example.com"},
  2677  	})
  2678  	test.AssertNotError(t, err, "Could not add test order for fake reg ID order ID")
  2679  
  2680  	missingAuthzOrder, err := ra.NewOrder(context.Background(), &rapb.NewOrderRequest{
  2681  		RegistrationID: Registration.Id,
  2682  		Names:          []string{"002.example.com"},
  2683  	})
  2684  	test.AssertNotError(t, err, "Could not add test order for missing authz order ID")
  2685  
  2686  	validatedOrder, err := sa.NewOrderAndAuthzs(context.Background(), &sapb.NewOrderAndAuthzsRequest{
  2687  		NewOrder: &sapb.NewOrderRequest{
  2688  			RegistrationID:   Registration.Id,
  2689  			ExpiresNS:        exp.UnixNano(),
  2690  			Expires:          timestamppb.New(exp),
  2691  			Names:            []string{"not-example.com", "www.not-example.com"},
  2692  			V2Authorizations: []int64{authzIDA, authzIDB},
  2693  		},
  2694  	})
  2695  	test.AssertNotError(t, err, "Could not add test order with finalized authz IDs, ready status")
  2696  
  2697  	testCases := []struct {
  2698  		Name           string
  2699  		OrderReq       *rapb.FinalizeOrderRequest
  2700  		ExpectedErrMsg string
  2701  		ExpectIssuance bool
  2702  	}{
  2703  		{
  2704  			Name: "No id in order",
  2705  			OrderReq: &rapb.FinalizeOrderRequest{
  2706  				Order: &corepb.Order{},
  2707  				Csr:   oneDomainCSR,
  2708  			},
  2709  			ExpectedErrMsg: "invalid order ID: 0",
  2710  		},
  2711  		{
  2712  			Name: "No account id in order",
  2713  			OrderReq: &rapb.FinalizeOrderRequest{
  2714  				Order: &corepb.Order{
  2715  					Id: 1,
  2716  				},
  2717  				Csr: oneDomainCSR,
  2718  			},
  2719  			ExpectedErrMsg: "invalid account ID: 0",
  2720  		},
  2721  		{
  2722  			Name: "No names in order",
  2723  			OrderReq: &rapb.FinalizeOrderRequest{
  2724  				Order: &corepb.Order{
  2725  					Id:             1,
  2726  					RegistrationID: 1,
  2727  					Status:         string(core.StatusReady),
  2728  					Names:          []string{},
  2729  				},
  2730  				Csr: oneDomainCSR,
  2731  			},
  2732  			ExpectedErrMsg: "Order has no associated names",
  2733  		},
  2734  		{
  2735  			Name: "Wrong order state (valid)",
  2736  			OrderReq: &rapb.FinalizeOrderRequest{
  2737  				Order: &corepb.Order{
  2738  					Id:             1,
  2739  					RegistrationID: 1,
  2740  					Status:         string(core.StatusValid),
  2741  					Names:          []string{"a.com"},
  2742  				},
  2743  				Csr: oneDomainCSR,
  2744  			},
  2745  			ExpectedErrMsg: `Order's status ("valid") is not acceptable for finalization`,
  2746  		},
  2747  		{
  2748  			Name: "Wrong order state (pending)",
  2749  			OrderReq: &rapb.FinalizeOrderRequest{
  2750  				Order: &corepb.Order{
  2751  					Id:             1,
  2752  					RegistrationID: 1,
  2753  					Status:         string(core.StatusPending),
  2754  					Names:          []string{"a.com"},
  2755  				},
  2756  				Csr: oneDomainCSR,
  2757  			},
  2758  			ExpectIssuance: false,
  2759  			ExpectedErrMsg: `Order's status ("pending") is not acceptable for finalization`,
  2760  		},
  2761  		{
  2762  			Name: "Invalid CSR",
  2763  			OrderReq: &rapb.FinalizeOrderRequest{
  2764  				Order: &corepb.Order{
  2765  					Id:             1,
  2766  					RegistrationID: 1,
  2767  					Status:         string(core.StatusReady),
  2768  					Names:          []string{"a.com"},
  2769  				},
  2770  				Csr: []byte{0xC0, 0xFF, 0xEE},
  2771  			},
  2772  			ExpectedErrMsg: "unable to parse CSR: asn1: syntax error: truncated tag or length",
  2773  		},
  2774  		{
  2775  			Name: "CSR and Order with diff number of names",
  2776  			OrderReq: &rapb.FinalizeOrderRequest{
  2777  				Order: &corepb.Order{
  2778  					Id:             1,
  2779  					RegistrationID: 1,
  2780  					Status:         string(core.StatusReady),
  2781  					Names:          []string{"a.com", "b.com"},
  2782  				},
  2783  				Csr: oneDomainCSR,
  2784  			},
  2785  			ExpectedErrMsg: "Order includes different number of names than CSR specifies",
  2786  		},
  2787  		{
  2788  			Name: "CSR and Order with diff number of names (other way)",
  2789  			OrderReq: &rapb.FinalizeOrderRequest{
  2790  				Order: &corepb.Order{
  2791  					Id:             1,
  2792  					RegistrationID: 1,
  2793  					Status:         string(core.StatusReady),
  2794  					Names:          []string{"a.com"},
  2795  				},
  2796  				Csr: twoDomainCSR,
  2797  			},
  2798  			ExpectedErrMsg: "Order includes different number of names than CSR specifies",
  2799  		},
  2800  		{
  2801  			Name: "CSR missing an order name",
  2802  			OrderReq: &rapb.FinalizeOrderRequest{
  2803  				Order: &corepb.Order{
  2804  					Id:             1,
  2805  					RegistrationID: 1,
  2806  					Status:         string(core.StatusReady),
  2807  					Names:          []string{"foobar.com"},
  2808  				},
  2809  				Csr: oneDomainCSR,
  2810  			},
  2811  			ExpectedErrMsg: "CSR is missing Order domain \"foobar.com\"",
  2812  		},
  2813  		{
  2814  			Name: "CSR with policy forbidden name",
  2815  			OrderReq: &rapb.FinalizeOrderRequest{
  2816  				Order: &corepb.Order{
  2817  					Id:                1,
  2818  					RegistrationID:    1,
  2819  					Status:            string(core.StatusReady),
  2820  					Names:             []string{"example.org"},
  2821  					ExpiresNS:         exp.UnixNano(),
  2822  					Expires:           timestamppb.New(exp),
  2823  					CertificateSerial: "",
  2824  					BeganProcessing:   false,
  2825  				},
  2826  				Csr: policyForbidCSR,
  2827  			},
  2828  			ExpectedErrMsg: "Cannot issue for \"example.org\": The ACME server refuses to issue a certificate for this domain name, because it is forbidden by policy",
  2829  		},
  2830  		{
  2831  			Name: "Order with missing registration",
  2832  			OrderReq: &rapb.FinalizeOrderRequest{
  2833  				Order: &corepb.Order{
  2834  					Status:            string(core.StatusReady),
  2835  					Names:             []string{"a.com"},
  2836  					Id:                fakeRegOrder.Id,
  2837  					RegistrationID:    fakeRegID,
  2838  					ExpiresNS:         exp.UnixNano(),
  2839  					Expires:           timestamppb.New(exp),
  2840  					CertificateSerial: "",
  2841  					BeganProcessing:   false,
  2842  					CreatedNS:         now.UnixNano(),
  2843  					Created:           timestamppb.New(now),
  2844  				},
  2845  				Csr: oneDomainCSR,
  2846  			},
  2847  			ExpectedErrMsg: fmt.Sprintf("registration with ID '%d' not found", fakeRegID),
  2848  		},
  2849  		{
  2850  			Name: "Order with missing authorizations",
  2851  			OrderReq: &rapb.FinalizeOrderRequest{
  2852  				Order: &corepb.Order{
  2853  					Status:            string(core.StatusReady),
  2854  					Names:             []string{"a.com", "b.com"},
  2855  					Id:                missingAuthzOrder.Id,
  2856  					RegistrationID:    Registration.Id,
  2857  					ExpiresNS:         exp.UnixNano(),
  2858  					Expires:           timestamppb.New(exp),
  2859  					CertificateSerial: "",
  2860  					BeganProcessing:   false,
  2861  					CreatedNS:         now.UnixNano(),
  2862  					Created:           timestamppb.New(now),
  2863  				},
  2864  				Csr: twoDomainCSR,
  2865  			},
  2866  			ExpectedErrMsg: "authorizations for these names not found or expired: a.com, b.com",
  2867  		},
  2868  		{
  2869  			Name: "Order with correct authorizations, ready status",
  2870  			OrderReq: &rapb.FinalizeOrderRequest{
  2871  				Order: validatedOrder,
  2872  				Csr:   validCSR,
  2873  			},
  2874  			ExpectIssuance: true,
  2875  		},
  2876  	}
  2877  
  2878  	for _, tc := range testCases {
  2879  		t.Run(tc.Name, func(t *testing.T) {
  2880  			_, result := ra.FinalizeOrder(context.Background(), tc.OrderReq)
  2881  			// If we don't expect issuance we expect an error
  2882  			if !tc.ExpectIssuance {
  2883  				// Check that the error happened and the message matches expected
  2884  				test.AssertError(t, result, "FinalizeOrder did not fail when expected to")
  2885  				test.AssertEquals(t, result.Error(), tc.ExpectedErrMsg)
  2886  			} else {
  2887  				// Otherwise we expect an issuance and no error
  2888  				test.AssertNotError(t, result, fmt.Sprintf("FinalizeOrder result was %#v, expected nil", result))
  2889  				// Check that the order now has a serial for the issued certificate
  2890  				updatedOrder, err := sa.GetOrder(
  2891  					context.Background(),
  2892  					&sapb.OrderRequest{Id: tc.OrderReq.Order.Id})
  2893  				test.AssertNotError(t, err, "Error getting order to check serial")
  2894  				test.AssertNotEquals(t, updatedOrder.CertificateSerial, "")
  2895  				test.AssertEquals(t, updatedOrder.Status, "valid")
  2896  				test.AssertEquals(t, updatedOrder.ExpiresNS, exp.UnixNano())
  2897  				test.AssertEquals(t, updatedOrder.Expires.AsTime(), exp)
  2898  			}
  2899  		})
  2900  	}
  2901  }
  2902  
  2903  func TestFinalizeOrderWithMixedSANAndCN(t *testing.T) {
  2904  	_, sa, ra, _, cleanUp := initAuthorities(t)
  2905  	defer cleanUp()
  2906  	ra.orderLifetime = time.Hour
  2907  
  2908  	// Pick an expiry in the future
  2909  	now := ra.clk.Now()
  2910  	exp := now.Add(365 * 24 * time.Hour)
  2911  
  2912  	// Create one finalized authorization for Registration.Id for not-example.com and
  2913  	// one finalized authorization for Registration.Id for www.not-example.org
  2914  	authzIDA := createFinalizedAuthorization(t, sa, "not-example.com", exp, core.ChallengeTypeHTTP01, ra.clk.Now())
  2915  	authzIDB := createFinalizedAuthorization(t, sa, "www.not-example.com", exp, core.ChallengeTypeHTTP01, ra.clk.Now())
  2916  
  2917  	// Create a new order to finalize with names in SAN and CN
  2918  	mixedOrder, err := sa.NewOrderAndAuthzs(context.Background(), &sapb.NewOrderAndAuthzsRequest{
  2919  		NewOrder: &sapb.NewOrderRequest{
  2920  			RegistrationID:   Registration.Id,
  2921  			ExpiresNS:        exp.UnixNano(),
  2922  			Expires:          timestamppb.New(exp),
  2923  			Names:            []string{"not-example.com", "www.not-example.com"},
  2924  			V2Authorizations: []int64{authzIDA, authzIDB},
  2925  		},
  2926  	})
  2927  	test.AssertNotError(t, err, "Could not add test order with finalized authz IDs")
  2928  	testKey, err := rsa.GenerateKey(rand.Reader, 2048)
  2929  	test.AssertNotError(t, err, "error generating test key")
  2930  	mixedCSR, err := x509.CreateCertificateRequest(rand.Reader, &x509.CertificateRequest{
  2931  		PublicKey:          testKey.PublicKey,
  2932  		SignatureAlgorithm: x509.SHA256WithRSA,
  2933  		Subject:            pkix.Name{CommonName: "not-example.com"},
  2934  		DNSNames:           []string{"www.not-example.com"},
  2935  	}, testKey)
  2936  	test.AssertNotError(t, err, "Could not create mixed CSR")
  2937  
  2938  	template := &x509.Certificate{
  2939  		SerialNumber:          big.NewInt(12),
  2940  		Subject:               pkix.Name{CommonName: "not-example.com"},
  2941  		DNSNames:              []string{"www.not-example.com", "not-example.com"},
  2942  		NotBefore:             time.Now(),
  2943  		BasicConstraintsValid: true,
  2944  		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
  2945  	}
  2946  	cert, err := x509.CreateCertificate(rand.Reader, template, template, testKey.Public(), testKey)
  2947  	test.AssertNotError(t, err, "Failed to create mixed cert")
  2948  
  2949  	ra.CA = &mocks.MockCA{
  2950  		PEM: pem.EncodeToMemory(&pem.Block{
  2951  			Bytes: cert,
  2952  		}),
  2953  	}
  2954  
  2955  	_, result := ra.FinalizeOrder(context.Background(), &rapb.FinalizeOrderRequest{Order: mixedOrder, Csr: mixedCSR})
  2956  	test.AssertNotError(t, result, "FinalizeOrder failed")
  2957  	// Check that the order now has a serial for the issued certificate
  2958  	updatedOrder, err := sa.GetOrder(
  2959  		context.Background(),
  2960  		&sapb.OrderRequest{Id: mixedOrder.Id})
  2961  	test.AssertNotError(t, err, "Error getting order to check serial")
  2962  	test.AssertNotEquals(t, updatedOrder.CertificateSerial, "")
  2963  	test.AssertEquals(t, updatedOrder.Status, "valid")
  2964  }
  2965  
  2966  func TestFinalizeOrderWildcard(t *testing.T) {
  2967  	_, sa, ra, _, cleanUp := initAuthorities(t)
  2968  	defer cleanUp()
  2969  
  2970  	// Pick an expiry in the future
  2971  	now := ra.clk.Now()
  2972  	exp := now.Add(365 * 24 * time.Hour)
  2973  
  2974  	testKey, err := rsa.GenerateKey(rand.Reader, 2048)
  2975  	test.AssertNotError(t, err, "Error creating test RSA key")
  2976  	wildcardCSR, err := x509.CreateCertificateRequest(rand.Reader, &x509.CertificateRequest{
  2977  		PublicKey:          testKey.PublicKey,
  2978  		SignatureAlgorithm: x509.SHA256WithRSA,
  2979  		DNSNames:           []string{"*.zombo.com"},
  2980  	}, testKey)
  2981  	test.AssertNotError(t, err, "Error creating CSR with wildcard DNS name")
  2982  
  2983  	template := &x509.Certificate{
  2984  		SerialNumber:          big.NewInt(1337),
  2985  		NotBefore:             time.Now(),
  2986  		NotAfter:              time.Now().AddDate(0, 0, 1),
  2987  		KeyUsage:              x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
  2988  		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
  2989  		BasicConstraintsValid: true,
  2990  		Subject:               pkix.Name{CommonName: "*.zombo.com"},
  2991  		DNSNames:              []string{"*.zombo.com"},
  2992  	}
  2993  
  2994  	certBytes, err := x509.CreateCertificate(rand.Reader, template, template, testKey.Public(), testKey)
  2995  	test.AssertNotError(t, err, "Error creating test certificate")
  2996  
  2997  	certPEM := pem.EncodeToMemory(&pem.Block{
  2998  		Type:  "CERTIFICATE",
  2999  		Bytes: certBytes,
  3000  	})
  3001  
  3002  	// Set up a mock CA capable of giving back a cert for the wildcardCSR above
  3003  	ca := &mocks.MockCA{
  3004  		PEM: certPEM,
  3005  	}
  3006  	ra.CA = ca
  3007  
  3008  	// Create a new order for a wildcard domain
  3009  	orderNames := []string{"*.zombo.com"}
  3010  	wildcardOrderRequest := &rapb.NewOrderRequest{
  3011  		RegistrationID: Registration.Id,
  3012  		Names:          orderNames,
  3013  	}
  3014  	order, err := ra.NewOrder(context.Background(), wildcardOrderRequest)
  3015  	test.AssertNotError(t, err, "NewOrder failed for wildcard domain order")
  3016  
  3017  	// Create one standard finalized authorization for Registration.Id for zombo.com
  3018  	_ = createFinalizedAuthorization(t, sa, "zombo.com", exp, core.ChallengeTypeHTTP01, ra.clk.Now())
  3019  
  3020  	// Finalizing the order should *not* work since the existing validated authz
  3021  	// is not a special DNS-01-Wildcard challenge authz, so the order will be
  3022  	// "pending" not "ready".
  3023  	finalizeReq := &rapb.FinalizeOrderRequest{
  3024  		Order: order,
  3025  		Csr:   wildcardCSR,
  3026  	}
  3027  	_, err = ra.FinalizeOrder(context.Background(), finalizeReq)
  3028  	test.AssertError(t, err, "FinalizeOrder did not fail for unauthorized "+
  3029  		"wildcard order")
  3030  	test.AssertEquals(t, err.Error(),
  3031  		`Order's status ("pending") is not acceptable for finalization`)
  3032  
  3033  	// Creating another order for the wildcard name
  3034  	validOrder, err := ra.NewOrder(context.Background(), wildcardOrderRequest)
  3035  	test.AssertNotError(t, err, "NewOrder failed for wildcard domain order")
  3036  	test.AssertEquals(t, numAuthorizations(validOrder), 1)
  3037  	// We expect to be able to get the authorization by ID
  3038  	_, err = sa.GetAuthorization2(ctx, &sapb.AuthorizationID2{Id: validOrder.V2Authorizations[0]})
  3039  	test.AssertNotError(t, err, "sa.GetAuthorization2 failed")
  3040  
  3041  	// Finalize the authorization with the challenge validated
  3042  	expires := now.Add(time.Hour * 24 * 7)
  3043  	_, err = sa.FinalizeAuthorization2(ctx, &sapb.FinalizeAuthorizationRequest{
  3044  		Id:            validOrder.V2Authorizations[0],
  3045  		Status:        string(core.StatusValid),
  3046  		ExpiresNS:     expires.UnixNano(),
  3047  		Expires:       timestamppb.New(expires),
  3048  		Attempted:     string(core.ChallengeTypeDNS01),
  3049  		AttemptedAtNS: now.UnixNano(),
  3050  		AttemptedAt:   timestamppb.New(now),
  3051  	})
  3052  	test.AssertNotError(t, err, "sa.FinalizeAuthorization2 failed")
  3053  
  3054  	// Refresh the order so the SA sets its status
  3055  	validOrder, err = sa.GetOrder(ctx, &sapb.OrderRequest{
  3056  		Id: validOrder.Id,
  3057  	})
  3058  	test.AssertNotError(t, err, "Could not refresh valid order from SA")
  3059  
  3060  	// Now it should be possible to finalize the order
  3061  	finalizeReq = &rapb.FinalizeOrderRequest{
  3062  		Order: validOrder,
  3063  		Csr:   wildcardCSR,
  3064  	}
  3065  	_, err = ra.FinalizeOrder(context.Background(), finalizeReq)
  3066  	test.AssertNotError(t, err, "FinalizeOrder failed for authorized "+
  3067  		"wildcard order")
  3068  }
  3069  
  3070  func TestIssueCertificateAuditLog(t *testing.T) {
  3071  	_, sa, ra, _, cleanUp := initAuthorities(t)
  3072  	defer cleanUp()
  3073  
  3074  	// Set up order and authz expiries
  3075  	ra.orderLifetime = 24 * time.Hour
  3076  	exp := ra.clk.Now().Add(24 * time.Hour)
  3077  
  3078  	// Make some valid authorizations for some names using different challenge types
  3079  	names := []string{"not-example.com", "www.not-example.com", "still.not-example.com", "definitely.not-example.com"}
  3080  	challs := []core.AcmeChallenge{core.ChallengeTypeHTTP01, core.ChallengeTypeDNS01, core.ChallengeTypeHTTP01, core.ChallengeTypeDNS01}
  3081  	var authzIDs []int64
  3082  	for i, name := range names {
  3083  		authzIDs = append(authzIDs, createFinalizedAuthorization(t, sa, name, exp, challs[i], ra.clk.Now()))
  3084  	}
  3085  
  3086  	// Create a pending order for all of the names
  3087  	order, err := sa.NewOrderAndAuthzs(context.Background(), &sapb.NewOrderAndAuthzsRequest{
  3088  		NewOrder: &sapb.NewOrderRequest{
  3089  			RegistrationID:   Registration.Id,
  3090  			ExpiresNS:        exp.UnixNano(),
  3091  			Expires:          timestamppb.New(exp),
  3092  			Names:            names,
  3093  			V2Authorizations: authzIDs,
  3094  		},
  3095  	})
  3096  	test.AssertNotError(t, err, "Could not add test order with finalized authz IDs")
  3097  
  3098  	// Generate a CSR covering the order names with a random RSA key
  3099  	testKey, err := rsa.GenerateKey(rand.Reader, 2048)
  3100  	test.AssertNotError(t, err, "error generating test key")
  3101  	csr, err := x509.CreateCertificateRequest(rand.Reader, &x509.CertificateRequest{
  3102  		PublicKey:          testKey.PublicKey,
  3103  		SignatureAlgorithm: x509.SHA256WithRSA,
  3104  		Subject:            pkix.Name{CommonName: "not-example.com"},
  3105  		DNSNames:           names,
  3106  	}, testKey)
  3107  	test.AssertNotError(t, err, "Could not create test order CSR")
  3108  
  3109  	// Create a mock certificate for the fake CA to return
  3110  	template := &x509.Certificate{
  3111  		SerialNumber: big.NewInt(12),
  3112  		Subject: pkix.Name{
  3113  			CommonName: "not-example.com",
  3114  		},
  3115  		DNSNames:              names,
  3116  		NotBefore:             time.Now(),
  3117  		NotAfter:              time.Now().AddDate(0, 0, 1),
  3118  		BasicConstraintsValid: true,
  3119  		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
  3120  	}
  3121  	cert, err := x509.CreateCertificate(rand.Reader, template, template, testKey.Public(), testKey)
  3122  	test.AssertNotError(t, err, "Failed to create mock cert for test CA")
  3123  
  3124  	// Set up the RA's CA with a mock that returns the cert from above
  3125  	ra.CA = &mocks.MockCA{
  3126  		PEM: pem.EncodeToMemory(&pem.Block{
  3127  			Bytes: cert,
  3128  		}),
  3129  	}
  3130  
  3131  	// The mock cert needs to be parsed to get its notbefore/notafter dates
  3132  	parsedCerts, err := x509.ParseCertificates(cert)
  3133  	test.AssertNotError(t, err, "Failed to parse mock cert DER bytes")
  3134  	test.AssertEquals(t, len(parsedCerts), 1)
  3135  	parsedCert := parsedCerts[0]
  3136  
  3137  	// Cast the RA's mock log so we can ensure its cleared and can access the
  3138  	// matched log lines
  3139  	mockLog := ra.log.(*blog.Mock)
  3140  	mockLog.Clear()
  3141  
  3142  	// Finalize the order with the CSR
  3143  	order.Status = string(core.StatusReady)
  3144  	_, err = ra.FinalizeOrder(context.Background(), &rapb.FinalizeOrderRequest{
  3145  		Order: order,
  3146  		Csr:   csr,
  3147  	})
  3148  	test.AssertNotError(t, err, "Error finalizing test order")
  3149  
  3150  	// Get the logged lines from the audit logger
  3151  	loglines := mockLog.GetAllMatching("Certificate request - successful JSON=")
  3152  
  3153  	// There should be exactly 1 matching log line
  3154  	test.AssertEquals(t, len(loglines), 1)
  3155  	// Strip away the stuff before 'JSON='
  3156  	jsonContent := strings.TrimPrefix(loglines[0], "INFO: [AUDIT] Certificate request - successful JSON=")
  3157  
  3158  	// Unmarshal the JSON into a certificate request event object
  3159  	var event certificateRequestEvent
  3160  	err = json.Unmarshal([]byte(jsonContent), &event)
  3161  	// The JSON should unmarshal without error
  3162  	test.AssertNotError(t, err, "Error unmarshalling logged JSON issuance event")
  3163  	// The event should have no error
  3164  	test.AssertEquals(t, event.Error, "")
  3165  	// The event requester should be the expected reg ID
  3166  	test.AssertEquals(t, event.Requester, Registration.Id)
  3167  	// The event order ID should be the expected order ID
  3168  	test.AssertEquals(t, event.OrderID, order.Id)
  3169  	// The event serial number should be the expected serial number
  3170  	test.AssertEquals(t, event.SerialNumber, core.SerialToString(template.SerialNumber))
  3171  	// The event verified fields should be the expected value
  3172  	test.AssertDeepEquals(t, event.VerifiedFields, []string{"subject.commonName", "subjectAltName"})
  3173  	// The event CommonName should match the expected common name
  3174  	test.AssertEquals(t, event.CommonName, "not-example.com")
  3175  	// The event names should match the order names
  3176  	test.AssertDeepEquals(t, core.UniqueLowerNames(event.Names), core.UniqueLowerNames(order.Names))
  3177  	// The event's NotBefore and NotAfter should match the cert's
  3178  	test.AssertEquals(t, event.NotBefore, parsedCert.NotBefore)
  3179  	test.AssertEquals(t, event.NotAfter, parsedCert.NotAfter)
  3180  
  3181  	// There should be one event Authorization entry for each name
  3182  	test.AssertEquals(t, len(event.Authorizations), len(names))
  3183  
  3184  	// Check the authz entry for each name
  3185  	for i, name := range names {
  3186  		authzEntry := event.Authorizations[name]
  3187  		// The authz entry should have the correct authz ID
  3188  		test.AssertEquals(t, authzEntry.ID, fmt.Sprintf("%d", authzIDs[i]))
  3189  		// The authz entry should have the correct challenge type
  3190  		test.AssertEquals(t, authzEntry.ChallengeType, challs[i])
  3191  	}
  3192  }
  3193  
  3194  func TestIssueCertificateCAACheckLog(t *testing.T) {
  3195  	_, sa, ra, fc, cleanUp := initAuthorities(t)
  3196  	defer cleanUp()
  3197  
  3198  	// Set up order and authz expiries.
  3199  	ra.orderLifetime = 24 * time.Hour
  3200  	ra.authorizationLifetime = 15 * time.Hour
  3201  
  3202  	exp := fc.Now().Add(24 * time.Hour)
  3203  	recent := fc.Now().Add(-1 * time.Hour)
  3204  	older := fc.Now().Add(-8 * time.Hour)
  3205  
  3206  	// Make some valid authzs for four names. Half of them were validated
  3207  	// recently and half were validated in excess of our CAA recheck time.
  3208  	names := []string{"not-example.com", "www.not-example.com", "still.not-example.com", "definitely.not-example.com"}
  3209  	var authzIDs []int64
  3210  	for i, name := range names {
  3211  		attemptedAt := older
  3212  		if i%2 == 0 {
  3213  			attemptedAt = recent
  3214  		}
  3215  		authzIDs = append(authzIDs, createFinalizedAuthorization(t, sa, name, exp, core.ChallengeTypeHTTP01, attemptedAt))
  3216  	}
  3217  
  3218  	// Create a pending order for all of the names.
  3219  	order, err := sa.NewOrderAndAuthzs(context.Background(), &sapb.NewOrderAndAuthzsRequest{
  3220  		NewOrder: &sapb.NewOrderRequest{
  3221  			RegistrationID:   Registration.Id,
  3222  			ExpiresNS:        exp.UnixNano(),
  3223  			Expires:          timestamppb.New(exp),
  3224  			Names:            names,
  3225  			V2Authorizations: authzIDs,
  3226  		},
  3227  	})
  3228  	test.AssertNotError(t, err, "Could not add test order with finalized authz IDs")
  3229  
  3230  	// Generate a CSR covering the order names with a random RSA key.
  3231  	testKey, err := rsa.GenerateKey(rand.Reader, 2048)
  3232  	test.AssertNotError(t, err, "error generating test key")
  3233  	csr, err := x509.CreateCertificateRequest(rand.Reader, &x509.CertificateRequest{
  3234  		PublicKey:          testKey.PublicKey,
  3235  		SignatureAlgorithm: x509.SHA256WithRSA,
  3236  		Subject:            pkix.Name{CommonName: "not-example.com"},
  3237  		DNSNames:           names,
  3238  	}, testKey)
  3239  	test.AssertNotError(t, err, "Could not create test order CSR")
  3240  
  3241  	// Create a mock certificate for the fake CA to return.
  3242  	template := &x509.Certificate{
  3243  		SerialNumber: big.NewInt(12),
  3244  		Subject: pkix.Name{
  3245  			CommonName: "not-example.com",
  3246  		},
  3247  		DNSNames:              names,
  3248  		NotBefore:             time.Now(),
  3249  		NotAfter:              time.Now().AddDate(0, 0, 1),
  3250  		BasicConstraintsValid: true,
  3251  		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
  3252  	}
  3253  	cert, err := x509.CreateCertificate(rand.Reader, template, template, testKey.Public(), testKey)
  3254  	test.AssertNotError(t, err, "Failed to create mock cert for test CA")
  3255  
  3256  	// Set up the RA's CA with a mock that returns the cert from above.
  3257  	ra.CA = &mocks.MockCA{
  3258  		PEM: pem.EncodeToMemory(&pem.Block{
  3259  			Bytes: cert,
  3260  		}),
  3261  	}
  3262  
  3263  	// Cast the RA's mock log so we can ensure its cleared and can access the
  3264  	// matched log lines.
  3265  	mockLog := ra.log.(*blog.Mock)
  3266  	mockLog.Clear()
  3267  
  3268  	// Finalize the order with the CSR.
  3269  	order.Status = string(core.StatusReady)
  3270  	_, err = ra.FinalizeOrder(context.Background(), &rapb.FinalizeOrderRequest{
  3271  		Order: order,
  3272  		Csr:   csr,
  3273  	})
  3274  	test.AssertNotError(t, err, "Error finalizing test order")
  3275  
  3276  	// Get the logged lines from the mock logger.
  3277  	loglines := mockLog.GetAllMatching("FinalizationCaaCheck JSON=")
  3278  	// There should be exactly 1 matching log line.
  3279  	test.AssertEquals(t, len(loglines), 1)
  3280  
  3281  	// Strip away the stuff before 'JSON='.
  3282  	jsonContent := strings.TrimPrefix(loglines[0], "INFO: FinalizationCaaCheck JSON=")
  3283  
  3284  	// Unmarshal the JSON into an event object.
  3285  	var event finalizationCAACheckEvent
  3286  	err = json.Unmarshal([]byte(jsonContent), &event)
  3287  	// The JSON should unmarshal without error.
  3288  	test.AssertNotError(t, err, "Error unmarshalling logged JSON issuance event.")
  3289  	// The event requester should be the expected registration ID.
  3290  	test.AssertEquals(t, event.Requester, Registration.Id)
  3291  	// The event should have the expected number of Authzs where CAA was reused.
  3292  	test.AssertEquals(t, event.Reused, 2)
  3293  	// The event should have the expected number of Authzs where CAA was
  3294  	// rechecked.
  3295  	test.AssertEquals(t, event.Rechecked, 2)
  3296  }
  3297  
  3298  // TestUpdateMissingAuthorization tests the race condition where a challenge is
  3299  // updated to valid concurrently with another attempt to have the challenge
  3300  // updated. Previously this would return a `berrors.InternalServer` error when
  3301  // the row was found missing from `pendingAuthorizations` by the 2nd update
  3302  // since the 1st had already deleted it. We accept this may happen and now test
  3303  // for a `berrors.NotFound` error return.
  3304  //
  3305  // See https://github.com/letsencrypt/boulder/issues/3201
  3306  func TestUpdateMissingAuthorization(t *testing.T) {
  3307  	_, sa, ra, fc, cleanUp := initAuthorities(t)
  3308  	defer cleanUp()
  3309  	ctx := context.Background()
  3310  
  3311  	authzPB := createPendingAuthorization(t, sa, Identifier, fc.Now().Add(12*time.Hour))
  3312  	authz, err := bgrpc.PBToAuthz(authzPB)
  3313  	test.AssertNotError(t, err, "failed to deserialize authz")
  3314  
  3315  	// Twiddle the authz to pretend its been validated by the VA
  3316  	authz.Status = "valid"
  3317  	authz.Challenges[0].Status = "valid"
  3318  	err = ra.recordValidation(ctx, authz.ID, authz.Expires, &authz.Challenges[0])
  3319  	test.AssertNotError(t, err, "ra.recordValidation failed")
  3320  
  3321  	err = ra.recordValidation(ctx, authz.ID, authz.Expires, &authz.Challenges[0])
  3322  	test.AssertError(t, err, "ra.recordValidation didn't fail")
  3323  	test.AssertErrorIs(t, err, berrors.NotFound)
  3324  }
  3325  
  3326  func TestPerformValidationBadChallengeType(t *testing.T) {
  3327  	_, _, ra, fc, cleanUp := initAuthorities(t)
  3328  	defer cleanUp()
  3329  	pa, err := policy.New(map[core.AcmeChallenge]bool{}, blog.NewMock())
  3330  	test.AssertNotError(t, err, "Couldn't create PA")
  3331  	ra.PA = pa
  3332  
  3333  	exp := fc.Now().Add(10 * time.Hour)
  3334  	authz := core.Authorization{
  3335  		ID:             "1337",
  3336  		Identifier:     identifier.DNSIdentifier("not-example.com"),
  3337  		RegistrationID: 1,
  3338  		Status:         "valid",
  3339  		Challenges: []core.Challenge{
  3340  			{
  3341  				Status: core.StatusValid,
  3342  				Type:   core.ChallengeTypeHTTP01,
  3343  				Token:  "exampleToken",
  3344  			},
  3345  		},
  3346  		Expires: &exp,
  3347  	}
  3348  	authzPB, err := bgrpc.AuthzToPB(authz)
  3349  	test.AssertNotError(t, err, "AuthzToPB failed")
  3350  
  3351  	_, err = ra.PerformValidation(context.Background(), &rapb.PerformValidationRequest{
  3352  		Authz:          authzPB,
  3353  		ChallengeIndex: 0,
  3354  	})
  3355  	test.AssertError(t, err, "ra.PerformValidation allowed a update to a authorization")
  3356  	test.AssertEquals(t, err.Error(), "challenge type \"http-01\" no longer allowed")
  3357  }
  3358  
  3359  type timeoutPub struct {
  3360  }
  3361  
  3362  func (mp *timeoutPub) SubmitToSingleCTWithResult(_ context.Context, _ *pubpb.Request, _ ...grpc.CallOption) (*pubpb.Result, error) {
  3363  	return nil, context.DeadlineExceeded
  3364  }
  3365  
  3366  func TestCTPolicyMeasurements(t *testing.T) {
  3367  	_, ssa, ra, _, cleanup := initAuthorities(t)
  3368  	defer cleanup()
  3369  
  3370  	ra.ctpolicy = ctpolicy.New(&timeoutPub{}, loglist.List{
  3371  		"OperA": {
  3372  			"LogA1": {Url: "UrlA1", Key: "KeyA1"},
  3373  		},
  3374  		"OperB": {
  3375  			"LogB1": {Url: "UrlB1", Key: "KeyB1"},
  3376  		},
  3377  	}, nil, nil, 0, log, metrics.NoopRegisterer)
  3378  
  3379  	// Create valid authorizations for not-example.com and www.not-example.com
  3380  	exp := ra.clk.Now().Add(365 * 24 * time.Hour)
  3381  	authzIDA := createFinalizedAuthorization(t, ssa, "not-example.com", exp, core.ChallengeTypeHTTP01, ra.clk.Now())
  3382  	authzIDB := createFinalizedAuthorization(t, ssa, "www.not-example.com", exp, core.ChallengeTypeHTTP01, ra.clk.Now())
  3383  
  3384  	order, err := ra.SA.NewOrderAndAuthzs(context.Background(), &sapb.NewOrderAndAuthzsRequest{
  3385  		NewOrder: &sapb.NewOrderRequest{
  3386  			RegistrationID:   Registration.Id,
  3387  			ExpiresNS:        exp.UnixNano(),
  3388  			Expires:          timestamppb.New(exp),
  3389  			Names:            []string{"not-example.com", "www.not-example.com"},
  3390  			V2Authorizations: []int64{authzIDA, authzIDB},
  3391  		},
  3392  	})
  3393  	test.AssertNotError(t, err, "error generating test order")
  3394  
  3395  	testKey, err := rsa.GenerateKey(rand.Reader, 2048)
  3396  	test.AssertNotError(t, err, "error generating test key")
  3397  
  3398  	csr, err := x509.CreateCertificateRequest(rand.Reader, &x509.CertificateRequest{
  3399  		PublicKey:          testKey.Public(),
  3400  		SignatureAlgorithm: x509.SHA256WithRSA,
  3401  		DNSNames:           []string{"not-example.com", "www.not-example.com"},
  3402  	}, testKey)
  3403  	test.AssertNotError(t, err, "error generating test CSR")
  3404  
  3405  	_, err = ra.FinalizeOrder(context.Background(), &rapb.FinalizeOrderRequest{
  3406  		Order: order,
  3407  		Csr:   csr,
  3408  	})
  3409  	test.AssertError(t, err, "FinalizeOrder should have failed when SCTs timed out")
  3410  	test.AssertContains(t, err.Error(), "getting SCTs")
  3411  	test.AssertMetricWithLabelsEquals(t, ra.ctpolicyResults, prometheus.Labels{"result": "failure"}, 1)
  3412  }
  3413  
  3414  func TestWildcardOverlap(t *testing.T) {
  3415  	err := wildcardOverlap([]string{
  3416  		"*.example.com",
  3417  		"*.example.net",
  3418  	})
  3419  	if err != nil {
  3420  		t.Errorf("Got error %q, expected none", err)
  3421  	}
  3422  	err = wildcardOverlap([]string{
  3423  		"*.example.com",
  3424  		"*.example.net",
  3425  		"www.example.com",
  3426  	})
  3427  	if err == nil {
  3428  		t.Errorf("Got no error, expected one")
  3429  	}
  3430  	test.AssertErrorIs(t, err, berrors.Malformed)
  3431  
  3432  	err = wildcardOverlap([]string{
  3433  		"*.foo.example.com",
  3434  		"*.example.net",
  3435  		"www.example.com",
  3436  	})
  3437  	if err != nil {
  3438  		t.Errorf("Got error %q, expected none", err)
  3439  	}
  3440  }
  3441  
  3442  // mockCAFailPrecert is a mock CA that always returns an error from `IssuePrecertificate`
  3443  type mockCAFailPrecert struct {
  3444  	mocks.MockCA
  3445  	err error
  3446  }
  3447  
  3448  func (ca *mockCAFailPrecert) IssuePrecertificate(
  3449  	context.Context,
  3450  	*capb.IssueCertificateRequest,
  3451  	...grpc.CallOption) (*capb.IssuePrecertificateResponse, error) {
  3452  	return nil, ca.err
  3453  }
  3454  
  3455  // mockCAFailCertForPrecert is a mock CA that always returns an error from
  3456  // `IssueCertificateForPrecertificate`
  3457  type mockCAFailCertForPrecert struct {
  3458  	mocks.MockCA
  3459  	err error
  3460  }
  3461  
  3462  // IssuePrecertificate needs to be mocked for mockCAFailCertForPrecert's `IssueCertificateForPrecertificate` to get called.
  3463  func (ca *mockCAFailCertForPrecert) IssuePrecertificate(
  3464  	context.Context,
  3465  	*capb.IssueCertificateRequest,
  3466  	...grpc.CallOption) (*capb.IssuePrecertificateResponse, error) {
  3467  	k, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
  3468  	if err != nil {
  3469  		return nil, err
  3470  	}
  3471  	tmpl := &ctx509.Certificate{
  3472  		SerialNumber: big.NewInt(1),
  3473  		ExtraExtensions: []ctpkix.Extension{
  3474  			{
  3475  				Id:       ctx509.OIDExtensionCTPoison,
  3476  				Critical: true,
  3477  				Value:    ctasn1.NullBytes,
  3478  			},
  3479  		},
  3480  	}
  3481  	precert, err := ctx509.CreateCertificate(rand.Reader, tmpl, tmpl, k.Public(), k)
  3482  	if err != nil {
  3483  		return nil, err
  3484  	}
  3485  	return &capb.IssuePrecertificateResponse{
  3486  		DER: precert,
  3487  	}, nil
  3488  }
  3489  
  3490  func (ca *mockCAFailCertForPrecert) IssueCertificateForPrecertificate(
  3491  	context.Context,
  3492  	*capb.IssueCertificateForPrecertificateRequest,
  3493  	...grpc.CallOption) (*corepb.Certificate, error) {
  3494  	return &corepb.Certificate{}, ca.err
  3495  }
  3496  
  3497  // TestIssueCertificateInnerErrs tests that errors from the CA caught during
  3498  // `ra.issueCertificateInner` are propagated correctly, with the part of the
  3499  // issuance process that failed prefixed on the error message.
  3500  func TestIssueCertificateInnerErrs(t *testing.T) {
  3501  	_, sa, ra, _, cleanUp := initAuthorities(t)
  3502  	defer cleanUp()
  3503  
  3504  	ra.orderLifetime = 24 * time.Hour
  3505  	exp := ra.clk.Now().Add(24 * time.Hour)
  3506  
  3507  	// Make some valid authorizations for some names
  3508  	names := []string{"not-example.com", "www.not-example.com", "still.not-example.com", "definitely.not-example.com"}
  3509  	var authzIDs []int64
  3510  	for _, name := range names {
  3511  		authzIDs = append(authzIDs, createFinalizedAuthorization(t, sa, name, exp, core.ChallengeTypeHTTP01, ra.clk.Now()))
  3512  	}
  3513  
  3514  	// Create a pending order for all of the names
  3515  	order, err := sa.NewOrderAndAuthzs(context.Background(), &sapb.NewOrderAndAuthzsRequest{
  3516  		NewOrder: &sapb.NewOrderRequest{
  3517  			RegistrationID:   Registration.Id,
  3518  			ExpiresNS:        exp.UnixNano(),
  3519  			Expires:          timestamppb.New(exp),
  3520  			Names:            names,
  3521  			V2Authorizations: authzIDs,
  3522  		},
  3523  	})
  3524  	test.AssertNotError(t, err, "Could not add test order with finalized authz IDs")
  3525  
  3526  	// Generate a CSR covering the order names with a random RSA key
  3527  	testKey, err := rsa.GenerateKey(rand.Reader, 2048)
  3528  	test.AssertNotError(t, err, "error generating test key")
  3529  	csr, err := x509.CreateCertificateRequest(rand.Reader, &x509.CertificateRequest{
  3530  		PublicKey:          testKey.PublicKey,
  3531  		SignatureAlgorithm: x509.SHA256WithRSA,
  3532  		Subject:            pkix.Name{CommonName: "not-example.com"},
  3533  		DNSNames:           names,
  3534  	}, testKey)
  3535  	test.AssertNotError(t, err, "Could not create test order CSR")
  3536  
  3537  	csrOb, err := x509.ParseCertificateRequest(csr)
  3538  	test.AssertNotError(t, err, "Error pasring generated CSR")
  3539  
  3540  	testCases := []struct {
  3541  		Name         string
  3542  		Mock         capb.CertificateAuthorityClient
  3543  		ExpectedErr  error
  3544  		ExpectedProb *berrors.BoulderError
  3545  	}{
  3546  		{
  3547  			Name: "vanilla error during IssuePrecertificate",
  3548  			Mock: &mockCAFailPrecert{
  3549  				err: fmt.Errorf("bad bad not good"),
  3550  			},
  3551  			ExpectedErr: fmt.Errorf("issuing precertificate: bad bad not good"),
  3552  		},
  3553  		{
  3554  			Name: "malformed problem during IssuePrecertificate",
  3555  			Mock: &mockCAFailPrecert{
  3556  				err: berrors.MalformedError("detected 1x whack attack"),
  3557  			},
  3558  			ExpectedProb: &berrors.BoulderError{
  3559  				Detail: "issuing precertificate: detected 1x whack attack",
  3560  				Type:   berrors.Malformed,
  3561  			},
  3562  		},
  3563  		{
  3564  			Name: "vanilla error during IssueCertificateForPrecertificate",
  3565  			Mock: &mockCAFailCertForPrecert{
  3566  				err: fmt.Errorf("aaaaaaaaaaaaaaaaaaaa!!"),
  3567  			},
  3568  			ExpectedErr: fmt.Errorf("issuing certificate for precertificate: aaaaaaaaaaaaaaaaaaaa!!"),
  3569  		},
  3570  		{
  3571  			Name: "malformed problem during IssueCertificateForPrecertificate",
  3572  			Mock: &mockCAFailCertForPrecert{
  3573  				err: berrors.MalformedError("provided DER is DERanged"),
  3574  			},
  3575  			ExpectedProb: &berrors.BoulderError{
  3576  				Detail: "issuing certificate for precertificate: provided DER is DERanged",
  3577  				Type:   berrors.Malformed,
  3578  			},
  3579  		},
  3580  	}
  3581  
  3582  	for _, tc := range testCases {
  3583  		t.Run(tc.Name, func(t *testing.T) {
  3584  			// Mock the CA
  3585  			ra.CA = tc.Mock
  3586  			// Attempt issuance
  3587  			_, err = ra.issueCertificateInner(ctx, csrOb, accountID(Registration.Id), orderID(order.Id))
  3588  			// We expect all of the testcases to fail because all use mocked CAs that deliberately error
  3589  			test.AssertError(t, err, "issueCertificateInner with failing mock CA did not fail")
  3590  			// If there is an expected `error` then match the error message
  3591  			if tc.ExpectedErr != nil {
  3592  				test.AssertEquals(t, err.Error(), tc.ExpectedErr.Error())
  3593  			} else if tc.ExpectedProb != nil {
  3594  				// If there is an expected `berrors.BoulderError` then we expect the
  3595  				// `issueCertificateInner` error to be a `berrors.BoulderError`
  3596  				var berr *berrors.BoulderError
  3597  				test.AssertErrorWraps(t, err, &berr)
  3598  				// Match the expected berror Type and Detail to the observed
  3599  				test.AssertErrorIs(t, berr, tc.ExpectedProb.Type)
  3600  				test.AssertEquals(t, berr.Detail, tc.ExpectedProb.Detail)
  3601  			}
  3602  		})
  3603  	}
  3604  }
  3605  
  3606  func TestNewOrderMaxNames(t *testing.T) {
  3607  	_, _, ra, _, cleanUp := initAuthorities(t)
  3608  	defer cleanUp()
  3609  
  3610  	ra.maxNames = 2
  3611  	_, err := ra.NewOrder(context.Background(), &rapb.NewOrderRequest{
  3612  		RegistrationID: 1,
  3613  		Names: []string{
  3614  			"a",
  3615  			"b",
  3616  			"c",
  3617  		},
  3618  	})
  3619  	test.AssertError(t, err, "NewOrder didn't fail with too many names in request")
  3620  	test.AssertEquals(t, err.Error(), "Order cannot contain more than 2 DNS names")
  3621  	test.AssertErrorIs(t, err, berrors.Malformed)
  3622  }
  3623  
  3624  // CSR generated by Go:
  3625  // * Random public key
  3626  // * CN = not-example.com
  3627  // * DNSNames = not-example.com, www.not-example.com
  3628  var CSRPEM = []byte(`
  3629  -----BEGIN CERTIFICATE REQUEST-----
  3630  MIICrjCCAZYCAQAwJzELMAkGA1UEBhMCVVMxGDAWBgNVBAMTD25vdC1leGFtcGxl
  3631  LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKT1B7UsonZuLOp7
  3632  qq2pw+COo0I9ZheuhN9ltu1+bAMWBYUb8KFPNGGp8Ygt6YCLjlnWOche7Fjb5lPj
  3633  hV6U2BkEt85mdaGTDg6mU3qjk2/cnZeAvJWW5ewYOBGxN/g/KHgdYZ+uhHH/PbGt
  3634  Wktcv5bRJ9Dxbjxsy7l8SLQ6fd/MF/3z6sBJzIHkcDupDOFdPN/Z0KOw7BOPHAbg
  3635  ghLJTmiESA1Ljxb8848bENlCz8pVizIu2Ilr4xBPtA5oUfO0FJKbT1T66JZoqwy/
  3636  drfrlHA7F6c8kYlAmwiOfWHzlWCkE1YuZPJrZQrt4tJ70rrPxV1qEGJDumzgcEbU
  3637  /aYYiBsCAwEAAaBCMEAGCSqGSIb3DQEJDjEzMDEwLwYDVR0RBCgwJoIPbm90LWV4
  3638  YW1wbGUuY29tghN3d3cubm90LWV4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4IB
  3639  AQBuFo5SHqN1lWmM6rKaOBXFezAdzZyGb9x8+5Zq/eh9pSxpn0MTOmq/u+sDHxsC
  3640  ywcshUO3P9//9u4ALtNn/jsJmSrElsTvG3SH5owl9muNEiOgf+6/rY/X8Zcnv/e0
  3641  Ar9r73BcCkjoAOFbr7xiLLYu5EaBQjSj6/m4ujwJTWS2SqobK5VfdpzmDp4wT3eB
  3642  V4FPLxyxxOLuWLzcBkDdLw/zh922HtR5fqk155Y4pj3WS9NnI/NMHmclrlfY/2P4
  3643  dJrBVM+qVbPTzM19QplMkiy7FxpDx6toUXDYM4KdKKV0+yX/zw/V0/Gb7K7yIjVB
  3644  wqjllqgMjN4nvHjiDXFx/kPY
  3645  -----END CERTIFICATE REQUEST-----
  3646  `)
  3647  
  3648  var eeCertPEM = []byte(`
  3649  -----BEGIN CERTIFICATE-----
  3650  MIIEfTCCAmWgAwIBAgISCr9BRk0C9OOGVke6CAa8F+AXMA0GCSqGSIb3DQEBCwUA
  3651  MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQKDAdUZXN0IENBMRAwDgYDVQQDDAdUZXN0
  3652  IENBMB4XDTE2MDMyMDE4MTEwMFoXDTE2MDMyMDE5MTEwMFowHjEcMBoGA1UEAxMT
  3653  d3d3Lm5vdC1leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
  3654  ggEBAKT1B7UsonZuLOp7qq2pw+COo0I9ZheuhN9ltu1+bAMWBYUb8KFPNGGp8Ygt
  3655  6YCLjlnWOche7Fjb5lPjhV6U2BkEt85mdaGTDg6mU3qjk2/cnZeAvJWW5ewYOBGx
  3656  N/g/KHgdYZ+uhHH/PbGtWktcv5bRJ9Dxbjxsy7l8SLQ6fd/MF/3z6sBJzIHkcDup
  3657  DOFdPN/Z0KOw7BOPHAbgghLJTmiESA1Ljxb8848bENlCz8pVizIu2Ilr4xBPtA5o
  3658  UfO0FJKbT1T66JZoqwy/drfrlHA7F6c8kYlAmwiOfWHzlWCkE1YuZPJrZQrt4tJ7
  3659  0rrPxV1qEGJDumzgcEbU/aYYiBsCAwEAAaOBoTCBnjAdBgNVHSUEFjAUBggrBgEF
  3660  BQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUIEr9ryJ0aJuD
  3661  CwBsCp7Eun8Hx4AwHwYDVR0jBBgwFoAUmiamd/N/8knrCb1QlhwB4WXCqaswLwYD
  3662  VR0RBCgwJoIPbm90LWV4YW1wbGUuY29tghN3d3cubm90LWV4YW1wbGUuY29tMA0G
  3663  CSqGSIb3DQEBCwUAA4ICAQBpGLrCt38Z+knbuE1ALEB3hqUQCAm1OPDW6HR+v2nO
  3664  f2ERxTwL9Cad++3vONxgB68+6KQeIf5ph48OGnS5DgO13mb2cxLlmM2IJpkbSFtW
  3665  VeRNFt/WxRJafpbKw2hgQNJ/sxEAsCyA+kVeh1oCxGQyPO7IIXtw5FecWfIiNNwM
  3666  mVM17uchtvsM5BRePvet9xZxrKOFnn6TQRs8vC4e59Y8h52On+L2Q/ytAa7j3+fb
  3667  7OYCe+yWypGeosekamZTMBjHFV3RRxsGdRATSuZkv1uewyUnEPmsy5Ow4doSYZKW
  3668  QmKjti+vv1YhAhFxPArob0SG3YOiFuKzZ9rSOhUtzSg01ml/kRyOiC7rfO7NRzHq
  3669  idhPUhu2QBmdJTLLOBQLvKDNDOHqDYwKdIHJ7pup2y0Fvm4T96q5bnrSdmz/QAlB
  3670  XVw08HWMcjeOeHYiHST3yxYfQivTNm2PlKfUACb7vcrQ6pYhOnVdYgJZm6gkV4Xd
  3671  K1HKja36snIevv/gSgsE7bGcBYLVCvf16o3IRt9K8CpDoSsWn0iAVcwUP2CyPLm4
  3672  QsqA1afjTUPKQTAgDKRecDPhrT1+FjtBwdpXetpRiBK0UE5exfnI4nszZ9+BYG1l
  3673  xGUhoOJp0T++nz6R3TX7Rwk7KmG6xX3vWr/MFu5A3c8fvkqj987Vti5BeBezCXfs
  3674  rA==
  3675  -----END CERTIFICATE-----
  3676  `)
  3677  
  3678  type mockSARevocation struct {
  3679  	mocks.StorageAuthority
  3680  
  3681  	known   *corepb.CertificateStatus
  3682  	blocked []*sapb.AddBlockedKeyRequest
  3683  	revoked map[string]int64
  3684  }
  3685  
  3686  func newMockSARevocation(known *x509.Certificate, clk clock.Clock) *mockSARevocation {
  3687  	return &mockSARevocation{
  3688  		StorageAuthority: *mocks.NewStorageAuthority(clk),
  3689  		known: &corepb.CertificateStatus{
  3690  			Serial:   core.SerialToString(known.SerialNumber),
  3691  			IssuerID: int64(issuance.GetIssuerNameID(known)),
  3692  		},
  3693  		blocked: make([]*sapb.AddBlockedKeyRequest, 0),
  3694  		revoked: make(map[string]int64),
  3695  	}
  3696  }
  3697  
  3698  func (msar *mockSARevocation) AddBlockedKey(_ context.Context, req *sapb.AddBlockedKeyRequest, _ ...grpc.CallOption) (*emptypb.Empty, error) {
  3699  	msar.blocked = append(msar.blocked, req)
  3700  	return &emptypb.Empty{}, nil
  3701  }
  3702  
  3703  func (msar *mockSARevocation) GetCertificateStatus(_ context.Context, req *sapb.Serial, _ ...grpc.CallOption) (*corepb.CertificateStatus, error) {
  3704  	if msar.known != nil && req.Serial == msar.known.Serial {
  3705  		return msar.known, nil
  3706  	}
  3707  	return nil, fmt.Errorf("unknown certificate status")
  3708  }
  3709  
  3710  func (msar *mockSARevocation) RevokeCertificate(_ context.Context, req *sapb.RevokeCertificateRequest, _ ...grpc.CallOption) (*emptypb.Empty, error) {
  3711  	if _, present := msar.revoked[req.Serial]; present {
  3712  		return nil, berrors.AlreadyRevokedError("already revoked")
  3713  	}
  3714  	msar.revoked[req.Serial] = req.Reason
  3715  	msar.known.Status = string(core.OCSPStatusRevoked)
  3716  	return &emptypb.Empty{}, nil
  3717  }
  3718  
  3719  func (msar *mockSARevocation) UpdateRevokedCertificate(_ context.Context, req *sapb.RevokeCertificateRequest, _ ...grpc.CallOption) (*emptypb.Empty, error) {
  3720  	reason, present := msar.revoked[req.Serial]
  3721  	if !present {
  3722  		return nil, errors.New("not already revoked")
  3723  	}
  3724  	if present && reason == ocsp.KeyCompromise {
  3725  		return nil, berrors.AlreadyRevokedError("already revoked for keyCompromise")
  3726  	}
  3727  	msar.revoked[req.Serial] = req.Reason
  3728  	return &emptypb.Empty{}, nil
  3729  }
  3730  
  3731  type mockOCSPA struct {
  3732  	mocks.MockCA
  3733  }
  3734  
  3735  func (mcao *mockOCSPA) GenerateOCSP(context.Context, *capb.GenerateOCSPRequest, ...grpc.CallOption) (*capb.OCSPResponse, error) {
  3736  	return &capb.OCSPResponse{Response: []byte{1, 2, 3}}, nil
  3737  }
  3738  
  3739  type mockPurger struct{}
  3740  
  3741  func (mp *mockPurger) Purge(context.Context, *akamaipb.PurgeRequest, ...grpc.CallOption) (*emptypb.Empty, error) {
  3742  	return &emptypb.Empty{}, nil
  3743  }
  3744  
  3745  type mockSAGenerateOCSP struct {
  3746  	mocks.StorageAuthority
  3747  	expiration time.Time
  3748  }
  3749  
  3750  func (msgo *mockSAGenerateOCSP) GetCertificateStatus(_ context.Context, req *sapb.Serial, _ ...grpc.CallOption) (*corepb.CertificateStatus, error) {
  3751  	return &corepb.CertificateStatus{
  3752  		Serial:     req.Serial,
  3753  		Status:     "good",
  3754  		NotAfterNS: msgo.expiration.UTC().UnixNano(),
  3755  		NotAfter:   timestamppb.New(msgo.expiration.UTC()),
  3756  	}, nil
  3757  }
  3758  
  3759  func TestGenerateOCSP(t *testing.T) {
  3760  	_, _, ra, clk, cleanUp := initAuthorities(t)
  3761  	defer cleanUp()
  3762  
  3763  	ra.OCSP = &mockOCSPA{}
  3764  	ra.SA = &mockSAGenerateOCSP{expiration: clk.Now().Add(time.Hour)}
  3765  
  3766  	req := &rapb.GenerateOCSPRequest{
  3767  		Serial: core.SerialToString(big.NewInt(1)),
  3768  	}
  3769  
  3770  	resp, err := ra.GenerateOCSP(context.Background(), req)
  3771  	test.AssertNotError(t, err, "generating OCSP")
  3772  	test.AssertByteEquals(t, resp.Response, []byte{1, 2, 3})
  3773  
  3774  	ra.SA = &mockSAGenerateOCSP{expiration: clk.Now().Add(-time.Hour)}
  3775  	_, err = ra.GenerateOCSP(context.Background(), req)
  3776  	if !errors.Is(err, berrors.NotFound) {
  3777  		t.Errorf("expected NotFound error, got %s", err)
  3778  	}
  3779  }
  3780  
  3781  func TestRevokeCertByApplicant_Subscriber(t *testing.T) {
  3782  	_, _, ra, clk, cleanUp := initAuthorities(t)
  3783  	defer cleanUp()
  3784  
  3785  	ra.OCSP = &mockOCSPA{}
  3786  	ra.purger = &mockPurger{}
  3787  
  3788  	_, cert := test.ThrowAwayCert(t, 1)
  3789  	ic, err := issuance.NewCertificate(cert)
  3790  	test.AssertNotError(t, err, "failed to create issuer cert")
  3791  	ra.issuersByNameID = map[issuance.IssuerNameID]*issuance.Certificate{
  3792  		ic.NameID(): ic,
  3793  	}
  3794  	ra.issuersByID = map[issuance.IssuerID]*issuance.Certificate{
  3795  		ic.ID(): ic,
  3796  	}
  3797  	ra.SA = newMockSARevocation(cert, clk)
  3798  
  3799  	// Revoking without a regID should fail.
  3800  	_, err = ra.RevokeCertByApplicant(context.Background(), &rapb.RevokeCertByApplicantRequest{
  3801  		Cert:  cert.Raw,
  3802  		Code:  ocsp.Unspecified,
  3803  		RegID: 0,
  3804  	})
  3805  	test.AssertError(t, err, "should have failed with no RegID")
  3806  	test.AssertContains(t, err.Error(), "incomplete")
  3807  
  3808  	// Revoking for a disallowed reason should fail.
  3809  	_, err = ra.RevokeCertByApplicant(context.Background(), &rapb.RevokeCertByApplicantRequest{
  3810  		Cert:  cert.Raw,
  3811  		Code:  ocsp.CertificateHold,
  3812  		RegID: 1,
  3813  	})
  3814  	test.AssertError(t, err, "should have failed with bad reasonCode")
  3815  	test.AssertContains(t, err.Error(), "disallowed revocation reason")
  3816  
  3817  	// Revoking with the correct regID should succeed.
  3818  	_, err = ra.RevokeCertByApplicant(context.Background(), &rapb.RevokeCertByApplicantRequest{
  3819  		Cert:  cert.Raw,
  3820  		Code:  ocsp.Unspecified,
  3821  		RegID: 1,
  3822  	})
  3823  	test.AssertNotError(t, err, "should have succeeded")
  3824  
  3825  	// Revoking an already-revoked serial should fail.
  3826  	_, err = ra.RevokeCertByApplicant(context.Background(), &rapb.RevokeCertByApplicantRequest{
  3827  		Cert:  cert.Raw,
  3828  		Code:  ocsp.Unspecified,
  3829  		RegID: 1,
  3830  	})
  3831  	test.AssertError(t, err, "should have failed with bad reasonCode")
  3832  	test.AssertContains(t, err.Error(), "already revoked")
  3833  }
  3834  
  3835  func TestRevokeCertByApplicant_Controller(t *testing.T) {
  3836  	_, _, ra, clk, cleanUp := initAuthorities(t)
  3837  	defer cleanUp()
  3838  
  3839  	ra.OCSP = &mockOCSPA{}
  3840  	ra.purger = &mockPurger{}
  3841  
  3842  	_, cert := test.ThrowAwayCert(t, 1)
  3843  	ic, err := issuance.NewCertificate(cert)
  3844  	test.AssertNotError(t, err, "failed to create issuer cert")
  3845  	ra.issuersByNameID = map[issuance.IssuerNameID]*issuance.Certificate{
  3846  		ic.NameID(): ic,
  3847  	}
  3848  	ra.issuersByID = map[issuance.IssuerID]*issuance.Certificate{
  3849  		ic.ID(): ic,
  3850  	}
  3851  	mockSA := newMockSARevocation(cert, clk)
  3852  	ra.SA = mockSA
  3853  
  3854  	// Revoking with the wrong regID should fail.
  3855  	_, err = ra.RevokeCertByApplicant(context.Background(), &rapb.RevokeCertByApplicantRequest{
  3856  		Cert:  cert.Raw,
  3857  		Code:  ocsp.Unspecified,
  3858  		RegID: 2,
  3859  	})
  3860  	test.AssertError(t, err, "should have failed with wrong RegID")
  3861  	test.AssertContains(t, err.Error(), "requester does not control all names")
  3862  
  3863  	// Revoking with a different RegID that has valid authorizations should succeed,
  3864  	// but override the revocation reason to cessationOfOperation.
  3865  	_, err = ra.RevokeCertByApplicant(context.Background(), &rapb.RevokeCertByApplicantRequest{
  3866  		Cert:  cert.Raw,
  3867  		Code:  ocsp.Unspecified,
  3868  		RegID: 5,
  3869  	})
  3870  	test.AssertNotError(t, err, "should have succeeded")
  3871  	test.AssertEquals(t, mockSA.revoked[core.SerialToString(cert.SerialNumber)], int64(ocsp.CessationOfOperation))
  3872  }
  3873  
  3874  func TestRevokeCertByKey(t *testing.T) {
  3875  	_, _, ra, clk, cleanUp := initAuthorities(t)
  3876  	defer cleanUp()
  3877  
  3878  	ra.OCSP = &mockOCSPA{}
  3879  	ra.purger = &mockPurger{}
  3880  
  3881  	k, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
  3882  	test.AssertNotError(t, err, "ecdsa.GenerateKey failed")
  3883  	digest, err := core.KeyDigest(k.Public())
  3884  	test.AssertNotError(t, err, "core.KeyDigest failed")
  3885  
  3886  	template := x509.Certificate{SerialNumber: big.NewInt(257)}
  3887  	der, err := x509.CreateCertificate(rand.Reader, &template, &template, k.Public(), k)
  3888  	test.AssertNotError(t, err, "x509.CreateCertificate failed")
  3889  	cert, err := x509.ParseCertificate(der)
  3890  	test.AssertNotError(t, err, "x509.ParseCertificate failed")
  3891  	ic, err := issuance.NewCertificate(cert)
  3892  	test.AssertNotError(t, err, "failed to create issuer cert")
  3893  	ra.issuersByNameID = map[issuance.IssuerNameID]*issuance.Certificate{
  3894  		ic.NameID(): ic,
  3895  	}
  3896  	ra.issuersByID = map[issuance.IssuerID]*issuance.Certificate{
  3897  		ic.ID(): ic,
  3898  	}
  3899  	mockSA := newMockSARevocation(cert, clk)
  3900  	ra.SA = mockSA
  3901  
  3902  	// Revoking should work, but override the requested reason and block the key.
  3903  	_, err = ra.RevokeCertByKey(context.Background(), &rapb.RevokeCertByKeyRequest{
  3904  		Cert: cert.Raw,
  3905  	})
  3906  	test.AssertNotError(t, err, "should have succeeded")
  3907  	test.AssertEquals(t, len(mockSA.blocked), 1)
  3908  	test.Assert(t, bytes.Equal(digest[:], mockSA.blocked[0].KeyHash), "key hash mismatch")
  3909  	test.AssertEquals(t, mockSA.blocked[0].Source, "API")
  3910  	test.AssertEquals(t, len(mockSA.blocked[0].Comment), 0)
  3911  	test.AssertEquals(t, mockSA.revoked[core.SerialToString(cert.SerialNumber)], int64(ocsp.KeyCompromise))
  3912  
  3913  	// Re-revoking should fail, because it is already revoked for keyCompromise.
  3914  	_, err = ra.RevokeCertByKey(context.Background(), &rapb.RevokeCertByKeyRequest{
  3915  		Cert: cert.Raw,
  3916  	})
  3917  	test.AssertError(t, err, "should have failed")
  3918  
  3919  	// Reset and have the Subscriber revoke for a different reason.
  3920  	// Then re-revoking using the key should work.
  3921  	mockSA.revoked = make(map[string]int64)
  3922  	_, err = ra.RevokeCertByApplicant(context.Background(), &rapb.RevokeCertByApplicantRequest{
  3923  		Cert:  cert.Raw,
  3924  		Code:  ocsp.Unspecified,
  3925  		RegID: 1,
  3926  	})
  3927  	test.AssertNotError(t, err, "should have succeeded")
  3928  	_, err = ra.RevokeCertByKey(context.Background(), &rapb.RevokeCertByKeyRequest{
  3929  		Cert: cert.Raw,
  3930  	})
  3931  	test.AssertNotError(t, err, "should have succeeded")
  3932  }
  3933  
  3934  func TestAdministrativelyRevokeCertificate(t *testing.T) {
  3935  	_, _, ra, clk, cleanUp := initAuthorities(t)
  3936  	defer cleanUp()
  3937  
  3938  	ra.OCSP = &mockOCSPA{}
  3939  	ra.purger = &mockPurger{}
  3940  
  3941  	k, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
  3942  	test.AssertNotError(t, err, "ecdsa.GenerateKey failed")
  3943  	digest, err := core.KeyDigest(k.Public())
  3944  	test.AssertNotError(t, err, "core.KeyDigest failed")
  3945  
  3946  	serial := "04eac294a0e61035d8254d5a04f61a37c802"
  3947  	serialInt, err := core.StringToSerial(serial)
  3948  	test.AssertNotError(t, err, "decoding serial number")
  3949  	template := x509.Certificate{SerialNumber: serialInt}
  3950  	der, err := x509.CreateCertificate(rand.Reader, &template, &template, k.Public(), k)
  3951  	test.AssertNotError(t, err, "x509.CreateCertificate failed")
  3952  	cert, err := x509.ParseCertificate(der)
  3953  	test.AssertNotError(t, err, "x509.ParseCertificate failed")
  3954  	ic, err := issuance.NewCertificate(cert)
  3955  	test.AssertNotError(t, err, "failed to create issuer cert")
  3956  	ra.issuersByNameID = map[issuance.IssuerNameID]*issuance.Certificate{
  3957  		ic.NameID(): ic,
  3958  	}
  3959  	ra.issuersByID = map[issuance.IssuerID]*issuance.Certificate{
  3960  		ic.ID(): ic,
  3961  	}
  3962  	mockSA := newMockSARevocation(cert, clk)
  3963  	ra.SA = mockSA
  3964  
  3965  	// Revoking with an empty request should fail immediately.
  3966  	_, err = ra.AdministrativelyRevokeCertificate(context.Background(), &rapb.AdministrativelyRevokeCertificateRequest{})
  3967  	test.AssertError(t, err, "AdministrativelyRevokeCertificate should have failed for nil request object")
  3968  
  3969  	// Revoking with neither a cert nor a serial should fail immediately.
  3970  	_, err = ra.AdministrativelyRevokeCertificate(context.Background(), &rapb.AdministrativelyRevokeCertificateRequest{
  3971  		Code:      ocsp.Unspecified,
  3972  		AdminName: "root",
  3973  	})
  3974  	test.AssertError(t, err, "AdministrativelyRevokeCertificate should have failed with no cert or serial")
  3975  
  3976  	// Revoking with a nil cert and no serial should fail immediately.
  3977  	_, err = ra.AdministrativelyRevokeCertificate(context.Background(), &rapb.AdministrativelyRevokeCertificateRequest{
  3978  		Cert:      []byte{},
  3979  		Code:      ocsp.KeyCompromise,
  3980  		AdminName: "",
  3981  	})
  3982  	test.AssertError(t, err, "AdministrativelyRevokeCertificate should have failed for nil `Cert`")
  3983  
  3984  	// Revoking without an admin name should fail immediately.
  3985  	_, err = ra.AdministrativelyRevokeCertificate(context.Background(), &rapb.AdministrativelyRevokeCertificateRequest{
  3986  		Cert:      cert.Raw,
  3987  		Serial:    serial,
  3988  		Code:      ocsp.KeyCompromise,
  3989  		AdminName: "",
  3990  	})
  3991  	test.AssertError(t, err, "AdministrativelyRevokeCertificate should have failed with empty string for `AdminName`")
  3992  
  3993  	// Revoking for a forbidden reason should fail immediately.
  3994  	_, err = ra.AdministrativelyRevokeCertificate(context.Background(), &rapb.AdministrativelyRevokeCertificateRequest{
  3995  		Cert:      cert.Raw,
  3996  		Serial:    serial,
  3997  		Code:      ocsp.CertificateHold,
  3998  		AdminName: "root",
  3999  	})
  4000  	test.AssertError(t, err, "AdministrativelyRevokeCertificate should have failed with forbidden revocation reason")
  4001  
  4002  	// Revoking a cert for an unspecified reason should work but not block the key.
  4003  	_, err = ra.AdministrativelyRevokeCertificate(context.Background(), &rapb.AdministrativelyRevokeCertificateRequest{
  4004  		Cert:      cert.Raw,
  4005  		Serial:    serial,
  4006  		Code:      ocsp.Unspecified,
  4007  		AdminName: "root",
  4008  	})
  4009  	test.AssertNotError(t, err, "AdministrativelyRevokeCertificate failed")
  4010  	test.AssertEquals(t, len(mockSA.blocked), 0)
  4011  	test.AssertMetricWithLabelsEquals(
  4012  		t, ra.revocationReasonCounter, prometheus.Labels{"reason": "unspecified"}, 1)
  4013  
  4014  	// Revoking a serial for an unspecified reason should work but not block the key.
  4015  	mockSA.revoked = make(map[string]int64)
  4016  	_, err = ra.AdministrativelyRevokeCertificate(context.Background(), &rapb.AdministrativelyRevokeCertificateRequest{
  4017  		Serial:    core.SerialToString(cert.SerialNumber),
  4018  		Code:      ocsp.Unspecified,
  4019  		AdminName: "root",
  4020  	})
  4021  	test.AssertNotError(t, err, "AdministrativelyRevokeCertificate failed")
  4022  	test.AssertEquals(t, len(mockSA.blocked), 0)
  4023  	test.AssertMetricWithLabelsEquals(
  4024  		t, ra.revocationReasonCounter, prometheus.Labels{"reason": "unspecified"}, 2)
  4025  
  4026  	// Duplicate administrative revocation of a serial for an unspecified reason
  4027  	// should fail and not block the key
  4028  	_, err = ra.AdministrativelyRevokeCertificate(context.Background(), &rapb.AdministrativelyRevokeCertificateRequest{
  4029  		Serial:    core.SerialToString(cert.SerialNumber),
  4030  		Code:      ocsp.Unspecified,
  4031  		AdminName: "root",
  4032  	})
  4033  	test.AssertError(t, err, "Should be revoked")
  4034  	test.AssertContains(t, err.Error(), "already revoked")
  4035  	test.AssertEquals(t, len(mockSA.blocked), 0)
  4036  	test.AssertMetricWithLabelsEquals(
  4037  		t, ra.revocationReasonCounter, prometheus.Labels{"reason": "unspecified"}, 2)
  4038  
  4039  	// Revoking a cert for key compromise should work and block the key.
  4040  	mockSA.revoked = make(map[string]int64)
  4041  	_, err = ra.AdministrativelyRevokeCertificate(context.Background(), &rapb.AdministrativelyRevokeCertificateRequest{
  4042  		Cert:      cert.Raw,
  4043  		Serial:    serial,
  4044  		Code:      ocsp.KeyCompromise,
  4045  		AdminName: "root",
  4046  	})
  4047  	test.AssertNotError(t, err, "AdministrativelyRevokeCertificate failed")
  4048  	test.AssertEquals(t, len(mockSA.blocked), 1)
  4049  	test.Assert(t, bytes.Equal(digest[:], mockSA.blocked[0].KeyHash), "key hash mismatch")
  4050  	test.AssertEquals(t, mockSA.blocked[0].Source, "admin-revoker")
  4051  	test.AssertEquals(t, mockSA.blocked[0].Comment, "revoked by root")
  4052  	test.AssertEquals(t, mockSA.blocked[0].AddedNS, clk.Now().UnixNano())
  4053  	test.AssertEquals(t, mockSA.blocked[0].Added.AsTime(), clk.Now())
  4054  	test.AssertMetricWithLabelsEquals(
  4055  		t, ra.revocationReasonCounter, prometheus.Labels{"reason": "keyCompromise"}, 1)
  4056  
  4057  	// Revoking a serial for key compromise should fail because we don't have the pubkey to block.
  4058  	mockSA.revoked = make(map[string]int64)
  4059  	_, err = ra.AdministrativelyRevokeCertificate(context.Background(), &rapb.AdministrativelyRevokeCertificateRequest{
  4060  		Serial:    core.SerialToString(cert.SerialNumber),
  4061  		Code:      ocsp.KeyCompromise,
  4062  		AdminName: "root",
  4063  	})
  4064  	test.AssertError(t, err, "AdministrativelyRevokeCertificate should have failed with just serial for keyCompromise")
  4065  }
  4066  

View as plain text