@@ -22,7 +22,7 @@ import (
2222 "github.com/miekg/dns"
2323 "github.com/prometheus/client_golang/prometheus"
2424
25- "github.com/letsencrypt/boulder/blog "
25+ blog "github.com/letsencrypt/boulder/log "
2626 "github.com/letsencrypt/boulder/metrics"
2727 "github.com/letsencrypt/boulder/test"
2828)
@@ -283,7 +283,7 @@ func TestDNSNoServers(t *testing.T) {
283283 staticProvider , err := NewStaticProvider ([]string {})
284284 test .AssertNotError (t , err , "Got error creating StaticProvider" )
285285
286- obj := New (time .Hour , staticProvider , metrics .NoopRegisterer , clock .NewFake (), 1 , "" , blog .NewMock (), tlsConfig )
286+ obj := New (time .Hour , staticProvider , metrics .NoopRegisterer , clock .NewFake (), 1 , "" , blog .UseMock (), tlsConfig )
287287
288288 _ , resolver , err := obj .LookupA (context .Background (), "letsencrypt.org" )
289289 test .AssertEquals (t , resolver , "" )
@@ -306,7 +306,7 @@ func TestDNSOneServer(t *testing.T) {
306306 staticProvider , err := NewStaticProvider ([]string {dnsLoopbackAddr })
307307 test .AssertNotError (t , err , "Got error creating StaticProvider" )
308308
309- obj := New (time .Second * 10 , staticProvider , metrics .NoopRegisterer , clock .NewFake (), 1 , "" , blog .NewMock (), tlsConfig )
309+ obj := New (time .Second * 10 , staticProvider , metrics .NoopRegisterer , clock .NewFake (), 1 , "" , blog .UseMock (), tlsConfig )
310310
311311 _ , resolver , err := obj .LookupA (context .Background (), "letsencrypt.org" )
312312 test .AssertNotError (t , err , "No message" )
@@ -317,7 +317,7 @@ func TestDNSDuplicateServers(t *testing.T) {
317317 staticProvider , err := NewStaticProvider ([]string {dnsLoopbackAddr , dnsLoopbackAddr })
318318 test .AssertNotError (t , err , "Got error creating StaticProvider" )
319319
320- obj := New (time .Second * 10 , staticProvider , metrics .NoopRegisterer , clock .NewFake (), 1 , "" , blog .NewMock (), tlsConfig )
320+ obj := New (time .Second * 10 , staticProvider , metrics .NoopRegisterer , clock .NewFake (), 1 , "" , blog .UseMock (), tlsConfig )
321321
322322 _ , resolver , err := obj .LookupA (context .Background (), "letsencrypt.org" )
323323 test .AssertNotError (t , err , "No message" )
@@ -328,7 +328,7 @@ func TestDNSServFail(t *testing.T) {
328328 staticProvider , err := NewStaticProvider ([]string {dnsLoopbackAddr })
329329 test .AssertNotError (t , err , "Got error creating StaticProvider" )
330330
331- obj := New (time .Second * 10 , staticProvider , metrics .NoopRegisterer , clock .NewFake (), 1 , "" , blog .NewMock (), tlsConfig )
331+ obj := New (time .Second * 10 , staticProvider , metrics .NoopRegisterer , clock .NewFake (), 1 , "" , blog .UseMock (), tlsConfig )
332332 bad := "servfail.com"
333333
334334 _ , _ , err = obj .LookupTXT (context .Background (), "servfail.com" )
@@ -348,7 +348,7 @@ func TestDNSLookupTXT(t *testing.T) {
348348 staticProvider , err := NewStaticProvider ([]string {dnsLoopbackAddr })
349349 test .AssertNotError (t , err , "Got error creating StaticProvider" )
350350
351- obj := New (time .Second * 10 , staticProvider , metrics .NoopRegisterer , clock .NewFake (), 1 , "" , blog .NewMock (), tlsConfig )
351+ obj := New (time .Second * 10 , staticProvider , metrics .NoopRegisterer , clock .NewFake (), 1 , "" , blog .UseMock (), tlsConfig )
352352
353353 _ , _ , err = obj .LookupTXT (context .Background (), "letsencrypt.org" )
354354 test .AssertNotError (t , err , "No message" )
@@ -363,7 +363,7 @@ func TestDNSLookupA(t *testing.T) {
363363 staticProvider , err := NewStaticProvider ([]string {dnsLoopbackAddr })
364364 test .AssertNotError (t , err , "Got error creating StaticProvider" )
365365
366- obj := New (time .Second * 10 , staticProvider , metrics .NoopRegisterer , clock .NewFake (), 1 , "" , blog .NewMock (), tlsConfig )
366+ obj := New (time .Second * 10 , staticProvider , metrics .NoopRegisterer , clock .NewFake (), 1 , "" , blog .UseMock (), tlsConfig )
367367
368368 for _ , tc := range []struct {
369369 name string
@@ -448,7 +448,7 @@ func TestDNSLookupAAAA(t *testing.T) {
448448 staticProvider , err := NewStaticProvider ([]string {dnsLoopbackAddr })
449449 test .AssertNotError (t , err , "Got error creating StaticProvider" )
450450
451- obj := New (time .Second * 10 , staticProvider , metrics .NoopRegisterer , clock .NewFake (), 1 , "" , blog .NewMock (), tlsConfig )
451+ obj := New (time .Second * 10 , staticProvider , metrics .NoopRegisterer , clock .NewFake (), 1 , "" , blog .UseMock (), tlsConfig )
452452
453453 for _ , tc := range []struct {
454454 name string
@@ -533,7 +533,7 @@ func TestDNSNXDOMAIN(t *testing.T) {
533533 staticProvider , err := NewStaticProvider ([]string {dnsLoopbackAddr })
534534 test .AssertNotError (t , err , "Got error creating StaticProvider" )
535535
536- obj := New (time .Second * 10 , staticProvider , metrics .NoopRegisterer , clock .NewFake (), 1 , "" , blog .NewMock (), tlsConfig )
536+ obj := New (time .Second * 10 , staticProvider , metrics .NoopRegisterer , clock .NewFake (), 1 , "" , blog .UseMock (), tlsConfig )
537537 hostname := "nxdomain.letsencrypt.org"
538538
539539 _ , _ , err = obj .LookupA (context .Background (), hostname )
@@ -543,15 +543,15 @@ func TestDNSNXDOMAIN(t *testing.T) {
543543 test .AssertContains (t , err .Error (), "NXDOMAIN looking up AAAA for" )
544544
545545 _ , _ , err = obj .LookupTXT (context .Background (), hostname )
546- expected := Error {dns .TypeTXT , hostname , nil , dns .RcodeNameError , nil }
546+ expected := Error {dns .TypeTXT , hostname , nil , dns .RcodeNameError , nil , false }
547547 test .AssertDeepEquals (t , err , expected )
548548}
549549
550550func TestDNSLookupCAA (t * testing.T ) {
551551 staticProvider , err := NewStaticProvider ([]string {dnsLoopbackAddr })
552552 test .AssertNotError (t , err , "Got error creating StaticProvider" )
553553
554- obj := New (time .Second * 10 , staticProvider , metrics .NoopRegisterer , clock .NewFake (), 1 , "" , blog .NewMock (), tlsConfig )
554+ obj := New (time .Second * 10 , staticProvider , metrics .NoopRegisterer , clock .NewFake (), 1 , "" , blog .UseMock (), tlsConfig )
555555 removeIDExp := regexp .MustCompile (" id: [[:digit:]]+" )
556556
557557 caas , resolver , err := obj .LookupCAA (context .Background (), "bracewel.net" )
@@ -759,7 +759,7 @@ func TestRetry(t *testing.T) {
759759 staticProvider , err := NewStaticProvider ([]string {dnsLoopbackAddr })
760760 test .AssertNotError (t , err , "Got error creating StaticProvider" )
761761
762- testClient := New (time .Second * 10 , staticProvider , metrics .NoopRegisterer , clock .NewFake (), tc .maxTries , "" , blog .NewMock (), tlsConfig )
762+ testClient := New (time .Second * 10 , staticProvider , metrics .NoopRegisterer , clock .NewFake (), tc .maxTries , "" , blog .UseMock (), tlsConfig )
763763 dr := testClient .(* impl )
764764 dr .exchanger = tc .te
765765 _ , _ , err = dr .LookupTXT (context .Background (), "example.com" )
@@ -796,7 +796,7 @@ func TestRetryMetrics(t *testing.T) {
796796 // context itself being cancelled. It should never see the error in the
797797 // testExchanger, because the fake exchanger (like the real http package)
798798 // checks for cancellation before doing any work.
799- testClient := New (time .Second * 10 , staticProvider , metrics .NoopRegisterer , clock .NewFake (), 3 , "" , blog .NewMock (), tlsConfig )
799+ testClient := New (time .Second * 10 , staticProvider , metrics .NoopRegisterer , clock .NewFake (), 3 , "" , blog .UseMock (), tlsConfig )
800800 dr := testClient .(* impl )
801801 dr .exchanger = & testExchanger {errs : []error {errors .New ("oops" )}}
802802 ctx , cancel := context .WithCancel (t .Context ())
@@ -815,7 +815,7 @@ func TestRetryMetrics(t *testing.T) {
815815
816816 // Same as above, except rather than cancelling the context ourselves, we
817817 // let the go runtime cancel it as a result of a deadline in the past.
818- testClient = New (time .Second * 10 , staticProvider , metrics .NoopRegisterer , clock .NewFake (), 3 , "" , blog .NewMock (), tlsConfig )
818+ testClient = New (time .Second * 10 , staticProvider , metrics .NoopRegisterer , clock .NewFake (), 3 , "" , blog .UseMock (), tlsConfig )
819819 dr = testClient .(* impl )
820820 dr .exchanger = & testExchanger {errs : []error {errors .New ("oops" )}}
821821 ctx , cancel = context .WithTimeout (t .Context (), - 10 * time .Hour )
@@ -883,7 +883,7 @@ func TestRotateServerOnErr(t *testing.T) {
883883 test .AssertNotError (t , err , "Got error creating StaticProvider" )
884884
885885 maxTries := 5
886- client := New (time .Second * 10 , staticProvider , metrics .NoopRegisterer , clock .NewFake (), maxTries , "" , blog .NewMock (), tlsConfig )
886+ client := New (time .Second * 10 , staticProvider , metrics .NoopRegisterer , clock .NewFake (), maxTries , "" , blog .UseMock (), tlsConfig )
887887
888888 // Configure a mock exchanger that will always return a retryable error for
889889 // servers A and B. This will force server "[2606:4700:4700::1111]:53" to do
@@ -948,7 +948,7 @@ func TestDOHMetric(t *testing.T) {
948948 staticProvider , err := NewStaticProvider ([]string {dnsLoopbackAddr })
949949 test .AssertNotError (t , err , "Got error creating StaticProvider" )
950950
951- testClient := New (time .Second * 11 , staticProvider , metrics .NoopRegisterer , clock .NewFake (), 0 , "" , blog .NewMock (), tlsConfig )
951+ testClient := New (time .Second * 11 , staticProvider , metrics .NoopRegisterer , clock .NewFake (), 0 , "" , blog .UseMock (), tlsConfig )
952952 resolver := testClient .(* impl )
953953 resolver .exchanger = & dohAlwaysRetryExchanger {err : & url.Error {Op : "read" , Err : testTimeoutError (true )}}
954954
@@ -961,3 +961,39 @@ func TestDOHMetric(t *testing.T) {
961961 // Now, we should count 1 "out of retries" errors.
962962 test .AssertMetricWithLabelsEquals (t , resolver .timeoutCounter , prometheus.Labels {"qtype" : "None" , "type" : "out of retries" , "resolver" : "127.0.0.1" , "isTLD" : "false" }, 1 )
963963}
964+
965+ // truncatedExchanger returns a truncated (TC bit set) response with the given
966+ // Rcode. If a caller failed to check for truncation on a CAA query, it would
967+ // otherwise be fooled into trusting an incomplete set of records, potentially
968+ // missing an issue record that would forbid issuance.
969+ type truncatedExchanger struct {
970+ rcode int
971+ }
972+
973+ func (te truncatedExchanger ) ExchangeContext (_ context.Context , m * dns.Msg , _ string ) (* dns.Msg , time.Duration , error ) {
974+ resp := new (dns.Msg )
975+ resp .SetReply (m )
976+ resp .Rcode = te .rcode
977+ resp .Truncated = true
978+ return resp , time .Millisecond , nil
979+ }
980+
981+ func TestDNSCAATruncatedResponse (t * testing.T ) {
982+ staticProvider , err := NewStaticProvider ([]string {dnsLoopbackAddr })
983+ test .AssertNotError (t , err , "Got error creating StaticProvider" )
984+
985+ client := New (time .Second * 10 , staticProvider , metrics .NoopRegisterer , clock .NewFake (), 1 , "" , blog .NewMock (), tlsConfig )
986+ client .(* impl ).exchanger = truncatedExchanger {rcode : dns .RcodeSuccess }
987+
988+ _ , _ , err = client .LookupCAA (context .Background (), "example.com" )
989+ test .AssertError (t , err , "expected error for truncated CAA response" )
990+ test .AssertContains (t , err .Error (), "response was truncated" )
991+
992+ // A truncated NXDOMAIN response must not be treated as the usual
993+ // NXDOMAIN-as-empty-CAA-set special case for non-TLD names: we can't
994+ // trust an incomplete response to accurately reflect an NXDOMAIN.
995+ client .(* impl ).exchanger = truncatedExchanger {rcode : dns .RcodeNameError }
996+ _ , _ , err = client .LookupCAA (context .Background (), "nonexistent.letsencrypt.org" )
997+ test .AssertError (t , err , "expected error for truncated CAA response, even when NXDOMAIN-shaped" )
998+ test .AssertContains (t , err .Error (), "response was truncated" )
999+ }
0 commit comments