예제 #1
0
        private void HandleMessageReceive(ChannelMessage message)
        {
            SimpleMessage simpleMessage = new SimpleMessage(message);

            if (ShowTransportPackets)
            {
                CConsole.Gray("{0}", JsonConvert.SerializeObject(simpleMessage, Formatting.Indented));
            }
            if (message.CipherText == null)
            {
                //  It's not a message packet
                if (message.AnnouncedKey != null && message.AcknowledgeKey == null)
                {
                    //  BOB
                    //  Initial announce from other side
                    if (PlaintextMode != message.PlaintextMode)
                    {
                        CConsole.Red("!!! Invalid Far-side configuration! Near-Side PlaintextMode = {0}, Far-Side PlaintextMode = {1}", PlaintextMode, message.PlaintextMode);
                        IsOpen = false;
                        MessageEvent.Set();
                        return;
                        //throw new Exception("PlaintextMode Mismatch");
                    }
                    Parameters = new DHParameters(
                        new BigInteger(message.Param_P, 16),
                        new BigInteger(message.Param_G, 16),
                        new BigInteger(message.Param_Q, 16),
                        message.Param_L);
                    RachetKeyPair = DHKeyPair.Generate(Parameters);
                    if (Verbose)
                    {
                        CConsole.Yellow("RootChainKey = {0}", H(RachetKeyPair.ComputeSharedSecret(message.AnnouncedKey)));
                    }
                    LastParterAnnouncedKey = message.AnnouncedKey;

                    IsOpen = true;
                    MessageEvent.Set();
                }
                else if (message.AnnouncedKey != null && message.AcknowledgeKey != null)
                {
                    //  ALICE
                    //  Initial acknowledge from other side
                    if (Verbose)
                    {
                        CConsole.DarkMagenta("Acknowledging = {0}", message.AnnouncedKey);
                    }
                    LastParterAnnouncedKey = message.AnnouncedKey;
                    if (message.AcknowledgeKey != RachetKeyPair.PublicKey)
                    {
                        CConsole.Red("!!! Invalid AcknowledgedKey !!!");
                        throw new Exception("Invalid AcknowledgedKey");
                    }
                    else
                    {
                        string secretA = RachetKeyPair.ComputeSharedSecret(message.AnnouncedKey);   //FIRST RootChainKey
                        if (PrefilledRootKey != null)
                        {
                            RootChainKey = PrefilledRootKey;
                            string outputA;
                            string outputB;
                            KDF(RootChainKey, RootChainKey, out outputA, out outputB);
                            RootChainKey = outputA;
                        }
                        else
                        {
                            RootChainKey = secretA;
                        }
                        if (Verbose)
                        {
                            CConsole.Yellow("RootChainKey = {0}", H(RootChainKey));
                        }
                        string outputA1;
                        string outputB1;
                        KDF(RootChainKey, RootChainKey, out outputA1, out outputB1);
                        RootChainKey      = outputA1;
                        ReceivingChainKey = outputB1;
                        if (Verbose)
                        {
                            CConsole.DarkYellow("RootChainKey = {0}", H(RootChainKey));
                        }
                        if (Verbose)
                        {
                            CConsole.Magenta("ReceivingChainKey = {0}", H(ReceivingChainKey));
                        }
                        string outputA2;
                        string outputB2;
                        RachetKeyPair = DHKeyPair.Generate(Parameters);
                        if (Verbose)
                        {
                            if (RootChainCount % 2 == 1)
                            {
                                CConsole.DarkMagenta("Announcing = {0}", H(RachetKeyPair.PublicKey));
                            }
                            else
                            {
                                CConsole.DarkCyan("Announcing = {0}", H(RachetKeyPair.PublicKey));
                            }
                        }
                        string secret = RachetKeyPair.ComputeSharedSecret(message.AnnouncedKey);
                        KDF(secret, RootChainKey, out outputA2, out outputB2);
                        RootChainKey    = outputA2;
                        SendingChainKey = outputB2;
                        if (Verbose)
                        {
                            CConsole.Yellow("RootChainKey = {0}", H(RootChainKey));
                        }
                    }
                    IsOpen = true;
                    MessageEvent.Set();
                }
            }
            else
            {
                //  It's a message packet! Do the decrypt
                string text;
                if (!Decrypt(message, out text))
                {
                    throw new Exception("Failed to Decrypt packet!");
                }
                OnMessage(text);
                MessageListener?.Invoke(text);
            }
        }
