Remove caa-checker from the tree (#2351)

The VA can internally check CAA and this additional code was deemed unneeded complexity that could be hoisted outside of Boulder. Fixes #2346.
This commit is contained in:
Roland Bracewell Shoemaker 2016-11-23 05:42:33 -08:00 committed by Daniel McCarney
parent 38c2ea3382
commit e2155388a1
13 changed files with 2 additions and 658 deletions

View File

@ -11,7 +11,6 @@ import (
"github.com/letsencrypt/boulder/bdns"
"github.com/letsencrypt/boulder/cdr"
"github.com/letsencrypt/boulder/cmd"
caaPB "github.com/letsencrypt/boulder/cmd/caa-checker/proto"
bgrpc "github.com/letsencrypt/boulder/grpc"
"github.com/letsencrypt/boulder/metrics"
"github.com/letsencrypt/boulder/rpc"
@ -34,8 +33,6 @@ type config struct {
GoogleSafeBrowsing *cmd.GoogleSafeBrowsingConfig
CAAService *cmd.GRPCClientConfig
CAADistributedResolver *cmd.CAADistributedResolverConfig
// The number of times to try a DNS query (that has a temporary error)
@ -90,13 +87,6 @@ func main() {
pc.TLSPort = c.VA.PortConfig.TLSPort
}
var caaClient caaPB.CAACheckerClient
if c.VA.CAAService != nil {
conn, err := bgrpc.ClientSetup(c.VA.CAAService, scope)
cmd.FailOnError(err, "Failed to load credentials and create connection to service")
caaClient = caaPB.NewCAACheckerClient(conn)
}
sbc := newGoogleSafeBrowsing(c.VA.GoogleSafeBrowsing)
var cdrClient *cdr.CAADistributedResolver
@ -138,7 +128,6 @@ func main() {
vai := va.NewValidationAuthorityImpl(
pc,
sbc,
caaClient,
cdrClient,
resolver,
c.VA.UserAgent,

View File

@ -1,178 +0,0 @@
// Code generated by protoc-gen-go.
// source: caaChecker.proto
// DO NOT EDIT!
/*
Package caaChecker is a generated protocol buffer package.
It is generated from these files:
caaChecker.proto
It has these top-level messages:
Check
Result
*/
package caaChecker
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import (
context "golang.org/x/net/context"
grpc "google.golang.org/grpc"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type Check struct {
Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
IssuerDomain *string `protobuf:"bytes,2,opt,name=issuerDomain" json:"issuerDomain,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *Check) Reset() { *m = Check{} }
func (m *Check) String() string { return proto.CompactTextString(m) }
func (*Check) ProtoMessage() {}
func (*Check) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (m *Check) GetName() string {
if m != nil && m.Name != nil {
return *m.Name
}
return ""
}
func (m *Check) GetIssuerDomain() string {
if m != nil && m.IssuerDomain != nil {
return *m.IssuerDomain
}
return ""
}
type Result struct {
Present *bool `protobuf:"varint,1,opt,name=present" json:"present,omitempty"`
Valid *bool `protobuf:"varint,2,opt,name=valid" json:"valid,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *Result) Reset() { *m = Result{} }
func (m *Result) String() string { return proto.CompactTextString(m) }
func (*Result) ProtoMessage() {}
func (*Result) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
func (m *Result) GetPresent() bool {
if m != nil && m.Present != nil {
return *m.Present
}
return false
}
func (m *Result) GetValid() bool {
if m != nil && m.Valid != nil {
return *m.Valid
}
return false
}
func init() {
proto.RegisterType((*Check)(nil), "Check")
proto.RegisterType((*Result)(nil), "Result")
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion3
// Client API for CAAChecker service
type CAACheckerClient interface {
ValidForIssuance(ctx context.Context, in *Check, opts ...grpc.CallOption) (*Result, error)
}
type cAACheckerClient struct {
cc *grpc.ClientConn
}
func NewCAACheckerClient(cc *grpc.ClientConn) CAACheckerClient {
return &cAACheckerClient{cc}
}
func (c *cAACheckerClient) ValidForIssuance(ctx context.Context, in *Check, opts ...grpc.CallOption) (*Result, error) {
out := new(Result)
err := grpc.Invoke(ctx, "/CAAChecker/ValidForIssuance", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for CAAChecker service
type CAACheckerServer interface {
ValidForIssuance(context.Context, *Check) (*Result, error)
}
func RegisterCAACheckerServer(s *grpc.Server, srv CAACheckerServer) {
s.RegisterService(&_CAAChecker_serviceDesc, srv)
}
func _CAAChecker_ValidForIssuance_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(Check)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(CAACheckerServer).ValidForIssuance(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/CAAChecker/ValidForIssuance",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(CAACheckerServer).ValidForIssuance(ctx, req.(*Check))
}
return interceptor(ctx, in, info, handler)
}
var _CAAChecker_serviceDesc = grpc.ServiceDesc{
ServiceName: "CAAChecker",
HandlerType: (*CAACheckerServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "ValidForIssuance",
Handler: _CAAChecker_ValidForIssuance_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: fileDescriptor0,
}
func init() { proto.RegisterFile("caaChecker.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 157 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x12, 0x48, 0x4e, 0x4c, 0x74,
0xce, 0x48, 0x4d, 0xce, 0x4e, 0x2d, 0xd2, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x57, 0xd2, 0xe6, 0x62,
0x05, 0x0b, 0x08, 0xf1, 0x70, 0xb1, 0xe4, 0x25, 0xe6, 0xa6, 0x4a, 0x30, 0x2a, 0x30, 0x6a, 0x70,
0x0a, 0x89, 0x70, 0xf1, 0x64, 0x16, 0x17, 0x97, 0xa6, 0x16, 0xb9, 0xe4, 0xe7, 0x26, 0x66, 0xe6,
0x49, 0x30, 0x81, 0x44, 0x95, 0x34, 0xb8, 0xd8, 0x82, 0x52, 0x8b, 0x4b, 0x73, 0x4a, 0x84, 0xf8,
0xb9, 0xd8, 0x0b, 0x8a, 0x52, 0x8b, 0x53, 0xf3, 0x4a, 0xc0, 0x1a, 0x38, 0x84, 0x78, 0xb9, 0x58,
0xcb, 0x12, 0x73, 0x32, 0x53, 0xc0, 0x2a, 0x39, 0x8c, 0x8c, 0xb9, 0xb8, 0x9c, 0x1d, 0x1d, 0xa1,
0x56, 0x09, 0xa9, 0x72, 0x09, 0x84, 0x81, 0x24, 0xdd, 0xf2, 0x8b, 0x3c, 0x8b, 0x8b, 0x4b, 0x13,
0xf3, 0x92, 0x53, 0x85, 0xd8, 0xf4, 0xc0, 0xb2, 0x52, 0xec, 0x7a, 0x10, 0x23, 0x95, 0x18, 0x00,
0x01, 0x00, 0x00, 0xff, 0xff, 0xa4, 0xed, 0x44, 0x02, 0x9e, 0x00, 0x00, 0x00,
}

View File

@ -1,15 +0,0 @@
syntax = "proto2";
service CAAChecker {
rpc ValidForIssuance(Check) returns (Result) {}
}
message Check {
optional string name = 1;
optional string issuerDomain = 2;
}
message Result {
optional bool present = 1;
optional bool valid = 2;
}

View File

@ -1,3 +0,0 @@
package caaChecker
//go:generate protoc --go_out=plugins=grpc:. caaChecker.proto

View File

@ -1,255 +0,0 @@
package main
import (
"flag"
"fmt"
"io/ioutil"
"strings"
"sync"
"github.com/jmhodges/clock"
"github.com/miekg/dns"
"golang.org/x/net/context"
grpcCodes "google.golang.org/grpc/codes"
"gopkg.in/yaml.v2"
"github.com/letsencrypt/boulder/bdns"
"github.com/letsencrypt/boulder/cmd"
pb "github.com/letsencrypt/boulder/cmd/caa-checker/proto"
bgrpc "github.com/letsencrypt/boulder/grpc"
"github.com/letsencrypt/boulder/metrics"
)
type caaCheckerServer struct {
resolver bdns.DNSResolver
stats metrics.Scope
}
// caaSet consists of filtered CAA records
type caaSet struct {
Issue []*dns.CAA
Issuewild []*dns.CAA
Iodef []*dns.CAA
Unknown []*dns.CAA
}
// returns true if any CAA records have unknown tag properties and are flagged critical.
func (caaSet caaSet) criticalUnknown() bool {
if len(caaSet.Unknown) > 0 {
for _, caaRecord := range caaSet.Unknown {
// The critical flag is the bit with significance 128. However, many CAA
// record users have misinterpreted the RFC and concluded that the bit
// with significance 1 is the critical bit. This is sufficiently
// widespread that that bit must reasonably be considered an alias for
// the critical bit. The remaining bits are 0/ignore as proscribed by the
// RFC.
if (caaRecord.Flag & (128 | 1)) != 0 {
return true
}
}
}
return false
}
// Filter CAA records by property
func newCAASet(CAAs []*dns.CAA) *caaSet {
var filtered caaSet
for _, caaRecord := range CAAs {
switch caaRecord.Tag {
case "issue":
filtered.Issue = append(filtered.Issue, caaRecord)
case "issuewild":
filtered.Issuewild = append(filtered.Issuewild, caaRecord)
case "iodef":
filtered.Iodef = append(filtered.Iodef, caaRecord)
default:
filtered.Unknown = append(filtered.Unknown, caaRecord)
}
}
return &filtered
}
func (ccs *caaCheckerServer) getCAASet(ctx context.Context, hostname string) (*caaSet, error) {
hostname = strings.TrimRight(hostname, ".")
labels := strings.Split(hostname, ".")
// See RFC 6844 "Certification Authority Processing" for pseudocode.
// Essentially: check CAA records for the FDQN to be issued, and all
// parent domains.
//
// The lookups are performed in parallel in order to avoid timing out
// the RPC call.
//
// We depend on our resolver to snap CNAME and DNAME records.
type result struct {
records []*dns.CAA
err error
}
results := make([]result, len(labels))
var wg sync.WaitGroup
for i := 0; i < len(labels); i++ {
// Start the concurrent DNS lookup.
wg.Add(1)
go func(name string, r *result) {
r.records, r.err = ccs.resolver.LookupCAA(ctx, name)
wg.Done()
}(strings.Join(labels[i:], "."), &results[i])
}
wg.Wait()
// Return the first result
for _, res := range results {
if res.err != nil {
return nil, res.err
}
if len(res.records) > 0 {
return newCAASet(res.records), nil
}
}
// no CAA records found
return nil, nil
}
// Given a CAA record, assume that the Value is in the issue/issuewild format,
// that is, a domain name with zero or more additional key-value parameters.
// Returns the domain name, which may be "" (unsatisfiable).
func extractIssuerDomain(caa *dns.CAA) string {
v := caa.Value
v = strings.Trim(v, " \t") // Value can start and end with whitespace.
idx := strings.IndexByte(v, ';')
if idx < 0 {
return v // no parameters; domain only
}
// Currently, ignore parameters. Unfortunately, the RFC makes no statement on
// whether any parameters are critical. Treat unknown parameters as
// non-critical.
return strings.Trim(v[0:idx], " \t")
}
func (ccs *caaCheckerServer) checkCAA(ctx context.Context, hostname string, issuer string) (present, valid bool, err error) {
hostname = strings.ToLower(hostname)
caaSet, err := ccs.getCAASet(ctx, hostname)
if err != nil {
return false, false, err
}
if caaSet == nil {
// No CAA records found, can issue
return false, true, nil
}
if caaSet.criticalUnknown() {
// Contains unknown critical directives.
ccs.stats.Inc("CCS.UnknownCritical", 1)
return true, false, nil
}
if len(caaSet.Unknown) > 0 {
ccs.stats.Inc("CCS.WithUnknownNoncritical", 1)
}
if len(caaSet.Issue) == 0 {
// Although CAA records exist, none of them pertain to issuance in this case.
// (e.g. there is only an issuewild directive, but we are checking for a
// non-wildcard identifier, or there is only an iodef or non-critical unknown
// directive.)
ccs.stats.Inc("CCS.CAA.NoneRelevant", 1)
return true, true, nil
}
// There are CAA records pertaining to issuance in our case. Note that this
// includes the case of the unsatisfiable CAA record value ";", used to
// prevent issuance by any CA under any circumstance.
//
// Our CAA identity must be found in the chosen checkSet.
for _, caa := range caaSet.Issue {
if extractIssuerDomain(caa) == issuer {
ccs.stats.Inc("CCS.CAA.Authorized", 1)
return true, true, nil
}
}
// The list of authorized issuers is non-empty, but we are not in it. Fail.
ccs.stats.Inc("CCS.CAA.Unauthorized", 1)
return true, false, nil
}
func (ccs *caaCheckerServer) ValidForIssuance(ctx context.Context, check *pb.Check) (*pb.Result, error) {
if check.Name == nil || check.IssuerDomain == nil {
return nil, bgrpc.CodedError(grpcCodes.InvalidArgument, "Both name and issuerDomain are required")
}
present, valid, err := ccs.checkCAA(ctx, *check.Name, *check.IssuerDomain)
if err != nil {
if err == context.DeadlineExceeded || err == context.Canceled {
return nil, bgrpc.CodedError(bgrpc.DNSQueryTimeout, err.Error())
}
if dnsErr, ok := err.(*bdns.DNSError); ok {
if dnsErr.Timeout() {
return nil, bgrpc.CodedError(bgrpc.DNSQueryTimeout, err.Error())
}
return nil, bgrpc.CodedError(bgrpc.DNSError, dnsErr.Error())
}
return nil, bgrpc.CodedError(bgrpc.DNSError, "server failure at resolver")
}
return &pb.Result{Present: &present, Valid: &valid}, nil
}
type config struct {
GRPC cmd.GRPCServerConfig
Statsd cmd.StatsdConfig
Syslog cmd.SyslogConfig
DebugAddr string `yaml:"debug-addr"`
DNSResolver string `yaml:"dns-resolver"`
DNSNetwork string `yaml:"dns-network"`
DNSTimeout cmd.ConfigDuration `yaml:"dns-timeout"`
CAASERVFAILExceptions string `yaml:"caa-servfail-exceptions"`
}
func main() {
configPath := flag.String("config", "config.yml", "Path to configuration file")
flag.Parse()
configBytes, err := ioutil.ReadFile(*configPath)
cmd.FailOnError(err, fmt.Sprintf("Failed to read configuration file from '%s'", *configPath))
var c config
err = yaml.Unmarshal(configBytes, &c)
cmd.FailOnError(err, fmt.Sprintf("Failed to parse configuration file from '%s'", *configPath))
stats, logger := cmd.StatsAndLogging(c.Statsd, c.Syslog)
scope := metrics.NewStatsdScope(stats, "CAAService")
defer logger.AuditPanic()
logger.Info(cmd.VersionString("CAA-Checker"))
caaSERVFAILExceptions, err := bdns.ReadHostList(c.CAASERVFAILExceptions)
cmd.FailOnError(err, "Couldn't read CAASERVFAILExceptions file")
resolver := bdns.NewDNSResolverImpl(
c.DNSTimeout.Duration,
[]string{c.DNSResolver},
caaSERVFAILExceptions,
scope,
clock.Default(),
5,
)
s, l, err := bgrpc.NewServer(&c.GRPC, scope)
cmd.FailOnError(err, "Failed to setup gRPC server")
ccs := &caaCheckerServer{resolver, scope}
pb.RegisterCAACheckerServer(s, ccs)
go cmd.CatchSignals(logger, s.GracefulStop)
go cmd.DebugServer(c.DebugAddr)
err = s.Serve(l)
cmd.FailOnError(err, "gRPC service failed")
}

View File

@ -1,84 +0,0 @@
package main
import (
"testing"
"golang.org/x/net/context"
"google.golang.org/grpc"
"github.com/letsencrypt/boulder/bdns"
pb "github.com/letsencrypt/boulder/cmd/caa-checker/proto"
bgrpc "github.com/letsencrypt/boulder/grpc"
"github.com/letsencrypt/boulder/metrics"
"github.com/letsencrypt/boulder/test"
)
func TestChecking(t *testing.T) {
type CAATest struct {
Domain string
Present bool
Valid bool
}
tests := []CAATest{
// Reserved
{"reserved.com", true, false},
// Critical
{"critical.com", true, false},
{"nx.critical.com", true, false},
// Good (absent)
{"absent.com", false, true},
{"example.co.uk", false, true},
// Good (present)
{"present.com", true, true},
{"present.servfail.com", true, true},
// Good (multiple critical, one matching)
{"multi-crit-present.com", true, true},
// Bad (unknown critical)
{"unknown-critical.com", true, false},
{"unknown-critical2.com", true, false},
// Good (unknown noncritical, no issue/issuewild records)
{"unknown-noncritical.com", true, true},
// Good (issue record with unknown parameters)
{"present-with-parameter.com", true, true},
// Bad (unsatisfiable issue record)
{"unsatisfiable.com", true, false},
}
stats := metrics.NewNoopScope()
ccs := &caaCheckerServer{&bdns.MockDNSResolver{}, stats}
issuerDomain := "letsencrypt.org"
ctx := context.Background()
for _, caaTest := range tests {
result, err := ccs.ValidForIssuance(ctx, &pb.Check{Name: &caaTest.Domain, IssuerDomain: &issuerDomain})
if err != nil {
t.Errorf("CheckCAARecords error for %s: %s", caaTest.Domain, err)
}
if *result.Present != caaTest.Present {
t.Errorf("CheckCAARecords presence mismatch for %s: got %t expected %t", caaTest.Domain, *result.Present, caaTest.Present)
}
if *result.Valid != caaTest.Valid {
t.Errorf("CheckCAARecords presence mismatch for %s: got %t expected %t", caaTest.Domain, *result.Valid, caaTest.Valid)
}
}
servfail := "servfail.com"
servfailPresent := "servfail.present.com"
result, err := ccs.ValidForIssuance(ctx, &pb.Check{Name: &servfail, IssuerDomain: &issuerDomain})
test.AssertError(t, err, "servfail.com")
test.Assert(t, result == nil, "result should be nil")
test.AssertEquals(t, grpc.Code(err), bgrpc.DNSError)
result, err = ccs.ValidForIssuance(ctx, &pb.Check{Name: &servfailPresent, IssuerDomain: &issuerDomain})
test.AssertError(t, err, "servfail.present.com")
test.Assert(t, result == nil, "result should be nil")
test.AssertEquals(t, grpc.Code(err), bgrpc.DNSError)
timeout := "caa-timeout.com"
result, err = ccs.ValidForIssuance(ctx, &pb.Check{Name: &timeout, IssuerDomain: &issuerDomain})
test.AssertError(t, err, "timeout.com")
test.Assert(t, result == nil, "result should be nil")
test.AssertEquals(t, grpc.Code(err), bgrpc.DNSQueryTimeout)
}

View File

@ -1,42 +0,0 @@
package main
import (
"flag"
"fmt"
"os"
"golang.org/x/net/context"
"github.com/letsencrypt/boulder/cmd"
pb "github.com/letsencrypt/boulder/cmd/caa-checker/proto"
bgrpc "github.com/letsencrypt/boulder/grpc"
"github.com/letsencrypt/boulder/metrics"
)
func main() {
addr := flag.String("addr", "boulder:9090", "CCS address")
name := flag.String("name", "", "Name to check")
issuer := flag.String("issuerDomain", "", "Issuer domain to check against")
flag.Parse()
// Set up a connection to the server.
conn, err := bgrpc.ClientSetup(&cmd.GRPCClientConfig{
ServerAddresses: []string{*addr},
ServerIssuerPath: "test/grpc-creds/minica.pem",
ClientCertificatePath: "test/grpc-creds/boulder-client/cert.pem",
ClientKeyPath: "test/grpc-creds/boulder-client/key.pem",
}, metrics.NewNoopScope())
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to setup client connection: %s\n", err)
os.Exit(1)
}
defer conn.Close()
c := pb.NewCAACheckerClient(conn)
r, err := c.ValidForIssuance(context.Background(), &pb.Check{Name: name, IssuerDomain: issuer})
if err != nil {
fmt.Fprintf(os.Stderr, "ValidForIssuance call failed: %s\n", err)
os.Exit(1)
}
fmt.Fprintf(os.Stderr, "%s valid for issuance: %t (records present: %t)\n", *name, *r.Valid, *r.Present)
}

View File

@ -1,15 +0,0 @@
debug-addr: 127.0.0.1:8011
dns-resolver: 127.0.0.1:8053
dns-timeout: 10s
statsd-server: 127.0.0.1:8125
statsd-prefix: boulder
grpc:
address: boulder:9090
server-certificate-path: test/grpc-creds/boulder-server/cert.pem
server-key-path: test/grpc-creds/boulder-server/key.pem
client-issuer-path: test/grpc-creds/minica.pem
client-names:
- boulder-client

View File

@ -11,18 +11,6 @@
"maxConcurrentRPCServerRequests": 16,
"dnsTries": 3,
"issuerDomain": "happy-hacker-ca.invalid",
"caaService": {
"serverAddresses": ["boulder:9090"],
"serverIssuerPath": "test/grpc-creds/minica.pem",
"clientCertificatePath": "test/grpc-creds/boulder-client/cert.pem",
"clientKeyPath": "test/grpc-creds/boulder-client/key.pem"
},
"caaPublicResolver": {
"timeout": "10s",
"keepalive": "30s",
"maxFailures": 1,
"proxies": []
},
"grpc": {
"address": "boulder:9092",
"clientIssuerPath": "test/grpc-creds/minica.pem",

View File

@ -56,8 +56,7 @@ def start(race_detection):
'ocsp-responder --config %s' % os.path.join(default_config_dir, "ocsp-responder.json"),
'ct-test-srv',
'dns-test-srv',
'mail-test-srv --closeFirst 5',
'caa-checker --config cmd/caa-checker/test-config.yml'
'mail-test-srv --closeFirst 5'
]
if not install(race_detection):
return False

View File

@ -35,7 +35,6 @@ func TestIsSafeDomain(t *testing.T) {
sbc,
nil,
nil,
nil,
"user agent 1.0",
"letsencrypt.org",
stats,
@ -86,7 +85,6 @@ func TestAllowNilInIsSafeDomain(t *testing.T) {
nil,
nil,
nil,
nil,
"user agent 1.0",
"letsencrypt.org",
stats,

View File

@ -25,12 +25,9 @@ import (
"github.com/letsencrypt/boulder/cdr"
"github.com/letsencrypt/boulder/cmd"
"github.com/letsencrypt/boulder/core"
bgrpc "github.com/letsencrypt/boulder/grpc"
blog "github.com/letsencrypt/boulder/log"
"github.com/letsencrypt/boulder/metrics"
"github.com/letsencrypt/boulder/probs"
caaPB "github.com/letsencrypt/boulder/cmd/caa-checker/proto"
)
const (
@ -56,7 +53,6 @@ type ValidationAuthorityImpl struct {
userAgent string
stats metrics.Scope
clk clock.Clock
caaClient caaPB.CAACheckerClient
caaDR *cdr.CAADistributedResolver
}
@ -64,7 +60,6 @@ type ValidationAuthorityImpl struct {
func NewValidationAuthorityImpl(
pc *cmd.PortConfig,
sbc SafeBrowsing,
caaClient caaPB.CAACheckerClient,
cdrClient *cdr.CAADistributedResolver,
resolver bdns.DNSResolver,
userAgent string,
@ -84,7 +79,6 @@ func NewValidationAuthorityImpl(
userAgent: userAgent,
stats: stats,
clk: clk,
caaClient: caaClient,
caaDR: cdrClient,
}
}
@ -447,12 +441,7 @@ func (va *ValidationAuthorityImpl) validateDNS01(ctx context.Context, identifier
}
func (va *ValidationAuthorityImpl) checkCAA(ctx context.Context, identifier core.AcmeIdentifier) *probs.ProblemDetails {
var prob *probs.ProblemDetails
if va.caaClient != nil {
prob = va.checkCAAService(ctx, identifier)
} else {
prob = va.checkCAAInternal(ctx, identifier)
}
prob := va.checkCAAInternal(ctx, identifier)
if va.caaDR != nil && prob != nil && prob.Type == probs.ConnectionProblem {
return va.checkGPDNS(ctx, identifier)
}
@ -476,31 +465,6 @@ func (va *ValidationAuthorityImpl) checkCAAInternal(ctx context.Context, ident c
return nil
}
func (va *ValidationAuthorityImpl) checkCAAService(ctx context.Context, ident core.AcmeIdentifier) *probs.ProblemDetails {
r, err := va.caaClient.ValidForIssuance(ctx, &caaPB.Check{Name: &ident.Value, IssuerDomain: &va.issuerDomain})
if err != nil {
va.log.Warning(fmt.Sprintf("grpc: error calling ValidForIssuance: %s", err))
return bgrpc.ErrorToProb(err)
}
if r.Present == nil || r.Valid == nil {
va.log.AuditErr("gRPC: communication failure: response is missing fields")
return &probs.ProblemDetails{
Type: probs.ServerInternalProblem,
Detail: "Internal communication failure",
}
}
va.log.AuditInfo(fmt.Sprintf(
"Checked CAA records for %s, [Present: %t, Valid for issuance: %t]",
ident.Value,
*r.Present,
*r.Valid,
))
if !*r.Valid {
return probs.ConnectionFailure(fmt.Sprintf("CAA record for %s prevents issuance", ident.Value))
}
return nil
}
func (va *ValidationAuthorityImpl) checkGPDNS(ctx context.Context, identifier core.AcmeIdentifier) *probs.ProblemDetails {
results := va.parallelCAALookup(ctx, identifier.Value, va.caaDR.LookupCAA)
set, err := parseResults(results)

View File

@ -850,7 +850,6 @@ func setup() (*ValidationAuthorityImpl, *mocks.Statter, *blog.Mock) {
&cmd.PortConfig{},
nil,
nil,
nil,
&bdns.MockDNSResolver{},
"user agent 1.0",
"letsencrypt.org",
@ -874,7 +873,6 @@ func TestCheckCAAFallback(t *testing.T) {
va := NewValidationAuthorityImpl(
&cmd.PortConfig{},
nil,
nil,
caaDR,
&bdns.MockDNSResolver{},
"user agent 1.0",