コード例 #1
0
ファイル: AxolotlManager.cs プロジェクト: kaank/Chat-API-NET
        /// <summary>
        /// Generate the keysets for ourself
        /// </summary>
        /// <returns></returns>
        public bool sendSetPreKeys(bool isnew = false)
        {
            uint registrationId = 0;

            if (!isnew)
            {
                registrationId = (uint)this.GetLocalRegistrationId();
            }
            else
            {
                registrationId = libaxolotl.util.KeyHelper.generateRegistrationId(true);
            }
            Random          random          = new Random();
            uint            randomid        = (uint)libaxolotl.util.KeyHelper.getRandomSequence(65536);
            IdentityKeyPair identityKeyPair = libaxolotl.util.KeyHelper.generateIdentityKeyPair();

            byte[] privateKey                  = identityKeyPair.getPrivateKey().serialize();
            byte[] publicKey                   = identityKeyPair.getPublicKey().serialize();
            IList <PreKeyRecord> preKeys       = libaxolotl.util.KeyHelper.generatePreKeys((uint)random.Next(), 200);
            SignedPreKeyRecord   signedPreKey  = libaxolotl.util.KeyHelper.generateSignedPreKey(identityKeyPair, randomid);
            PreKeyRecord         lastResortKey = libaxolotl.util.KeyHelper.generateLastResortPreKey();

            this.StorePreKeys(preKeys);
            this.StoreLocalData(registrationId, identityKeyPair.getPublicKey().serialize(), identityKeyPair.getPrivateKey().serialize());
            this.StoreSignedPreKey(signedPreKey.getId(), signedPreKey);

            List <ProtocolTreeNode> preKeyNodes = new List <ProtocolTreeNode>();

            for (int i = 0; i < 200; i++)
            {
                byte[]           prekeyId  = adjustId(preKeys[i].getId().ToString());
                byte[]           prekey    = preKeys[i].getKeyPair().getPublicKey().serialize().Skip(1).ToArray();
                ProtocolTreeNode NodeId    = new ProtocolTreeNode("id", null, null, prekeyId);
                ProtocolTreeNode NodeValue = new ProtocolTreeNode("value", null, null, prekey);
                preKeyNodes.Add(new ProtocolTreeNode("key", null, new[] { NodeId, NodeValue }, null));
            }

            ProtocolTreeNode registration = new ProtocolTreeNode("registration", null, null, adjustId(registrationId.ToString()));
            ProtocolTreeNode identity     = new ProtocolTreeNode("identity", null, null, publicKey.Skip(1).ToArray());
            ProtocolTreeNode type         = new ProtocolTreeNode("type", null, null, new byte[] { Curve.DJB_TYPE });
            ProtocolTreeNode list         = new ProtocolTreeNode("list", null, preKeyNodes.ToArray(), null);
            ProtocolTreeNode sid          = new ProtocolTreeNode("id", null, null, adjustId(signedPreKey.getId().ToString()));
            ProtocolTreeNode value        = new ProtocolTreeNode("value", null, null, signedPreKey.getKeyPair().getPublicKey().serialize().Skip(1).ToArray());
            ProtocolTreeNode signature    = new ProtocolTreeNode("signature", null, null, signedPreKey.getSignature());
            ProtocolTreeNode secretKey    = new ProtocolTreeNode("skey", null, new[] { sid, value, signature }, null);

            String id = TicketManager.GenerateId();

            Helper.DebugAdapter.Instance.fireOnPrintDebug(string.Format("axolotl id = {0}", id));

            ProtocolTreeNode Node = new ProtocolTreeNode("iq", new[] {
                new KeyValue("id", id),
                new KeyValue("xmlns", "encrypt"),
                new KeyValue("type", "set"),
                new KeyValue("to", "s.whatsapp.net")
            }, new ProtocolTreeNode[] { identity, registration, type, list, secretKey }, null);

            this.SendNode(Node);
            return(true);
        }
コード例 #2
0
        public OmemoBundleInformation getOmemoBundleInformation()
        {
            List <Tuple <uint, ECPublicKey> > pubPreKeys = new List <Tuple <uint, ECPublicKey> >();

            foreach (PreKeyRecord key in omemoPreKeys)
            {
                pubPreKeys.Add(new Tuple <uint, ECPublicKey>(key.getId(), key.getKeyPair().getPublicKey()));
            }
            return(new OmemoBundleInformation(omemoIdentityKeyPair.getPublicKey(), omemoSignedPreKeyPair.getKeyPair().getPublicKey(), omemoSignedPreKeyId, omemoSignedPreKeyPair.getSignature(), pubPreKeys));
        }
コード例 #3
0
        private void initializeSessionsV2(SessionState aliceSessionState, SessionState bobSessionState)
        {
            ECKeyPair       aliceIdentityKeyPair = Curve.generateKeyPair();
            IdentityKeyPair aliceIdentityKey     = new IdentityKeyPair(new IdentityKey(aliceIdentityKeyPair.getPublicKey()),
                                                                       aliceIdentityKeyPair.getPrivateKey());
            ECKeyPair aliceBaseKey      = Curve.generateKeyPair();
            ECKeyPair aliceEphemeralKey = Curve.generateKeyPair();

            ECKeyPair       bobIdentityKeyPair = Curve.generateKeyPair();
            IdentityKeyPair bobIdentityKey     = new IdentityKeyPair(new IdentityKey(bobIdentityKeyPair.getPublicKey()),
                                                                     bobIdentityKeyPair.getPrivateKey());
            ECKeyPair bobBaseKey      = Curve.generateKeyPair();
            ECKeyPair bobEphemeralKey = bobBaseKey;

            AliceAxolotlParameters aliceParameters = AliceAxolotlParameters.newBuilder()
                                                     .setOurIdentityKey(aliceIdentityKey)
                                                     .setOurBaseKey(aliceBaseKey)
                                                     .setTheirIdentityKey(bobIdentityKey.getPublicKey())
                                                     .setTheirSignedPreKey(bobEphemeralKey.getPublicKey())
                                                     .setTheirRatchetKey(bobEphemeralKey.getPublicKey())
                                                     .setTheirOneTimePreKey(May <ECPublicKey> .NoValue)
                                                     .create();

            BobAxolotlParameters bobParameters = BobAxolotlParameters.newBuilder()
                                                 .setOurIdentityKey(bobIdentityKey)
                                                 .setOurOneTimePreKey(May <ECKeyPair> .NoValue)
                                                 .setOurRatchetKey(bobEphemeralKey)
                                                 .setOurSignedPreKey(bobBaseKey)
                                                 .setTheirBaseKey(aliceBaseKey.getPublicKey())
                                                 .setTheirIdentityKey(aliceIdentityKey.getPublicKey())
                                                 .create();

            RatchetingSession.initializeSession(aliceSessionState, 2, aliceParameters);
            RatchetingSession.initializeSession(bobSessionState, 2, bobParameters);
        }
