Exemplo n.º 1
0
        private void InitializeSessionsV2(SessionState aliceSessionState, SessionState bobSessionState)
        {
            var aliceIdentityKeyPair = Curve.GenerateKeyPair();
            var aliceIdentityKey     = new IdentityKeyPair(new IdentityKey(aliceIdentityKeyPair.PublicKey),
                                                                       aliceIdentityKeyPair.PrivateKey);
            var aliceBaseKey         = Curve.GenerateKeyPair();
            var aliceEphemeralKey    = Curve.GenerateKeyPair();

            var bobIdentityKeyPair   = Curve.GenerateKeyPair();
            var bobIdentityKey       = new IdentityKeyPair(new IdentityKey(bobIdentityKeyPair.PublicKey),
                                                                       bobIdentityKeyPair.PrivateKey);
            var bobBaseKey           = Curve.GenerateKeyPair();
            var bobEphemeralKey      = bobBaseKey;

            AliceAxolotlParameters aliceParameters = AliceAxolotlParameters.NewBuilder()
                .SetOurIdentityKey(aliceIdentityKey)
                    .SetOurBaseKey(aliceBaseKey)
                    .SetTheirIdentityKey(bobIdentityKey.PublicKey)
                    .SetTheirSignedPreKey(bobEphemeralKey.PublicKey)
                    .SetTheirRatchetKey(bobEphemeralKey.PublicKey)
                    .SetTheirOneTimePreKey(Maybe<ECPublicKey>.Nothing)
                    .Create();

            BobAxolotlParameters bobParameters = BobAxolotlParameters.NewBuilder()
                .SetOurIdentityKey(bobIdentityKey)
                    .SetOurOneTimePreKey(Maybe<ECKeyPair>.Nothing)
                    .SetOurRatchetKey(bobEphemeralKey)
                    .SetOurSignedPreKey(bobBaseKey)
                    .SetTheirBaseKey(aliceBaseKey.PublicKey)
                    .SetTheirIdentityKey(aliceIdentityKey.PublicKey)
                    .Create();

            RatchetingSession.InitializeSession(aliceSessionState, 2, aliceParameters);
            RatchetingSession.InitializeSession(bobSessionState, 2, bobParameters);
        }
Exemplo n.º 2
0
        public static void InitializeSession(SessionState sessionState,
		                                     UInt32 sessionVersion,
		                                     SymmetricAxolotlParameters parameters)
        {
            try {
                if (IsAlice(parameters.OurBaseKey.PublicKey, parameters.TheirBaseKey))
                {
                    var aliceParams = AliceAxolotlParameters.NewBuilder();

                    aliceParams.SetOurBaseKey(parameters.OurBaseKey)
                            .SetOurIdentityKey(parameters.OurIdentityKey)
                            .SetTheirRatchetKey(parameters.TheirRatchetKey)
                            .SetTheirIdentityKey(parameters.TheirIdentityKey)
                            .SetTheirSignedPreKey(parameters.TheirBaseKey)
                            .SetTheirOneTimePreKey(Maybe<ECPublicKey>.Nothing);

                    RatchetingSession.InitializeSession(sessionState, sessionVersion, aliceParams.Create());
                } else
                {
                    var bobParams = BobAxolotlParameters.NewBuilder();
                    bobParams.SetOurIdentityKey(parameters.OurIdentityKey)
                            .SetOurRatchetKey(parameters.OurRatchetKey)
                            .SetOurSignedPreKey(parameters.OurBaseKey)
                            .SetOurOneTimePreKey(Maybe<ECKeyPair>.Nothing)
                            .SetTheirBaseKey(parameters.TheirBaseKey)
                            .SetTheirIdentityKey(parameters.TheirIdentityKey);

                    RatchetingSession.InitializeSession(sessionState, sessionVersion, bobParams.Create());
                }
            } catch (Exception e) {
                throw new InvalidOperationException ("Asserion error", e);
            }
        }
