From d0813c1800fc1cf926fdf346f1709ba1ce21c835 Mon Sep 17 00:00:00 2001 From: Sergey Matveev Date: Sun, 11 Jan 2015 16:44:35 +0300 Subject: [PATCH] Rehandshake after every 4GiB of transferred data Signed-off-by: Sergey Matveev --- README | 3 ++- govpn.go | 14 +++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/README b/README index c529c3e..2852a09 100644 --- a/README +++ b/README @@ -26,7 +26,8 @@ High security and high performance are the goals for that daemon. It uses fast cryptography algorithms with 128bit security margin, strong mutual zero-knowledge authentication and perfect-forward secrecy property. An attacker can not know anything from captured traffic, even -if pre-shared key is compromised. +if pre-shared key is compromised. Rehandshake is performed by client +every 4 GiB of transfered data. Also you can provide up and down scripts that will be executed after either connection is initiated (up-script in background), or is went diff --git a/govpn.go b/govpn.go index 1e15710..b4eda05 100644 --- a/govpn.go +++ b/govpn.go @@ -55,6 +55,8 @@ const ( S20BS = 64 HeartBeatSize = 12 HeartBeatMark = "\x00\x00\x00HEARTBEAT" + // Maximal amount of bytes transfered with single key (4 GiB) + MaxBytesPerKey = 4294967296 ) type TAP interface { @@ -189,6 +191,7 @@ func main() { var p *Peer timeouts := 0 + bytes := 0 states := make(map[string]*Handshake) nonce := make([]byte, NonceSize) keyAuth := new([KeySize]byte) @@ -203,6 +206,7 @@ func main() { } heartbeat := time.Tick(time.Second * time.Duration(timeout/3)) + go func() { <-heartbeat }() heartbeatMark := []byte(HeartBeatMark) termSignal := make(chan os.Signal, 1) @@ -213,6 +217,10 @@ func main() { if finished { break } + if !serverMode && bytes > MaxBytesPerKey { + states[remote.String()] = HandshakeStart(conn, remote, key) + bytes = 0 + } select { case <-termSignal: finished = true @@ -248,9 +256,11 @@ func main() { } if p != nil { fmt.Print("[HS-OK]") + if peer == nil { + go ScriptCall(upPath) + } peer = p delete(states, addr) - go ScriptCall(upPath) } continue } @@ -279,6 +289,7 @@ func main() { peer.nonceRecv = nonceRecv timeouts = 0 frame = buf[S20BS : S20BS+udpPkt.size-NonceSize-poly1305.TagSize] + bytes += len(frame) if string(frame[0:HeartBeatSize]) == HeartBeatMark { continue } @@ -312,6 +323,7 @@ func main() { copy(keyAuth[:], buf[:KeySize]) dataToSend := buf[S20BS-NonceSize : S20BS+ethPktSize] poly1305.Sum(tag, dataToSend, keyAuth) + bytes += len(dataToSend) if _, err := conn.WriteTo(append(dataToSend, tag[:]...), peer.addr); err != nil { log.Println("Error sending UDP", err) } -- 2.44.0