Beispiel #1
0
            public SharedFileInfo(Stream s)
            {
                BincodingDecoder decoder = new BincodingDecoder(s, "FI");

                while (true)
                {
                    Bincoding value = decoder.DecodeNext();

                    if (value.Type == BincodingType.NULL)
                    {
                        break;
                    }

                    KeyValuePair <string, Bincoding> pair = value.GetKeyValuePair();

                    switch (pair.Key)
                    {
                    case "file_path":
                        _filePath = pair.Value.GetStringValue();
                        break;

                    case "file_metadata":
                        _fileMetaData = new SharedFileMetaData(pair.Value.GetValueStream());
                        break;

                    case "state":
                        _state = (SharedFileState)pair.Value.GetByteValue();
                        break;

                    case "block_available":
                        _blockAvailable = pair.Value.Value;
                        break;
                    }
                }
            }
        public MessageRecipient(Stream s)
        {
            BincodingDecoder decoder = new BincodingDecoder(s);

            switch (decoder.DecodeNext().GetByteValue()) //version
            {
            case 1:
                _name        = decoder.DecodeNext().GetStringValue();
                _status      = (MessageRecipientStatus)decoder.DecodeNext().GetByteValue();
                _deliveredOn = decoder.DecodeNext().GetDateTimeValue();
                break;

            default:
                throw new InvalidDataException("Cannot decode data format: version not supported.");
            }
        }
        public DiffieHellmanPublicKey(byte[] publicKey)
        {
            using (MemoryStream mS = new MemoryStream(publicKey, false))
            {
                BincodingDecoder decoder = new BincodingDecoder(mS, "DH");

                switch (decoder.Version)
                {
                case 1:
                    _keySize = decoder.DecodeNext().GetIntegerValue();
                    _group   = (DiffieHellmanGroupType)decoder.DecodeNext().GetByteValue();

                    switch (_group)
                    {
                    case DiffieHellmanGroupType.RFC3526:
                        DiffieHellmanGroup dhg = DiffieHellmanGroup.GetGroup(_group, _keySize);
                        _p = dhg.P;
                        _g = dhg.G;
                        _x = ReadPositiveNumber(decoder.DecodeNext().Value);
                        break;

                    case DiffieHellmanGroupType.None:
                        _p = ReadPositiveNumber(decoder.DecodeNext().Value);
                        _g = ReadPositiveNumber(decoder.DecodeNext().Value);
                        _x = ReadPositiveNumber(decoder.DecodeNext().Value);
                        break;

                    default:
                        throw new NotSupportedException("DiffieHellmanGroup type not supported.");
                    }


                    break;

                default:
                    throw new InvalidDataException("DiffieHellmanPublicKey data format version not supported.");
                }
            }

            VerifyPublicKey(_keySize, _p, _g, _x);
        }
Beispiel #4
0
        private void LoadZoneFileV1(Stream s)
        {
            BincodingDecoder decoder = new BincodingDecoder(s, "DZ");

            switch (decoder.Version)
            {
            case 1:
                ICollection <Bincoding> entries = decoder.DecodeNext().GetList();
                DnsResourceRecord[]     records = new DnsResourceRecord[entries.Count];

                int i = 0;
                foreach (Bincoding entry in entries)
                {
                    records[i++] = new DnsResourceRecord(entry.GetValueStream());
                }

                _dnsServer.AuthoritativeZoneRoot.SetRecords(records);
                break;

            default:
                throw new IOException("DNS Zone file version not supported: " + decoder.Version);
            }
        }
