private void ProcessCryption() { if (IsEncrypted == CryptMethods.Unknown) { if (info?.name?.StartsWith(Config.CarotDAV_CryptNameHeader) ?? false) { IsEncrypted = CryptMethods.Method2_CBC_CarotDAV; } else if (Regex.IsMatch(info?.name ?? "", ".*?\\.[a-z0-9]{8}\\.enc$")) { IsEncrypted = CryptMethods.Method1_CTR; _DisplayName = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(info.name)); return; } else if (Regex.IsMatch(info?.name ?? "", "^[\u2800-\u28ff]+$")) { IsEncrypted = CryptMethods.Method1_CTR; var decodename = DriveData.DecryptFilename(info); if (decodename != null) { IsEncrypted = CryptMethods.Method1_CTR; _DisplayName = Path.GetFileNameWithoutExtension(decodename); return; } _DisplayName = info?.name; CryptError = true; } else { IsEncrypted = CryptMethods.Method0_Plain; } } switch (IsEncrypted) { case CryptMethods.Method0_Plain: _DisplayName = info?.name; break; case CryptMethods.Method1_CTR: if (Regex.IsMatch(info?.name ?? "", ".*?\\.[a-z0-9]{8}\\.enc$")) { _DisplayName = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(info.name)); CryptError = false; } else if (Regex.IsMatch(info?.name ?? "", "^[\u2800-\u28ff]+$")) { var decodename = DriveData.DecryptFilename(info); if (decodename != null) { _DisplayName = Path.GetFileNameWithoutExtension(decodename); CryptError = false; } else { _DisplayName = info?.name; CryptError = true; } } else { IsEncrypted = CryptMethods.Method0_Plain; _DisplayName = info?.name; } break; case CryptMethods.Method2_CBC_CarotDAV: { var decodename = CryptCarotDAV.DecryptFilename(info?.name); if (decodename != null) { _DisplayName = decodename; CryptError = false; } else { _DisplayName = info?.name; CryptError = true; } } break; } }
public async Task <Stream> downloadFile(FileMetadata_Info target, long?from = null, long?to = null, string enckey = null, bool autodecrypt = true, CancellationToken ct = default(CancellationToken)) { string id = target.id; string filename = target.name; CryptMethods Encrypted = CryptMethods.Method0_Plain; if (enckey != null) { Encrypted = CryptMethods.Method1_CTR; } else { if (filename.StartsWith(Config.CarotDAV_CryptNameHeader)) { Encrypted = CryptMethods.Method2_CBC_CarotDAV; enckey = ""; } else if (Regex.IsMatch(filename, ".*?\\.[a-z0-9]{8}\\.enc$")) { Encrypted = CryptMethods.Method1_CTR; enckey = Path.GetFileNameWithoutExtension(filename); } else if (Regex.IsMatch(filename, "^[\u2800-\u28ff]+$")) { enckey = DriveData.DecryptFilename(target); if (enckey != null) { Encrypted = CryptMethods.Method1_CTR; } } if (enckey == null) { Encrypted = CryptMethods.Method0_Plain; } } if (!autodecrypt) { Encrypted = CryptMethods.Method0_Plain; } Config.Log.LogOut("\t[downloadFile] " + id); string error_str = ""; var client = new HttpClient(); client.Timeout = TimeSpan.FromDays(1); try { long?fix_from = from, fix_to = to; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Authkey.access_token); if (from != null || to != null) { if (Encrypted == CryptMethods.Method2_CBC_CarotDAV) { if (fix_from != null) { // ひとつ前のブロックから要求する fix_from -= CryptCarotDAV.BlockSizeByte; if (fix_from < CryptCarotDAV.BlockSizeByte) { // 先頭ブロックを取得するときはファイルの先頭から fix_from = 0; } else { // ブロックにアライメントを合わせる fix_from -= ((fix_from - 1) % CryptCarotDAV.BlockSizeByte + 1); // 途中のブロックを要求された場合は、ヘッダをスキップ fix_from += CryptCarotDAV.CryptHeaderByte; } } if (fix_to != null) { if (fix_to >= target.OrignalLength) { // 末尾まで読み込むときは、ハッシュチェックのために最後まで読み込む fix_to = null; } else { // オリジナルの位置を、暗号化済みの位置に変更 fix_to += CryptCarotDAV.CryptHeaderByte; } } if (fix_from != null || fix_to != null) { client.DefaultRequestHeaders.Range = new RangeHeaderValue(fix_from, fix_to); } } else { client.DefaultRequestHeaders.Range = new RangeHeaderValue(from, to); } } string url = Config.contentUrl + "nodes/" + id + "/content?download=false"; var response = await client.GetAsync( url, HttpCompletionOption.ResponseHeadersRead, ct).ConfigureAwait(false); response.EnsureSuccessStatusCode(); if (Encrypted == CryptMethods.Method1_CTR) { return(new CryptCTR.AES256CTR_CryptStream(new ThrottleDownloadStream(new HashStream(await response.Content.ReadAsStreamAsync().ConfigureAwait(false), new MD5CryptoServiceProvider()), ct), enckey, from ?? 0)); } else if (Encrypted == CryptMethods.Method2_CBC_CarotDAV) { return(new CryptCarotDAV.CryptCarotDAV_DecryptStream(new ThrottleDownloadStream(new HashStream(await response.Content.ReadAsStreamAsync().ConfigureAwait(false), new MD5CryptoServiceProvider()), ct), from ?? 0, fix_from ?? 0, target.contentProperties?.size ?? -1 )); } else { return(new ThrottleDownloadStream(new HashStream(await response.Content.ReadAsStreamAsync().ConfigureAwait(false), new MD5CryptoServiceProvider()), ct)); } } catch (HttpRequestException ex) { error_str = ex.Message; Config.Log.LogOut("\t[downloadFile] " + error_str); throw; } catch (OperationCanceledException) { throw; } catch (Exception ex) { error_str = ex.ToString(); Config.Log.LogOut("\t[downloadFile] " + error_str); throw; } throw new SystemException("fileDownload failed. " + error_str); }