Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
72a2ea5
ra: call MTCA when profile indicates MTC (#8781)
jsha Jun 12, 2026
d8ea179
crl-storer: use IfMatch to do a compare-and-swap when uploading (#8791)
aarongable Jun 12, 2026
0e4a75a
mtpublisher: Add skeleton that pushes dummy cosignatures (#8793)
beautifulentropy Jun 12, 2026
187b602
Add int-type Authz ID proto fields alongside any string-type proto fi…
ezekiel Jun 15, 2026
eedf942
wfe: block accounts from YAML config file (#8797)
jsha Jun 15, 2026
a5ecaf9
cert-checker: fix logging & push metrics (#8763)
lenaunderwood22 Jun 15, 2026
5e88bab
wfe: fix test comment (#8798)
jsha Jun 15, 2026
bd42fe1
wfe: add MaxCumulativeIdentifierLength (#8804)
jsha Jun 17, 2026
9f0086c
test: give more retries to bvitess health checks (#8805)
jsha Jun 17, 2026
664bc74
Allow dependabot to manage container versions in docker-compose file …
pgporada Jun 17, 2026
b72b108
ci: build gotip into boulder-tools (#8801)
jsha Jun 17, 2026
57214b4
mtpki: use ML-DSA (#8803)
jsha Jun 17, 2026
703c483
Dependabot docker-compose should group changes into a single PR (#8811)
pgporada Jun 18, 2026
65367a4
Update zlint to just past v3.7.1 (#8800)
aarongable Jun 18, 2026
281a820
build(deps): bump github/codeql-action from 4.36.0 to 4.36.2 (#8810)
dependabot[bot] Jun 18, 2026
1d93ceb
build(deps): bump golang.org/x/time from 0.11.0 to 0.15.0 (#8772)
dependabot[bot] Jun 22, 2026
cddf16d
build(deps): bump jaegertracing/all-in-one from 1.50 to 1.76.0 (#8809)
dependabot[bot] Jun 22, 2026
3b540a9
build(deps): bump the aws group across 1 directory with 4 updates (#8…
dependabot[bot] Jun 22, 2026
f9e80fb
dependencies: Update go-redis from v9.10.0 to v9.20.1 (#8815)
beautifulentropy Jun 22, 2026
abfceb5
Replace log package with fully slog-based system (#8606)
aarongable Jun 29, 2026
57551d1
ceremony: defer closing filehandle in writeFile (#8825)
pgporada Jun 29, 2026
aa99d7c
trees/cosigned: Add cosigned.Message (#8819)
jsha Jun 30, 2026
cee9fc6
admin: close files after reading (#8835)
aarongable Jul 1, 2026
12aa435
Drastically simplify changes to verify.go
aarongable Jul 3, 2026
6ca2282
Merge branch main
aarongable Jul 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
19 changes: 18 additions & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,25 @@ updates:
default-days: 30
- package-ecosystem: "github-actions"
directory: "/"
schedule:
schedule:
interval: monthly
open-pull-requests-limit: 1
cooldown:
default-days: 7
- package-ecosystem: "docker-compose"
directory: "/"
schedule:
interval: "weekly"
day: "wednesday"
open-pull-requests-limit: 1
cooldown:
default-days: 7
groups:
docker-compose:
patterns:
- "*"
allow:
- dependency-name: "ghcr.io/pkimetal/pkimetal"
- dependency-name: "jaegertracing/all-in-one"
- dependency-name: "minio/minio"
- dependency-name: "minio/mc"
4 changes: 2 additions & 2 deletions .github/workflows/boulder-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
matrix:
# Add additional docker image tags here and all tests will be run with the additional image.
BOULDER_TOOLS_TAG:
- go1.26.3_2026-05-22
- go1.26.3_2026-06-15
# Tests command definitions. Use the entire "docker compose" command you want to run.
tests:
# Run ./test.sh --help for a description of each of the flags.
Expand Down Expand Up @@ -66,7 +66,7 @@ jobs:
# use in tests. It will be set appropriately for each tag in the list
# defined in the matrix.
BOULDER_TOOLS_TAG: ${{ matrix.BOULDER_TOOLS_TAG }}
BOULDER_VTCOMBOSERVER_TAG: vitessv23.0.0_2026-03-05
BOULDER_VTCOMBOSERVER_TAG: vitessv23.0.0_2026-06-09

# Sequence of tasks that will be executed as part of the job.
steps:
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ jobs:
with:
persist-credentials: false
- name: Initialize CodeQL
uses: github/codeql-action/init@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0
uses: github/codeql-action/init@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2
- name: Autobuild
uses: github/codeql-action/autobuild@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0
uses: github/codeql-action/autobuild@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0
uses: github/codeql-action/analyze@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ test/secrets/badkeyrevoker_dburl
test/secrets/cert_checker_dburl
test/secrets/incidents_dburl
test/secrets/incidents_admin_dburl
test/secrets/mtpublisher_dburl
test/secrets/revoker_dburl
test/secrets/sa_dburl
test/secrets/sa_ro_dburl
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ VERSION ?= 1.0.0
EPOCH ?= 1
MAINTAINER ?= "Community"

GO ?= go

# TODO(#8410): Remove pardot-test-srv when we've fully migrated to
# salesforce-test-srv.
CMDS = admin boulder ceremony ct-test-srv salesforce-test-srv pardot-test-srv chall-test-srv zendesk-test-srv
Expand Down Expand Up @@ -44,7 +46,7 @@ bin/pardot-test-srv: bin/salesforce-test-srv

build_cmds: | $(OBJDIR)
echo $(OBJECTS)
GOBIN=$(OBJDIR) go install -mod=vendor $(GO_BUILD_FLAGS) ./...
GOBIN=$(OBJDIR) $(GO) install -mod=vendor $(GO_BUILD_FLAGS) ./...

# Building a .deb requires `fpm` from https://github.com/jordansissel/fpm
# which you can install with `gem install fpm`.
Expand Down
10 changes: 8 additions & 2 deletions bdns/dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"errors"
"fmt"
"io"
"log/slog"
"net"
"net/http"
"strconv"
Expand All @@ -17,7 +18,7 @@ import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"

blog "github.com/letsencrypt/boulder/log"
"github.com/letsencrypt/boulder/blog"
"github.com/letsencrypt/boulder/metrics"
)

Expand Down Expand Up @@ -226,7 +227,12 @@ func (c *impl) exchangeOne(ctx context.Context, hostname string, qtype uint16) (
}).Observe(rtt.Seconds())

if err != nil {
c.log.Infof("logDNSError chosenServer=[%s] hostname=[%s] queryType=[%s] err=[%s]", chosenServer, hostname, qtypeStr, err)
c.log.Info(ctx, "logDNSError",
slog.String("chosenServer", chosenServer),
slog.String("hostname", hostname),
slog.String("qtype", qtypeStr),
blog.Error(err),
)

// Check if the error is a network timeout, rather than a local context
// timeout. If it is, retry instead of giving up.
Expand Down
30 changes: 15 additions & 15 deletions bdns/dns_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
"github.com/miekg/dns"
"github.com/prometheus/client_golang/prometheus"

blog "github.com/letsencrypt/boulder/log"
"github.com/letsencrypt/boulder/blog"
"github.com/letsencrypt/boulder/metrics"
"github.com/letsencrypt/boulder/test"
)
Expand Down Expand Up @@ -283,7 +283,7 @@ func TestDNSNoServers(t *testing.T) {
staticProvider, err := NewStaticProvider([]string{})
test.AssertNotError(t, err, "Got error creating StaticProvider")

obj := New(time.Hour, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 1, "", blog.UseMock(), tlsConfig)
obj := New(time.Hour, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 1, "", blog.NewMock(), tlsConfig)

_, resolver, err := obj.LookupA(context.Background(), "letsencrypt.org")
test.AssertEquals(t, resolver, "")
Expand All @@ -306,7 +306,7 @@ func TestDNSOneServer(t *testing.T) {
staticProvider, err := NewStaticProvider([]string{dnsLoopbackAddr})
test.AssertNotError(t, err, "Got error creating StaticProvider")

obj := New(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 1, "", blog.UseMock(), tlsConfig)
obj := New(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 1, "", blog.NewMock(), tlsConfig)

_, resolver, err := obj.LookupA(context.Background(), "letsencrypt.org")
test.AssertNotError(t, err, "No message")
Expand All @@ -317,7 +317,7 @@ func TestDNSDuplicateServers(t *testing.T) {
staticProvider, err := NewStaticProvider([]string{dnsLoopbackAddr, dnsLoopbackAddr})
test.AssertNotError(t, err, "Got error creating StaticProvider")

obj := New(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 1, "", blog.UseMock(), tlsConfig)
obj := New(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 1, "", blog.NewMock(), tlsConfig)

_, resolver, err := obj.LookupA(context.Background(), "letsencrypt.org")
test.AssertNotError(t, err, "No message")
Expand All @@ -328,7 +328,7 @@ func TestDNSServFail(t *testing.T) {
staticProvider, err := NewStaticProvider([]string{dnsLoopbackAddr})
test.AssertNotError(t, err, "Got error creating StaticProvider")

obj := New(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 1, "", blog.UseMock(), tlsConfig)
obj := New(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 1, "", blog.NewMock(), tlsConfig)
bad := "servfail.com"

_, _, err = obj.LookupTXT(context.Background(), "servfail.com")
Expand All @@ -348,7 +348,7 @@ func TestDNSLookupTXT(t *testing.T) {
staticProvider, err := NewStaticProvider([]string{dnsLoopbackAddr})
test.AssertNotError(t, err, "Got error creating StaticProvider")

obj := New(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 1, "", blog.UseMock(), tlsConfig)
obj := New(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 1, "", blog.NewMock(), tlsConfig)

_, _, err = obj.LookupTXT(context.Background(), "letsencrypt.org")
test.AssertNotError(t, err, "No message")
Expand All @@ -363,7 +363,7 @@ func TestDNSLookupA(t *testing.T) {
staticProvider, err := NewStaticProvider([]string{dnsLoopbackAddr})
test.AssertNotError(t, err, "Got error creating StaticProvider")

obj := New(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 1, "", blog.UseMock(), tlsConfig)
obj := New(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 1, "", blog.NewMock(), tlsConfig)

for _, tc := range []struct {
name string
Expand Down Expand Up @@ -448,7 +448,7 @@ func TestDNSLookupAAAA(t *testing.T) {
staticProvider, err := NewStaticProvider([]string{dnsLoopbackAddr})
test.AssertNotError(t, err, "Got error creating StaticProvider")

obj := New(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 1, "", blog.UseMock(), tlsConfig)
obj := New(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 1, "", blog.NewMock(), tlsConfig)

for _, tc := range []struct {
name string
Expand Down Expand Up @@ -533,7 +533,7 @@ func TestDNSNXDOMAIN(t *testing.T) {
staticProvider, err := NewStaticProvider([]string{dnsLoopbackAddr})
test.AssertNotError(t, err, "Got error creating StaticProvider")

obj := New(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 1, "", blog.UseMock(), tlsConfig)
obj := New(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 1, "", blog.NewMock(), tlsConfig)
hostname := "nxdomain.letsencrypt.org"

_, _, err = obj.LookupA(context.Background(), hostname)
Expand All @@ -551,7 +551,7 @@ func TestDNSLookupCAA(t *testing.T) {
staticProvider, err := NewStaticProvider([]string{dnsLoopbackAddr})
test.AssertNotError(t, err, "Got error creating StaticProvider")

obj := New(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 1, "", blog.UseMock(), tlsConfig)
obj := New(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 1, "", blog.NewMock(), tlsConfig)
removeIDExp := regexp.MustCompile(" id: [[:digit:]]+")

caas, resolver, err := obj.LookupCAA(context.Background(), "bracewel.net")
Expand Down Expand Up @@ -759,7 +759,7 @@ func TestRetry(t *testing.T) {
staticProvider, err := NewStaticProvider([]string{dnsLoopbackAddr})
test.AssertNotError(t, err, "Got error creating StaticProvider")

testClient := New(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), tc.maxTries, "", blog.UseMock(), tlsConfig)
testClient := New(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), tc.maxTries, "", blog.NewMock(), tlsConfig)
dr := testClient.(*impl)
dr.exchanger = tc.te
_, _, err = dr.LookupTXT(context.Background(), "example.com")
Expand Down Expand Up @@ -796,7 +796,7 @@ func TestRetryMetrics(t *testing.T) {
// context itself being cancelled. It should never see the error in the
// testExchanger, because the fake exchanger (like the real http package)
// checks for cancellation before doing any work.
testClient := New(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 3, "", blog.UseMock(), tlsConfig)
testClient := New(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 3, "", blog.NewMock(), tlsConfig)
dr := testClient.(*impl)
dr.exchanger = &testExchanger{errs: []error{errors.New("oops")}}
ctx, cancel := context.WithCancel(t.Context())
Expand All @@ -815,7 +815,7 @@ func TestRetryMetrics(t *testing.T) {

// Same as above, except rather than cancelling the context ourselves, we
// let the go runtime cancel it as a result of a deadline in the past.
testClient = New(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 3, "", blog.UseMock(), tlsConfig)
testClient = New(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 3, "", blog.NewMock(), tlsConfig)
dr = testClient.(*impl)
dr.exchanger = &testExchanger{errs: []error{errors.New("oops")}}
ctx, cancel = context.WithTimeout(t.Context(), -10*time.Hour)
Expand Down Expand Up @@ -883,7 +883,7 @@ func TestRotateServerOnErr(t *testing.T) {
test.AssertNotError(t, err, "Got error creating StaticProvider")

maxTries := 5
client := New(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), maxTries, "", blog.UseMock(), tlsConfig)
client := New(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), maxTries, "", blog.NewMock(), tlsConfig)

// Configure a mock exchanger that will always return a retryable error for
// servers A and B. This will force server "[2606:4700:4700::1111]:53" to do
Expand Down Expand Up @@ -948,7 +948,7 @@ func TestDOHMetric(t *testing.T) {
staticProvider, err := NewStaticProvider([]string{dnsLoopbackAddr})
test.AssertNotError(t, err, "Got error creating StaticProvider")

testClient := New(time.Second*11, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 0, "", blog.UseMock(), tlsConfig)
testClient := New(time.Second*11, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 0, "", blog.NewMock(), tlsConfig)
resolver := testClient.(*impl)
resolver.exchanger = &dohAlwaysRetryExchanger{err: &url.Error{Op: "read", Err: testTimeoutError(true)}}

Expand Down
61 changes: 61 additions & 0 deletions blog/attr.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package blog

// This file contains helper functions that can be used throughout the boulder
// code base to ensure that certain commonly-logged values always have the same
// key name and value type. This prevents situations like sometimes calling the
// requesting account "requester" or "acct" or "regID"; or sometimes logging the
// authz ID as an integer and sometimes as a string.
//
// Any time we find ourselves logging the same slog.Attr from 3+ files we
// should consider adding a helper here instead.
//
// Note that several other attr keys are reserved and should not be used:
// - "time": used by the slog package
// - "level": used by the slog package
// - "msg": used by the slog package
// - "source": used by the slog package
// - "error": used by our blog.Error and blog.AuditError helpers
// - "audit": used by our blog.AuditError and blog.AuditInfo helpers

import (
"log/slog"

"github.com/letsencrypt/boulder/identifier"
)

// Acct returns a slog.Attr whose key is "acct" and whose value is the unique
// numeric ID of the account.
func Acct(acctID int64) slog.Attr {
return slog.Int64("acct", acctID)
}

// Order returns a slog.Attr whose key is "order" and whose value is the unique
// numeric ID of the order.
func Order(orderID int64) slog.Attr {
return slog.Int64("order", orderID)
}

// Authz returns a slog.Attr whose key is "authz" and whose value is the unique
// numeric ID of the authz.
func Authz(authzID int64) slog.Attr {
return slog.Int64("authz", authzID)
}

// Serial returns a slog.Attr whose key is "serial" and whose value is the
// given string. The argument should be hex-encoded.
func Serial(serial string) slog.Attr {
return slog.String("serial", serial)
}

// Idents returns a slog.Attr whose key is "idents" and whose value is a list
// of the given identifiers.
func Idents(idents ...identifier.ACMEIdentifier) slog.Attr {
return slog.Any("idents", idents)
}

// Error returns a slog.Attr whose key is "error" and whose value is the value
// from err.Error(). This attribute is used automatically by methods that log
// at the error level, like blog.Logger.AuditError().
func Error(err error) slog.Attr {
return slog.String("error", err.Error())
}
Loading