Exemplo n.º 3
0
        public static void InitializeSession(SessionState sessionState,
					                          UInt32 sessionVersion,
					                          AliceAxolotlParameters parameters)
        {
            try {
                sessionState.SetSessionVersion(sessionVersion);
                sessionState.SetRemoteIdentityKey(parameters.TheirIdentityKey);
                sessionState.SetLocalIdentityKey(parameters.OurIdentityKey.PublicKey);

                ECKeyPair             sendingRatchetKey = Curve.GenerateKeyPair();

                byte[] secrets;
                using(var stream = new MemoryStream())
                using(var sw = new BinaryWriter(stream))
                {
                    byte[] buf;

                    if (sessionVersion >= 3) {
                        buf = GetDiscontinuityBytes();
                        sw.Write(buf);
                    }

                    buf = Curve.CalculateAgreement(parameters.TheirSignedPreKey,
                                                   parameters.OurIdentityKey.PrivateKey);

                    sw.Write(buf);

                    buf = Curve.CalculateAgreement(parameters.TheirIdentityKey.PublicKey,
                                                   parameters.OurBaseKey.PrivateKey);

                    sw.Write(buf);

                    buf = Curve.CalculateAgreement(parameters.TheirSignedPreKey,
                                                   parameters.OurBaseKey.PrivateKey);

                    sw.Write(buf);

                    if (sessionVersion >= 3 && parameters.TheirOneTimePreKey.IsSomething()) {
                        parameters.TheirOneTimePreKey.Do(pKey => {
                            buf = Curve.CalculateAgreement(pKey,
                                                           parameters.OurBaseKey.PrivateKey);
                            sw.Write(buf);
                        });
                    }

                    sw.Flush();

                    secrets = stream.ToArray();
                }

                DerivedKeys             derivedKeys  = CalculateDerivedKeys(sessionVersion, secrets);
                Tuple<RootKey, ChainKey> sendingChain = derivedKeys.RootKey.CreateChain(parameters.TheirRatchetKey, sendingRatchetKey);

                sessionState.AddReceiverChain(parameters.TheirRatchetKey, derivedKeys.ChainKey);
                sessionState.SetSenderChain(sendingRatchetKey, sendingChain.Item2);
                sessionState.RootKey = sendingChain.Item1;
            } catch (Exception e) {
                throw new InvalidOperationException("Assertion error" + e);
            }
        }
Exemplo n.º 4
0
        public SessionRecord()
        {
            PreviousStates = new List<SessionState>();

            SessionState = new SessionState();

            IsFresh = true;
        }
Exemplo n.º 5
0
        public SessionRecord(byte[] serialized)
        {
            PreviousStates = new List<SessionState>();

            RecordStructure record;

            using(var stream = new MemoryStream(serialized))
            {
                record = Serializer.Deserialize<RecordStructure>(stream);
            }

            SessionState = new SessionState(record.CurrentSession);
            IsFresh = false;

            foreach(var previousStructure in record.PreviousSessions)
            {
                PreviousStates.Add(new SessionState(previousStructure));
            }
        }
Exemplo n.º 6
0
 public SessionState(SessionState copy)
 {
     Structure = copy.Structure;
 }
Exemplo n.º 7
0
        public void PromoteState(SessionState promotedState)
        {
            PreviousStates.Insert(0, SessionState);
            SessionState = promotedState;

            if(PreviousStates.Count > ARCHIVED_STATES_MAX_LENGTH)
            {
                PreviousStates.RemoveAt(PreviousStates.Count - 1);
            }
        }