コード例 #4
0
        /// <summary>
        /// TODO
        /// </summary>
        /// <param name="deviceIdentifier"></param>
        /// <param name="deviceKey"></param>
        /// <param name="identityKeyPair"></param>
        /// <param name="profileKey"></param>
        /// <param name="code"></param>
        /// <param name="token"></param>
        /// <exception cref="InvalidKeyException"><</exception>
        /// <exception cref="IOException"></exception>
        public async Task AddDeviceAsync(string deviceIdentifier,
                                         ECPublicKey deviceKey,
                                         IdentityKeyPair identityKeyPair,
                                         byte[] profileKey,
                                         string code,
                                         CancellationToken?token = null)
        {
            if (token == null)
            {
                token = CancellationToken.None;
            }

            ProvisioningCipher cipher  = new ProvisioningCipher(deviceKey);
            ProvisionMessage   message = new ProvisionMessage
            {
                IdentityKeyPublic  = ByteString.CopyFrom(identityKeyPair.getPublicKey().serialize()),
                IdentityKeyPrivate = ByteString.CopyFrom(identityKeyPair.getPrivateKey().serialize()),
                Number             = credentials.E164,
                ProvisioningCode   = code
            };

            if (profileKey != null)
            {
                message.ProfileKey = ByteString.CopyFrom(profileKey);
            }

            byte[] ciphertext = cipher.Encrypt(message);
            await pushServiceSocket.SendProvisioningMessageAsync(deviceIdentifier, ciphertext, token);
        }
コード例 #5
0
        public DeviceConsistencyMessage(DeviceConsistencyCommitment commitment, IdentityKeyPair identityKeyPair)
        {
            try
            {
                byte[] signatureBytes = Curve.calculateVrfSignature(identityKeyPair.getPrivateKey(), commitment.toByteArray());
                byte[] vrfOutputBytes = Curve.verifyVrfSignature(identityKeyPair.getPublicKey().getPublicKey(), commitment.toByteArray(), signatureBytes);

                this.generation = commitment.getGeneration();
                this.signature  = new DeviceConsistencySignature(signatureBytes, vrfOutputBytes);
                this.serialized = new DeviceConsistencyCodeMessage
                {
                    Generation = (uint)commitment.getGeneration(),
                    Signature  = ByteString.CopyFrom(signature.getSignature())
                }.ToByteArray();
            }
            catch (InvalidKeyException e)
            {
                Debug.Assert(false);
                throw e;
            }
            catch (VrfSignatureVerificationFailedException e)
            {
                Debug.Assert(false);
                throw e;
            }
        }
コード例 #6
0
        protected override async Task <string> ExecuteAsync()
        {
            //if (!TextSecurePreferences.isPushRegistered()) return;

            int availableKeys = await App.Current.accountManager.getPreKeysCount();

            if (availableKeys >= PREKEY_MINIMUM && TextSecurePreferences.isSignedPreKeyRegistered())
            {
                Debug.WriteLine("Available keys sufficient: " + availableKeys);
                return("");
            }

            List <PreKeyRecord> preKeyRecords = await PreKeyUtil.generatePreKeys(/*context, masterSecret*/);

            PreKeyRecord lastResortKeyRecord = await PreKeyUtil.generateLastResortKey(/*context, masterSecret*/);

            IdentityKeyPair    identityKey        = IdentityKeyUtil.GetIdentityKeyPair(/*context, masterSecret*/);
            SignedPreKeyRecord signedPreKeyRecord = PreKeyUtil.generateSignedPreKey(/*context, masterSecret, */ identityKey);

            Debug.WriteLine("Registering new prekeys...");

            await App.Current.accountManager.setPreKeys(identityKey.getPublicKey(), lastResortKeyRecord, signedPreKeyRecord, preKeyRecords);

            TextSecurePreferences.setSignedPreKeyRegistered(true);

            //App.Current.Worker.AddTaskActivities(new CleanPreKeysTask());

            return("");
        }
コード例 #7
0
        private async Task <bool> handleRegistration(string receivedSmsVerificationCode)
        {
            try
            {
                var registrationId = KeyHelper.generateRegistrationId(false);
                TextSecurePreferences.setLocalRegistrationId((int)registrationId);

                await App.Current.accountManager.verifyAccountWithCode(receivedSmsVerificationCode, signalingKey, registrationId, false);

                //await PushHelper.getInstance().OpenChannelAndUpload(); // also updates push channel id

                Recipient self = DatabaseFactory.getRecipientDatabase().GetSelfRecipient(number);
                IdentityKeyUtil.generateIdentityKeys();
                IdentityKeyPair     identityKey = IdentityKeyUtil.GetIdentityKeyPair();
                List <PreKeyRecord> records     = await PreKeyUtil.generatePreKeys();

                PreKeyRecord lastResort = await PreKeyUtil.generateLastResortKey();

                SignedPreKeyRecord signedPreKey = await PreKeyUtil.generateSignedPreKey(identityKey);

                await App.Current.accountManager.setPreKeys(identityKey.getPublicKey(), lastResort, signedPreKey, records);

                DatabaseFactory.getIdentityDatabase().SaveIdentity(self.getRecipientId(), identityKey.getPublicKey());

                //await DirectoryHelper.refreshDirectory(App.Current.accountManager, TextSecurePreferences.getLocalNumber());


                markAsVerified(number, password, signalingKey);
            }
            catch (RateLimitException ex)
            {
                return(false);
            }
            catch (AuthorizationFailedException ex)
            {
                return(false);
            }
            catch (PushNetworkException ex)
            {
                return(false);
            }
            catch (NonSuccessfulResponseCodeException ex)
            {
                return(false);
            }
            catch (Exception ex)
            {
                return(false);
                //throw new Exception(ex.Message);
            }

            return(true);
        }
コード例 #8
0
        public void Test_CryptoUtils_GenOmemoFingerprint()
        {
            string identKeyPairSerializedHex = "0a210511dbad7fcece74492f390f0a2a8387c543e802ab7f2176e303e28840559c41521220a082ae07fd8941536457cb2f3e4b560a87991d380f02af460b5204e46ca7b15a";

            byte[]          identKeyPairSerialized = CryptoUtils.hexStringToByteArray(identKeyPairSerializedHex);
            IdentityKeyPair identKeyPair           = new IdentityKeyPair(identKeyPairSerialized);

            string outputRef = "11dbad7f cece7449 2f390f0a 2a8387c5 43e802ab 7f2176e3 03e28840 559c4152";
            string output    = CryptoUtils.generateOmemoFingerprint(identKeyPair.getPublicKey(), false);

            Assert.AreEqual(outputRef, output);
        }
コード例 #9
0
        public async void addDevice(string deviceIdentifier,
                                    ECPublicKey deviceKey,
                                    IdentityKeyPair identityKeyPair,
                                    string code)//throws InvalidKeyException, IOException
        {
            ProvisioningCipher cipher  = new ProvisioningCipher(deviceKey);
            ProvisionMessage   message = ProvisionMessage.CreateBuilder()
                                         .SetIdentityKeyPublic(ByteString.CopyFrom(identityKeyPair.getPublicKey().serialize()))
                                         .SetIdentityKeyPrivate(ByteString.CopyFrom(identityKeyPair.getPrivateKey().serialize()))
                                         .SetNumber(user)
                                         .SetProvisioningCode(code)
                                         .Build();

            byte[] ciphertext = cipher.encrypt(message);
            await this.pushServiceSocket.sendProvisioningMessage(deviceIdentifier, ciphertext);
        }
コード例 #10
0
        public void setPendingKeyExchange(uint sequence,
                                          ECKeyPair ourBaseKey,
                                          ECKeyPair ourRatchetKey,
                                          IdentityKeyPair ourIdentityKey)
        {
            PendingKeyExchange structure = new PendingKeyExchange
            {
                LocalBaseKey            = ByteString.CopyFrom(ourBaseKey.getPublicKey().serialize()),
                LocalBaseKeyPrivate     = ByteString.CopyFrom(ourBaseKey.getPrivateKey().serialize()),
                LocalRatchetKey         = ByteString.CopyFrom(ourRatchetKey.getPublicKey().serialize()),
                LocalRatchetKeyPrivate  = ByteString.CopyFrom(ourRatchetKey.getPrivateKey().serialize()),
                LocalIdentityKey        = ByteString.CopyFrom(ourIdentityKey.getPublicKey().serialize()),
                LocalIdentityKeyPrivate = ByteString.CopyFrom(ourIdentityKey.getPrivateKey().serialize())
            };

            this.sessionStructure.PendingKeyExchange = structure;
        }
コード例 #11
0
        public void addDevice(string deviceIdentifier,
                              ECPublicKey deviceKey,
                              IdentityKeyPair identityKeyPair,
                              string code)//throws InvalidKeyException, IOException
        {
            ProvisioningCipher cipher  = new ProvisioningCipher(deviceKey);
            ProvisionMessage   message = new ProvisionMessage
            {
                IdentityKeyPublic  = ByteString.CopyFrom(identityKeyPair.getPublicKey().serialize()),
                IdentityKeyPrivate = ByteString.CopyFrom(identityKeyPair.getPrivateKey().serialize()),
                Number             = user,
                ProvisioningCode   = code
            };

            byte[] ciphertext = cipher.encrypt(message);
            this.pushServiceSocket.sendProvisioningMessage(deviceIdentifier, ciphertext);
        }
コード例 #12
0
        public void testDeviceConsistency()
        {
            IdentityKeyPair deviceOne   = KeyHelper.generateIdentityKeyPair();
            IdentityKeyPair deviceTwo   = KeyHelper.generateIdentityKeyPair();
            IdentityKeyPair deviceThree = KeyHelper.generateIdentityKeyPair();

            List <IdentityKey> keyList = new List <IdentityKey>(new[]
            {
                deviceOne.getPublicKey(),
                deviceTwo.getPublicKey(),
                deviceThree.getPublicKey()
            });

            Random random = new Random();

            HelperMethods.Shuffle(keyList, random);
            DeviceConsistencyCommitment deviceOneCommitment = new DeviceConsistencyCommitment(1, keyList);

            HelperMethods.Shuffle(keyList, random);
            DeviceConsistencyCommitment deviceTwoCommitment = new DeviceConsistencyCommitment(1, keyList);

            HelperMethods.Shuffle(keyList, random);
            DeviceConsistencyCommitment deviceThreeCommitment = new DeviceConsistencyCommitment(1, keyList);

            CollectionAssert.AreEqual(deviceOneCommitment.toByteArray(), deviceTwoCommitment.toByteArray());
            CollectionAssert.AreEqual(deviceTwoCommitment.toByteArray(), deviceThreeCommitment.toByteArray());

            DeviceConsistencyMessage deviceOneMessage   = new DeviceConsistencyMessage(deviceOneCommitment, deviceOne);
            DeviceConsistencyMessage deviceTwoMessage   = new DeviceConsistencyMessage(deviceOneCommitment, deviceTwo);
            DeviceConsistencyMessage deviceThreeMessage = new DeviceConsistencyMessage(deviceOneCommitment, deviceThree);

            DeviceConsistencyMessage receivedDeviceOneMessage   = new DeviceConsistencyMessage(deviceOneCommitment, deviceOneMessage.getSerialized(), deviceOne.getPublicKey());
            DeviceConsistencyMessage receivedDeviceTwoMessage   = new DeviceConsistencyMessage(deviceOneCommitment, deviceTwoMessage.getSerialized(), deviceTwo.getPublicKey());
            DeviceConsistencyMessage receivedDeviceThreeMessage = new DeviceConsistencyMessage(deviceOneCommitment, deviceThreeMessage.getSerialized(), deviceThree.getPublicKey());

            CollectionAssert.AreEqual(deviceOneMessage.getSignature().getVrfOutput(), receivedDeviceOneMessage.getSignature().getVrfOutput());
            CollectionAssert.AreEqual(deviceTwoMessage.getSignature().getVrfOutput(), receivedDeviceTwoMessage.getSignature().getVrfOutput());
            CollectionAssert.AreEqual(deviceThreeMessage.getSignature().getVrfOutput(), receivedDeviceThreeMessage.getSignature().getVrfOutput());

            string codeOne   = generateCode(deviceOneCommitment, deviceOneMessage, receivedDeviceTwoMessage, receivedDeviceThreeMessage);
            string codeTwo   = generateCode(deviceTwoCommitment, deviceTwoMessage, receivedDeviceThreeMessage, receivedDeviceOneMessage);
            string codeThree = generateCode(deviceThreeCommitment, deviceThreeMessage, receivedDeviceTwoMessage, receivedDeviceOneMessage);

            Assert.AreEqual(codeOne, codeTwo);
            Assert.AreEqual(codeTwo, codeThree);
        }
コード例 #13
0
ファイル: SessionState.cs プロジェクト: jmue/libaxolotl-uwp
        public void setPendingKeyExchange(uint sequence,
                                          ECKeyPair ourBaseKey,
                                          ECKeyPair ourRatchetKey,
                                          IdentityKeyPair ourIdentityKey)
        {
            PendingKeyExchange structure =
                PendingKeyExchange.CreateBuilder()
                .SetSequence(sequence)
                .SetLocalBaseKey(ByteString.CopyFrom(ourBaseKey.getPublicKey().serialize()))
                .SetLocalBaseKeyPrivate(ByteString.CopyFrom(ourBaseKey.getPrivateKey().serialize()))
                .SetLocalRatchetKey(ByteString.CopyFrom(ourRatchetKey.getPublicKey().serialize()))
                .SetLocalRatchetKeyPrivate(ByteString.CopyFrom(ourRatchetKey.getPrivateKey().serialize()))
                .SetLocalIdentityKey(ByteString.CopyFrom(ourIdentityKey.getPublicKey().serialize()))
                .SetLocalIdentityKeyPrivate(ByteString.CopyFrom(ourIdentityKey.getPrivateKey().serialize()))
                .Build();

            this.sessionStructure = this.sessionStructure.ToBuilder()
                                    .SetPendingKeyExchange(structure)
                                    .Build();
        }
コード例 #14
0
ファイル: Test_Omemo.cs プロジェクト: Chryssie/UWPX-Client
        public string getBundleInfoMsg(IdentityKeyPair identKey, SignedPreKeyRecord signedPreKey, IList <PreKeyRecord> preKeys)
        {
            IList <Tuple <uint, ECPublicKey> > publicPreKeys = new List <Tuple <uint, ECPublicKey> >();

            foreach (PreKeyRecord pk in preKeys)
            {
                publicPreKeys.Add(new Tuple <uint, ECPublicKey>(pk.getId(), pk.getKeyPair().getPublicKey()));
            }
            OmemoBundleInformation bundleInfo = new OmemoBundleInformation(identKey.getPublicKey(), signedPreKey.getKeyPair().getPublicKey(), signedPreKey.getId(), signedPreKey.getSignature(), publicPreKeys);

            StringBuilder sb = new StringBuilder("<iq xml:lang='en' to='");

            sb.Append(ALICE_ADDRESS.getName());
            sb.Append("/SOME_RESOURCE' from='");
            sb.Append(BOB_ADDRESS.getName());
            sb.Append("' type='result' id='83d5aa79-484b-4b76-83db-703f5cf60b57'><pubsub xmlns='http://jabber.org/protocol/pubsub'><items node='eu.siacs.conversations.axolotl.bundles:");
            sb.Append(BOB_ADDRESS.getDeviceId());
            sb.Append("'>");
            sb.Append(bundleInfo.toXElement(Consts.XML_XEP_0384_BUNDLE_INFO_NODE + BOB_ADDRESS.getDeviceId()));
            sb.Append("</items></pubsub></iq>");

            return(sb.ToString());
        }
コード例 #15
0
        /// <summary>
        /// TODO
        /// </summary>
        /// <param name="token"></param>
        /// <param name="deviceIdentifier"></param>
        /// <param name="deviceKey"></param>
        /// <param name="identityKeyPair"></param>
        /// <param name="profileKey"></param>
        /// <param name="code"></param>
        public async Task AddDevice(CancellationToken token,
                                    string deviceIdentifier,
                                    ECPublicKey deviceKey,
                                    IdentityKeyPair identityKeyPair,
                                    byte[] profileKey,
                                    string code)//throws InvalidKeyException, IOException
        {
            ProvisioningCipher cipher  = new ProvisioningCipher(deviceKey);
            ProvisionMessage   message = new ProvisionMessage
            {
                IdentityKeyPublic  = ByteString.CopyFrom(identityKeyPair.getPublicKey().serialize()),
                IdentityKeyPrivate = ByteString.CopyFrom(identityKeyPair.getPrivateKey().serialize()),
                Number             = User,
                ProvisioningCode   = code
            };

            if (profileKey != null)
            {
                message.ProfileKey = ByteString.CopyFrom(profileKey);
            }

            byte[] ciphertext = cipher.encrypt(message);
            await PushServiceSocket.SendProvisioningMessage(token, deviceIdentifier, ciphertext);
        }
コード例 #16
0
        public void Test_Libsignal_Enc_Dec_2()
        {
            // Generate Alices keys:
            IdentityKeyPair      aliceIdentKey     = CryptoUtils.generateOmemoIdentityKeyPair();
            IList <PreKeyRecord> alicePreKeys      = CryptoUtils.generateOmemoPreKeys();
            SignedPreKeyRecord   aliceSignedPreKey = CryptoUtils.generateOmemoSignedPreKey(aliceIdentKey);

            // Create Alices stores:
            InMemoryIdentityKeyStore aliceIdentStore  = new InMemoryIdentityKeyStore(aliceIdentKey, ALICE_ADDRESS.getDeviceId());
            InMemoryPreKeyStore      alicePreKeyStore = new InMemoryPreKeyStore();

            foreach (PreKeyRecord key in alicePreKeys)
            {
                alicePreKeyStore.StorePreKey(key.getId(), key);
            }
            InMemorySignedPreKeyStore aliceSignedPreKeyStore = new InMemorySignedPreKeyStore();

            aliceSignedPreKeyStore.StoreSignedPreKey(aliceSignedPreKey.getId(), aliceSignedPreKey);
            InMemorySessionStore aliceSessionStore = new InMemorySessionStore();

            // Generate Bobs keys:
            IdentityKeyPair      bobIdentKey     = CryptoUtils.generateOmemoIdentityKeyPair();
            IList <PreKeyRecord> bobPreKeys      = CryptoUtils.generateOmemoPreKeys();
            SignedPreKeyRecord   bobSignedPreKey = CryptoUtils.generateOmemoSignedPreKey(bobIdentKey);

            // Create Bobs stores:
            InMemoryIdentityKeyStore bobIdentStore  = new InMemoryIdentityKeyStore(bobIdentKey, BOB_ADDRESS.getDeviceId());
            InMemoryPreKeyStore      bobPreKeyStore = new InMemoryPreKeyStore();

            foreach (PreKeyRecord key in bobPreKeys)
            {
                bobPreKeyStore.StorePreKey(key.getId(), key);
            }
            InMemorySignedPreKeyStore bobSignedPreKeyStore = new InMemorySignedPreKeyStore();

            bobSignedPreKeyStore.StoreSignedPreKey(bobSignedPreKey.getId(), bobSignedPreKey);
            InMemorySessionStore bobSessionStore = new InMemorySessionStore();

            // Alice builds a session to Bob:
            SessionBuilder sessionBuilder = new SessionBuilder(aliceSessionStore, alicePreKeyStore, aliceSignedPreKeyStore, aliceIdentStore, BOB_ADDRESS);
            PreKeyBundle   bobPreKey      = new PreKeyBundle(BOB_ADDRESS.getDeviceId(), BOB_ADDRESS.getDeviceId(), bobPreKeys[0].getId(), bobPreKeys[0].getKeyPair().getPublicKey(), bobSignedPreKey.getId(), bobSignedPreKey.getKeyPair().getPublicKey(), bobSignedPreKey.getSignature(), bobIdentKey.getPublicKey());

            sessionBuilder.process(bobPreKey);

            // Check if session exists:
            Assert.IsTrue(aliceSessionStore.ContainsSession(BOB_ADDRESS));
            Assert.IsTrue(aliceSessionStore.LoadSession(BOB_ADDRESS).getSessionState().getSessionVersion() == 3);

            // Alice sends a message:
            string            aliceOrigMsg       = "$(rm -rvf .)";
            SessionCipher     aliceSessionCipher = new SessionCipher(aliceSessionStore, alicePreKeyStore, aliceSignedPreKeyStore, aliceIdentStore, BOB_ADDRESS);
            CiphertextMessage aliceOutMsg        = aliceSessionCipher.encrypt(Encoding.UTF8.GetBytes(aliceOrigMsg));

            // Check if successfully encrypted:
            Assert.IsTrue(aliceOutMsg.getType() == CiphertextMessage.PREKEY_TYPE);

            // Bob receives the message:
            PreKeySignalMessage bobInMsg         = new PreKeySignalMessage(aliceOutMsg.serialize());
            SessionCipher       bobSessionCipher = new SessionCipher(bobSessionStore, bobPreKeyStore, bobSignedPreKeyStore, bobIdentStore, ALICE_ADDRESS);

            byte[] bobData   = bobSessionCipher.decrypt(bobInMsg);
            string bobRecMsg = Encoding.UTF8.GetString(bobData);

            // Check if successfully send:
            Assert.AreEqual(aliceOrigMsg, bobRecMsg);
            Assert.IsTrue(bobSessionStore.ContainsSession(ALICE_ADDRESS));

            //---------------------------Connection/App get restarted:---------------------------

            // Bob answers:
            string bobOrigMsg = ":(){ :|:& };:";

            // Simulate a chat break:
            bobSessionCipher = new SessionCipher(bobSessionStore, bobPreKeyStore, bobSignedPreKeyStore, bobIdentStore, ALICE_ADDRESS);
            CiphertextMessage bobOutMsg = bobSessionCipher.encrypt(Encoding.UTF8.GetBytes(bobOrigMsg));

            // Alice receives the message:
            aliceSessionCipher = new SessionCipher(aliceSessionStore, alicePreKeyStore, aliceSignedPreKeyStore, aliceIdentStore, BOB_ADDRESS);
            SignalMessage aliceInMsg = new SignalMessage(bobOutMsg.serialize());

            byte[] aliceData   = aliceSessionCipher.decrypt(aliceInMsg);
            string aliceRecMsg = Encoding.UTF8.GetString(aliceData);

            // Check if successfully send:
            Assert.AreEqual(bobOrigMsg, aliceRecMsg);
            Assert.IsTrue(bobSessionStore.ContainsSession(ALICE_ADDRESS));
        }
コード例 #17
0
		public void setPendingKeyExchange(uint sequence,
										  ECKeyPair ourBaseKey,
										  ECKeyPair ourRatchetKey,
										  IdentityKeyPair ourIdentityKey)
		{
			PendingKeyExchange structure =
				PendingKeyExchange.CreateBuilder()
								  .SetSequence(sequence)
								  .SetLocalBaseKey(ByteString.CopyFrom(ourBaseKey.getPublicKey().serialize()))
								  .SetLocalBaseKeyPrivate(ByteString.CopyFrom(ourBaseKey.getPrivateKey().serialize()))
								  .SetLocalRatchetKey(ByteString.CopyFrom(ourRatchetKey.getPublicKey().serialize()))
								  .SetLocalRatchetKeyPrivate(ByteString.CopyFrom(ourRatchetKey.getPrivateKey().serialize()))
								  .SetLocalIdentityKey(ByteString.CopyFrom(ourIdentityKey.getPublicKey().serialize()))
								  .SetLocalIdentityKeyPrivate(ByteString.CopyFrom(ourIdentityKey.getPrivateKey().serialize()))
								  .Build();

			this.sessionStructure = this.sessionStructure.ToBuilder()
														 .SetPendingKeyExchange(structure)
														 .Build();
		}
コード例 #18
0
        public async Task BeginLinking()
        {
            try
            {
                CancelSource = new CancellationTokenSource();
                string deviceName = DeviceName;
                LinkingTask = Task.Run(() =>
                {
                    /* clean the database from stale values */
                    LibsignalDBContext.PurgeAccountData();

                    /* prepare qrcode */
                    string password             = Base64.encodeBytes(Util.getSecretBytes(18));
                    IdentityKeyPair tmpIdentity = KeyHelper.generateIdentityKeyPair();
                    SignalServiceAccountManager accountManager = new SignalServiceAccountManager(App.ServiceUrls, CancelSource.Token, "Signal-Windows");
                    string uuid     = accountManager.GetNewDeviceUuid(CancelSource.Token);
                    string tsdevice = "tsdevice:/?uuid=" + Uri.EscapeDataString(uuid) + "&pub_key=" + Uri.EscapeDataString(Base64.encodeBytesWithoutPadding(tmpIdentity.getPublicKey().serialize()));
                    Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
                    {
                        View.SetQR(tsdevice);
                        QRVisible    = Visibility.Visible;
                        QRCodeString = tsdevice;
                    }).AsTask().Wait();

                    string tmpSignalingKey = Base64.encodeBytes(Util.getSecretBytes(52));
                    int registrationId     = (int)KeyHelper.generateRegistrationId(false);

                    NewDeviceLinkResult result = accountManager.FinishNewDeviceRegistration(tmpIdentity, tmpSignalingKey, password, false, true, registrationId, deviceName);
                    SignalStore store          = new SignalStore()
                    {
                        DeviceId           = (uint)result.DeviceId,
                        IdentityKeyPair    = Base64.encodeBytes(result.Identity.serialize()),
                        NextSignedPreKeyId = 1,
                        Password           = password,
                        PreKeyIdOffset     = 1,
                        Registered         = true,
                        RegistrationId     = (uint)registrationId,
                        SignalingKey       = tmpSignalingKey,
                        Username           = result.Number
                    };
                    LibsignalDBContext.SaveOrUpdateSignalStore(store);

                    /* reload registered state */
                    Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
                    {
                        UIEnabled = false;
                        App.Store = store;
                    }).AsTask().Wait();

                    /* create prekeys */
                    LibsignalDBContext.RefreshPreKeys(new SignalServiceAccountManager(App.ServiceUrls, store.Username, store.Password, (int)store.DeviceId, App.USER_AGENT));

                    /* reload again with prekeys and their offsets */
                    store = LibsignalDBContext.GetSignalStore();
                    Debug.WriteLine("success!");
                    Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
                    {
                        App.Store = store;
                        View.Finish(true);
                    }).AsTask().Wait();
                });
                await LinkingTask;
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.Message);
                Debug.WriteLine(e.StackTrace);
            }
        }
コード例 #19
0
ファイル: Test_Omemo.cs プロジェクト: Chryssie/UWPX-Client
        public void Test_OmemoBundleInformation_2()
        {
            IdentityKeyPair      aliceIdentKey     = CryptoUtils.generateOmemoIdentityKeyPair();
            IList <PreKeyRecord> alicePreKeys      = CryptoUtils.generateOmemoPreKeys();
            SignedPreKeyRecord   aliceSignedPreKey = CryptoUtils.generateOmemoSignedPreKey(aliceIdentKey);
            string bundleInfo = getBundleInfoMsg(aliceIdentKey, aliceSignedPreKey, alicePreKeys);

            MessageParser2         parser   = new MessageParser2();
            List <AbstractMessage> messages = parser.parseMessages(ref bundleInfo);

            // Check if message parsed successfully:
            Assert.IsTrue(messages.Count == 1);
            Assert.IsInstanceOfType(messages[0], typeof(OmemoBundleInformationResultMessage));

            OmemoBundleInformationResultMessage bundleInfoMsg = messages[0] as OmemoBundleInformationResultMessage;

            // Check if keys match:
            Assert.IsTrue(bundleInfoMsg.BUNDLE_INFO.PUBLIC_IDENTITY_KEY.serialize().SequenceEqual(aliceIdentKey.getPublicKey().serialize()));
            Assert.IsTrue(bundleInfoMsg.BUNDLE_INFO.PUBLIC_SIGNED_PRE_KEY.serialize().SequenceEqual(aliceSignedPreKey.getKeyPair().getPublicKey().serialize()));
            Assert.IsTrue(bundleInfoMsg.BUNDLE_INFO.SIGNED_PRE_KEY_ID == aliceSignedPreKey.getId());
            Assert.IsTrue(bundleInfoMsg.BUNDLE_INFO.SIGNED_PRE_KEY_SIGNATURE.SequenceEqual(aliceSignedPreKey.getSignature()));

            Assert.IsTrue(bundleInfoMsg.BUNDLE_INFO.PUBLIC_PRE_KEYS.Count == alicePreKeys.Count);
            foreach (PreKeyRecord key in alicePreKeys)
            {
                IEnumerable <Tuple <uint, ECPublicKey> > matches = bundleInfoMsg.BUNDLE_INFO.PUBLIC_PRE_KEYS.Where(x => x.Item1 == key.getId());
                Assert.IsTrue(matches.Count() == 1);
                byte[] a = matches.First().Item2.serialize();
                byte[] b = key.getKeyPair().getPublicKey().serialize();
                Assert.IsTrue(a.SequenceEqual(b));
            }
        }
コード例 #20
0
ファイル: Test_Omemo.cs プロジェクト: Chryssie/UWPX-Client
        public void Test_OmemoBundleInformation_1()
        {
            IdentityKeyPair      aliceIdentKey     = CryptoUtils.generateOmemoIdentityKeyPair();
            IList <PreKeyRecord> alicePreKeys      = KeyHelper.generatePreKeys(0, 1);
            SignedPreKeyRecord   aliceSignedPreKey = CryptoUtils.generateOmemoSignedPreKey(aliceIdentKey);
            string bundleInfo = getBundleInfoMsg(aliceIdentKey, aliceSignedPreKey, alicePreKeys);

            MessageParser2         parser   = new MessageParser2();
            List <AbstractMessage> messages = parser.parseMessages(ref bundleInfo);

            // Check if message parsed successfully:
            Assert.IsTrue(messages.Count == 1);
            Assert.IsInstanceOfType(messages[0], typeof(OmemoBundleInformationResultMessage));

            OmemoBundleInformationResultMessage bundleInfoMsg = messages[0] as OmemoBundleInformationResultMessage;

            // Check if keys match:
            Assert.IsTrue(bundleInfoMsg.BUNDLE_INFO.PUBLIC_IDENTITY_KEY.serialize().SequenceEqual(aliceIdentKey.getPublicKey().serialize()));
            Assert.IsTrue(bundleInfoMsg.BUNDLE_INFO.PUBLIC_SIGNED_PRE_KEY.serialize().SequenceEqual(aliceSignedPreKey.getKeyPair().getPublicKey().serialize()));
            Assert.IsTrue(bundleInfoMsg.BUNDLE_INFO.SIGNED_PRE_KEY_ID == aliceSignedPreKey.getId());
            Assert.IsTrue(bundleInfoMsg.BUNDLE_INFO.SIGNED_PRE_KEY_SIGNATURE.SequenceEqual(aliceSignedPreKey.getSignature()));
            Assert.IsTrue(bundleInfoMsg.BUNDLE_INFO.PUBLIC_PRE_KEYS.Count == 1);
            Assert.IsTrue(bundleInfoMsg.BUNDLE_INFO.PUBLIC_PRE_KEYS[0].Item2.serialize().SequenceEqual(alicePreKeys[0].getKeyPair().getPublicKey().serialize()));
        }
コード例 #21
0
        public byte[] Encrypt(SignalProtocolAddress destinationAddress, SenderCertificate senderCertificate, byte[] paddedPlaintext)
        {
            CiphertextMessage message       = new SessionCipher(SignalProtocolStore, destinationAddress).encrypt(paddedPlaintext);
            IdentityKeyPair   ourIdentity   = SignalProtocolStore.GetIdentityKeyPair();
            ECPublicKey       theirIdentity = SignalProtocolStore.GetIdentity(destinationAddress).getPublicKey();

            ECKeyPair ephemeral = Curve.generateKeyPair();

            byte[]        ephemeralSalt = ByteUtil.combine(Encoding.ASCII.GetBytes("UnidentifiedDelivery"), theirIdentity.serialize(), ephemeral.getPublicKey().serialize());
            EphemeralKeys ephemeralKeys = CalculateEphemeralKeys(theirIdentity, ephemeral.getPrivateKey(), ephemeralSalt);

            byte[] staticKeyCiphertext = Encrypt(ephemeralKeys.CipherKey, ephemeralKeys.MacKey, ourIdentity.getPublicKey().getPublicKey().serialize());

            byte[]     staticSalt = ByteUtil.combine(ephemeralKeys.ChainKey, staticKeyCiphertext);
            StaticKeys staticKeys = CalculateStaticKeys(theirIdentity, ourIdentity.getPrivateKey(), staticSalt);
            UnidentifiedSenderMessageContent content = new UnidentifiedSenderMessageContent((int)message.getType(), senderCertificate, message.serialize());

            byte[] messageBytes = Encrypt(staticKeys.CipherKey, staticKeys.MacKey, content.Serialized);

            return(new UnidentifiedSenderMessage(ephemeral.getPublicKey(), staticKeyCiphertext, messageBytes).Serialized);
        }
コード例 #22
0
        public (SignalProtocolAddress, byte[]) Decrypt(CertificateValidator validator, byte[] ciphertext, long timestamp)
        {
            UnidentifiedSenderMessageContent content;

            try
            {
                IdentityKeyPair           ourIdentity = SignalProtocolStore.GetIdentityKeyPair();
                UnidentifiedSenderMessage wrapper     = new UnidentifiedSenderMessage(ciphertext);
                byte[]        ephemeralSalt           = ByteUtil.combine(Encoding.ASCII.GetBytes("UnidentifiedDelivery"), ourIdentity.getPublicKey().getPublicKey().serialize(), wrapper.Ephemeral.serialize());
                EphemeralKeys ephemeralKeys           = CalculateEphemeralKeys(wrapper.Ephemeral, ourIdentity.getPrivateKey(), ephemeralSalt);
                byte[]        staticKeyBytes          = Decrypt(ephemeralKeys.CipherKey, ephemeralKeys.MacKey, wrapper.EncryptedStatic);

                ECPublicKey staticKey    = Curve.decodePoint(staticKeyBytes, 0);
                byte[]      staticSalt   = ByteUtil.combine(ephemeralKeys.ChainKey, wrapper.EncryptedStatic);
                StaticKeys  staticKeys   = CalculateStaticKeys(staticKey, ourIdentity.getPrivateKey(), staticSalt);
                byte[]      messageBytes = Decrypt(staticKeys.CipherKey, staticKeys.MacKey, wrapper.EncryptedMessage);

                content = new UnidentifiedSenderMessageContent(messageBytes);
                validator.Validate(content.SenderCertificate, timestamp);

                if (!Enumerable.SequenceEqual(content.SenderCertificate.Key.serialize(), staticKeyBytes))
                {
                    throw new libsignal.InvalidKeyException("Sender's certificate key does not match key used in message");
                }

                if (content.SenderCertificate.Sender == LocalAddress.Name &&
                    content.SenderCertificate.SenderDeviceId == LocalAddress.DeviceId)
                {
                    throw new SelfSendException();
                }
            }
            catch (libsignal.InvalidKeyException e)
            {
                throw new InvalidMetadataMessageException(e);
            }
            catch (InvalidCertificateException e)
            {
                throw new InvalidMetadataMessageException(e);
            }
            catch (InvalidMacException e)
            {
                throw new InvalidMetadataMessageException(e);
            }

            try
            {
                return(new SignalProtocolAddress(content.SenderCertificate.Sender, (uint)content.SenderCertificate.SenderDeviceId),
                       Decrypt(content));
            }
            catch (InvalidMessageException e)
            {
                throw new ProtocolInvalidMessageException(e, content.SenderCertificate.Sender, content.SenderCertificate.SenderDeviceId);
            }
            catch (libsignal.InvalidKeyException e)
            {
                throw new ProtocolInvalidKeyException(e, content.SenderCertificate.Sender, content.SenderCertificate.SenderDeviceId);
            }
            catch (NoSessionException e)
            {
                throw new ProtocolNoSessionException(e, content.SenderCertificate.Sender, content.SenderCertificate.SenderDeviceId);
            }
            catch (LegacyMessageException e)
            {
                throw new ProtocolLegacyMessageException(e, content.SenderCertificate.Sender, content.SenderCertificate.SenderDeviceId);
            }
            catch (InvalidVersionException e)
            {
                throw new ProtocolInvalidVersionException(e, content.SenderCertificate.Sender, content.SenderCertificate.SenderDeviceId);
            }
            catch (DuplicateMessageException e)
            {
                throw new ProtocolDuplicateMessageException(e, content.SenderCertificate.Sender, content.SenderCertificate.SenderDeviceId);
            }
            catch (InvalidKeyIdException e)
            {
                throw new ProtocolInvalidKeyIdException(e, content.SenderCertificate.Sender, content.SenderCertificate.SenderDeviceId);
            }
            catch (UntrustedIdentityException e)
            {
                throw new ProtocolUntrustedIdentityException(e, content.SenderCertificate.Sender, content.SenderCertificate.SenderDeviceId);
            }
        }
コード例 #23
0
        private void RequestRegister(uint registrationId, IdentityKeyPair identityKeyPair, SignedPreKeyRecord signedPreKey, List <PreKeyRecord> preKeys)
        {
            //Send the login username and password to the server and get response
            string apiUrl    = "https://ycandgap.me/api_server2.php";
            string apiMethod = "registerUser";

            // Login_Request has two properties: username and password
            Login_Request myLogin_Request = new Login_Request();

            myLogin_Request.Username                    = username.Text;
            myLogin_Request.Password                    = password.Text.GetHashCode();
            myLogin_Request.RegistrationID              = registrationId;
            myLogin_Request.PublicIdentityKey           = JsonConvert.SerializeObject(identityKeyPair.getPublicKey().serialize());
            myLogin_Request.PublicSignedPreKeyID        = signedPreKey.getId();
            myLogin_Request.PublicSignedPreKeySignature = JsonConvert.SerializeObject(signedPreKey.getSignature());
            myLogin_Request.PublicSignedPreKey          = JsonConvert.SerializeObject(signedPreKey.getKeyPair().getPublicKey().serialize());

            // Save in local Database
            ISharedPreferences       sharedprefs = PreferenceManager.GetDefaultSharedPreferences(this);
            ISharedPreferencesEditor editor      = sharedprefs.Edit();

            // Store identityKeyPair somewhere durable and safe.
            editor.PutString("IdentityKeyPair", JsonConvert.SerializeObject(identityKeyPair.serialize()));
            editor.PutString("SignedPreKey", JsonConvert.SerializeObject(signedPreKey.serialize()));
            editor.PutString("Username", username.Text);
            editor.PutInt("Password", password.Text.GetHashCode());

            // Store registrationId somewhere durable and safe.
            editor.PutString("RegistrationId", registrationId.ToString());
            editor.Apply();

            // make http post request
            string response = Http.Post(apiUrl, new NameValueCollection()
            {
                { "api_method", apiMethod },
                { "api_data", JsonConvert.SerializeObject(myLogin_Request) }
            });

            // decode json string to dto object
            API_Response r = JsonConvert.DeserializeObject <API_Response>(response);

            if (r != null)
            {
                if (!r.IsError)
                {
                    foreach (PreKeyRecord preKey in preKeys)
                    {
                        Prekey_Request preKey_Request = new Prekey_Request();
                        preKey_Request.PublicSignedPreKeyID = signedPreKey.getId();
                        preKey_Request.PublicPreKeyID       = preKey.getId();
                        preKey_Request.PublicPreKey         = JsonConvert.SerializeObject(preKey.getKeyPair().getPublicKey().serialize());
                        apiMethod = "storePreKeys";

                        // make http post request
                        string preKeyResponse = Http.Post(apiUrl, new NameValueCollection()
                        {
                            { "api_method", apiMethod },
                            { "api_data", JsonConvert.SerializeObject(preKey_Request) }
                        });

                        // decode json string to dto object
                        API_Response preKeyR = JsonConvert.DeserializeObject <API_Response>(preKeyResponse);
                        if (preKeyR == null)
                        {
                            break;
                        }
                    }
                }
            }
        }
コード例 #24
0
        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[] bobSignedPreKeyPublic = { (byte)0x05, (byte)0xac, (byte)0x24, (byte)0x8a, (byte)0x8f,
                                             (byte)0x26, (byte)0x3b, (byte)0xe6, (byte)0x86, (byte)0x35,
                                             (byte)0x76, (byte)0xeb, (byte)0x03, (byte)0x62, (byte)0xe2,
                                             (byte)0x8c, (byte)0x82, (byte)0x8f, (byte)0x01, (byte)0x07,
                                             (byte)0xa3, (byte)0x37, (byte)0x9d, (byte)0x34, (byte)0xba,
                                             (byte)0xb1, (byte)0x58, (byte)0x6b, (byte)0xf8, (byte)0xc7,
                                             (byte)0x70, (byte)0xcd, (byte)0x67 };

            byte[] bobSignedPreKeyPrivate = { (byte)0x58, (byte)0x39, (byte)0x00, (byte)0x13, (byte)0x1f,
                                              (byte)0xb7, (byte)0x27, (byte)0x99, (byte)0x8b, (byte)0x78,
                                              (byte)0x03, (byte)0xfe, (byte)0x6a, (byte)0xc2, (byte)0x2c,
                                              (byte)0xc5, (byte)0x91, (byte)0xf3, (byte)0x42, (byte)0xe4,
                                              (byte)0xe4, (byte)0x2a, (byte)0x8c, (byte)0x8d, (byte)0x5d,
                                              (byte)0x78, (byte)0x19, (byte)0x42, (byte)0x09, (byte)0xb8,
                                              (byte)0xd2, (byte)0x53 };

            byte[] senderChain = { (byte)0x97, (byte)0x97, (byte)0xca, (byte)0xca, (byte)0x53,
                                   (byte)0xc9, (byte)0x89, (byte)0xbb, (byte)0xe2, (byte)0x29,
                                   (byte)0xa4, (byte)0x0c, (byte)0xa7, (byte)0x72, (byte)0x70,
                                   (byte)0x10, (byte)0xeb, (byte)0x26, (byte)0x04, (byte)0xfc,
                                   (byte)0x14, (byte)0x94, (byte)0x5d, (byte)0x77, (byte)0x95,
                                   (byte)0x8a, (byte)0x0a, (byte)0xed, (byte)0xa0, (byte)0x88,
                                   (byte)0xb4, (byte)0x4d };

            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(bobEphemeralPublicKey, bobEphemeralPrivateKey);
            ECKeyPair       bobBaseKey             = bobEphemeralKey;
            ECKeyPair       bobSignedPreKey        = new ECKeyPair(Curve.decodePoint(bobSignedPreKeyPublic, 0), Curve.decodePrivatePoint(bobSignedPreKeyPrivate));

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

            BobSignalProtocolParameters parameters = BobSignalProtocolParameters.newBuilder()
                                                     .setOurIdentityKey(bobIdentityKey)
                                                     .setOurSignedPreKey(bobSignedPreKey)
                                                     .setOurRatchetKey(bobEphemeralKey)
                                                     .setOurOneTimePreKey(May <ECKeyPair> .NoValue)
                                                     .setTheirIdentityKey(aliceIdentityPublicKey)
                                                     .setTheirBaseKey(aliceBasePublicKey)
                                                     .create();

            SessionState session = new SessionState();

            RatchetingSession.initializeSession(session, parameters);

            Assert.AreEqual <IdentityKey>(session.getLocalIdentityKey(), bobIdentityKey.getPublicKey());
            Assert.AreEqual <IdentityKey>(session.getRemoteIdentityKey(), aliceIdentityPublicKey);
            CollectionAssert.AreEqual(session.getSenderChainKey().getKey(), senderChain);
        }
コード例 #25
0
        public void testRatchetingSessionAsAlice()
        {
            byte[] bobPublic =
            {
                0x05, 0x2c, 0xb4, 0x97, 0x76,
                0xb8, 0x77, 0x02, 0x05, 0x74,
                0x5a, 0x3a, 0x6e, 0x24, 0xf5,
                0x79, 0xcd, 0xb4, 0xba, 0x7a,
                0x89, 0x04, 0x10, 0x05, 0x92,
                0x8e, 0xbb, 0xad, 0xc9, 0xc0,
                0x5a, 0xd4, 0x58
            };

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

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

            byte[] aliceBasePrivate =
            {
                0x11, 0xae, 0x7c, 0x64, 0xd1,
                0xe6, 0x1c, 0xd5, 0x96, 0xb7,
                0x6a, 0x0d, 0xb5, 0x01, 0x26,
                0x73, 0x39, 0x1c, 0xae, 0x66,
                0xed, 0xbf, 0xcf, 0x07, 0x3b,
                0x4d, 0xa8, 0x05, 0x16, 0xa4,
                0x74, 0x49
            };

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

            byte[] aliceEphemeralPrivate =
            {
                0xd1, 0xba, 0x38, 0xce, 0xa9,
                0x17, 0x43, 0xd3, 0x39, 0x39,
                0xc3, 0x3c, 0x84, 0x98, 0x65,
                0x09, 0x28, 0x01, 0x61, 0xb8,
                0xb6, 0x0f, 0xc7, 0x87, 0x0c,
                0x59, 0x9c, 0x1d, 0x46, 0x20,
                0x12, 0x48
            };

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

            byte[] aliceIdentityPrivate =
            {
                0x90, 0x40, 0xf0, 0xd4, 0xe0,
                0x9c, 0xf3, 0x8f, 0x6d, 0xc7,
                0xc1, 0x37, 0x79, 0xc9, 0x08,
                0xc0, 0x15, 0xa1, 0xda, 0x4f,
                0xa7, 0x87, 0x37, 0xa0, 0x80,
                0xeb, 0x0a, 0x6f, 0x4f, 0x5f,
                0x8f, 0x58
            };

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

            IdentityKey     bobIdentityKey           = new IdentityKey(bobIdentityPublic, 0);
            ECPublicKey     bobEphemeralPublicKey    = Curve.decodePoint(bobPublic, 0);
            ECPublicKey     bobBasePublicKey         = bobEphemeralPublicKey;
            ECPublicKey     aliceBasePublicKey       = Curve.decodePoint(aliceBasePublic, 0);
            ECPrivateKey    aliceBasePrivateKey      = Curve.decodePrivatePoint(aliceBasePrivate);
            ECKeyPair       aliceBaseKey             = new ECKeyPair(aliceBasePublicKey, aliceBasePrivateKey);
            ECPublicKey     aliceEphemeralPublicKey  = Curve.decodePoint(aliceEphemeralPublic, 0);
            ECPrivateKey    aliceEphemeralPrivateKey = Curve.decodePrivatePoint(aliceEphemeralPrivate);
            ECKeyPair       aliceEphemeralKey        = new ECKeyPair(aliceEphemeralPublicKey, aliceEphemeralPrivateKey);
            IdentityKey     aliceIdentityPublicKey   = new IdentityKey(aliceIdentityPublic, 0);
            ECPrivateKey    aliceIdentityPrivateKey  = Curve.decodePrivatePoint(aliceIdentityPrivate);
            IdentityKeyPair aliceIdentityKey         = new IdentityKeyPair(aliceIdentityPublicKey, aliceIdentityPrivateKey);

            SessionState session = new SessionState();

            AliceAxolotlParameters parameters = AliceAxolotlParameters.newBuilder()
                                                .setOurBaseKey(aliceBaseKey)
                                                .setOurIdentityKey(aliceIdentityKey)
                                                .setTheirIdentityKey(bobIdentityKey)
                                                .setTheirSignedPreKey(bobBasePublicKey)
                                                .setTheirRatchetKey(bobEphemeralPublicKey)
                                                .setTheirOneTimePreKey(May <ECPublicKey> .NoValue)
                                                .create();

            RatchetingSession.initializeSession(session, 2, parameters);

            Assert.AreEqual(session.getLocalIdentityKey(), aliceIdentityKey.getPublicKey());
            Assert.AreEqual(session.getRemoteIdentityKey(), bobIdentityKey);
            CollectionAssert.AreEqual(session.getReceiverChainKey(bobEphemeralPublicKey).getKey(), receiverChain);
        }
        private void InitializeSessions(TestInMemorySignalProtocolStore aliceStore, TestInMemorySignalProtocolStore bobStore)
        {
            ECKeyPair          bobPreKey       = Curve.generateKeyPair();
            IdentityKeyPair    bobIdentityKey  = bobStore.GetIdentityKeyPair();
            SignedPreKeyRecord bobSignedPreKey = KeyHelper.generateSignedPreKey(bobIdentityKey, 2);

            PreKeyBundle   bobBundle           = new PreKeyBundle(1, 1, 1, bobPreKey.getPublicKey(), 2, bobSignedPreKey.getKeyPair().getPublicKey(), bobSignedPreKey.getSignature(), bobIdentityKey.getPublicKey());
            SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, new SignalProtocolAddress("+14152222222", 1));

            aliceSessionBuilder.process(bobBundle);

            bobStore.StoreSignedPreKey(2, bobSignedPreKey);
            bobStore.StorePreKey(1, new PreKeyRecord(1, bobPreKey));
        }