Esempio n. 1
0
 public static DHWrapper BeginDiffieHellman(ref byte[] pubKey, bool initiator = false)
 {
     var dh = new DHWrapper();
     var size = dh.Keysize;
     byte[] newPubKey;
     if (initiator)
     {
         newPubKey = new byte[4 + size];
         newPubKey[0] = 0x81;
         newPubKey[1] = 0x02;
         newPubKey[2] = 0x1D;
         newPubKey[3] = 0x02;
         pubKey = newPubKey;
         Buffer.BlockCopy(dh.PublicKey, 0, newPubKey, 4, size);
         return dh;
     }
     var index = pubKey.Length;
     newPubKey = new byte[index + 4 + size];
     Buffer.BlockCopy(pubKey,0,newPubKey,0,index);
     var byte2 = (byte) (KEY_SIZE - size);
     if (byte2 > 2)
     {
         Logger.WARN("Generation DH key with less of 126 bytes!");
         byte2 = 2;
     }
     byte2 = (byte) (2 - byte2);
     newPubKey[index++] = 0x81;
     newPubKey[index++] = byte2;
     newPubKey[index++] = 0x0D;
     newPubKey[index++] = 0x02;
     Buffer.BlockCopy(dh.PublicKey, 0, newPubKey, index, size);
     pubKey = newPubKey;
     return dh;
 }
        private bool PerformHandshakeStage1(bool encrypted)
        {
            OutputBuffer.WriteByte((byte)(encrypted ? 6 : 3));
            _pOutputBuffer=new byte[1536];
            var rand = new Random();
            for (var i = 0; i < 1536; i++)
            {
                _pOutputBuffer[i] = (byte) (rand.Next()%256);
            }
            _pOutputBuffer[0] = _pOutputBuffer[1] = _pOutputBuffer[2] = _pOutputBuffer[3] = 0;
            // 5. Put the flash version. We impersonate with 9.0.124.2
            _pOutputBuffer[4] = 9;
            _pOutputBuffer[5] = 0;
            _pOutputBuffer[6] = 124;
            _pOutputBuffer[7] = 2;
            var clientDHOffset = GetDHOffset(_pOutputBuffer, _usedScheme);
            _pDHWrapper = new DHWrapper(1024);
            _pClientPublicKey = _pDHWrapper.PublicKey;
            Buffer.BlockCopy(_pClientPublicKey, 0, _pOutputBuffer, (int)clientDHOffset, 128);
            var clientDigestOffset = GetDigestOffset(_pOutputBuffer, _usedScheme);
            var pTempBuffer = new byte[1536 - 32];
            Buffer.BlockCopy(_pOutputBuffer, 0, pTempBuffer, 0, (int)clientDigestOffset);
            Buffer.BlockCopy(_pOutputBuffer, (int) (clientDigestOffset + 32), pTempBuffer, (int)clientDigestOffset, (int) (1536 - clientDigestOffset - 32));
            //var pTempHash = new byte[512];

            var pTempHash = HMACsha256(pTempBuffer,1536-32,GenuineFpKey,30 ); // Hmacsha256.ComputeHash(pTempBuffer, 0,1536 - 32);
            Buffer.BlockCopy(pTempHash, 0, _pOutputBuffer, (int) clientDigestOffset,32);
            _pClientDigest = new byte[32];
            Buffer.BlockCopy(pTempHash, 0, _pClientDigest, 0, 32);
            OutputBuffer.Write(_pOutputBuffer, 0, 1536);
            //_outputBuffer222.Write(_pOutputBuffer, 0, 1536);
            _pOutputBuffer = null;
            if (!EnqueueForOutbound(OutputBuffer))
            {
                Logger.FATAL("Unable to signal ouput data");
                return false;
            }
            _rtmpState = RTMPState.RTMP_STATE_CLIENT_REQUEST_SENT;

            return true;
        }
