Nonce: Simplify Nonce Redeemer testing (#6740)

Implements three nonce redeemer clients that are either valid, invalid,
or broken.

Fixes https://github.com/letsencrypt/boulder/issues/6701
This commit is contained in:
Phil Porada 2023-03-13 17:08:44 -04:00 committed by GitHub
parent b9f0fe030a
commit db9b247b92
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 27 deletions

View File

@ -360,7 +360,7 @@ type Getter interface {
Nonce(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*noncepb.NonceMessage, error) Nonce(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*noncepb.NonceMessage, error)
} }
// Getter is an interface for an RPC client that can redeem a nonce. // Redeemer is an interface for an RPC client that can redeem a nonce.
type Redeemer interface { type Redeemer interface {
Redeem(ctx context.Context, in *noncepb.NonceMessage, opts ...grpc.CallOption) (*noncepb.ValidMessage, error) Redeem(ctx context.Context, in *noncepb.NonceMessage, opts ...grpc.CallOption) (*noncepb.ValidMessage, error)
} }

View File

@ -10,7 +10,6 @@ import (
noncepb "github.com/letsencrypt/boulder/nonce/proto" noncepb "github.com/letsencrypt/boulder/nonce/proto"
"github.com/letsencrypt/boulder/test" "github.com/letsencrypt/boulder/test"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/protobuf/types/known/emptypb"
) )
func TestValidNonce(t *testing.T) { func TestValidNonce(t *testing.T) {
@ -142,16 +141,22 @@ func TestNoncePrefixing(t *testing.T) {
test.Assert(t, !ns.Valid(n[6:]), "Valid nonce without prefix accepted") test.Assert(t, !ns.Valid(n[6:]), "Valid nonce without prefix accepted")
} }
type malleableNonceClient struct { type validRedeemer struct{}
redeem func(ctx context.Context, in *noncepb.NonceMessage, opts ...grpc.CallOption) (*noncepb.ValidMessage, error)
func (vr *validRedeemer) Redeem(ctx context.Context, in *noncepb.NonceMessage, _ ...grpc.CallOption) (*noncepb.ValidMessage, error) {
return &noncepb.ValidMessage{Valid: true}, nil
} }
func (mnc *malleableNonceClient) Redeem(ctx context.Context, in *noncepb.NonceMessage, opts ...grpc.CallOption) (*noncepb.ValidMessage, error) { type invalidRedeemer struct{}
return mnc.redeem(ctx, in, opts...)
func (ivr *invalidRedeemer) Redeem(ctx context.Context, in *noncepb.NonceMessage, _ ...grpc.CallOption) (*noncepb.ValidMessage, error) {
return &noncepb.ValidMessage{Valid: false}, nil
} }
func (mnc *malleableNonceClient) Nonce(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*noncepb.NonceMessage, error) { type brokenRedeemer struct{}
return nil, errors.New("unimplemented")
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) { func TestRemoteRedeem(t *testing.T) {
@ -163,16 +168,8 @@ func TestRemoteRedeem(t *testing.T) {
test.Assert(t, !valid, "RemoteRedeem accepted an empty nonce") test.Assert(t, !valid, "RemoteRedeem accepted an empty nonce")
prefixMap := map[string]Redeemer{ prefixMap := map[string]Redeemer{
"abcd": &malleableNonceClient{ "abcd": &brokenRedeemer{},
redeem: func(ctx context.Context, in *noncepb.NonceMessage, opts ...grpc.CallOption) (*noncepb.ValidMessage, error) { "wxyz": &invalidRedeemer{},
return nil, errors.New("wrong one!")
},
},
"wxyz": &malleableNonceClient{
redeem: func(ctx context.Context, in *noncepb.NonceMessage, opts ...grpc.CallOption) (*noncepb.ValidMessage, error) {
return &noncepb.ValidMessage{Valid: false}, nil
},
},
} }
// Attempt to redeem a nonce with a prefix not in the prefix map, expect return false, nil // Attempt to redeem a nonce with a prefix not in the prefix map, expect return false, nil
valid, err = RemoteRedeem(context.Background(), prefixMap, "asddCQEC") valid, err = RemoteRedeem(context.Background(), prefixMap, "asddCQEC")
@ -184,19 +181,15 @@ func TestRemoteRedeem(t *testing.T) {
_, err = RemoteRedeem(context.Background(), prefixMap, "abcdbeef") _, err = RemoteRedeem(context.Background(), prefixMap, "abcdbeef")
test.AssertError(t, err, "RemoteRedeem didn't return error when remote did") 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 valid // Attempt to redeem a nonce with a prefix in the prefix map, remote returns invalid
// expect true, nil // expect false, nil
valid, err = RemoteRedeem(context.Background(), prefixMap, "wxyzdead") valid, err = RemoteRedeem(context.Background(), prefixMap, "wxyzdead")
test.AssertNotError(t, err, "RemoteRedeem failed") test.AssertNotError(t, err, "RemoteRedeem failed")
test.Assert(t, !valid, "RemoteRedeem didn't honor remote result") test.Assert(t, !valid, "RemoteRedeem didn't honor remote result")
// Attempt to redeem a nonce with a prefix in the prefix map, remote returns invalid // Attempt to redeem a nonce with a prefix in the prefix map, remote returns valid
// expect false, nil // expect true, nil
prefixMap["wxyz"] = &malleableNonceClient{ prefixMap["wxyz"] = &validRedeemer{}
redeem: func(ctx context.Context, in *noncepb.NonceMessage, opts ...grpc.CallOption) (*noncepb.ValidMessage, error) {
return &noncepb.ValidMessage{Valid: true}, nil
},
}
valid, err = RemoteRedeem(context.Background(), prefixMap, "wxyzdead") valid, err = RemoteRedeem(context.Background(), prefixMap, "wxyzdead")
test.AssertNotError(t, err, "RemoteRedeem failed") test.AssertNotError(t, err, "RemoteRedeem failed")
test.Assert(t, valid, "RemoteRedeem didn't honor remote result") test.Assert(t, valid, "RemoteRedeem didn't honor remote result")