Beispiel #5
0
            public BitChatInfo(Stream s)
            {
                BincodingDecoder decoder = new BincodingDecoder(s, "BI");

                while (true)
                {
                    Bincoding value = decoder.DecodeNext();

                    if (value.Type == BincodingType.NULL)
                    {
                        break;
                    }

                    KeyValuePair <string, Bincoding> pair = value.GetKeyValuePair();

                    switch (pair.Key)
                    {
                    case "type":
                        _type = (BitChatNetworkType)pair.Value.GetByteValue();
                        break;

                    case "network_name":
                        _networkNameOrPeerEmailAddress = pair.Value.GetStringValue();
                        break;

                    case "shared_secret":
                        _sharedSecret = pair.Value.GetStringValue();
                        break;

                    case "enable_tracking":
                        _enableTracking = pair.Value.GetBooleanValue();
                        break;

                    case "send_invitation":
                        _sendInvitation = pair.Value.GetBooleanValue();
                        break;

                    case "invitation_sender":
                        _invitationSender = pair.Value.GetStringValue();
                        break;

                    case "invitation_message":
                        _invitationMessage = pair.Value.GetStringValue();
                        break;

                    case "network_status":
                        _networkStatus = (BitChatNetworkStatus)pair.Value.GetByteValue();
                        break;

                    case "hashed_peer_email_address":
                        _hashedPeerEmailAddress = new BinaryNumber(pair.Value.Value);
                        break;

                    case "network_id":
                        _networkID = new BinaryNumber(pair.Value.Value);
                        break;

                    case "network_secret":
                        _networkSecret = new BinaryNumber(pair.Value.Value);
                        break;

                    case "message_store_id":
                        _messageStoreID = pair.Value.GetStringValue();
                        break;

                    case "message_store_key":
                        _messageStoreKey = pair.Value.Value;
                        break;

                    case "group_image_date_modified":
                        _groupImageDateModified = pair.Value.GetLongValue();
                        break;

                    case "group_image":
                        _groupImage = pair.Value.Value;
                        break;

                    case "mute":
                        _mute = pair.Value.GetBooleanValue();
                        break;

                    case "peer_certs":
                    {
                        List <Bincoding> peerCerts = pair.Value.GetList();

                        _peerCerts = new Certificate[peerCerts.Count];
                        int i = 0;

                        foreach (Bincoding item in peerCerts)
                        {
                            _peerCerts[i++] = new Certificate(item.GetValueStream());
                        }
                    }
                    break;

                    case "shared_files":
                    {
                        List <Bincoding> sharedFiles = pair.Value.GetList();

                        _sharedFiles = new SharedFileInfo[sharedFiles.Count];
                        int i = 0;

                        foreach (Bincoding item in sharedFiles)
                        {
                            _sharedFiles[i++] = new SharedFileInfo(item.GetValueStream());
                        }
                    }
                    break;

                    case "tracker_list":
                    {
                        List <Bincoding> trackerList = pair.Value.GetList();

                        _trackerURIs = new Uri[trackerList.Count];
                        int i = 0;

                        foreach (Bincoding item in trackerList)
                        {
                            _trackerURIs[i++] = new Uri(item.GetStringValue());
                        }
                    }
                    break;
                    }
                }
            }
