X Tutup
Skip to content

Commit d3b9107

Browse files
jshaDaniel McCarney
authored andcommitted
orphan-finder: add OCSP generation (letsencrypt#4457)
Fixes letsencrypt#4428
1 parent 58ec874 commit d3b9107

File tree

4 files changed

+54
-13
lines changed

4 files changed

+54
-13
lines changed

cmd/orphan-finder/main.go

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"strings"
1515
"time"
1616

17+
capb "github.com/letsencrypt/boulder/ca/proto"
1718
"github.com/letsencrypt/boulder/cmd"
1819
"github.com/letsencrypt/boulder/core"
1920
berrors "github.com/letsencrypt/boulder/errors"
@@ -40,6 +41,7 @@ command descriptions:
4041
type config struct {
4142
TLS cmd.TLSConfig
4243
SAService *cmd.GRPCClientConfig
44+
CAService *cmd.GRPCClientConfig
4345
Syslog cmd.SyslogConfig
4446
// Backdate specifies how to adjust a certificate's NotBefore date to get back
4547
// to the original issued date. It should match the value used in
@@ -53,6 +55,10 @@ type certificateStorage interface {
5355
GetCertificate(ctx context.Context, serial string) (core.Certificate, error)
5456
}
5557

58+
type ocspGenerator interface {
59+
GenerateOCSP(context.Context, core.OCSPSigningRequest) ([]byte, error)
60+
}
61+
5662
var (
5763
derOrphan = regexp.MustCompile(`cert=\[([0-9a-f]+)\]`)
5864
regOrphan = regexp.MustCompile(`regID=\[(\d+)\]`)
@@ -77,7 +83,12 @@ func checkDER(sai certificateStorage, der []byte) (*x509.Certificate, error) {
7783
return nil, fmt.Errorf("Existing certificate lookup failed: %s", err)
7884
}
7985

80-
func parseLogLine(sa certificateStorage, logger blog.Logger, line string) (found bool, added bool) {
86+
// storeParsedLogLine attempts to parse one log line according to the format used when
87+
// orphaning certificates. It returns two booleans: The first is true if the
88+
// line was a match, and the second is true if the certificate was successfully
89+
// added to the DB. As part of adding a certificate to the DB, it requests a
90+
// fresh OCSP response from the CA to store alongside the certificate.
91+
func storeParsedLogLine(sa certificateStorage, ca ocspGenerator, logger blog.Logger, line string) (found bool, added bool) {
8192
ctx := context.Background()
8293
if !strings.Contains(line, "cert=") || !strings.Contains(line, "orphaning certificate") {
8394
return false, false
@@ -119,15 +130,23 @@ func parseLogLine(sa certificateStorage, logger blog.Logger, line string) (found
119130
// backdated we need to add the backdate duration to find the true issued
120131
// time.
121132
issuedDate := cert.NotBefore.Add(backdateDuration)
122-
_, err = sa.AddCertificate(ctx, der, int64(regID), nil, &issuedDate)
133+
ocspResponse, err := ca.GenerateOCSP(ctx, core.OCSPSigningRequest{
134+
CertDER: der,
135+
Status: string(core.OCSPStatusGood),
136+
})
137+
if err != nil {
138+
logger.AuditErrf("Couldn't generate OCSP: %s, [%s]", err, line)
139+
return true, false
140+
}
141+
_, err = sa.AddCertificate(ctx, der, int64(regID), ocspResponse, &issuedDate)
123142
if err != nil {
124143
logger.AuditErrf("Failed to store certificate: %s, [%s]", err, line)
125144
return true, false
126145
}
127146
return true, true
128147
}
129148

130-
func setup(configFile string) (blog.Logger, core.StorageAuthority) {
149+
func setup(configFile string) (blog.Logger, core.StorageAuthority, core.CertificateAuthority) {
131150
configJSON, err := ioutil.ReadFile(configFile)
132151
cmd.FailOnError(err, "Failed to read config file")
133152
var conf config
@@ -141,12 +160,16 @@ func setup(configFile string) (blog.Logger, core.StorageAuthority) {
141160
cmd.FailOnError(err, "TLS config")
142161

143162
clientMetrics := bgrpc.NewClientMetrics(metrics.NewNoopScope())
144-
conn, err := bgrpc.ClientSetup(conf.SAService, tlsConfig, clientMetrics, cmd.Clock())
163+
saConn, err := bgrpc.ClientSetup(conf.SAService, tlsConfig, clientMetrics, cmd.Clock())
145164
cmd.FailOnError(err, "Failed to load credentials and create gRPC connection to SA")
146-
sac := bgrpc.NewStorageAuthorityClient(sapb.NewStorageAuthorityClient(conn))
165+
sac := bgrpc.NewStorageAuthorityClient(sapb.NewStorageAuthorityClient(saConn))
166+
167+
caConn, err := bgrpc.ClientSetup(conf.CAService, tlsConfig, clientMetrics, cmd.Clock())
168+
cmd.FailOnError(err, "Failed to load credentials and create gRPC connection to CA")
169+
cac := bgrpc.NewCertificateAuthorityClient(nil, capb.NewCertificateAuthorityClient(caConn))
147170

148171
backdateDuration = conf.Backdate.Duration
149-
return logger, sac
172+
return logger, sac, cac
150173
}
151174

152175
func main() {
@@ -176,7 +199,7 @@ func main() {
176199

177200
switch command {
178201
case "parse-ca-log":
179-
logger, sa := setup(*configFile)
202+
logger, sa, ca := setup(*configFile)
180203
if *logPath == "" {
181204
usage()
182205
}
@@ -187,7 +210,7 @@ func main() {
187210
orphansFound := int64(0)
188211
orphansAdded := int64(0)
189212
for _, line := range strings.Split(string(logData), "\n") {
190-
found, added := parseLogLine(sa, logger, line)
213+
found, added := storeParsedLogLine(sa, ca, logger, line)
191214
if found {
192215
orphansFound++
193216
if added {
@@ -199,7 +222,7 @@ func main() {
199222

200223
case "parse-der":
201224
ctx := context.Background()
202-
_, sa := setup(*configFile)
225+
_, sa, ca := setup(*configFile)
203226
if *derPath == "" || *regID == 0 {
204227
usage()
205228
}
@@ -210,7 +233,12 @@ func main() {
210233
// Because certificates are backdated we need to add the backdate duration
211234
// to find the true issued time.
212235
issuedDate := cert.NotBefore.Add(1 * backdateDuration)
213-
_, err = sa.AddCertificate(ctx, der, int64(*regID), nil, &issuedDate)
236+
ocspResponse, err := ca.GenerateOCSP(ctx, core.OCSPSigningRequest{
237+
CertDER: der,
238+
Status: string(core.OCSPStatusGood),
239+
})
240+
cmd.FailOnError(err, "Generating OCSP")
241+
_, err = sa.AddCertificate(ctx, der, int64(*regID), ocspResponse, &issuedDate)
214242
cmd.FailOnError(err, "Failed to add certificate to database")
215243

216244
default:

cmd/orphan-finder/main_test.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ func (m *mockSA) GetCertificate(ctx context.Context, s string) (core.Certificate
4242
return core.Certificate{}, berrors.NotFoundError("no cert stored")
4343
}
4444

45+
type mockCA struct{}
46+
47+
func (ca *mockCA) GenerateOCSP(ctx context.Context, xferObj core.OCSPSigningRequest) (ocsp []byte, err error) {
48+
return []byte("HI"), nil
49+
}
50+
4551
func checkNoErrors(t *testing.T) {
4652
logs := log.GetAllMatching("ERR:")
4753
if len(logs) != 0 {
@@ -56,6 +62,7 @@ func TestParseLine(t *testing.T) {
5662
fc := clock.NewFake()
5763
fc.Set(time.Date(2015, 3, 4, 5, 0, 0, 0, time.UTC))
5864
sa := &mockSA{}
65+
ca := &mockCA{}
5966

6067
// Set an example backdate duration (this is normally read from config)
6168
backdateDuration = time.Hour
@@ -111,7 +118,7 @@ func TestParseLine(t *testing.T) {
111118
for _, tc := range testCases {
112119
t.Run(tc.Name, func(t *testing.T) {
113120
log.Clear()
114-
found, added := parseLogLine(sa, log, tc.LogLine)
121+
found, added := storeParsedLogLine(sa, ca, log, tc.LogLine)
115122
test.AssertEquals(t, found, tc.ExpectFound)
116123
test.AssertEquals(t, added, tc.ExpectAdded)
117124
logs := log.GetAllMatching("ERR:")
@@ -140,9 +147,10 @@ func TestNotOrphan(t *testing.T) {
140147
fc := clock.NewFake()
141148
fc.Set(time.Date(2015, 3, 4, 5, 0, 0, 0, time.UTC))
142149
sa := &mockSA{}
150+
ca := &mockCA{}
143151

144152
log.Clear()
145-
found, added := parseLogLine(sa, log, "cert=fakeout")
153+
found, added := storeParsedLogLine(sa, ca, log, "cert=fakeout")
146154
test.AssertEquals(t, found, false)
147155
test.AssertEquals(t, added, false)
148156
checkNoErrors(t)

test/config-next/ca-a.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
"grpcOCSPGenerator": {
2525
"address": ":9096",
2626
"clientNames": [
27-
"ocsp-updater.boulder"
27+
"ocsp-updater.boulder",
28+
"orphan-finder.boulder"
2829
]
2930
},
3031
"Issuers": [{

test/config-next/orphan-finder.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
"keyFile": "test/grpc-creds/orphan-finder.boulder/key.pem"
1212
},
1313

14+
"ocspGeneratorService": {
15+
"serverAddress": "ca.boulder:9096",
16+
"timeout": "15s"
17+
},
1418
"saService": {
1519
"serverAddress": "sa.boulder:9095",
1620
"timeout": "15s"

0 commit comments

Comments
 (0)
X Tutup