From 145a43e5f076cb65dbcf73d25fb29ea23625ff4d Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Tue, 16 Jul 2019 09:49:28 +0100 Subject: [PATCH] Fix #413 by always generating public keys from private ones instead of trusting public keys supplied by config --- src/crypto/crypto.go | 18 ++++++++++++++++++ src/yggdrasil/core.go | 28 +++++++++++++++++++--------- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/src/crypto/crypto.go b/src/crypto/crypto.go index d5b467e9..75736ba7 100644 --- a/src/crypto/crypto.go +++ b/src/crypto/crypto.go @@ -15,6 +15,7 @@ import ( "crypto/sha512" "encoding/hex" + "golang.org/x/crypto/curve25519" "golang.org/x/crypto/ed25519" "golang.org/x/crypto/nacl/box" @@ -124,6 +125,15 @@ func Verify(pub *SigPubKey, msg []byte, sig *SigBytes) bool { return ed25519.Verify(pub[:], msg, sig[:]) } +func (p SigPrivKey) Public() SigPubKey { + priv := make(ed25519.PrivateKey, ed25519.PrivateKeySize) + copy(priv[:], p[:]) + pub := priv.Public().(ed25519.PublicKey) + var sigPub SigPubKey + copy(sigPub[:], pub[:]) + return sigPub +} + //////////////////////////////////////////////////////////////////////////////// // NaCl-like crypto "box" (curve25519+xsalsa20+poly1305) @@ -204,6 +214,14 @@ func (n *BoxNonce) Increment() { } } +func (p BoxPrivKey) Public() BoxPubKey { + var boxPub [BoxPubKeyLen]byte + var boxPriv [BoxPrivKeyLen]byte + copy(boxPriv[:BoxPrivKeyLen], p[:BoxPrivKeyLen]) + curve25519.ScalarBaseMult(&boxPub, &boxPriv) + return boxPub +} + // Used to subtract one nonce from another, staying in the range +- 64. // This is used by the nonce progression machinery to advance the bitmask of recently received packets (indexed by nonce), or to check the appropriate bit of the bitmask. // It's basically part of the machinery that prevents replays and duplicate packets. diff --git a/src/yggdrasil/core.go b/src/yggdrasil/core.go index 62d89a8b..35a86df1 100644 --- a/src/yggdrasil/core.go +++ b/src/yggdrasil/core.go @@ -2,6 +2,7 @@ package yggdrasil import ( "encoding/hex" + "errors" "io/ioutil" "time" @@ -46,28 +47,37 @@ func (c *Core) init() error { current, _ := c.config.Get() - boxPubHex, err := hex.DecodeString(current.EncryptionPublicKey) - if err != nil { - return err - } boxPrivHex, err := hex.DecodeString(current.EncryptionPrivateKey) if err != nil { return err } - sigPubHex, err := hex.DecodeString(current.SigningPublicKey) - if err != nil { - return err + if len(boxPrivHex) < crypto.BoxPrivKeyLen { + return errors.New("EncryptionPrivateKey is incorrect length") } + sigPrivHex, err := hex.DecodeString(current.SigningPrivateKey) if err != nil { return err } + if len(sigPrivHex) < crypto.SigPrivKeyLen { + return errors.New("SigningPrivateKey is incorrect length") + } - copy(c.boxPub[:], boxPubHex) copy(c.boxPriv[:], boxPrivHex) - copy(c.sigPub[:], sigPubHex) copy(c.sigPriv[:], sigPrivHex) + boxPub, sigPub := c.boxPriv.Public(), c.sigPriv.Public() + + copy(c.boxPub[:], boxPub[:]) + copy(c.sigPub[:], sigPub[:]) + + if bp := hex.EncodeToString(c.boxPub[:]); current.EncryptionPublicKey != bp { + c.log.Warnln("EncryptionPublicKey in config is incorrect, should be", bp) + } + if sp := hex.EncodeToString(c.sigPub[:]); current.SigningPublicKey != sp { + c.log.Warnln("SigningPublicKey in config is incorrect, should be", sp) + } + c.searches.init(c) c.dht.init(c) c.sessions.init(c)