mirror of
https://github.com/go-i2p/go-i2p.git
synced 2025-07-13 20:41:25 -04:00
NTCP2: Change noise interface so we get static keys from better places
This commit is contained in:
@ -7,7 +7,7 @@ import (
|
||||
"time"
|
||||
|
||||
. "github.com/go-i2p/go-i2p/lib/common/data"
|
||||
"github.com/go-i2p/go-i2p/lib/util/logger"
|
||||
"github.com/go-i2p/logger"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
|
@ -148,10 +148,10 @@ func Test10K(t *testing.T) {
|
||||
t.Fatalf("Failed to read temp directory: %v", err)
|
||||
}
|
||||
|
||||
for _, file := range files {
|
||||
for d, file := range files {
|
||||
if !file.IsDir() && strings.HasPrefix(file.Name(), "routerInfo-") {
|
||||
// Read the router info file
|
||||
log.Println("RI LOAD: ", file.Name())
|
||||
log.Println("RI LOAD: ", d, file.Name())
|
||||
data, err := os.ReadFile(filepath.Join(tempDir, file.Name()))
|
||||
if err != nil {
|
||||
t.Logf("Failed to read file %s: %v", file.Name(), err)
|
||||
|
@ -1,7 +1,6 @@
|
||||
package transport
|
||||
|
||||
import (
|
||||
"github.com/go-i2p/go-i2p/lib/common/router_identity"
|
||||
"github.com/go-i2p/go-i2p/lib/common/router_info"
|
||||
"github.com/go-i2p/logger"
|
||||
)
|
||||
@ -25,7 +24,7 @@ func Mux(t ...Transport) (tmux *TransportMuxer) {
|
||||
}
|
||||
|
||||
// set the identity for every transport
|
||||
func (tmux *TransportMuxer) SetIdentity(ident router_identity.RouterIdentity) (err error) {
|
||||
func (tmux *TransportMuxer) SetIdentity(ident router_info.RouterInfo) (err error) {
|
||||
log.WithField("identity", ident).Debug("TransportMuxer: Setting identity for all transports")
|
||||
for i, t := range tmux.trans {
|
||||
err = t.SetIdentity(ident)
|
||||
|
@ -14,7 +14,6 @@ type HandshakeState struct {
|
||||
ephemeral *noise.DHKey
|
||||
pattern noise.HandshakePattern
|
||||
handshakeComplete bool
|
||||
HandKey noise.DHKey
|
||||
*noise.HandshakeState
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@ import (
|
||||
func (c *NoiseSession) RunIncomingHandshake() error {
|
||||
log.Debug("Starting incoming handshake")
|
||||
|
||||
negData, msg, state, err := c.ComposeReceiverHandshakeMessage(c.HandKey, nil, nil, nil)
|
||||
negData, msg, state, err := c.ComposeReceiverHandshakeMessage(*c.HandshakeKey(), nil, nil, nil)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Failed to compose receiver handshake message")
|
||||
return err
|
||||
@ -42,11 +42,11 @@ func (c *NoiseSession) RunIncomingHandshake() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *NoiseSession) ComposeReceiverHandshakeMessage(s noise.DHKey, rs []byte, payload []byte, ePrivate []byte) (negData, msg []byte, state *noise.HandshakeState, err error) {
|
||||
func (c *NoiseSession) ComposeReceiverHandshakeMessage(localStatic noise.DHKey, remoteStatic []byte, payload []byte, ephemeralPrivate []byte) (negData, msg []byte, state *noise.HandshakeState, err error) {
|
||||
log.Debug("Starting ComposeReceiverHandshakeMessage")
|
||||
|
||||
if len(rs) != 0 && len(rs) != noise.DH25519.DHLen() {
|
||||
log.WithField("rs_length", len(rs)).Error("Invalid remote static key length")
|
||||
if len(remoteStatic) != 0 && len(remoteStatic) != noise.DH25519.DHLen() {
|
||||
log.WithField("rs_length", len(remoteStatic)).Error("Invalid remote static key length")
|
||||
return nil, nil, nil, errors.New("only 32 byte curve25519 public keys are supported")
|
||||
}
|
||||
|
||||
@ -56,18 +56,18 @@ func (c *NoiseSession) ComposeReceiverHandshakeMessage(s noise.DHKey, rs []byte,
|
||||
negData[5] = NOISE_PATTERN_XK
|
||||
|
||||
var random io.Reader
|
||||
if len(ePrivate) == 0 {
|
||||
if len(ephemeralPrivate) == 0 {
|
||||
random = rand.Reader
|
||||
log.Debug("Using crypto/rand as random source")
|
||||
} else {
|
||||
random = bytes.NewBuffer(ePrivate)
|
||||
random = bytes.NewBuffer(ephemeralPrivate)
|
||||
}
|
||||
|
||||
config := noise.Config{
|
||||
CipherSuite: noise.NewCipherSuite(noise.DH25519, noise.CipherChaChaPoly, noise.HashSHA256),
|
||||
Pattern: pattern,
|
||||
Initiator: false,
|
||||
StaticKeypair: s,
|
||||
StaticKeypair: localStatic,
|
||||
Random: random,
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
@ -14,7 +15,7 @@ import (
|
||||
func (c *NoiseSession) RunOutgoingHandshake() error {
|
||||
log.Debug("Starting outgoing handshake")
|
||||
|
||||
negData, msg, state, err := c.ComposeInitiatorHandshakeMessage(c.HandKey, nil, nil, nil)
|
||||
negData, msg, state, err := c.ComposeInitiatorHandshakeMessage(nil, nil)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Failed to compose initiator handshake message")
|
||||
return err
|
||||
@ -46,8 +47,6 @@ func (c *NoiseSession) RunOutgoingHandshake() error {
|
||||
}
|
||||
|
||||
func (c *NoiseSession) ComposeInitiatorHandshakeMessage(
|
||||
localStatic noise.DHKey,
|
||||
remoteStatic []byte,
|
||||
payload []byte,
|
||||
ephemeralPrivate []byte,
|
||||
) (
|
||||
@ -58,6 +57,21 @@ func (c *NoiseSession) ComposeInitiatorHandshakeMessage(
|
||||
) {
|
||||
log.Debug("Starting ComposeInitiatorHandshakeMessage")
|
||||
|
||||
remoteStatic, err := c.peerStaticKey()
|
||||
if err != nil {
|
||||
return nil, nil, nil, fmt.Errorf("Peer static key retrieval error: %s", err)
|
||||
}
|
||||
|
||||
/*localStatic, err := c.localStaticKey()
|
||||
if err != nil {
|
||||
return nil, nil, nil, fmt.Errorf("Local static key retrieval error: %s", err)
|
||||
}
|
||||
localStaticDH := noise.DHKey{
|
||||
Public: localStatic[:],
|
||||
Private: localStatic[:],
|
||||
}*/
|
||||
localStaticDH := *c.HandshakeKey()
|
||||
|
||||
if len(remoteStatic) != 0 && len(remoteStatic) != noise.DH25519.DHLen() {
|
||||
return nil, nil, nil, errors.New("only 32 byte curve25519 public keys are supported")
|
||||
}
|
||||
@ -78,7 +92,7 @@ func (c *NoiseSession) ComposeInitiatorHandshakeMessage(
|
||||
CipherSuite: noise.NewCipherSuite(noise.DH25519, noise.CipherChaChaPoly, noise.HashSHA256),
|
||||
Pattern: pattern,
|
||||
Initiator: true,
|
||||
StaticKeypair: localStatic,
|
||||
StaticKeypair: localStaticDH,
|
||||
Random: random,
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@ type NoiseSession struct {
|
||||
router_info.RouterInfo
|
||||
*noise.CipherState
|
||||
*sync.Cond
|
||||
*NoiseTransport // The parent transport, which "Dialed" the connection to the peer whith whom we established the session
|
||||
*NoiseTransport // The parent transport, which "Dialed" the connection to the peer with whom we established the session
|
||||
*HandshakeState
|
||||
RecvQueue *cb.Queue
|
||||
SendQueue *cb.Queue
|
||||
@ -90,6 +90,33 @@ func (c *NoiseSession) processCallback(publicKey []byte, payload []byte) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// PeerStaticKey is equal to the NTCP2 peer's static public key, found in their router info
|
||||
func (s *NoiseSession) peerStaticKey() ([32]byte, error) {
|
||||
for _, addr := range s.RouterInfo.RouterAddresses() {
|
||||
transportStyle, err := addr.TransportStyle().Data()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if transportStyle == NOISE_PROTOCOL_NAME {
|
||||
return addr.StaticKey()
|
||||
}
|
||||
}
|
||||
return [32]byte{}, fmt.Errorf("Remote static key error")
|
||||
}
|
||||
|
||||
func (s *NoiseSession) peerStaticIV() ([16]byte, error) {
|
||||
for _, addr := range s.RouterInfo.RouterAddresses() {
|
||||
transportStyle, err := addr.TransportStyle().Data()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if transportStyle == NOISE_PROTOCOL_NAME {
|
||||
return addr.InitializationVector()
|
||||
}
|
||||
}
|
||||
return [16]byte{}, fmt.Errorf("Remote static IV error")
|
||||
}
|
||||
|
||||
// newBlock allocates a new packet, from hc's free list if possible.
|
||||
func newBlock() []byte {
|
||||
// return make([]byte, MaxPayloadSize)
|
||||
|
@ -8,20 +8,24 @@ package noise
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"sync"
|
||||
|
||||
"github.com/flynn/noise"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/go-i2p/go-i2p/lib/common/data"
|
||||
"github.com/go-i2p/go-i2p/lib/common/router_identity"
|
||||
"github.com/go-i2p/go-i2p/lib/common/router_info"
|
||||
"github.com/go-i2p/go-i2p/lib/transport"
|
||||
)
|
||||
|
||||
const NOISE_PROTOCOL_NAME = "NOISE"
|
||||
|
||||
type NoiseTransport struct {
|
||||
sync.Mutex
|
||||
router_identity.RouterIdentity
|
||||
router_info.RouterInfo
|
||||
transportStyle string
|
||||
Listener net.Listener
|
||||
peerConnections map[data.Hash]transport.TransportSession
|
||||
}
|
||||
@ -71,9 +75,9 @@ func (noopt *NoiseTransport) Name() string {
|
||||
// will bind if the underlying socket is not already
|
||||
// if the underlying socket is already bound update the RouterIdentity
|
||||
// returns any errors that happen if they do
|
||||
func (noopt *NoiseTransport) SetIdentity(ident router_identity.RouterIdentity) (err error) {
|
||||
func (noopt *NoiseTransport) SetIdentity(ident router_info.RouterInfo) (err error) {
|
||||
log.WithField("identity", ident).Debug("NoiseTransport: Setting identity")
|
||||
noopt.RouterIdentity = ident
|
||||
noopt.RouterInfo = ident
|
||||
if noopt.Listener == nil {
|
||||
log.WithFields(logrus.Fields{
|
||||
"at": "(NoiseTransport) SetIdentity",
|
||||
@ -158,6 +162,7 @@ func NewNoiseTransport(netSocket net.Listener) *NoiseTransport {
|
||||
return &NoiseTransport{
|
||||
peerConnections: make(map[data.Hash]transport.TransportSession),
|
||||
Listener: netSocket,
|
||||
transportStyle: NOISE_PROTOCOL_NAME,
|
||||
}
|
||||
}
|
||||
|
||||
@ -175,3 +180,35 @@ func NewNoiseTransportSocket() (*NoiseTransport, error) {
|
||||
log.WithField("addr", netSocket.Addr().String()).Debug("Created new NoiseTransportSocket")
|
||||
return _transport, nil
|
||||
}
|
||||
|
||||
// LocalStaticKey is equal to the NTCP2 static public key, found in our router info
|
||||
func (s *NoiseTransport) localStaticKey() ([32]byte, error) {
|
||||
// s.RouterIdentity
|
||||
for _, addr := range s.RouterInfo.RouterAddresses() {
|
||||
transportStyle, err := addr.TransportStyle().Data()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if transportStyle == s.transportStyle {
|
||||
return addr.StaticKey()
|
||||
}
|
||||
}
|
||||
return [32]byte{}, fmt.Errorf("Remote static key error")
|
||||
}
|
||||
|
||||
func (s *NoiseTransport) localStaticIV() ([16]byte, error) {
|
||||
for _, addr := range s.RouterInfo.RouterAddresses() {
|
||||
transportStyle, err := addr.TransportStyle().Data()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if transportStyle == s.transportStyle {
|
||||
return addr.InitializationVector()
|
||||
}
|
||||
}
|
||||
return [16]byte{}, fmt.Errorf("Remote static IV error")
|
||||
}
|
||||
|
||||
func (h *NoiseTransport) HandshakeKey() *noise.DHKey {
|
||||
return nil
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ import (
|
||||
// NTCP2Session extends the base noise.NoiseSession with NTCP2-specific functionality
|
||||
type NTCP2Session struct {
|
||||
*noise.NoiseSession
|
||||
*NTCP2Transport
|
||||
paddingStrategy PaddingStrategy
|
||||
}
|
||||
|
||||
|
@ -19,18 +19,18 @@ const (
|
||||
NTCP_MESSAGE_MAX_SIZE = 65537
|
||||
)
|
||||
|
||||
var exampleNTCPTransport transport.Transport = &Transport{}
|
||||
var exampleNTCPTransport transport.Transport = &NTCP2Transport{}
|
||||
|
||||
// Transport is an ntcp2 transport implementing transport.Transport interface
|
||||
type Transport struct {
|
||||
// NTCP2Transport is an ntcp2 transport implementing transport.NTCP2Transport interface
|
||||
type NTCP2Transport struct {
|
||||
*noise.NoiseTransport
|
||||
}
|
||||
|
||||
func (t *Transport) Name() string {
|
||||
func (t *NTCP2Transport) Name() string {
|
||||
return NTCP_PROTOCOL_NAME
|
||||
}
|
||||
|
||||
func (t *Transport) Compatible(routerInfo router_info.RouterInfo) bool {
|
||||
func (t *NTCP2Transport) Compatible(routerInfo router_info.RouterInfo) bool {
|
||||
// Check if the router info contains NTCP2 address and capabilities
|
||||
addresses := routerInfo.RouterAddresses()
|
||||
for _, addr := range addresses {
|
||||
@ -45,7 +45,7 @@ func (t *Transport) Compatible(routerInfo router_info.RouterInfo) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (t *Transport) GetSession(routerInfo router_info.RouterInfo) (transport.TransportSession, error) {
|
||||
func (t *NTCP2Transport) GetSession(routerInfo router_info.RouterInfo) (transport.TransportSession, error) {
|
||||
// Create new NTCP2 session
|
||||
session, err := NewNTCP2Session(routerInfo)
|
||||
if err != nil {
|
||||
@ -53,14 +53,14 @@ func (t *Transport) GetSession(routerInfo router_info.RouterInfo) (transport.Tra
|
||||
}
|
||||
|
||||
// Perform handshake
|
||||
if err := session.Handshake(routerInfo); err != nil {
|
||||
if err := session.NTCP2Transport.Handshake(routerInfo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return session, nil
|
||||
}
|
||||
|
||||
func (t *Transport) Accept() (net.Conn, error) {
|
||||
func (t *NTCP2Transport) Accept() (net.Conn, error) {
|
||||
conn, err := t.NoiseTransport.Accept()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -86,3 +86,31 @@ func (t *Transport) Accept() (net.Conn, error) {
|
||||
|
||||
return session, nil
|
||||
}
|
||||
|
||||
// LocalStaticKey is equal to the NTCP2 static public key, found in our router info
|
||||
func (s *NTCP2Transport) localStaticKey() ([32]byte, error) {
|
||||
// s.RouterIdentity
|
||||
for _, addr := range s.RouterInfo.RouterAddresses() {
|
||||
transportStyle, err := addr.TransportStyle().Data()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if transportStyle == NTCP_PROTOCOL_NAME {
|
||||
return addr.StaticKey()
|
||||
}
|
||||
}
|
||||
return [32]byte{}, fmt.Errorf("Remote static key error")
|
||||
}
|
||||
|
||||
func (s *NTCP2Transport) localStaticIV() ([16]byte, error) {
|
||||
for _, addr := range s.RouterInfo.RouterAddresses() {
|
||||
transportStyle, err := addr.TransportStyle().Data()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if transportStyle == NTCP_PROTOCOL_NAME {
|
||||
return addr.InitializationVector()
|
||||
}
|
||||
}
|
||||
return [16]byte{}, fmt.Errorf("Remote static IV error")
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ package transport
|
||||
import (
|
||||
"net"
|
||||
|
||||
"github.com/go-i2p/go-i2p/lib/common/router_identity"
|
||||
"github.com/go-i2p/go-i2p/lib/common/router_info"
|
||||
|
||||
"github.com/go-i2p/go-i2p/lib/i2np"
|
||||
@ -37,7 +36,7 @@ type Transport interface {
|
||||
// will bind if the underlying socket is not already
|
||||
// if the underlying socket is already bound update the RouterIdentity
|
||||
// returns any errors that happen if they do
|
||||
SetIdentity(ident router_identity.RouterIdentity) error
|
||||
SetIdentity(ident router_info.RouterInfo) error
|
||||
|
||||
// Obtain a transport session with a router given its RouterInfo.
|
||||
// If a session with this router is NOT already made attempt to create one and block until made or until an error happens
|
||||
|
Reference in New Issue
Block a user