Fix ReactorError during InvokeBare

This commit is contained in:
Wizou 2022-10-08 15:06:36 +02:00
parent e51ea2441e
commit e4b2cdd2c1
4 changed files with 16 additions and 8 deletions

View file

@ -67,7 +67,6 @@ Type a command, or a message to send to the active secret chat:");
} }
else if (ActiveChat == null) Console.WriteLine("No active secret chat"); else if (ActiveChat == null) Console.WriteLine("No active secret chat");
else await Secrets.SendMessage(ActiveChat, new TL.Layer73.DecryptedMessage { message = line, random_id = WTelegram.Helpers.RandomLong() }); else await Secrets.SendMessage(ActiveChat, new TL.Layer73.DecryptedMessage { message = line, random_id = WTelegram.Helpers.RandomLong() });
} }
catch (Exception ex) catch (Exception ex)
{ {

View file

@ -1247,9 +1247,12 @@ namespace WTelegram
internal async Task<T> InvokeBare<T>(IMethod<T> request) internal async Task<T> InvokeBare<T>(IMethod<T> request)
{ {
if (_bareRpc != null) throw new ApplicationException("A bare request is already undergoing"); if (_bareRpc != null) throw new ApplicationException("A bare request is already undergoing");
retry:
_bareRpc = new Rpc { type = typeof(T) }; _bareRpc = new Rpc { type = typeof(T) };
await SendAsync(request, false, _bareRpc); await SendAsync(request, false, _bareRpc);
return (T)await _bareRpc.Task; var result = await _bareRpc.Task;
if (result is ReactorError) goto retry;
return (T)result;
} }
/// <summary>Call the given TL method <i>(You shouldn't need to use this method directly)</i></summary> /// <summary>Call the given TL method <i>(You shouldn't need to use this method directly)</i></summary>

View file

@ -526,13 +526,15 @@ j4WcDuXc2CTHgH8gFTNhp/Y8/SpDOhvn9QIDAQAB
#endif #endif
} }
/// <summary>Stream for encryption/decryption of AES-256 with infinite garble extension (IGE) </summary>
public class AES_IGE_Stream : Helpers.IndirectStream public class AES_IGE_Stream : Helpers.IndirectStream
{ {
private readonly ICryptoTransform aesCrypto; private readonly ICryptoTransform aesCrypto;
private readonly byte[] prevBytes; private readonly byte[] prevBytes;
/// <summary>Decryption of AES-256 IGE file with key/iv obtained from media structure</summary>
public AES_IGE_Stream(Stream stream, DecryptedMessageMedia media) : this(stream, media.SizeKeyIV) { } public AES_IGE_Stream(Stream stream, DecryptedMessageMedia media) : this(stream, media.SizeKeyIV) { }
public AES_IGE_Stream(Stream innerStream, (int size, byte[] key, byte[] iv) t) : this(innerStream, t.key, t.iv) { ContentLength = t.size; } public AES_IGE_Stream(Stream stream, (int size, byte[] key, byte[] iv) t) : this(stream, t.key, t.iv) { ContentLength = t.size; }
public AES_IGE_Stream(Stream stream, byte[] key, byte[] iv, bool encrypt = false) : base(stream) public AES_IGE_Stream(Stream stream, byte[] key, byte[] iv, bool encrypt = false) : base(stream)
{ {
aesCrypto = encrypt ? Encryption.AesECB.CreateEncryptor(key, null) : Encryption.AesECB.CreateDecryptor(key, null); aesCrypto = encrypt ? Encryption.AesECB.CreateEncryptor(key, null) : Encryption.AesECB.CreateDecryptor(key, null);

View file

@ -264,7 +264,7 @@ namespace WTelegram
/// <param name="chatId">Secret Chat ID</param> /// <param name="chatId">Secret Chat ID</param>
/// <param name="msg">The pre-filled <see cref="TL.Layer73.DecryptedMessage">DecryptedMessage</see> or <see cref="TL.Layer17.DecryptedMessageService">DecryptedMessageService </see> to send</param> /// <param name="msg">The pre-filled <see cref="TL.Layer73.DecryptedMessage">DecryptedMessage</see> or <see cref="TL.Layer17.DecryptedMessageService">DecryptedMessageService </see> to send</param>
/// <param name="silent">Send encrypted message without a notification</param> /// <param name="silent">Send encrypted message without a notification</param>
/// <param name="file">Optional file attachment</param> /// <param name="file">Optional file attachment. See method <see cref="UploadFile">UploadFile</see></param>
/// <returns>Confirmation of sent message</returns> /// <returns>Confirmation of sent message</returns>
public async Task<Messages_SentEncryptedMessage> SendMessage(int chatId, DecryptedMessageBase msg, bool silent = false, InputEncryptedFileBase file = null) public async Task<Messages_SentEncryptedMessage> SendMessage(int chatId, DecryptedMessageBase msg, bool silent = false, InputEncryptedFileBase file = null)
{ {
@ -569,7 +569,12 @@ namespace WTelegram
} }
} }
public async Task<InputEncryptedFileBase> UploadFile(Stream stream, DecryptedMessageMedia media) /// <summary>Upload a file to Telegram in encrypted form</summary>
/// <param name="stream">Content of the file to upload. This method close/dispose the stream</param>
/// <param name="media">The associated media structure that will be updated with file size and the random AES key/iv</param>
/// <param name="progress">(optional) Callback for tracking the progression of the transfer</param>
/// <returns>the uploaded file info that should be passed to method <see cref="SendMessage">SendMessage</see></returns>
public async Task<InputEncryptedFileBase> UploadFile(Stream stream, DecryptedMessageMedia media, Client.ProgressCallback progress = null)
{ {
byte[] aes_key = new byte[32], aes_iv = new byte[32]; byte[] aes_key = new byte[32], aes_iv = new byte[32];
RNG.GetBytes(aes_key); RNG.GetBytes(aes_key);
@ -579,12 +584,11 @@ namespace WTelegram
using var md5 = MD5.Create(); using var md5 = MD5.Create();
md5.TransformBlock(aes_key, 0, 32, null, 0); md5.TransformBlock(aes_key, 0, 32, null, 0);
var res = md5.TransformFinalBlock(aes_iv, 0, 32); var res = md5.TransformFinalBlock(aes_iv, 0, 32);
var digest = md5.Hash; long fingerprint = BinaryPrimitives.ReadInt64LittleEndian(md5.Hash);
long fingerprint = BinaryPrimitives.ReadInt64LittleEndian(digest);
fingerprint ^= fingerprint >> 32; fingerprint ^= fingerprint >> 32;
using var ige = new AES_IGE_Stream(stream, aes_key, aes_iv, true); using var ige = new AES_IGE_Stream(stream, aes_key, aes_iv, true);
return await client.UploadFileAsync(ige, null) switch return await client.UploadFileAsync(ige, null, progress) switch
{ {
InputFile ifl => new InputEncryptedFileUploaded { id = ifl.id, parts = ifl.parts, md5_checksum = ifl.md5_checksum, key_fingerprint = (int)fingerprint }, InputFile ifl => new InputEncryptedFileUploaded { id = ifl.id, parts = ifl.parts, md5_checksum = ifl.md5_checksum, key_fingerprint = (int)fingerprint },
InputFileBig ifb => new InputEncryptedFileBigUploaded { id = ifb.id, parts = ifb.parts, key_fingerprint = (int)fingerprint }, InputFileBig ifb => new InputEncryptedFileBigUploaded { id = ifb.id, parts = ifb.parts, key_fingerprint = (int)fingerprint },