Esempio n. 1
0
        private Payload GetPayload()
        {
            lock (_lock4GetPayload)
                if (_payload == null)
                {
                    PrivateKey myPrivkeyFrom = PrivateKey.GetPrivateKey(_bm.DB, KeyFrom);
                    if (myPrivkeyFrom == null)
                    {
                        throw new Exception("PrivateKey not found");
                    }

                    Pubkey pubkeyTo = Pubkey.Find(_bm.DB, KeyTo);                     // TODO Получать ключ, если его ещё нет
                    if (pubkeyTo == null)
                    {
                        throw new Exception("Pubkey not found");
                    }

                    var   payload = new MemoryStream(1000 + Subject.Length + Body.Length);                   // TODO realy 1000?
                    var   rnd     = new Random();
                    ulong dt      = DateTime.UtcNow.ToUnix() + (ulong)rnd.Next(600) - 300;

                    payload.Write(dt);
                    payload.WriteVarInt(Stream);

                    var dataToEncrypt = new MemoryStream(1000 + Subject.Length + Body.Length);                     // TODO realy 1000?
                    dataToEncrypt.WriteVarInt(Version);

                    byte[] publicAddress = myPrivkeyFrom.GetPayload4Broadcast();
                    dataToEncrypt.Write(publicAddress, 0, publicAddress.Length);

                    dataToEncrypt.Write(pubkeyTo.Hash, 0, 20);

                    var encodingType = (byte)EncodingType;
                    dataToEncrypt.Write(encodingType);
                    dataToEncrypt.WriteVarStr("Subject:" + Subject + "\nBody:" + Body);

                    byte[] askMsg = PayloadOfAskData().GetFullMsg();
                    dataToEncrypt.WriteVarInt((UInt64)askMsg.Length);
                    dataToEncrypt.Write(askMsg, 0, askMsg.Length);

                    byte[] signature = myPrivkeyFrom.Sign(dataToEncrypt.ToArray());

                    //Debug.WriteLine("data=" + dataToEncrypt.ToArray().ToHex());
                    //Debug.WriteLine("SigningKey=" + myPrivkeyFrom.SigningKey.ToHex());
                    //Debug.WriteLine("signature=" + signature.ToHex());

                    dataToEncrypt.WriteVarInt((UInt64)signature.Length);
                    dataToEncrypt.Write(signature, 0, signature.Length);

                    byte[] bytesToEncrypt = dataToEncrypt.ToArray();
                    byte[] encrypt        = ECDSA.Encrypt(bytesToEncrypt, pubkeyTo.EncryptionKey);

                    payload.Write(encrypt, 0, encrypt.Length);

                    _payload = new Payload("msg", ProofOfWork.AddPow(payload.ToArray()));
                }
            return(_payload);
        }
        public void AddSubscription(Pubkey pubkey)
        {
            if (pubkey.SubscriptionIndex == 0)
            {
                pubkey.SubscriptionIndex = 1;
                pubkey.SaveAsync(DB);

                lock (_lock4pubkeysCache)
                    _pubkeysCache = null;
            }
        }
