Enable administrative revocation of malformed certs (#5813)

Today, the revocation codepaths involve parsing the to-be-revoked
certificate multiple times: inside `admin-revoker` itself, inside the
RA's `AdministrativelyRevokeCertificate` method, and again in its helper
`revokeCertificate`. In addition, we use the fact that we have the full
certificate multiple times: to log various attributes of it, to compute
its `IssuerNameID`, and more. All of this will fail if we ever issue a
cert that is malformed to the point that it cannot be parsed.

Add a new argument to the `AdministrativelyRevokeCertificateRequest`
that allows the certificate to be identified by serial only, instead of
by full certificate bytes. Add support for this in the gRPC handler by
using the serial to construct a dummy in-memory Certificate object.
Support this in the `revokeCertificate` codepath by checking to see if
the passed-in cert has any underlying raw DER bytes, and if not,
triggering the new codepath that does everything via the serial.

In order to support this, unfortunately we have to add a second
in-memory map to the RA, so that it can look up issuer certs by either
name ID or old-style ID, as the IDs gleaned from the database (instead
of from the cert itself) may still be old-style. This will be removed
when the old-style Issuer IDs have aged out.

Fixes #5759
This commit is contained in:
Aaron Gable 2021-11-29 11:28:19 -08:00 committed by GitHub
parent 6184ad5365
commit 2a2629493d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 298 additions and 123 deletions

View File

@ -392,8 +392,7 @@ func GeneratePurgeURLs(cert, issuer *x509.Certificate) ([]string, error) {
if !strings.HasSuffix(ocspServer, "/") {
ocspServer += "/"
}
// Generate GET url
urls = generateOCSPCacheKeys(req, ocspServer)
urls = append(urls, generateOCSPCacheKeys(req, ocspServer)...)
}
return urls, nil
}

View File

