func newScrambleSuitClientConn(conn net.Conn, tStore *ssTicketStore, ca *ssClientArgs) (net.Conn, error) { // At this point we have kB and our session key, so we can directly // start handshaking and seeing what happens. // Seed the initial polymorphism distribution. seed, err := drbg.NewSeed() if err != nil { return nil, err } dist := probdist.New(seed, minLenDistLength, maxLenDistLength, true) // Allocate the client structure. c := &ssConn{conn, false, dist, bytes.NewBuffer(nil), bytes.NewBuffer(nil), ssRxState{}, nil, nil, tStore} // Start the handshake timeout. deadline := time.Now().Add(clientHandshakeTimeout) if err := conn.SetDeadline(deadline); err != nil { return nil, err } // Attempt to handshake. if err := c.clientHandshake(ca.kB, ca.sessionKey); err != nil { return nil, err } // Stop the handshake timeout. if err := conn.SetDeadline(time.Time{}); err != nil { return nil, err } return c, nil }
func TestWeightedDist(t *testing.T) { seed, err := drbg.NewSeed() if err != nil { t.Fatal("failed to generate a DRBG seed:", err) } const nrTrials = 1000000 hist := make([]int, 1000) w := New(seed, 0, 999, true) if debug { // Dump a string representation of the probability table. fmt.Println("Table:") var sum float64 for _, weight := range w.weights { sum += weight } for i, weight := range w.weights { p := weight / sum if p > 0.000001 { // Filter out tiny values. fmt.Printf(" [%d]: %f\n", w.minValue+w.values[i], p) } } fmt.Println() } for i := 0; i < nrTrials; i++ { value := w.Sample() hist[value]++ } if debug { fmt.Println("Generated:") for value, count := range hist { if count != 0 { p := float64(count) / float64(nrTrials) fmt.Printf(" [%d]: %f (%d)\n", value, p, count) } } } }
func newObfs4ClientConn(conn net.Conn, args *obfs4ClientArgs) (c *obfs4Conn, err error) { // Generate the initial protocol polymorphism distribution(s). var seed *drbg.Seed if seed, err = drbg.NewSeed(); err != nil { return } lenDist := probdist.New(seed, 0, framing.MaximumSegmentLength, biasedDist) var iatDist *probdist.WeightedDist if args.iatMode != iatNone { var iatSeed *drbg.Seed iatSeedSrc := sha256.Sum256(seed.Bytes()[:]) if iatSeed, err = drbg.SeedFromBytes(iatSeedSrc[:]); err != nil { return } iatDist = probdist.New(iatSeed, 0, maxIATDelay, biasedDist) } // Allocate the client structure. c = &obfs4Conn{conn, false, lenDist, iatDist, args.iatMode, bytes.NewBuffer(nil), bytes.NewBuffer(nil), nil, nil} // Start the handshake timeout. deadline := time.Now().Add(clientHandshakeTimeout) if err = conn.SetDeadline(deadline); err != nil { return nil, err } if err = c.clientHandshake(args.nodeID, args.publicKey, args.sessionKey); err != nil { return nil, err } // Stop the handshake timeout. if err = conn.SetDeadline(time.Time{}); err != nil { return nil, err } return }
func newJSONServerState(stateDir string, js *jsonServerState) (err error) { // Generate everything a server needs, using the cryptographic PRNG. var st obfs4ServerState rawID := make([]byte, ntor.NodeIDLength) if err = csrand.Bytes(rawID); err != nil { return } if st.nodeID, err = ntor.NewNodeID(rawID); err != nil { return } if st.identityKey, err = ntor.NewKeypair(false); err != nil { return } if st.drbgSeed, err = drbg.NewSeed(); err != nil { return } st.iatMode = iatNone // Encode it into JSON format and write the state file. js.NodeID = st.nodeID.Hex() js.PrivateKey = st.identityKey.Private().Hex() js.PublicKey = st.identityKey.Public().Hex() js.DrbgSeed = st.drbgSeed.Hex() js.IATMode = st.iatMode var encoded []byte if encoded, err = json.Marshal(js); err != nil { return } if err = ioutil.WriteFile(path.Join(stateDir, stateFile), encoded, 0600); err != nil { return err } return nil }