Exemple #1
0
        /// <summary>
        /// Tries to parse a possible Crype packet and dispatches the packet for further processing in case it's a valid packet
        /// </summary>
        /// <param name="sender">Sender of the packet</param>
        /// <param name="body">The message with the possible packet in it</param>
        private void TryParseAndDispatchPacket(User sender, string body)
        {
            byte[] packetBodyBytes = null;
            try
            {
                if (ValidationUtility.IsBase64String(body))
                    packetBodyBytes = Convert.FromBase64String(body);
                else
                    return;
            }
            catch(FormatException)
            {
                return;
            }

            DEncodeValue parsedPacket = null;
            try
            {
                // try to decode a valid packet from the message
                var reader = new DEncodeReader(new MemoryStream(packetBodyBytes));
                parsedPacket = reader.Read();
            }
            catch
            {
                return;
            }

            // raise the event to dispatch the packet to be processed further
            if (PacketReceived != null)
            {
                PacketReceived(this, new ChatPacketReceivedEventArgs(new ReceivedPacket(sender, _chatImpl, parsedPacket)));
            }
        }
Exemple #2
0
        /// <summary>
        /// Parses a packet decrypting it if necessary. Returns the unwrapped plain packet and information about the options of the packet
        /// </summary>
        /// <param name="packet">The packet</param>
        /// <param name="targetedDecryptorCsp">RSA instance to decrypt targeted packets</param>
        /// <param name="untargetedMasterKey">Master key to decrypt untargeted packets on chat</param>
        /// <returns>The unwrapped packet and information about it</returns>
        public static PacketInfo UnwrapPacket(DEncodeValue packet, RSACryptoServiceProvider targetedDecryptorCsp,
                                              byte[] untargetedMasterKey)
        {
            var packetDict = (DEncodeDictionary) packet;
            var type = ((DEncodeString) packetDict.Items["ty"]).Value;
            if (type == "plain")
            {
                return new PacketInfo(packet, false, null, false, false);
            }

            if (type == "sigwrap")
            {
                var signedByKey = ((DEncodeArray) packetDict.Items["sb"]).Value;
                var signature = ((DEncodeArray) packetDict.Items["si"]).Value;
                var wrappedPacket = packetDict.Items["pa"];

                var packetStream = new MemoryStream();
                var writer = new DEncodeWriter(packetStream);
                writer.Write(wrappedPacket);
                var wrappedPacketBytes = packetStream.ToArray();

                var validatorCsp = new RSACryptoServiceProvider();
                validatorCsp.ImportCspBlob(signedByKey);

                if (!validatorCsp.VerifyHash(ComputeSha1Hash(wrappedPacketBytes), Sha1Csp.ToString(), signature))
                {
                    throw new CryptographicException("Invalid signature");
                }

                var wrappedPacketInfo = UnwrapPacket(wrappedPacket, targetedDecryptorCsp, untargetedMasterKey);
                wrappedPacketInfo.IsSigned = true;
                wrappedPacketInfo.SignedByKey = signedByKey;
                return wrappedPacketInfo;
            }

            if (type == "targeted")
            {
                var encryptedPacketKey = ((DEncodeArray) packetDict.Items["ke"]).Value;
                var iv = ((DEncodeArray) packetDict.Items["iv"]).Value;
                var encryptedPacketBytes = ((DEncodeArray) packetDict.Items["pa"]).Value;

                // decrypt the packet key
                var packetKey = targetedDecryptorCsp.Decrypt(encryptedPacketKey, true);

                // decrypt the packet
                var decryptorCsp = CreatePacketCryptingAlgoInstance();
                decryptorCsp.Key = packetKey;
                decryptorCsp.IV = iv;

                var decryptedPacketBytes = decryptorCsp.CreateDecryptor()
                                                       .TransformFinalBlock(encryptedPacketBytes, 0,
                                                                            encryptedPacketBytes.Length);
                // parse the wrapped packet
                var reader = new DEncodeReader(new MemoryStream(decryptedPacketBytes));
                var wrappedPacket = reader.Read();

                var wrappedPacketInfo = UnwrapPacket(wrappedPacket, targetedDecryptorCsp, untargetedMasterKey);
                wrappedPacketInfo.IsTargeted = true;
                return wrappedPacketInfo;
            }

            if (type == "nontargeted")
            {

                var iv = ((DEncodeArray)packetDict.Items["iv"]).Value;
                var encryptedPacketBytes = ((DEncodeArray)packetDict.Items["pa"]).Value;

                // decrypt the packet
                var decryptorCsp = CreatePacketCryptingAlgoInstance();
                decryptorCsp.Key = untargetedMasterKey;
                decryptorCsp.IV = iv;

                var decryptedPacketBytes = decryptorCsp.CreateDecryptor()
                                                       .TransformFinalBlock(encryptedPacketBytes, 0,
                                                                            encryptedPacketBytes.Length);
                // parse the wrapped packet
                var reader = new DEncodeReader(new MemoryStream(decryptedPacketBytes));
                var wrappedPacket = reader.Read();

                var wrappedPacketInfo = UnwrapPacket(wrappedPacket, targetedDecryptorCsp, untargetedMasterKey);
                wrappedPacketInfo.IsUntargeted = true;
                return wrappedPacketInfo;
            }

            throw new Exception("Invalid packet type code");
        }