func KiSS_handshake_client(wire io.ReadWriteCloser, verify Verifier) (wr io.ReadWriteCloser, err error) { defer func() { if r := recover(); r != nil { err = errors.New(fmt.Sprint(r)) } }() // our keys our_keypair := kicrypt.SecureDH_genpair() //LOG(LOG_DEBUG, "CPUB: %d", our_keypair.Public) // construct the client handshake our_greeting := KiSS_HS_Client{0x02, our_keypair.Public} our_greeting_packed := KiSS_Segment{K_HANDSHAKE_C, our_greeting.Pack()} // send across the client handshake _, err = wire.Write(our_greeting_packed.Bytes()) if err != nil { return nil, errors.New("wtf") } //LOG(LOG_DEBUG, "our client greeting of sent") // obtain the server handshake their_handshake_raw, err2 := KiSS_read_segment(wire) //LOG(LOG_DEBUG, "their server greeting of got") if err2 != nil { return nil, err2 } if their_handshake_raw.segment_type != K_HANDSHAKE_S { return nil, errors.New("wtf") } their_handshake, err3 := KiSS_unpack_server_handshake(their_handshake_raw.raw_payload, verify) if err3 != nil { return nil, err3 } // obtain the shared secret secret := kicrypt.SecureDH_gensecret(our_keypair.Private, their_handshake.public_edh_key) secret = append(secret, kicrypt.SecureDH_gensecret(our_keypair.Private, their_handshake.public_dh_key)...) upkey := kicrypt.KeyedHash(secret, "kiss-2-up") downkey := kicrypt.KeyedHash(secret, "kiss-2-down") // get the cipher thingies read_ciph := __KISS_AS(downkey) write_ciph := __KISS_AS(upkey) bt := new([]byte) *bt = make([]byte, 0) toret := KiSS_State{read_ciph, write_ciph, secret, 0, 0, wire, bt} return io.ReadWriteCloser(toret), nil }
func KiSS_handshake_server(wire io.ReadWriteCloser, keys kicrypt.SecureDH_keypair) (wr io.ReadWriteCloser, err error) { defer func() { if r := recover(); r != nil { err = errors.New(fmt.Sprint(r)) } }() // read their handshake their_greeting_packed, err1 := KiSS_read_segment(wire) if err1 != nil { return nil, err1 } if their_greeting_packed.segment_type != K_HANDSHAKE_C { return nil, errors.New("client sent something other than a handshake") } // unpack their greeting their_greeting, err2 := KiSS_unpack_client_handshake(their_greeting_packed.raw_payload) if err2 != nil { return nil, err2 } // send our handshake our_keypair := kicrypt.SecureDH_genpair() our_greeting := KiSS_Segment{K_HANDSHAKE_S, (KiSS_HS_Server{keys.Public, our_keypair.Public}).Pack()} _, err3 := wire.Write(our_greeting.Bytes()) if err3 != nil { return nil, err3 } // obtain the shared secret secret := kicrypt.SecureDH_gensecret(our_keypair.Private, their_greeting.public_edh_key) secret = append(secret, kicrypt.SecureDH_gensecret(keys.Private, their_greeting.public_edh_key)...) upkey := kicrypt.KeyedHash(secret, "kiss-2-up") downkey := kicrypt.KeyedHash(secret, "kiss-2-down") read_ciph := __KISS_AS(upkey) write_ciph := __KISS_AS(downkey) bt := new([]byte) *bt = make([]byte, 0) toret := KiSS_State{read_ciph, write_ciph, secret, 0, 0, wire, bt} //LOG(LOG_DEBUG, "keygens on server side of done") return io.ReadWriteCloser(toret), nil }
// Kirisurf_handshake_client returns a socket obfuscating the socket sock after // initiating the client-side handshake. func Kiriobfs_handshake_client(sock net.Conn) (net.Conn, error) { // generate our keypair our_keypair := kicrypt.UniformDH_genpair() scatch := make(chan bool, 16) //send our key c, err := sock.Write(our_keypair.PublicBytes()) LOG(LOG_DEBUG, "Sent our %d-byte key", c) if err != nil { return nil, errors.New("error encountered when sending uniformdh pubkey") } //send 16384 bytes of garbage go func() { for i := 0; i < 64; i++ { buf := make([]byte, 256) rand.Reader.Read(buf) c, err := sock.Write(buf) if err != nil && c == c { return } } scatch <- true }() // read their key buf := make([]byte, 192) _, ecd := io.ReadFull(sock, buf) if ecd != nil { return nil, ecd } LOG(LOG_DEBUG, "Read their %d-byte key", 192) theirpub := big.NewInt(0).SetBytes(buf) //read 16384 bytes of garbage from remote go func() { buf := make([]byte, 16384) _, err := io.ReadFull(sock, buf) if err != nil { return } scatch <- true }() //synchronize <-scatch <-scatch LOG(LOG_DEBUG, "All garbage-related things done.") //shared secret shared_secret := kicrypt.UniformDH_gensecret(our_keypair.Private, theirpub) up_key := kicrypt.KeyedHash(shared_secret, "kiriobfs/up") down_key := kicrypt.KeyedHash(shared_secret, "kiriobfs/down") LOG(LOG_DEBUG, "Shared secret derived.") //RC4 initialization var toret Kiriobfs_state toret.RC4_state_r, err = rc4.NewCipher(down_key) toret.RC4_state_w, err = rc4.NewCipher(up_key) toret.underlying = sock throwaway := make([]byte, 8192) toret.RC4_state_r.XORKeyStream(throwaway, throwaway) toret.RC4_state_w.XORKeyStream(throwaway, throwaway) //Actual garbage blarg := make([]byte, 2) rand.Reader.Read(blarg) bllen := big.NewInt(0).SetBytes(blarg).Int64() toret.Write(blarg) toret.Write(make([]byte, bllen)) LOG(LOG_DEBUG, "Encrypted junk sent.") //Read the actual garbage glarg := make([]byte, 2) io.ReadFull(net.Conn(toret), glarg) glwerg := make([]byte, big.NewInt(0).SetBytes(glarg).Int64()) io.ReadFull(net.Conn(toret), glwerg) return net.Conn(toret), nil }