Merge pull request #680 from letsencrypt/log-revoke
Log more about revocation process
This commit is contained in:
commit
d3c8d8e409
|
|
@ -223,7 +223,7 @@ func (ca *CertificateAuthorityImpl) GenerateOCSP(xferObj core.OCSPSigningRequest
|
|||
signRequest := ocsp.SignRequest{
|
||||
Certificate: cert,
|
||||
Status: xferObj.Status,
|
||||
Reason: xferObj.Reason,
|
||||
Reason: int(xferObj.Reason),
|
||||
RevokedAt: xferObj.RevokedAt,
|
||||
}
|
||||
|
||||
|
|
@ -232,7 +232,7 @@ func (ca *CertificateAuthorityImpl) GenerateOCSP(xferObj core.OCSPSigningRequest
|
|||
}
|
||||
|
||||
// RevokeCertificate revokes the trust of the Cert referred to by the provided Serial.
|
||||
func (ca *CertificateAuthorityImpl) RevokeCertificate(serial string, reasonCode int) (err error) {
|
||||
func (ca *CertificateAuthorityImpl) RevokeCertificate(serial string, reasonCode core.RevocationCode) (err error) {
|
||||
coreCert, err := ca.SA.GetCertificate(serial)
|
||||
if err != nil {
|
||||
// AUDIT[ Revocation Requests ] 4e85d791-09c0-4ab3-a837-d3d67e945134
|
||||
|
|
@ -249,7 +249,7 @@ func (ca *CertificateAuthorityImpl) RevokeCertificate(serial string, reasonCode
|
|||
signRequest := ocsp.SignRequest{
|
||||
Certificate: cert,
|
||||
Status: string(core.OCSPStatusRevoked),
|
||||
Reason: reasonCode,
|
||||
Reason: int(reasonCode),
|
||||
RevokedAt: time.Now(),
|
||||
}
|
||||
ocspResponse, err := ca.OCSPSigner.Sign(signRequest)
|
||||
|
|
|
|||
|
|
@ -25,20 +25,6 @@ import (
|
|||
"github.com/letsencrypt/boulder/sa"
|
||||
)
|
||||
|
||||
var reasons = map[int]string{
|
||||
0: "unspecified",
|
||||
1: "keyCompromise",
|
||||
2: "cACompromise",
|
||||
3: "affiliationChanged",
|
||||
4: "superseded",
|
||||
5: "cessationOfOperation",
|
||||
6: "certificateHold",
|
||||
// 7 is unused
|
||||
8: "removeFromCRL", // needed?
|
||||
9: "privilegeWithdrawn",
|
||||
10: "aAcompromise",
|
||||
}
|
||||
|
||||
func loadConfig(c *cli.Context) (config cmd.Config, err error) {
|
||||
configFileName := c.GlobalString("config")
|
||||
configJSON, err := ioutil.ReadFile(configFileName)
|
||||
|
|
@ -90,7 +76,7 @@ func addDeniedNames(tx *gorp.Transaction, names []string) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func revokeBySerial(serial string, reasonCode int, deny bool, cac rpc.CertificateAuthorityClient, auditlogger *blog.AuditLogger, tx *gorp.Transaction) (err error) {
|
||||
func revokeBySerial(serial string, reasonCode core.RevocationCode, deny bool, cac rpc.CertificateAuthorityClient, auditlogger *blog.AuditLogger, tx *gorp.Transaction) (err error) {
|
||||
if reasonCode < 0 || reasonCode == 7 || reasonCode > 10 {
|
||||
panic(fmt.Sprintf("Invalid reason code: %d", reasonCode))
|
||||
}
|
||||
|
|
@ -122,11 +108,11 @@ func revokeBySerial(serial string, reasonCode int, deny bool, cac rpc.Certificat
|
|||
return
|
||||
}
|
||||
|
||||
auditlogger.Info(fmt.Sprintf("Revoked certificate %s with reason '%s'", serial, reasons[reasonCode]))
|
||||
auditlogger.Info(fmt.Sprintf("Revoked certificate %s with reason '%s'", serial, core.RevocationReasons[reasonCode]))
|
||||
return
|
||||
}
|
||||
|
||||
func revokeByReg(regID int64, reasonCode int, deny bool, cac rpc.CertificateAuthorityClient, auditlogger *blog.AuditLogger, tx *gorp.Transaction) (err error) {
|
||||
func revokeByReg(regID int64, reasonCode core.RevocationCode, deny bool, cac rpc.CertificateAuthorityClient, auditlogger *blog.AuditLogger, tx *gorp.Transaction) (err error) {
|
||||
var certs []core.Certificate
|
||||
_, err = tx.Select(&certs, "SELECT serial FROM certificates WHERE registrationID = :regID", map[string]interface{}{"regID": regID})
|
||||
if err != nil {
|
||||
|
|
@ -182,7 +168,7 @@ func main() {
|
|||
}
|
||||
cmd.FailOnError(err, "Couldn't begin transaction")
|
||||
|
||||
err = revokeBySerial(serial, reasonCode, deny, cac, auditlogger, tx)
|
||||
err = revokeBySerial(serial, core.RevocationCode(reasonCode), deny, cac, auditlogger, tx)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
}
|
||||
|
|
@ -218,7 +204,7 @@ func main() {
|
|||
cmd.FailOnError(err, "Couldn't fetch registration")
|
||||
}
|
||||
|
||||
err = revokeByReg(regID, reasonCode, deny, cac, auditlogger, tx)
|
||||
err = revokeByReg(regID, core.RevocationCode(reasonCode), deny, cac, auditlogger, tx)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
}
|
||||
|
|
@ -232,14 +218,14 @@ func main() {
|
|||
Name: "list-reasons",
|
||||
Usage: "List all revocation reason codes",
|
||||
Action: func(c *cli.Context) {
|
||||
var codes []int
|
||||
for k := range reasons {
|
||||
var codes core.RevocationCodes
|
||||
for k := range core.RevocationReasons {
|
||||
codes = append(codes, k)
|
||||
}
|
||||
sort.Ints(codes)
|
||||
sort.Sort(codes)
|
||||
fmt.Printf("Revocation reason codes\n-----------------------\n\n")
|
||||
for _, k := range codes {
|
||||
fmt.Printf("%d: %s\n", k, reasons[k])
|
||||
fmt.Printf("%d: %s\n", k, core.RevocationReasons[k])
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ type RegistrationAuthority interface {
|
|||
UpdateAuthorization(Authorization, int, Challenge) (Authorization, error)
|
||||
|
||||
// [WebFrontEnd]
|
||||
RevokeCertificate(x509.Certificate) error
|
||||
RevokeCertificate(x509.Certificate, RevocationCode, *int64) error
|
||||
|
||||
// [ValidationAuthority]
|
||||
OnValidationUpdate(Authorization) error
|
||||
|
|
@ -88,7 +88,7 @@ type ValidationAuthority interface {
|
|||
type CertificateAuthority interface {
|
||||
// [RegistrationAuthority]
|
||||
IssueCertificate(x509.CertificateRequest, int64, time.Time) (Certificate, error)
|
||||
RevokeCertificate(string, int) error
|
||||
RevokeCertificate(string, RevocationCode) error
|
||||
GenerateOCSP(OCSPSigningRequest) ([]byte, error)
|
||||
}
|
||||
|
||||
|
|
@ -118,7 +118,7 @@ type StorageAdder interface {
|
|||
NewPendingAuthorization(Authorization) (Authorization, error)
|
||||
UpdatePendingAuthorization(Authorization) error
|
||||
FinalizeAuthorization(Authorization) error
|
||||
MarkCertificateRevoked(serial string, ocspResponse []byte, reasonCode int) error
|
||||
MarkCertificateRevoked(serial string, ocspResponse []byte, reasonCode RevocationCode) error
|
||||
UpdateOCSP(serial string, ocspResponse []byte) error
|
||||
|
||||
AddCertificate([]byte, int64) (string, error)
|
||||
|
|
|
|||
|
|
@ -597,7 +597,7 @@ type CertificateStatus struct {
|
|||
// revokedReason: If status is 'revoked', this is the reason code for the
|
||||
// revocation. Otherwise it is zero (which happens to be the reason
|
||||
// code for 'unspecified').
|
||||
RevokedReason int `db:"revokedReason"`
|
||||
RevokedReason RevocationCode `db:"revokedReason"`
|
||||
|
||||
LastExpirationNagSent time.Time `db:"lastExpirationNagSent"`
|
||||
|
||||
|
|
@ -646,6 +646,39 @@ type DeniedCSR struct {
|
|||
type OCSPSigningRequest struct {
|
||||
CertDER []byte
|
||||
Status string
|
||||
Reason int
|
||||
Reason RevocationCode
|
||||
RevokedAt time.Time
|
||||
}
|
||||
|
||||
// RevocationCode is used to specify a certificate revocation reason
|
||||
type RevocationCode int
|
||||
|
||||
type RevocationCodes []RevocationCode
|
||||
|
||||
func (rc RevocationCodes) Len() int {
|
||||
return len(rc)
|
||||
}
|
||||
|
||||
func (rc RevocationCodes) Less(i, j int) bool {
|
||||
return rc[i] < rc[j]
|
||||
}
|
||||
|
||||
func (rc RevocationCodes) Swap(i, j int) {
|
||||
rc[i], rc[j] = rc[j], rc[i]
|
||||
}
|
||||
|
||||
// RevocationReasons provides a map from reason code to string explaining the
|
||||
// code
|
||||
var RevocationReasons = map[RevocationCode]string{
|
||||
0: "unspecified",
|
||||
1: "keyCompromise",
|
||||
2: "cACompromise",
|
||||
3: "affiliationChanged",
|
||||
4: "superseded",
|
||||
5: "cessationOfOperation",
|
||||
6: "certificateHold",
|
||||
// 7 is unused
|
||||
8: "removeFromCRL", // needed?
|
||||
9: "privilegeWithdrawn",
|
||||
10: "aAcompromise",
|
||||
}
|
||||
|
|
|
|||
|
|
@ -381,17 +381,41 @@ func (ra *RegistrationAuthorityImpl) UpdateAuthorization(base core.Authorization
|
|||
}
|
||||
|
||||
// RevokeCertificate terminates trust in the certificate provided.
|
||||
func (ra *RegistrationAuthorityImpl) RevokeCertificate(cert x509.Certificate) (err error) {
|
||||
func (ra *RegistrationAuthorityImpl) RevokeCertificate(cert x509.Certificate, revocationCode core.RevocationCode, regID *int64) (err error) {
|
||||
serialString := core.SerialToString(cert.SerialNumber)
|
||||
err = ra.CA.RevokeCertificate(serialString, 0)
|
||||
err = ra.CA.RevokeCertificate(serialString, revocationCode)
|
||||
|
||||
state := "Failure"
|
||||
defer func() {
|
||||
// AUDIT[ Revocation Requests ] 4e85d791-09c0-4ab3-a837-d3d67e945134
|
||||
// Needed:
|
||||
// Serial
|
||||
// CN
|
||||
// Revocation reason
|
||||
// Error (if there was one)
|
||||
revMsg := fmt.Sprintf(
|
||||
"Revocation - State: %s, Serial: %s, CN: %s, DNS Names: %s, Reason: %s",
|
||||
state,
|
||||
serialString,
|
||||
cert.Subject.CommonName,
|
||||
cert.DNSNames,
|
||||
core.RevocationReasons[revocationCode],
|
||||
)
|
||||
// Check regID is set, if not revocation came from the admin-revoker tool
|
||||
if regID != nil {
|
||||
revMsg = fmt.Sprintf("%s, Requested by registration ID: %d", revMsg, *regID)
|
||||
} else {
|
||||
revMsg = fmt.Sprintf("%s, Revoked using admin tool", revMsg)
|
||||
}
|
||||
ra.log.Audit(revMsg)
|
||||
}()
|
||||
|
||||
// AUDIT[ Revocation Requests ] 4e85d791-09c0-4ab3-a837-d3d67e945134
|
||||
if err != nil {
|
||||
ra.log.Audit(fmt.Sprintf("Revocation error - %s - %s", serialString, err))
|
||||
state = fmt.Sprintf("Failure -- %s", err)
|
||||
return err
|
||||
}
|
||||
state = "Success"
|
||||
|
||||
ra.log.Audit(fmt.Sprintf("Revocation - %s", serialString))
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -108,13 +108,13 @@ type addCertificateRequest struct {
|
|||
|
||||
type revokeCertificateRequest struct {
|
||||
Serial string
|
||||
ReasonCode int
|
||||
ReasonCode core.RevocationCode
|
||||
}
|
||||
|
||||
type markCertificateRevokedRequest struct {
|
||||
Serial string
|
||||
OCSPResponse []byte
|
||||
ReasonCode int
|
||||
ReasonCode core.RevocationCode
|
||||
}
|
||||
|
||||
type caaRequest struct {
|
||||
|
|
@ -272,14 +272,23 @@ func NewRegistrationAuthorityServer(rpc RPCServer, impl core.RegistrationAuthori
|
|||
})
|
||||
|
||||
rpc.Handle(MethodRevokeCertificate, func(req []byte) (response []byte, err error) {
|
||||
certs, err := x509.ParseCertificates(req)
|
||||
if err != nil || len(certs) == 0 {
|
||||
var revReq struct {
|
||||
Cert []byte
|
||||
Reason core.RevocationCode
|
||||
RegID *int64
|
||||
}
|
||||
if err = json.Unmarshal(req, &revReq); err != nil {
|
||||
// AUDIT[ Improper Messages ] 0786b6f2-91ca-4f48-9883-842a19084c64
|
||||
improperMessage(MethodRevokeCertificate, err, req)
|
||||
return
|
||||
}
|
||||
cert, err := x509.ParseCertificate(revReq.Cert)
|
||||
if err != nil {
|
||||
// AUDIT[ Error Conditions ] 9cc4d537-8534-4970-8665-4b382abe82f3
|
||||
return
|
||||
}
|
||||
|
||||
err = impl.RevokeCertificate(*certs[0])
|
||||
err = impl.RevokeCertificate(*cert, revReq.Reason, revReq.RegID)
|
||||
return
|
||||
})
|
||||
|
||||
|
|
@ -399,8 +408,20 @@ func (rac RegistrationAuthorityClient) UpdateAuthorization(authz core.Authorizat
|
|||
}
|
||||
|
||||
// RevokeCertificate sends a Revoke Certificate request
|
||||
func (rac RegistrationAuthorityClient) RevokeCertificate(cert x509.Certificate) (err error) {
|
||||
_, err = rac.rpc.DispatchSync(MethodRevokeCertificate, cert.Raw)
|
||||
func (rac RegistrationAuthorityClient) RevokeCertificate(cert x509.Certificate, reason core.RevocationCode, regID *int64) (err error) {
|
||||
var revReq struct {
|
||||
Cert []byte
|
||||
Reason core.RevocationCode
|
||||
RegID *int64
|
||||
}
|
||||
revReq.Cert = cert.Raw
|
||||
revReq.Reason = reason
|
||||
revReq.RegID = regID
|
||||
data, err := json.Marshal(revReq)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
_, err = rac.rpc.DispatchSync(MethodRevokeCertificate, data)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -613,7 +634,7 @@ func (cac CertificateAuthorityClient) IssueCertificate(csr x509.CertificateReque
|
|||
}
|
||||
|
||||
// RevokeCertificate sends a request to revoke a certificate
|
||||
func (cac CertificateAuthorityClient) RevokeCertificate(serial string, reasonCode int) (err error) {
|
||||
func (cac CertificateAuthorityClient) RevokeCertificate(serial string, reasonCode core.RevocationCode) (err error) {
|
||||
var revokeReq revokeCertificateRequest
|
||||
revokeReq.Serial = serial
|
||||
revokeReq.ReasonCode = reasonCode
|
||||
|
|
@ -1044,7 +1065,7 @@ func (cac StorageAuthorityClient) GetCertificateStatus(id string) (status core.C
|
|||
}
|
||||
|
||||
// MarkCertificateRevoked sends a request to mark a certificate as revoked
|
||||
func (cac StorageAuthorityClient) MarkCertificateRevoked(serial string, ocspResponse []byte, reasonCode int) (err error) {
|
||||
func (cac StorageAuthorityClient) MarkCertificateRevoked(serial string, ocspResponse []byte, reasonCode core.RevocationCode) (err error) {
|
||||
var mcrReq markCertificateRevokedRequest
|
||||
|
||||
mcrReq.Serial = serial
|
||||
|
|
|
|||
|
|
@ -344,7 +344,7 @@ func (ssa *SQLStorageAuthority) UpdateOCSP(serial string, ocspResponse []byte) (
|
|||
|
||||
// MarkCertificateRevoked stores the fact that a certificate is revoked, along
|
||||
// with a timestamp and a reason.
|
||||
func (ssa *SQLStorageAuthority) MarkCertificateRevoked(serial string, ocspResponse []byte, reasonCode int) (err error) {
|
||||
func (ssa *SQLStorageAuthority) MarkCertificateRevoked(serial string, ocspResponse []byte, reasonCode core.RevocationCode) (err error) {
|
||||
if _, err = ssa.GetCertificate(serial); err != nil {
|
||||
return fmt.Errorf(
|
||||
"Unable to mark certificate %s revoked: cert not found.", serial)
|
||||
|
|
|
|||
|
|
@ -892,7 +892,7 @@ func (ra *MockRegistrationAuthority) UpdateAuthorization(authz core.Authorizatio
|
|||
return authz, nil
|
||||
}
|
||||
|
||||
func (ra *MockRegistrationAuthority) RevokeCertificate(cert x509.Certificate) error {
|
||||
func (ra *MockRegistrationAuthority) RevokeCertificate(cert x509.Certificate, reason core.RevocationCode, reg *int64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -640,7 +640,8 @@ func (wfe *WebFrontEndImpl) RevokeCertificate(response http.ResponseWriter, requ
|
|||
return
|
||||
}
|
||||
|
||||
err = wfe.RA.RevokeCertificate(*parsedCertificate)
|
||||
// Use revocation code 0, meaning "unspecified"
|
||||
err = wfe.RA.RevokeCertificate(*parsedCertificate, 0, ®istration.ID)
|
||||
if err != nil {
|
||||
logEvent.Error = err.Error()
|
||||
wfe.sendError(response, "Failed to revoke certificate", err, statusCodeFromError(err))
|
||||
|
|
|
|||
|
|
@ -241,7 +241,7 @@ func (sa *MockSA) FinalizeAuthorization(authz core.Authorization) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func (sa *MockSA) MarkCertificateRevoked(serial string, ocspResponse []byte, reasonCode int) (err error) {
|
||||
func (sa *MockSA) MarkCertificateRevoked(serial string, ocspResponse []byte, reasonCode core.RevocationCode) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -289,7 +289,7 @@ func (ra *MockRegistrationAuthority) UpdateAuthorization(authz core.Authorizatio
|
|||
return authz, nil
|
||||
}
|
||||
|
||||
func (ra *MockRegistrationAuthority) RevokeCertificate(cert x509.Certificate) error {
|
||||
func (ra *MockRegistrationAuthority) RevokeCertificate(cert x509.Certificate, reason core.RevocationCode, reg *int64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -310,7 +310,7 @@ func (ca *MockCA) GenerateOCSP(xferObj core.OCSPSigningRequest) (ocsp []byte, er
|
|||
return
|
||||
}
|
||||
|
||||
func (ca *MockCA) RevokeCertificate(serial string, reasonCode int) (err error) {
|
||||
func (ca *MockCA) RevokeCertificate(serial string, reasonCode core.RevocationCode) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue