func (y *Conn) receiveCall(session uint32, tube tube.TubedConn) (subject string, rwc io.ReadWriteCloser, err os.Error) { u_subject := &U_Subject{} err = tube.Decode(u_subject) if err != nil || u_subject.Subject == "" || y.setRegime(regimeBusy) != nil { err = y.kill(os.ErrorString("d,conn: receive call")) return "", nil, err } //fmt.Printf(term.FgCyan + "d·conn[%#p] —— ring! subject=%s\n"+term.Reset, y, u_subject.Subject) y.hlk.Lock() h := newHandoff(y, session, func() { y.setRegime(regimeReady) y.lk.Lock() y.h = nil y.lk.Unlock() y.hlk.Unlock() }) y.lk.Lock() y.h = h y.lk.Unlock() return u_subject.Subject, h, nil }
// authHello establishes a symmetrically encrypted channel over t func authHello(t tube.TubedConn) (tube.TubedConn, os.Error) { // Make my hello private key HelloA := GenerateHelloKey() HelloA_proto := HelloA.Proto() // Send my hello public key err := t.Encode(HelloA_proto) if err != nil { return nil, err } // Receive their hello public key HelloB_proto := &U_HelloKey{} err = t.Decode(HelloB_proto) if err != nil { return nil, err } HelloB, err := UnprotoHelloPubKey(HelloB_proto) if err != nil { return nil, err } // Make my session key half HalvesA := GenerateKeyHalves() // Encrypt my session key half with their intro public key HalvesA_HelloB, err := crypto.EncryptShortMsg(HelloB.RSAPubKey(), HalvesA.Bytes(), []byte("key-halves")) if err != nil { return nil, err } // Send my encrypted session half key err = t.Encode(&U_KeyHalves{HalvesA_HelloB}) if err != nil { return nil, err } // Receive their session key half, encrypted with my intro private key HalvesB_HelloA_proto := &U_KeyHalves{} err = t.Decode(HalvesB_HelloA_proto) if err != nil { return nil, err } // Decrypt their session key half HalvesB_bytes, err := crypto.DecryptShortMsg(HelloA.RSAPrivKey(), HalvesB_HelloA_proto.Halves, []byte("key-halves")) if err != nil { return nil, err } HalvesB, err := BytesToKeyHalves(HalvesB_bytes) if err != nil { return nil, err } // Compute session keys me->them and them->me keyAB := makeSessionKey("SK", HalvesA.Bytes(), HalvesB.Bytes(), HelloA.RSAPubKey(), HelloB.RSAPubKey()) keyBA := makeSessionKey("SK", HalvesB.Bytes(), HalvesA.Bytes(), HelloB.RSAPubKey(), HelloA.RSAPubKey()) // Create encrypted tube return tube.NewRC4Tube(t, keyBA, keyAB), nil }