private bool VerifyServer(InputStream inputBuffer) { var pBuffer = new BufferWithOffset(inputBuffer); pBuffer.Offset++; var serverDigestPos = GetDigestOffset(pBuffer, _usedScheme); var pTempBuffer = new byte[1536 - 32]; Buffer.BlockCopy(inputBuffer.GetBuffer(), pBuffer.Offset, pTempBuffer, 0, (int)serverDigestPos); Buffer.BlockCopy(inputBuffer.GetBuffer(), (int)(pBuffer.Offset + serverDigestPos + 32), pTempBuffer, (int)serverDigestPos, (int)(1536 - serverDigestPos - 32)); var pDigest = HMACsha256(pTempBuffer, 1536 - 32, GenuineFmsKey, 36); for (var i = 0; i < 32; i++) { if (pDigest[i] != pBuffer[(int)(i + serverDigestPos)]) { Logger.FATAL("Server not verified"); return(false); } } pBuffer.Offset += 1536; var pChallange = HMACsha256(_pClientDigest, 32, GenuineFmsKey, 68); pDigest = new HMACSHA256(pChallange).ComputeHash(pBuffer.Buffer, pBuffer.Offset, 1536 - 32); for (var i = 0; i < 32; i++) { if (pDigest[i] != pBuffer[i + 1536 - 32]) { Logger.FATAL("Server not verified"); return(false); } } return(true); }
public override void SendStreamMessage(BufferWithOffset buffer) { int skipCount = buffer[2]; skipCount = ((skipCount << 8) | buffer[3]); buffer.Offset = skipCount + 4; Writer.WriteAMFPacket(Encoding.UTF8.GetString(buffer.Buffer, 4, skipCount)).Write(buffer.Buffer, buffer.Offset, buffer.Length); }
public override void SendStreamMessage(BufferWithOffset buffer) { var header = new Header(); header.Reset(0, 3, 0, (uint)buffer.Length, Defines.RM_HEADER_MESSAGETYPE_FLEXSTREAMSEND, RTMPStreamId); Protocol.ChunkAmfMessage(header, buffer, OutputStream); Protocol.EnqueueForOutbound(OutputStream); }
public override void SendStreamMessage(BufferWithOffset buffer) { _file.Bw.Write(Defines.RM_HEADER_MESSAGETYPE_FLEXSTREAMSEND); _file.Bw.Write24(buffer.Length); _file.Bw.WriteS32(0); _file.Bw.Write24(0); _file.DataStream.Write(buffer.Buffer, buffer.Offset, buffer.Length); _file.Bw.Write((uint)buffer.Length + 11); }
public override void SendStreamMessage(BufferWithOffset buffer) { Protocol.Send(ClusterMessageType.StreamMessage, o => { o.Write7BitValue(StreamId); o.Write7BitValue((uint)buffer.Length); o.Write(buffer.Buffer); }); }
public uint GetDHOffset1(BufferWithOffset pBuffer) { var offset = (uint)(pBuffer[768] + pBuffer[769] + pBuffer[770] + pBuffer[771]); offset = offset % 632; offset = offset + 8; if (offset + 128 >= 1536) { ASSERT("Invalid DH offset"); } return(offset); }
public uint GetDigestOffset0(BufferWithOffset pBuffer) { var offset = (uint)(pBuffer[8] + pBuffer[9] + pBuffer[10] + pBuffer[11]); offset = offset % 728; offset = offset + 12; if (offset + 32 >= 1536) { ASSERT("Invalid digest offset"); } return(offset); }
public uint GetDHOffset0(BufferWithOffset pBuffer) { var offset = (uint)(pBuffer[1532] + pBuffer[1533] + pBuffer[1534] + pBuffer[1535]); offset = offset % 632; offset = offset + 772; if (offset + 128 >= 1536) { ASSERT("Invalid DH offset"); } return(offset); }
public uint GetDigestOffset1(BufferWithOffset pBuffer) { var offset = (uint)(pBuffer[772] + pBuffer[773] + pBuffer[774] + pBuffer[775]); offset = offset % 728; offset = offset + 776; if (offset + 32 >= 1536) { ASSERT("Invalid digest offset"); } return(offset); }
public uint GetDigestOffset(BufferWithOffset pBuffer, byte schemeNumber) { switch (schemeNumber) { case 0: return(GetDigestOffset0(pBuffer)); case 1: return(GetDigestOffset1(pBuffer)); default: WARN("Invalid scheme number: {0}. Defaulting to 0", schemeNumber); return(GetDigestOffset0(pBuffer)); } }
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); }
}; // 62 public static byte[] HMACsha256(BufferWithOffset pData, uint dataLength, byte[] key, uint keyLength) { byte[] _key; if (keyLength != key.Length) { _key = new byte[keyLength]; Buffer.BlockCopy(key, 0, _key, 0, (int)keyLength); } else { _key = key; } var hmac = new HMACSHA256(_key); return(hmac.ComputeHash(pData.Buffer, pData.Offset, (int)dataLength)); }
public OutboundConnectivity(bool forceTcp, RtspProtocol pRTSPProtocol) { _forceTcp = forceTcp; _rtspProtocol = pRTSPProtocol; _dataMessage = new MsgHdr(); _rtcpMessage = new MsgHdr { Buffers = new[] { new byte[28] } }; _rtcpMessage.Buffers[0][0] = 0x80; _rtcpMessage.Buffers[0][1] = 0xc8; _rtcpMessage.Buffers[0].Write(2, (ushort)6); _rtcpNTP = new BufferWithOffset(_rtcpMessage.Buffers[0], 8); _rtcpRTP = new BufferWithOffset(_rtcpMessage.Buffers[0], 16); _rtcpSPC = new BufferWithOffset(_rtcpMessage.Buffers[0], 20); _rtcpSOC = new BufferWithOffset(_rtcpMessage.Buffers[0], 24); _startupTime = DateTime.Now; }
//public override bool AllowNearProtocol(ulong type) //{ // Logger.FATAL("This protocol doesn't allow any near protocols"); // return false; //} //public override bool AllowFarProtocol(ulong type) //{ // return type == ProtocolTypes.PT_TCP || type == ProtocolTypes.PT_RTMPE || type == ProtocolTypes.PT_INBOUND_SSL || // type == ProtocolTypes.PT_INBOUND_HTTP_FOR_RTMP; //} public void ChunkAmfMessage(Header header, BufferWithOffset input, MemoryStream output) { var channel = GetChannel(header.ChannelId); long available; while ((available = input.Length) != 0) { header.Write(channel, output); if (available > _outboundChunkSize) { available = _outboundChunkSize; } output.Write(input.Buffer, input.Offset, (int)available); channel.lastOutProcBytes += (uint)available; input.Offset += (int)available; } channel.lastOutProcBytes = 0; }
public bool SignalOutputData(EndPoint address, MemoryStream outputStream) { var outputBuffer = new BufferWithOffset(outputStream); while (outputBuffer.Length > 0) { var sendCount = Socket.SendTo(outputBuffer.Buffer, outputBuffer.Offset, outputBuffer.Length, SocketFlags.None, address); if (sendCount < 0) { break; } outputBuffer.Offset += sendCount; } outputStream.SetLength(0); return(true); }
public override bool EnqueueForOutbound(MemoryStream outputStream, int offset = 0) { var pOutputBuffer = _nearProtocol.OutputBuffer; if (pOutputBuffer == null) { return(true); } var buffer = new BufferWithOffset(pOutputBuffer, true) { Offset = (int)_skipBytes }; Utils.RC4(buffer, _pKeyOut, buffer.Length); _skipBytes = 0; buffer.Offset = 0; OutputBuffer.Write(buffer.Buffer, buffer.Offset, buffer.Length); return(_farProtocol == null || _farProtocol.EnqueueForOutbound(outputStream)); }
private bool ValidateClientScheme(InputStream inputBuffer, byte scheme) { var pBuffer = new BufferWithOffset(inputBuffer); var clientDigestOffset = GetDigestOffset(pBuffer, scheme); var pTempBuffer = new byte[1536 - 32]; Buffer.BlockCopy(pBuffer.Buffer, pBuffer.Offset, pTempBuffer, 0, (int)clientDigestOffset); Buffer.BlockCopy(pBuffer.Buffer, (int)(pBuffer.Offset + clientDigestOffset + 32), pTempBuffer, (int)clientDigestOffset, (int)(1536 - clientDigestOffset - 32)); var pTempHash = HMACsha256(pTempBuffer, 1536 - 32, GenuineFpKey, 30);//Hmacsha256.ComputeHash(pTempBuffer, 0, 1536 - 32); for (var i = 0; i < 32; i++) { if (pBuffer[(int)(clientDigestOffset + i)] != pTempHash[i]) { return(false); } } return(true); }
protected override bool FeedOtherType() { if (_currentFrame.Type == MediaFrameType.Message && OutStreams.Last() is BaseOutNetRTMPStream) { if (!_pFile.SeekTo(_currentFrame.Start)) { FATAL("Unable to seek to position {0}", _currentFrame.Start); return(false); } var buffer = new BufferWithOffset(_amf0Reader.BaseStream, false, (int)_currentFrame.Length); SendStreamMessage(buffer); _pFile.Position = _currentFrame.Start + _currentFrame.Length; //message.Recycle(); _currentFrameIndex++; return(true); } //todo 这里会导致播放中断,对于其他协议要修改 Paused = true; return(base.FeedOtherType()); }
//public override bool SignalOutputData(MemoryStream ouputStream = null) //{ // while (Protocol.OutputBuffer!=null) // { // var outputBuffer = Protocol.OutputBuffer; // SocketError errorCode; // var sendCount = OutboundFd.Send(outputBuffer.GetBuffer(), // (int)outputBuffer.Consumed, // (int)outputBuffer.Length, SocketFlags.None, out errorCode); // if (errorCode!=SocketError.Success || sendCount <= 0) // { // Logger.FATAL("Unable to send data.{0}:{1}", NearIP, NearPort); // IOHandlerManager.EnqueueForDelete(this); // break; // } // outputBuffer.Ignore((uint)sendCount); // } // //Protocol.OutputBuffer.Recycle(true); // return true; //} public override bool SignalOutputData(EndPoint address, MemoryStream outputStream) { var outputBuffer = new BufferWithOffset(outputStream); while (outputBuffer.Length > 0) { var sendCount = Socket.SendTo(outputBuffer.Buffer, outputBuffer.Offset, outputBuffer.Length, SocketFlags.None, address); if (sendCount < 0) { Logger.FATAL("Unable to send data.{0}:{1}", NearIP, NearPort); IOHandlerManager.EnqueueForDelete(this); break; } outputBuffer.Offset += sendCount; } outputStream.SetLength(0); return(true); }
public override void SendStreamMessage(BufferWithOffset buffer) => OnSendStreamMessage?.Invoke(buffer);
public override void SendStreamMessage(BufferWithOffset buffer) { base.SendStreamMessage(buffer); StreamMessageBuffer.Add(buffer); }
public virtual void SendStreamMessage(BufferWithOffset buffer) { }
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); }