mirror of
https://github.com/go-i2p/go-i2p.git
synced 2025-07-16 21:51:30 -04:00
Work on implementing and migrating to message processors
This commit is contained in:
@ -1,8 +1,11 @@
|
||||
package ntcp
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/go-i2p/go-i2p/lib/common/data"
|
||||
"github.com/go-i2p/go-i2p/lib/transport/ntcp/handshake"
|
||||
"github.com/go-i2p/go-i2p/lib/transport/ntcp/messages"
|
||||
)
|
||||
@ -45,7 +48,47 @@ type SessionConfirmedProcessor struct {
|
||||
|
||||
// CreateMessage implements handshake.HandshakeMessageProcessor.
|
||||
func (s *SessionConfirmedProcessor) CreateMessage(hs *handshake.HandshakeState) (messages.Message, error) {
|
||||
panic("unimplemented")
|
||||
// Create the SessionConfirmed message
|
||||
sc := &messages.SessionConfirmed{}
|
||||
|
||||
// Step 1: Get our static key from the handshake state
|
||||
// Note: The static key must be encrypted using the handshakeState's WriteMessage
|
||||
// but we need to extract it first to store in the result structure
|
||||
localKeyPair, err := s.NTCP2Session.localStaticKey()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get local static keypair: %w", err)
|
||||
}
|
||||
|
||||
// Copy the 32-byte static key
|
||||
copy(sc.StaticKey[:], localKeyPair[:])
|
||||
|
||||
// Step 2: Set the RouterInfo
|
||||
sc.RouterInfo = &s.NTCP2Session.RouterInfo
|
||||
|
||||
// Step 3: Create options with padding settings
|
||||
// Use default padding for now - we should make this something we can configure
|
||||
paddingLength, err := data.NewIntegerFromInt(calculatePaddingLength(sc.RouterInfo), 1)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create padding length: %w", err)
|
||||
}
|
||||
|
||||
sc.Options = &messages.ConfirmedOptions{
|
||||
PaddingLength: paddingLength,
|
||||
}
|
||||
|
||||
// Step 4: Generate padding data according to the specified length
|
||||
// In a real implementation, this should be cryptographically secure random data
|
||||
if paddingLength.Int() > 0 {
|
||||
sc.Padding = make([]byte, paddingLength.Int())
|
||||
if _, err := rand.Read(sc.Padding); err != nil {
|
||||
return nil, fmt.Errorf("failed to generate padding: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// The actual encryption of the message will happen in the calling function
|
||||
// using the handshakeState.WriteMessage() method, as it needs to maintain the
|
||||
// proper noise protocol state
|
||||
return sc, nil
|
||||
}
|
||||
|
||||
// EncryptPayload implements handshake.HandshakeMessageProcessor.
|
||||
|
@ -1,8 +1,12 @@
|
||||
package ntcp
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"math/big"
|
||||
"net"
|
||||
|
||||
"github.com/go-i2p/go-i2p/lib/common/data"
|
||||
"github.com/go-i2p/go-i2p/lib/crypto/curve25519"
|
||||
"github.com/go-i2p/go-i2p/lib/transport/ntcp/handshake"
|
||||
"github.com/go-i2p/go-i2p/lib/transport/ntcp/messages"
|
||||
"github.com/samber/oops"
|
||||
@ -40,7 +44,46 @@ type SessionCreatedProcessor struct {
|
||||
|
||||
// CreateMessage implements handshake.HandshakeMessageProcessor.
|
||||
func (s *SessionCreatedProcessor) CreateMessage(hs *handshake.HandshakeState) (messages.Message, error) {
|
||||
panic("unimplemented")
|
||||
// 1. Generate ephemeral key (handshakeState has already done this, we just need to extract it)
|
||||
ephemeralKey, err := s.NTCP2Session.HandshakeState.(*handshake.HandshakeState).LocalEphemeral.Public()
|
||||
if err != nil {
|
||||
return nil, oops.Errorf("failed to get local ephemeral key: %w", err)
|
||||
}
|
||||
|
||||
// 2. Create padding according to NTCP2 spec
|
||||
// NTCP2 spec recommends 0-31 bytes of random padding
|
||||
paddingSize, err := rand.Int(rand.Reader, big.NewInt(32))
|
||||
if err != nil {
|
||||
return nil, oops.Errorf("failed to generate random padding size: %w", err)
|
||||
}
|
||||
|
||||
padding := make([]byte, paddingSize.Int64())
|
||||
if _, err := rand.Read(padding); err != nil {
|
||||
return nil, oops.Errorf("failed to generate padding: %w", err)
|
||||
}
|
||||
|
||||
// 3. Create response options
|
||||
timestamp, err := data.DateFromTime(s.GetCurrentTime())
|
||||
if err != nil {
|
||||
return nil, oops.Errorf("failed to create timestamp: %w", err)
|
||||
}
|
||||
paddingLen, err := data.NewIntegerFromInt(len(padding), 1)
|
||||
if err != nil {
|
||||
return nil, oops.Errorf("failed to create padding length: %w", err)
|
||||
}
|
||||
|
||||
// Create response options with appropriate fields
|
||||
responseOptions := &messages.CreatedOptions{
|
||||
PaddingLength: paddingLen,
|
||||
Timestamp: timestamp,
|
||||
}
|
||||
|
||||
// 4. Return the complete SessionCreated message
|
||||
return &messages.SessionCreated{
|
||||
YContent: [32]byte(ephemeralKey.Bytes()), // Y is the obfuscated ephemeral key
|
||||
Options: responseOptions,
|
||||
Padding: padding,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// EncryptPayload implements handshake.HandshakeMessageProcessor.
|
||||
@ -62,9 +105,27 @@ func (s *SessionCreatedProcessor) EncryptPayload(
|
||||
)
|
||||
}
|
||||
|
||||
// GetPadding implements handshake.HandshakeMessageProcessor.
|
||||
// ObfuscateKey should follow the same pattern as in SessionRequestProcessor
|
||||
func (s *SessionCreatedProcessor) ObfuscateKey(msg messages.Message, hs *handshake.HandshakeState) ([]byte, error) {
|
||||
created, ok := msg.(*messages.SessionCreated)
|
||||
if !ok {
|
||||
return nil, oops.Errorf("expected SessionCreated message")
|
||||
}
|
||||
|
||||
// Store the ephemeral key in the handshake state for reuse
|
||||
hs.LocalEphemeral = curve25519.Curve25519PrivateKey(created.YContent[:])
|
||||
|
||||
return s.NTCP2Session.ObfuscateEphemeral(created.YContent[:])
|
||||
}
|
||||
|
||||
// GetPadding retrieves padding from a message
|
||||
func (s *SessionCreatedProcessor) GetPadding(msg messages.Message) []byte {
|
||||
panic("unimplemented")
|
||||
created, ok := msg.(*messages.SessionCreated)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
return created.Padding
|
||||
}
|
||||
|
||||
// MessageType implements handshake.HandshakeMessageProcessor.
|
||||
@ -72,11 +133,6 @@ func (s *SessionCreatedProcessor) MessageType() messages.MessageType {
|
||||
return messages.MessageTypeSessionCreated
|
||||
}
|
||||
|
||||
// ObfuscateKey implements handshake.HandshakeMessageProcessor.
|
||||
func (s *SessionCreatedProcessor) ObfuscateKey(msg messages.Message, hs *handshake.HandshakeState) ([]byte, error) {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
// ProcessMessage implements handshake.HandshakeMessageProcessor.
|
||||
func (s *SessionCreatedProcessor) ProcessMessage(message messages.Message, hs *handshake.HandshakeState) error {
|
||||
panic("unimplemented")
|
||||
|
Reference in New Issue
Block a user