Example #1
0
        public ProvisionMessage Decrypt(IdentityKeyPair tmpIdentity, byte[] message)
        {
            ProvisionEnvelope env       = ProvisionEnvelope.Parser.ParseFrom(message);
            ECPublicKey       publicKey = Curve.decodePoint(env.PublicKey.ToByteArray(), 0);

            byte[]   sharedSecret  = Curve.calculateAgreement(publicKey, tmpIdentity.getPrivateKey());
            byte[]   derivedSecret = new HKDFv3().deriveSecrets(sharedSecret, Encoding.UTF8.GetBytes("TextSecure Provisioning Message"), 64);
            byte[][] parts         = Util.Split(derivedSecret, 32, 32);
            byte[]   joined        = env.Body.ToByteArray();
            if (joined[0] != 0x01)
            {
                throw new Exception("Bad version number on provision message!");
            }
            byte[] iv = new byte[16];
            Array.Copy(joined, 1, iv, 0, 16);
            byte[] ciphertext = new byte[joined.Length - 32 - 17];
            Array.Copy(joined, 17, ciphertext, 0, joined.Length - 32 - 17);
            byte[] ivAndCiphertext = new byte[joined.Length - 32];
            Array.Copy(joined, ivAndCiphertext, joined.Length - 32);
            byte[] mac = new byte[32];
            Array.Copy(joined, joined.Length - 32, mac, 0, 32);

            VerifyMac(parts[1], ivAndCiphertext, mac);
            return(ProvisionMessage.Parser.ParseFrom(Decrypt(parts[0], iv, ciphertext)));
        }
        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());
        }