func TestCertificateKeyNotEqualAccountKey(t *testing.T) {
	_, _, sa, ra, cleanUp := initAuthorities(t)
	defer cleanUp()
	authz := core.Authorization{}
	authz, _ = sa.NewPendingAuthorization(authz)
	authz.Identifier = core.AcmeIdentifier{
		Type:  core.IdentifierDNS,
		Value: "www.example.com",
	}
	csr := x509.CertificateRequest{
		SignatureAlgorithm: x509.SHA256WithRSA,
		PublicKey:          AccountKeyA.Key,
		DNSNames:           []string{"www.example.com"},
	}
	csrBytes, err := x509.CreateCertificateRequest(rand.Reader, &csr, AccountPrivateKey.Key)
	test.AssertNotError(t, err, "Failed to sign CSR")
	parsedCSR, err := x509.ParseCertificateRequest(csrBytes)
	test.AssertNotError(t, err, "Failed to parse CSR")
	sa.UpdatePendingAuthorization(authz)
	sa.FinalizeAuthorization(authz)
	certRequest := core.CertificateRequest{
		CSR: parsedCSR,
	}

	// Registration id 1 has key == AccountKeyA
	_, err = ra.NewCertificate(certRequest, 1)
	test.AssertError(t, err, "Should have rejected cert with key = account key")
	test.AssertEquals(t, err.Error(), "Certificate public key must be different than account key")

	t.Log("DONE TestCertificateKeyNotEqualAccountKey")
}
func TestTotalCertRateLimit(t *testing.T) {
	_, sa, ra, fc, cleanUp := initAuthorities(t)
	defer cleanUp()

	ra.rlPolicies = cmd.RateLimitConfig{
		TotalCertificates: cmd.RateLimitPolicy{
			Threshold: 1,
			Window:    cmd.ConfigDuration{Duration: 24 * 90 * time.Hour},
		},
	}
	fc.Add(24 * 90 * time.Hour)

	AuthzFinal.RegistrationID = Registration.ID
	AuthzFinal, _ = sa.NewPendingAuthorization(AuthzFinal)
	sa.UpdatePendingAuthorization(AuthzFinal)
	sa.FinalizeAuthorization(AuthzFinal)

	// Inject another final authorization to cover www.example.com
	authzFinalWWW := AuthzFinal
	authzFinalWWW.Identifier.Value = "www.not-example.com"
	authzFinalWWW, _ = sa.NewPendingAuthorization(authzFinalWWW)
	sa.FinalizeAuthorization(authzFinalWWW)

	certRequest := core.CertificateRequest{
		CSR: ExampleCSR,
	}

	_, err := ra.NewCertificate(certRequest, Registration.ID)
	test.AssertNotError(t, err, "Failed to issue certificate")

	fc.Add(time.Hour)

	_, err = ra.NewCertificate(certRequest, Registration.ID)
	test.AssertError(t, err, "Total certificate rate limit failed")
}
func TestOnValidationUpdateSuccess(t *testing.T) {
	_, sa, ra, fclk, cleanUp := initAuthorities(t)
	defer cleanUp()
	authzUpdated, err := sa.NewPendingAuthorization(AuthzInitial)
	test.AssertNotError(t, err, "Failed to create new pending authz")

	expires := fclk.Now().Add(300 * 24 * time.Hour)
	authzUpdated.Expires = &expires
	sa.UpdatePendingAuthorization(authzUpdated)

	// Simulate a successful simpleHTTP challenge
	authzFromVA := authzUpdated
	authzFromVA.Challenges[0].Status = core.StatusValid

	ra.OnValidationUpdate(authzFromVA)

	// Verify that the Authz in the DB is the same except for Status->StatusValid
	authzFromVA.Status = core.StatusValid
	dbAuthz, err := sa.GetAuthorization(authzFromVA.ID)
	test.AssertNotError(t, err, "Could not fetch authorization from database")
	t.Log("authz from VA: ", authzFromVA)
	t.Log("authz from DB: ", dbAuthz)

	assertAuthzEqual(t, authzFromVA, dbAuthz)
}
func TestUpdateAuthorization(t *testing.T) {
	_, va, sa, ra := initAuthorities(t)
	AuthzInitial.ID, _ = sa.NewPendingAuthorization()
	sa.UpdatePendingAuthorization(AuthzInitial)

	authz, err := ra.UpdateAuthorization(AuthzInitial, ResponseIndex, Response)
	test.AssertNotError(t, err, "UpdateAuthorization failed")

	// Verify that returned authz same as DB
	dbAuthz, err := sa.GetAuthorization(authz.ID)
	test.AssertNotError(t, err, "Could not fetch authorization from database")
	assertAuthzEqual(t, authz, dbAuthz)

	// Verify that the VA got the authz, and it's the same as the others
	test.Assert(t, va.Called, "Authorization was not passed to the VA")
	assertAuthzEqual(t, authz, va.Argument)

	// Verify that the responses are reflected
	test.Assert(t, len(va.Argument.Challenges) > 0, "Authz passed to VA has no challenges")
	simpleHttps := va.Argument.Challenges[0]
	test.Assert(t, simpleHttps.Path == Response.Path, "simpleHttps changed")

	// If we get to here, we'll use this authorization for the next test
	AuthzUpdated = authz

	// TODO Test failure cases
	t.Log("DONE TestUpdateAuthorization")
}
func TestOnValidationUpdate(t *testing.T) {
	_, _, sa, ra := initAuthorities(t)
	AuthzUpdated.ID, _ = sa.NewPendingAuthorization()
	sa.UpdatePendingAuthorization(AuthzUpdated)

	// Simulate a successful simpleHTTPS challenge
	AuthzFromVA = AuthzUpdated
	AuthzFromVA.Challenges[0].Status = core.StatusValid

	ra.OnValidationUpdate(AuthzFromVA)

	// Verify that the Authz in the DB is the same except for Status->StatusValid
	AuthzFromVA.Status = core.StatusValid
	dbAuthz, err := sa.GetAuthorization(AuthzFromVA.ID)
	test.AssertNotError(t, err, "Could not fetch authorization from database")
	assertAuthzEqual(t, AuthzFromVA, dbAuthz)
	t.Log(" ~~> from VA: ", AuthzFromVA.Status)
	t.Log(" ~~> from DB: ", dbAuthz.Status)

	// If we get to here, we'll use this authorization for the next test
	AuthzFinal = dbAuthz

	// TODO Test failure cases
	t.Log("DONE TestOnValidationUpdate")
}
func TestNewCertificate(t *testing.T) {
	_, sa, ra, _, cleanUp := initAuthorities(t)
	defer cleanUp()
	AuthzFinal.RegistrationID = Registration.ID
	AuthzFinal, _ = sa.NewPendingAuthorization(AuthzFinal)
	sa.UpdatePendingAuthorization(AuthzFinal)
	sa.FinalizeAuthorization(AuthzFinal)

	// Inject another final authorization to cover www.example.com
	authzFinalWWW := AuthzFinal
	authzFinalWWW.Identifier.Value = "www.not-example.com"
	authzFinalWWW, _ = sa.NewPendingAuthorization(authzFinalWWW)
	sa.FinalizeAuthorization(authzFinalWWW)

	// Check that we fail if the CSR signature is invalid
	ExampleCSR.Signature[0] += 1
	certRequest := core.CertificateRequest{
		CSR: ExampleCSR,
	}

	_, err := ra.NewCertificate(certRequest, Registration.ID)
	ExampleCSR.Signature[0] -= 1
	test.AssertError(t, err, "Failed to check CSR signature")

	// Check that we don't fail on case mismatches
	ExampleCSR.Subject.CommonName = "www.NOT-example.com"
	certRequest = core.CertificateRequest{
		CSR: ExampleCSR,
	}

	cert, err := ra.NewCertificate(certRequest, Registration.ID)
	test.AssertNotError(t, err, "Failed to issue certificate")
	if err != nil {
		return
	}

	parsedCert, err := x509.ParseCertificate(cert.DER)
	test.AssertNotError(t, err, "Failed to parse certificate")
	if err != nil {
		return
	}

	// Verify that cert shows up and is as expected
	dbCert, err := sa.GetCertificate(core.SerialToString(parsedCert.SerialNumber))
	test.AssertNotError(t, err, fmt.Sprintf("Could not fetch certificate %032x from database",
		parsedCert.SerialNumber))
	if err != nil {
		return
	}
	test.Assert(t, bytes.Compare(cert.DER, dbCert.DER) == 0, "Certificates differ")

	t.Log("DONE TestOnValidationUpdate")
}
func TestOnValidationUpdateFailure(t *testing.T) {
	_, sa, ra, _, cleanUp := initAuthorities(t)
	defer cleanUp()
	authzFromVA, _ := sa.NewPendingAuthorization(AuthzUpdated)
	sa.UpdatePendingAuthorization(AuthzUpdated)
	authzFromVA.Challenges[0].Status = core.StatusInvalid

	err := ra.OnValidationUpdate(authzFromVA)
	test.AssertNotError(t, err, "unable to update validation")

	authzFromVA.Status = core.StatusInvalid
	dbAuthz, err := sa.GetAuthorization(authzFromVA.ID)
	test.AssertNotError(t, err, "Could not fetch authorization from database")
	assertAuthzEqual(t, authzFromVA, dbAuthz)
}
func TestOnValidationUpdateFailure(t *testing.T) {
	_, sa, ra, fclk, cleanUp := initAuthorities(t)
	defer cleanUp()
	authzFromVA, _ := sa.NewPendingAuthorization(AuthzInitial)
	expires := fclk.Now().Add(300 * 24 * time.Hour)
	authzFromVA.Expires = &expires
	sa.UpdatePendingAuthorization(authzFromVA)
	authzFromVA.Challenges[0].Status = core.StatusInvalid

	err := ra.OnValidationUpdate(authzFromVA)
	test.AssertNotError(t, err, "unable to update validation")

	authzFromVA.Status = core.StatusInvalid
	dbAuthz, err := sa.GetAuthorization(authzFromVA.ID)
	test.AssertNotError(t, err, "Could not fetch authorization from database")
	assertAuthzEqual(t, authzFromVA, dbAuthz)
}
func TestNewCertificate(t *testing.T) {
	_, _, sa, ra := initAuthorities(t)
	AuthzFinal.RegistrationID = 1
	AuthzFinal, _ = sa.NewPendingAuthorization(AuthzFinal)
	sa.UpdatePendingAuthorization(AuthzFinal)
	sa.FinalizeAuthorization(AuthzFinal)

	// Inject another final authorization to cover www.example.com
	authzFinalWWW := AuthzFinal
	authzFinalWWW.Identifier.Value = "www.not-example.com"
	authzFinalWWW, _ = sa.NewPendingAuthorization(authzFinalWWW)
	sa.FinalizeAuthorization(authzFinalWWW)

	// Construct a cert request referencing the two authorizations
	url1, _ := url.Parse("http://doesnt.matter/" + AuthzFinal.ID)
	url2, _ := url.Parse("http://doesnt.matter/" + authzFinalWWW.ID)

	certRequest := core.CertificateRequest{
		CSR:            ExampleCSR,
		Authorizations: []core.AcmeURL{core.AcmeURL(*url1), core.AcmeURL(*url2)},
	}

	cert, err := ra.NewCertificate(certRequest, 1)
	test.AssertNotError(t, err, "Failed to issue certificate")
	if err != nil {
		return
	}

	parsedCert, err := x509.ParseCertificate(cert.DER)
	test.AssertNotError(t, err, "Failed to parse certificate")
	if err != nil {
		return
	}

	// Verify that cert shows up and is as expected
	dbCert, err := sa.GetCertificate(core.SerialToString(parsedCert.SerialNumber))
	test.AssertNotError(t, err, fmt.Sprintf("Could not fetch certificate %032x from database",
		parsedCert.SerialNumber))
	if err != nil {
		return
	}
	test.Assert(t, bytes.Compare(cert.DER, dbCert.DER) == 0, "Certificates differ")

	t.Log("DONE TestOnValidationUpdate")
}
func TestAuthorizationRequired(t *testing.T) {
	_, _, sa, ra, cleanUp := initAuthorities(t)
	defer cleanUp()
	AuthzFinal.RegistrationID = 1
	AuthzFinal, _ = sa.NewPendingAuthorization(AuthzFinal)
	sa.UpdatePendingAuthorization(AuthzFinal)
	sa.FinalizeAuthorization(AuthzFinal)

	// ExampleCSR requests not-example.com and www.not-example.com,
	// but the authorization only covers not-example.com
	certRequest := core.CertificateRequest{
		CSR: ExampleCSR,
	}

	_, err := ra.NewCertificate(certRequest, 1)
	test.Assert(t, err != nil, "Issued certificate with insufficient authorization")

	t.Log("DONE TestAuthorizationRequired")
}
func TestNewCertificate(t *testing.T) {
	_, _, sa, ra, cleanUp := initAuthorities(t)
	defer cleanUp()
	AuthzFinal.RegistrationID = 1
	AuthzFinal, _ = sa.NewPendingAuthorization(AuthzFinal)
	sa.UpdatePendingAuthorization(AuthzFinal)
	sa.FinalizeAuthorization(AuthzFinal)

	// Inject another final authorization to cover www.example.com
	authzFinalWWW := AuthzFinal
	authzFinalWWW.Identifier.Value = "www.not-example.com"
	authzFinalWWW, _ = sa.NewPendingAuthorization(authzFinalWWW)
	sa.FinalizeAuthorization(authzFinalWWW)

	certRequest := core.CertificateRequest{
		CSR: ExampleCSR,
	}

	cert, err := ra.NewCertificate(certRequest, 1)
	test.AssertNotError(t, err, "Failed to issue certificate")
	if err != nil {
		return
	}

	parsedCert, err := x509.ParseCertificate(cert.DER)
	test.AssertNotError(t, err, "Failed to parse certificate")
	if err != nil {
		return
	}

	// Verify that cert shows up and is as expected
	dbCert, err := sa.GetCertificate(core.SerialToString(parsedCert.SerialNumber))
	test.AssertNotError(t, err, fmt.Sprintf("Could not fetch certificate %032x from database",
		parsedCert.SerialNumber))
	if err != nil {
		return
	}
	test.Assert(t, bytes.Compare(cert.DER, dbCert.DER) == 0, "Certificates differ")

	t.Log("DONE TestOnValidationUpdate")
}
func TestOnValidationUpdate(t *testing.T) {
	_, _, sa, ra := initAuthorities(t)
	AuthzUpdated, _ = sa.NewPendingAuthorization(AuthzUpdated)
	sa.UpdatePendingAuthorization(AuthzUpdated)

	// Simulate a successful simpleHTTP challenge
	authzFromVA := AuthzUpdated
	authzFromVA.Challenges[0].Status = core.StatusValid

	ra.OnValidationUpdate(authzFromVA)

	// Verify that the Authz in the DB is the same except for Status->StatusValid
	authzFromVA.Status = core.StatusValid
	dbAuthz, err := sa.GetAuthorization(authzFromVA.ID)
	test.AssertNotError(t, err, "Could not fetch authorization from database")
	assertAuthzEqual(t, authzFromVA, dbAuthz)
	t.Log(" ~~> from VA: ", authzFromVA.Status)
	t.Log(" ~~> from DB: ", dbAuthz.Status)

	t.Log("DONE TestOnValidationUpdate")
}
func TestAuthorizationRequired(t *testing.T) {
	_, _, sa, ra := initAuthorities(t)
	AuthzFinal.RegistrationID = 1
	AuthzFinal, _ = sa.NewPendingAuthorization(AuthzFinal)
	sa.UpdatePendingAuthorization(AuthzFinal)
	sa.FinalizeAuthorization(AuthzFinal)

	// Construct a cert request referencing the authorization
	url1, _ := url.Parse("http://doesnt.matter/" + AuthzFinal.ID)

	// ExampleCSR requests not-example.com and www.not-example.com,
	// but the authorization only covers not-example.com
	certRequest := core.CertificateRequest{
		CSR:            ExampleCSR,
		Authorizations: []core.AcmeURL{core.AcmeURL(*url1)},
	}

	_, err := ra.NewCertificate(certRequest, 1)
	test.Assert(t, err != nil, "Issued certificate with insufficient authorization")

	t.Log("DONE TestAuthorizationRequired")
}
func TestUpdateAuthorization(t *testing.T) {
	_, va, sa, ra, cleanUp := initAuthorities(t)
	defer cleanUp()
	AuthzInitial, _ = sa.NewPendingAuthorization(AuthzInitial)
	sa.UpdatePendingAuthorization(AuthzInitial)

	authz, err := ra.UpdateAuthorization(AuthzInitial, ResponseIndex, Response)
	test.AssertNotError(t, err, "UpdateAuthorization failed")

	// Verify that returned authz same as DB
	dbAuthz, err := sa.GetAuthorization(authz.ID)
	test.AssertNotError(t, err, "Could not fetch authorization from database")
	assertAuthzEqual(t, authz, dbAuthz)

	// Verify that the VA got the authz, and it's the same as the others
	test.Assert(t, va.Called, "Authorization was not passed to the VA")
	assertAuthzEqual(t, authz, va.Argument)

	// Verify that the responses are reflected
	test.Assert(t, len(va.Argument.Challenges) > 0, "Authz passed to VA has no challenges")

	t.Log("DONE TestUpdateAuthorization")
}