Esempio n. 3
0
 private static void NewPubkey(Pubkey pubkey)
 {
     _bm.AddSubscription(pubkey);
     Console.WriteLine("Pubkey " + pubkey);
 }
        private void ListenerLoop()
        {
            try
            {
                NetworkStream ns = _tcpClient.GetStream();

                while (ns.CanRead)
                {
                    #region Read header and payload from network

                    Header header;
                    Payload payload;
                    try
                    {
                        header = new Header(BinaryReader);
                        payload =
                            (header.Length == 0)
                            ? new Payload(header.Command, null)
                            : new Payload(header.Command, BinaryReader.ReadBytes(header.Length));
                    }
                    catch (Exception e)
                    {
                        string excptionStr = e.ToString();
                        if ((e is IOException) || (e is SocketException))
                            excptionStr = "";
                        Debug.WriteLine("соединение " + NetworkAddress + " потерено " + excptionStr);
                        Bitmessage.NodeIsDisconnected.Set();
                        break;
                    }

                    #endregion Read header and payload from network

                    bool checksum = header.Checksum.SequenceEqual(payload.Checksum());

                    if (checksum && payload.IsValid)
                    {
                        debug("Command=" + header.Command);

                        #region Save payload to Inventory

                        if ((header.Command == "msg") || (header.Command == "pubkey") || (header.Command == "broadcast") || (header.Command == "getpubkey"))
                        {
                            _nodeConnectionInventory.Insert(payload.InventoryVector);
                            payload.SaveAsync(Bitmessage);
                        }

                        #endregion Save to Inventory

                        #region VERSION

                        if (header.Command == "version")
                        {
                            var v = new Version(payload);
                            debug("Подключились с " + v.UserAgent);
                            if ((v.Value != 1) && (v.Value != 2))
                                Stop("Version = " + v.Value);
                            else if (v.Nonce == Version.EightBytesOfRandomDataUsedToDetectConnectionsToSelf)
                            {
                                Bitmessage.DeleteNode(NetworkAddress);
                                Stop("DetectConnectionsToSelf");
                            }
                            else
                                Send(new Verack());
                        }

                        #endregion VERSION

                        #region INV

                        else if (header.Command == "inv")
                        {
                            var inputInventory = new Inv(payload.SentData);
                            var buff4GetData = new MemoryInventory(inputInventory.Count);

                            debug("прислали inv. Inventory.Count=" + inputInventory.Count);

                            //lock (Bitmessage.MemoryInventory)
                            //{
                                foreach (byte[] inventoryVector in inputInventory)
                                {
                                    _nodeConnectionInventory.Insert(inventoryVector);
                                    if (!Bitmessage.MemoryInventory.Exists(inventoryVector))
                                    {
                                        Bitmessage.MemoryInventory.AddWait(inventoryVector);
                                        buff4GetData.Insert(inventoryVector);
                                    }
                                }
                            //}

                            if (buff4GetData.Count > 0)
                            {
                                debug("SendGetdata count=" + buff4GetData.Count);
                                Send(new GetData(buff4GetData));
                            }
                            else
                                debug("All know, don't send GetData");
                        }

                        #endregion

                        #region verack

                        else if (header.Command == "verack")
                        {
                            Send(new Inv(Bitmessage.MemoryInventory));

                            NetworkAddress.TimeLastSeen = DateTime.UtcNow;
                            NetworkAddress.SaveAsync(Bitmessage.DB);

                        }

                        #endregion

                        #region getpubkey

                        else if (header.Command == "getpubkey")
                        {
                            var getpubkey = new GetPubkey(payload);

                            PrivateKey pk = Bitmessage.FindPrivateKey(getpubkey);
                            if ((pk != null) &&
                                (pk.LastPubkeySendTime.ToUnix() <
                                 (DateTime.UtcNow.ToUnix() - Payload.LengthOfTimeToHoldOnToAllPubkeys)))
                            {
                                pk.SendAsync(Bitmessage);
                            }
                        }

                            #endregion getpubkey

                            #region pubkey

                        else if (header.Command == "pubkey")
                        {
                            int pos = payload.FirstByteAfterTime;
                            var pubkey = new Pubkey(payload.SentData, ref pos, true);

                            if (pubkey.Status == Status.Valid)
                            {
                                pubkey.SaveAsync(Bitmessage.DB);
                                Bitmessage.OnReceivePubkey(pubkey);
                            }
                            else
                                Bitmessage.OnReceiveInvalidPubkey(pubkey);
                        }

                            #endregion PUBKEY

                            #region msg

                        else if (header.Command == "msg")
                        {
                            var msg = new Msg(Bitmessage, payload);
                            msg.SaveAsync(Bitmessage.DB);

                            if (msg.Status == Status.Valid)
                                Bitmessage.OnReceiveMsg(msg);
                            else
                                Bitmessage.OnReceiveInvalidMsg(msg);
                        }

                            #endregion MSG

                            #region broadcast

                        else if (header.Command == "broadcast")
                        {
                            var broadcast = new Broadcast(Bitmessage, payload);
                            broadcast.SaveAsync(Bitmessage.DB);

                            if (broadcast.Status == Status.Valid)
                                Bitmessage.OnReceiveBroadcast(broadcast);
                            else
                                Bitmessage.OnReceiveInvalidBroadcast(broadcast);
                        }

                            #endregion BROADCAST

                            #region addr

                        else if (header.Command == "addr")
                        {
                            int pos = 0;
                            UInt64 numberOfAddressesIncluded = payload.SentData.ReadVarInt(ref pos);
                            if ((numberOfAddressesIncluded > 0) && (numberOfAddressesIncluded < 1001))
                            {
                                if (payload.Length != (pos + (38*(int) numberOfAddressesIncluded)))
                                    throw new Exception(
                                        "addr message does not contain the correct amount of data. Ignoring.");

                                while (pos < payload.Length)
                                {
                                    NetworkAddress networkAddress = NetworkAddress.GetFromAddrList(payload.SentData,
                                                                                                   ref pos);
                                    Bitmessage.AddNode(networkAddress);
                                }
                            }
                        }

                            #endregion addr

                            #region getdata

                        else if (header.Command == "getdata")
                        {
                            debug("Load getdata");
                            var getData = new GetData(payload.SentData);

                            foreach (byte[] hash in getData.Inventory)
                                Payload.SendAsync(this, hash.ToHex(false));
                        }

                            #endregion getdata

                            #region ping

                        else if (header.Command == "ping")
                        {
                            Send(new Pong());
                        }

                            #endregion ping

                            #region pong

                        else if (header.Command == "pong")
                        {

                        }

                            #endregion pong

                        else debug("unknown command");
                    }
                    else
                        debug("checksum error");
                }
                _tcpClient.Close();
            }
            // ReSharper disable EmptyGeneralCatchClause
            catch(Exception e)
            {
                debug("Закрываю соединение " + e);
            } // ReSharper restore EmptyGeneralCatchClause

            Bitmessage.NodeIsDisconnected.Set();
        }