Exemplo n.º 8
0
 public void SetState(SessionState sessionState)
 {
     SessionState = sessionState;
 }
        public void TestRatchetingSessionAsBob()
        {
            byte[] bobPublic             = {(byte) 0x05, (byte) 0x2c, (byte) 0xb4, (byte) 0x97,
                (byte) 0x76, (byte) 0xb8, (byte) 0x77, (byte) 0x02,
                (byte) 0x05, (byte) 0x74, (byte) 0x5a, (byte) 0x3a,
                (byte) 0x6e, (byte) 0x24, (byte) 0xf5, (byte) 0x79,
                (byte) 0xcd, (byte) 0xb4, (byte) 0xba, (byte) 0x7a,
                (byte) 0x89, (byte) 0x04, (byte) 0x10, (byte) 0x05,
                (byte) 0x92, (byte) 0x8e, (byte) 0xbb, (byte) 0xad,
                (byte) 0xc9, (byte) 0xc0, (byte) 0x5a, (byte) 0xd4,
                (byte) 0x58};

            byte[] bobPrivate            = {(byte) 0xa1, (byte) 0xca, (byte) 0xb4, (byte) 0x8f,
                (byte) 0x7c, (byte) 0x89, (byte) 0x3f, (byte) 0xaf,
                (byte) 0xa9, (byte) 0x88, (byte) 0x0a, (byte) 0x28,
                (byte) 0xc3, (byte) 0xb4, (byte) 0x99, (byte) 0x9d,
                (byte) 0x28, (byte) 0xd6, (byte) 0x32, (byte) 0x95,
                (byte) 0x62, (byte) 0xd2, (byte) 0x7a, (byte) 0x4e,
                (byte) 0xa4, (byte) 0xe2, (byte) 0x2e, (byte) 0x9f,
                (byte) 0xf1, (byte) 0xbd, (byte) 0xd6, (byte) 0x5a};

            byte[] bobIdentityPublic     = {(byte) 0x05, (byte) 0xf1, (byte) 0xf4, (byte) 0x38,
                (byte) 0x74, (byte) 0xf6, (byte) 0x96, (byte) 0x69,
                (byte) 0x56, (byte) 0xc2, (byte) 0xdd, (byte) 0x47,
                (byte) 0x3f, (byte) 0x8f, (byte) 0xa1, (byte) 0x5a,
                (byte) 0xde, (byte) 0xb7, (byte) 0x1d, (byte) 0x1c,
                (byte) 0xb9, (byte) 0x91, (byte) 0xb2, (byte) 0x34,
                (byte) 0x16, (byte) 0x92, (byte) 0x32, (byte) 0x4c,
                (byte) 0xef, (byte) 0xb1, (byte) 0xc5, (byte) 0xe6,
                (byte) 0x26};

            byte[] bobIdentityPrivate    = {(byte) 0x48, (byte) 0x75, (byte) 0xcc, (byte) 0x69,
                (byte) 0xdd, (byte) 0xf8, (byte) 0xea, (byte) 0x07,
                (byte) 0x19, (byte) 0xec, (byte) 0x94, (byte) 0x7d,
                (byte) 0x61, (byte) 0x08, (byte) 0x11, (byte) 0x35,
                (byte) 0x86, (byte) 0x8d, (byte) 0x5f, (byte) 0xd8,
                (byte) 0x01, (byte) 0xf0, (byte) 0x2c, (byte) 0x02,
                (byte) 0x25, (byte) 0xe5, (byte) 0x16, (byte) 0xdf,
                (byte) 0x21, (byte) 0x56, (byte) 0x60, (byte) 0x5e};

            byte[] aliceBasePublic       = {(byte) 0x05, (byte) 0x47, (byte) 0x2d, (byte) 0x1f,
                (byte) 0xb1, (byte) 0xa9, (byte) 0x86, (byte) 0x2c,
                (byte) 0x3a, (byte) 0xf6, (byte) 0xbe, (byte) 0xac,
                (byte) 0xa8, (byte) 0x92, (byte) 0x02, (byte) 0x77,
                (byte) 0xe2, (byte) 0xb2, (byte) 0x6f, (byte) 0x4a,
                (byte) 0x79, (byte) 0x21, (byte) 0x3e, (byte) 0xc7,
                (byte) 0xc9, (byte) 0x06, (byte) 0xae, (byte) 0xb3,
                (byte) 0x5e, (byte) 0x03, (byte) 0xcf, (byte) 0x89,
                (byte) 0x50};

            byte[] aliceEphemeralPublic  = {(byte) 0x05, (byte) 0x6c, (byte) 0x3e, (byte) 0x0d,
                (byte) 0x1f, (byte) 0x52, (byte) 0x02, (byte) 0x83,
                (byte) 0xef, (byte) 0xcc, (byte) 0x55, (byte) 0xfc,
                (byte) 0xa5, (byte) 0xe6, (byte) 0x70, (byte) 0x75,
                (byte) 0xb9, (byte) 0x04, (byte) 0x00, (byte) 0x7f,
                (byte) 0x18, (byte) 0x81, (byte) 0xd1, (byte) 0x51,
                (byte) 0xaf, (byte) 0x76, (byte) 0xdf, (byte) 0x18,
                (byte) 0xc5, (byte) 0x1d, (byte) 0x29, (byte) 0xd3,
                (byte) 0x4b};

            byte[] aliceIdentityPublic   = {(byte) 0x05, (byte) 0xb4, (byte) 0xa8, (byte) 0x45,
                (byte) 0x56, (byte) 0x60, (byte) 0xad, (byte) 0xa6,
                (byte) 0x5b, (byte) 0x40, (byte) 0x10, (byte) 0x07,
                (byte) 0xf6, (byte) 0x15, (byte) 0xe6, (byte) 0x54,
                (byte) 0x04, (byte) 0x17, (byte) 0x46, (byte) 0x43,
                (byte) 0x2e, (byte) 0x33, (byte) 0x39, (byte) 0xc6,
                (byte) 0x87, (byte) 0x51, (byte) 0x49, (byte) 0xbc,
                (byte) 0xee, (byte) 0xfc, (byte) 0xb4, (byte) 0x2b,
                (byte) 0x4a};

            byte[] senderChain           = {(byte)0xd2, (byte)0x2f, (byte)0xd5, (byte)0x6d, (byte)0x3f,
                (byte)0xec, (byte)0x81, (byte)0x9c, (byte)0xf4, (byte)0xc3,
                (byte)0xd5, (byte)0x0c, (byte)0x56, (byte)0xed, (byte)0xfb,
                (byte)0x1c, (byte)0x28, (byte)0x0a, (byte)0x1b, (byte)0x31,
                (byte)0x96, (byte)0x45, (byte)0x37, (byte)0xf1, (byte)0xd1,
                (byte)0x61, (byte)0xe1, (byte)0xc9, (byte)0x31, (byte)0x48,
                (byte)0xe3, (byte)0x6b};

            IdentityKey     bobIdentityKeyPublic   = new IdentityKey(bobIdentityPublic, 0);
            ECPrivateKey    bobIdentityKeyPrivate  = Curve.DecodePrivatePoint(bobIdentityPrivate);
            IdentityKeyPair bobIdentityKey         = new IdentityKeyPair(bobIdentityKeyPublic, bobIdentityKeyPrivate);
            ECPublicKey     bobEphemeralPublicKey  = Curve.DecodePoint(bobPublic, 0);
            ECPrivateKey    bobEphemeralPrivateKey = Curve.DecodePrivatePoint(bobPrivate);
            ECKeyPair       bobEphemeralKey        = new ECKeyPair(bobEphemeralPrivateKey, bobEphemeralPublicKey);
            ECKeyPair       bobBaseKey             = bobEphemeralKey;

            ECPublicKey     aliceBasePublicKey       = Curve.DecodePoint(aliceBasePublic, 0);
            // ECPublicKey     aliceEphemeralPublicKey  = Curve.DecodePoint(aliceEphemeralPublic, 0);
            IdentityKey     aliceIdentityPublicKey   = new IdentityKey(aliceIdentityPublic, 0);

            BobAxolotlParameters parameters = BobAxolotlParameters.NewBuilder()
                .SetOurIdentityKey(bobIdentityKey)
                    .SetOurSignedPreKey(bobBaseKey)
                    .SetOurRatchetKey(bobEphemeralKey)
                    .SetOurOneTimePreKey(Maybe<ECKeyPair>.Nothing)
                    .SetTheirIdentityKey(aliceIdentityPublicKey)
                    .SetTheirBaseKey(aliceBasePublicKey)
                    .Create();

            SessionState session = new SessionState();

            RatchetingSession.InitializeSession(session, 2, parameters);

            var bobPk = bobIdentityKey.PublicKey;
            var sessionLocalIk = session.GetLocalIdentityKey ();

            Assert.True (sessionLocalIk.Equals (bobPk));
            Assert.True (session.GetRemoteIdentityKey().Equals (aliceIdentityPublicKey));
            Assert.True (ArrayComparer.Compare(session.GetSenderChainKey().Key, senderChain));
        }
