private bool PerformHandshakeStage2(InputStream inputBuffer, bool encrypted) { if (encrypted || _pProtocolHandler.ValidateHandshake) { if (!VerifyServer(inputBuffer)) { Logger.FATAL("Unable to verify server"); return(false); } } var pBuffer = new BufferWithOffset(inputBuffer); pBuffer.Offset++; var serverDHOffset = GetDHOffset(pBuffer, _usedScheme); if (_pDHWrapper == null) { Logger.FATAL("dh wrapper not initialized"); return(false); } var pubKey = new byte[128]; Buffer.BlockCopy(pBuffer.Buffer, (pBuffer.Offset + (int)serverDHOffset), pubKey, 0, 128); var secretKey = _pDHWrapper.CreateSharedKey(pubKey); if (encrypted) { _pKeyIn = new RC4_KEY(); _pKeyOut = new RC4_KEY(); var pubKeyIn = new byte[128]; Buffer.BlockCopy(pBuffer.Buffer, (int)(pBuffer.Offset + serverDHOffset), pubKeyIn, 0, 128); Utils.InitRC4Encryption(secretKey, pubKeyIn, _pClientPublicKey, _pKeyIn, _pKeyOut); } var serverDigestOffset = GetDigestOffset(pBuffer, _usedScheme); _pOutputBuffer = Utils.GenerateRandomBytes(1536); pBuffer.Offset += (int)serverDigestOffset; var pChallangeKey = HMACsha256(pBuffer, 32, GenuineFpKey, 62);//Hmacsha256.ComputeHash(pBuffer.Buffer, pBuffer.Offset, 32); var pDigest = new HMACSHA256(pChallangeKey).ComputeHash(_pOutputBuffer, 0, 1536 - 32); Buffer.BlockCopy(pDigest, 0, _pOutputBuffer, 1536 - 32, 32); OutputBuffer.Write(_pOutputBuffer, 0, 1536); _pOutputBuffer = null; _rtmpState = RTMPState.RTMP_STATE_DONE; return(true); }
private bool PerformHandshakeStage2(InputStream inputBuffer, bool encrypted) { if (encrypted || _pProtocolHandler.ValidateHandshake) { if (!VerifyServer(inputBuffer)) { Logger.FATAL("Unable to verify server"); return false; } } var pBuffer = new BufferWithOffset(inputBuffer); pBuffer.Offset++; var serverDHOffset = GetDHOffset(pBuffer, _usedScheme); if (_pDHWrapper == null) { Logger.FATAL("dh wrapper not initialized"); return false; } var pubKey= new byte[128]; Buffer.BlockCopy(pBuffer.Buffer, (pBuffer.Offset + (int)serverDHOffset), pubKey, 0, 128); var secretKey = _pDHWrapper.CreateSharedKey(pubKey); if (encrypted) { _pKeyIn = new RC4_KEY(); _pKeyOut = new RC4_KEY(); var pubKeyIn = new byte[128]; Buffer.BlockCopy(pBuffer.Buffer,(int) (pBuffer.Offset+serverDHOffset),pubKeyIn,0,128); Utils.InitRC4Encryption(secretKey, pubKeyIn, _pClientPublicKey,_pKeyIn,_pKeyOut); } var serverDigestOffset = GetDigestOffset(pBuffer, _usedScheme); _pOutputBuffer = Utils.GenerateRandomBytes(1536); pBuffer.Offset += (int)serverDigestOffset; var pChallangeKey = HMACsha256(pBuffer, 32, GenuineFpKey, 62);//Hmacsha256.ComputeHash(pBuffer.Buffer, pBuffer.Offset, 32); var pDigest = new HMACSHA256(pChallangeKey).ComputeHash(_pOutputBuffer, 0, 1536 - 32); Buffer.BlockCopy(pDigest,0,_pOutputBuffer,1536-32,32); OutputBuffer.Write(_pOutputBuffer, 0, 1536); _pOutputBuffer = null; _rtmpState = RTMPState.RTMP_STATE_DONE; return true; }
//public InputStream InputBuffer; //public OutputStream OutputBuffer; public RTMPEProtocol(RC4_KEY pKeyIn, RC4_KEY pKeyOut, uint skipBytes = 0) { _pKeyIn = pKeyIn; _pKeyOut = pKeyOut; _skipBytes = skipBytes; }
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; }
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); }