Esempio n. 5
0
 private static void NewPubkey(Pubkey pubkey)
 {
     Console.WriteLine("Pubkey " + pubkey);
     if (pubkey.Name == "BM-2DAV89w336ovy6BUJnfVRD5B9qipFbRgmr")
         Bitmessage.AddSubscription(pubkey);
 }
        public Broadcast(Bitmessage bm, Payload payload)
        {
            Status = Status.Invalid;
            try
            {
                int pos = payload.FirstByteAfterTime;
                Version = payload.SentData.ReadVarInt(ref pos);

                if (Version == 2)
                {
                    _inventoryVector = payload.InventoryVector;

                    Stream = payload.SentData.ReadVarInt(ref pos);
                    byte[] encrypted = payload.SentData.ReadBytes(ref pos, payload.Length - pos);
                    byte[] decryptedData = null;
                    Pubkey encryptionKey = null;
                    foreach (Pubkey subscriptionKey in bm.Subscriptions(Stream4DB))
                    {
                        if (subscriptionKey.Stream != _stream) continue;
                        try
                        {
                            decryptedData = subscriptionKey.DecryptAes256Cbc4Broadcast(encrypted);
                            encryptionKey = subscriptionKey;
                        }
                            // ReSharper disable EmptyGeneralCatchClause
                        catch
                        {
                        } // ReSharper restore EmptyGeneralCatchClause

                        if (decryptedData != null)
                            break;
                    }

                    if ((decryptedData == null) || (encryptionKey == null))
                    {
                        Status = Status.Encrypted;
                        return;
                    }

                    if (encryptionKey.SubscriptionIndex < int.MaxValue)
                    {
                        encryptionKey.SubscriptionIndex += 1;
                        encryptionKey.SaveAsync(bm.DB).Wait();
                    }

                    pos = 0;
                    /*var signedBroadcastVersion = */
                    decryptedData.ReadVarInt(ref pos);
                    Pubkey keyFromMsg = new Pubkey(decryptedData, ref pos);
                    if (!encryptionKey.Hash.SequenceEqual(keyFromMsg.Hash))
                        return;
                    Key = encryptionKey.Name;
                    EncodingType = (EncodingType) decryptedData.ReadVarInt(ref pos);
                    decryptedData.ReadVarStrSubjectAndBody(ref pos, out _subject, out _body);

                    int posOfEndMsg = pos;
                    UInt64 signatureLength = decryptedData.ReadVarInt(ref pos);
                    byte[] signature = decryptedData.ReadBytes(ref pos, (int) signatureLength);

                    byte[] data = new byte[posOfEndMsg];
                    Buffer.BlockCopy(decryptedData, 0, data, 0, posOfEndMsg);

                    if (data.ECDSAVerify(encryptionKey.SigningKey, signature))
                        Status = Status.Valid;
                }
            }
            catch
            {
                Status = Status.Invalid;
            }
        }
        public void DeleteSubscription(Pubkey pubkey)
        {
            if (pubkey.SubscriptionIndex != 0)
            {
                pubkey.SubscriptionIndex = 0;
                pubkey.SaveAsync(DB);

                lock (_lock4pubkeysCache)
                    _pubkeysCache = null;
            }
        }
 public void OnReceivePubkey(Pubkey pubkey)
 {
     Pubkey.EventHandler handler = ReceivePubkey;
     if (handler != null) handler(pubkey);
 }
