Documentation
¶
Index ¶
- Constants
- func BuildAuthSignMessage(nodeID uint32, x25519Pub []byte, timestamp uint64, nonce [16]byte) []byte
- func CheckAndRecordNonce(nonce [16]byte) error
- func CheckReplayNonce(nonce [16]byte) error
- func InjectReplayNonce(nonce [16]byte)
- func ReadExact(r io.Reader, n int) ([]byte, error)
- func ResetReplayCache()
- func VerifyAuthFrame(frame []byte, peerEdPubKey ed25519.PublicKey, peerX25519Pub []byte, ...) (uint32, error)
- type Handler
- type HandshakeConfig
- type PeerPubKeyLookup
- type SecureConn
- func Dial(d *driver.Driver, addr protocol.Addr, auth ...*HandshakeConfig) (*SecureConn, error)
- func Handshake(conn net.Conn, isServer bool, auth ...*HandshakeConfig) (*SecureConn, error)
- func HandshakeWithLookup(conn net.Conn, isServer bool, cfg *HandshakeConfig, lookup PeerPubKeyLookup) (*SecureConn, error)
- func HandshakeWithTimestampOffset(conn net.Conn, isServer bool, cfg *HandshakeConfig, offset time.Duration) (*SecureConn, error)
- func (sc *SecureConn) Close() error
- func (sc *SecureConn) LocalAddr() net.Addr
- func (sc *SecureConn) Read(b []byte) (int, error)
- func (sc *SecureConn) RemoteAddr() net.Addr
- func (sc *SecureConn) SetDeadline(t time.Time) error
- func (sc *SecureConn) SetReadDeadline(t time.Time) error
- func (sc *SecureConn) SetWriteDeadline(t time.Time) error
- func (sc *SecureConn) Write(b []byte) (int, error)
- type Server
Constants ¶
const AuthFrameLen = 4 + 8 + 16 + 64
AuthFrameLen is the total size of an auth frame: nodeID(4) + timestamp(8) + nonce(16) + ed25519_signature(64) = 92 bytes.
const HandshakeTimeout = 10 * time.Second
HandshakeTimeout is the maximum time allowed for the ECDH handshake.
const MaxEncryptedMessageLen = 16 * 1024 * 1024 // 16 MB
MaxEncryptedMessageLen limits the maximum decrypted message size to prevent memory exhaustion from a malicious peer advertising a huge msgLen.
Variables ¶
This section is empty.
Functions ¶
func BuildAuthSignMessage ¶
BuildAuthSignMessage constructs the message that is signed in the auth frame. Format: "pilot-secure-auth:" + nodeID(4) + X25519_ephemeral_pubkey(32) + timestamp(8) + nonce(16)
func CheckAndRecordNonce ¶
CheckAndRecordNonce returns an error if the nonce was already seen within the replay window, otherwise records it and returns nil.
func CheckReplayNonce ¶
CheckReplayNonce checks if a nonce is in the replay cache without recording it. Exported for testing only.
func InjectReplayNonce ¶
func InjectReplayNonce(nonce [16]byte)
InjectReplayNonce adds a nonce to the replay cache. Exported for testing only.
func ResetReplayCache ¶
func ResetReplayCache()
ResetReplayCache clears the replay cache. Exported for testing only.
func VerifyAuthFrame ¶
func VerifyAuthFrame(frame []byte, peerEdPubKey ed25519.PublicKey, peerX25519Pub []byte, now time.Time) (uint32, error)
VerifyAuthFrame validates a peer's auth frame. The peer signed over their own X25519 ephemeral pubkey (peerX25519Pub), which we received during the ECDH exchange. We reconstruct the signed message and verify against the peer's Ed25519 public key from the registry.
Types ¶
type HandshakeConfig ¶
type HandshakeConfig struct {
NodeID uint32
Signer ed25519.PrivateKey
PeerPubKey ed25519.PublicKey
}
HandshakeConfig holds identity authentication parameters for the secure channel handshake. If nil is passed to Handshake, authentication is skipped (backward compatibility for tests and unauthenticated channels).
type PeerPubKeyLookup ¶
PeerPubKeyLookup returns the Ed25519 public key for a given node ID. Used by the server to look up a connecting client's identity for auth verification. Returns nil if the node is unknown.
Definitive declaration of PeerPubKeyLookup; do not duplicate in this package.
type SecureConn ¶
type SecureConn struct {
PeerNodeID uint32 // authenticated peer node ID (0 if unauthenticated)
// contains filtered or unexported fields
}
SecureConn wraps a net.Conn with AES-256-GCM encryption. After a successful ECDH handshake, all reads and writes are encrypted.
func Dial ¶
func Dial(d *driver.Driver, addr protocol.Addr, auth ...*HandshakeConfig) (*SecureConn, error)
Dial connects to a remote agent's secure port and performs the handshake. Returns an encrypted connection that implements net.Conn.
func Handshake ¶
func Handshake(conn net.Conn, isServer bool, auth ...*HandshakeConfig) (*SecureConn, error)
Handshake performs an ECDH key exchange over the connection. isServer determines which side reads first. An optional HandshakeConfig enables mutual Ed25519 authentication inside the encrypted channel after the ECDH exchange. Pass nil or omit for unauthenticated mode (backward compatible). A deadline is set to prevent indefinite blocking (M14 fix).
func HandshakeWithLookup ¶
func HandshakeWithLookup(conn net.Conn, isServer bool, cfg *HandshakeConfig, lookup PeerPubKeyLookup) (*SecureConn, error)
HandshakeWithLookup is like Handshake with auth, but uses a lookup function to resolve the peer's Ed25519 public key by nodeID. This is used by servers that don't know the peer's identity until they read the auth frame.
func HandshakeWithTimestampOffset ¶
func HandshakeWithTimestampOffset(conn net.Conn, isServer bool, cfg *HandshakeConfig, offset time.Duration) (*SecureConn, error)
HandshakeWithTimestampOffset performs an authenticated handshake but shifts the auth frame timestamp by the given offset. Exported for testing only.
func (*SecureConn) Close ¶
func (sc *SecureConn) Close() error
func (*SecureConn) LocalAddr ¶
func (sc *SecureConn) LocalAddr() net.Addr
func (*SecureConn) Read ¶
func (sc *SecureConn) Read(b []byte) (int, error)
Read decrypts and reads data from the connection. Leftover plaintext from a previous decryption is returned first (H14 fix).
func (*SecureConn) RemoteAddr ¶
func (sc *SecureConn) RemoteAddr() net.Addr
func (*SecureConn) SetDeadline ¶
func (sc *SecureConn) SetDeadline(t time.Time) error
func (*SecureConn) SetReadDeadline ¶
func (sc *SecureConn) SetReadDeadline(t time.Time) error
func (*SecureConn) SetWriteDeadline ¶
func (sc *SecureConn) SetWriteDeadline(t time.Time) error
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server listens on port 443 and upgrades connections to encrypted channels.
func NewAuthServer ¶
func NewAuthServer(d *driver.Driver, handler Handler, nodeID uint32, signer ed25519.PrivateKey, lookup PeerPubKeyLookup) *Server
NewAuthServer creates a secure channel server with Ed25519 authentication. The server authenticates itself and verifies connecting clients using the lookup function to obtain each client's expected Ed25519 public key.
func (*Server) AuthNodeID ¶
AuthNodeID returns the authenticated node id (zero when unauth). Exposed for tests.
func (*Server) AuthSigner ¶
func (s *Server) AuthSigner() ed25519.PrivateKey
AuthSigner returns the server's Ed25519 signing key (nil when unauth). Exposed for tests.
func (*Server) ListenAndServe ¶
ListenAndServe binds port 443 and starts accepting secure connections.
func (*Server) PeerLookup ¶
func (s *Server) PeerLookup() PeerPubKeyLookup
PeerLookup returns the per-peer pubkey lookup (nil when unauth). Exposed for tests.