private byte PerformHandshake(byte id, N2HBinaryReader reader, long oldPos) { //Logger.Debug("PerformHandshake{0}", id); switch (id) { case 0x30: reader.ReadByte(); var epdLen = reader.ReadByte() - 1; var type = reader.ReadByte(); var epd = reader.ReadBytes(epdLen); var tag = reader.ReadBytes(16); Writer.Write((byte)tag.Length); Writer.Write(tag); if (type == 0x0F) return Handler.PerformHandshake(tag, Writer,Peer.Address, epd); if (type == 0x0a) { var tagstr = tag.BytesToString(); var attempt = GetHelloAttempt<HelloAttempt>(tagstr); ushort port; string host; RtmfpUtils.UnpackUrl(epd.BytesToString(), out host, out port, out Peer.Path,out Peer.Properties); var addresses = new List<string>(); Peer.OnHandshake(attempt.Count + 1, addresses); if (addresses.Count > 0) { for (var i = 0; i < addresses.Count; i++) { if (addresses[i] == "again") { addresses[i] = host + ":" + port; Writer.WriteAddress(new IPEndPoint(IPAddress.Parse(host),port),i==0 ); } } return 0x71; } CreateCookie(Writer, attempt, tag, epd.BytesToString()); Writer.Write(_certificat); return 0x70; } else { Logger.FATAL("Unkown handshake first way with '{0}' type", type); } return 0; case 0x38: FarId = reader.ReadUInt32(); if (reader.Read7BitLongValue() != CookieComputing.COOKIE_SIZE) { return 0; } var cookieKey = reader.ReadBytes(CookieComputing.COOKIE_SIZE).BytesToString(); reader.BaseStream.Position -= CookieComputing.COOKIE_SIZE; if (!_cookies.ContainsKey(cookieKey)) { Logger.WARN("Cookie {0} unknown, maybe already connected (udpBuffer congested?)", cookieKey); return 0; } var cookie = _cookies[cookieKey]; cookie.PeerAddress = Peer.Address; if (cookie.FarId == 0) { cookie.FarId = FarId; reader.BaseStream.Position += CookieComputing.COOKIE_SIZE; var size = reader.Read7BitLongValue(); var buffer = reader.ReadBytes((int) size); uint tempSize = 0; cookie.PeerId = Target.Sha256.ComputeHash(buffer, 0, (int)size); //Native.EVP_Digest(buffer, (uint)size, cookie.PeerId, ref tempSize, Native.EVP_sha256(), IntPtr.Zero); reader.BaseStream.Position -= (long) size; var initiatorKeySize = (int) (reader.Read7BitValue() - 2); reader.BaseStream.Position += 2; cookie.CookieComputing.InitiatorKey = new byte[initiatorKeySize]; reader.BaseStream.Read(cookie.CookieComputing.InitiatorKey, 0, initiatorKeySize); //cookie.CookieComputing.InitiatorKey = reader.ReadBytes((int) initiatorKeySize); cookie.CookieComputing.InitiatorNonce = reader.ReadBytes((int) reader.Read7BitValue()); Writer.BaseStream.Position = oldPos; tempSize = reader.ReadByte();//0x58 if(tempSize!=0x58)Logger.WARN("not 0x58!!"); cookie.ComputeKeys(); } else if(cookie.Id>0) { cookie.Read(Writer.BaseStream); return 0x78; } return 0; default: Logger.FATAL("Unkown handshake packet id {0}", id); return 0; } }
internal static bool Deserialize(Stream raw, StreamCapabilities _streamCapabilities) { var reader = new N2HBinaryReader(raw); //var length = raw.GetAvaliableByteCounts(); //if (length < 28) //{ // Logger.FATAL("Not enough data"); // return false; //} var ver = reader.ReadUInt64(); if (ver != Utils.__STREAM_CAPABILITIES_VERSION) { Logger.FATAL("Invalid stream capabilities version. Wanted: {0}; Got: {1}", Utils.__STREAM_CAPABILITIES_VERSION, ver); return false; } _streamCapabilities.Clear(); _streamCapabilities.VideoCodecId = (VideoCodec)reader.ReadByte(); _streamCapabilities.AudioCodecId = (AudioCodec)reader.ReadByte(); _streamCapabilities.BandwidthHint = reader.ReadUInt32(); if (_streamCapabilities.VideoCodecId == VideoCodec.H264 && !VideoAvc.Deserialize(raw, out _streamCapabilities.Avc)) { Logger.FATAL("Unable to deserialize avc"); return false; } if (_streamCapabilities.AudioCodecId == AudioCodec.Aac && !AudioAac.Deserialize(raw, out _streamCapabilities.Aac)) { Logger.FATAL("Unable to deserialize aac"); return false; } return true; }
public static bool Deserialize(Stream src, out VideoAvc dest) { dest = new VideoAvc(); if (src.GetAvaliableByteCounts() < 2) { Logger.FATAL("Not enough data"); return false; } var reader = new N2HBinaryReader(src); var _spsLength = reader.ReadUInt16(); if (src.GetAvaliableByteCounts() < _spsLength + 2 + 8) { Logger.FATAL("Not enough data"); return false; } var psps = reader.ReadBytes(_spsLength); var _ppsLength = reader.ReadUInt16(); if (src.GetAvaliableByteCounts() < _ppsLength + 2 + 8) { Logger.FATAL("Not enough data"); return false; } var ppps = reader.ReadBytes(_ppsLength); dest.Init(psps, ppps); dest._widthOverride = reader.ReadUInt32(); dest._heightOverride = reader.ReadUInt32(); return true; }
public static bool Deserialize(Stream src, out AudioAac dest) { dest = new AudioAac(); var length = src.GetAvaliableByteCounts(); if (length < 4) { Logger.FATAL("Not enough data"); return false; } using (var reader = new N2HBinaryReader(src)) { dest._aacLength = reader.ReadUInt32(); if (length < 4 + dest._aacLength) { Logger.FATAL("Not enough data"); return false; } if (!dest.Init(src, (int) dest._aacLength)) { Logger.FATAL("Unable to init AAC"); return false; } } return true; }
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; } }