Esempio n. 9
0
        public Broadcast(Bitmessage bm, Payload payload)
        {
            Status = Status.Invalid;
            try
            {
                int pos = payload.FirstByteAfterTime;
                Version = payload.SentData.ReadVarInt(ref pos);

                if (Version == 2)
                {
                    _inventoryVector = payload.InventoryVector;

                    Stream = payload.SentData.ReadVarInt(ref pos);
                    byte[] encrypted     = payload.SentData.ReadBytes(ref pos, payload.Length - pos);
                    byte[] decryptedData = null;
                    Pubkey encryptionKey = null;
                    foreach (Pubkey subscriptionKey in bm.Subscriptions(Stream4DB))
                    {
                        if (subscriptionKey.Stream != _stream)
                        {
                            continue;
                        }
                        try
                        {
                            decryptedData = subscriptionKey.DecryptAes256Cbc4Broadcast(encrypted);
                            encryptionKey = subscriptionKey;
                        }
                        // ReSharper disable EmptyGeneralCatchClause
                        catch
                        {
                        }                         // ReSharper restore EmptyGeneralCatchClause

                        if (decryptedData != null)
                        {
                            break;
                        }
                    }

                    if ((decryptedData == null) || (encryptionKey == null))
                    {
                        Status = Status.Encrypted;
                        return;
                    }

                    if (encryptionKey.SubscriptionIndex < int.MaxValue)
                    {
                        encryptionKey.SubscriptionIndex += 1;
                        encryptionKey.SaveAsync(bm.DB).Wait();
                    }

                    pos = 0;
                    /*var signedBroadcastVersion = */
                    decryptedData.ReadVarInt(ref pos);
                    Pubkey keyFromMsg = new Pubkey(decryptedData, ref pos);
                    if (!encryptionKey.Hash.SequenceEqual(keyFromMsg.Hash))
                    {
                        return;
                    }
                    Key          = encryptionKey.Name;
                    EncodingType = (EncodingType)decryptedData.ReadVarInt(ref pos);
                    decryptedData.ReadVarStrSubjectAndBody(ref pos, out _subject, out _body);

                    int    posOfEndMsg     = pos;
                    UInt64 signatureLength = decryptedData.ReadVarInt(ref pos);
                    byte[] signature       = decryptedData.ReadBytes(ref pos, (int)signatureLength);

                    byte[] data = new byte[posOfEndMsg];
                    Buffer.BlockCopy(decryptedData, 0, data, 0, posOfEndMsg);

                    if (data.ECDSAVerify(encryptionKey.SigningKey, signature))
                    {
                        Status = Status.Valid;
                    }
                }
            }
            catch
            {
                Status = Status.Invalid;
            }
        }
