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:
parent
6184ad5365
commit
2a2629493d
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ message RevokeCertificateWithRegRequest {
|
|||
|
||||
message AdministrativelyRevokeCertificateRequest {
|
||||
bytes cert = 1;
|
||||
string serial = 4;
|
||||
int64 code = 2;
|
||||
string adminName = 3;
|
||||
}
|
||||
|
|
|
|||
101
ra/ra.go
101
ra/ra.go
|
|
@ -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
|
||||
|
|
|
|||
126
ra/ra_test.go
126
ra/ra_test.go
|
|
@ -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")
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue