Example #1
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);
        }
Example #2
0
        public void TestSignature()
        {
            ECKeyPair serverKey = Curve.generateKeyPair();
            ECKeyPair key       = Curve.generateKeyPair();


            byte[] certificateBytes = new libsignalmetadata.protobuf.SenderCertificate.Types.Certificate()
            {
                Sender       = "+14152222222",
                SenderDevice = 1,
                Expires      = 31337,
                IdentityKey  = ByteString.CopyFrom(key.getPublicKey().serialize()),
                Signer       = GetServerCertificate(serverKey)
            }.ToByteArray();

            byte[] certificateSignature = Curve.calculateSignature(serverKey.getPrivateKey(), certificateBytes);

            SenderCertificate senderCertificate = new SenderCertificate(new libsignalmetadata.protobuf.SenderCertificate()
            {
                Certificate = ByteString.CopyFrom(certificateBytes),
                Signature   = ByteString.CopyFrom(certificateSignature)
            }.ToByteArray());

            new CertificateValidator(TrustRoot.getPublicKey()).Validate(senderCertificate, 31336);
        }
Example #3
0
        public void testBadMessageBundle()
        {
            SignalProtocolStore aliceStore          = new TestInMemorySignalProtocolStore();
            SessionBuilder      aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_ADDRESS);

            SignalProtocolStore bobStore = new TestInMemorySignalProtocolStore();

            ECKeyPair bobPreKeyPair       = Curve.generateKeyPair();
            ECKeyPair bobSignedPreKeyPair = Curve.generateKeyPair();

            byte[] bobSignedPreKeySignature = Curve.calculateSignature(bobStore.GetIdentityKeyPair().getPrivateKey(),
                                                                       bobSignedPreKeyPair.getPublicKey().serialize());

            PreKeyBundle bobPreKey = new PreKeyBundle(bobStore.GetLocalRegistrationId(), 1,
                                                      31337, bobPreKeyPair.getPublicKey(),
                                                      22, bobSignedPreKeyPair.getPublicKey(), bobSignedPreKeySignature,
                                                      bobStore.GetIdentityKeyPair().getPublicKey());

            bobStore.StorePreKey(31337, new PreKeyRecord(bobPreKey.getPreKeyId(), bobPreKeyPair));
            bobStore.StoreSignedPreKey(22, new SignedPreKeyRecord(22, DateUtil.currentTimeMillis(), bobSignedPreKeyPair, bobSignedPreKeySignature));

            aliceSessionBuilder.process(bobPreKey);

            String            originalMessage    = "L'homme est condamné à être libre";
            SessionCipher     aliceSessionCipher = new SessionCipher(aliceStore, BOB_ADDRESS);
            CiphertextMessage outgoingMessageOne = aliceSessionCipher.encrypt(Encoding.UTF8.GetBytes(originalMessage));

            Assert.AreEqual(CiphertextMessage.PREKEY_TYPE, outgoingMessageOne.getType());

            byte[] goodMessage = outgoingMessageOne.serialize();
            byte[] badMessage  = new byte[goodMessage.Length];
            Array.Copy(goodMessage, 0, badMessage, 0, badMessage.Length);

            badMessage[badMessage.Length - 10] ^= 0x01;

            PreKeySignalMessage incomingMessage  = new PreKeySignalMessage(badMessage);
            SessionCipher       bobSessionCipher = new SessionCipher(bobStore, ALICE_ADDRESS);

            byte[] plaintext = new byte[0];

            try
            {
                plaintext = bobSessionCipher.decrypt(incomingMessage);
                throw new Exception("Decrypt should have failed!");
            }
            catch (InvalidMessageException)
            {
                // good.
            }

            Assert.IsTrue(bobStore.ContainsPreKey(31337));

            plaintext = bobSessionCipher.decrypt(new PreKeySignalMessage(goodMessage));

            Assert.AreEqual(originalMessage, Encoding.UTF8.GetString(plaintext));
            Assert.IsFalse(bobStore.ContainsPreKey(31337));
        }
Example #4
0
        public void testRepeatBundleMessageV3()
        {
            SignalProtocolStore aliceStore          = new TestInMemorySignalProtocolStore();
            SessionBuilder      aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_ADDRESS);

            SignalProtocolStore bobStore = new TestInMemorySignalProtocolStore();

            ECKeyPair bobPreKeyPair       = Curve.generateKeyPair();
            ECKeyPair bobSignedPreKeyPair = Curve.generateKeyPair();

            byte[] bobSignedPreKeySignature = Curve.calculateSignature(bobStore.GetIdentityKeyPair().getPrivateKey(),
                                                                       bobSignedPreKeyPair.getPublicKey().serialize());

            PreKeyBundle bobPreKey = new PreKeyBundle(bobStore.GetLocalRegistrationId(), 1,
                                                      31337, bobPreKeyPair.getPublicKey(),
                                                      22, bobSignedPreKeyPair.getPublicKey(), bobSignedPreKeySignature,
                                                      bobStore.GetIdentityKeyPair().getPublicKey());

            bobStore.StorePreKey(31337, new PreKeyRecord(bobPreKey.getPreKeyId(), bobPreKeyPair));
            bobStore.StoreSignedPreKey(22, new SignedPreKeyRecord(22, DateUtil.currentTimeMillis(), bobSignedPreKeyPair, bobSignedPreKeySignature));

            aliceSessionBuilder.process(bobPreKey);

            String            originalMessage    = "L'homme est condamné à être libre";
            SessionCipher     aliceSessionCipher = new SessionCipher(aliceStore, BOB_ADDRESS);
            CiphertextMessage outgoingMessageOne = aliceSessionCipher.encrypt(Encoding.UTF8.GetBytes(originalMessage));
            CiphertextMessage outgoingMessageTwo = aliceSessionCipher.encrypt(Encoding.UTF8.GetBytes(originalMessage));

            Assert.AreEqual(CiphertextMessage.PREKEY_TYPE, outgoingMessageOne.getType());
            Assert.AreEqual(CiphertextMessage.PREKEY_TYPE, outgoingMessageTwo.getType());

            PreKeySignalMessage incomingMessage = new PreKeySignalMessage(outgoingMessageOne.serialize());

            SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_ADDRESS);

            byte[] plaintext = bobSessionCipher.decrypt(incomingMessage);
            Assert.AreEqual(originalMessage, Encoding.UTF8.GetString(plaintext));

            CiphertextMessage bobOutgoingMessage = bobSessionCipher.encrypt(Encoding.UTF8.GetBytes(originalMessage));

            byte[] alicePlaintext = aliceSessionCipher.decrypt(new SignalMessage(bobOutgoingMessage.serialize()));
            Assert.AreEqual(originalMessage, Encoding.UTF8.GetString(alicePlaintext));

            // The test

            PreKeySignalMessage incomingMessageTwo = new PreKeySignalMessage(outgoingMessageTwo.serialize());

            plaintext = bobSessionCipher.decrypt(new PreKeySignalMessage(incomingMessageTwo.serialize()));
            Assert.AreEqual(originalMessage, Encoding.UTF8.GetString(plaintext));

            bobOutgoingMessage = bobSessionCipher.encrypt(Encoding.UTF8.GetBytes(originalMessage));
            alicePlaintext     = aliceSessionCipher.decrypt(new SignalMessage(bobOutgoingMessage.serialize()));
            Assert.AreEqual(originalMessage, Encoding.UTF8.GetString(alicePlaintext));
        }
        public void testMatchingFingerprints()
        {
            ECKeyPair aliceKeyPair = Curve.generateKeyPair();
            ECKeyPair bobKeyPair   = Curve.generateKeyPair();

            IdentityKey aliceIdentityKey = new IdentityKey(aliceKeyPair.getPublicKey());
            IdentityKey bobIdentityKey   = new IdentityKey(bobKeyPair.getPublicKey());

            NumericFingerprintGenerator generator = new NumericFingerprintGenerator(1024);
            Fingerprint aliceFingerprint          = generator.createFor("+14152222222", aliceIdentityKey,
                                                                        "+14153333333", bobIdentityKey);

            Fingerprint bobFingerprint = generator.createFor("+14153333333", bobIdentityKey,
                                                             "+14152222222", aliceIdentityKey);

            Assert.AreEqual <string>(aliceFingerprint.getDisplayableFingerprint().getDisplayText(),
                                     bobFingerprint.getDisplayableFingerprint().getDisplayText());

            Assert.IsTrue(
                aliceFingerprint.getScannableFingerprint().compareTo(
                    bobFingerprint.getScannableFingerprint().getSerialized()));
            Assert.IsTrue(
                bobFingerprint.getScannableFingerprint().compareTo(
                    aliceFingerprint.getScannableFingerprint().getSerialized()));

            Assert.AreEqual <int>(aliceFingerprint.getDisplayableFingerprint().getDisplayText().Length, 60);
        }
        /**
         * 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(CiphertextMessage.CURRENT_VERSION, sequence, flags, baseKey.getPublicKey(), baseKeySignature,
                                                  ratchetKey.getPublicKey(), identityKey.getPublicKey()));
                }
                catch (InvalidKeyException e)
                {
                    throw new Exception(e.Message);
                }
            }
        }
Example #7
0
        private static IdentityKeyPair generateIdentityKeyPair()
        {
            ECKeyPair identityKeyPairKeys = Curve.generateKeyPair();

            return(new IdentityKeyPair(new IdentityKey(identityKeyPairKeys.getPublicKey()),
                                       identityKeyPairKeys.getPrivateKey()));
        }
Example #8
0
        private void GenerateKey(IDataStore dataStore, object context)
        {
            keyPair = Curve.generateKeyPair();

            dataStore.SetString(context, "privateKey", Convert.ToBase64String(keyPair.getPrivateKey().serialize()));
            dataStore.SetString(context, "publicKey", Convert.ToBase64String(keyPair.getPublicKey().serialize()));
        }
        public void testMismatchingFingerprints()
        {
            ECKeyPair aliceKeyPair = Curve.generateKeyPair();
            ECKeyPair bobKeyPair   = Curve.generateKeyPair();
            ECKeyPair mitmKeyPair  = Curve.generateKeyPair();

            IdentityKey aliceIdentityKey = new IdentityKey(aliceKeyPair.getPublicKey());
            IdentityKey bobIdentityKey   = new IdentityKey(bobKeyPair.getPublicKey());
            IdentityKey mitmIdentityKey  = new IdentityKey(mitmKeyPair.getPublicKey());

            NumericFingerprintGenerator generator = new NumericFingerprintGenerator(1024);
            Fingerprint aliceFingerprint          = generator.createFor(VERSION_1,
                                                                        Encoding.UTF8.GetBytes("+14152222222"), aliceIdentityKey,
                                                                        Encoding.UTF8.GetBytes("+14153333333"), mitmIdentityKey);

            Fingerprint bobFingerprint = generator.createFor(VERSION_1,
                                                             Encoding.UTF8.GetBytes("+14153333333"), bobIdentityKey,
                                                             Encoding.UTF8.GetBytes("+14152222222"), aliceIdentityKey);

            Assert.AreNotEqual(aliceFingerprint.getDisplayableFingerprint().getDisplayText(),
                               bobFingerprint.getDisplayableFingerprint().getDisplayText());

            Assert.IsFalse(aliceFingerprint.getScannableFingerprint().compareTo(bobFingerprint.getScannableFingerprint().getSerialized()));
            Assert.IsFalse(bobFingerprint.getScannableFingerprint().compareTo(aliceFingerprint.getScannableFingerprint().getSerialized()));
        }
        public void TestEncryptFromWrongIdentity()
        {
            TestInMemorySignalProtocolStore aliceStore = new TestInMemorySignalProtocolStore();
            TestInMemorySignalProtocolStore bobStore   = new TestInMemorySignalProtocolStore();

            InitializeSessions(aliceStore, bobStore);

            ECKeyPair           trustRoot         = Curve.generateKeyPair();
            ECKeyPair           randomKeyPair     = Curve.generateKeyPair();
            SenderCertificate   senderCertificate = CreateCertificateFor(trustRoot, "+14151111111", 1, randomKeyPair.getPublicKey(), 31337);
            SealedSessionCipher aliceCipher       = new SealedSessionCipher(aliceStore, new SignalProtocolAddress("+14151111111", 1));

            byte[] ciphertext = aliceCipher.Encrypt(new SignalProtocolAddress("+14152222222", 1),
                                                    senderCertificate, Encoding.ASCII.GetBytes("smert za smert"));


            SealedSessionCipher bobCipher = new SealedSessionCipher(bobStore, new SignalProtocolAddress("+14152222222", 1));

            try
            {
                bobCipher.Decrypt(new CertificateValidator(trustRoot.getPublicKey()), ciphertext, 31335);
            }
            catch (InvalidMetadataMessageException)
            {
                // good
            }
        }
Example #11
0
        /// <summary>
        /// Generate an identity key pair. Clients should only do this once, at install time.
        /// </summary>
        /// <returns>the generated IdentityKeyPair.</returns>
        public static IdentityKeyPair generateIdentityKeyPair()
        {
            ECKeyPair   keyPair   = Curve.generateKeyPair();
            IdentityKey publicKey = new IdentityKey(keyPair.getPublicKey());

            return(new IdentityKeyPair(publicKey, keyPair.getPrivateKey()));
        }
        private SenderCertificate CreateCertificateFor(ECKeyPair trustRoot, String sender, int deviceId, ECPublicKey identityKey, long expires)
        {
            ECKeyPair serverKey = Curve.generateKeyPair();

            byte[] serverCertificateBytes = new libsignalmetadata.protobuf.ServerCertificate.Types.Certificate()
            {
                Id  = 1,
                Key = ByteString.CopyFrom(serverKey.getPublicKey().serialize())
            }.ToByteArray();

            byte[] serverCertificateSignature = Curve.calculateSignature(trustRoot.getPrivateKey(), serverCertificateBytes);

            ServerCertificate serverCertificate = new ServerCertificate(new libsignalmetadata.protobuf.ServerCertificate()
            {
                Certificate = ByteString.CopyFrom(serverCertificateBytes),
                Signature   = ByteString.CopyFrom(serverCertificateSignature)
            }.ToByteArray());

            byte[] senderCertificateBytes = new libsignalmetadata.protobuf.SenderCertificate.Types.Certificate
            {
                Sender       = sender,
                SenderDevice = (uint)deviceId,
                IdentityKey  = ByteString.CopyFrom(identityKey.serialize()),
                Expires      = (ulong)expires,
                Signer       = libsignalmetadata.protobuf.ServerCertificate.Parser.ParseFrom(serverCertificate.Serialized)
            }.ToByteArray();

            byte[] senderCertificateSignature = Curve.calculateSignature(serverKey.getPrivateKey(), senderCertificateBytes);

            return(new SenderCertificate(new libsignalmetadata.protobuf.SenderCertificate()
            {
                Certificate = ByteString.CopyFrom(senderCertificateBytes),
                Signature = ByteString.CopyFrom(senderCertificateSignature)
            }.ToByteArray()));
        }
Example #13
0
        public void testOptionalOneTimePreKey()
        {
            SignalProtocolStore aliceStore          = new TestInMemorySignalProtocolStore();
            SessionBuilder      aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_ADDRESS);

            SignalProtocolStore bobStore = new TestInMemorySignalProtocolStore();

            ECKeyPair bobPreKeyPair       = Curve.generateKeyPair();
            ECKeyPair bobSignedPreKeyPair = Curve.generateKeyPair();

            byte[] bobSignedPreKeySignature = Curve.calculateSignature(bobStore.GetIdentityKeyPair().getPrivateKey(),
                                                                       bobSignedPreKeyPair.getPublicKey().serialize());

            PreKeyBundle bobPreKey = new PreKeyBundle(bobStore.GetLocalRegistrationId(), 1,
                                                      0, null,
                                                      22, bobSignedPreKeyPair.getPublicKey(),
                                                      bobSignedPreKeySignature,
                                                      bobStore.GetIdentityKeyPair().getPublicKey());

            aliceSessionBuilder.process(bobPreKey);

            Assert.IsTrue(aliceStore.ContainsSession(BOB_ADDRESS));
            Assert.AreEqual((uint)3, aliceStore.LoadSession(BOB_ADDRESS).getSessionState().getSessionVersion());

            String            originalMessage    = "L'homme est condamné à être libre";
            SessionCipher     aliceSessionCipher = new SessionCipher(aliceStore, BOB_ADDRESS);
            CiphertextMessage outgoingMessage    = aliceSessionCipher.encrypt(Encoding.UTF8.GetBytes(originalMessage));

            Assert.AreEqual(outgoingMessage.getType(), CiphertextMessage.PREKEY_TYPE);

            PreKeySignalMessage incomingMessage = new PreKeySignalMessage(outgoingMessage.serialize());

            Assert.IsFalse(incomingMessage.getPreKeyId().HasValue);

            bobStore.StorePreKey(31337, new PreKeyRecord(bobPreKey.getPreKeyId(), bobPreKeyPair));
            bobStore.StoreSignedPreKey(22, new SignedPreKeyRecord(22, DateUtil.currentTimeMillis(), bobSignedPreKeyPair, bobSignedPreKeySignature));

            SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_ADDRESS);

            byte[] plaintext = bobSessionCipher.decrypt(incomingMessage);

            Assert.IsTrue(bobStore.ContainsSession(ALICE_ADDRESS));
            Assert.AreEqual((uint)3, bobStore.LoadSession(ALICE_ADDRESS).getSessionState().getSessionVersion());
            Assert.IsNotNull(bobStore.LoadSession(ALICE_ADDRESS).getSessionState().getAliceBaseKey());
            Assert.AreEqual(originalMessage, Encoding.UTF8.GetString(plaintext));
        }
Example #14
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());
            }
        }
Example #15
0
        private PreKeyBundle createBobPreKeyBundle(SignalProtocolStore bobStore)
        {
            ECKeyPair bobUnsignedPreKey   = Curve.generateKeyPair();
            int       bobUnsignedPreKeyId = new Random().Next((int)Medium.MAX_VALUE);

            byte[] bobSignature = Curve.calculateSignature(bobStore.GetIdentityKeyPair().getPrivateKey(),
                                                           bobSignedPreKey.getPublicKey().serialize());

            PreKeyBundle bobPreKeyBundle = new PreKeyBundle(1, 1,
                                                            (uint)bobUnsignedPreKeyId, bobUnsignedPreKey.getPublicKey(),
                                                            bobSignedPreKeyId, bobSignedPreKey.getPublicKey(),
                                                            bobSignature, bobStore.GetIdentityKeyPair().getPublicKey());

            bobStore.StoreSignedPreKey(bobSignedPreKeyId, new SignedPreKeyRecord(bobSignedPreKeyId, (ulong)DateTime.UtcNow.Ticks, bobSignedPreKey, bobSignature));
            bobStore.StorePreKey((uint)bobUnsignedPreKeyId, new PreKeyRecord((uint)bobUnsignedPreKeyId, bobUnsignedPreKey));

            return(bobPreKeyBundle);
        }
Example #16
0
 public PreKeyRecord(uint id, ECKeyPair keyPair)
 {
     this.structure = new PreKeyRecordStructure
     {
         Id         = id,
         PublicKey  = ByteString.CopyFrom(keyPair.getPublicKey().serialize()),
         PrivateKey = ByteString.CopyFrom(keyPair.getPrivateKey().serialize())
     };
 }
Example #17
0
        private PreKeyBundle createBobPreKeyBundle(AxolotlStore bobStore)
        {
            ECKeyPair bobUnsignedPreKey   = Curve.generateKeyPair();
            uint      bobUnsignedPreKeyId = (uint)new Random().Next((int)Medium.MAX_VALUE);

            byte[] bobSignature = Curve.calculateSignature(bobStore.GetIdentityKeyPair().getPrivateKey(),
                                                           bobSignedPreKey.getPublicKey().serialize());

            PreKeyBundle bobPreKeyBundle = new PreKeyBundle(1, 1,
                                                            bobUnsignedPreKeyId, bobUnsignedPreKey.getPublicKey(),
                                                            bobSignedPreKeyId, bobSignedPreKey.getPublicKey(),
                                                            bobSignature, bobStore.GetIdentityKeyPair().getPublicKey());

            bobStore.StoreSignedPreKey(bobSignedPreKeyId, new SignedPreKeyRecord(bobSignedPreKeyId, DateUtil.currentTimeMillis(), bobSignedPreKey, bobSignature));
            bobStore.StorePreKey(bobUnsignedPreKeyId, new PreKeyRecord(bobUnsignedPreKeyId, bobUnsignedPreKey));

            return(bobPreKeyBundle);
        }
Example #18
0
        private PreKeyBundle createAlicePreKeyBundle(SignalProtocolStore aliceStore)
        {
            ECKeyPair aliceUnsignedPreKey   = Curve.generateKeyPair();
            int       aliceUnsignedPreKeyId = new Random().Next((int)Medium.MAX_VALUE);

            byte[] aliceSignature = Curve.calculateSignature(aliceStore.GetIdentityKeyPair().getPrivateKey(),
                                                             aliceSignedPreKey.getPublicKey().serialize());

            PreKeyBundle alicePreKeyBundle = new PreKeyBundle(1, 1,
                                                              (uint)aliceUnsignedPreKeyId, aliceUnsignedPreKey.getPublicKey(),
                                                              aliceSignedPreKeyId, aliceSignedPreKey.getPublicKey(),
                                                              aliceSignature, aliceStore.GetIdentityKeyPair().getPublicKey());

            aliceStore.StoreSignedPreKey(aliceSignedPreKeyId, new SignedPreKeyRecord(aliceSignedPreKeyId, (ulong)DateTime.UtcNow.Ticks, aliceSignedPreKey, aliceSignature));
            aliceStore.StorePreKey((uint)aliceUnsignedPreKeyId, new PreKeyRecord((uint)aliceUnsignedPreKeyId, aliceUnsignedPreKey));

            return(alicePreKeyBundle);
        }
Example #19
0
        public void testBadSignedPreKeySignature()
        {
            SignalProtocolStore aliceStore          = new TestInMemorySignalProtocolStore();
            SessionBuilder      aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_ADDRESS);

            IdentityKeyStore bobIdentityKeyStore = new TestInMemoryIdentityKeyStore();

            ECKeyPair bobPreKeyPair       = Curve.generateKeyPair();
            ECKeyPair bobSignedPreKeyPair = Curve.generateKeyPair();

            byte[] bobSignedPreKeySignature = Curve.calculateSignature(bobIdentityKeyStore.GetIdentityKeyPair().getPrivateKey(),
                                                                       bobSignedPreKeyPair.getPublicKey().serialize());


            for (int i = 0; i < bobSignedPreKeySignature.Length * 8; i++)
            {
                byte[] modifiedSignature = new byte[bobSignedPreKeySignature.Length];
                Array.Copy(bobSignedPreKeySignature, 0, modifiedSignature, 0, modifiedSignature.Length);

                modifiedSignature[i / 8] ^= (byte)(0x01 << (i % 8));

                PreKeyBundle bobPreKey = new PreKeyBundle(bobIdentityKeyStore.GetLocalRegistrationId(), 1,
                                                          31337, bobPreKeyPair.getPublicKey(),
                                                          22, bobSignedPreKeyPair.getPublicKey(), modifiedSignature,
                                                          bobIdentityKeyStore.GetIdentityKeyPair().getPublicKey());

                try
                {
                    aliceSessionBuilder.process(bobPreKey);
                    throw new Exception("Accepted modified device key signature!");
                }
                catch (InvalidKeyException)
                {
                    // good
                }
            }

            PreKeyBundle bobPreKey2 = new PreKeyBundle(bobIdentityKeyStore.GetLocalRegistrationId(), 1,
                                                       31337, bobPreKeyPair.getPublicKey(),
                                                       22, bobSignedPreKeyPair.getPublicKey(), bobSignedPreKeySignature,
                                                       bobIdentityKeyStore.GetIdentityKeyPair().getPublicKey());

            aliceSessionBuilder.process(bobPreKey2);
        }
Example #20
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();
 }
 public SignedPreKeyRecord(uint id, ulong timestamp, ECKeyPair keyPair, byte[] signature)
 {
     this.structure = new SignedPreKeyRecordStructure
     {
         Id         = id,
         PublicKey  = ByteString.CopyFrom(keyPair.getPublicKey().serialize()),
         PrivateKey = ByteString.CopyFrom(keyPair.getPrivateKey().serialize()),
         Signature  = ByteString.CopyFrom(signature),
         Timestamp  = timestamp
     };
 }
Example #22
0
        public static void generateCurve25519IdentityKeys()
        {
            //MasterCipher masterCipher = new MasterCipher(masterSecret);
            ECKeyPair   djbKeyPair     = Curve.generateKeyPair();
            IdentityKey djbIdentityKey = new IdentityKey(djbKeyPair.getPublicKey());

            byte[] djbPrivateKey = /*masterCipher.encryptKey(*/ djbKeyPair.getPrivateKey().serialize() /*)*/;

            save(IDENTITY_PUBLIC_KEY_DJB_PREF, System.Convert.ToBase64String(djbIdentityKey.serialize()));
            save(IDENTITY_PRIVATE_KEY_DJB_PREF, System.Convert.ToBase64String(djbPrivateKey));
        }
Example #23
0
 public SignedPreKeyRecord(uint id, ulong timestamp, ECKeyPair keyPair, byte[] signature)
 {
     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 #24
0
        public void TestDecodeSize()
        {
            ECKeyPair keyPair = Curve.generateKeyPair();

            byte[] serializedPublic = keyPair.getPublicKey().serialize();

            ECPublicKey justRight = Curve.decodePoint(serializedPublic, 0);

            try
            {
                ECPublicKey tooSmall = Curve.decodePoint(serializedPublic, 1);
                Assert.Fail("Shouldn't decode");
            }
            catch (InvalidKeyException e)
            {
                // good
            }

            try
            {
                ECPublicKey empty = Curve.decodePoint(new byte[0], 0);
                Assert.Fail("Shouldn't parse");
            }
            catch (InvalidKeyException e)
            {
                // good
            }

            try
            {
                byte[] badKeyType = new byte[33];
                Array.Copy(serializedPublic, 0, badKeyType, 0, serializedPublic.Length);
                badKeyType[0] = 0x01;
                Curve.decodePoint(badKeyType, 0);
                Assert.Fail("Should be bad key type");
            }
            catch (InvalidKeyException e)
            {
                // good
            }

            byte[] extraSpace = new byte[serializedPublic.Length + 1];
            Array.Copy(serializedPublic, 0, extraSpace, 0, serializedPublic.Length);
            ECPublicKey extra = Curve.decodePoint(extraSpace, 0);

            byte[] offsetSpace = new byte[serializedPublic.Length + 1];
            Array.Copy(serializedPublic, 0, offsetSpace, 1, serializedPublic.Length);
            ECPublicKey offset = Curve.decodePoint(offsetSpace, 1);

            CollectionAssert.AreEqual(serializedPublic, justRight.serialize());
            CollectionAssert.AreEqual(extra.serialize(), serializedPublic);
            CollectionAssert.AreEqual(offset.serialize(), serializedPublic);
        }
Example #25
0
        public void testRandomAgreements()
        {
            for (int i = 0; i < 50; i++)
            {
                ECKeyPair alice = Curve.generateKeyPair();
                ECKeyPair bob   = Curve.generateKeyPair();

                byte[] sharedAlice = Curve.calculateAgreement(bob.getPublicKey(), alice.getPrivateKey());
                byte[] sharedBob   = Curve.calculateAgreement(alice.getPublicKey(), bob.getPrivateKey());

                CollectionAssert.AreEqual(sharedAlice, sharedBob);
            }
        }
        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));
        }
Example #27
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 #28
0
        private libsignalmetadata.protobuf.ServerCertificate GetServerCertificate(ECKeyPair serverKey)
        {
            byte[] certificateBytes = new libsignalmetadata.protobuf.ServerCertificate.Types.Certificate()
            {
                Id  = 1,
                Key = ByteString.CopyFrom(serverKey.getPublicKey().serialize())
            }.ToByteArray();

            byte[] certificateSignature = Curve.calculateSignature(TrustRoot.getPrivateKey(), certificateBytes);

            return(new libsignalmetadata.protobuf.ServerCertificate()
            {
                Certificate = ByteString.CopyFrom(certificateBytes),
                Signature = ByteString.CopyFrom(certificateSignature)
            });
        }
        public void setSenderChain(ECKeyPair senderRatchetKeyPair, ChainKey chainKey)
        {
            Chain.Types.ChainKey chainKeyStructure = new Chain.Types.ChainKey
            {
                Key   = ByteString.CopyFrom(chainKey.getKey()),
                Index = chainKey.getIndex()
            };

            Chain senderChain = new Chain
            {
                SenderRatchetKey        = ByteString.CopyFrom(senderRatchetKeyPair.getPublicKey().serialize()),
                SenderRatchetKeyPrivate = ByteString.CopyFrom(senderRatchetKeyPair.getPrivateKey().serialize()),
                ChainKey = chainKeyStructure
            };

            this.sessionStructure.SenderChain = senderChain;
        }
        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;
        }