Example #1
0
        /**
         * Initiate a new session by sending an initial KeyExchangeMessage to the recipient.
         *
         * @return the KeyExchangeMessage to deliver.
         */

        public KeyExchangeMessage Process()
        {
            lock (SessionCipher.SESSION_LOCK)
            {
                try
                {
                    uint            sequence         = KeyHelper.GetRandomSequence(65534) + 1;
                    uint            flags            = KeyExchangeMessage.INITIATE_FLAG;
                    ECKeyPair       baseKey          = Curve.GenerateKeyPair();
                    ECKeyPair       ratchetKey       = Curve.GenerateKeyPair();
                    IdentityKeyPair identityKey      = identityKeyStore.GetIdentityKeyPair();
                    byte[]          baseKeySignature = Curve.CalculateSignature(identityKey.GetPrivateKey(), baseKey.GetPublicKey().Serialize());
                    SessionRecord   sessionRecord    = sessionStore.LoadSession(remoteAddress);

                    sessionRecord.GetSessionState().SetPendingKeyExchange(sequence, baseKey, ratchetKey, identityKey);
                    sessionStore.StoreSession(remoteAddress, sessionRecord);

                    return(new KeyExchangeMessage(2, sequence, flags, baseKey.GetPublicKey(), baseKeySignature, ratchetKey.GetPublicKey(), identityKey.GetPublicKey()));
                }
                catch (InvalidKeyException e)
                {
                    throw new Exception(e.Message);
                }
            }
        }
Example #2
0
        /**
         * Generate an identity key pair.  Clients should only do this once,
         * at install time.
         *
         * @return the generated IdentityKeyPair.
         */

        public static IdentityKeyPair GenerateIdentityKeyPair()
        {
            ECKeyPair   keyPair   = Curve.GenerateKeyPair();
            IdentityKey publicKey = new IdentityKey(keyPair.GetPublicKey());

            return(new IdentityKeyPair(publicKey, keyPair.GetPrivateKey()));
        }
Example #3
0
        /**
         * Build a new session from a {@link org.whispersystems.libaxolotl.state.PreKeyBundle} retrieved from
         * a server.
         *
         * @param preKey A PreKey for the destination recipient, retrieved from a server.
         * @throws InvalidKeyException when the {@link org.whispersystems.libaxolotl.state.PreKeyBundle} is
         *                             badly formatted.
         * @throws org.whispersystems.libaxolotl.UntrustedIdentityException when the sender's
         *                                                                  {@link IdentityKey} is not
         *                                                                  trusted.
         */

        public void Process(PreKeyBundle preKey)
        {
            lock (SessionCipher.SESSION_LOCK)
            {
                if (!identityKeyStore.IsTrustedIdentity(remoteAddress.GetName(), preKey.GetIdentityKey()))
                {
                    throw new UntrustedIdentityException(remoteAddress.GetName(), preKey.GetIdentityKey());
                }

                if (preKey.GetSignedPreKey() != null &&
                    !Curve.VerifySignature(preKey.GetIdentityKey().GetPublicKey(),
                                           preKey.GetSignedPreKey().Serialize(),
                                           preKey.GetSignedPreKeySignature()))
                {
                    throw new InvalidKeyException("Invalid Signature on Device Key!");
                }

                if (preKey.GetSignedPreKey() == null && preKey.GetPreKey() == null)
                {
                    throw new InvalidKeyException("Both Signed and Unsigned Prekeys are Absent!");
                }

                bool              supportsV3        = preKey.GetSignedPreKey() != null;
                SessionRecord     sessionRecord     = sessionStore.LoadSession(remoteAddress);
                ECKeyPair         ourBaseKey        = Curve.GenerateKeyPair();
                ECPublicKey       theirSignedPreKey = supportsV3 ? preKey.GetSignedPreKey() : preKey.GetPreKey();
                ECPublicKey       test = preKey.GetPreKey(); // TODO: Cleanup
                May <ECPublicKey> theirOneTimePreKey   = (test == null) ? May <ECPublicKey> .NoValue : new May <ECPublicKey>(test);
                May <uint>        theirOneTimePreKeyId = theirOneTimePreKey.HasValue ? new May <uint>(preKey.GetPreKeyId()) : May <uint> .NoValue;

                AliceAxolotlParameters.Builder parameters = AliceAxolotlParameters.NewBuilder();

                parameters.SetOurBaseKey(ourBaseKey)
                .SetOurIdentityKey(identityKeyStore.GetIdentityKeyPair())
                .SetTheirIdentityKey(preKey.GetIdentityKey())
                .SetTheirSignedPreKey(theirSignedPreKey)
                .SetTheirRatchetKey(theirSignedPreKey)
                .SetTheirOneTimePreKey(supportsV3 ? theirOneTimePreKey : May <ECPublicKey> .NoValue);

                if (!sessionRecord.IsFresh())
                {
                    sessionRecord.ArchiveCurrentState();
                }

                RatchetingSession.InitializeSession(sessionRecord.GetSessionState(),
                                                    supportsV3 ? (uint)3 : 2,
                                                    parameters.Create());

                sessionRecord.GetSessionState().SetUnacknowledgedPreKeyMessage(theirOneTimePreKeyId, preKey.GetSignedPreKeyId(), ourBaseKey.GetPublicKey());
                sessionRecord.GetSessionState().SetLocalRegistrationId(identityKeyStore.GetLocalRegistrationId());
                sessionRecord.GetSessionState().SetRemoteRegistrationId(preKey.GetRegistrationId());
                sessionRecord.GetSessionState().SetAliceBaseKey(ourBaseKey.GetPublicKey().Serialize());

                sessionStore.StoreSession(remoteAddress, sessionRecord);
                identityKeyStore.SaveIdentity(remoteAddress.GetName(), preKey.GetIdentityKey());
            }
        }
 public SignedPreKeyRecord(uint id, ulong timestamp, ECKeyPair keyPair, byte[] signature)
 {
     this.structure = SignedPreKeyRecordStructure.CreateBuilder()
                      .SetId(id)
                      .SetPublicKey(ByteString.CopyFrom(keyPair.GetPublicKey().Serialize()))
                      .SetPrivateKey(ByteString.CopyFrom(keyPair.GetPrivateKey().Serialize()))
                      .SetSignature(ByteString.CopyFrom(signature))
                      .SetTimestamp(timestamp)
                      .Build();
 }
Example #5
0
 public PreKeyRecord(uint id, ECKeyPair keyPair)
 {
     this.structure = PreKeyRecordStructure.CreateBuilder()
                      .SetId(id)
                      .SetPublicKey(ByteString.CopyFrom(keyPair.GetPublicKey()
                                                        .Serialize()))
                      .SetPrivateKey(ByteString.CopyFrom(keyPair.GetPrivateKey()
                                                         .Serialize()))
                      .Build();
 }
Example #6
0
        public void SetSenderChain(ECKeyPair senderRatchetKeyPair, ChainKey chainKey)
        {
            Chain.Types.ChainKey chainKeyStructure = Chain.Types.ChainKey.CreateBuilder()
                                                     .SetKey(ByteString.CopyFrom(chainKey.GetKey()))
                                                     .SetIndex(chainKey.GetIndex())
                                                     .Build();

            Chain senderChain = Chain.CreateBuilder()
                                .SetSenderRatchetKey(ByteString.CopyFrom(senderRatchetKeyPair.GetPublicKey().Serialize()))
                                .SetSenderRatchetKeyPrivate(ByteString.CopyFrom(senderRatchetKeyPair.GetPrivateKey().Serialize()))
                                .SetChainKey(chainKeyStructure)
                                .Build();

            this.sessionStructure = this.sessionStructure.ToBuilder().SetSenderChain(senderChain).Build();
        }
Example #7
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();
        }
Example #8
0
        public static SignatureData SignMessage(byte[] message, ECKeyPair keys, bool needToHash)
        {
            BigInteger publicKey   = keys.GetPublicKey();
            var        messageHash = needToHash ? Hash.HashBlake2B(message) : message;
            var        recId       = -1;

            ECDSASignature sig = keys.Sign(messageHash);

            for (int i = 0; i < 4; i++)
            {
                BigInteger k = RecoverFromSignature(i, sig, messageHash);

                if (k != null && k.Equals(publicKey))
                {
                    recId = i;
                    break;
                }
            }

            if (recId == -1)
            {
                throw new FormatException("Sign the data failed.");
            }
            if (recId == 2 || recId == 3)
            {
                throw new InvalidOperationException("Recovery is not valid for VeChain MainNet.");
            }

            byte v = (byte)recId;

            sig.R.ToByteArray();
            byte[] r = BigIntToBytesWithPadding(sig.R, 32);
            byte[] s = BigIntToBytesWithPadding(sig.S, 32);

            return(new SignatureData(v, r, s));
        }
 public SenderKeyState(uint id, uint iteration, byte[] chainKey, ECKeyPair signatureKey)
     : this(id, iteration, chainKey, signatureKey.GetPublicKey(), new May <ECPrivateKey>(signatureKey.GetPrivateKey()))
 {
 }
Example #10
0
        /**
         * Generate a signed PreKey
         *
         * @param identityKeyPair The local client's identity key pair.
         * @param signedPreKeyId The PreKey id to assign the generated signed PreKey
         *
         * @return the generated signed PreKey
         * @throws InvalidKeyException when the provided identity key is invalid
         */

        public static SignedPreKeyRecord GenerateSignedPreKey(IdentityKeyPair identityKeyPair, uint signedPreKeyId)
        {
            ECKeyPair keyPair = Curve.GenerateKeyPair();

            byte[] signature = Curve.CalculateSignature(identityKeyPair.GetPrivateKey(), keyPair.GetPublicKey().Serialize());

            return(new SignedPreKeyRecord(signedPreKeyId, GetTime(), keyPair, signature));
        }