summaryrefslogtreecommitdiff
path: root/obfs4.go
diff options
context:
space:
mode:
authorYawning Angel <yawning@schwanenlied.me>2014-06-01 05:22:07 +0000
committerYawning Angel <yawning@schwanenlied.me>2014-06-01 05:22:07 +0000
commit36228437c43bf3fa67a4d5b8da8ddf123645e530 (patch)
treeb4772fe6a9162c543a46961dc8af053be5b1405c /obfs4.go
parent2001f0b698183b998dbf8e52f5d40a0d82aeef09 (diff)
Move the server keypair generation to right after Accept().
Instead of threading the code, move the keypair generation to right after Accept() is called. This should mask the timing differential due to the rejection sampling with the noise from the variablity in how long it takes for the server to get around to pulling a connection out of the backlog, and the time taken for the client to send it's portion of the handshake. The downside is that anyone connecting to the obfs4 port does force us to do a bunch of math, but the obfs4 math is relatively cheap compared to it's precursors. Fixes #9.
Diffstat (limited to 'obfs4.go')
-rw-r--r--obfs4.go20
1 files changed, 14 insertions, 6 deletions
diff --git a/obfs4.go b/obfs4.go
index cc5e3b9..b34eceb 100644
--- a/obfs4.go
+++ b/obfs4.go
@@ -159,7 +159,6 @@ func (c *Obfs4Conn) clientHandshake(nodeID *ntor.NodeID, publicKey *ntor.PublicK
}
defer func() {
- // The session key is not needed past returning from this routine.
c.sessionKey = nil
if err != nil {
c.setBroken()
@@ -169,10 +168,7 @@ func (c *Obfs4Conn) clientHandshake(nodeID *ntor.NodeID, publicKey *ntor.PublicK
// Generate/send the client handshake.
var hs *clientHandshake
var blob []byte
- hs, err = newClientHandshake(nodeID, publicKey, c.sessionKey)
- if err != nil {
- return
- }
+ hs = newClientHandshake(nodeID, publicKey, c.sessionKey)
blob, err = hs.generateHandshake()
if err != nil {
return
@@ -231,12 +227,13 @@ func (c *Obfs4Conn) serverHandshake(nodeID *ntor.NodeID, keypair *ntor.Keypair)
}
defer func() {
+ c.sessionKey = nil
if err != nil {
c.setBroken()
}
}()
- hs := newServerHandshake(nodeID, keypair)
+ hs := newServerHandshake(nodeID, keypair, c.sessionKey)
err = c.conn.SetDeadline(time.Now().Add(connectionTimeout))
if err != nil {
return
@@ -645,6 +642,17 @@ func (l *Obfs4Listener) AcceptObfs4() (*Obfs4Conn, error) {
// Allocate the obfs4 connection state.
cObfs := new(Obfs4Conn)
+
+ // Generate the session keypair *before* consuming data from the peer, to
+ // add more noise to the keypair generation time. The idea is that jitter
+ // here is masked by network latency (the time it takes for a server to
+ // accept a socket out of the backlog should not be fixed, and the client
+ // needs to send the public key).
+ cObfs.sessionKey, err = ntor.NewKeypair(true)
+ if err != nil {
+ return nil, err
+ }
+
cObfs.conn = c
cObfs.isServer = true
cObfs.listener = l