Esempio n. 3
0
 public Target(IPEndPoint address, Cookie cookie = null)
 {
     Address = address;
     IsPeer = cookie != null;
    
     if (address.Port == 0)
     {
         Address = new IPEndPoint(address.Address, RtmfpUtils.RTMFP_DEFAULT_PORT);
     }
     if (IsPeer)
     {
         DH = cookie.CookieComputing.DH;
         PublicKey = new byte[cookie.CookieComputing.Nonce.Length-7];
         Buffer.BlockCopy(cookie.CookieComputing.Nonce, 7, PublicKey,0,PublicKey.Length);
         PublicKey[3] = 0x1D;
        // uint s = 0;
         Id = Sha256.ComputeHash(PublicKey, 0, PublicKey.Length);
         //Native.EVP_Digest(PublicKey, (uint) PublicKey.Length, Id, ref s, Native.EVP_sha256(), IntPtr.Zero);
         cookie.CookieComputing.DH = null;
     }
 }
Esempio n. 4
0
        public void Run()
        {
            if(DH == null) {
		        DH = RtmfpUtils.BeginDiffieHellman(ref Nonce);
		        return;
	        }
	        // Compute Diffie-Hellman secret
            SharedSecret = DH.CreateSharedKey(InitiatorKey);
             // Compute Keys
            RtmfpUtils.ComputeAsymetricKeys(SharedSecret, InitiatorNonce, Nonce, out DecryptKey,out EncryptKey);
            var pSession = _handshake?.CreateSession(Value);
            if (pSession != null)
            {
                pSession.Peer.UserState = this;
            }
        }
Esempio n. 5
0
 public CookieComputing(OutboundHandshake handshake)
 {
     Nonce = new byte[0];
     DH = RtmfpUtils.BeginDiffieHellman(ref Nonce, true);
     
 }
