func TestMarkCertificateRevoked(t *testing.T) { sa, fc, cleanUp := initSA(t) defer cleanUp() reg := satest.CreateWorkingRegistration(t, sa) // Add a cert to the DB to test with. certDER, err := ioutil.ReadFile("www.eff.org.der") test.AssertNotError(t, err, "Couldn't read example cert DER") _, err = sa.AddCertificate(certDER, reg.ID) test.AssertNotError(t, err, "Couldn't add www.eff.org.der") serial := "000000000000000000000000000000021bd4" const ocspResponse = "this is a fake OCSP response" certificateStatusObj, err := sa.dbMap.Get(core.CertificateStatus{}, serial) beforeStatus := certificateStatusObj.(*core.CertificateStatus) test.AssertEquals(t, beforeStatus.Status, core.OCSPStatusGood) fc.Add(1 * time.Hour) code := core.RevocationCode(1) err = sa.MarkCertificateRevoked(serial, code) test.AssertNotError(t, err, "MarkCertificateRevoked failed") certificateStatusObj, err = sa.dbMap.Get(core.CertificateStatus{}, serial) afterStatus := certificateStatusObj.(*core.CertificateStatus) test.AssertNotError(t, err, "Failed to fetch certificate status") if code != afterStatus.RevokedReason { t.Errorf("RevokedReasons, expected %v, got %v", code, afterStatus.RevokedReason) } if !fc.Now().Equal(afterStatus.RevokedDate) { t.Errorf("RevokedData, expected %s, got %s", fc.Now(), afterStatus.RevokedDate) } }
func TestMarkCertificateRevoked(t *testing.T) { sa, fc, cleanUp := initSA(t) defer cleanUp() reg := satest.CreateWorkingRegistration(t, sa) // Add a cert to the DB to test with. certDER, err := ioutil.ReadFile("www.eff.org.der") test.AssertNotError(t, err, "Couldn't read example cert DER") _, err = sa.AddCertificate(certDER, reg.ID) test.AssertNotError(t, err, "Couldn't add www.eff.org.der") serial := "000000000000000000000000000000021bd4" const ocspResponse = "this is a fake OCSP response" certificateStatusObj, err := sa.dbMap.Get(core.CertificateStatus{}, serial) beforeStatus := certificateStatusObj.(*core.CertificateStatus) test.AssertEquals(t, beforeStatus.Status, core.OCSPStatusGood) fc.Add(1 * time.Hour) code := core.RevocationCode(1) err = sa.MarkCertificateRevoked(serial, []byte(ocspResponse), code) test.AssertNotError(t, err, "MarkCertificateRevoked failed") certificateStatusObj, err = sa.dbMap.Get(core.CertificateStatus{}, serial) afterStatus := certificateStatusObj.(*core.CertificateStatus) test.AssertNotError(t, err, "Failed to fetch certificate status") if code != afterStatus.RevokedReason { t.Errorf("RevokedReasons, expected %v, got %v", code, afterStatus.RevokedReason) } if !fc.Now().Equal(afterStatus.RevokedDate) { t.Errorf("RevokedData, expected %s, got %s", fc.Now(), afterStatus.RevokedDate) } if !fc.Now().Equal(afterStatus.OCSPLastUpdated) { t.Errorf("OCSPLastUpdated, expected %s, got %s", fc.Now(), afterStatus.OCSPLastUpdated) } if !afterStatus.OCSPLastUpdated.After(beforeStatus.OCSPLastUpdated) { t.Errorf("OCSPLastUpdated did not update correctly. before: %s; after: %s", beforeStatus.OCSPLastUpdated, afterStatus.OCSPLastUpdated) } var fetched core.OCSPResponse err = sa.dbMap.SelectOne(&fetched, `SELECT * from ocspResponses where serial = ? order by createdAt DESC limit 1;`, serial) test.AssertNotError(t, err, "Failed to fetch OCSP response") if ocspResponse != string(fetched.Response) { t.Errorf("OCSPResponse response, expected %#v, got %#v", ocspResponse, string(fetched.Response)) } }
func TestFindRevokedCertificatesToUpdate(t *testing.T) { updater, sa, _, _, cleanUp := setup(t) defer cleanUp() reg := satest.CreateWorkingRegistration(t, sa) cert, err := core.LoadCert("test-cert.pem") test.AssertNotError(t, err, "Couldn't read test certificate") _, err = sa.AddCertificate(cert.Raw, reg.ID) test.AssertNotError(t, err, "Couldn't add www.eff.org.der") statuses, err := updater.findRevokedCertificatesToUpdate(10) test.AssertNotError(t, err, "Failed to find revoked certificates") test.AssertEquals(t, len(statuses), 0) err = sa.MarkCertificateRevoked(core.SerialToString(cert.SerialNumber), core.RevocationCode(1)) test.AssertNotError(t, err, "Failed to revoke certificate") statuses, err = updater.findRevokedCertificatesToUpdate(10) test.AssertNotError(t, err, "Failed to find revoked certificates") test.AssertEquals(t, len(statuses), 1) }
func TestRevokedCertificatesTick(t *testing.T) { updater, sa, _, _, cleanUp := setup(t) defer cleanUp() reg := satest.CreateWorkingRegistration(t, sa) parsedCert, err := core.LoadCert("test-cert.pem") test.AssertNotError(t, err, "Couldn't read test certificate") _, err = sa.AddCertificate(parsedCert.Raw, reg.ID) test.AssertNotError(t, err, "Couldn't add www.eff.org.der") err = sa.MarkCertificateRevoked(core.SerialToString(parsedCert.SerialNumber), core.RevocationCode(1)) test.AssertNotError(t, err, "Failed to revoke certificate") statuses, err := updater.findRevokedCertificatesToUpdate(10) test.AssertNotError(t, err, "Failed to find revoked certificates") test.AssertEquals(t, len(statuses), 1) updater.revokedCertificatesTick(10) status, err := sa.GetCertificateStatus(core.SerialToString(parsedCert.SerialNumber)) test.AssertNotError(t, err, "Failed to get certificate status") test.AssertEquals(t, status.Status, core.OCSPStatusRevoked) test.Assert(t, len(status.OCSPResponse) != 0, "Certificate status doesn't contain OCSP response") }
func main() { app := cli.NewApp() app.Name = "admin-revoker" app.Usage = "Revokes issued certificates" app.Version = cmd.Version() app.Author = "Boulder contributors" app.Email = "*****@*****.**" app.Flags = []cli.Flag{ cli.StringFlag{ Name: "config", Value: "config.json", EnvVar: "BOULDER_CONFIG", Usage: "Path to Boulder JSON configuration file", }, cli.BoolFlag{ Name: "deny", Usage: "Add certificate DNS names to the denied list", }, } app.Commands = []cli.Command{ { Name: "serial-revoke", Usage: "Revoke a single certificate by the hex serial number", Action: func(c *cli.Context) { // 1: serial, 2: reasonCode (3: deny flag) serial := c.Args().First() reasonCode, err := strconv.Atoi(c.Args().Get(1)) cmd.FailOnError(err, "Reason code argument must be a integer") deny := c.GlobalBool("deny") cac, auditlogger, dbMap, _ := setupContext(c) tx, err := dbMap.Begin() if err != nil { tx.Rollback() } cmd.FailOnError(err, "Couldn't begin transaction") err = revokeBySerial(serial, core.RevocationCode(reasonCode), deny, cac, auditlogger, tx) if err != nil { tx.Rollback() } cmd.FailOnError(err, "Couldn't revoke certificate") err = tx.Commit() cmd.FailOnError(err, "Couldn't cleanly close transaction") }, }, { Name: "reg-revoke", Usage: "Revoke all certificates associated with a registration ID", Action: func(c *cli.Context) { // 1: registration ID, 2: reasonCode (3: deny flag) regID, err := strconv.ParseInt(c.Args().First(), 10, 64) cmd.FailOnError(err, "Registration ID argument must be a integer") reasonCode, err := strconv.Atoi(c.Args().Get(1)) cmd.FailOnError(err, "Reason code argument must be a integer") deny := c.GlobalBool("deny") cac, auditlogger, dbMap, sac := setupContext(c) // AUDIT[ Error Conditions ] 9cc4d537-8534-4970-8665-4b382abe82f3 defer auditlogger.AuditPanic() tx, err := dbMap.Begin() if err != nil { tx.Rollback() } cmd.FailOnError(err, "Couldn't begin transaction") _, err = sac.GetRegistration(regID) if err != nil { cmd.FailOnError(err, "Couldn't fetch registration") } err = revokeByReg(regID, core.RevocationCode(reasonCode), deny, cac, auditlogger, tx) if err != nil { tx.Rollback() } cmd.FailOnError(err, "Couldn't revoke certificate") err = tx.Commit() cmd.FailOnError(err, "Couldn't cleanly close transaction") }, }, { Name: "list-reasons", Usage: "List all revocation reason codes", Action: func(c *cli.Context) { var codes core.RevocationCodes for k := range core.RevocationReasons { codes = append(codes, k) } sort.Sort(codes) fmt.Printf("Revocation reason codes\n-----------------------\n\n") for _, k := range codes { fmt.Printf("%d: %s\n", k, core.RevocationReasons[k]) } }, }, } err := app.Run(os.Args) cmd.FailOnError(err, "Failed to run application") }
func main() { ctx := context.Background() app := cli.NewApp() app.Name = "admin-revoker" app.Usage = "Revokes issued certificates" app.Version = cmd.Version() app.Author = "Boulder contributors" app.Email = "*****@*****.**" app.Flags = []cli.Flag{ cli.StringFlag{ Name: "config", Value: "config.json", EnvVar: "BOULDER_CONFIG", Usage: "Path to Boulder JSON configuration file", }, } app.Commands = []cli.Command{ { Name: "serial-revoke", Usage: "Revoke a single certificate by the hex serial number", Action: func(c *cli.Context) { // 1: serial, 2: reasonCode serial := c.Args().First() reasonCode, err := strconv.Atoi(c.Args().Get(1)) cmd.FailOnError(err, "Reason code argument must be an integer") cac, logger, dbMap, _, _ := setupContext(c) tx, err := dbMap.Begin() if err != nil { cmd.FailOnError(sa.Rollback(tx, err), "Couldn't begin transaction") } err = revokeBySerial(ctx, serial, core.RevocationCode(reasonCode), cac, logger, tx) if err != nil { cmd.FailOnError(sa.Rollback(tx, err), "Couldn't revoke certificate") } err = tx.Commit() cmd.FailOnError(err, "Couldn't cleanly close transaction") }, }, { Name: "reg-revoke", Usage: "Revoke all certificates associated with a registration ID", Action: func(c *cli.Context) { // 1: registration ID, 2: reasonCode regID, err := strconv.ParseInt(c.Args().First(), 10, 64) cmd.FailOnError(err, "Registration ID argument must be an integer") reasonCode, err := strconv.Atoi(c.Args().Get(1)) cmd.FailOnError(err, "Reason code argument must be an integer") cac, logger, dbMap, sac, _ := setupContext(c) // AUDIT[ Error Conditions ] 9cc4d537-8534-4970-8665-4b382abe82f3 defer logger.AuditPanic() tx, err := dbMap.Begin() if err != nil { cmd.FailOnError(sa.Rollback(tx, err), "Couldn't begin transaction") } _, err = sac.GetRegistration(ctx, regID) if err != nil { cmd.FailOnError(err, "Couldn't fetch registration") } err = revokeByReg(ctx, regID, core.RevocationCode(reasonCode), cac, logger, tx) if err != nil { cmd.FailOnError(sa.Rollback(tx, err), "Couldn't revoke certificate") } err = tx.Commit() cmd.FailOnError(err, "Couldn't cleanly close transaction") }, }, { Name: "list-reasons", Usage: "List all revocation reason codes", Action: func(c *cli.Context) { var codes revocationCodes for k := range core.RevocationReasons { codes = append(codes, k) } sort.Sort(codes) fmt.Printf("Revocation reason codes\n-----------------------\n\n") for _, k := range codes { fmt.Printf("%d: %s\n", k, core.RevocationReasons[k]) } }, }, { Name: "auth-revoke", Usage: "Revoke all pending/valid authorizations for a domain", Action: func(c *cli.Context) { domain := c.Args().First() _, logger, _, sac, stats := setupContext(c) ident := core.AcmeIdentifier{Value: domain, Type: core.IdentifierDNS} authsRevoked, pendingAuthsRevoked, err := sac.RevokeAuthorizationsByDomain(ctx, ident) cmd.FailOnError(err, fmt.Sprintf("Failed to revoke authorizations for %s", ident.Value)) logger.Info(fmt.Sprintf( "Revoked %d pending authorizations and %d final authorizations\n", authsRevoked, pendingAuthsRevoked, )) stats.Inc("admin-revoker.revokedAuthorizations", authsRevoked, 1.0) stats.Inc("admin-revoker.revokedPendingAuthorizations", pendingAuthsRevoked, 1.0) }, }, } err := app.Run(os.Args) cmd.FailOnError(err, "Failed to run application") }