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 {
}
// NewLocal creates a new local peer linked to the provided db.
func NewLocal(network string, address string, db DB) (*Local, error) {
key, err := db.LocalPrivateKey()
// If an optional seed is provided, the seed is used to generate the private key. Without a seed,
// the provided key is loaded from the provided database and generated if not stored there.
func NewLocal(network string, address string, db DB, seed ...[]byte) (*Local, error) {
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 {
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
serviceRecord := service.New()
......
......@@ -67,6 +67,15 @@ func (db *mapDB) LocalPrivateKey() (PrivateKey, error) {
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.
func (db *mapDB) LastPing(id ID, address string) time.Time {
db.mutex.RLock()
......
......@@ -28,6 +28,8 @@ const (
type DB interface {
// LocalPrivateKey returns the private key stored in the database or creates a new one.
LocalPrivateKey() (PrivateKey, error)
// UpdateLocalPrivateKey stores the provided key in the database.
UpdateLocalPrivateKey(key PrivateKey) error
// Peer retrieves a peer from the database.
Peer(id ID) *Peer
......@@ -175,7 +177,7 @@ func (db *persistentDB) LocalPrivateKey() (PrivateKey, error) {
if err == database.ErrKeyNotFound {
key, err = generatePrivateKey()
if err == nil {
err = db.db.Set(localFieldKey(dbLocalKey), key)
err = db.UpdateLocalPrivateKey(key)
}
return key, err
}
......@@ -186,6 +188,11 @@ func (db *persistentDB) LocalPrivateKey() (PrivateKey, error) {
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.
func (db *persistentDB) LastPing(id ID, address string) time.Time {
return time.Unix(db.getInt64(nodeFieldKey(id, address, dbNodePing)), 0)
......
package local
import (
"crypto/ed25519"
"encoding/base64"
"fmt"
"io/ioutil"
"net"
......@@ -23,7 +25,7 @@ func configureLocal() *peer.Local {
ip := net.ParseIP(parameter.NodeConfig.GetString(CFG_ADDRESS))
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() {
log.Info("Querying public IP ...")
......@@ -40,7 +42,25 @@ func configureLocal() *peer.Local {
// create a new local node
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 {
log.Fatalf("Error creating local: %s", err)
}
......
......@@ -7,9 +7,11 @@ import (
const (
CFG_ADDRESS = "autopeering.address"
CFG_PORT = "autopeering.port"
CFG_SEED = "autopeering.seed"
)
func init() {
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.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.
Please register or to comment