@ -106,19 +106,30 @@ func (r *revoker) revokeCertificate(ctx context.Context, certObj core.Certificat
if reasonCode < 0 || reasonCode == 7 || reasonCode > 10 {
panic(fmt.Sprintf("Invalid reason code: %d", reasonCode))
}
cert, err := x509.ParseCertificate(certObj.DER)
if err != nil {
return err
}
u, err := user.Current()
if err != nil {
return err
}
_, err = r.rac.AdministrativelyRevokeCertificate(ctx, &rapb.AdministrativelyRevokeCertificateRequest{
Cert: cert.Raw,
Code: int64(reasonCode),
AdminName: u.Username,
})
var req *rapb.AdministrativelyRevokeCertificateRequest
if certObj.DER != nil {
cert, err := x509.ParseCertificate(certObj.DER)
if err != nil {
return err
}
req = &rapb.AdministrativelyRevokeCertificateRequest{
Cert: cert.Raw,
Code: int64(reasonCode),
AdminName: u.Username,
}
} else {
req = &rapb.AdministrativelyRevokeCertificateRequest{
Serial: certObj.Serial,
Code: int64(reasonCode),
AdminName: u.Username,
}
}
_, err = r.rac.AdministrativelyRevokeCertificate(ctx, req)
if err != nil {
return err
}
@ -199,6 +210,10 @@ func (r *revoker) revokeByReg(ctx context.Context, regID int64, reasonCode revoc
return nil
}
func (r *revoker) revokeMalformedBySerial(ctx context.Context, serial string, reasonCode revocation.Reason) error {
return r.revokeCertificate(ctx, core.Certificate{Serial: serial}, reasonCode)
}
// This abstraction is needed so that we can use sort.Sort below
type revocationCodes []revocation.Reason
@ -270,6 +285,15 @@ func main() {
err = r.revokeByReg(ctx, regID, revocation.Reason(reasonCode))
cmd.FailOnError(err, "Couldn't revoke certificate by registration")
case command == "malformed-revoke" && len(args) == 3:
// 1: serial, 2: reasonCode
serial := args[0]
reasonCode, err := strconv.Atoi(args[1])
cmd.FailOnError(err, "Reason code argument must be an integer")
err = r.revokeMalformedBySerial(ctx, serial, revocation.Reason(reasonCode))
cmd.FailOnError(err, "Couldn't revoke certificate by serial")
case command == "list-reasons":
var codes revocationCodes
for k := range revocation.ReasonToString {

View File

@ -382,6 +382,7 @@ type AdministrativelyRevokeCertificateRequest struct {
unknownFields protoimpl.UnknownFields
Cert []byte `protobuf:"bytes,1,opt,name=cert,proto3" json:"cert,omitempty"`
Serial string `protobuf:"bytes,4,opt,name=serial,proto3" json:"serial,omitempty"`
Code int64 `protobuf:"varint,2,opt,name=code,proto3" json:"code,omitempty"`
AdminName string `protobuf:"bytes,3,opt,name=adminName,proto3" json:"adminName,omitempty"`
}
@ -425,6 +426,13 @@ func (x *AdministrativelyRevokeCertificateRequest) GetCert() []byte {
return nil
}
func (x *AdministrativelyRevokeCertificateRequest) GetSerial() string {
if x != nil {
return x.Serial
}
return ""
}
func (x *AdministrativelyRevokeCertificateRequest) GetCode() int64 {
if x != nil {
return x.Code
@ -598,78 +606,80 @@ var file_ra_proto_rawDesc = []byte{
0x01, 0x28, 0x0c, 0x52, 0x04, 0x63, 0x65, 0x72, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64,
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a,
0x05, 0x72, 0x65, 0x67, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x72, 0x65,
0x67, 0x49, 0x44, 0x22, 0x70, 0x0a, 0x28, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x69, 0x73, 0x74, 0x72,
0x61, 0x74, 0x69, 0x76, 0x65, 0x6c, 0x79, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x43, 0x65, 0x72,
0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
0x12, 0x0a, 0x04, 0x63, 0x65, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x63,
0x65, 0x72, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
0x03, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x64, 0x6d, 0x69, 0x6e,
0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x64, 0x6d, 0x69,
0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x4f, 0x0a, 0x0f, 0x4e, 0x65, 0x77, 0x4f, 0x72, 0x64, 0x65,
0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x72, 0x65, 0x67, 0x69,
0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03,
0x52, 0x0e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44,
0x12, 0x14, 0x0a, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52,
0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x4b, 0x0a, 0x14, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69,
0x7a, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21,
0x0a, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e,
0x63, 0x6f, 0x72, 0x65, 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x05, 0x6f, 0x72, 0x64, 0x65,
0x72, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x73, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03,
0x63, 0x73, 0x72, 0x32, 0xb7, 0x06, 0x0a, 0x15, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x3b, 0x0a,
0x0f, 0x4e, 0x65, 0x77, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x12, 0x12, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x12, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x52, 0x65, 0x67, 0x69,
0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x00, 0x12, 0x46, 0x0a, 0x10, 0x4e, 0x65,
0x77, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1b,
0x2e, 0x72, 0x61, 0x2e, 0x4e, 0x65, 0x77, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61,
0x67, 0x49, 0x44, 0x22, 0x88, 0x01, 0x0a, 0x28, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x69, 0x73, 0x74,
0x72, 0x61, 0x74, 0x69, 0x76, 0x65, 0x6c, 0x79, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x43, 0x65,
0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x12, 0x12, 0x0a, 0x04, 0x63, 0x65, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04,
0x63, 0x65, 0x72, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x18, 0x04,
0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x12, 0x12, 0x0a, 0x04,
0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65,
0x12, 0x1c, 0x0a, 0x09, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20,
0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x4f,
0x0a, 0x0f, 0x4e, 0x65, 0x77, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x12, 0x26, 0x0a, 0x0e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x72, 0x65, 0x67, 0x69, 0x73,
0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x61, 0x6d,
0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x22,
0x4b, 0x0a, 0x14, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72,
0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x4f, 0x72,
0x64, 0x65, 0x72, 0x52, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x73,
0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x63, 0x73, 0x72, 0x32, 0xb7, 0x06, 0x0a,
0x15, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x75, 0x74,
0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x3b, 0x0a, 0x0f, 0x4e, 0x65, 0x77, 0x52, 0x65, 0x67,
0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x2e, 0x63, 0x6f, 0x72, 0x65,
0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x12, 0x2e,
0x63, 0x6f, 0x72, 0x65, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x22, 0x00, 0x12, 0x46, 0x0a, 0x10, 0x4e, 0x65, 0x77, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x2e, 0x72, 0x61, 0x2e, 0x4e, 0x65, 0x77,
0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x75, 0x74, 0x68,
0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x0e, 0x4e,
0x65, 0x77, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x19, 0x2e,
0x72, 0x61, 0x2e, 0x4e, 0x65, 0x77, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e,
0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x22, 0x00, 0x12, 0x49, 0x0a,
0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x2e, 0x72, 0x61, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52,
0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x12, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74,
0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x00, 0x12, 0x48, 0x0a, 0x11, 0x50, 0x65, 0x72, 0x66,
0x6f, 0x72, 0x6d, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x2e,
0x72, 0x61, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x63, 0x6f,
0x72, 0x65, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x22, 0x00, 0x12, 0x40, 0x0a, 0x0e, 0x4e, 0x65, 0x77, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
0x63, 0x61, 0x74, 0x65, 0x12, 0x19, 0x2e, 0x72, 0x61, 0x2e, 0x4e, 0x65, 0x77, 0x43, 0x65, 0x72,
0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x11, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
0x74, 0x65, 0x22, 0x00, 0x12, 0x49, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65,
0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x2e, 0x72, 0x61, 0x2e,
0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x63, 0x6f, 0x72, 0x65,
0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x00, 0x12,
0x48, 0x0a, 0x11, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x2e, 0x72, 0x61, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72,
0x6d, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x13, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x00, 0x12, 0x59, 0x0a, 0x18, 0x52, 0x65, 0x76,
0x6f, 0x6b, 0x65, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x57, 0x69,
0x74, 0x68, 0x52, 0x65, 0x67, 0x12, 0x23, 0x2e, 0x72, 0x61, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b,
0x65, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x57, 0x69, 0x74, 0x68,
0x52, 0x65, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f,
0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70,
0x74, 0x79, 0x22, 0x00, 0x12, 0x46, 0x0a, 0x16, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61,
0x74, 0x65, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12,
0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x48, 0x0a, 0x17,
0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x13, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x41,
0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x16, 0x2e, 0x67,
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45,
0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x6b, 0x0a, 0x21, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x69,
0x22, 0x00, 0x12, 0x59, 0x0a, 0x18, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x43, 0x65, 0x72, 0x74,
0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x57, 0x69, 0x74, 0x68, 0x52, 0x65, 0x67, 0x12, 0x23,
0x2e, 0x72, 0x61, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
0x69, 0x63, 0x61, 0x74, 0x65, 0x57, 0x69, 0x74, 0x68, 0x52, 0x65, 0x67, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x46, 0x0a,
0x16, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x52, 0x65, 0x67, 0x69, 0x73,
0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x52,
0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x16, 0x2e, 0x67, 0x6f,
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d,
0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x48, 0x0a, 0x17, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76,
0x61, 0x74, 0x65, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x12, 0x13, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a,
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12,
0x6b, 0x0a, 0x21, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x76,
0x65, 0x6c, 0x79, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
0x63, 0x61, 0x74, 0x65, 0x12, 0x2c, 0x2e, 0x72, 0x61, 0x2e, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x69,
0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x76, 0x65, 0x6c, 0x79, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65,
0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x2c, 0x2e, 0x72, 0x61,
0x2e, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x76, 0x65, 0x6c,
0x79, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74,
0x79, 0x22, 0x00, 0x12, 0x2e, 0x0a, 0x08, 0x4e, 0x65, 0x77, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12,
0x13, 0x2e, 0x72, 0x61, 0x2e, 0x4e, 0x65, 0x77, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x0b, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x4f, 0x72, 0x64, 0x65,
0x72, 0x22, 0x00, 0x12, 0x38, 0x0a, 0x0d, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x4f,
0x72, 0x64, 0x65, 0x72, 0x12, 0x18, 0x2e, 0x72, 0x61, 0x2e, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69,
0x7a, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0b,
0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x22, 0x00, 0x42, 0x29, 0x5a,
0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x65, 0x74, 0x73,
0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x2f, 0x62, 0x6f, 0x75, 0x6c, 0x64, 0x65, 0x72, 0x2f,
0x72, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x2e, 0x0a, 0x08,
0x4e, 0x65, 0x77, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x13, 0x2e, 0x72, 0x61, 0x2e, 0x4e, 0x65,
0x77, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0b, 0x2e,
0x63, 0x6f, 0x72, 0x65, 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x22, 0x00, 0x12, 0x38, 0x0a, 0x0d,
0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x18, 0x2e,
0x72, 0x61, 0x2e, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0b, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x4f,
0x72, 0x64, 0x65, 0x72, 0x22, 0x00, 0x42, 0x29, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x65, 0x74, 0x73, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74,
0x2f, 0x62, 0x6f, 0x75, 0x6c, 0x64, 0x65, 0x72, 0x2f, 0x72, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (

View File

@ -55,6 +55,7 @@ message RevokeCertificateWithRegRequest {
message AdministrativelyRevokeCertificateRequest {
bytes cert = 1;
string serial = 4;
int64 code = 2;
string adminName = 3;
}

101
ra/ra.go
View File

@ -87,8 +87,9 @@ type RegistrationAuthorityImpl struct {
reuseValidAuthz bool
orderLifetime time.Duration
issuers map[issuance.IssuerNameID]*issuance.Certificate
purger akamaipb.AkamaiPurgerClient
issuersByNameID map[issuance.IssuerNameID]*issuance.Certificate
issuersByID map[issuance.IssuerID]*issuance.Certificate
purger akamaipb.AkamaiPurgerClient
ctpolicy *ctpolicy.CTPolicy
@ -186,9 +187,11 @@ func NewRegistrationAuthorityImpl(
}, []string{"reason"})
stats.MustRegister(revocationReasonCounter)
issuersByID := make(map[issuance.IssuerNameID]*issuance.Certificate)
issuersByNameID := make(map[issuance.IssuerNameID]*issuance.Certificate)
issuersByID := make(map[issuance.IssuerID]*issuance.Certificate)
for _, issuer := range issuers {
issuersByID[issuer.NameID()] = issuer
issuersByNameID[issuer.NameID()] = issuer
issuersByID[issuer.ID()] = issuer
}
ra := &RegistrationAuthorityImpl{
@ -207,7 +210,8 @@ func NewRegistrationAuthorityImpl(
ctpolicy: ctp,
ctpolicyResults: ctpolicyResults,
purger: purger,
issuers: issuersByID,
issuersByNameID: issuersByNameID,
issuersByID: issuersByID,
namesPerCert: namesPerCert,
rateLimitCounter: rateLimitCounter,
newRegCounter: newRegCounter,
@ -1865,20 +1869,49 @@ func revokeEvent(state, serial, cn string, names []string, revocationCode revoca
// revokeCertificate generates a revoked OCSP response for the given certificate, stores
// the revocation information, and purges OCSP request URLs from Akamai.
func (ra *RegistrationAuthorityImpl) revokeCertificate(ctx context.Context, cert x509.Certificate, code revocation.Reason, revokedBy int64, source string, comment string) error {
issuer, ok := ra.issuers[issuance.GetIssuerNameID(&cert)]
if !ok {
return fmt.Errorf("unable to identify issuer of certificate to revoke: %v", cert)
}
func (ra *RegistrationAuthorityImpl) revokeCertificate(ctx context.Context, cert *x509.Certificate, reason revocation.Reason, revokedBy int64, source string, comment string) error {
serial := core.SerialToString(cert.SerialNumber)
reason := int32(code)
revokedAt := ra.clk.Now().UnixNano()
var issuerID int64
var issuer *issuance.Certificate
var ok bool
if cert.Raw == nil {
// We've been given a synthetic cert containing just a serial number,
// presumably because the cert we're revoking is so badly malformed that
// it is unparsable. We need to gather the relevant info using only the
// serial number.
if reason == ocsp.KeyCompromise {
return fmt.Errorf("cannot revoke for KeyCompromise without full cert")
}
status, err := ra.SA.GetCertificateStatus(ctx, &sapb.Serial{Serial: serial})
if err != nil {
return fmt.Errorf("unable to confirm that serial %q was ever issued: %w", serial, err)
}
issuerID = status.IssuerID
issuer, ok = ra.issuersByNameID[issuance.IssuerNameID(issuerID)]
if !ok {
// TODO(#5152): Remove this fallback to old-style IssuerIDs.
issuer, ok = ra.issuersByID[issuance.IssuerID(issuerID)]
if !ok {
return fmt.Errorf("unable to identify issuer of serial %q", serial)
}
}
} else {
issuerID = int64(issuance.GetIssuerNameID(cert))
issuer, ok = ra.issuersByNameID[issuance.IssuerNameID(issuerID)]
if !ok {
return fmt.Errorf("unable to identify issuer of serial %q", serial)
}
}
revokedAt := ra.clk.Now().UnixNano()
ocspResponse, err := ra.CA.GenerateOCSP(ctx, &capb.GenerateOCSPRequest{
Serial: serial,
IssuerID: int64(issuer.NameID()),
IssuerID: issuerID,
Status: string(core.OCSPStatusRevoked),
Reason: reason,
Reason: int32(reason),
RevokedAt: revokedAt,
})
if err != nil {
@ -1887,7 +1920,7 @@ func (ra *RegistrationAuthorityImpl) revokeCertificate(ctx context.Context, cert
_, err = ra.SA.RevokeCertificate(ctx, &sapb.RevokeCertificateRequest{
Serial: serial,
Reason: int64(code),
Reason: int64(reason),
Date: revokedAt,
Response: ocspResponse.Response,
})
@ -1916,7 +1949,7 @@ func (ra *RegistrationAuthorityImpl) revokeCertificate(ctx context.Context, cert
}
}
purgeURLs, err := akamai.GeneratePurgeURLs(&cert, issuer.Certificate)
purgeURLs, err := akamai.GeneratePurgeURLs(cert, issuer.Certificate)
if err != nil {
return err
}
@ -1942,7 +1975,7 @@ func (ra *RegistrationAuthorityImpl) RevokeCertificateWithReg(ctx context.Contex
serialString := core.SerialToString(cert.SerialNumber)
revocationCode := revocation.Reason(req.Code)
err = ra.revokeCertificate(ctx, *cert, revocationCode, req.RegID, "API", "")
err = ra.revokeCertificate(ctx, cert, revocationCode, req.RegID, "API", "")
state := "Failure"
defer func() {
@ -1972,17 +2005,37 @@ func (ra *RegistrationAuthorityImpl) RevokeCertificateWithReg(ctx context.Contex
// does not require the registration ID of the requester since this method is only
// called from the admin-revoker tool.
func (ra *RegistrationAuthorityImpl) AdministrativelyRevokeCertificate(ctx context.Context, req *rapb.AdministrativelyRevokeCertificateRequest) (*emptypb.Empty, error) {
if req == nil || req.Cert == nil || req.AdminName == "" {
if req == nil || req.AdminName == "" {
return nil, errIncompleteGRPCRequest
}
if req.Cert == nil && req.Serial == "" {
return nil, errIncompleteGRPCRequest
}
cert, err := x509.ParseCertificate(req.Cert)
if err != nil {
return nil, err
revocationCode := revocation.Reason(req.Code)
if revocationCode == ocsp.KeyCompromise && req.Cert == nil {
return nil, fmt.Errorf("cannot revoke for KeyCompromise by serial alone")
}
revocationCode := revocation.Reason(req.Code)
serialString := core.SerialToString(cert.SerialNumber)
var cert *x509.Certificate
var serialString string
var err error
if req.Cert != nil {
cert, err = x509.ParseCertificate(req.Cert)
if err != nil {
return nil, err
}
serialString = core.SerialToString(cert.SerialNumber)
} else {
serialNum, err := core.StringToSerial(req.Serial)
if err != nil {
return nil, err
}
cert = &x509.Certificate{
SerialNumber: serialNum,
}
serialString = req.Serial
}
state := "Failure"
defer func() {
@ -1999,7 +2052,7 @@ func (ra *RegistrationAuthorityImpl) AdministrativelyRevokeCertificate(ctx conte
req.AdminName)
}()
err = ra.revokeCertificate(ctx, *cert, revocationCode, 0, "admin-revoker", fmt.Sprintf("revoked by %s", req.AdminName))
err = ra.revokeCertificate(ctx, cert, revocationCode, 0, "admin-revoker", fmt.Sprintf("revoked by %s", req.AdminName))
if err != nil {
state = fmt.Sprintf("Failure -- %s", err)
return nil, err

View File

@ -3902,17 +3902,25 @@ rA==
-----END CERTIFICATE-----
`)
type mockSABlockedKey struct {
type mockSARevocation struct {
mocks.StorageAuthority
known *corepb.CertificateStatus
added *sapb.AddBlockedKeyRequest
}
func (msabk *mockSABlockedKey) AddBlockedKey(_ context.Context, req *sapb.AddBlockedKeyRequest, _ ...grpc.CallOption) (*emptypb.Empty, error) {
msabk.added = req
func (msar *mockSARevocation) AddBlockedKey(_ context.Context, req *sapb.AddBlockedKeyRequest, _ ...grpc.CallOption) (*emptypb.Empty, error) {
msar.added = req
return &emptypb.Empty{}, nil
}
func (msar *mockSARevocation) GetCertificateStatus(_ context.Context, req *sapb.Serial, _ ...grpc.CallOption) (*corepb.CertificateStatus, error) {
if req.Serial == msar.known.Serial {
return msar.known, nil
}
return nil, fmt.Errorf("unknown certificate status")
}
type mockCAOCSP struct {
mocks.MockCA
}
@ -3927,11 +3935,11 @@ func (mp *mockPurger) Purge(context.Context, *akamaipb.PurgeRequest, ...grpc.Cal
return &emptypb.Empty{}, nil
}
func TestRevocationAddBlockedKey(t *testing.T) {
func TestRevokerCertificateWithReg(t *testing.T) {
_, _, ra, _, cleanUp := initAuthorities(t)
defer cleanUp()
mockSA := mockSABlockedKey{}
mockSA := mockSARevocation{}
ra.SA = &mockSA
ra.CA = &mockCAOCSP{}
ra.purger = &mockPurger{}
@ -3947,10 +3955,14 @@ func TestRevocationAddBlockedKey(t *testing.T) {
cert, err := x509.ParseCertificate(der)
test.AssertNotError(t, err, "x509.ParseCertificate failed")
ic := issuance.Certificate{Certificate: cert}
ra.issuers = map[issuance.IssuerNameID]*issuance.Certificate{
ra.issuersByNameID = map[issuance.IssuerNameID]*issuance.Certificate{
ic.NameID(): &ic,
}
ra.issuersByID = map[issuance.IssuerID]*issuance.Certificate{
ic.ID(): &ic,
}
// Revoking for an unspecified reason should work but not block the key.
_, err = ra.RevokeCertificateWithReg(context.Background(), &rapb.RevokeCertificateWithRegRequest{
Cert: cert.Raw,
Code: ocsp.Unspecified,
@ -3961,6 +3973,7 @@ func TestRevocationAddBlockedKey(t *testing.T) {
test.AssertMetricWithLabelsEquals(
t, ra.revocationReasonCounter, prometheus.Labels{"reason": "unspecified"}, 1)
// Revoking for key comprommise should work and block the key.
_, err = ra.RevokeCertificateWithReg(context.Background(), &rapb.RevokeCertificateWithRegRequest{
Cert: cert.Raw,
Code: ocsp.KeyCompromise,
@ -3973,8 +3986,89 @@ func TestRevocationAddBlockedKey(t *testing.T) {
test.Assert(t, mockSA.added.Comment == "", "Comment is not empty")
test.AssertMetricWithLabelsEquals(
t, ra.revocationReasonCounter, prometheus.Labels{"reason": "keyCompromise"}, 1)
}
mockSA.added = nil
func TestAdministrativelyRevokeCertificate(t *testing.T) {
_, _, ra, _, cleanUp := initAuthorities(t)
defer cleanUp()
mockSA := mockSARevocation{}
ra.SA = &mockSA
ra.CA = &mockCAOCSP{}
ra.purger = &mockPurger{}
k, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
test.AssertNotError(t, err, "ecdsa.GenerateKey failed")
digest, err := core.KeyDigest(k.Public())
test.AssertNotError(t, err, "core.KeyDigest failed")
template := x509.Certificate{SerialNumber: big.NewInt(257)}
der, err := x509.CreateCertificate(rand.Reader, &template, &template, k.Public(), k)
test.AssertNotError(t, err, "x509.CreateCertificate failed")
cert, err := x509.ParseCertificate(der)
test.AssertNotError(t, err, "x509.ParseCertificate failed")
ic := issuance.Certificate{Certificate: cert}
ra.issuersByNameID = map[issuance.IssuerNameID]*issuance.Certificate{
ic.NameID(): &ic,
}
ra.issuersByID = map[issuance.IssuerID]*issuance.Certificate{
ic.ID(): &ic,
}
mockSA.known = &corepb.CertificateStatus{
Serial: core.SerialToString(cert.SerialNumber),
IssuerID: int64(ic.NameID()),
}
// Revoking with an empty request should fail immediately.
_, err = ra.AdministrativelyRevokeCertificate(context.Background(), &rapb.AdministrativelyRevokeCertificateRequest{})
test.AssertError(t, err, "AdministrativelyRevokeCertificate should have failed for nil request object")
// Revoking with neither a cert nor a serial should fail immediately.
_, err = ra.AdministrativelyRevokeCertificate(context.Background(), &rapb.AdministrativelyRevokeCertificateRequest{
Code: ocsp.Unspecified,
AdminName: "root",
})
test.AssertError(t, err, "AdministrativelyRevokeCertificate should have failed with no cert or serial")
// Revoking with a nil cert and no serial should fail immediately.
_, err = ra.AdministrativelyRevokeCertificate(context.Background(), &rapb.AdministrativelyRevokeCertificateRequest{
Cert: []byte{},
Code: ocsp.KeyCompromise,
AdminName: "",
})
test.AssertError(t, err, "AdministrativelyRevokeCertificate should have failed for nil `Cert`")
// Revoking without an admin name should fail immediately.
_, err = ra.AdministrativelyRevokeCertificate(context.Background(), &rapb.AdministrativelyRevokeCertificateRequest{
Cert: cert.Raw,
Code: ocsp.KeyCompromise,
AdminName: "",
})
test.AssertError(t, err, "AdministrativelyRevokeCertificate should have failed with empty string for `AdminName`")
// Revoking a cert for an unspecified reason should work but not block the key.
_, err = ra.AdministrativelyRevokeCertificate(context.Background(), &rapb.AdministrativelyRevokeCertificateRequest{
Cert: cert.Raw,
Code: ocsp.Unspecified,
AdminName: "root",
})
test.AssertNotError(t, err, "AdministrativelyRevokeCertificate failed")
test.Assert(t, mockSA.added == nil, "blocked key was added when reason was not keyCompromise")
test.AssertMetricWithLabelsEquals(
t, ra.revocationReasonCounter, prometheus.Labels{"reason": "unspecified"}, 1)
// Revoking a serial for an unspecified reason should work but not block the key.
_, err = ra.AdministrativelyRevokeCertificate(context.Background(), &rapb.AdministrativelyRevokeCertificateRequest{
Serial: core.SerialToString(cert.SerialNumber),
Code: ocsp.Unspecified,
AdminName: "root",
})
test.AssertNotError(t, err, "AdministrativelyRevokeCertificate failed")
test.Assert(t, mockSA.added == nil, "blocked key was added when reason was not keyCompromise")
test.AssertMetricWithLabelsEquals(
t, ra.revocationReasonCounter, prometheus.Labels{"reason": "unspecified"}, 2)
// Revoking a cert for key compromise should work and block the key.
_, err = ra.AdministrativelyRevokeCertificate(context.Background(), &rapb.AdministrativelyRevokeCertificateRequest{
Cert: cert.Raw,
Code: ocsp.KeyCompromise,
@ -3987,19 +4081,13 @@ func TestRevocationAddBlockedKey(t *testing.T) {
test.Assert(t, mockSA.added.Comment != "", "Comment is nil")
test.AssertEquals(t, mockSA.added.Comment, "revoked by root")
test.AssertMetricWithLabelsEquals(
t, ra.revocationReasonCounter, prometheus.Labels{"reason": "keyCompromise"}, 2)
t, ra.revocationReasonCounter, prometheus.Labels{"reason": "keyCompromise"}, 1)
// Revoking a serial for key compromise should fail because we don't have the pubkey to block.
_, err = ra.AdministrativelyRevokeCertificate(context.Background(), &rapb.AdministrativelyRevokeCertificateRequest{
Cert: cert.Raw,
Serial: core.SerialToString(cert.SerialNumber),
Code: ocsp.KeyCompromise,
AdminName: "",
AdminName: "root",
})
test.AssertError(t, err, "AdministrativelyRevokeCertificate should have failed with empty string for `AdminName`")
_, err = ra.AdministrativelyRevokeCertificate(context.Background(), &rapb.AdministrativelyRevokeCertificateRequest{})
test.AssertError(t, err, "AdministrativelyRevokeCertificate should have failed for nil request object")
_, err = ra.AdministrativelyRevokeCertificate(context.Background(), &rapb.AdministrativelyRevokeCertificateRequest{
Cert: []byte{},
Code: ocsp.KeyCompromise,
AdminName: "",
})
test.AssertError(t, err, "AdministrativelyRevokeCertificate should have failed for nil `Cert`")
test.AssertError(t, err, "AdministrativelyRevokeCertificate should have failed with just serial for keyCompromise")
}