Example #1
0
        private static IdentityKeyPair generateIdentityKeyPair()
        {
            ECKeyPair identityKeyPairKeys = Curve.generateKeyPair();

            return(new IdentityKeyPair(new IdentityKey(identityKeyPairKeys.getPublicKey()),
                                       identityKeyPairKeys.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 #3
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()));
        }
Example #4
0
        public void TestExpiredSignature()
        {
            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());

            try
            {
                new CertificateValidator(TrustRoot.getPublicKey()).Validate(senderCertificate, 31338);
                throw new Exception();
            }
            catch (InvalidCertificateException)
            {
                // good
            }
        }
Example #5
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 #6
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()));
        }
Example #7
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 #8
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 #10
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 #11
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 #12
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);
            }
        }
Example #13
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 #14
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)
            });
        }
Example #15
0
        public void testSignatureOverflow()
        {
            ECKeyPair keys = Curve.generateKeyPair();

            byte[] message = new byte[4096];

            try
            {
                byte[] signature = Curve.calculateSignature(keys.getPrivateKey(), message);
                throw new InvalidKeyException("Should have asserted!");
            }
            catch (InvalidKeyException)
            {
                // Success!
            }
        }
        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 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;
        }
Example #18
0
        public void TestBadSignature()
        {
            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);

            for (int i = 0; i < certificateSignature.Length; i++)
            {
                for (int b = 0; b < 8; b++)
                {
                    byte[] badSignature = new byte[certificateSignature.Length];
                    Array.Copy(certificateSignature, 0, badSignature, 0, certificateSignature.Length);

                    badSignature[i] = (byte)(badSignature[i] ^ 1 << b);

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

                    try
                    {
                        new CertificateValidator(TrustRoot.getPublicKey()).Validate(senderCertificate, 31336);
                        throw new Exception();
                    }
                    catch (InvalidCertificateException)
                    {
                        // good
                    }
                }
            }
        }
        public byte[] encrypt(ProvisionMessage message)// throws InvalidKeyException
        {
            ECKeyPair ourKeyPair = Curve.generateKeyPair();

            byte[]   sharedSecret  = Curve.calculateAgreement(theirPublicKey, ourKeyPair.getPrivateKey());
            byte[]   derivedSecret = new HKDFv3().deriveSecrets(sharedSecret, Encoding.UTF8.GetBytes("TextSecure Provisioning Message"), 64);
            byte[][] parts         = Util.split(derivedSecret, 32, 32);

            byte[] version    = { 0x01 };
            byte[] ciphertext = getCiphertext(parts[0], message.ToByteArray());
            byte[] mac        = getMac(parts[1], Util.join(version, ciphertext));
            byte[] body       = Util.join(version, ciphertext, mac);

            return(ProvisionEnvelope.CreateBuilder()
                   .SetPublicKey(ByteString.CopyFrom(ourKeyPair.getPublicKey().serialize()))
                   .SetBody(ByteString.CopyFrom(body))
                   .Build()
                   .ToByteArray());
        }
Example #20
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 #21
0
        public byte[] Encrypt(SignalProtocolAddress destinationAddress, SenderCertificate senderCertificate, byte[] paddedPlaintext)
        {
            CiphertextMessage message       = new SessionCipher(SignalProtocolStore, destinationAddress).encrypt(paddedPlaintext);
            IdentityKeyPair   ourIdentity   = SignalProtocolStore.GetIdentityKeyPair();
            ECPublicKey       theirIdentity = SignalProtocolStore.GetIdentity(destinationAddress).getPublicKey();

            ECKeyPair ephemeral = Curve.generateKeyPair();

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

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

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

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

            return(new UnidentifiedSenderMessage(ephemeral.getPublicKey(), staticKeyCiphertext, messageBytes).Serialized);
        }
        public void TestSignature()
        {
            ECKeyPair trustRoot = Curve.generateKeyPair();
            ECKeyPair keyPair   = Curve.generateKeyPair();

            var certificate = new libsignalmetadata.protobuf.ServerCertificate.Types.Certificate()
            {
                Id  = 1,
                Key = ByteString.CopyFrom(keyPair.getPublicKey().serialize())
            };

            byte[] certificateBytes     = certificate.ToByteArray();
            byte[] certificateSignature = Curve.calculateSignature(trustRoot.getPrivateKey(), certificateBytes);

            byte[] serialized = new libsignalmetadata.protobuf.ServerCertificate()
            {
                Certificate = ByteString.CopyFrom(certificateBytes),
                Signature   = ByteString.CopyFrom(certificateSignature)
            }.ToByteArray();

            new CertificateValidator(trustRoot.getPublicKey()).Validate(new ServerCertificate(serialized));
        }
