Skip to content

Commit

Permalink
Split sagoodkey.NewKeyPolicy from goodkey.NewKeyPolicy
Browse files Browse the repository at this point in the history
... so that goodkey no longer depends on google.golang.org/grpc and
github.com/letsencrypt/boulder/sa/proto , making it cheaper to use
from external Go code.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
  • Loading branch information
mtrmac committed Feb 11, 2023
1 parent 581ea05 commit 0e8e289
Show file tree
Hide file tree
Showing 9 changed files with 110 additions and 26 deletions.
3 changes: 2 additions & 1 deletion cmd/boulder-ca/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/letsencrypt/boulder/ctpolicy/loglist"
"github.com/letsencrypt/boulder/features"
"github.com/letsencrypt/boulder/goodkey"
"github.com/letsencrypt/boulder/goodkey/sagoodkey"
bgrpc "github.com/letsencrypt/boulder/grpc"
"github.com/letsencrypt/boulder/issuance"
"github.com/letsencrypt/boulder/linter"
Expand Down Expand Up @@ -239,7 +240,7 @@ func main() {
cmd.FailOnError(err, "Failed to load credentials and create gRPC connection to SA")
sa := sapb.NewStorageAuthorityClient(conn)

kp, err := goodkey.NewKeyPolicy(&c.CA.GoodKey, sa.KeyBlocked)
kp, err := sagoodkey.NewKeyPolicy(&c.CA.GoodKey, sa.KeyBlocked)
cmd.FailOnError(err, "Unable to create key policy")

var orphanQueue *goque.Queue
Expand Down
3 changes: 2 additions & 1 deletion cmd/boulder-ra/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/letsencrypt/boulder/ctpolicy/loglist"
"github.com/letsencrypt/boulder/features"
"github.com/letsencrypt/boulder/goodkey"
"github.com/letsencrypt/boulder/goodkey/sagoodkey"
bgrpc "github.com/letsencrypt/boulder/grpc"
"github.com/letsencrypt/boulder/issuance"
"github.com/letsencrypt/boulder/policy"
Expand Down Expand Up @@ -228,7 +229,7 @@ func main() {
}
pendingAuthorizationLifetime := time.Duration(c.RA.PendingAuthorizationLifetimeDays) * 24 * time.Hour

kp, err := goodkey.NewKeyPolicy(&c.RA.GoodKey, sac.KeyBlocked)
kp, err := sagoodkey.NewKeyPolicy(&c.RA.GoodKey, sac.KeyBlocked)
cmd.FailOnError(err, "Unable to create key policy")

if c.RA.MaxNames == 0 {
Expand Down
3 changes: 2 additions & 1 deletion cmd/boulder-wfe2/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/letsencrypt/boulder/cmd"
"github.com/letsencrypt/boulder/features"
"github.com/letsencrypt/boulder/goodkey"
"github.com/letsencrypt/boulder/goodkey/sagoodkey"
bgrpc "github.com/letsencrypt/boulder/grpc"
"github.com/letsencrypt/boulder/grpc/noncebalancer"
"github.com/letsencrypt/boulder/issuance"
Expand Down Expand Up @@ -449,7 +450,7 @@ func main() {

rac, sac, gnc, npm, rnc, npKey := setupWFE(c, stats, clk)

kp, err := goodkey.NewKeyPolicy(&c.WFE.GoodKey, sac.KeyBlocked)
kp, err := sagoodkey.NewKeyPolicy(&c.WFE.GoodKey, sac.KeyBlocked)
cmd.FailOnError(err, "Unable to create key policy")

if c.WFE.StaleTimeout.Duration == 0 {
Expand Down
3 changes: 2 additions & 1 deletion cmd/cert-checker/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/letsencrypt/boulder/ctpolicy/loglist"
"github.com/letsencrypt/boulder/features"
"github.com/letsencrypt/boulder/goodkey"
"github.com/letsencrypt/boulder/goodkey/sagoodkey"
"github.com/letsencrypt/boulder/identifier"
_ "github.com/letsencrypt/boulder/linter"
blog "github.com/letsencrypt/boulder/log"
Expand Down Expand Up @@ -487,7 +488,7 @@ func main() {
if config.CertChecker.GoodKey.BlockedKeyFile != "" {
cmd.Fail("cert-checker does not support checking against blocked key files")
}
kp, err := goodkey.NewKeyPolicy(&config.CertChecker.GoodKey, nil)
kp, err := sagoodkey.NewKeyPolicy(&config.CertChecker.GoodKey, nil)
cmd.FailOnError(err, "Unable to create key policy")

saDbMap, err := sa.InitWrappedDb(config.CertChecker.DB, prometheus.DefaultRegisterer, logger)
Expand Down
3 changes: 2 additions & 1 deletion cmd/cert-checker/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"github.com/letsencrypt/boulder/core"
"github.com/letsencrypt/boulder/ctpolicy/loglist"
"github.com/letsencrypt/boulder/goodkey"
"github.com/letsencrypt/boulder/goodkey/sagoodkey"
blog "github.com/letsencrypt/boulder/log"
"github.com/letsencrypt/boulder/metrics"
"github.com/letsencrypt/boulder/policy"
Expand Down Expand Up @@ -56,7 +57,7 @@ func init() {
if err != nil {
log.Fatal(err)
}
kp, err = goodkey.NewKeyPolicy(&goodkey.Config{FermatRounds: 100}, nil)
kp, err = sagoodkey.NewKeyPolicy(&goodkey.Config{FermatRounds: 100}, nil)
if err != nil {
log.Fatal(err)
}
Expand Down
14 changes: 7 additions & 7 deletions goodkey/good_key.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ import (

"github.com/letsencrypt/boulder/core"
berrors "github.com/letsencrypt/boulder/errors"
sapb "github.com/letsencrypt/boulder/sa/proto"
"google.golang.org/grpc"

"github.com/titanous/rocacheck"
)
Expand Down Expand Up @@ -67,10 +65,12 @@ func badKey(msg string, args ...interface{}) error {
return fmt.Errorf("%w%s", ErrBadKey, fmt.Errorf(msg, args...))
}

// BlockedKeyCheckFunc is used to pass in the sa.BlockedKey method to KeyPolicy,
// rather than storing a full sa.SQLStorageAuthority. This makes testing
// BlockedKeyCheckFunc is used to pass in the sa.BlockedKey functionality to KeyPolicy,
// rather than storing a full sa.SQLStorageAuthority. This allows external
// users who don’t want to import all of boulder/sa, and makes testing
// significantly simpler.
type BlockedKeyCheckFunc func(context.Context, *sapb.KeyBlockedRequest, ...grpc.CallOption) (*sapb.Exists, error)
// On success, the function returns a boolean which is true if the key is blocked.
type BlockedKeyCheckFunc func(ctx context.Context, keyHash []byte) (bool, error)

// KeyPolicy determines which types of key may be used with various boulder
// operations.
Expand Down Expand Up @@ -146,10 +146,10 @@ func (policy *KeyPolicy) GoodKey(ctx context.Context, key crypto.PublicKey) erro
if err != nil {
return badKey("%w", err)
}
exists, err := policy.dbCheck(ctx, &sapb.KeyBlockedRequest{KeyHash: digest[:]})
exists, err := policy.dbCheck(ctx, digest[:])
if err != nil {
return err
} else if exists.Exists {
} else if exists {
return badKey("public key is forbidden")
}
}
Expand Down
29 changes: 15 additions & 14 deletions goodkey/good_key_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ import (
"math/big"
"testing"

sapb "github.com/letsencrypt/boulder/sa/proto"
"github.com/letsencrypt/boulder/test"
"google.golang.org/grpc"
)

var testingPolicy = &KeyPolicy{
Expand Down Expand Up @@ -259,22 +257,25 @@ func TestNonRefKey(t *testing.T) {
}

func TestDBBlocklistAccept(t *testing.T) {
testCheck := func(context.Context, *sapb.KeyBlockedRequest, ...grpc.CallOption) (*sapb.Exists, error) {
return &sapb.Exists{Exists: false}, nil
for _, testCheck := range []BlockedKeyCheckFunc{
nil,
func(context.Context, []byte) (bool, error) {
return false, nil
},
} {
policy, err := NewKeyPolicy(&Config{}, testCheck)
test.AssertNotError(t, err, "NewKeyPolicy failed")

k, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
test.AssertNotError(t, err, "ecdsa.GenerateKey failed")
err = policy.GoodKey(context.Background(), k.Public())
test.AssertNotError(t, err, "GoodKey failed with a non-blocked key")
}

policy, err := NewKeyPolicy(&Config{}, testCheck)
test.AssertNotError(t, err, "NewKeyPolicy failed")

k, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
test.AssertNotError(t, err, "ecdsa.GenerateKey failed")
err = policy.GoodKey(context.Background(), k.Public())
test.AssertNotError(t, err, "GoodKey failed with a non-blocked key")
}

func TestDBBlocklistReject(t *testing.T) {
testCheck := func(context.Context, *sapb.KeyBlockedRequest, ...grpc.CallOption) (*sapb.Exists, error) {
return &sapb.Exists{Exists: true}, nil
testCheck := func(context.Context, []byte) (bool, error) {
return true, nil
}

policy, err := NewKeyPolicy(&Config{}, testCheck)
Expand Down
31 changes: 31 additions & 0 deletions goodkey/sagoodkey/good_key.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package sagoodkey

import (
"context"

"github.com/letsencrypt/boulder/goodkey"
sapb "github.com/letsencrypt/boulder/sa/proto"
"google.golang.org/grpc"
)

// BlockedKeyCheckFunc is used to pass in the sa.BlockedKey method to KeyPolicy,
// rather than storing a full sa.SQLStorageAuthority. This makes testing
// significantly simpler.
type BlockedKeyCheckFunc func(context.Context, *sapb.KeyBlockedRequest, ...grpc.CallOption) (*sapb.Exists, error)

// NewKeyPolicy returns a KeyPolicy that uses a sa.BlockedKey method.
// See goodkey.NewKeyPolicy for more details about the policy itself.
func NewKeyPolicy(config *goodkey.Config, bkc BlockedKeyCheckFunc) (goodkey.KeyPolicy, error) {
var genericCheck goodkey.BlockedKeyCheckFunc
if bkc != nil {
genericCheck = func(ctx context.Context, keyHash []byte) (bool, error) {
exists, err := bkc(ctx, &sapb.KeyBlockedRequest{KeyHash: keyHash})
if err != nil {
return false, err
}
return exists.Exists, nil
}
}

return goodkey.NewKeyPolicy(config, genericCheck)
}
47 changes: 47 additions & 0 deletions goodkey/sagoodkey/good_key_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package sagoodkey

import (
"context"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"testing"

"github.com/letsencrypt/boulder/goodkey"
sapb "github.com/letsencrypt/boulder/sa/proto"
"github.com/letsencrypt/boulder/test"
"google.golang.org/grpc"
)

func TestDBBlocklistAccept(t *testing.T) {
for _, testCheck := range []BlockedKeyCheckFunc{
nil,
func(context.Context, *sapb.KeyBlockedRequest, ...grpc.CallOption) (*sapb.Exists, error) {
return &sapb.Exists{Exists: false}, nil
},
} {
policy, err := NewKeyPolicy(&goodkey.Config{}, testCheck)
test.AssertNotError(t, err, "NewKeyPolicy failed")

k, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
test.AssertNotError(t, err, "ecdsa.GenerateKey failed")
err = policy.GoodKey(context.Background(), k.Public())
test.AssertNotError(t, err, "GoodKey failed with a non-blocked key")
}
}

func TestDBBlocklistReject(t *testing.T) {
testCheck := func(context.Context, *sapb.KeyBlockedRequest, ...grpc.CallOption) (*sapb.Exists, error) {
return &sapb.Exists{Exists: true}, nil
}

policy, err := NewKeyPolicy(&goodkey.Config{}, testCheck)
test.AssertNotError(t, err, "NewKeyPolicy failed")

k, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
test.AssertNotError(t, err, "ecdsa.GenerateKey failed")
err = policy.GoodKey(context.Background(), k.Public())
test.AssertError(t, err, "GoodKey didn't fail with a blocked key")
test.AssertErrorIs(t, err, goodkey.ErrBadKey)
test.AssertEquals(t, err.Error(), "public key is forbidden")
}

0 comments on commit 0e8e289

Please sign in to comment.