Exemplo n.º 10
0
        public static void InitializeSession(SessionState sessionState,
					                          UInt32 sessionVersion,
					                          BobAxolotlParameters parameters)
        {
            try {
                sessionState.SetSessionVersion(sessionVersion);
                sessionState.SetRemoteIdentityKey(parameters.TheirIdentityKey);
                sessionState.SetLocalIdentityKey(parameters.OurIdentityKey.PublicKey);

                byte[] secrets;

                using(var stream = new MemoryStream())
                using(var sw = new BinaryWriter(stream))
                {
                    byte[] buffer;

                    if (sessionVersion >= 3) {
                        buffer = GetDiscontinuityBytes();
                        sw.Write(buffer);
                    }

                    buffer = Curve.CalculateAgreement(parameters.TheirIdentityKey.PublicKey,
                                                      parameters.OurSignedPreKey.PrivateKey);
                    sw.Write(buffer);

                    buffer = Curve.CalculateAgreement(parameters.TheirBaseKey,
                                                      parameters.OurIdentityKey.PrivateKey);
                    sw.Write(buffer);

                    buffer = Curve.CalculateAgreement(parameters.TheirBaseKey,
                                                      parameters.OurSignedPreKey.PrivateKey);
                    sw.Write(buffer);

                    if (sessionVersion >= 3 && parameters.OurOneTimePreKey.IsSomething()) {

                        parameters.OurOneTimePreKey.Do(otpK => {
                            buffer = Curve.CalculateAgreement(parameters.TheirBaseKey, otpK.PrivateKey);
                            sw.Write(buffer);
                        });
                    }

                    sw.Flush();

                    secrets = stream.ToArray();
                }

                DerivedKeys derivedKeys = CalculateDerivedKeys(sessionVersion, secrets);

                sessionState.SetSenderChain(parameters.OurRatchetKey, derivedKeys.ChainKey);
                sessionState.RootKey = derivedKeys.RootKey;
            } catch (Exception e) {
                throw new InvalidOperationException("Assertion error", e);
            }
        }
