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 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 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 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 TestReuseExpiringAuthorization(t *testing.T) { _, sa, ra, _, cleanUp := initAuthorities(t) defer cleanUp() // Turn on AuthZ Reuse ra.reuseValidAuthz = true // Create one finalized authorization that expires in 12 hours from now expiringAuth := AuthzInitial expiringAuth.Status = "valid" exp := ra.clk.Now().Add(12 * time.Hour) expiringAuth.Expires = &exp expiringAuth.Challenges[0].Status = "valid" expiringAuth.RegistrationID = Registration.ID expiringAuth, err := sa.NewPendingAuthorization(ctx, expiringAuth) test.AssertNotError(t, err, "Could not store test pending authorization") err = sa.FinalizeAuthorization(ctx, expiringAuth) test.AssertNotError(t, err, "Could not finalize test pending authorization") // Now create another authorization for the same Reg.ID/domain secondAuthz, err := ra.NewAuthorization(ctx, AuthzRequest, Registration.ID) test.AssertNotError(t, err, "NewAuthorization for secondAuthz failed") // The second authz should not have the same ID as the previous AuthZ, // because the existing valid authorization expires within 1 day from now test.AssertNotEquals(t, expiringAuth.ID, secondAuthz.ID) // The second authz shouldn't be valid, but pending since it is a brand new // authz, not a reused one test.AssertEquals(t, secondAuthz.Status, core.StatusPending) }
func TestReuseAuthorizationDisabled(t *testing.T) { _, sa, ra, _, cleanUp := initAuthorities(t) defer cleanUp() // Turn *off* AuthZ Reuse ra.reuseValidAuthz = false // Create one finalized authorization finalAuthz := AuthzInitial finalAuthz.Status = "valid" exp := ra.clk.Now().Add(365 * 24 * time.Hour) finalAuthz.Expires = &exp finalAuthz.Challenges[0].Status = "valid" finalAuthz.RegistrationID = Registration.ID finalAuthz, err := sa.NewPendingAuthorization(ctx, finalAuthz) test.AssertNotError(t, err, "Could not store test pending authorization") err = sa.FinalizeAuthorization(ctx, finalAuthz) test.AssertNotError(t, err, "Could not finalize test pending authorization") // Now create another authorization for the same Reg.ID/domain secondAuthz, err := ra.NewAuthorization(ctx, AuthzRequest, Registration.ID) test.AssertNotError(t, err, "NewAuthorization for secondAuthz failed") // The second authz should not have the same ID as the previous AuthZ, // because we have set `reuseValidAuthZ` to false. It should be a fresh // & unique authz test.AssertNotEquals(t, finalAuthz.ID, secondAuthz.ID) // The second authz shouldn't be valid, but pending since it is a brand new // authz, not a reused one test.AssertEquals(t, secondAuthz.Status, core.StatusPending) }
func TestReuseAuthorization(t *testing.T) { _, sa, ra, _, cleanUp := initAuthorities(t) defer cleanUp() // Turn on AuthZ Reuse ra.reuseValidAuthz = true // Create one finalized authorization finalAuthz := AuthzInitial finalAuthz.Status = "valid" exp := ra.clk.Now().Add(365 * 24 * time.Hour) finalAuthz.Expires = &exp finalAuthz.Challenges[0].Status = "valid" finalAuthz.RegistrationID = Registration.ID finalAuthz, err := sa.NewPendingAuthorization(ctx, finalAuthz) test.AssertNotError(t, err, "Could not store test pending authorization") err = sa.FinalizeAuthorization(ctx, finalAuthz) test.AssertNotError(t, err, "Could not finalize test pending authorization") // Now create another authorization for the same Reg.ID/domain secondAuthz, err := ra.NewAuthorization(ctx, AuthzRequest, Registration.ID) test.AssertNotError(t, err, "NewAuthorization for secondAuthz failed") // The first authz should be reused as the second and thus have the same ID test.AssertEquals(t, finalAuthz.ID, secondAuthz.ID) // The second authz shouldn't be pending, it should be valid (that's why it // was reused) test.AssertEquals(t, secondAuthz.Status, core.StatusValid) // It should have one http challenge already marked valid httpIndex := ResponseIndex httpChallenge := secondAuthz.Challenges[httpIndex] test.AssertEquals(t, httpChallenge.Type, core.ChallengeTypeHTTP01) test.AssertEquals(t, httpChallenge.Status, core.StatusValid) // It should have one SNI challenge that is pending sniIndex := httpIndex + 1 sniChallenge := secondAuthz.Challenges[sniIndex] test.AssertEquals(t, sniChallenge.Type, core.ChallengeTypeTLSSNI01) test.AssertEquals(t, sniChallenge.Status, core.StatusPending) // Sending an update to this authz for an already valid challenge should do // nothing (but produce no error), since it is already a valid authz response, err := makeResponse(httpChallenge) test.AssertNotError(t, err, "Unable to construct response to secondAuthz http challenge") secondAuthz, err = ra.UpdateAuthorization(ctx, secondAuthz, httpIndex, response) test.AssertNotError(t, err, "UpdateAuthorization on secondAuthz http failed") test.AssertEquals(t, finalAuthz.ID, secondAuthz.ID) test.AssertEquals(t, secondAuthz.Status, core.StatusValid) // Similarly, sending an update to this authz for a pending challenge should do // nothing (but produce no error), since the overall authz is already valid response, err = makeResponse(sniChallenge) test.AssertNotError(t, err, "Unable to construct response to secondAuthz sni challenge") secondAuthz, err = ra.UpdateAuthorization(ctx, secondAuthz, sniIndex, response) test.AssertNotError(t, err, "UpdateAuthorization on secondAuthz sni failed") test.AssertEquals(t, finalAuthz.ID, secondAuthz.ID) test.AssertEquals(t, secondAuthz.Status, core.StatusValid) }
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 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 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 TestTotalCertRateLimit(t *testing.T) { _, sa, ra, fc, cleanUp := initAuthorities(t) defer cleanUp() ra.rlPolicies = &dummyRateLimitConfig{ TotalCertificatesPolicy: ratelimit.RateLimitPolicy{ Threshold: 1, Window: cmd.ConfigDuration{Duration: 24 * 90 * time.Hour}, }, } fc.Add(24 * 90 * time.Hour) AuthzFinal.RegistrationID = Registration.ID AuthzFinal, err := sa.NewPendingAuthorization(ctx, AuthzFinal) test.AssertNotError(t, err, "Could not store test data") err = sa.FinalizeAuthorization(ctx, AuthzFinal) // Inject another final authorization to cover www.not-example.com authzFinalWWW := AuthzFinal authzFinalWWW.Identifier.Value = "www.not-example.com" authzFinalWWW, err = sa.NewPendingAuthorization(ctx, authzFinalWWW) test.AssertNotError(t, err, "Could not store test data") err = sa.FinalizeAuthorization(ctx, authzFinalWWW) test.AssertNotError(t, err, "Could not store test data") ExampleCSR.Subject.CommonName = "www.NOT-example.com" certRequest := core.CertificateRequest{ CSR: ExampleCSR, } // TODO(jsha): Since we're using a real SA rather than a mock, we call // NewCertificate twice and insert the first result into the SA. Instead we // should mock out the SA and have it return the cert count that we want. cert, err := ra.NewCertificate(ctx, certRequest, Registration.ID) test.AssertNotError(t, err, "Failed to issue certificate") _, err = sa.AddCertificate(ctx, cert.DER, Registration.ID) test.AssertNotError(t, err, "Failed to store certificate") fc.Add(time.Hour) _, err = ra.NewCertificate(ctx, certRequest, Registration.ID) test.AssertError(t, err, "Total certificate rate limit failed") }
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 TestNewCertificate(t *testing.T) { _, sa, ra, _, cleanUp := initAuthorities(t) defer cleanUp() AuthzFinal.RegistrationID = Registration.ID AuthzFinal, err := sa.NewPendingAuthorization(ctx, AuthzFinal) test.AssertNotError(t, err, "Could not store test data") err = sa.FinalizeAuthorization(ctx, AuthzFinal) test.AssertNotError(t, err, "Could not store test data") // Inject another final authorization to cover www.not-example.com authzFinalWWW := AuthzFinal authzFinalWWW.Identifier.Value = "www.not-example.com" authzFinalWWW, err = sa.NewPendingAuthorization(ctx, authzFinalWWW) test.AssertNotError(t, err, "Could not store test data") err = sa.FinalizeAuthorization(ctx, authzFinalWWW) test.AssertNotError(t, err, "Could not store test data") // Check that we fail if the CSR signature is invalid ExampleCSR.Signature[0]++ certRequest := core.CertificateRequest{ CSR: ExampleCSR, } _, err = ra.NewCertificate(ctx, certRequest, Registration.ID) ExampleCSR.Signature[0]-- 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(ctx, certRequest, Registration.ID) test.AssertNotError(t, err, "Failed to issue certificate") _, err = x509.ParseCertificate(cert.DER) test.AssertNotError(t, err, "Failed to parse certificate") }
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 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 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") }