// Decrypt the Hello using the node's private comms key, and decode its // contents. func ServerDecryptHello(ciphertext []byte, ckPriv *rsa.PrivateKey, rng *xr.PRNG) ( sOneShot *AesSession, version1s uint32, err error) { if rng == nil { rng = xr.MakeSystemRNG() } sha := sha1.New() data, err := rsa.DecryptOAEP(sha, nil, ckPriv, ciphertext, nil) // DEBUG if err == nil { expectedLen := 2*aes.BlockSize + 12 if len(data) != expectedLen { fmt.Printf("expected OAEP packet len %d, actual %d bytes\n", expectedLen, len(data)) err = WrongOAEPSize // XXX BAD NAME } } // END if err == nil { key1s := data[:2*aes.BlockSize] // salt1s = data[2*aes.BlockSize : 2*aes.BlockSize+8] vBytes := data[2*aes.BlockSize+8:] version1s = uint32(vBytes[0]) | uint32(vBytes[1])<<8 | uint32(vBytes[2])<<16 | uint32(vBytes[3])<<24 sOneShot, err = NewAesSession(key1s, rng) } return }
// Create an AES IV and key and an 8-byte salt, then encrypt these and // the proposed protocol version using the server's comms public key. func ClientEncryptHello(version1 uint32, ck *rsa.PublicKey, rng *xr.PRNG) ( cOneShot *AesSession, ciphertext []byte, err error) { if rng == nil { rng = xr.MakeSystemRNG() } vBytes := make([]byte, 4) vBytes[0] = byte(version1) vBytes[1] = byte(version1 >> 8) vBytes[2] = byte(version1 >> 16) vBytes[3] = byte(version1 >> 24) // Generate 32-byte AES key, and 8-byte salt for the Hello salty := make([]byte, 2*aes.BlockSize+8+20) rng.NextBytes(salty) key1 := salty[:2*aes.BlockSize] // salt1 := salty[2*aes.BlockSize : 2*aes.BlockSize+8] oaep1 := salty[2*aes.BlockSize+8:] oaepSalt := bytes.NewBuffer(oaep1) sha := sha1.New() data := salty[:2*aes.BlockSize+8] // contains key1,salt1 data = append(data, vBytes...) // ... plus preferred protocol version ciphertext, err = rsa.EncryptOAEP(sha, oaepSalt, ck, data, nil) if err == nil { cOneShot, err = NewAesSession(key1, rng) } return }
func MakeHelloMsg(n *xn.Node) (m *XLatticeMsg, err error) { var ck, sk, salt, sig []byte cmd := XLatticeMsg_Hello id := n.GetNodeID().Value() ck, err = xc.RSAPubKeyToWire(n.GetCommsPublicKey()) if err == nil { sk, err = xc.RSAPubKeyToWire(n.GetSigPublicKey()) } if err == nil { sysRNG := xr.MakeSystemRNG() salt = make([]byte, 8) sysRNG.NextBytes(salt) chunks := [][]byte{id, ck, sk, salt} sig, err = n.Sign(chunks) } if err == nil { m = &XLatticeMsg{ Op: &cmd, MsgN: &ONE, ID: id, CommsKey: ck, SigKey: sk, Salt: salt, Sig: sig, } } return }
func (mm *MemberMaker) SessionSetup(proposedVersion uint32) ( cnx *xt.TcpConnection, decidedVersion uint32, err error) { var ( ciphertext1 []byte ciphertext2 []byte ) // Set up connection to server. --------------------------------- ctor := mm.RegPeer.GetConnector(0) // DEBUG fmt.Printf(" SessionSetup: ctor is %s\n", ctor.String()) // END var conn xt.ConnectionI //conn, err = ctor.Connect(xt.ANY_TCP_END_POINT) // 2016-11-14 conn, err = ctor.Connect(nil) if err == nil { cnx = conn.(*xt.TcpConnection) // DEBUG fmt.Printf(" SessionSetup: cnx is %s\n", cnx.String()) // END var cnxHandler *CnxHandler if err == nil { cnxHandler, err = NewCnxHandler(cnx, nil, nil) if err == nil { cnxHandler.State = MEMBER_START mm.CnxHandler = *cnxHandler } } } if err == nil { var cOneShot, cSession *xa.AesSession // Send HELLO ----------------------------------------------- mm.Cnx = cnx ck := mm.RegPeer.GetCommsPublicKey() rng := xr.MakeSystemRNG() cOneShot, ciphertext1, err = xa.ClientEncryptHello( proposedVersion, ck, rng) if err == nil { err = mm.WriteData(ciphertext1) // Process HELLO REPLY ---------------------------------- if err == nil { ciphertext2, err = mm.ReadData() if len(ciphertext2) == 0 { if err == nil { err = io.EOF } } if err == nil { cSession, decidedVersion, err = xa.ClientDecryptHelloReply(cOneShot, ciphertext2) if err == nil { mm.AesSession = *cSession } } } } } return }
// An AesSession establishes one side of a two-sided relationship. Encryption // and decryption share the same key (although per-direction keys could be // supported in a slightly different implementation). If a random number // generator (RNG) is not supplied, it uses a secure (and expensive) system // RNG. If no key is supplied it creates a random 256-bit AES key. // func NewAesSession(key []byte, rng *xr.PRNG) (session *AesSession, err error) { if rng == nil { rng = xr.MakeSystemRNG() } if key == nil || len(key) == 0 { key = make([]byte, 2*aes.BlockSize) } engine, err := aes.NewCipher(key) if err == nil { session = &AesSession{ Engine: engine, Key: key, RNG: rng, } } return session, err }
func New(id []byte) (q *NodeID, err error) { q = new(NodeID) if id == nil { id = make([]byte, xu.SHA1_BIN_LEN) rng := xr.MakeSystemRNG() rng.NextBytes(id) q._nodeID = id } else { // deep copy the slice size := len(id) myID := make([]byte, size) for i := 0; i < size; i++ { myID[i] = id[i] } q._nodeID = myID } if !IsValidID(id) { err = BadNodeIDLen } return }
func (upc *UpaxClient) SessionSetup(proposedVersion uint32) ( upcx *xt.TcpConnection, decidedVersion uint32, err error) { var ( ciphertext1, ciphertext2 []byte cOneShot, cSession *xa.AesSession ) rng := xr.MakeSystemRNG() // Set up connection to server. ----------------------------- ctor, err := xt.NewTcpConnector(upc.serverEnd) if err == nil { var conn xt.ConnectionI conn, err = ctor.Connect(nil) if err == nil { upcx = conn.(*xt.TcpConnection) } } // Send HELLO ----------------------------------------------- if err == nil { upc.Cnx = upcx cOneShot, ciphertext1, err = xa.ClientEncryptHello( proposedVersion, upc.serverCK, rng) } if err == nil { err = upc.WriteData(ciphertext1) } // Process HELLO REPLY -------------------------------------- if err == nil { ciphertext2, err = upc.ReadData() } if err == nil { cSession, decidedVersion, err = xa.ClientDecryptHelloReply( cOneShot, ciphertext2) } // Set up AES engines --------------------------------------- if err == nil { upc.AesSession = *cSession upc.Version = xu.DecimalVersion(decidedVersion) } return }
// The client has sent the server a one-time AES key+iv encrypted with // the server's RSA comms public key. The server creates the real // session iv+key and returns them to the client encrypted with the // one-time key+iv. // // XXX This is simply a copy of the function in s_in_handler.go, with // "Out" inserted: we definitely need to refactor! // func handleOutPeerHello(h *ClusterOutHandler) (err error) { var ( ciphertext, ciphertextOut []byte version1 uint32 sOneShot, sSession *xa.AesSession rng *xr.PRNG ) ciphertext, err = h.ReadData() if err == nil { rng = xr.MakeSystemRNG() sOneShot, version1, err = xa.ServerDecryptHello( ciphertext, h.us.ckPriv, rng) } if err == nil { _ = version1 // just ignored for now version2 := uint32(serverVersion) sSession, ciphertextOut, err = xa.ServerEncryptHelloReply( sOneShot, version2) if err == nil { h.AesSession = *sSession err = h.WriteData(ciphertextOut) } if err == nil { h.version = uint32(version2) h.State = S_HELLO_RCVD } } // On any error silently close the connection and delete the handler, // an exciting thing to do. if err != nil { // DEBUG fmt.Printf("handleOutPeerHello closing cnx, error was %v\n", err) // END h.Cnx.Close() h = nil } return }
// The client has sent the server a one-time AES key+iv encrypted with // the server's RSA comms public key. The server creates the real // session iv+key and returns them to the client encrypted with the // one-time key+iv. func handleClientHello(h *ClientInHandler) (err error) { var ( ciphertext, ciphertextOut []byte version1, version2 uint32 sOneShot, sSession *xa.AesSession ) rng := xr.MakeSystemRNG() ciphertext, err = h.ReadData() if err == nil { sOneShot, version1, err = xa.ServerDecryptHello( ciphertext, h.us.ckPriv, rng) _ = version1 // we don't actually use this } if err == nil { version2 = uint32(serverVersion) // a global ! sSession, ciphertextOut, err = xa.ServerEncryptHelloReply( sOneShot, version2) if err == nil { h.AesSession = *sSession err = h.WriteData(ciphertextOut) } if err == nil { h.version = version2 h.State = C_HELLO_RCVD } } // On any error silently close the connection. if err != nil { // DEBUG fmt.Printf("handleClientHello closing cnx, error was %s\n", err.Error()) // END h.Cnx.Close() } return }