/// <summary> /// Initializes a new instance of the <see cref="Session"/> class. /// </summary> protected Session() { _id = Crypto8.GenerateNonce(); #if DEBUG _ident = InternalUtils.BytesToString(_id); #endif }
private byte[] ProcessOutgoingData(MessageDirection direction, byte[] plaintext) { var chiper = (byte[])null; // Handshaking if (_outgoingState == 0) { chiper = (byte[])plaintext.Clone(); _direction = direction; if (_crypto == null) { _crypto = new Crypto8(direction, _keyPair); } } if (direction != _direction) { throw new InvalidOperationException("Tried to process an outgoing message coming from a different direction."); // -> Protocol Exception? } // _outgoingState == 2 means we're the server. // Usually processing 20104 - LoginSuccessMessage. if (_outgoingState == 2) { Debug.Assert(_remoteNonce != null); Debug.Assert(_localNonce == null); var key = Crypto8.GenerateKeyPair(); var localNonce = Crypto8.GenerateNonce(); var remoteNonce = _remoteNonce; var tmpChiper = new byte[plaintext.Length + KeyPair.NonceLength + KeyPair.KeyLength]; Buffer.BlockCopy(localNonce, 0, tmpChiper, 0, KeyPair.NonceLength); Buffer.BlockCopy(key.PublicKey, 0, tmpChiper, KeyPair.NonceLength, KeyPair.KeyLength); Buffer.BlockCopy(plaintext, 0, tmpChiper, KeyPair.NonceLength + KeyPair.KeyLength, plaintext.Length); _crypto.Encrypt(ref tmpChiper); Debug.WriteLine($"Server-nonce: {ToHexString(localNonce)}"); Debug.WriteLine($"Shared-key: {ToHexString(key.PublicKey)}"); _crypto.UpdateNonce(localNonce, UpdateNonceType.Encrypt); _crypto.UpdateSharedKey(key.PublicKey); _localNonce = localNonce; chiper = tmpChiper; //_key = key; } // _outgoingState == 3 means we're the client. // Usually processing 10101 - LoginRequestMessage. else if (_outgoingState == 3) { var serverKey = _serverKey; var sessionKey = _sessionKey; Debug.Assert(serverKey != null, "Server key was null."); Debug.Assert(sessionKey != null, "Session key was null."); // Generate a ClientNonce. var localNonce = Crypto8.GenerateNonce(); Debug.WriteLine($"Generated ClientNonce: {ToHexString(localNonce)}"); // Craft the new packet which is // tmpChiper = sessionKey + localNonce + plaintext. var tmpChiper = new byte[plaintext.Length + KeyPair.NonceLength * 2]; Buffer.BlockCopy(sessionKey, 0, tmpChiper, 0, KeyPair.NonceLength); Buffer.BlockCopy(localNonce, 0, tmpChiper, KeyPair.NonceLength, KeyPair.NonceLength); Buffer.BlockCopy(plaintext, 0, tmpChiper, KeyPair.NonceLength * 2, plaintext.Length); // Use our specified from the constructor _keyPair.PublicKey and specified _serverKey from the constructor // to generate the blake2b nonce and encrypt using _keyPair.PrivateKey and the generated blake2b nonce. _crypto.UpdateSharedKey(serverKey); _crypto.Encrypt(ref tmpChiper); // Craft another new packet which is // chiper = _keyPair.PublicKey + tmpChiper. chiper = new byte[tmpChiper.Length + KeyPair.KeyLength]; Buffer.BlockCopy(_crypto.KeyPair.PublicKey, 0, chiper, 0, KeyPair.KeyLength); Buffer.BlockCopy(tmpChiper, 0, chiper, KeyPair.KeyLength, tmpChiper.Length); _localNonce = localNonce; } // Messages after the previous states are processed the same way. else if (_outgoingState > (int)_direction) { var tmpChiper = (byte[])plaintext.Clone(); _crypto.Encrypt(ref tmpChiper); chiper = tmpChiper; } return(chiper); }