Пример #1
0
		private ChainKey getOrCreateChainKey(SessionState sessionState, ECPublicKey theirEphemeral)

		{
			try
			{
				if (sessionState.hasReceiverChain(theirEphemeral))
				{
					return sessionState.getReceiverChainKey(theirEphemeral);
				}
				else
				{
					RootKey rootKey = sessionState.getRootKey();
					ECKeyPair ourEphemeral = sessionState.getSenderRatchetKeyPair();
					Pair<RootKey, ChainKey> receiverChain = rootKey.createChain(theirEphemeral, ourEphemeral);
					ECKeyPair ourNewEphemeral = Curve.generateKeyPair();
					Pair<RootKey, ChainKey> senderChain = receiverChain.first().createChain(theirEphemeral, ourNewEphemeral);

					sessionState.setRootKey(senderChain.first());
					sessionState.addReceiverChain(theirEphemeral, receiverChain.second());
					sessionState.setPreviousCounter(Math.Max(sessionState.getSenderChainKey().getIndex() - 1, 0));
					sessionState.setSenderChain(ourNewEphemeral, senderChain.second());

					return receiverChain.second();
				}
			}
			catch (InvalidKeyException e)
			{
				throw new InvalidMessageException(e);
			}
		}
Пример #2
0
        public static void initializeSession(SessionState sessionState,
                                             uint sessionVersion,
                                             AliceAxolotlParameters parameters)
        {
            try
            {
                sessionState.setSessionVersion(sessionVersion);
                sessionState.setRemoteIdentityKey(parameters.getTheirIdentityKey());
                sessionState.setLocalIdentityKey(parameters.getOurIdentityKey().getPublicKey());

                ECKeyPair sendingRatchetKey = Curve.generateKeyPair();
                MemoryStream secrets = new MemoryStream();

                if (sessionVersion >= 3)
                {
                    byte[] discontinuityBytes = getDiscontinuityBytes();
                    secrets.Write(discontinuityBytes, 0, discontinuityBytes.Length);
                }

                byte[] agree1 = Curve.calculateAgreement(parameters.getTheirSignedPreKey(),
                                                       parameters.getOurIdentityKey().getPrivateKey());
                byte[] agree2 = Curve.calculateAgreement(parameters.getTheirIdentityKey().getPublicKey(),
                                                        parameters.getOurBaseKey().getPrivateKey());
                byte[] agree3 = Curve.calculateAgreement(parameters.getTheirSignedPreKey(),
                                                       parameters.getOurBaseKey().getPrivateKey());

                secrets.Write(agree1, 0, agree1.Length);
                secrets.Write(agree2, 0, agree2.Length);
                secrets.Write(agree3, 0, agree3.Length);

                if (sessionVersion >= 3 && parameters.getTheirOneTimePreKey().HasValue)
                {
                    byte[] agree4 = Curve.calculateAgreement(parameters.getTheirOneTimePreKey().ForceGetValue(),
                                                           parameters.getOurBaseKey().getPrivateKey());
                    secrets.Write(agree4, 0, agree4.Length);
                }

                DerivedKeys derivedKeys = calculateDerivedKeys(sessionVersion, secrets.ToArray());
                Pair<RootKey, ChainKey> sendingChain = derivedKeys.getRootKey().createChain(parameters.getTheirRatchetKey(), sendingRatchetKey);

                sessionState.addReceiverChain(parameters.getTheirRatchetKey(), derivedKeys.getChainKey());
                sessionState.setSenderChain(sendingRatchetKey, sendingChain.second());
                sessionState.setRootKey(sendingChain.first());
            }
            catch (IOException e)
            {
                throw new Exception(e.Message);
            }
        }