func newClientArgs(args *pt.Args) (ca *ssClientArgs, err error) { ca = &ssClientArgs{} if ca.kB, err = parsePasswordArg(args); err != nil { return nil, err } // Generate the client keypair before opening a connection since the time // taken is visible to an adversary. This key might not end up being used // if a session ticket is present, but this doesn't take that long. if ca.sessionKey, err = uniformdh.GenerateKey(csrand.Reader); err != nil { return nil, err } return }
func (conn *obfs3Conn) handshake() error { // The party who opens the connection is the 'initiator'; the one who // accepts it is the 'responder'. Each begins by generating a // UniformDH keypair, and a random number PADLEN in [0, MAX_PADDING/2]. // Both parties then send: // // PUB_KEY | WR(PADLEN) privateKey, err := uniformdh.GenerateKey(csrand.Reader) if err != nil { return err } padLen := csrand.IntRange(0, maxPadding/2) blob := make([]byte, uniformdh.Size+padLen) publicKey, err := privateKey.PublicKey.Bytes() if err != nil { return err } copy(blob[0:], publicKey) if err := csrand.Bytes(blob[uniformdh.Size:]); err != nil { return err } if _, err := conn.Conn.Write(blob); err != nil { return err } // Read the public key from the peer. rawPeerPublicKey := make([]byte, uniformdh.Size) if _, err := io.ReadFull(conn.Conn, rawPeerPublicKey); err != nil { return err } var peerPublicKey uniformdh.PublicKey if err := peerPublicKey.SetBytes(rawPeerPublicKey); err != nil { return err } // After retrieving the public key of the other end, each party // completes the DH key exchange and generates a shared-secret for the // session (named SHARED_SECRET). sharedSecret, err := uniformdh.Handshake(privateKey, &peerPublicKey) if err != nil { return err } if err := conn.kdf(sharedSecret); err != nil { return err } return nil }