Remove deprecated WFE.RedeemNonceServices (#7493)

Fixes https://github.com/letsencrypt/boulder/issues/6610
This commit is contained in:
Aaron Gable 2024-05-21 10:13:13 -07:00 committed by GitHub
parent 4663b9898e
commit 5be3650e56
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 95 additions and 360 deletions

View File

@ -66,23 +66,13 @@ type Config struct {
// used to lookup nonce-service instances used exclusively for nonce
// creation. In a multi-DC deployment this should refer to local
// nonce-service instances only.
GetNonceService *cmd.GRPCClientConfig
// RedeemNonceServices contains a map of nonce-service prefixes to
// gRPC configs we want to use to redeem nonces. In a multi-DC deployment
// this should contain all nonce-services from all DCs as we want to be
// able to redeem nonces generated at any DC.
//
// Deprecated: See RedeemNonceService, below.
// TODO (#6610) Remove this after all configs have migrated to
// `RedeemNonceService`.
RedeemNonceServices map[string]cmd.GRPCClientConfig `validate:"required_without=RedeemNonceService,omitempty,min=1,dive"`
GetNonceService *cmd.GRPCClientConfig `validate:"required"`
// RedeemNonceService is a gRPC config which contains a list of SRV
// names used to lookup nonce-service instances used exclusively for
// nonce redemption. In a multi-DC deployment this should contain both
// local and remote nonce-service instances.
RedeemNonceService *cmd.GRPCClientConfig `validate:"required_without=RedeemNonceServices"`
RedeemNonceService *cmd.GRPCClientConfig `validate:"required"`
// NoncePrefixKey is a secret used for deriving the prefix of each nonce
// instance. It should contain 256 bits of random data to be suitable as
@ -209,7 +199,7 @@ func loadChain(certFiles []string) (*issuance.Certificate, []byte, error) {
return certs[0], buf.Bytes(), nil
}
func setupWFE(c Config, scope prometheus.Registerer, clk clock.Clock) (rapb.RegistrationAuthorityClient, sapb.StorageAuthorityReadOnlyClient, nonce.Getter, map[string]nonce.Redeemer, nonce.Redeemer, string) {
func setupWFE(c Config, scope prometheus.Registerer, clk clock.Clock) (rapb.RegistrationAuthorityClient, sapb.StorageAuthorityReadOnlyClient, nonce.Getter, nonce.Redeemer, string) {
tlsConfig, err := c.WFE.TLS.Load(scope)
cmd.FailOnError(err, "TLS config")
@ -221,15 +211,8 @@ func setupWFE(c Config, scope prometheus.Registerer, clk clock.Clock) (rapb.Regi
cmd.FailOnError(err, "Failed to load credentials and create gRPC connection to SA")
sac := sapb.NewStorageAuthorityReadOnlyClient(saConn)
// TODO(#6610) Refactor these checks.
if c.WFE.RedeemNonceService != nil && c.WFE.RedeemNonceServices != nil {
cmd.Fail("Only one of 'redeemNonceService' or 'redeemNonceServices' should be configured.")
}
if c.WFE.RedeemNonceService == nil && c.WFE.RedeemNonceServices == nil {
cmd.Fail("One of 'redeemNonceService' or 'redeemNonceServices' must be configured.")
}
if c.WFE.RedeemNonceService != nil && c.WFE.NoncePrefixKey.PasswordFile == "" {
cmd.Fail("'noncePrefixKey' must be configured if 'redeemNonceService' is configured.")
if c.WFE.RedeemNonceService == nil {
cmd.Fail("'redeemNonceService' must be configured.")
}
if c.WFE.GetNonceService == nil {
cmd.Fail("'getNonceService' must be configured")
@ -245,32 +228,16 @@ func setupWFE(c Config, scope prometheus.Registerer, clk clock.Clock) (rapb.Regi
cmd.FailOnError(err, "Failed to load credentials and create gRPC connection to get nonce service")
gnc := nonce.NewGetter(getNonceConn)
var rnc nonce.Redeemer
var npm map[string]nonce.Redeemer
if c.WFE.RedeemNonceService != nil {
// Dispatch nonce redemption RPCs dynamically.
if c.WFE.RedeemNonceService.SRVResolver != noncebalancer.SRVResolverScheme {
cmd.Fail(fmt.Sprintf(
"'redeemNonceService.SRVResolver' must be set to %q", noncebalancer.SRVResolverScheme),
)
}
redeemNonceConn, err := bgrpc.ClientSetup(c.WFE.RedeemNonceService, tlsConfig, scope, clk)
cmd.FailOnError(err, "Failed to load credentials and create gRPC connection to redeem nonce service")
rnc = nonce.NewRedeemer(redeemNonceConn)
} else {
// Dispatch nonce redpemption RPCs using a static mapping.
//
// TODO(#6610) Remove code below and the `npm` mapping.
npm = make(map[string]nonce.Redeemer)
for prefix, serviceConfig := range c.WFE.RedeemNonceServices {
serviceConfig := serviceConfig
conn, err := bgrpc.ClientSetup(&serviceConfig, tlsConfig, scope, clk)
cmd.FailOnError(err, "Failed to load credentials and create gRPC connection to redeem nonce service")
npm[prefix] = nonce.NewRedeemer(conn)
}
if c.WFE.RedeemNonceService.SRVResolver != noncebalancer.SRVResolverScheme {
cmd.Fail(fmt.Sprintf(
"'redeemNonceService.SRVResolver' must be set to %q", noncebalancer.SRVResolverScheme),
)
}
redeemNonceConn, err := bgrpc.ClientSetup(c.WFE.RedeemNonceService, tlsConfig, scope, clk)
cmd.FailOnError(err, "Failed to load credentials and create gRPC connection to redeem nonce service")
rnc := nonce.NewRedeemer(redeemNonceConn)
return rac, sac, gnc, npm, rnc, rncKey
return rac, sac, gnc, rnc, rncKey
}
type errorWriter struct {
@ -342,7 +309,7 @@ func main() {
clk := cmd.Clock()
rac, sac, gnc, npm, rnc, npKey := setupWFE(c, stats, clk)
rac, sac, gnc, rnc, npKey := setupWFE(c, stats, clk)
kp, err := sagoodkey.NewKeyPolicy(&c.WFE.GoodKey, sac.KeyBlocked)
cmd.FailOnError(err, "Unable to create key policy")
@ -408,7 +375,6 @@ func main() {
rac,
sac,
gnc,
npm,
rnc,
npKey,
accountGetter,

View File

@ -18,29 +18,22 @@ type Config struct {
cmd.ServiceConfig
MaxUsed int
// TODO(#6610): Remove once we've moved to derivable prefixes by
// default.
NoncePrefix string `validate:"excluded_with=UseDerivablePrefix,omitempty,len=4"`
// UseDerivablePrefix indicates whether to use a nonce prefix derived
// from the gRPC listening address. If this is false, the nonce prefix
// will be the value of the NoncePrefix field. If this is true, the
// NoncePrefixKey field is required.
// TODO(#6610): Remove this.
//
// TODO(#6610): Remove once we've moved to derivable prefixes by
// default.
UseDerivablePrefix bool `validate:"excluded_with=NoncePrefix"`
// Deprecated: this value is ignored, and treated as though it is always true.
UseDerivablePrefix bool `validate:"-"`
// NoncePrefixKey is a secret used for deriving the prefix of each nonce
// instance. It should contain 256 bits (32 bytes) of random data to be
// suitable as an HMAC-SHA256 key (e.g. the output of `openssl rand -hex
// 32`). In a multi-DC deployment this value should be the same across
// all boulder-wfe and nonce-service instances. This is only used if
// UseDerivablePrefix is true.
//
// TODO(#6610): Edit this comment once we've moved to derivable prefixes
// by default.
NoncePrefixKey cmd.PasswordConfig `validate:"excluded_with=NoncePrefix,structonly"`
// all boulder-wfe and nonce-service instances.
NoncePrefixKey cmd.PasswordConfig `validate:"required"`
Syslog cmd.SyslogConfig
OpenTelemetry cmd.OpenTelemetryConfig
@ -89,28 +82,20 @@ func main() {
c.NonceService.DebugAddr = *debugAddr
}
// TODO(#6610): Remove once we've moved to derivable prefixes by default.
if c.NonceService.NoncePrefix != "" && c.NonceService.UseDerivablePrefix {
cmd.Fail("Cannot set both 'noncePrefix' and 'useDerivablePrefix'")
if c.NonceService.NoncePrefixKey.PasswordFile == "" {
cmd.Fail("NoncePrefixKey PasswordFile must be set")
}
// TODO(#6610): Remove once we've moved to derivable prefixes by default.
if c.NonceService.UseDerivablePrefix && c.NonceService.NoncePrefixKey.PasswordFile == "" {
cmd.Fail("Cannot set 'noncePrefixKey' without 'useDerivablePrefix'")
}
if c.NonceService.UseDerivablePrefix && c.NonceService.NoncePrefixKey.PasswordFile != "" {
key, err := c.NonceService.NoncePrefixKey.Pass()
cmd.FailOnError(err, "Failed to load 'noncePrefixKey' file.")
c.NonceService.NoncePrefix, err = derivePrefix(key, c.NonceService.GRPC.Address)
cmd.FailOnError(err, "Failed to derive nonce prefix")
}
key, err := c.NonceService.NoncePrefixKey.Pass()
cmd.FailOnError(err, "Failed to load 'noncePrefixKey' file.")
noncePrefix, err := derivePrefix(key, c.NonceService.GRPC.Address)
cmd.FailOnError(err, "Failed to derive nonce prefix")
scope, logger, oTelShutdown := cmd.StatsAndLogging(c.NonceService.Syslog, c.NonceService.OpenTelemetry, c.NonceService.DebugAddr)
defer oTelShutdown(context.Background())
logger.Info(cmd.VersionString())
ns, err := nonce.NewNonceService(scope, c.NonceService.MaxUsed, c.NonceService.NoncePrefix)
ns, err := nonce.NewNonceService(scope, c.NonceService.MaxUsed, noncePrefix)
cmd.FailOnError(err, "Failed to initialize nonce service")
tlsConfig, err := c.NonceService.TLS.Load(scope)

View File

@ -39,12 +39,6 @@ const (
// PrefixLen is the character length of a nonce prefix.
PrefixLen = 8
// DeprecatedPrefixLen is the character length of a nonce prefix.
//
// Deprecated: Use PrefixLen instead.
// TODO(#6610): Remove once we've moved to derivable prefixes by default.
DeprecatedPrefixLen = 4
// NonceLen is the character length of a nonce, excluding the prefix.
NonceLen = 32
defaultMaxUsed = 65536
@ -81,9 +75,6 @@ type NonceService struct {
nonceEarliest prometheus.Gauge
nonceRedeems *prometheus.CounterVec
nonceHeapLatency prometheus.Histogram
// TODO(#6610): Remove this field once we've moved to derivable prefixes by
// default.
prefixLen int
}
type int64Heap []int64
@ -106,23 +97,16 @@ func (h *int64Heap) Pop() interface{} {
// NewNonceService constructs a NonceService with defaults
func NewNonceService(stats prometheus.Registerer, maxUsed int, prefix string) (*NonceService, error) {
// If a prefix is provided it must be four characters and valid base64. The
// If a prefix is provided it must be eight characters and valid base64. The
// prefix is required to be base64url as RFC8555 section 6.5.1 requires that
// nonces use that encoding. As base64 operates on three byte binary
// segments we require the prefix to be three or six bytes (four or eight
// characters) so that the bytes preceding the prefix wouldn't impact the
// encoding.
//
// TODO(#6610): Update this comment once we've moved to eight character
// prefixes by default.
// nonces use that encoding. As base64 operates on three byte binary segments
// we require the prefix to be six bytes (eight characters) so that the bytes
// preceding the prefix wouldn't impact the encoding.
if prefix != "" {
// TODO(#6610): Refactor once we've moved to derivable prefixes by
// default.
if len(prefix) != PrefixLen && len(prefix) != DeprecatedPrefixLen {
if len(prefix) != PrefixLen {
return nil, fmt.Errorf(
"'noncePrefix' must be %d or %d characters, not %d",
"nonce prefix must be %d characters, not %d",
PrefixLen,
DeprecatedPrefixLen,
len(prefix),
)
}
@ -182,9 +166,6 @@ func NewNonceService(stats prometheus.Registerer, maxUsed int, prefix string) (*
nonceEarliest: nonceEarliest,
nonceRedeems: nonceRedeems,
nonceHeapLatency: nonceHeapLatency,
// TODO(#6610): Remove this field once we've moved to derivable prefixes
// by default.
prefixLen: len(prefix),
}, nil
}
@ -303,43 +284,10 @@ func (ns *NonceService) Valid(nonce string) bool {
// splitNonce splits a nonce into a prefix and a body.
func (ns *NonceService) splitNonce(nonce string) (string, string, error) {
if len(nonce) < ns.prefixLen {
if len(nonce) < PrefixLen {
return "", "", errInvalidNonceLength
}
return nonce[:ns.prefixLen], nonce[ns.prefixLen:], nil
}
// splitDeprecatedNonce splits a nonce into a prefix and a body.
//
// Deprecated: Use NonceService.splitDeprecatedNonce instead.
// TODO(#6610): Remove this function once we've moved to derivable prefixes by
// default.
func splitDeprecatedNonce(nonce string) (string, string, error) {
if len(nonce) < DeprecatedPrefixLen {
return "", "", errInvalidNonceLength
}
return nonce[:DeprecatedPrefixLen], nonce[DeprecatedPrefixLen:], nil
}
// RemoteRedeem checks the nonce prefix and routes the Redeem RPC
// to the associated remote nonce service.
//
// TODO(#6610): Remove this function once we've moved to derivable prefixes by
// default.
func RemoteRedeem(ctx context.Context, noncePrefixMap map[string]Redeemer, nonce string) (bool, error) {
prefix, _, err := splitDeprecatedNonce(nonce)
if err != nil {
return false, nil
}
nonceService, present := noncePrefixMap[prefix]
if !present {
return false, nil
}
resp, err := nonceService.Redeem(ctx, &noncepb.NonceMessage{Nonce: nonce})
if err != nil {
return false, err
}
return resp.Valid, nil
return nonce[:PrefixLen], nonce[PrefixLen:], nil
}
// NewServer returns a new Server, wrapping a NonceService.

View File

@ -1,13 +1,9 @@
package nonce
import (
"context"
"errors"
"fmt"
"testing"
"google.golang.org/grpc"
"github.com/letsencrypt/boulder/metrics"
noncepb "github.com/letsencrypt/boulder/nonce/proto"
"github.com/letsencrypt/boulder/test"
@ -129,7 +125,7 @@ func BenchmarkNonces(b *testing.B) {
}
func TestNoncePrefixing(t *testing.T) {
ns, err := NewNonceService(metrics.NoopRegisterer, 0, "zinc")
ns, err := NewNonceService(metrics.NoopRegisterer, 0, "aluminum")
test.AssertNotError(t, err, "Could not create nonce service")
n, err := ns.Nonce()
@ -146,66 +142,12 @@ func TestNoncePrefixing(t *testing.T) {
test.Assert(t, !ns.Valid(n[6:]), "Valid nonce without prefix accepted")
}
type validRedeemer struct{}
func (vr *validRedeemer) Redeem(ctx context.Context, in *noncepb.NonceMessage, _ ...grpc.CallOption) (*noncepb.ValidMessage, error) {
return &noncepb.ValidMessage{Valid: true}, nil
}
type invalidRedeemer struct{}
func (ivr *invalidRedeemer) Redeem(ctx context.Context, in *noncepb.NonceMessage, _ ...grpc.CallOption) (*noncepb.ValidMessage, error) {
return &noncepb.ValidMessage{Valid: false}, nil
}
type brokenRedeemer struct{}
func (br *brokenRedeemer) Redeem(ctx context.Context, in *noncepb.NonceMessage, _ ...grpc.CallOption) (*noncepb.ValidMessage, error) {
return nil, errors.New("broken redeemer!")
}
func TestRemoteRedeem(t *testing.T) {
valid, err := RemoteRedeem(context.Background(), nil, "q")
test.AssertNotError(t, err, "RemoteRedeem failed")
test.Assert(t, !valid, "RemoteRedeem accepted an invalid nonce")
valid, err = RemoteRedeem(context.Background(), nil, "")
test.AssertNotError(t, err, "RemoteRedeem failed")
test.Assert(t, !valid, "RemoteRedeem accepted an empty nonce")
prefixMap := map[string]Redeemer{
"abcd": &brokenRedeemer{},
"wxyz": &invalidRedeemer{},
}
// Attempt to redeem a nonce with a prefix not in the prefix map, expect return false, nil
valid, err = RemoteRedeem(context.Background(), prefixMap, "asddCQEC")
test.AssertNotError(t, err, "RemoteRedeem failed")
test.Assert(t, !valid, "RemoteRedeem accepted nonce not in prefix map")
// Attempt to redeem a nonce with a prefix in the prefix map, remote returns error
// expect false, err
_, err = RemoteRedeem(context.Background(), prefixMap, "abcdbeef")
test.AssertError(t, err, "RemoteRedeem didn't return error when remote did")
// Attempt to redeem a nonce with a prefix in the prefix map, remote returns invalid
// expect false, nil
valid, err = RemoteRedeem(context.Background(), prefixMap, "wxyzdead")
test.AssertNotError(t, err, "RemoteRedeem failed")
test.Assert(t, !valid, "RemoteRedeem didn't honor remote result")
// Attempt to redeem a nonce with a prefix in the prefix map, remote returns valid
// expect true, nil
prefixMap["wxyz"] = &validRedeemer{}
valid, err = RemoteRedeem(context.Background(), prefixMap, "wxyzdead")
test.AssertNotError(t, err, "RemoteRedeem failed")
test.Assert(t, valid, "RemoteRedeem didn't honor remote result")
}
func TestNoncePrefixValidation(t *testing.T) {
_, err := NewNonceService(metrics.NoopRegisterer, 0, "hey")
_, err := NewNonceService(metrics.NoopRegisterer, 0, "whatsup")
test.AssertError(t, err, "NewNonceService didn't fail with short prefix")
_, err = NewNonceService(metrics.NoopRegisterer, 0, "hey!")
_, err = NewNonceService(metrics.NoopRegisterer, 0, "whatsup!")
test.AssertError(t, err, "NewNonceService didn't fail with invalid base64")
_, err = NewNonceService(metrics.NoopRegisterer, 0, "heyy")
_, err = NewNonceService(metrics.NoopRegisterer, 0, "whatsupp")
test.AssertNotError(t, err, "NewNonceService failed with valid nonce prefix")
}

View File

@ -1,7 +1,6 @@
{
"NonceService": {
"maxUsed": 131072,
"useDerivablePrefix": true,
"noncePrefixKey": {
"passwordFile": "test/secrets/nonce_prefix_key"
},

View File

@ -1,7 +1,6 @@
{
"NonceService": {
"maxUsed": 131072,
"useDerivablePrefix": true,
"noncePrefixKey": {
"passwordFile": "test/secrets/nonce_prefix_key"
},

View File

@ -224,53 +224,35 @@ func (wfe *WebFrontEndImpl) validNonce(ctx context.Context, header jose.Header)
wfe.stats.joseErrorCount.With(prometheus.Labels{"type": "JWSMissingNonce"}).Inc()
return probs.BadNonce("JWS has no anti-replay nonce")
}
var valid bool
var err error
if wfe.noncePrefixMap == nil {
// Dispatch nonce redemption RPCs dynamically.
prob := nonceWellFormed(header.Nonce, nonce.PrefixLen)
if prob != nil {
wfe.stats.joseErrorCount.With(prometheus.Labels{"type": "JWSMalformedNonce"}).Inc()
return prob
}
// Populate the context with the nonce prefix and HMAC key. These are
// used by a custom gRPC balancer, known as "noncebalancer", to route
// redemption RPCs to the backend that originally issued the nonce.
ctx = context.WithValue(ctx, nonce.PrefixCtxKey{}, header.Nonce[:nonce.PrefixLen])
ctx = context.WithValue(ctx, nonce.HMACKeyCtxKey{}, wfe.rncKey)
prob := nonceWellFormed(header.Nonce, nonce.PrefixLen)
if prob != nil {
wfe.stats.joseErrorCount.With(prometheus.Labels{"type": "JWSMalformedNonce"}).Inc()
return prob
}
resp, err := wfe.rnc.Redeem(ctx, &noncepb.NonceMessage{Nonce: header.Nonce})
if err != nil {
rpcStatus, ok := status.FromError(err)
if !ok || rpcStatus != nb.ErrNoBackendsMatchPrefix {
return web.ProblemDetailsForError(err, "failed to redeem nonce")
}
// Populate the context with the nonce prefix and HMAC key. These are
// used by a custom gRPC balancer, known as "noncebalancer", to route
// redemption RPCs to the backend that originally issued the nonce.
ctx = context.WithValue(ctx, nonce.PrefixCtxKey{}, header.Nonce[:nonce.PrefixLen])
ctx = context.WithValue(ctx, nonce.HMACKeyCtxKey{}, wfe.rncKey)
// ErrNoBackendsMatchPrefix suggests that the nonce backend, which
// issued this nonce, is presently unreachable or unrecognized by
// this WFE. As this is a transient failure, the client should retry
// their request with a fresh nonce.
resp = &noncepb.ValidMessage{Valid: false}
wfe.stats.nonceNoMatchingBackendCount.Inc()
}
valid = resp.Valid
} else {
// Dispatch nonce redpemption RPCs using a static mapping.
//
// TODO(#6610) Remove code below and the `npm` mapping.
prob := nonceWellFormed(header.Nonce, nonce.DeprecatedPrefixLen)
if prob != nil {
wfe.stats.joseErrorCount.With(prometheus.Labels{"type": "JWSMalformedNonce"}).Inc()
return prob
}
valid, err = nonce.RemoteRedeem(ctx, wfe.noncePrefixMap, header.Nonce)
if err != nil {
resp, err := wfe.rnc.Redeem(ctx, &noncepb.NonceMessage{Nonce: header.Nonce})
if err != nil {
rpcStatus, ok := status.FromError(err)
if !ok || rpcStatus != nb.ErrNoBackendsMatchPrefix {
return web.ProblemDetailsForError(err, "failed to redeem nonce")
}
// ErrNoBackendsMatchPrefix suggests that the nonce backend, which
// issued this nonce, is presently unreachable or unrecognized by
// this WFE. As this is a transient failure, the client should retry
// their request with a fresh nonce.
resp = &noncepb.ValidMessage{Valid: false}
wfe.stats.nonceNoMatchingBackendCount.Inc()
}
if !valid {
if !resp.Valid {
wfe.stats.joseErrorCount.With(prometheus.Labels{"type": "JWSInvalidNonce"}).Inc()
return probs.BadNonce(fmt.Sprintf("JWS has an invalid anti-replay nonce: %q", header.Nonce))
}

View File

@ -9,7 +9,6 @@ import (
"crypto/rsa"
"fmt"
"net/http"
"os"
"strings"
"testing"
@ -691,10 +690,6 @@ func (b badNonceProvider) Nonce() (string, error) {
// characters and static prefixes are 4 characters.
return "woww", nil
}
if os.Getenv("BOULDER_CONFIG_DIR") != "test/config-next" {
// TODO(#6610): Remove this.
return "mlol3ov77I5Ui-cdaY_k8IcjK58FvbG0y_BCRrx5rGQ8rjA", nil
}
return "mlolmlol3ov77I5Ui-cdaY_k8IcjK58FvbG0y_BCRrx5rGQ8rjA", nil
}
@ -708,10 +703,6 @@ func TestValidNonce(t *testing.T) {
JWS *jose.JSONWebSignature
ExpectedResult *probs.ProblemDetails
ErrorStatType string
// TODO(#6610): Remove this.
SkipConfigNext bool
// TODO(#6610): Remove this.
SkipConfig bool
}{
{
Name: "No nonce in JWS",
@ -743,17 +734,6 @@ func TestValidNonce(t *testing.T) {
},
ErrorStatType: "JWSMalformedNonce",
},
{
Name: "Invalid nonce in JWS (test/config)",
JWS: signer.invalidNonce(),
ExpectedResult: &probs.ProblemDetails{
Type: probs.BadNonceProblem,
Detail: "JWS has an invalid anti-replay nonce: \"mlol3ov77I5Ui-cdaY_k8IcjK58FvbG0y_BCRrx5rGQ8rjA\"",
HTTPStatus: http.StatusBadRequest,
},
ErrorStatType: "JWSInvalidNonce",
SkipConfigNext: true,
},
{
Name: "Invalid nonce in JWS (test/config-next)",
JWS: signer.invalidNonce(),
@ -763,7 +743,6 @@ func TestValidNonce(t *testing.T) {
HTTPStatus: http.StatusBadRequest,
},
ErrorStatType: "JWSInvalidNonce",
SkipConfig: true,
},
{
Name: "Valid nonce in JWS",
@ -774,14 +753,6 @@ func TestValidNonce(t *testing.T) {
for _, tc := range testCases {
t.Run(tc.Name, func(t *testing.T) {
// TODO(#6610): Remove this.
if os.Getenv("BOULDER_CONFIG_DIR") == "test/config-next" {
if tc.SkipConfigNext {
t.Skip("Skipping test in config-next")
}
} else if tc.SkipConfig {
t.Skip("Skipping test in config")
}
wfe.stats.joseErrorCount.Reset()
prob := wfe.validNonce(context.Background(), tc.JWS.Signatures[0].Header)
if tc.ExpectedResult == nil && prob != nil {
@ -806,10 +777,6 @@ func (n noBackendsNonceRedeemer) Redeem(ctx context.Context, _ *noncepb.NonceMes
}
func TestValidNonce_NoMatchingBackendFound(t *testing.T) {
// TODO(#6610): Remove this.
if os.Getenv("BOULDER_CONFIG_DIR") != "test/config-next" {
t.Skip("Skipping test in config")
}
wfe, _, signer := setupWFE(t)
goodJWS, _, _ := signer.embeddedJWK(nil, "", "")
wfe.rnc = noBackendsNonceRedeemer{}
@ -1364,10 +1331,6 @@ func TestValidJWSForKey(t *testing.T) {
Body string
ExpectedProblem *probs.ProblemDetails
ErrorStatType string
// TODO(#6610): Remove this.
SkipConfig bool
// TODO(#6610): Remove this.
SkipConfigNext bool
}{
{
Name: "JWS with an invalid algorithm",
@ -1380,18 +1343,6 @@ func TestValidJWSForKey(t *testing.T) {
},
ErrorStatType: "JWSAlgorithmCheckFailed",
},
{
Name: "JWS with an invalid nonce (test/config)",
JWS: bJSONWebSignature{signer.invalidNonce()},
JWK: goodJWK,
ExpectedProblem: &probs.ProblemDetails{
Type: probs.BadNonceProblem,
Detail: "JWS has an invalid anti-replay nonce: \"mlol3ov77I5Ui-cdaY_k8IcjK58FvbG0y_BCRrx5rGQ8rjA\"",
HTTPStatus: http.StatusBadRequest,
},
ErrorStatType: "JWSInvalidNonce",
SkipConfigNext: true,
},
{
Name: "JWS with an invalid nonce (test/config-next)",
JWS: bJSONWebSignature{signer.invalidNonce()},
@ -1402,7 +1353,6 @@ func TestValidJWSForKey(t *testing.T) {
HTTPStatus: http.StatusBadRequest,
},
ErrorStatType: "JWSInvalidNonce",
SkipConfig: true,
},
{
Name: "JWS with broken signature",
@ -1445,16 +1395,7 @@ func TestValidJWSForKey(t *testing.T) {
}
for _, tc := range testCases {
// TODO(#6610): Remove this.
t.Run(tc.Name, func(t *testing.T) {
// TODO(#6610): Remove this.
if os.Getenv("BOULDER_CONFIG_DIR") == "test/config-next" {
if tc.SkipConfigNext {
t.Skip("Skipping test in config-next")
}
} else if tc.SkipConfig {
t.Skip("Skipping test in config")
}
wfe.stats.joseErrorCount.Reset()
request := makePostRequestWithPath("test", tc.Body)
outPayload, prob := wfe.validJWSForKey(context.Background(), &tc.JWS, tc.JWK, request)

View File

@ -97,10 +97,6 @@ type WebFrontEndImpl struct {
// nonces. It's configured to route requests to backends colocated with the
// WFE.
gnc nonce.Getter
// Register of anti-replay nonces
//
// Deprecated: See `rnc`, above.
noncePrefixMap map[string]nonce.Redeemer
// rnc is a nonce-service client used exclusively for the redemption of
// nonces. It uses a custom RPC load balancer which is configured to route
// requests to backends based on the prefix and HMAC key passed as in the
@ -189,7 +185,6 @@ func NewWebFrontEndImpl(
rac rapb.RegistrationAuthorityClient,
sac sapb.StorageAuthorityReadOnlyClient,
gnc nonce.Getter,
noncePrefixMap map[string]nonce.Redeemer,
rnc nonce.Redeemer,
rncKey string,
accountGetter AccountGetter,
@ -210,8 +205,7 @@ func NewWebFrontEndImpl(
return WebFrontEndImpl{}, errors.New("must provide a service for nonce issuance")
}
// TODO(#6610): Remove the check for the map.
if noncePrefixMap == nil && rnc == nil {
if rnc == nil {
return WebFrontEndImpl{}, errors.New("must provide a service for nonce redemption")
}
@ -229,7 +223,6 @@ func NewWebFrontEndImpl(
ra: rac,
sa: sac,
gnc: gnc,
noncePrefixMap: noncePrefixMap,
rnc: rnc,
rncKey: rncKey,
accountGetter: accountGetter,

View File

@ -349,61 +349,42 @@ func setupWFE(t *testing.T) (WebFrontEndImpl, clock.FakeClock, requestSigner) {
log := blog.NewMock()
var gnc nonce.Getter
var noncePrefixMap map[string]nonce.Redeemer
var rnc nonce.Redeemer
var rncKey string
var inmemNonceService *inmemnonce.Service
var limiter *ratelimits.Limiter
var txnBuilder *ratelimits.TransactionBuilder
if strings.Contains(os.Getenv("BOULDER_CONFIG_DIR"), "test/config-next") {
// Use derived nonces.
noncePrefix := nonce.DerivePrefix("192.168.1.1:8080", "b8c758dd85e113ea340ce0b3a99f389d40a308548af94d1730a7692c1874f1f")
nonceService, err := nonce.NewNonceService(metrics.NoopRegisterer, 100, noncePrefix)
test.AssertNotError(t, err, "making nonceService")
// Use derived nonces.
noncePrefix := nonce.DerivePrefix("192.168.1.1:8080", "b8c758dd85e113ea340ce0b3a99f389d40a308548af94d1730a7692c1874f1f")
nonceService, err := nonce.NewNonceService(metrics.NoopRegisterer, 100, noncePrefix)
test.AssertNotError(t, err, "making nonceService")
inmemNonceService = &inmemnonce.Service{NonceService: nonceService}
gnc = inmemNonceService
rnc = inmemNonceService
inmemNonceService := &inmemnonce.Service{NonceService: nonceService}
gnc := inmemNonceService
rnc := inmemNonceService
// Setup rate limiting.
rc := bredis.Config{
Username: "unittest-rw",
TLS: cmd.TLSConfig{
CACertFile: "../test/certs/ipki/minica.pem",
CertFile: "../test/certs/ipki/localhost/cert.pem",
KeyFile: "../test/certs/ipki/localhost/key.pem",
// Setup rate limiting.
rc := bredis.Config{
Username: "unittest-rw",
TLS: cmd.TLSConfig{
CACertFile: "../test/certs/ipki/minica.pem",
CertFile: "../test/certs/ipki/localhost/cert.pem",
KeyFile: "../test/certs/ipki/localhost/key.pem",
},
Lookups: []cmd.ServiceDomain{
{
Service: "redisratelimits",
Domain: "service.consul",
},
Lookups: []cmd.ServiceDomain{
{
Service: "redisratelimits",
Domain: "service.consul",
},
},
LookupDNSAuthority: "consul.service.consul",
}
rc.PasswordConfig = cmd.PasswordConfig{
PasswordFile: "../test/secrets/ratelimits_redis_password",
}
ring, err := bredis.NewRingFromConfig(rc, stats, log)
test.AssertNotError(t, err, "making redis ring client")
source := ratelimits.NewRedisSource(ring.Ring, fc, stats)
test.AssertNotNil(t, source, "source should not be nil")
limiter, err = ratelimits.NewLimiter(fc, source, stats)
test.AssertNotError(t, err, "making limiter")
txnBuilder, err = ratelimits.NewTransactionBuilder("../test/config-next/wfe2-ratelimit-defaults.yml", "")
test.AssertNotError(t, err, "making transaction composer")
} else {
// TODO(#6610): Remove this once we've moved to derived to prefixes.
noncePrefix := "mlem"
nonceService, err := nonce.NewNonceService(metrics.NoopRegisterer, 100, noncePrefix)
test.AssertNotError(t, err, "making nonceService")
inmemNonceService = &inmemnonce.Service{NonceService: nonceService}
gnc = inmemNonceService
noncePrefixMap = map[string]nonce.Redeemer{noncePrefix: inmemNonceService}
rnc = inmemNonceService
},
LookupDNSAuthority: "consul.service.consul",
}
rc.PasswordConfig = cmd.PasswordConfig{
PasswordFile: "../test/secrets/ratelimits_redis_password",
}
ring, err := bredis.NewRingFromConfig(rc, stats, log)
test.AssertNotError(t, err, "making redis ring client")
source := ratelimits.NewRedisSource(ring.Ring, fc, stats)
test.AssertNotNil(t, source, "source should not be nil")
limiter, err := ratelimits.NewLimiter(fc, source, stats)
test.AssertNotError(t, err, "making limiter")
txnBuilder, err := ratelimits.NewTransactionBuilder("../test/config-next/wfe2-ratelimit-defaults.yml", "")
test.AssertNotError(t, err, "making transaction composer")
wfe, err := NewWebFrontEndImpl(
stats,
@ -419,9 +400,8 @@ func setupWFE(t *testing.T) (WebFrontEndImpl, clock.FakeClock, requestSigner) {
&MockRegistrationAuthority{},
mockSA,
gnc,
noncePrefixMap,
rnc,
rncKey,
"rncKey",
mockSA,
limiter,
txnBuilder,