Exemplo n.º 11
0
        private MessageKeys GetOrCreateMessageKeys(SessionState sessionState, ECPublicKey theirEphemeral, ChainKey chainKey, UInt32 counter)
        {
            if(chainKey.Index > counter)
            {
                if(sessionState.HasMessageKeys(theirEphemeral, counter))
                {
                    return sessionState.RemoveMessageKeys(theirEphemeral, counter);
                }
                else
                {
                    throw new DuplicateMessageException("Received message with old counter: " +
                    chainKey.Index + " , " + counter);
                }
            }

            if(counter - chainKey.Index > 2000)
            {
                throw new InvalidMessageException("Over 2000 messages into the future!");
            }

            while(chainKey.Index < counter)
            {
                MessageKeys messageKeys = chainKey.GetMessageKeys();
                sessionState.SetMessageKeys(theirEphemeral, messageKeys);
                chainKey = chainKey.GetNextChainKey();
            }

            sessionState.SetReceiverChainKey(theirEphemeral, chainKey.GetNextChainKey());
            return chainKey.GetMessageKeys();
        }
Exemplo n.º 12
0
        private ChainKey GetOrCreateChainKey(SessionState sessionState, ECPublicKey theirEphemeral)
        {
            try
            {
                if(sessionState.HasReceiverChain(theirEphemeral))
                {
                    return sessionState.GetReceiverChainKey(theirEphemeral);
                }
                else
                {
                    RootKey rootKey = sessionState.RootKey;
                    ECKeyPair ourEphemeral = sessionState.SenderRatchetKeyPair;
                    Tuple<RootKey, ChainKey> receiverChain = rootKey.CreateChain(theirEphemeral, ourEphemeral);
                    ECKeyPair ourNewEphemeral = Curve.GenerateKeyPair();
                    Tuple<RootKey, ChainKey> senderChain = receiverChain.Item1.CreateChain(theirEphemeral, ourNewEphemeral);

                    sessionState.RootKey = senderChain.Item1;
                    sessionState.AddReceiverChain(theirEphemeral, receiverChain.Item2);
                    sessionState.PreviousCounter = Math.Max(sessionState.GetSenderChainKey().Index - 1, 0);
                    sessionState.SetSenderChain(ourNewEphemeral, senderChain.Item2);

                    return receiverChain.Item2;
                }
            }
            catch(InvalidKeyException e)
            {
                throw new InvalidMessageException(e);
            }
        }
