Skip to content
Snippets Groups Projects
Unverified Commit b7ef5142 authored by Wolfgang Welz's avatar Wolfgang Welz Committed by GitHub
Browse files

Feat: Add option for node identity seed (#142)

* feat: add option to configure the private key seed

* Improve log messages
parent e6d8eeaa
No related branches found
No related tags found
No related merge requests found
...@@ -42,13 +42,25 @@ func newLocal(key PrivateKey, serviceRecord *service.Record, db DB) *Local { ...@@ -42,13 +42,25 @@ func newLocal(key PrivateKey, serviceRecord *service.Record, db DB) *Local {
} }
// NewLocal creates a new local peer linked to the provided db. // NewLocal creates a new local peer linked to the provided db.
func NewLocal(network string, address string, db DB) (*Local, error) { // If an optional seed is provided, the seed is used to generate the private key. Without a seed,
key, err := db.LocalPrivateKey() // the provided key is loaded from the provided database and generated if not stored there.
if err != nil { func NewLocal(network string, address string, db DB, seed ...[]byte) (*Local, error) {
return nil, err var key PrivateKey
if len(seed) > 0 {
key = PrivateKey(ed25519.NewKeyFromSeed(seed[0]))
if err := db.UpdateLocalPrivateKey(key); err != nil {
return nil, err
}
} else {
var err error
key, err = db.LocalPrivateKey()
if err != nil {
return nil, err
}
} }
if l := len(key); l != ed25519.PrivateKeySize { if l := len(key); l != ed25519.PrivateKeySize {
return nil, fmt.Errorf("invalid key length: %d, need %d", l, ed25519.PublicKeySize) return nil, fmt.Errorf("invalid key length: %d, need %d", l, ed25519.PrivateKeySize)
} }
// update the external address used for the peering // update the external address used for the peering
serviceRecord := service.New() serviceRecord := service.New()
......
...@@ -67,6 +67,15 @@ func (db *mapDB) LocalPrivateKey() (PrivateKey, error) { ...@@ -67,6 +67,15 @@ func (db *mapDB) LocalPrivateKey() (PrivateKey, error) {
return db.key, nil return db.key, nil
} }
// UpdateLocalPrivateKey stores the provided key in the database.
func (db *mapDB) UpdateLocalPrivateKey(key PrivateKey) error {
db.mutex.Lock()
defer db.mutex.Unlock()
db.key = key
return nil
}
// LastPing returns that property for the given peer ID and address. // LastPing returns that property for the given peer ID and address.
func (db *mapDB) LastPing(id ID, address string) time.Time { func (db *mapDB) LastPing(id ID, address string) time.Time {
db.mutex.RLock() db.mutex.RLock()
......
...@@ -28,6 +28,8 @@ const ( ...@@ -28,6 +28,8 @@ const (
type DB interface { type DB interface {
// LocalPrivateKey returns the private key stored in the database or creates a new one. // LocalPrivateKey returns the private key stored in the database or creates a new one.
LocalPrivateKey() (PrivateKey, error) LocalPrivateKey() (PrivateKey, error)
// UpdateLocalPrivateKey stores the provided key in the database.
UpdateLocalPrivateKey(key PrivateKey) error
// Peer retrieves a peer from the database. // Peer retrieves a peer from the database.
Peer(id ID) *Peer Peer(id ID) *Peer
...@@ -175,7 +177,7 @@ func (db *persistentDB) LocalPrivateKey() (PrivateKey, error) { ...@@ -175,7 +177,7 @@ func (db *persistentDB) LocalPrivateKey() (PrivateKey, error) {
if err == database.ErrKeyNotFound { if err == database.ErrKeyNotFound {
key, err = generatePrivateKey() key, err = generatePrivateKey()
if err == nil { if err == nil {
err = db.db.Set(localFieldKey(dbLocalKey), key) err = db.UpdateLocalPrivateKey(key)
} }
return key, err return key, err
} }
...@@ -186,6 +188,11 @@ func (db *persistentDB) LocalPrivateKey() (PrivateKey, error) { ...@@ -186,6 +188,11 @@ func (db *persistentDB) LocalPrivateKey() (PrivateKey, error) {
return key, nil return key, nil
} }
// UpdateLocalPrivateKey stores the provided key in the database.
func (db *persistentDB) UpdateLocalPrivateKey(key PrivateKey) error {
return db.db.Set(localFieldKey(dbLocalKey), key)
}
// LastPing returns that property for the given peer ID and address. // LastPing returns that property for the given peer ID and address.
func (db *persistentDB) LastPing(id ID, address string) time.Time { func (db *persistentDB) LastPing(id ID, address string) time.Time {
return time.Unix(db.getInt64(nodeFieldKey(id, address, dbNodePing)), 0) return time.Unix(db.getInt64(nodeFieldKey(id, address, dbNodePing)), 0)
......
package local package local
import ( import (
"crypto/ed25519"
"encoding/base64"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"net" "net"
...@@ -23,7 +25,7 @@ func configureLocal() *peer.Local { ...@@ -23,7 +25,7 @@ func configureLocal() *peer.Local {
ip := net.ParseIP(parameter.NodeConfig.GetString(CFG_ADDRESS)) ip := net.ParseIP(parameter.NodeConfig.GetString(CFG_ADDRESS))
if ip == nil { if ip == nil {
log.Fatalf("Invalid IP address: %s", parameter.NodeConfig.GetString(CFG_ADDRESS)) log.Fatalf("Invalid %s address: %s", CFG_ADDRESS, parameter.NodeConfig.GetString(CFG_ADDRESS))
} }
if ip.IsUnspecified() { if ip.IsUnspecified() {
log.Info("Querying public IP ...") log.Info("Querying public IP ...")
...@@ -40,7 +42,25 @@ func configureLocal() *peer.Local { ...@@ -40,7 +42,25 @@ func configureLocal() *peer.Local {
// create a new local node // create a new local node
db := peer.NewPersistentDB(log) db := peer.NewPersistentDB(log)
local, err := peer.NewLocal("udp", net.JoinHostPort(ip.String(), port), db) // the private key seed of the current local can be returned the following way:
// key, _ := db.LocalPrivateKey()
// fmt.Println(base64.StdEncoding.EncodeToString(ed25519.PrivateKey(key).Seed()))
// set the private key from the seed provided in the config
var seed [][]byte
if parameter.NodeConfig.IsSet(CFG_SEED) {
str := parameter.NodeConfig.GetString(CFG_SEED)
bytes, err := base64.StdEncoding.DecodeString(str)
if err != nil {
log.Fatalf("Invalid %s: %s", CFG_SEED, err)
}
if l := len(bytes); l != ed25519.SeedSize {
log.Fatalf("Invalid %s length: %d, need %d", CFG_SEED, l, ed25519.SeedSize)
}
seed = append(seed, bytes)
}
local, err := peer.NewLocal("udp", net.JoinHostPort(ip.String(), port), db, seed...)
if err != nil { if err != nil {
log.Fatalf("Error creating local: %s", err) log.Fatalf("Error creating local: %s", err)
} }
......
...@@ -7,9 +7,11 @@ import ( ...@@ -7,9 +7,11 @@ import (
const ( const (
CFG_ADDRESS = "autopeering.address" CFG_ADDRESS = "autopeering.address"
CFG_PORT = "autopeering.port" CFG_PORT = "autopeering.port"
CFG_SEED = "autopeering.seed"
) )
func init() { func init() {
flag.String(CFG_ADDRESS, "0.0.0.0", "address to bind for incoming peering requests") flag.String(CFG_ADDRESS, "0.0.0.0", "address to bind for incoming peering requests")
flag.Int(CFG_PORT, 14626, "udp port for incoming peering requests") flag.Int(CFG_PORT, 14626, "udp port for incoming peering requests")
flag.BytesBase64(CFG_SEED, nil, "private key seed used to derive the node identity; optional Base64 encoded 256-bit string")
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment