rework message signing options

Previously, there was no non-breaking upgrade path to enable message signing by
default while still providing a way to disable it. This patch breaks the options
into:

1. WithMessageSigning - actually enable message signing.
2. WithStrictSignatureVerification - enforce strict signature verification.
3. WithMessageAuthor - set the message author (independent of signing).

Now, users can explicitly set all three options and any changes we make to the
defaults will never override these explicit settings.

This patch *also* enables *signing* by default but not strict signature
verification. We obviously can't enable verification by default yet but I see no
reason not to enable signing. Basically, we're either hurting performance or
security by default. Security issues are generally only noticed once it's too
late. Performance issues can be caught ahead of time.
This commit is contained in:
Steven Allen 2018-10-25 06:37:11 -07:00
parent 3d408775de
commit fba434025b
2 changed files with 47 additions and 5 deletions

View File

@ -905,7 +905,7 @@ func TestWithSigning(t *testing.T) {
defer cancel()
hosts := getNetHosts(t, ctx, 2)
psubs := getPubsubs(ctx, hosts, WithMessageSigning(true))
psubs := getPubsubs(ctx, hosts, WithStrictSignatureVerification(true))
connect(t, hosts[0], hosts[1])

View File

@ -147,6 +147,8 @@ func NewPubSub(ctx context.Context, h host.Host, rt PubSubRouter, opts ...Option
host: h,
ctx: ctx,
rt: rt,
signID: h.ID(),
signKey: h.Peerstore().PrivKey(h.ID()),
incoming: make(chan *RPC, 32),
publish: make(chan *Message),
newPeers: make(chan inet.Stream),
@ -187,6 +189,8 @@ func NewPubSub(ctx context.Context, h host.Host, rt PubSubRouter, opts ...Option
return ps, nil
}
// WithValidateThrottle sets the upper bound on the number of active validation
// goroutines.
func WithValidateThrottle(n int) Option {
return func(ps *PubSub) error {
ps.validateThrottle = make(chan struct{}, n)
@ -194,11 +198,49 @@ func WithValidateThrottle(n int) Option {
}
}
func WithMessageSigning(strict bool) Option {
// WithMessageSigning enables or disables message signing (enabled by default).
func WithMessageSigning(enabled bool) Option {
return func(p *PubSub) error {
p.signID = p.host.ID()
p.signKey = p.host.Peerstore().PrivKey(p.signID)
p.signStrict = strict
if enabled {
p.signKey = p.host.Peerstore().PrivKey(p.signID)
if p.signKey == nil {
return fmt.Errorf("can't sign for peer %s: no private key", p.signID)
}
} else {
p.signKey = nil
}
return nil
}
}
// WithMessageAuthor sets the author for outbound messages to the given peer ID
// (defaults to the host's ID). If message signing is enabled, the private key
// must be available in the host's peerstore.
func WithMessageAuthor(author peer.ID) Option {
return func(p *PubSub) error {
if author == "" {
author = p.host.ID()
}
if p.signKey != nil {
newSignKey := p.host.Peerstore().PrivKey(author)
if newSignKey == nil {
return fmt.Errorf("can't sign for peer %s: no private key", p.signID)
}
p.signKey = newSignKey
}
p.signID = author
return nil
}
}
// WithStrictSignatureVerification enforces message signing. If set, unsigned
// messages will be discarded.
//
// This currently defaults to false but as we transition to signing by default
// but will eventually default to true.
func WithStrictSignatureVerification(required bool) Option {
return func(p *PubSub) error {
p.signStrict = required
return nil
}
}