Skip to content

Commit 776287f

Browse files
authored
ra: send UnknownSerial error from GenerateOCSP (#7110)
The allows the ocsp-responder to log unknown serial numbers (vs just expired ones). Follow-up of #7108 Updates #7091
1 parent fdaab3e commit 776287f

File tree

2 files changed

+73
-1
lines changed

2 files changed

+73
-1
lines changed

ra/ra.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2380,7 +2380,14 @@ func (ra *RegistrationAuthorityImpl) checkOrderNames(names []string) error {
23802380
// or the certificate is expired, it returns berrors.NotFoundError.
23812381
func (ra *RegistrationAuthorityImpl) GenerateOCSP(ctx context.Context, req *rapb.GenerateOCSPRequest) (*capb.OCSPResponse, error) {
23822382
status, err := ra.SA.GetCertificateStatus(ctx, &sapb.Serial{Serial: req.Serial})
2383-
if err != nil {
2383+
if errors.Is(err, berrors.NotFound) {
2384+
_, err := ra.SA.GetSerialMetadata(ctx, &sapb.Serial{Serial: req.Serial})
2385+
if errors.Is(err, berrors.NotFound) {
2386+
return nil, berrors.UnknownSerialError()
2387+
} else {
2388+
return nil, berrors.NotFoundError("certificate not found")
2389+
}
2390+
} else if err != nil {
23842391
return nil, err
23852392
}
23862393

ra/ra_test.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3742,6 +3742,7 @@ func (mp *mockPurger) Purge(context.Context, *akamaipb.PurgeRequest, ...grpc.Cal
37423742
return &emptypb.Empty{}, nil
37433743
}
37443744

3745+
// mockSAGenerateOCSP is a mock SA that always returns a good OCSP response, with a constant NotAfter.
37453746
type mockSAGenerateOCSP struct {
37463747
mocks.StorageAuthority
37473748
expiration time.Time
@@ -3778,6 +3779,70 @@ func TestGenerateOCSP(t *testing.T) {
37783779
}
37793780
}
37803781

3782+
// mockSALongExpiredSerial is a mock SA that treats every serial as if it expired a long time ago.
3783+
// Specifically, it returns NotFound to GetCertificateStatus (simulating the serial having been
3784+
// removed from the certificateStatus table), but returns success to GetSerialMetadata (simulating
3785+
// a serial number staying in the `serials` table indefinitely).
3786+
type mockSALongExpiredSerial struct {
3787+
mocks.StorageAuthority
3788+
}
3789+
3790+
func (msgo *mockSALongExpiredSerial) GetCertificateStatus(_ context.Context, req *sapb.Serial, _ ...grpc.CallOption) (*corepb.CertificateStatus, error) {
3791+
return nil, berrors.NotFoundError("not found")
3792+
}
3793+
3794+
func (msgo *mockSALongExpiredSerial) GetSerialMetadata(_ context.Context, req *sapb.Serial, _ ...grpc.CallOption) (*sapb.SerialMetadata, error) {
3795+
return &sapb.SerialMetadata{
3796+
Serial: req.Serial,
3797+
}, nil
3798+
}
3799+
3800+
func TestGenerateOCSPLongExpiredSerial(t *testing.T) {
3801+
_, _, ra, _, cleanUp := initAuthorities(t)
3802+
defer cleanUp()
3803+
3804+
ra.OCSP = &mockOCSPA{}
3805+
ra.SA = &mockSALongExpiredSerial{}
3806+
3807+
req := &rapb.GenerateOCSPRequest{
3808+
Serial: core.SerialToString(big.NewInt(1)),
3809+
}
3810+
3811+
_, err := ra.GenerateOCSP(context.Background(), req)
3812+
test.AssertError(t, err, "generating OCSP")
3813+
if !errors.Is(err, berrors.NotFound) {
3814+
t.Errorf("expected NotFound error, got %#v", err)
3815+
}
3816+
}
3817+
3818+
// mockSAUnknownSerial is a mock SA that always returns NotFound to certificate status and serial lookups.
3819+
// It emulates an SA that has never issued a certificate.
3820+
type mockSAUnknownSerial struct {
3821+
mockSALongExpiredSerial
3822+
}
3823+
3824+
func (msgo *mockSAUnknownSerial) GetSerialMetadata(_ context.Context, req *sapb.Serial, _ ...grpc.CallOption) (*sapb.SerialMetadata, error) {
3825+
return nil, berrors.NotFoundError("not found")
3826+
}
3827+
3828+
func TestGenerateOCSPUnknownSerial(t *testing.T) {
3829+
_, _, ra, _, cleanUp := initAuthorities(t)
3830+
defer cleanUp()
3831+
3832+
ra.OCSP = &mockOCSPA{}
3833+
ra.SA = &mockSAUnknownSerial{}
3834+
3835+
req := &rapb.GenerateOCSPRequest{
3836+
Serial: core.SerialToString(big.NewInt(1)),
3837+
}
3838+
3839+
_, err := ra.GenerateOCSP(context.Background(), req)
3840+
test.AssertError(t, err, "generating OCSP")
3841+
if !errors.Is(err, berrors.UnknownSerial) {
3842+
t.Errorf("expected UnknownSerial error, got %#v", err)
3843+
}
3844+
}
3845+
37813846
func TestRevokeCertByApplicant_Subscriber(t *testing.T) {
37823847
_, _, ra, clk, cleanUp := initAuthorities(t)
37833848
defer cleanUp()

0 commit comments

Comments
 (0)