func TestAddAuthorization(t *testing.T) { sa, _, cleanUp := initSA(t) defer cleanUp() reg := satest.CreateWorkingRegistration(t, sa) PA := core.Authorization{RegistrationID: reg.ID} PA, err := sa.NewPendingAuthorization(PA) test.AssertNotError(t, err, "Couldn't create new pending authorization") test.Assert(t, PA.ID != "", "ID shouldn't be blank") dbPa, err := sa.GetAuthorization(PA.ID) test.AssertNotError(t, err, "Couldn't get pending authorization with ID "+PA.ID) test.AssertMarshaledEquals(t, PA, dbPa) expectedPa := core.Authorization{ID: PA.ID} test.AssertMarshaledEquals(t, dbPa.ID, expectedPa.ID) combos := make([][]int, 1) combos[0] = []int{0, 1} exp := time.Now().AddDate(0, 0, 1) identifier := core.AcmeIdentifier{Type: core.IdentifierDNS, Value: "wut.com"} newPa := core.Authorization{ID: PA.ID, Identifier: identifier, RegistrationID: reg.ID, Status: core.StatusPending, Expires: &exp, Combinations: combos} err = sa.UpdatePendingAuthorization(newPa) test.AssertNotError(t, err, "Couldn't update pending authorization with ID "+PA.ID) newPa.Status = core.StatusValid err = sa.FinalizeAuthorization(newPa) test.AssertNotError(t, err, "Couldn't finalize pending authorization with ID "+PA.ID) dbPa, err = sa.GetAuthorization(PA.ID) test.AssertNotError(t, err, "Couldn't get authorization with ID "+PA.ID) }
// OnValidationUpdate is called when a given Authorization is updated by the VA. func (ra *RegistrationAuthorityImpl) OnValidationUpdate(authz core.Authorization) error { // Consider validation successful if any of the combinations // specified in the authorization has been fulfilled validated := map[int]bool{} for i, ch := range authz.Challenges { if ch.Status == core.StatusValid { validated[i] = true } } for _, combo := range authz.Combinations { comboValid := true for _, i := range combo { if !validated[i] { comboValid = false break } } if comboValid { authz.Status = core.StatusValid } } // If no validation succeeded, then the authorization is invalid // NOTE: This only works because we only ever do one validation if authz.Status != core.StatusValid { authz.Status = core.StatusInvalid } else { // TODO: Enable configuration of expiry time exp := time.Now().Add(365 * 24 * time.Hour) authz.Expires = &exp } // Finalize the authorization (error ignored) return ra.SA.FinalizeAuthorization(authz) }
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") }
// prepAuthorizationForDisplay takes a core.Authorization and prepares it for // display to the client by clearing its ID and RegistrationID fields, and // preparing all its challenges. func (wfe *WebFrontEndImpl) prepAuthorizationForDisplay(authz *core.Authorization) { for i := range authz.Challenges { wfe.prepChallengeForDisplay(*authz, &authz.Challenges[i]) } authz.ID = "" authz.RegistrationID = 0 }
func TestCountPendingAuthorizations(t *testing.T) { sa, fc, cleanUp := initSA(t) defer cleanUp() reg := satest.CreateWorkingRegistration(t, sa) expires := fc.Now().Add(time.Hour) pendingAuthz := core.Authorization{ RegistrationID: reg.ID, Expires: &expires, } pendingAuthz, err := sa.NewPendingAuthorization(ctx, pendingAuthz) test.AssertNotError(t, err, "Couldn't create new pending authorization") count, err := sa.CountPendingAuthorizations(ctx, reg.ID) test.AssertNotError(t, err, "Couldn't count pending authorizations") test.AssertEquals(t, count, 0) pendingAuthz.Status = core.StatusPending pendingAuthz, err = sa.NewPendingAuthorization(ctx, pendingAuthz) test.AssertNotError(t, err, "Couldn't create new pending authorization") count, err = sa.CountPendingAuthorizations(ctx, reg.ID) test.AssertNotError(t, err, "Couldn't count pending authorizations") test.AssertEquals(t, count, 1) fc.Add(2 * time.Hour) count, err = sa.CountPendingAuthorizations(ctx, reg.ID) test.AssertNotError(t, err, "Couldn't count pending authorizations") test.AssertEquals(t, count, 0) }
// NewPendingAuthorization stores a new Pending Authorization func (ssa *SQLStorageAuthority) NewPendingAuthorization(ctx context.Context, authz core.Authorization) (core.Authorization, error) { var output core.Authorization tx, err := ssa.dbMap.Begin() if err != nil { return output, err } // Check that it doesn't exist already authz.ID = core.NewToken() for existingPending(tx, authz.ID) || existingFinal(tx, authz.ID) { authz.ID = core.NewToken() } // Insert a stub row in pending pendingAuthz := pendingauthzModel{Authorization: authz} err = tx.Insert(&pendingAuthz) if err != nil { err = Rollback(tx, err) return output, err } for i, c := range authz.Challenges { challModel, err := challengeToModel(&c, pendingAuthz.ID) if err != nil { err = Rollback(tx, err) return output, err } // Magic happens here: Gorp will modify challModel, setting challModel.ID // to the auto-increment primary key. This is important because we want // the challenge objects inside the Authorization we return to know their // IDs, so they can have proper URLs. // See https://godoc.org/github.com/coopernurse/gorp#DbMap.Insert err = tx.Insert(challModel) if err != nil { err = Rollback(tx, err) return output, err } challenge, err := modelToChallenge(challModel) if err != nil { err = Rollback(tx, err) return output, err } authz.Challenges[i] = challenge } err = tx.Commit() output = pendingAuthz.Authorization output.Challenges = authz.Challenges return output, err }
func TestAddAuthorization(t *testing.T) { sa := initSA(t) PA := core.Authorization{} PA, err := sa.NewPendingAuthorization(PA) test.AssertNotError(t, err, "Couldn't create new pending authorization") test.Assert(t, PA.ID != "", "ID shouldn't be blank") dbPa, err := sa.GetAuthorization(PA.ID) test.AssertNotError(t, err, "Couldn't get pending authorization with ID "+PA.ID) test.AssertMarshaledEquals(t, PA, dbPa) expectedPa := core.Authorization{ID: PA.ID} test.AssertMarshaledEquals(t, dbPa.ID, expectedPa.ID) var jwk jose.JsonWebKey err = json.Unmarshal([]byte(theKey), &jwk) if err != nil { t.Errorf("JSON unmarshal error: %+v", err) return } uu, err := url.Parse("test.com") u := core.AcmeURL(*uu) chall := core.Challenge{Type: "simpleHttp", Status: core.StatusPending, URI: u, Token: "THISWOULDNTBEAGOODTOKEN", Path: "test-me"} combos := make([][]int, 1) combos[0] = []int{0, 1} exp := time.Now().AddDate(0, 0, 1) newPa := core.Authorization{ID: PA.ID, Identifier: core.AcmeIdentifier{Type: core.IdentifierDNS, Value: "wut.com"}, RegistrationID: 0, Status: core.StatusPending, Expires: &exp, Challenges: []core.Challenge{chall}, Combinations: combos} err = sa.UpdatePendingAuthorization(newPa) test.AssertNotError(t, err, "Couldn't update pending authorization with ID "+PA.ID) newPa.Status = core.StatusValid err = sa.FinalizeAuthorization(newPa) test.AssertNotError(t, err, "Couldn't finalize pending authorization with ID "+PA.ID) dbPa, err = sa.GetAuthorization(PA.ID) test.AssertNotError(t, err, "Couldn't get authorization with ID "+PA.ID) }
// OnValidationUpdate is called when a given Authorization is updated by the VA. func (ra *RegistrationAuthorityImpl) OnValidationUpdate(authz core.Authorization) error { // Consider validation successful if any of the combinations // specified in the authorization has been fulfilled validated := map[int]bool{} for i, ch := range authz.Challenges { if ch.Status == core.StatusValid { validated[i] = true } } for _, combo := range authz.Combinations { comboValid := true for _, i := range combo { if !validated[i] { comboValid = false break } } if comboValid { authz.Status = core.StatusValid } } // If no validation succeeded, then the authorization is invalid // NOTE: This only works because we only ever do one validation if authz.Status != core.StatusValid { authz.Status = core.StatusInvalid } else { exp := ra.clk.Now().Add(ra.authorizationLifetime) authz.Expires = &exp } // Finalize the authorization err := ra.SA.FinalizeAuthorization(authz) if err != nil { return err } ra.stats.Inc("RA.FinalizedAuthorizations", 1, 1.0) return nil }
func TestAddAuthorization(t *testing.T) { sa, cleanUp := initSA(t) defer cleanUp() PA := core.Authorization{} PA, err := sa.NewPendingAuthorization(PA) test.AssertNotError(t, err, "Couldn't create new pending authorization") test.Assert(t, PA.ID != "", "ID shouldn't be blank") dbPa, err := sa.GetAuthorization(PA.ID) test.AssertNotError(t, err, "Couldn't get pending authorization with ID "+PA.ID) test.AssertMarshaledEquals(t, PA, dbPa) expectedPa := core.Authorization{ID: PA.ID} test.AssertMarshaledEquals(t, dbPa.ID, expectedPa.ID) var jwk jose.JsonWebKey err = json.Unmarshal([]byte(theKey), &jwk) if err != nil { t.Errorf("JSON unmarshal error: %+v", err) return } combos := make([][]int, 1) combos[0] = []int{0, 1} exp := time.Now().AddDate(0, 0, 1) identifier := core.AcmeIdentifier{Type: core.IdentifierDNS, Value: "wut.com"} newPa := core.Authorization{ID: PA.ID, Identifier: identifier, RegistrationID: 0, Status: core.StatusPending, Expires: &exp, Combinations: combos} err = sa.UpdatePendingAuthorization(newPa) test.AssertNotError(t, err, "Couldn't update pending authorization with ID "+PA.ID) newPa.Status = core.StatusValid err = sa.FinalizeAuthorization(newPa) test.AssertNotError(t, err, "Couldn't finalize pending authorization with ID "+PA.ID) dbPa, err = sa.GetAuthorization(PA.ID) test.AssertNotError(t, err, "Couldn't get authorization with ID "+PA.ID) }
func (ra *RegistrationAuthorityImpl) OnValidationUpdate(authz core.Authorization) error { // Check to see whether the updated validations are sufficient // Current policy is to accept if any validation succeeded for _, val := range authz.Challenges { if val.Status == core.StatusValid { authz.Status = core.StatusValid break } } // If no validation succeeded, then the authorization is invalid // NOTE: This only works because we only ever do one validation if authz.Status != core.StatusValid { authz.Status = core.StatusInvalid } else { // TODO: Enable configuration of expiry time authz.Expires = time.Now().Add(365 * 24 * time.Hour) } // Finalize the authorization (error ignored) return ra.SA.FinalizeAuthorization(authz) }
// NewPendingAuthorization stores a new Pending Authorization func (ssa *SQLStorageAuthority) NewPendingAuthorization(authz core.Authorization) (output core.Authorization, err error) { tx, err := ssa.dbMap.Begin() if err != nil { return } // Check that it doesn't exist already authz.ID = core.NewToken() for existingPending(tx, authz.ID) || existingFinal(tx, authz.ID) { authz.ID = core.NewToken() } // Insert a stub row in pending pendingAuthz := pendingauthzModel{Authorization: authz} err = tx.Insert(&pendingAuthz) if err != nil { tx.Rollback() return } for _, c := range authz.Challenges { chall, err := challengeToModel(&c, pendingAuthz.ID) if err != nil { tx.Rollback() return core.Authorization{}, err } err = tx.Insert(chall) if err != nil { tx.Rollback() return core.Authorization{}, err } } err = tx.Commit() output = pendingAuthz.Authorization output.Challenges = authz.Challenges return }
func (wfe *WebFrontEndImpl) GetAuthorization( response http.ResponseWriter, request *http.Request, authz core.Authorization, logEvent *requestEvent) { // Blank out ID and regID authz.ID = "" authz.RegistrationID = 0 jsonReply, err := json.Marshal(authz) if err != nil { logEvent.Error = err.Error() // InternalServerError because this is a failure to decode from our DB. wfe.sendError(response, "Failed to marshal authz", err, http.StatusInternalServerError) return } response.Header().Add("Link", link(wfe.NewCert, "next")) response.Header().Set("Content-Type", "application/json") response.WriteHeader(http.StatusOK) if _, err = response.Write(jsonReply); err != nil { logEvent.Error = err.Error() wfe.log.Warning(fmt.Sprintf("Could not write response: %s", err)) } }
func (ra *MockRegistrationAuthority) NewAuthorization(authz core.Authorization, regID int64) (core.Authorization, error) { authz.RegistrationID = regID authz.ID = "bkrPh2u0JUf18-rVBZtOOWWb3GuIiliypL-hBM9Ak1Q" return authz, nil }
func (ra *MockRegistrationAuthority) NewAuthorization(authz core.Authorization, regID int64) (core.Authorization, error) { authz.RegistrationID = regID return authz, nil }