Exemple #1
0
        public TLSEnvelope TLSServerEncryptRequest(byte[] clearPacket, string recipientId)
        {
            byte[] authSecret = GetAuthSecret(recipientId);

            DynamicSecret dynamicSecret = GetDynamicSecretForEncryption(recipientId);

            Debug.WriteLine($"{this.ServerId}: TLSEncrypt: DynamicPublicKeyID: {dynamicSecret.DynamicPublicKeyId}, PrivateKeyHint: {dynamicSecret.PrivateKeyHint}.");

            // Concatenate = 'TLSAuthMode.Combined'
            byte[] symmetricKeyMaterial64 = ByteArrays.Concatenate(dynamicSecret.DynamicSharedSecret, authSecret);

            var lro        = new LongRunningOperation(progress => { }, () => { });
            var clearBytes = new Clearbytes(clearPacket);
            var sha512PW64 = new KeyMaterial64(symmetricKeyMaterial64);
            var method     = new RoundsExponent(0xff);

            var encryptResponse = this.ixdsCryptoService.BinaryEncrypt(clearBytes, sha512PW64, method, lro.Context);

            if (!encryptResponse.IsSuccess)
            {
                throw new Exception(encryptResponse.Error);
            }

            var encodeResponse = this.ixdsCryptoService.BinaryEncodeXDSSec(encryptResponse.Result, lro.Context);

            if (!encodeResponse.IsSuccess)
            {
                throw new Exception(encodeResponse.Error);
            }

            var tlsEnvelope = new TLSEnvelope(dynamicSecret.PrivateKeyHint, dynamicSecret.DynamicPublicKeyId, dynamicSecret.DynamicPublicKey, encodeResponse.Result);

            return(tlsEnvelope);
        }
Exemple #2
0
        ChatWorker ChatWorker => this.dependencyInjection.ServiceProvider.Get <ChatWorker>(); // otherwise circular

        public async Task <Response> EncryptMessage(Message message, bool?isInitial = null)
        {
            var response = new Response();

            try
            {
                var roundsExponent = new RoundsExponent(RoundsExponent.DontMakeRounds);


                var initialKeyResult = await this.e2ERatchet.GetE2EEncryptionKeyCommonAsync(message.RecipientId, isInitial);

                var keyMaterial = initialKeyResult.Item1;
                message.DynamicPublicKey   = initialKeyResult.Item2;
                message.DynamicPublicKeyId = initialKeyResult.Item3;
                message.PrivateKeyHint     = initialKeyResult.Item4;

                // I this is not null, either isInitial was true, or the ratchet was just initialized the first time for an added user's first message.
                var initialMetadataKeyMaterial = initialKeyResult.Item5;


                await Task.Run(() => EncryptWithStrategy(message, keyMaterial, roundsExponent, initialMetadataKeyMaterial));

                response.SetSuccess();
            }
            catch (Exception e)
            {
                response.SetError(e.Message);
            }
            return(response);
        }