Exemplo n.º 13
0
        private byte[] Decrypt(SessionState sessionState, WhisperMessage ciphertextMessage)
        {
            if(!sessionState.HasSenderChain())
            {
                throw new InvalidMessageException("Uninitialized session!");
            }

            if(ciphertextMessage.MessageVersion != sessionState.GetSessionVersion())
            {
                throw new InvalidMessageException(string.Format("Message version {0}, but session version {1}",
                    ciphertextMessage.MessageVersion,
                    sessionState.GetSessionVersion()));
            }

            UInt32 messageVersion = ciphertextMessage.MessageVersion;
            ECPublicKey theirEphemeral = ciphertextMessage.SenderRatchetKey;
            UInt32 counter = ciphertextMessage.Counter;
            ChainKey chainKey = GetOrCreateChainKey(sessionState, theirEphemeral);
            MessageKeys messageKeys = GetOrCreateMessageKeys(sessionState, theirEphemeral,
                                          chainKey, counter);

            ciphertextMessage.VerifyMac(messageVersion,
                sessionState.GetRemoteIdentityKey(),
                sessionState.GetLocalIdentityKey(),
                messageKeys.MacKey);

            byte[] plaintext = GetPlaintext(messageVersion, messageKeys, ciphertextMessage.Body);

            sessionState.ClearUnacknowledgedPreKeyMessage();

            return plaintext;
        }
Exemplo n.º 14
0
        private byte[] Decrypt(SessionRecord sessionRecord, WhisperMessage ciphertext)
        {
            lock(SESSION_LOCK)
            {
                var previousStates = new List<SessionState>(sessionRecord.PreviousStates);
                var exceptions = new List<Exception>();

                try
                {
                    var sessionState = new SessionState(sessionRecord.SessionState);
                    byte[] plaintext = Decrypt(sessionState, ciphertext);

                    sessionRecord.SetState(sessionState);
                    return plaintext;
                }
                catch(InvalidMessageException e)
                {
                    exceptions.Add(e);
                }

                // TODO: Check~
                foreach(var state in previousStates)
                {
                    try
                    {
                        var promotedState = new SessionState(state);
                        byte[] plainText = Decrypt(promotedState, ciphertext);
                        sessionRecord.PreviousStates.Remove(state);
                        return plainText;
                    }
                    catch(InvalidMessageException e)
                    {
                        exceptions.Add(e);
                    }

                }

                throw new InvalidMessageException("No valid sessions.", exceptions);
            }
        }