Example #23
0
        public Pair <RootKey, ChainKey> createChain(ECPublicKey theirRatchetKey, ECKeyPair ourRatchetKey)
        {
            byte[]             sharedSecret       = Curve.calculateAgreement(theirRatchetKey, ourRatchetKey.getPrivateKey());
            byte[]             derivedSecretBytes = kdf.deriveSecrets(sharedSecret, key, Encoding.UTF8.GetBytes("WhisperRatchet"), DerivedRootSecrets.SIZE);
            DerivedRootSecrets derivedSecrets     = new DerivedRootSecrets(derivedSecretBytes);

            RootKey  newRootKey  = new RootKey(kdf, derivedSecrets.getRootKey());
            ChainKey newChainKey = new ChainKey(kdf, derivedSecrets.getChainKey(), 0);

            return(new Pair <RootKey, ChainKey>(newRootKey, newChainKey));
        }
 public SenderKeyState(uint id, uint iteration, byte[] chainKey, ECKeyPair signatureKey)
     : this(id, iteration, chainKey, signatureKey.getPublicKey(), new May <ECPrivateKey>(signatureKey.getPrivateKey()))
 {
 }
        public void TestBadSignature()
        {
            ECKeyPair trustRoot = Curve.generateKeyPair();
            ECKeyPair keyPair   = Curve.generateKeyPair();

            var certificate = new libsignalmetadata.protobuf.ServerCertificate.Types.Certificate()
            {
                Id  = 1,
                Key = ByteString.CopyFrom(keyPair.getPublicKey().serialize())
            };

            byte[] certificateBytes     = certificate.ToByteArray();
            byte[] certificateSignature = Curve.calculateSignature(trustRoot.getPrivateKey(), certificateBytes);

            for (int i = 0; i < certificateSignature.Length; i++)
            {
                for (int b = 0; b < 8; b++)
                {
                    byte[] badSignature = new byte[certificateSignature.Length];
                    Array.Copy(certificateSignature, 0, badSignature, 0, badSignature.Length);

                    badSignature[i] = (byte)(badSignature[i] ^ (1 << b));


                    byte[] serialized = new libsignalmetadata.protobuf.ServerCertificate()
                    {
                        Certificate = ByteString.CopyFrom(certificateBytes),
                        Signature   = ByteString.CopyFrom(badSignature)
                    }.ToByteArray();

                    try
                    {
                        new CertificateValidator(trustRoot.getPublicKey()).Validate(new ServerCertificate(serialized));
                        throw new Exception();
                    }
                    catch (InvalidCertificateException)
                    {
                        // good
                    }
                }
            }

            for (int i = 0; i < certificateBytes.Length; i++)
            {
                for (int b = 0; b < 8; b++)
                {
                    byte[] badCertificate = new byte[certificateBytes.Length];
                    Array.Copy(certificateBytes, 0, badCertificate, 0, badCertificate.Length);

                    badCertificate[i] = (byte)(badCertificate[i] ^ (1 << b));

                    byte[] serialized = new libsignalmetadata.protobuf.ServerCertificate()
                    {
                        Certificate = ByteString.CopyFrom(badCertificate),
                        Signature   = ByteString.CopyFrom(certificateSignature)
                    }.ToByteArray();

                    try
                    {
                        new CertificateValidator(trustRoot.getPublicKey()).Validate(new ServerCertificate(serialized));
                        throw new Exception();
                    }
                    catch (InvalidCertificateException)
                    {
                        // good
                    }
                }
            }
        }
Example #26
0
 public byte[] CalculateSignature(byte[] data)
 {
     return(Curve.calculateSignature(keyPair.getPrivateKey(), data));
 }