예제 #1
0
        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;
            }
        }
예제 #2
0
        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);
        }