Esempio n. 10
0
        public Msg(Bitmessage bm, Payload payload)
        {
            Status = Status.Invalid;
            try
            {
                int pos = payload.FirstByteAfterTime;
                _inventoryVector = payload.InventoryVector;

                Stream = payload.SentData.ReadVarInt(ref pos);

                byte[] encrypted = payload.SentData.ReadBytes(ref pos, payload.Length - pos);

                // TODO Check ask data

                byte[]     decryptedData   = null;
                PrivateKey myEncryptionKey = null;

                foreach (PrivateKey myKey in bm.ListMyAddresses())
                {
                    if (myKey.Stream != _stream)
                    {
                        continue;
                    }
                    try
                    {
                        decryptedData   = myKey.DecryptAES256CBC4Msg(encrypted);
                        myEncryptionKey = myKey;
                    }
                    // ReSharper disable EmptyGeneralCatchClause
                    catch
                    {
                    }                     // ReSharper restore EmptyGeneralCatchClause

                    if (decryptedData != null)
                    {
                        break;
                    }
                }

                if ((decryptedData == null) || (myEncryptionKey == null))
                {
                    Status = Status.Encrypted;
                    return;
                }

                pos = 0;

                Version = decryptedData.ReadVarInt(ref pos);
                var senderKey = new Pubkey(decryptedData, ref pos);

                if (!decryptedData.ReadBytes(ref pos, 20).SequenceEqual(myEncryptionKey.Hash))
                {
                    //print 'The original sender of this message did not send it to you. Someone is attempting a Surreptitious Forwarding Attack.'
                    //print 'See: http://world.std.com/~dtd/sign_encrypt/sign_encrypt7.html'
                    //print 'your toRipe:', toRipe.encode('hex')
                    //print 'embedded destination toRipe:', decryptedData[readPosition:readPosition + 20].encode('hex')
                    return;
                }

                KeyTo   = myEncryptionKey.Name;
                KeyFrom = senderKey.Name;

                EncodingType = (EncodingType)decryptedData.ReadVarInt(ref pos);
                decryptedData.ReadVarStrSubjectAndBody(ref pos, out _subject, out _body);

                UInt64 askDataLength = decryptedData.ReadVarInt(ref pos);
                _askData = decryptedData.ReadBytes(ref pos, (int)askDataLength);

                int    posOfEndMsg     = pos;
                UInt64 signatureLength = decryptedData.ReadVarInt(ref pos);
                byte[] signature       = decryptedData.ReadBytes(ref pos, (int)signatureLength);

                var data = new byte[posOfEndMsg];
                Buffer.BlockCopy(decryptedData, 0, data, 0, posOfEndMsg);

                if (data.ECDSAVerify(senderKey.SigningKey, signature))
                {
                    Status = Status.Valid;
                    senderKey.SaveAsync(bm.DB);
                }
            }
            catch
            {
                Status = Status.Invalid;
            }
        }
Esempio n. 11
0
        public Msg(Bitmessage bm, Payload payload)
        {
            Status = Status.Invalid;
            try
            {
                int pos = payload.FirstByteAfterTime;
                _inventoryVector = payload.InventoryVector;

                Stream = payload.SentData.ReadVarInt(ref pos);

                byte[] encrypted = payload.SentData.ReadBytes(ref pos, payload.Length - pos);

                // TODO Check ask data

                byte[] decryptedData = null;
                PrivateKey myEncryptionKey = null;

                foreach (PrivateKey myKey in bm.ListMyAddresses())
                {
                    if (myKey.Stream != _stream) continue;
                    try
                    {
                        decryptedData = myKey.DecryptAES256CBC4Msg(encrypted);
                        myEncryptionKey = myKey;
                    }
                        // ReSharper disable EmptyGeneralCatchClause
                    catch
                    {
                    } // ReSharper restore EmptyGeneralCatchClause

                    if (decryptedData != null)
                        break;
                }

                if ((decryptedData == null) || (myEncryptionKey == null))
                {
                    Status = Status.Encrypted;
                    return;
                }

                pos = 0;

                Version = decryptedData.ReadVarInt(ref pos);
                var senderKey = new Pubkey(decryptedData, ref pos);

                if (!decryptedData.ReadBytes(ref pos, 20).SequenceEqual(myEncryptionKey.Hash))
                    //print 'The original sender of this message did not send it to you. Someone is attempting a Surreptitious Forwarding Attack.'
                    //print 'See: http://world.std.com/~dtd/sign_encrypt/sign_encrypt7.html'
                    //print 'your toRipe:', toRipe.encode('hex')
                    //print 'embedded destination toRipe:', decryptedData[readPosition:readPosition + 20].encode('hex')
                    return;

                KeyTo = myEncryptionKey.Name;
                KeyFrom = senderKey.Name;

                EncodingType = (EncodingType) decryptedData.ReadVarInt(ref pos);
                decryptedData.ReadVarStrSubjectAndBody(ref pos, out _subject, out _body);

                UInt64 askDataLength = decryptedData.ReadVarInt(ref pos);
                _askData = decryptedData.ReadBytes(ref pos, (int) askDataLength);

                int posOfEndMsg = pos;
                UInt64 signatureLength = decryptedData.ReadVarInt(ref pos);
                byte[] signature = decryptedData.ReadBytes(ref pos, (int) signatureLength);

                var data = new byte[posOfEndMsg];
                Buffer.BlockCopy(decryptedData, 0, data, 0, posOfEndMsg);

                if (data.ECDSAVerify(senderKey.SigningKey, signature))
                {
                    Status = Status.Valid;
                    senderKey.SaveAsync(bm.DB);
                }
            }
            catch
            {
                Status = Status.Invalid;
            }
        }