예제 #2
0
        private bool Decrypt(ChannelMessage message, out string text)
        {
            if (PlaintextMode && message.PlaintextMode)
            {
                text = message.CipherText;
                return(true);
            }
            if (DHRachetNeeded(message.AnnouncedKey, message.AcknowledgeKey))
            {
                string secretA = RachetKeyPair.ComputeSharedSecret(message.AnnouncedKey);
                string outputA1;
                string outputB1;
                KDF(secretA, RootChainKey, out outputA1, out outputB1);
                RootChainKey      = outputA1;
                ReceivingChainKey = outputB1;
                if (Verbose)
                {
                    if (RootChainCount % 2 == 1)
                    {
                        CConsole.Yellow("RootChainKey = {0}", H(RootChainKey));
                    }
                    else
                    {
                        CConsole.DarkYellow("RootChainKey = {0}", H(RootChainKey));
                    }
                }
                if (Verbose)
                {
                    if (RootChainCount % 2 == 1)
                    {
                        CConsole.Blue("ReceivingChainKey = {0}", H(ReceivingChainKey));
                    }
                    else
                    {
                        CConsole.Magenta("ReceivingChainKey = {0}", H(ReceivingChainKey));
                    }
                }

                string messageKey;
                string outputA;
                string outputB;
                KDF(ReceivingChainKey, ReceivingChainKey, out outputA, out outputB);

                messageKey        = outputA;
                ReceivingChainKey = outputB;

                if (Verbose)
                {
                    if (RootChainCount % 2 == 1)
                    {
                        CConsole.Magenta("ReceivingChainKey = {0}", H(ReceivingChainKey));
                    }
                    else
                    {
                        CConsole.Blue("ReceivingChainKey = {0}", H(ReceivingChainKey));
                    }
                }


                if (Verbose)
                {
                    CConsole.DarkGreen("MessageKey = {0}", H(messageKey));
                }

                text = DES.DecryptB64(message.CipherText, messageKey);

                RachetKeyPair = DHKeyPair.Generate(RachetKeyPair.Parameters);
                if (Verbose)
                {
                    if (RootChainCount % 2 == 1)
                    {
                        CConsole.DarkMagenta("Announcing = {0}", H(RachetKeyPair.PublicKey));
                    }
                    else
                    {
                        CConsole.DarkCyan("Announcing = {0}", H(RachetKeyPair.PublicKey));
                    }
                }
                string secretB = RachetKeyPair.ComputeSharedSecret(message.AnnouncedKey);
                string outputA2;
                string outputB2;
                KDF(secretB, RootChainKey, out outputA2, out outputB2);
                RootChainKey    = outputA2;
                SendingChainKey = outputB2;
                if (Verbose)
                {
                    if (RootChainCount % 2 == 1)
                    {
                        CConsole.Yellow("RootChainKey = {0}", H(RootChainKey));
                    }
                    else
                    {
                        CConsole.DarkYellow("RootChainKey = {0}", H(RootChainKey));
                    }
                }

                ReceivingMessageId++;
                return(true);
            }
            else
            {
                if (Verbose)
                {
                    CConsole.Red("ReceivingChainKey = {0}", H(ReceivingChainKey));
                }

                string messageKey;
                string outputA;
                string outputB;
                KDF(ReceivingChainKey, ReceivingChainKey, out outputA, out outputB);

                messageKey        = outputA;
                ReceivingChainKey = outputB;

                if (Verbose)
                {
                    CConsole.DarkGreen("MessageKey = {0}", H(messageKey));
                }

                text = DES.DecryptB64(message.CipherText, messageKey);

                ReceivingMessageId++;
                return(true);
            }
        }
예제 #3
0
        public bool Open(bool sender)
        {
            if (!sender)
            {
                //  BOB
                MessageEvent.WaitOne(30 * 1000); //  Wait until fully opened or timeout in 30s
                if (IsOpen == false)
                {
                    return(false);
                }

                //  Send acknowledge
                if (Verbose)
                {
                    CConsole.DarkCyan("Acknowledging = {0}", LastParterAnnouncedKey);
                }
                if (Verbose)
                {
                    CConsole.DarkMagenta("Announcing = {0}", RachetKeyPair.PublicKey);
                }

                string secret = RachetKeyPair.ComputeSharedSecret(LastParterAnnouncedKey);
                if (PrefilledRootKey != null)
                {
                    RootChainKey = PrefilledRootKey;
                    string outputA1;
                    string outputB1;
                    KDF(RootChainKey, RootChainKey, out outputA1, out outputB1);
                    RootChainKey = outputA1;
                }
                else
                {
                    RootChainKey = secret;
                }
                string outputA;
                string outputB;
                KDF(RootChainKey, RootChainKey, out outputA, out outputB);
                RootChainKey    = outputA;
                SendingChainKey = outputB;
                if (Verbose)
                {
                    CConsole.DarkYellow("RootChainKey = {0}", H(RootChainKey));
                }
                if (Verbose)
                {
                    CConsole.Magenta("SendingChainKey = {0}", H(SendingChainKey));
                }

                ChannelMessage msg = new ChannelMessage()
                {
                    AcknowledgeKey = LastParterAnnouncedKey,
                    AnnouncedKey   = RachetKeyPair.PublicKey,
                    CipherText     = null
                };
                if (!SerializeAndSend(msg))
                {
                    CConsole.Red("!!! Error sending initial announce !!!");
                }
            }
            else
            {
                //  ALICE
                //  Send announce
                RachetKeyPair = DHKeyPair.Generate();
                Parameters    = RachetKeyPair.Parameters;
                ChannelMessage msg = new ChannelMessage()
                {
                    AcknowledgeKey = null,
                    AnnouncedKey   = RachetKeyPair.PublicKey,
                    Param_P        = RachetKeyPair.Parameters.P.ToString(16),
                    Param_G        = RachetKeyPair.Parameters.G.ToString(16),
                    Param_Q        = RachetKeyPair.Parameters.Q.ToString(16),
                    Param_L        = RachetKeyPair.Parameters.L,
                    CipherText     = null,
                    PlaintextMode  = PlaintextMode
                };
                if (Verbose)
                {
                    CConsole.DarkCyan("Announcing = {0}", RachetKeyPair.PublicKey);
                }
                if (!SerializeAndSend(msg))
                {
                    CConsole.Red("!!! Error sending initial announce !!!");
                }
                MessageEvent.WaitOne(30 * 1000); //  wait till fully opened or timeout in 30s
                if (IsOpen == false)
                {
                    return(false);
                }
            }
            return(true);
        }