Skip to content

Commit 44d081e

Browse files
aarongablenatalia.astashenko
authored andcommitted
Make CAA checking more like DCV checking (letsencrypt#8491)
If the primary perspective CAA check returns an error, return early rather than always kicking off the remote checks anyway. As part of this change, rearrange the code in DoCAA to more closely mirror the code in DoDCV. In particular, move the creation of the result protobuf into a helper function which can be called at both the early-return and late-return locations.
1 parent 43ec1b5 commit 44d081e

File tree

3 files changed

+31
-41
lines changed

3 files changed

+31
-41
lines changed

grpc/pb-marshalling.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,18 @@ func pbToValidationResult(in *vapb.ValidationResult) ([]core.ValidationRecord, *
227227
return recordAry, prob, nil
228228
}
229229

230+
func CAAResultToPB(prob *probs.ProblemDetails, perspective, rir string) (*vapb.IsCAAValidResponse, error) {
231+
marshalledProb, err := ProblemDetailsToPB(prob)
232+
if err != nil {
233+
return nil, err
234+
}
235+
return &vapb.IsCAAValidResponse{
236+
Problem: marshalledProb,
237+
Perspective: perspective,
238+
Rir: rir,
239+
}, nil
240+
}
241+
230242
func RegistrationToPB(reg core.Registration) (*corepb.Registration, error) {
231243
keyBytes, err := reg.Key.MarshalJSON()
232244
if err != nil {

va/caa.go

Lines changed: 17 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ import (
1515

1616
"github.com/letsencrypt/boulder/bdns"
1717
"github.com/letsencrypt/boulder/core"
18-
corepb "github.com/letsencrypt/boulder/core/proto"
1918
berrors "github.com/letsencrypt/boulder/errors"
19+
bgrpc "github.com/letsencrypt/boulder/grpc"
2020
"github.com/letsencrypt/boulder/identifier"
2121
"github.com/letsencrypt/boulder/probs"
2222
vapb "github.com/letsencrypt/boulder/va/proto"
@@ -45,12 +45,6 @@ func (va *ValidationAuthorityImpl) DoCAA(ctx context.Context, req *vapb.IsCAAVal
4545
return nil, berrors.MalformedError("Identifier type for CAA check was not DNS")
4646
}
4747

48-
logEvent := validationLogEvent{
49-
AuthzID: req.AuthzID,
50-
Requester: req.AccountURIID,
51-
Identifier: ident,
52-
}
53-
5448
challType := core.AcmeChallenge(req.ValidationMethod)
5549
if !challType.IsValid() {
5650
return nil, berrors.InternalServerError("unrecognized validation method %q", req.ValidationMethod)
@@ -66,10 +60,13 @@ func (va *ValidationAuthorityImpl) DoCAA(ctx context.Context, req *vapb.IsCAAVal
6660
// redeclare `prob`, `localLatency`, or `summary` below this point.
6761
var prob *probs.ProblemDetails
6862
var summary *mpicSummary
69-
var internalErr error
7063
var localLatency time.Duration
7164
start := va.clk.Now()
72-
65+
logEvent := validationLogEvent{
66+
AuthzID: req.AuthzID,
67+
Requester: req.AccountURIID,
68+
Identifier: ident,
69+
}
7370
defer func() {
7471
probType := ""
7572
outcome := fail
@@ -81,28 +78,32 @@ func (va *ValidationAuthorityImpl) DoCAA(ctx context.Context, req *vapb.IsCAAVal
8178
// CAA check passed.
8279
outcome = pass
8380
}
81+
8482
// Observe local check latency (primary|remote).
8583
va.observeLatency(opCAA, va.perspective, string(challType), probType, outcome, localLatency)
8684
if va.isPrimaryVA() {
8785
// Observe total check latency (primary+remote).
8886
va.observeLatency(opCAA, allPerspectives, string(challType), probType, outcome, va.clk.Since(start))
8987
logEvent.Summary = summary
9088
}
89+
9190
// Log the total check latency.
9291
logEvent.Latency = va.clk.Since(start).Round(time.Millisecond).Seconds()
93-
9492
va.log.AuditObject("CAA check result", logEvent)
9593
}()
9694

97-
internalErr = va.checkCAA(ctx, ident, params)
95+
// Do the local checks. We do these before kicking off the remote checks to
96+
// ensure that we don't waste effort on remote checks if the local ones fail.
97+
err := va.checkCAA(ctx, ident, params)
9898

9999
// Stop the clock for local check latency.
100100
localLatency = va.clk.Since(start)
101101

102-
if internalErr != nil {
103-
logEvent.InternalError = internalErr.Error()
104-
prob = detailedError(internalErr)
102+
if err != nil {
103+
logEvent.InternalError = err.Error()
104+
prob = detailedError(err)
105105
prob.Detail = fmt.Sprintf("While processing CAA for %s: %s", ident.Value, prob.Detail)
106+
return bgrpc.CAAResultToPB(filterProblemDetails(prob), va.perspective, va.rir)
106107
}
107108

108109
if va.isPrimaryVA() {
@@ -113,35 +114,10 @@ func (va *ValidationAuthorityImpl) DoCAA(ctx context.Context, req *vapb.IsCAAVal
113114
}
114115
return remoteva.DoCAA(ctx, checkRequest)
115116
}
116-
var remoteProb *probs.ProblemDetails
117-
summary, remoteProb = va.doRemoteOperation(ctx, op, req)
118-
// If the remote result was a non-nil problem then fail the CAA check
119-
if remoteProb != nil {
120-
prob = remoteProb
121-
va.log.Infof("CAA check failed due to remote failures: identifier=%v err=%s",
122-
ident.Value, remoteProb)
123-
}
117+
summary, prob = va.doRemoteOperation(ctx, op, req)
124118
}
125119

126-
if prob != nil {
127-
// The ProblemDetails will be serialized through gRPC, which requires UTF-8.
128-
// It will also later be serialized in JSON, which defaults to UTF-8. Make
129-
// sure it is UTF-8 clean now.
130-
prob = filterProblemDetails(prob)
131-
return &vapb.IsCAAValidResponse{
132-
Problem: &corepb.ProblemDetails{
133-
ProblemType: string(prob.Type),
134-
Detail: replaceInvalidUTF8([]byte(prob.Detail)),
135-
},
136-
Perspective: va.perspective,
137-
Rir: va.rir,
138-
}, nil
139-
} else {
140-
return &vapb.IsCAAValidResponse{
141-
Perspective: va.perspective,
142-
Rir: va.rir,
143-
}, nil
144-
}
120+
return bgrpc.CAAResultToPB(filterProblemDetails(prob), va.perspective, va.rir)
145121
}
146122

147123
// checkCAA performs a CAA lookup & validation for the provided identifier. If

va/va.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,7 @@ func (va *ValidationAuthorityImpl) DoDCV(ctx context.Context, req *vapb.PerformV
700700
logEvent.Challenge.Status = core.StatusValid
701701
outcome = pass
702702
}
703+
703704
// Observe local validation latency (primary|remote).
704705
va.observeLatency(opDCV, va.perspective, string(chall.Type), probType, outcome, localLatency)
705706
if va.isPrimaryVA() {
@@ -762,5 +763,6 @@ func (va *ValidationAuthorityImpl) DoDCV(ctx context.Context, req *vapb.PerformV
762763
}
763764
summary, prob = va.doRemoteOperation(ctx, op, req)
764765
}
766+
765767
return bgrpc.ValidationResultToPB(records, filterProblemDetails(prob), va.perspective, va.rir)
766768
}

0 commit comments

Comments
 (0)