Beispiel #6
0
        protected override void ReadPlainTextFrom(Stream s)
        {
            BincodingDecoder decoder = new BincodingDecoder(s, "BP");

            if (decoder.Version != 7)
            {
                throw new BitChatException("BitChatProfile data version not supported.");
            }

            NetProxyType proxyType    = NetProxyType.None;
            string       proxyAddress = "127.0.0.1";
            int          proxyPort    = 0;
            string       username     = null;
            string       password     = "";

            while (true)
            {
                Bincoding value = decoder.DecodeNext();

                if (value.Type == BincodingType.NULL)
                {
                    break;
                }

                KeyValuePair <string, Bincoding> item = value.GetKeyValuePair();

                switch (item.Key)
                {
                case "local_port":
                    _localPort = item.Value.GetIntegerValue();
                    break;

                case "check_cert_revocation":
                    _checkCertificateRevocationList = item.Value.GetBooleanValue();
                    break;

                case "enable_upnp":
                    _enableUPnP = item.Value.GetBooleanValue();
                    break;

                case "allow_inbound_invitations":
                    _allowInboundInvitations = item.Value.GetBooleanValue();
                    break;

                case "allow_only_local_inbound_invitations":
                    _allowOnlyLocalInboundInvitations = item.Value.GetBooleanValue();
                    break;

                case "download_folder":
                    _downloadFolder = item.Value.GetStringValue();
                    break;

                case "local_cert_store":
                    _localCertStore = new CertificateStore(item.Value.GetValueStream());
                    break;

                case "profile_image_date_modified":
                    _profileImageDateModified = item.Value.GetLongValue();
                    break;

                case "profile_image":
                case "profile_image_large":
                    _profileImage = item.Value.Value;
                    break;

                case "tracker_list":
                {
                    List <Bincoding> trackerList = item.Value.GetList();

                    _trackerURIs = new Uri[trackerList.Count];
                    int i = 0;

                    foreach (Bincoding trackerItem in trackerList)
                    {
                        _trackerURIs[i++] = new Uri(trackerItem.GetStringValue());
                    }
                }
                break;

                case "bitchat_info":
                {
                    List <Bincoding> bitChatInfoList = item.Value.GetList();

                    _bitChatInfoList = new BitChatInfo[bitChatInfoList.Count];
                    int i = 0;

                    foreach (Bincoding infoItem in bitChatInfoList)
                    {
                        _bitChatInfoList[i++] = new BitChatInfo(infoItem.GetValueStream());
                    }
                }
                break;

                case "dht_nodes":
                {
                    try
                    {
                        List <Bincoding> dhtNodeList = item.Value.GetList();

                        _bootstrapDhtNodes = new IPEndPoint[dhtNodeList.Count];
                        int i = 0;

                        foreach (Bincoding dhtItem in dhtNodeList)
                        {
                            _bootstrapDhtNodes[i++] = IPEndPointParser.Parse(dhtItem.GetValueStream());
                        }
                    }
                    catch (NotSupportedException)
                    {
                        _bootstrapDhtNodes = new IPEndPoint[] { };
                    }
                }
                break;

                case "proxy_type":
                    proxyType = (NetProxyType)item.Value.GetByteValue();
                    break;

                case "proxy_address":
                    proxyAddress = item.Value.GetStringValue();
                    break;

                case "proxy_port":
                    proxyPort = item.Value.GetIntegerValue();
                    break;

                case "proxy_user":
                    username = item.Value.GetStringValue();
                    break;

                case "proxy_pass":
                    password = item.Value.GetStringValue();
                    break;

                case "client_data":
                    if (item.Value.Type == BincodingType.BINARY)
                    {
                        _clientData = item.Value.Value;
                    }

                    break;
                }
            }

            if (string.IsNullOrEmpty(_downloadFolder))
            {
                _downloadFolder = Path.Combine(_profileFolder, "Downloads");

                if (!Directory.Exists(_downloadFolder))
                {
                    try
                    {
                        Directory.CreateDirectory(_downloadFolder);
                    }
                    catch
                    { }
                }
            }

            //apply proxy settings
            NetworkCredential proxyCredentials = null;

            if (username != null)
            {
                proxyCredentials = new NetworkCredential(username, password);
            }

            ConfigureProxy(proxyType, proxyAddress, proxyPort, proxyCredentials);
        }
        public MessageItem(MessageStore store, int messageNumber)
        {
            _messageNumber = messageNumber;
            byte[] messageData = store.ReadMessage(messageNumber);

            using (MemoryStream mS = new MemoryStream(messageData))
            {
                if (Encoding.ASCII.GetString(messageData, 0, 2) == "MI")
                {
                    //new format
                    BincodingDecoder decoder = new BincodingDecoder(mS, "MI");

                    switch (decoder.Version)
                    {
                    case 1:
                        _type        = (MessageType)decoder.DecodeNext().GetByteValue();
                        _messageDate = decoder.DecodeNext().GetDateTimeValue();

                        switch (_type)
                        {
                        case MessageType.Info:
                            _message = decoder.DecodeNext().GetStringValue();
                            break;

                        case MessageType.TextMessage:
                        case MessageType.InvitationMessage:
                            _sender  = decoder.DecodeNext().GetStringValue();
                            _message = decoder.DecodeNext().GetStringValue();

                            {
                                List <Bincoding> rcptDataList = decoder.DecodeNext().GetList();

                                _recipients = new MessageRecipient[rcptDataList.Count];
                                int i = 0;

                                foreach (Bincoding data in rcptDataList)
                                {
                                    _recipients[i++] = new MessageRecipient(data.GetValueStream());
                                }
                            }
                            break;

                        case MessageType.SharedFileMetaData:
                            _sender             = decoder.DecodeNext().GetStringValue();
                            _sharedFileMetaData = new SharedFileMetaData(decoder.DecodeNext().GetValueStream());
                            break;
                        }

                        break;

                    default:
                        throw new InvalidDataException("Cannot decode data format: version not supported.");
                    }
                }
                else
                {
                    //old format support
                    BincodingDecoder decoder = new BincodingDecoder(mS);

                    _type        = (MessageType)decoder.DecodeNext().GetByteValue();
                    _messageDate = _epoch.AddSeconds(decoder.DecodeNext().GetLongValue());

                    switch (_type)
                    {
                    case MessageType.Info:
                        _message = decoder.DecodeNext().GetStringValue();
                        break;

                    case MessageType.TextMessage:
                        _sender     = decoder.DecodeNext().GetStringValue();
                        _message    = decoder.DecodeNext().GetStringValue();
                        _recipients = new MessageRecipient[] { };
                        break;
                    }
                }
            }
        }
        public byte[] ReadMessage(int number)
        {
            lock (_lock)
            {
                //seek to index location
                int indexPosition = number * 4;

                if (indexPosition >= _index.Length)
                {
                    throw new IOException("Cannot read message from message store: message number out of range.");
                }

                _index.Position = indexPosition;

                //read message offset
                byte[] buffer = new byte[4];
                _index.Read(buffer, 0, 4);
                uint messageOffset = BitConverter.ToUInt32(buffer, 0);

                //seek to message offset
                _data.Position = messageOffset;

                //read data
                BincodingDecoder decoder = new BincodingDecoder(_data);
                byte[]           IV;
                byte[]           encryptedData;

                switch (decoder.DecodeNext().GetByteValue()) //version
                {
                case 1:
                    IV            = decoder.DecodeNext().Value;
                    encryptedData = decoder.DecodeNext().Value;
                    byte[] aeHmac = decoder.DecodeNext().Value;

                    //verify hmac
                    BinaryID computedAeHmac;

                    using (HMAC hmac = new HMACSHA256(_key))
                    {
                        computedAeHmac = new BinaryID(hmac.ComputeHash(encryptedData));
                    }

                    if (!computedAeHmac.Equals(new BinaryID(aeHmac)))
                    {
                        throw new CryptoException("Cannot read message from message store: message is corrupt or tampered.");
                    }

                    break;

                default:
                    throw new IOException("Cannot read message from message store: message version not supported.");
                }

                using (MemoryStream mS = new MemoryStream(encryptedData.Length))
                {
                    using (MemoryStream src = new MemoryStream(encryptedData, 0, encryptedData.Length))
                    {
                        _crypto.IV = IV;
                        _crypto.Decrypt(src, mS);
                    }

                    return(mS.ToArray());
                }
            }
        }
        public void UpdateMessage(int number, byte[] data, int offset, int count)
        {
            lock (_lock)
            {
                //seek to index location
                int indexPosition = number * 4;

                if (indexPosition >= _index.Length)
                {
                    throw new IOException("Cannot read message from message store: message number out of range.");
                }

                _index.Position = indexPosition;

                //read message offset
                byte[] buffer = new byte[4];
                _index.Read(buffer, 0, 4);
                uint messageOffset = BitConverter.ToUInt32(buffer, 0);

                //seek to message offset
                _data.Position = messageOffset;

                //read data
                BincodingDecoder decoder = new BincodingDecoder(_data);
                byte[]           existingEncryptedData;

                switch (decoder.DecodeNext().GetByteValue()) //version
                {
                case 1:
                    decoder.DecodeNext();
                    existingEncryptedData = decoder.DecodeNext().Value;
                    break;

                default:
                    throw new IOException("Cannot read message from message store: message version not supported.");
                }

                //encrypt message data
                byte[] newEncryptedData;
                using (MemoryStream mS = new MemoryStream(count))
                {
                    using (MemoryStream src = new MemoryStream(data, offset, count))
                    {
                        _crypto.GenerateIV();
                        _crypto.Encrypt(src, mS);
                    }

                    newEncryptedData = mS.ToArray();
                }

                byte[] aeHmac;
                using (HMAC hmac = new HMACSHA256(_key))
                {
                    aeHmac = hmac.ComputeHash(newEncryptedData);
                }

                bool lengthIsInLimit = (newEncryptedData.Length <= existingEncryptedData.Length);

                if (lengthIsInLimit)
                {
                    //seek to message offset
                    _data.Position = messageOffset;

                    //overwrite new data
                    BincodingEncoder encoder = new BincodingEncoder(_data);

                    encoder.Encode((byte)1); //version
                    encoder.Encode(_crypto.IV);
                    encoder.Encode(newEncryptedData);
                    encoder.Encode(aeHmac);
                }
                else
                {
                    //seek to index location
                    _index.Position = number * 4;

                    //seek to end of data stream
                    _data.Position = _data.Length;

                    //get message offset
                    messageOffset = Convert.ToUInt32(_data.Position);

                    //write new data
                    BincodingEncoder encoder = new BincodingEncoder(_data);

                    encoder.Encode((byte)1); //version
                    encoder.Encode(_crypto.IV);
                    encoder.Encode(newEncryptedData);
                    encoder.Encode(aeHmac);

                    //overwrite message offset to index stream
                    _index.Write(BitConverter.GetBytes(messageOffset), 0, 4);
                }
            }
        }