Exemple #3
0
        void EncryptWithStrategy(Message message, KeyMaterial64 keyMaterial, RoundsExponent roundsExponent, KeyMaterial64 initialMetadataKeyMaterial)
        {
            XMessageMetaData messageMetadata = new XMessageMetaData {
                MessageType = message.MessageType
            };

            switch (message.MessageType)
            {
            case MessageType.Text:
                message.TextCipher = EncryptTextToBytes(message.ThreadText, keyMaterial, roundsExponent);
                messageMetadata.SenderLocalMessageId = int.Parse(message.Id);
                break;

            case MessageType.Media:
                message.ImageCipher = this.ixdsCryptoService.DefaultEncrypt(message.ThreadMedia, keyMaterial);
                messageMetadata.SenderLocalMessageId = int.Parse(message.Id);
                break;

            case MessageType.TextAndMedia:
            case MessageType.File:
                message.TextCipher  = EncryptTextToBytes(message.ThreadText, keyMaterial, roundsExponent);
                message.ImageCipher = this.ixdsCryptoService.DefaultEncrypt(message.ThreadMedia, keyMaterial);
                messageMetadata.SenderLocalMessageId = int.Parse(message.Id);
                break;

            case MessageType.DeliveryReceipt:
            case MessageType.ReadReceipt:
                messageMetadata.SenderLocalMessageId = int.Parse(message.SenderLocalMessageId);
                break;

            default:
                throw new Exception("Invalid MessageType");
            }

            if (initialMetadataKeyMaterial != null)             // initialMetadataKeyMaterial is only for resend requests
            {
                messageMetadata.SenderPublicKey = this.profileViewModel.PublicKey;
                message.MetaCipher = this.ixdsCryptoService.DefaultEncrypt(messageMetadata.SerializeCore(), initialMetadataKeyMaterial);
            }
            else
            {
                messageMetadata.SenderPublicKey = this.ixdsCryptoService.GetRandom(32).Result.X;
                message.MetaCipher = this.ixdsCryptoService.DefaultEncrypt(messageMetadata.SerializeCore(), keyMaterial);
            }

            if (!message.MessageType.IsReceipt())
            {
                message.EncryptedE2EEncryptionKey = this.ixdsCryptoService.DefaultEncrypt(keyMaterial.GetBytes(), this.ixdsCryptoService.SymmetricKeyRepository.GetMasterRandomKey());
            }
        }
Exemple #4
0
        byte[] EncryptTextToBytes(string clearText, KeyMaterial64 keyMaterial64, RoundsExponent roundsExponent)
        {
            var encryptResponse = this.ixdsCryptoService.Encrypt(new Cleartext(clearText), keyMaterial64, roundsExponent, null);

            if (!encryptResponse.IsSuccess)
            {
                throw new InvalidOperationException(encryptResponse.Error);
            }
            var encodeResponse = this.ixdsCryptoService.BinaryEncodeXDSSec(encryptResponse.Result, null);

            if (!encodeResponse.IsSuccess)
            {
                throw new InvalidOperationException(encodeResponse.Error);
            }
            return(encodeResponse.Result);
        }
Exemple #5
0
        public TLSEnvelope TLSServerEncryptRequestAnonymous(byte[] clearPacket, byte[] dynamicPublicKey, long dynamicPublicKeyID)
        {
            byte[] authSecret = new byte[32]; // we cannot create an authSecret based on the client's public key when we don't know who the client is.

            // we use the dynamicPublicKey and the server private key.
            var dynamicSharedSecret = this.ixdsCryptoService.CalculateAndHashSharedSecret(this._serverPrivateKey, dynamicPublicKey);

            // the hint to the clients privk for pubkey he sent
            long privateKeyHint = dynamicPublicKeyID;

            // and now we create a dynamic public key, just to fit the protocol, but not intended for use.
            var random          = this.ixdsCryptoService.GetRandom(32).Result.X;
            var throwAwayPubKey = this.ixdsCryptoService.GenerateCurve25519KeyPairExact(random).Result.PublicKey;
            // and a fake id
            long fakeDynamicPublicKeyID = 9999; // use a realistic value, not 9999!

            Debug.WriteLine($"{this.ServerId}: TLSServerEncryptRequestAnonymous: FakeDynamicPublicKeyID: {fakeDynamicPublicKeyID}, PrivateKeyHint: {privateKeyHint}.");

            // Concatenate = 'TLSAuthMode.Dynamic' - THIS is anothe case!
            byte[] symmetricKeyMaterial64 = ByteArrays.Concatenate(dynamicSharedSecret, authSecret);

            // same as normally
            var lro        = new LongRunningOperation(progress => { }, () => { });
            var clearBytes = new Clearbytes(clearPacket);
            var sha512PW64 = new KeyMaterial64(symmetricKeyMaterial64);
            var method     = new RoundsExponent(0xff);

            var encryptResponse = this.ixdsCryptoService.BinaryEncrypt(clearBytes, sha512PW64, method, lro.Context);

            if (!encryptResponse.IsSuccess)
            {
                throw new Exception(encryptResponse.Error);
            }

            var encodeResponse = this.ixdsCryptoService.BinaryEncodeXDSSec(encryptResponse.Result, lro.Context);

            if (!encodeResponse.IsSuccess)
            {
                throw new Exception(encodeResponse.Error);
            }

            var tlsEnvelope = new TLSEnvelope(privateKeyHint, fakeDynamicPublicKeyID, throwAwayPubKey, encodeResponse.Result);

            return(tlsEnvelope);
        }
        public async Task <TLSEnvelope> EncryptRequest(byte[] clearPacket)
        {
            await this._publicMemberLock.WaitAsync();

            try
            {
                DynamicSecret dynamicSecret = GetDynamicSecretForEncryption();
                Debug.WriteLine(
                    $"{this.MyId}: TLSEncrypt: DynamicPublicKeyID: {dynamicSecret.DynamicPublicKeyId}, PrivateKeyHint: {dynamicSecret.PrivateKeyHint}.");

                byte[] authSecret = this._server.AuthSecret;

                var securable = ByteArrays.Concatenate(authSecret, this._myIdBytes, clearPacket);
                var symmetricKeyMaterial64 = ByteArrays.Concatenate(dynamicSecret.DynamicSharedSecret, new byte[32]);

                var lro           = new LongRunningOperation(progress => { }, () => { });
                var clearBytes    = new Clearbytes(securable);
                var keyMaterial64 = new KeyMaterial64(symmetricKeyMaterial64);
                var method        = new RoundsExponent(0xff);

                var encryptResponse = this._visualCrypt2Service.BinaryEncrypt(clearBytes, keyMaterial64, method, lro.Context);
                if (!encryptResponse.IsSuccess)
                {
                    throw new Exception(encryptResponse.Error);
                }

                var encodeResponse = this._visualCrypt2Service.BinaryEncodeVisualCrypt(encryptResponse.Result, lro.Context);
                if (!encodeResponse.IsSuccess)
                {
                    throw new Exception(encodeResponse.Error);
                }

                return(new TLSEnvelope(dynamicSecret.PrivateKeyHint, dynamicSecret.DynamicPublicKeyId,
                                       dynamicSecret.DynamicPublicKey, encodeResponse.Result));
            }
            finally
            {
                this._publicMemberLock.Release();
            }
        }
