Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Advertise available profiles in directory resource #7603

Merged
merged 1 commit into from
Jul 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions cmd/boulder-wfe2/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,11 +155,11 @@ type Config struct {
// the CA and RA configurations.
MaxNames int `validate:"min=0,max=100"`

// CertificateProfileNames is the list of acceptable certificate profile
// names for newOrder requests. Requests with a profile name not in this
// list will be rejected. This field is optional; if unset, no profile
// names are accepted.
CertificateProfileNames []string `validate:"omitempty,dive,alphanum,min=1,max=32"`
// CertProfiles is a map of acceptable certificate profile names to
// descriptions (perhaps including URLs) of those profiles. NewOrder
// Requests with a profile name not present in this map will be rejected.
// This field is optional; if unset, no profile names are accepted.
CertProfiles map[string]string `validate:"omitempty,dive,keys,alphanum,min=1,max=32,endkeys"`
}

Syslog cmd.SyslogConfig
Expand Down Expand Up @@ -355,7 +355,7 @@ func main() {
limiter,
txnBuilder,
maxNames,
c.WFE.CertificateProfileNames,
c.WFE.CertProfiles,
)
cmd.FailOnError(err, "Unable to create WFE")

Expand Down
6 changes: 3 additions & 3 deletions test/config-next/wfe2.json
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,9 @@
"TrackReplacementCertificatesARI": true,
"CheckRenewalExemptionAtWFE": true
},
"certificateProfileNames": [
"defaultBoulderCertificateProfile"
]
"certProfiles": {
"defaultBoulderCertificateProfile": "The normal profile you know and love"
}
},
"syslog": {
"stdoutlevel": 4,
Expand Down
26 changes: 14 additions & 12 deletions wfe2/wfe.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/prometheus/client_golang/prometheus"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
"go.opentelemetry.io/otel/trace"
"golang.org/x/exp/maps"
"google.golang.org/protobuf/types/known/emptypb"

"github.com/letsencrypt/boulder/core"
Expand All @@ -29,18 +30,16 @@ import (
"github.com/letsencrypt/boulder/features"
"github.com/letsencrypt/boulder/goodkey"
bgrpc "github.com/letsencrypt/boulder/grpc"
"github.com/letsencrypt/boulder/policy"
"github.com/letsencrypt/boulder/ratelimits"

// 'grpc/noncebalancer' is imported for its init function.
_ "github.com/letsencrypt/boulder/grpc/noncebalancer"
_ "github.com/letsencrypt/boulder/grpc/noncebalancer" // imported for its init function.
"github.com/letsencrypt/boulder/identifier"
"github.com/letsencrypt/boulder/issuance"
blog "github.com/letsencrypt/boulder/log"
"github.com/letsencrypt/boulder/metrics/measured_http"
"github.com/letsencrypt/boulder/nonce"
"github.com/letsencrypt/boulder/policy"
"github.com/letsencrypt/boulder/probs"
rapb "github.com/letsencrypt/boulder/ra/proto"
"github.com/letsencrypt/boulder/ratelimits"
"github.com/letsencrypt/boulder/revocation"
sapb "github.com/letsencrypt/boulder/sa/proto"
"github.com/letsencrypt/boulder/web"
Expand Down Expand Up @@ -165,10 +164,10 @@ type WebFrontEndImpl struct {
txnBuilder *ratelimits.TransactionBuilder
maxNames int

// certificateProfileNames is a list of profile names that are allowed to be
// passed to the newOrder endpoint. If a profile name is not in this list,
// the request will be rejected as malformed.
certificateProfileNames []string
// certProfiles is a map of acceptable certificate profile names to
// descriptions (perhaps including URLs) of those profiles. NewOrder
// Requests with a profile name not present in this map will be rejected.
certProfiles map[string]string
}

// NewWebFrontEndImpl constructs a web service for Boulder
Expand All @@ -192,7 +191,7 @@ func NewWebFrontEndImpl(
limiter *ratelimits.Limiter,
txnBuilder *ratelimits.TransactionBuilder,
maxNames int,
certificateProfileNames []string,
certProfiles map[string]string,
) (WebFrontEndImpl, error) {
if len(issuerCertificates) == 0 {
return WebFrontEndImpl{}, errors.New("must provide at least one issuer certificate")
Expand Down Expand Up @@ -230,7 +229,7 @@ func NewWebFrontEndImpl(
limiter: limiter,
txnBuilder: txnBuilder,
maxNames: maxNames,
certificateProfileNames: certificateProfileNames,
certProfiles: certProfiles,
}

return wfe, nil
Expand Down Expand Up @@ -550,6 +549,9 @@ func (wfe *WebFrontEndImpl) Directory(
wfe.DirectoryCAAIdentity,
}
}
if len(wfe.certProfiles) != 0 {
metaMap["profiles"] = wfe.certProfiles
}
// The "meta" directory entry may also include a string with a website URL
if wfe.DirectoryWebsite != "" {
metaMap["website"] = wfe.DirectoryWebsite
Expand Down Expand Up @@ -2190,7 +2192,7 @@ func (wfe *WebFrontEndImpl) validateCertificateProfileName(profile string) error
// No profile name is specified.
return nil
}
if !slices.Contains(wfe.certificateProfileNames, profile) {
if !slices.Contains(maps.Keys(wfe.certProfiles), profile) {
// The profile name is not in the list of configured profiles.
return errors.New("not a recognized profile name")
}
Expand Down
8 changes: 4 additions & 4 deletions wfe2/wfe_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ func setupWFE(t *testing.T) (WebFrontEndImpl, clock.FakeClock, requestSigner) {
limiter,
txnBuilder,
100,
[]string{""},
nil,
)
test.AssertNotError(t, err, "Unable to create WFE")

Expand Down Expand Up @@ -3816,7 +3816,7 @@ func TestNewOrderWithProfile(t *testing.T) {
expectProfileName := "test-profile"
wfe.ra = &mockRA{expectProfileName: expectProfileName}
mux := wfe.Handler(metrics.NoopRegisterer)
wfe.certificateProfileNames = []string{expectProfileName}
wfe.certProfiles = map[string]string{expectProfileName: "description"}

// Test that the newOrder endpoint returns the proper error if an invalid
// profile is specified.
Expand Down Expand Up @@ -3855,8 +3855,8 @@ func TestNewOrderWithProfile(t *testing.T) {
test.AssertNotError(t, err, "Failed to unmarshal order response")
test.AssertEquals(t, errorResp1["status"], "valid")

// Set the acceptable profiles to an empty list, the WFE should no longer accept any profiles.
wfe.certificateProfileNames = []string{}
// Set the acceptable profiles to the empty set, the WFE should no longer accept any profiles.
wfe.certProfiles = map[string]string{}
responseWriter = httptest.NewRecorder()
r = signAndPost(signer, newOrderPath, "http://localhost"+newOrderPath, validOrderBody)
mux.ServeHTTP(responseWriter, r)
Expand Down