Skip to content

Commit

Permalink
go/common/crypto/signature/signers/remote: Initial import
Browse files Browse the repository at this point in the history
  • Loading branch information
Yawning committed Feb 21, 2020
1 parent dd1d19d commit 3afa5ec
Show file tree
Hide file tree
Showing 26 changed files with 738 additions and 47 deletions.
5 changes: 5 additions & 0 deletions .changelog/2686.feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
go/common/crypto/signature/signers/remote: Add experimental remote signer

This commit adds an experimental remote signer, reference remote signer
implementation, and allows the node to be ran with a non-file based signer
backend.
1 change: 1 addition & 0 deletions go/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ oasis-node/oasis-node
oasis-node/integrationrunner/integrationrunner.test
oasis-test-runner/oasis-test-runner
oasis-net-runner/oasis-net-runner
oasis-remote-signer/oasis-remote-signer
storage/mkvs/urkel/interop/urkel-test-helpers
2 changes: 1 addition & 1 deletion go/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ all: build

# Build.
# List of Go binaries to build.
go-binaries := oasis-node oasis-test-runner oasis-net-runner extra/stats
go-binaries := oasis-node oasis-test-runner oasis-net-runner oasis-remote-signer extra/stats
# List of test helpers to build.
test-helpers := urkel
# List of test vectors to generate.
Expand Down
33 changes: 31 additions & 2 deletions go/common/crypto/signature/signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,19 @@ var (
errUnregisteredContext = errors.New("signature: unregistered context")
errNoChainContext = errors.New("signature: chain domain separation context not set")

registeredContexts sync.Map
registeredContexts sync.Map
allowUnregisteredContexts bool

chainContextLock sync.RWMutex
chainContext Context

// SignerRoles is the list of all supported signer roles.
SignerRoles = []SignerRole{
SignerEntity,
SignerNode,
SignerP2P,
SignerConsensus,
}
)

type contextOptions struct {
Expand Down Expand Up @@ -111,6 +120,13 @@ func UnsafeResetChainContext() {
chainContext = Context("")
}

// UnsafeAllowUnregisteredContexts bypasses the context registration check.
//
// This function is only for the benefit of implementing a remote signer.
func UnsafeAllowUnregisteredContexts() {
allowUnregisteredContexts = true
}

// SetChainContext configures the chain domain separation context that is
// used with any contexts constructed using the WithChainSeparation option.
func SetChainContext(rawContext string) {
Expand All @@ -137,10 +153,12 @@ const (
SignerNode
SignerP2P
SignerConsensus

// If you add to this, also add the new roles to SignerRoles.
)

// SignerFactoryCtor is an SignerFactory constructor.
type SignerFactoryCtor func(interface{}, ...SignerRole) SignerFactory
type SignerFactoryCtor func(interface{}, ...SignerRole) (SignerFactory, error)

// SignerFactory is the opaque factory interface for Signers.
type SignerFactory interface {
Expand Down Expand Up @@ -187,6 +205,17 @@ type UnsafeSigner interface {

// PrepareSignerContext prepares a context for use during signing by a Signer.
func PrepareSignerContext(context Context) ([]byte, error) {
// The remote signer implementation uses the raw context, and
// registration is dealt with client side. Just check that the
// length is sensible, even though the client should be sending
// something sane.
if allowUnregisteredContexts {
if cLen := len(context); cLen == 0 || cLen > ed25519.ContextMaxSize {
return nil, errMalformedContext
}
return []byte(context), nil
}

// Ensure that the context is registered for use.
rawOpts, isRegistered := registeredContexts.Load(context)
if !isRegistered {
Expand Down
6 changes: 3 additions & 3 deletions go/common/crypto/signature/signers/file/file_signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,16 @@ var (

// NewFactory creates a new factory with the specified roles, with the
// specified dataDir.
func NewFactory(config interface{}, roles ...signature.SignerRole) signature.SignerFactory {
func NewFactory(config interface{}, roles ...signature.SignerRole) (signature.SignerFactory, error) {
dataDir, ok := config.(string)
if !ok {
panic("invalid file signer configuration provided")
return nil, errors.New("signature/signer/file: invalid file signer configuration provided")
}

return &Factory{
roles: append([]signature.SignerRole{}, roles...),
dataDir: dataDir,
}
}, nil
}

// Factory is a PEM file backed SignerFactory.
Expand Down
3 changes: 2 additions & 1 deletion go/common/crypto/signature/signers/file/file_signer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ func TestFileSigner(t *testing.T) {
defer os.RemoveAll(tmpDir)

rolePEMFiles[signature.SignerUnknown] = "unit_test.pem"
factory := NewFactory(tmpDir, signature.SignerUnknown)
factory, err := NewFactory(tmpDir, signature.SignerUnknown)
require.NoError(err, "NewFactory()")

// Missing, no generate.
_, err = factory.Load(signature.SignerUnknown)
Expand Down
6 changes: 3 additions & 3 deletions go/common/crypto/signature/signers/ledger/ledger_signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,16 @@ type FactoryConfig struct {
}

// NewFactory creates a new factory with the specified roles.
func NewFactory(config interface{}, roles ...signature.SignerRole) signature.SignerFactory {
func NewFactory(config interface{}, roles ...signature.SignerRole) (signature.SignerFactory, error) {
ledgerConfig, ok := config.(*FactoryConfig)
if !ok {
panic("invalid Ledger signer configuration provided")
return nil, fmt.Errorf("invalid Ledger signer configuration provided")
}
return &Factory{
roles: append([]signature.SignerRole{}, roles...),
address: ledgerConfig.Address,
index: ledgerConfig.Index,
}
}, nil
}

// EnsureRole ensures that the SignatureFactory is configured for the given
Expand Down
Loading

0 comments on commit 3afa5ec

Please sign in to comment.