Esempio n. 6
0
        public override void PacketHandler(N2HBinaryReader reader)
        {
            if(Checked){
                lock (Writer)
                {
                    base.PacketHandler(reader);
                }
                return;
            }
            var marker = reader.ReadByte();
            if (marker != 0x0b)
            {
                Logger.FATAL("Marker hand shake wrong:should be 0b and not {0:X}", marker);
                return;
            }
            var time = reader.ReadUInt16();
            var type = reader.ReadByte();
            var length = reader.ReadUInt16();
            byte[] tag;
            Logger.Debug("handshake {0:X} len:{1}",type,length);
            switch (type)
            {
                case 0x70:
              
                    tag = reader.ReadBytes(reader.ReadByte());
                    var cookieBytes = reader.ReadBytes(reader.ReadByte());
                    var targetCertificat = reader.ReadBytes((int)reader.BaseStream.GetAvaliableByteCounts());
                    var nonce = new byte[0];
                    _dh = RtmfpUtils.BeginDiffieHellman(ref nonce, true);
                    Peer.Id = Target.Sha256.ComputeHash(nonce, 0, nonce.Length);
                    HandShake38(cookieBytes, nonce);
                    _handshake = () => HandShake38(cookieBytes, nonce);
                    break;
                case 0x71:
                    tag = reader.ReadBytes(reader.ReadByte());
                    var flag = reader.ReadByte();
                    var address = new IPEndPoint(new IPAddress(reader.ReadBytes(4)), reader.ReadInt16());
                    Target.Address.Port = address.Port;
                    Logger.Debug("redirect to {0}",address.ToString());
                    Handler.FarProtocol.IOHandler.Socket.Connect(Target.Address);
                    _handshake();
                    break;
                case 0x78:
                  
                    FarId = reader.ReadUInt32();
                    var targetNonce = reader.ReadBytes((int)reader.Read7BitLongValue());
                    var must58 = reader.ReadByte();
                    Debug.WriteLineIf(must58!=0x58,$"must58!{must58}");
                    var key = new byte[RtmfpUtils.KEY_SIZE];
                    Buffer.BlockCopy(targetNonce, targetNonce.Length - RtmfpUtils.KEY_SIZE, key, 0, RtmfpUtils.KEY_SIZE);
                    var  sharedSecret = _dh.CreateSharedKey(key);
                    byte[] decryptKey;
                    byte[] encryptKey;
                    RtmfpUtils.ComputeAsymetricKeys(sharedSecret, _certificat, targetNonce, out encryptKey, out decryptKey);
                    Checked = true;
                    _handshakeTimeoutTimer.Stop();
                    AesEncrypt = new AESEngine(encryptKey, AESEngine.Direction.ENCRYPT);
                    AesDecrypt = new AESEngine(decryptKey);
                    PrevAesType = AESEngine.AESType.DEFAULT;
                    Application = Handler.Application;
                    Handler.CreateSession(Peer, null);

                    break;
                default:

                    break;
            }

        }
        bool PerformHandshake(InputStream buffer, bool encrypted)
        {
            if (!ValidateClient(buffer))
            {
                if (encrypted || _pProtocolHandler.ValidateHandshake)
                {
                    Logger.FATAL("Unable to validate client");
                    return false;
                }
                else
                {
                    Logger.WARN("Client not validated");
                    _validationScheme = 0;
                }
            }
            _pOutputBuffer = Utils.GenerateRandomBytes(3072);
            _pOutputBuffer.Write(0, (uint)DateTime.Now.SecondsFrom1970());
            _pOutputBuffer.Write(0, (uint)0);
            var serverBytes = Encoding.ASCII.GetBytes(Defines.HTTP_HEADERS_SERVER_US);
            for (var i = 0; i < 10; i++)
            {
                var index = Utils.Random.Next(0, 3072 - Defines.HTTP_HEADERS_SERVER_US_LEN);
                Buffer.BlockCopy(serverBytes, 0, _pOutputBuffer, index, serverBytes.Length);
            }

            var _pOutputBufferWithOffset = new BufferWithOffset(_pOutputBuffer);
            var pInputBuffer = new BufferWithOffset(buffer);
            var serverDHOffset = GetDHOffset(_pOutputBufferWithOffset, _validationScheme);
            var clientDHOffset = GetDHOffset(pInputBuffer, _validationScheme);
            var dhWrapper = new DHWrapper();
            var pubKeyIn = new byte[128];
            Buffer.BlockCopy(buffer.GetBuffer(), (int)(buffer.Position + clientDHOffset), pubKeyIn, 0, 128);
            var sharedkey = dhWrapper.CreateSharedKey(pubKeyIn);
            var pubKeyOut = dhWrapper.PublicKey;
            Buffer.BlockCopy(pubKeyOut, 0, _pOutputBuffer, (int)serverDHOffset, 128);
            if (encrypted)
            {
                _pKeyIn = new RC4_KEY();
                _pKeyOut = new RC4_KEY();
                Utils.InitRC4Encryption(sharedkey, pubKeyIn, pubKeyOut, _pKeyIn, _pKeyOut);
                var data = new byte[1536];
                Utils.RC4(data, _pKeyIn, 1536);
                Utils.RC4(data, _pKeyOut, 1536);
            }
            var serverDigestOffset = GetDigestOffset(_pOutputBufferWithOffset, _validationScheme);
            var pTempBuffer = new byte[1536 - 32];
            Buffer.BlockCopy(_pOutputBuffer, 0, pTempBuffer, 0, (int)serverDigestOffset);
            Buffer.BlockCopy(_pOutputBuffer, (int)serverDigestOffset + 32, pTempBuffer, (int)serverDigestOffset, (int)(1536 - serverDigestOffset - 32));
            var pTempHash = HMACsha256(pTempBuffer, 1536 - 32, GenuineFmsKey, 36);
            Buffer.BlockCopy(pTempHash, 0, _pOutputBuffer, (int)serverDigestOffset, 32);
            var keyChallengeIndex = GetDigestOffset(pInputBuffer, _validationScheme);
            pInputBuffer.Offset += (int)keyChallengeIndex;
            pTempHash = HMACsha256(pInputBuffer, 32, GenuineFmsKey, 68);
            Buffer.BlockCopy(_pOutputBuffer, 1536, pTempBuffer, 0, 1536 - 32);
            pTempBuffer = new HMACSHA256(pTempHash).ComputeHash(pTempBuffer, 0, 1536 - 32);
            Buffer.BlockCopy(pTempBuffer, 0, _pOutputBuffer, 1536 * 2 - 32, 32);
            OutputBuffer.WriteByte((byte)(encrypted ? 6 : 3));
            OutputBuffer.Write(_pOutputBuffer, 0, 3072);
            buffer.Recycle(true);
            if (!EnqueueForOutbound(OutputBuffer))
            {
                Logger.FATAL("Unable to signal outbound data");
                return false;
            }
            _rtmpState = RTMPState.RTMP_STATE_SERVER_RESPONSE_SENT;
            return true;
        }