func (y *Conn) sendCall(session uint32, dial *connDial, tube tube.TubedConn) { subject := &U_Subject{dial.Subject} err := tube.Encode(subject) if err != nil || y.setRegime(regimeBusy) != nil { y.kill(os.ErrorString("d,conn: send call")) dial.Notify <- nil return } //fmt.Printf(term.FgCyan+"d·conn[%#p] —— dial tone, subject=%s\n"+term.Reset, y, dial.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() dial.Notify <- h }
// 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 }