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))
	}
}
Example #3
0
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)
}
Example #4
0
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")
}
Example #5
0
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")
}
Example #6
0
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")
}