Exemple #7
0
        CipherV2 EncryptCommon(KeyMaterial64 keyMaterial64, RoundsExponent roundsExponent, LongRunningOperationContext context,
                               Compressed compressed)
        {
            if (context == null)
            {
                context = new LongRunningOperation(progress => { }, () => { }).Context;
            }

            if (this._log)
            {
                Debug.WriteLine("KeyMaterial64:");
                Debug.WriteLine(keyMaterial64.GetBytes().ToHexView(false));
            }

            if (this._log)
            {
                Debug.WriteLine("Compressed:");
                Debug.WriteLine(compressed.GetBytes().ToHexView(false));
            }

            PaddedData paddedData = this._internal.ApplyRandomPadding(compressed);

            if (this._log)
            {
                Debug.WriteLine("PaddedData:");
                Debug.WriteLine(paddedData.GetBytes().ToHexView(false));

                Debug.WriteLine("PlainTextPadding:");
                Debug.WriteLine(paddedData.PlaintextPadding);
            }

            IV16 iv = new IV16(this._platform.GenerateRandomBytes(16));

            if (this._log)
            {
                Debug.WriteLine("IV16:");
                Debug.WriteLine(iv.GetBytes().ToHexView(false));
            }

            InputDerivedKey32 inputDerivedKey = roundsExponent.Value == RoundsExponent.DontMakeRounds
                ? CreateDerivedKeyWithSHA256(iv, keyMaterial64)
                : CreatePasswordDerivedKeyWithBCrypt(iv, keyMaterial64, roundsExponent, context);

            if (this._log)
            {
                Debug.WriteLine("InputDerivedKey32:");
                Debug.WriteLine(inputDerivedKey.GetBytes().ToHexView(false));
            }

            RandomKey32 randomKey = new RandomKey32(this._platform.GenerateRandomBytes(32));

            if (this._log)
            {
                Debug.WriteLine("RandomKey32:");
                Debug.WriteLine(randomKey.GetBytes().ToHexView(false));
            }

            XDSSecAPIInternal.IVCache ivCache = roundsExponent.Value == RoundsExponent.DontMakeRounds
                ? null
                : this._internal.CreateIVTable(iv, roundsExponent.Value);

            var cipherV2 = new CipherV2 {
                RoundsExponent = roundsExponent, IV16 = iv
            };

            this._internal.AESEncryptRandomKeyWithInputDerivedKey(inputDerivedKey, randomKey, cipherV2, ivCache, context);
            if (this._log)
            {
                Debug.WriteLine("RandomKeyCipher32:");
                Debug.WriteLine(cipherV2.RandomKeyCipher32.GetBytes().ToHexView(false));
            }

            this._internal.AESEncryptMessageWithRandomKey(paddedData, randomKey, cipherV2, ivCache, context);
            if (this._log)
            {
                Debug.WriteLine("MessageCipher:");
                Debug.WriteLine(cipherV2.MessageCipher.GetBytes().ToHexView(false));
            }

            MAC16 mac = CreateMAC(cipherV2, context);

            if (this._log)
            {
                Debug.WriteLine("MAC16:");
                Debug.WriteLine(mac.GetBytes().ToHexView(false));
            }

            this._internal.AESEncryptMACWithRandomKey(cipherV2, mac, randomKey, ivCache, context);
            if (this._log)
            {
                Debug.WriteLine("MACCipher16:");
                Debug.WriteLine(cipherV2.MACCipher16.GetBytes().ToHexView(false));
            }
            return(cipherV2);
        }
Exemple #8
0
        public Response <CipherV2> Encrypt(Cleartext cleartext, KeyMaterial64 keyMaterial64, RoundsExponent roundsExponent,
                                           LongRunningOperationContext context)
        {
            var response = new Response <CipherV2>();

            try
            {
                Guard.NotNull(new object[] { cleartext, keyMaterial64, roundsExponent });
                EnsurePlatform();

                Compressed compressed = this._internal.Compress(cleartext);

                var cipherV2 = EncryptCommon(keyMaterial64, roundsExponent, context, compressed);

                response.Result = cipherV2;
                response.SetSuccess();
            }
            catch (Exception e)
            {
                response.SetError(e);
            }
            return(response);
        }
Exemple #9
0
        InputDerivedKey32 CreatePasswordDerivedKeyWithBCrypt(IV16 iv, KeyMaterial64 keyMaterial64, RoundsExponent roundsExponent,
                                                             LongRunningOperationContext context)
        {
            var leftSHA512  = new byte[32];
            var rightSHA512 = new byte[32];

            Buffer.BlockCopy(keyMaterial64.GetBytes(), 0, leftSHA512, 0, 32);
            Buffer.BlockCopy(keyMaterial64.GetBytes(), 32, rightSHA512, 0, 32);

            context.EncryptionProgress.Message = LocalizableStrings.MsgProcessingKey;

            // Compute the left side on a ThreadPool thread
            var task = Task.Run(() => BCrypt.CreateHash(iv, leftSHA512, roundsExponent.Value, context));

            // Compute the right side after dispatching the work for the right side
            BCrypt24 rightBCrypt = BCrypt.CreateHash(iv, rightSHA512, roundsExponent.Value, context);

            // Wait for the left side result
            task.Wait(context.CancellationToken);

            // Use the results
            var combinedHashes = ByteArrays.Concatenate(keyMaterial64.GetBytes(), task.Result.GetBytes(), rightBCrypt.GetBytes());

            Debug.Assert(combinedHashes.Length == 64 + 24 + 24);

            var condensedHash = this._platform.ComputeSHA256(combinedHashes);

            return(new InputDerivedKey32(condensedHash));
        }