RA: improve AdministrativelyRevokeCertificate (#7275)
The RA.AdministrativelyRevokeCertificate method has two primary modes of operation: if a certificate DER blob is provided, it parses and extracts information from that blob, and revokes the cert; if no DER is provided, it assumes the cert is malformed, and revokes it (but doesn't do an OCSP cache purge) based on the serial alone. However, this scheme has slightly confusing semantics in the RA and requires that the admin tooling look up the certificates to provide them to the RA. Instead, add a new "malformed" field to the RA's AdministrativelyRevokeCertificateRequest, and deprecate the "cert" field of that same request. When the malformed boolean is false, the RA will look up and parse the certificate itself. When the malformed field is true, it will revoke the cert based on serial alone. Note that the main logic of AdministrativelyRevokeCertificate -- namely revoking, potentially re-revoking, doing an akamai cache purge, etc -- is not changed by this PR. The only thing that changes here is how the RA gets access to the to-be-revoked certificate's information. Part of https://github.com/letsencrypt/boulder/issues/7135
This commit is contained in:
parent
97a19b18d2
commit
d1f8fd2921
|
|
@ -358,16 +358,17 @@ type AdministrativelyRevokeCertificateRequest struct {
|
|||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// The `cert` field may be omitted. If it is omitted,
|
||||
// the revocation reason (`code`) must not be keyCompromise,
|
||||
// and purging the Akamai cache will not happen because the
|
||||
// base URL for the certificate's OCSP server is not known.
|
||||
// Deprecated: this field is ignored.
|
||||
Cert []byte `protobuf:"bytes,1,opt,name=cert,proto3" json:"cert,omitempty"`
|
||||
// The `serial` field is required.
|
||||
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"`
|
||||
SkipBlockKey bool `protobuf:"varint,5,opt,name=skipBlockKey,proto3" json:"skipBlockKey,omitempty"`
|
||||
// If the malformed flag is set, the RA will not attempt to parse the
|
||||
// certificate in question. In this case, the keyCompromise reason cannot be
|
||||
// specified, because the key cannot be blocked.
|
||||
Malformed bool `protobuf:"varint,6,opt,name=malformed,proto3" json:"malformed,omitempty"`
|
||||
}
|
||||
|
||||
func (x *AdministrativelyRevokeCertificateRequest) Reset() {
|
||||
|
|
@ -437,6 +438,13 @@ func (x *AdministrativelyRevokeCertificateRequest) GetSkipBlockKey() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (x *AdministrativelyRevokeCertificateRequest) GetMalformed() bool {
|
||||
if x != nil {
|
||||
return x.Malformed
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type NewOrderRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
|
|
@ -591,7 +599,7 @@ var file_ra_proto_rawDesc = []byte{
|
|||
0x44, 0x22, 0x32, 0x0a, 0x16, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x43, 0x65, 0x72, 0x74, 0x42,
|
||||
0x79, 0x4b, 0x65, 0x79, 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, 0x4a,
|
||||
0x04, 0x08, 0x02, 0x10, 0x03, 0x22, 0xac, 0x01, 0x0a, 0x28, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x69,
|
||||
0x04, 0x08, 0x02, 0x10, 0x03, 0x22, 0xca, 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,
|
||||
|
|
@ -602,71 +610,73 @@ var file_ra_proto_rawDesc = []byte{
|
|||
0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x4e, 0x61, 0x6d, 0x65,
|
||||
0x12, 0x22, 0x0a, 0x0c, 0x73, 0x6b, 0x69, 0x70, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4b, 0x65, 0x79,
|
||||
0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x73, 0x6b, 0x69, 0x70, 0x42, 0x6c, 0x6f, 0x63,
|
||||
0x6b, 0x4b, 0x65, 0x79, 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, 0xad, 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, 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, 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, 0x53, 0x0a, 0x15, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x43, 0x65, 0x72, 0x74, 0x42, 0x79,
|
||||
0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x6e, 0x74, 0x12, 0x20, 0x2e, 0x72, 0x61, 0x2e, 0x52,
|
||||
0x65, 0x76, 0x6f, 0x6b, 0x65, 0x43, 0x65, 0x72, 0x74, 0x42, 0x79, 0x41, 0x70, 0x70, 0x6c, 0x69,
|
||||
0x63, 0x61, 0x6e, 0x74, 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, 0x47, 0x0a, 0x0f, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x43,
|
||||
0x65, 0x72, 0x74, 0x42, 0x79, 0x4b, 0x65, 0x79, 0x12, 0x1a, 0x2e, 0x72, 0x61, 0x2e, 0x52, 0x65,
|
||||
0x76, 0x6f, 0x6b, 0x65, 0x43, 0x65, 0x72, 0x74, 0x42, 0x79, 0x4b, 0x65, 0x79, 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, 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, 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, 0x12, 0x3b, 0x0a, 0x0c, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74,
|
||||
0x65, 0x4f, 0x43, 0x53, 0x50, 0x12, 0x17, 0x2e, 0x72, 0x61, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72,
|
||||
0x61, 0x74, 0x65, 0x4f, 0x43, 0x53, 0x50, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10,
|
||||
0x2e, 0x63, 0x61, 0x2e, 0x4f, 0x43, 0x53, 0x50, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
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,
|
||||
0x6b, 0x4b, 0x65, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x6d, 0x61, 0x6c, 0x66, 0x6f, 0x72, 0x6d, 0x65,
|
||||
0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x6d, 0x61, 0x6c, 0x66, 0x6f, 0x72, 0x6d,
|
||||
0x65, 0x64, 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, 0xad, 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, 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, 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, 0x53,
|
||||
0x0a, 0x15, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x43, 0x65, 0x72, 0x74, 0x42, 0x79, 0x41, 0x70,
|
||||
0x70, 0x6c, 0x69, 0x63, 0x61, 0x6e, 0x74, 0x12, 0x20, 0x2e, 0x72, 0x61, 0x2e, 0x52, 0x65, 0x76,
|
||||
0x6f, 0x6b, 0x65, 0x43, 0x65, 0x72, 0x74, 0x42, 0x79, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61,
|
||||
0x6e, 0x74, 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, 0x47, 0x0a, 0x0f, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x43, 0x65, 0x72,
|
||||
0x74, 0x42, 0x79, 0x4b, 0x65, 0x79, 0x12, 0x1a, 0x2e, 0x72, 0x61, 0x2e, 0x52, 0x65, 0x76, 0x6f,
|
||||
0x6b, 0x65, 0x43, 0x65, 0x72, 0x74, 0x42, 0x79, 0x4b, 0x65, 0x79, 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, 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, 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, 0x12, 0x3b, 0x0a, 0x0c, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x4f,
|
||||
0x43, 0x53, 0x50, 0x12, 0x17, 0x2e, 0x72, 0x61, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74,
|
||||
0x65, 0x4f, 0x43, 0x53, 0x50, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x63,
|
||||
0x61, 0x2e, 0x4f, 0x43, 0x53, 0x50, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 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 (
|
||||
|
|
|
|||
|
|
@ -54,16 +54,17 @@ message RevokeCertByKeyRequest {
|
|||
}
|
||||
|
||||
message AdministrativelyRevokeCertificateRequest {
|
||||
// The `cert` field may be omitted. If it is omitted,
|
||||
// the revocation reason (`code`) must not be keyCompromise,
|
||||
// and purging the Akamai cache will not happen because the
|
||||
// base URL for the certificate's OCSP server is not known.
|
||||
// Deprecated: this field is ignored.
|
||||
bytes cert = 1;
|
||||
// The `serial` field is required.
|
||||
string serial = 4;
|
||||
int64 code = 2;
|
||||
string adminName = 3;
|
||||
bool skipBlockKey = 5;
|
||||
// If the malformed flag is set, the RA will not attempt to parse the
|
||||
// certificate in question. In this case, the keyCompromise reason cannot be
|
||||
// specified, because the key cannot be blocked.
|
||||
bool malformed = 6;
|
||||
}
|
||||
|
||||
message NewOrderRequest {
|
||||
|
|
|
|||
74
ra/ra.go
74
ra/ra.go
|
|
@ -2207,48 +2207,28 @@ func (ra *RegistrationAuthorityImpl) AdministrativelyRevokeCertificate(ctx conte
|
|||
}
|
||||
|
||||
reasonCode := revocation.Reason(req.Code)
|
||||
if reasonCode == ocsp.KeyCompromise && req.Cert == nil && !req.SkipBlockKey {
|
||||
return nil, fmt.Errorf("cannot revoke and block for KeyCompromise by serial alone")
|
||||
if _, present := revocation.AdminAllowedReasons[reasonCode]; !present {
|
||||
return nil, fmt.Errorf("cannot revoke for reason %d", reasonCode)
|
||||
}
|
||||
if req.SkipBlockKey && reasonCode != ocsp.KeyCompromise {
|
||||
return nil, fmt.Errorf("cannot skip key blocking for reasons other than KeyCompromise")
|
||||
}
|
||||
|
||||
if _, present := revocation.AdminAllowedReasons[reasonCode]; !present {
|
||||
return nil, fmt.Errorf("cannot revoke for reason %d", reasonCode)
|
||||
}
|
||||
|
||||
// If we weren't passed a cert in the request, find IssuerID from the db.
|
||||
// We could instead look up and parse the certificate itself, but we avoid
|
||||
// that in case we are administratively revoking the certificate because it is
|
||||
// so badly malformed that it can't be parsed.
|
||||
var cert *x509.Certificate
|
||||
var issuerID issuance.NameID
|
||||
var err error
|
||||
if req.Cert == nil {
|
||||
status, err := ra.SA.GetCertificateStatus(ctx, &sapb.Serial{Serial: req.Serial})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to confirm that serial %q was ever issued: %w", req.Serial, err)
|
||||
}
|
||||
issuerID = issuance.NameID(status.IssuerID)
|
||||
} else {
|
||||
cert, err = x509.ParseCertificate(req.Cert)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
issuerID = issuance.IssuerNameID(cert)
|
||||
if reasonCode == ocsp.KeyCompromise && req.Malformed {
|
||||
return nil, fmt.Errorf("cannot revoke malformed certificate for KeyCompromise")
|
||||
}
|
||||
|
||||
logEvent := certificateRevocationEvent{
|
||||
ID: core.NewToken(),
|
||||
Method: "key",
|
||||
AdminName: req.AdminName,
|
||||
SerialNumber: req.Serial,
|
||||
Reason: req.Code,
|
||||
Method: "admin",
|
||||
AdminName: req.AdminName,
|
||||
}
|
||||
|
||||
// Below this point, do not re-declare `err` (i.e. type `err :=`) in a
|
||||
// nested scope. Doing so will create a new `err` variable that is not
|
||||
// captured by this closure.
|
||||
var err error
|
||||
defer func() {
|
||||
if err != nil {
|
||||
logEvent.Error = err.Error()
|
||||
|
|
@ -2256,6 +2236,44 @@ func (ra *RegistrationAuthorityImpl) AdministrativelyRevokeCertificate(ctx conte
|
|||
ra.log.AuditObject("Revocation request:", logEvent)
|
||||
}()
|
||||
|
||||
var cert *x509.Certificate
|
||||
var issuerID issuance.NameID
|
||||
if req.Cert != nil {
|
||||
// If the incoming request includes a certificate body, just use that and
|
||||
// avoid doing any database queries. This code path is deprecated and will
|
||||
// be removed when req.Cert is removed.
|
||||
cert, err = x509.ParseCertificate(req.Cert)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
issuerID = issuance.IssuerNameID(cert)
|
||||
} else if !req.Malformed {
|
||||
// As long as we don't believe the cert will be malformed, we should
|
||||
// get the precertificate so we can block its pubkey if necessary and purge
|
||||
// the akamai OCSP cache.
|
||||
var certPB *corepb.Certificate
|
||||
certPB, err = ra.SA.GetLintPrecertificate(ctx, &sapb.Serial{Serial: req.Serial})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Note that, although the thing we're parsing here is actually a linting
|
||||
// precertificate, it has identical issuer info (and therefore an identical
|
||||
// issuer NameID) to the real thing.
|
||||
cert, err = x509.ParseCertificate(certPB.Der)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
issuerID = issuance.IssuerNameID(cert)
|
||||
} else {
|
||||
// But if the cert is malformed, we at least still need its IssuerID.
|
||||
var status *corepb.CertificateStatus
|
||||
status, err = ra.SA.GetCertificateStatus(ctx, &sapb.Serial{Serial: req.Serial})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to confirm that serial %q was ever issued: %w", req.Serial, err)
|
||||
}
|
||||
issuerID = issuance.NameID(status.IssuerID)
|
||||
}
|
||||
|
||||
var serialInt *big.Int
|
||||
serialInt, err = core.StringToSerial(req.Serial)
|
||||
if err != nil {
|
||||
|
|
|
|||
134
ra/ra_test.go
134
ra/ra_test.go
|
|
@ -3652,53 +3652,79 @@ rA==
|
|||
type mockSARevocation struct {
|
||||
mocks.StorageAuthority
|
||||
|
||||
known *corepb.CertificateStatus
|
||||
known map[string]*x509.Certificate
|
||||
revoked map[string]*corepb.CertificateStatus
|
||||
blocked []*sapb.AddBlockedKeyRequest
|
||||
revoked map[string]int64
|
||||
}
|
||||
|
||||
func newMockSARevocation(known *x509.Certificate, clk clock.Clock) *mockSARevocation {
|
||||
return &mockSARevocation{
|
||||
StorageAuthority: *mocks.NewStorageAuthority(clk),
|
||||
known: &corepb.CertificateStatus{
|
||||
Serial: core.SerialToString(known.SerialNumber),
|
||||
IssuerID: int64(issuance.IssuerNameID(known)),
|
||||
},
|
||||
known: map[string]*x509.Certificate{core.SerialToString(known.SerialNumber): known},
|
||||
revoked: make(map[string]*corepb.CertificateStatus),
|
||||
blocked: make([]*sapb.AddBlockedKeyRequest, 0),
|
||||
revoked: make(map[string]int64),
|
||||
}
|
||||
}
|
||||
|
||||
func (msar *mockSARevocation) reset() {
|
||||
msar.revoked = make(map[string]*corepb.CertificateStatus)
|
||||
msar.blocked = make([]*sapb.AddBlockedKeyRequest, 0)
|
||||
}
|
||||
|
||||
func (msar *mockSARevocation) AddBlockedKey(_ context.Context, req *sapb.AddBlockedKeyRequest, _ ...grpc.CallOption) (*emptypb.Empty, error) {
|
||||
msar.blocked = append(msar.blocked, req)
|
||||
return &emptypb.Empty{}, nil
|
||||
}
|
||||
|
||||
func (msar *mockSARevocation) GetCertificateStatus(_ context.Context, req *sapb.Serial, _ ...grpc.CallOption) (*corepb.CertificateStatus, error) {
|
||||
if msar.known != nil && req.Serial == msar.known.Serial {
|
||||
return msar.known, nil
|
||||
func (msar *mockSARevocation) GetLintPrecertificate(_ context.Context, req *sapb.Serial, _ ...grpc.CallOption) (*corepb.Certificate, error) {
|
||||
if cert, present := msar.known[req.Serial]; present {
|
||||
return &corepb.Certificate{Der: cert.Raw}, nil
|
||||
}
|
||||
return nil, fmt.Errorf("unknown certificate status")
|
||||
return nil, berrors.UnknownSerialError()
|
||||
}
|
||||
|
||||
func (msar *mockSARevocation) GetCertificateStatus(_ context.Context, req *sapb.Serial, _ ...grpc.CallOption) (*corepb.CertificateStatus, error) {
|
||||
if status, present := msar.revoked[req.Serial]; present {
|
||||
return status, nil
|
||||
}
|
||||
if cert, present := msar.known[req.Serial]; present {
|
||||
return &corepb.CertificateStatus{
|
||||
Serial: core.SerialToString(cert.SerialNumber),
|
||||
IssuerID: int64(issuance.IssuerNameID(cert)),
|
||||
}, nil
|
||||
}
|
||||
return nil, berrors.UnknownSerialError()
|
||||
}
|
||||
|
||||
func (msar *mockSARevocation) RevokeCertificate(_ context.Context, req *sapb.RevokeCertificateRequest, _ ...grpc.CallOption) (*emptypb.Empty, error) {
|
||||
if _, present := msar.revoked[req.Serial]; present {
|
||||
return nil, berrors.AlreadyRevokedError("already revoked")
|
||||
}
|
||||
msar.revoked[req.Serial] = req.Reason
|
||||
msar.known.Status = string(core.OCSPStatusRevoked)
|
||||
cert, present := msar.known[req.Serial]
|
||||
if !present {
|
||||
return nil, berrors.UnknownSerialError()
|
||||
}
|
||||
msar.revoked[req.Serial] = &corepb.CertificateStatus{
|
||||
Serial: req.Serial,
|
||||
IssuerID: int64(issuance.IssuerNameID(cert)),
|
||||
Status: string(core.OCSPStatusRevoked),
|
||||
RevokedReason: req.Reason,
|
||||
}
|
||||
return &emptypb.Empty{}, nil
|
||||
}
|
||||
|
||||
func (msar *mockSARevocation) UpdateRevokedCertificate(_ context.Context, req *sapb.RevokeCertificateRequest, _ ...grpc.CallOption) (*emptypb.Empty, error) {
|
||||
reason, present := msar.revoked[req.Serial]
|
||||
status, present := msar.revoked[req.Serial]
|
||||
if !present {
|
||||
return nil, errors.New("not already revoked")
|
||||
}
|
||||
if present && reason == ocsp.KeyCompromise {
|
||||
if req.Reason != ocsp.KeyCompromise {
|
||||
return nil, errors.New("cannot re-revoke except for keyCompromise")
|
||||
}
|
||||
if present && status.RevokedReason == ocsp.KeyCompromise {
|
||||
return nil, berrors.AlreadyRevokedError("already revoked for keyCompromise")
|
||||
}
|
||||
msar.revoked[req.Serial] = req.Reason
|
||||
msar.revoked[req.Serial].RevokedReason = req.Reason
|
||||
return &emptypb.Empty{}, nil
|
||||
}
|
||||
|
||||
|
|
@ -3904,7 +3930,7 @@ func TestRevokeCertByApplicant_Controller(t *testing.T) {
|
|||
RegID: 5,
|
||||
})
|
||||
test.AssertNotError(t, err, "should have succeeded")
|
||||
test.AssertEquals(t, mockSA.revoked[core.SerialToString(cert.SerialNumber)], int64(ocsp.CessationOfOperation))
|
||||
test.AssertEquals(t, mockSA.revoked[core.SerialToString(cert.SerialNumber)].RevokedReason, int64(ocsp.CessationOfOperation))
|
||||
}
|
||||
|
||||
func TestRevokeCertByKey(t *testing.T) {
|
||||
|
|
@ -3936,7 +3962,7 @@ func TestRevokeCertByKey(t *testing.T) {
|
|||
test.Assert(t, bytes.Equal(digest[:], mockSA.blocked[0].KeyHash), "key hash mismatch")
|
||||
test.AssertEquals(t, mockSA.blocked[0].Source, "API")
|
||||
test.AssertEquals(t, len(mockSA.blocked[0].Comment), 0)
|
||||
test.AssertEquals(t, mockSA.revoked[core.SerialToString(cert.SerialNumber)], int64(ocsp.KeyCompromise))
|
||||
test.AssertEquals(t, mockSA.revoked[core.SerialToString(cert.SerialNumber)].RevokedReason, int64(ocsp.KeyCompromise))
|
||||
|
||||
// Re-revoking should fail, because it is already revoked for keyCompromise.
|
||||
_, err = ra.RevokeCertByKey(context.Background(), &rapb.RevokeCertByKeyRequest{
|
||||
|
|
@ -3946,7 +3972,7 @@ func TestRevokeCertByKey(t *testing.T) {
|
|||
|
||||
// Reset and have the Subscriber revoke for a different reason.
|
||||
// Then re-revoking using the key should work.
|
||||
mockSA.revoked = make(map[string]int64)
|
||||
mockSA.revoked = make(map[string]*corepb.CertificateStatus)
|
||||
_, err = ra.RevokeCertByApplicant(context.Background(), &rapb.RevokeCertByApplicantRequest{
|
||||
Cert: cert.Raw,
|
||||
Code: ocsp.Unspecified,
|
||||
|
|
@ -3983,33 +4009,26 @@ func TestAdministrativelyRevokeCertificate(t *testing.T) {
|
|||
_, 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.
|
||||
// Revoking with no serial should fail immediately.
|
||||
mockSA.reset()
|
||||
_, 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.
|
||||
mockSA.reset()
|
||||
_, err = ra.AdministrativelyRevokeCertificate(context.Background(), &rapb.AdministrativelyRevokeCertificateRequest{
|
||||
Cert: cert.Raw,
|
||||
Serial: serial,
|
||||
Code: ocsp.KeyCompromise,
|
||||
Code: ocsp.Unspecified,
|
||||
AdminName: "",
|
||||
})
|
||||
test.AssertError(t, err, "AdministrativelyRevokeCertificate should have failed with empty string for `AdminName`")
|
||||
|
||||
// Revoking for a forbidden reason should fail immediately.
|
||||
mockSA.reset()
|
||||
_, err = ra.AdministrativelyRevokeCertificate(context.Background(), &rapb.AdministrativelyRevokeCertificateRequest{
|
||||
Cert: cert.Raw,
|
||||
Serial: serial,
|
||||
Code: ocsp.CertificateHold,
|
||||
AdminName: "root",
|
||||
|
|
@ -4017,8 +4036,8 @@ func TestAdministrativelyRevokeCertificate(t *testing.T) {
|
|||
test.AssertError(t, err, "AdministrativelyRevokeCertificate should have failed with forbidden revocation reason")
|
||||
|
||||
// Revoking a cert for an unspecified reason should work but not block the key.
|
||||
mockSA.reset()
|
||||
_, err = ra.AdministrativelyRevokeCertificate(context.Background(), &rapb.AdministrativelyRevokeCertificateRequest{
|
||||
Cert: cert.Raw,
|
||||
Serial: serial,
|
||||
Code: ocsp.Unspecified,
|
||||
AdminName: "root",
|
||||
|
|
@ -4029,9 +4048,9 @@ func TestAdministrativelyRevokeCertificate(t *testing.T) {
|
|||
t, ra.revocationReasonCounter, prometheus.Labels{"reason": "unspecified"}, 1)
|
||||
|
||||
// Revoking a serial for an unspecified reason should work but not block the key.
|
||||
mockSA.revoked = make(map[string]int64)
|
||||
mockSA.reset()
|
||||
_, err = ra.AdministrativelyRevokeCertificate(context.Background(), &rapb.AdministrativelyRevokeCertificateRequest{
|
||||
Serial: core.SerialToString(cert.SerialNumber),
|
||||
Serial: serial,
|
||||
Code: ocsp.Unspecified,
|
||||
AdminName: "root",
|
||||
})
|
||||
|
|
@ -4041,22 +4060,51 @@ func TestAdministrativelyRevokeCertificate(t *testing.T) {
|
|||
t, ra.revocationReasonCounter, prometheus.Labels{"reason": "unspecified"}, 2)
|
||||
|
||||
// Duplicate administrative revocation of a serial for an unspecified reason
|
||||
// should fail and not block the key
|
||||
// should succeed because the akamai cache purge succeeds.
|
||||
// Note that we *don't* call reset() here, so it recognizes the duplicate.
|
||||
_, err = ra.AdministrativelyRevokeCertificate(context.Background(), &rapb.AdministrativelyRevokeCertificateRequest{
|
||||
Serial: core.SerialToString(cert.SerialNumber),
|
||||
Serial: serial,
|
||||
Code: ocsp.Unspecified,
|
||||
AdminName: "root",
|
||||
})
|
||||
test.AssertNotError(t, err, "AdministrativelyRevokeCertificate failed")
|
||||
test.AssertEquals(t, len(mockSA.blocked), 0)
|
||||
test.AssertMetricWithLabelsEquals(
|
||||
t, ra.revocationReasonCounter, prometheus.Labels{"reason": "unspecified"}, 2)
|
||||
|
||||
// Duplicate administrative revocation of a serial for a *malformed* cert for
|
||||
// an unspecified reason should fail because we can't attempt an akamai cache
|
||||
// purge so the underlying AlreadyRevoked error gets propagated upwards.
|
||||
// Note that we *don't* call reset() here, so it recognizes the duplicate.
|
||||
_, err = ra.AdministrativelyRevokeCertificate(context.Background(), &rapb.AdministrativelyRevokeCertificateRequest{
|
||||
Serial: serial,
|
||||
Code: ocsp.Unspecified,
|
||||
AdminName: "root",
|
||||
Malformed: true,
|
||||
})
|
||||
test.AssertError(t, err, "Should be revoked")
|
||||
test.AssertContains(t, err.Error(), "already revoked")
|
||||
test.AssertEquals(t, len(mockSA.blocked), 0)
|
||||
test.AssertMetricWithLabelsEquals(
|
||||
t, ra.revocationReasonCounter, prometheus.Labels{"reason": "unspecified"}, 2)
|
||||
|
||||
// Revoking a cert for key compromise should work and block the key.
|
||||
mockSA.revoked = make(map[string]int64)
|
||||
// Revoking a cert for key compromise with skipBlockKey set should work but
|
||||
// not block the key.
|
||||
mockSA.reset()
|
||||
_, err = ra.AdministrativelyRevokeCertificate(context.Background(), &rapb.AdministrativelyRevokeCertificateRequest{
|
||||
Serial: serial,
|
||||
Code: ocsp.KeyCompromise,
|
||||
AdminName: "root",
|
||||
SkipBlockKey: true,
|
||||
})
|
||||
test.AssertNotError(t, err, "AdministrativelyRevokeCertificate failed")
|
||||
test.AssertEquals(t, len(mockSA.blocked), 0)
|
||||
test.AssertMetricWithLabelsEquals(
|
||||
t, ra.revocationReasonCounter, prometheus.Labels{"reason": "keyCompromise"}, 1)
|
||||
|
||||
// Revoking a cert for key compromise should work and block the key.
|
||||
mockSA.reset()
|
||||
_, err = ra.AdministrativelyRevokeCertificate(context.Background(), &rapb.AdministrativelyRevokeCertificateRequest{
|
||||
Cert: cert.Raw,
|
||||
Serial: serial,
|
||||
Code: ocsp.KeyCompromise,
|
||||
AdminName: "root",
|
||||
|
|
@ -4068,14 +4116,16 @@ func TestAdministrativelyRevokeCertificate(t *testing.T) {
|
|||
test.AssertEquals(t, mockSA.blocked[0].Comment, "revoked by root")
|
||||
test.AssertEquals(t, mockSA.blocked[0].Added.AsTime(), clk.Now())
|
||||
test.AssertMetricWithLabelsEquals(
|
||||
t, ra.revocationReasonCounter, prometheus.Labels{"reason": "keyCompromise"}, 1)
|
||||
t, ra.revocationReasonCounter, prometheus.Labels{"reason": "keyCompromise"}, 2)
|
||||
|
||||
// Revoking a serial for key compromise should fail because we don't have the pubkey to block.
|
||||
mockSA.revoked = make(map[string]int64)
|
||||
// Revoking a malformed cert for key compromise should fail because we don't
|
||||
// have the pubkey to block.
|
||||
mockSA.reset()
|
||||
_, err = ra.AdministrativelyRevokeCertificate(context.Background(), &rapb.AdministrativelyRevokeCertificateRequest{
|
||||
Serial: core.SerialToString(cert.SerialNumber),
|
||||
Code: ocsp.KeyCompromise,
|
||||
AdminName: "root",
|
||||
Malformed: true,
|
||||
})
|
||||
test.AssertError(t, err, "AdministrativelyRevokeCertificate should have failed with just serial for keyCompromise")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -117,6 +117,10 @@ func (sa SA) RevokeCertificate(ctx context.Context, req *sapb.RevokeCertificateR
|
|||
return sa.Impl.RevokeCertificate(ctx, req)
|
||||
}
|
||||
|
||||
func (sa SA) GetLintPrecertificate(ctx context.Context, req *sapb.Serial, _ ...grpc.CallOption) (*corepb.Certificate, error) {
|
||||
return sa.Impl.GetLintPrecertificate(ctx, req)
|
||||
}
|
||||
|
||||
func (sa SA) GetCertificateStatus(ctx context.Context, req *sapb.Serial, _ ...grpc.CallOption) (*corepb.CertificateStatus, error) {
|
||||
return sa.Impl.GetCertificateStatus(ctx, req)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue