/// <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); }
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)); }
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); }
/// <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); }
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; } }
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(""); }
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); }
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); }
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); }
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; }
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); }
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); }
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(); }
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()); }
/// <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); }
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)); }
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); } }
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)); } }
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())); }
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); }
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); } }
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; } } } } }
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); }
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)); }