mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-08-13 13:51:58 +03:00
Add OpenVPN, TrustTunnel, Sudoku, inbound managers. Fixes
This commit is contained in:
67
transport/sudoku/handshake_kip.go
Normal file
67
transport/sudoku/handshake_kip.go
Normal file
@@ -0,0 +1,67 @@
|
||||
package sudoku
|
||||
|
||||
import (
|
||||
"crypto/ecdh"
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/sagernet/sing-box/transport/sudoku/crypto"
|
||||
)
|
||||
|
||||
const kipHandshakeSkew = 60 * time.Second
|
||||
|
||||
func kipHandshakeClient(rc *crypto.RecordConn, seed string, userHash [kipHelloUserHashSize]byte, feats uint32, tableHint uint32, hasTableHint bool) (uint32, error) {
|
||||
if rc == nil {
|
||||
return 0, fmt.Errorf("nil conn")
|
||||
}
|
||||
|
||||
curve := ecdh.X25519()
|
||||
ephemeral, err := curve.GenerateKey(rand.Reader)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("ecdh generate failed: %w", err)
|
||||
}
|
||||
|
||||
var nonce [kipHelloNonceSize]byte
|
||||
if _, err := io.ReadFull(rand.Reader, nonce[:]); err != nil {
|
||||
return 0, fmt.Errorf("nonce generate failed: %w", err)
|
||||
}
|
||||
|
||||
var clientPub [kipHelloPubSize]byte
|
||||
copy(clientPub[:], ephemeral.PublicKey().Bytes())
|
||||
|
||||
ch := newKIPClientHello(userHash, nonce, clientPub, feats, tableHint, hasTableHint)
|
||||
if err := WriteKIPMessage(rc, KIPTypeClientHello, ch.EncodePayload()); err != nil {
|
||||
return 0, fmt.Errorf("write client hello failed: %w", err)
|
||||
}
|
||||
|
||||
msg, err := ReadKIPMessage(rc)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("read server hello failed: %w", err)
|
||||
}
|
||||
if msg.Type != KIPTypeServerHello {
|
||||
return 0, fmt.Errorf("unexpected handshake message: %d", msg.Type)
|
||||
}
|
||||
sh, err := DecodeKIPServerHelloPayload(msg.Payload)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("decode server hello failed: %w", err)
|
||||
}
|
||||
if sh.Nonce != nonce {
|
||||
return 0, fmt.Errorf("handshake nonce mismatch")
|
||||
}
|
||||
|
||||
shared, err := x25519SharedSecret(ephemeral, sh.ServerPub[:])
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("ecdh failed: %w", err)
|
||||
}
|
||||
sessC2S, sessS2C, err := deriveSessionDirectionalBases(seed, shared, nonce)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("derive session keys failed: %w", err)
|
||||
}
|
||||
if err := rc.Rekey(sessC2S, sessS2C); err != nil {
|
||||
return 0, fmt.Errorf("rekey failed: %w", err)
|
||||
}
|
||||
|
||||
return sh.SelectedFeats, nil
|
||||
}
|
||||
Reference in New Issue
Block a user