// Decompiled with JetBrains decompiler // Type: Rei.Fs.EncryptFs // Assembly: Rei.Fs, Version=1.13.2.8796, Culture=neutral, PublicKeyToken=null // MVID: D8B08A8B-697C-4439-9CFF-1BE4EE46F7B0 // Assembly location: F:\Eigene Dateien\Dropbox\portable Collection\Progs\CarotDAV\Rei.Fs.dll using Microsoft.VisualBasic.CompilerServices; using System; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Security.Cryptography; using System.Text; namespace Rei.Fs { public class EncryptFs : FsBase { private static string pVersionName = "1"; private static byte[] pSalt; private static string pName; private FsBase basefs; private string EscapeString; private string EncryptKey; private bool HideUnencryptedFile; private bool HideUnencryptedDirectory; private Rijndael crypto_none; private Rijndael crypto_zero; private const string FormatName = "CarotDAV Encryption 1.0 "; static EncryptFs() { Assembly executingAssembly = Assembly.GetExecutingAssembly(); EncryptFs.pName = ((AssemblyProductAttribute) executingAssembly.GetCustomAttributes(typeof (AssemblyProductAttribute), false)[0]).Product + executingAssembly.GetName().Version.ToString(3); } public EncryptFs(FsBase @base, string key, string escape, bool hidefile, bool hidedir) : base(@base.ConnectionSetting) { this.basefs = @base; this.EncryptKey = key; this.EscapeString = escape; this.HideUnencryptedFile = hidefile; this.HideUnencryptedDirectory = hidedir; this.crypto_none = Rijndael.Create(); this.crypto_none.Mode = CipherMode.CBC; this.crypto_none.Padding = PaddingMode.None; this.crypto_none.BlockSize = 128; this.crypto_none.KeySize = 256; this.crypto_zero = Rijndael.Create(); this.crypto_zero.Mode = CipherMode.CBC; this.crypto_zero.Padding = PaddingMode.Zeros; this.crypto_zero.BlockSize = 128; this.crypto_zero.KeySize = 256; Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(this.EncryptKey, Encoding.UTF8.GetBytes("CarotDAV Encryption 1.0 "), 1024); this.crypto_none.Key = rfc2898DeriveBytes.GetBytes(checked ((int) Math.Round(unchecked ((double) this.crypto_none.KeySize / 8.0)))); this.crypto_none.IV = rfc2898DeriveBytes.GetBytes(checked ((int) Math.Round(unchecked ((double) this.crypto_none.BlockSize / 8.0)))); this.crypto_zero.Key = this.crypto_none.Key; this.crypto_zero.IV = this.crypto_none.IV; this.basefs.LogMessage += new EventHandler(this.InnerOnLogMessage); } private void InnerOnLogMessage(object sender, LogMessageEventArgs e) { this.OnLogMessage(e.Message); } public override SecureType LastSecureType { get { return this.basefs.LastSecureType; } } public override string ClientName { get { return this.basefs.ClientName; } set { this.basefs.ClientName = value; } } public override string GroupName { get { return this.basefs.GroupName; } set { this.basefs.GroupName = value; } } public override string UserName { get { return this.basefs.UserName; } } public override string Password { get { return this.basefs.Password; } } public override FsAbility Ability { get { return this.basefs.Ability & ~(FsAbility.PartialRead | FsAbility.PartialWrite); } } public override void ResetConnection() { this.basefs.ResetConnection(); base.ResetConnection(); } public override ResourceInfo GetInfo(Uri targeturi) { string[] segments1 = this.BaseUri.Segments; string[] segments2 = targeturi.Segments; List resourceInfoList = new List(); Uri uri1 = new Uri(this.BaseUri.GetComponents(UriComponents.SchemeAndServer, UriFormat.UriEscaped) + "/"); Uri uri2 = uri1; bool encrypted = false; int index1 = 1; while (index1 < segments1.Length && index1 < segments2.Length && UriUtil.IsSameSegmentString(segments1[index1], segments2[index1])) { uri2 = UriUtil.CombineSegment(uri2, segments2[index1]); uri1 = UriUtil.CombineSegment(uri1, segments2[index1]); encrypted = false; checked { ++index1; } } int index2 = index1; while (index1 < segments2.Length) { string name = Uri.UnescapeDataString(segments2[index1]).Replace("/", ""); uri2 = UriUtil.CombineName(uri2, this.EncryptName(name)); encrypted = true; checked { ++index1; } } try { ResourceInfo info = this.basefs.GetInfo(uri2); this.CreateInfo2(targeturi, info, encrypted); return info; } catch (RemoteResourceNotFoundException ex) { ProjectData.SetProjectError((Exception) ex); ProjectData.ClearProjectError(); } catch (Exception ex) { ProjectData.SetProjectError(ex); throw; } if (this.HideUnencryptedDirectory) throw new RemoteResourceNotFoundException(targeturi); ResourceInfo[] infoAndEntries = this.basefs.GetInfoAndEntries(uri1); this.CreateInfo2(uri1, infoAndEntries[0], false); int num1 = 1; int num2 = checked (infoAndEntries.Length - 1); int index3 = num1; while (index3 <= num2) { if (this.CreateInfo(infoAndEntries[0].Id.Uri, infoAndEntries[index3])) resourceInfoList.Add(infoAndEntries[index3]); checked { ++index3; } } label_16: string Right = Uri.UnescapeDataString(segments2[index2]); int num3 = 0; int num4 = checked (resourceInfoList.Count - 1); int index4 = num3; while (index4 <= num4) { string lastName = UriUtil.GetLastName(resourceInfoList[index4].Id.Uri); if (Operators.CompareString(lastName, Right, false) == 0 || Operators.CompareString(lastName + "/", Right, false) == 0 || Operators.CompareString(lastName, Right + "/", false) == 0) { checked { ++index2; } ResourceInfo resourceInfo = resourceInfoList[index4]; if (index2 == segments2.Length) return resourceInfo; if (!resourceInfo.IsCollection) throw new RemoteResourceNotFoundException(targeturi); resourceInfoList.Clear(); resourceInfoList.AddRange((IEnumerable) this.GetEntries(resourceInfo.Id)); Uri.UnescapeDataString(segments2[index2]); goto label_16; } else checked { ++index4; } } throw new RemoteResourceNotFoundException(targeturi); } public override ResourceInfo GetInfo(ResourceId id) { EncryptFs.EncryptId encryptId = (EncryptFs.EncryptId) id; ResourceInfo info = this.basefs.GetInfo(encryptId.BaseId); if (this.CreateInfo(UriUtil.GetParent(encryptId.Uri), info)) return info; throw new RemoteResourceNotFoundException(id.Uri); } public override ResourceInfo GetInfo(ResourceId parentid, string name) { EncryptFs.EncryptId encryptId = (EncryptFs.EncryptId) parentid; string name1 = this.EncryptName(name); try { ResourceInfo info = this.basefs.GetInfo(encryptId.BaseId, name1); if (this.CreateInfo(encryptId.Uri, info)) return info; } catch (RemoteResourceNotFoundException ex) { ProjectData.SetProjectError((Exception) ex); ProjectData.ClearProjectError(); } catch (Exception ex) { ProjectData.SetProjectError(ex); throw; } ResourceInfo info1 = this.basefs.GetInfo(encryptId.BaseId, name); this.CreateInfo2(UriUtil.CombineName(encryptId.Uri, name), info1, false); return info1; } public override ResourceInfo GetParentInfo(ResourceId id) { EncryptFs.EncryptId encryptId = (EncryptFs.EncryptId) id; ResourceInfo parentInfo = this.basefs.GetParentInfo(encryptId.BaseId); if (this.CreateInfo(UriUtil.GetParent(UriUtil.GetParent(encryptId.Uri)), parentInfo)) return parentInfo; throw new RemoteResourceNotFoundException(id.Uri); } public override ResourceInfo[] GetEntries(ResourceId id) { EncryptFs.EncryptId encryptId = (EncryptFs.EncryptId) id; ResourceInfo[] entries = this.basefs.GetEntries(encryptId.BaseId); List resourceInfoList = new List(); int num1 = 0; int num2 = checked (entries.Length - 1); int index = num1; while (index <= num2) { if (this.CreateInfo(encryptId.Uri, entries[index])) resourceInfoList.Add(entries[index]); checked { ++index; } } return resourceInfoList.ToArray(); } public override ResourceInfo[] GetInfoAndEntries(Uri targeturi) { string[] segments1 = this.BaseUri.Segments; string[] segments2 = targeturi.Segments; List resourceInfoList = new List(); Uri uri1 = new Uri(this.BaseUri.GetComponents(UriComponents.SchemeAndServer, UriFormat.UriEscaped) + "/"); Uri uri2 = uri1; bool encrypted = false; int index1 = 1; while (index1 < segments1.Length && index1 < segments2.Length && UriUtil.IsSameSegmentString(segments1[index1], segments2[index1])) { uri2 = UriUtil.CombineSegment(uri2, segments2[index1]); uri1 = UriUtil.CombineSegment(uri1, segments2[index1]); encrypted = false; checked { ++index1; } } int index2 = index1; while (index1 < segments2.Length) { string name = Uri.UnescapeDataString(segments2[index1]).Replace("/", ""); uri2 = UriUtil.CombineName(uri2, this.EncryptName(name)); encrypted = true; checked { ++index1; } } try { ResourceInfo[] infoAndEntries = this.basefs.GetInfoAndEntries(uri2); this.CreateInfo2(targeturi, infoAndEntries[0], encrypted); resourceInfoList.Add(infoAndEntries[0]); int num1 = 1; int num2 = checked (infoAndEntries.Length - 1); int index3 = num1; while (index3 <= num2) { if (this.CreateInfo(infoAndEntries[0].Id.Uri, infoAndEntries[index3])) resourceInfoList.Add(infoAndEntries[index3]); checked { ++index3; } } return resourceInfoList.ToArray(); } catch (RemoteResourceNotFoundException ex) { ProjectData.SetProjectError((Exception) ex); ProjectData.ClearProjectError(); } if (this.HideUnencryptedDirectory) throw new RemoteResourceNotFoundException(targeturi); ResourceInfo[] infoAndEntries1 = this.basefs.GetInfoAndEntries(uri1); this.CreateInfo2(uri1, infoAndEntries1[0], false); int num3 = 1; int num4 = checked (infoAndEntries1.Length - 1); int index4 = num3; while (index4 <= num4) { if (this.CreateInfo(infoAndEntries1[0].Id.Uri, infoAndEntries1[index4])) resourceInfoList.Add(infoAndEntries1[index4]); checked { ++index4; } } label_20: string Right = Uri.UnescapeDataString(segments2[index2]); int num5 = 0; int num6 = checked (resourceInfoList.Count - 1); int index5 = num5; while (index5 <= num6) { string lastName = UriUtil.GetLastName(resourceInfoList[index5].Id.Uri); if (Operators.CompareString(lastName, Right, false) == 0 || Operators.CompareString(lastName + "/", Right, false) == 0 || Operators.CompareString(lastName, Right + "/", false) == 0) { checked { ++index2; } ResourceInfo resourceInfo = resourceInfoList[index5]; if (index2 != segments2.Length) { if (!resourceInfo.IsCollection) throw new RemoteResourceNotFoundException(targeturi); resourceInfoList.Clear(); resourceInfoList.AddRange((IEnumerable) this.GetEntries(resourceInfo.Id)); Uri.UnescapeDataString(segments2[index2]); goto label_20; } else { if (resourceInfo.IsCollection) { resourceInfoList.Clear(); resourceInfoList.Add(resourceInfo); resourceInfoList.AddRange((IEnumerable) this.GetEntries(resourceInfo.Id)); return resourceInfoList.ToArray(); } return new ResourceInfo[1]{ resourceInfo }; } } else checked { ++index5; } } throw new RemoteResourceNotFoundException(targeturi); } public override ResourceInfo[] GetInfoAndEntries(ResourceId id) { EncryptFs.EncryptId encryptId = (EncryptFs.EncryptId) id; ResourceInfo[] infoAndEntries = this.basefs.GetInfoAndEntries(encryptId.BaseId); if (!this.CreateInfo(UriUtil.GetParent(encryptId.Uri), infoAndEntries[0])) throw new RemoteResourceNotFoundException(encryptId.Uri); List resourceInfoList = new List(); resourceInfoList.Add(infoAndEntries[0]); int num1 = 1; int num2 = checked (infoAndEntries.Length - 1); int index = num1; while (index <= num2) { if (this.CreateInfo(infoAndEntries[0].Id.Uri, infoAndEntries[index])) resourceInfoList.Add(infoAndEntries[index]); checked { ++index; } } return resourceInfoList.ToArray(); } public override ResourceInfo[] GetParentInfoAndEntries(ResourceId childid) { EncryptFs.EncryptId encryptId = (EncryptFs.EncryptId) childid; ResourceInfo[] parentInfoAndEntries = this.basefs.GetParentInfoAndEntries(encryptId.BaseId); Uri parent = UriUtil.GetParent(encryptId.Uri); if (!this.CreateInfo(UriUtil.GetParent(parent), parentInfoAndEntries[0])) throw new RemoteResourceNotFoundException(parent); List resourceInfoList = new List(); resourceInfoList.Add(parentInfoAndEntries[0]); int num1 = 1; int num2 = checked (parentInfoAndEntries.Length - 1); int index = num1; while (index <= num2) { if (this.CreateInfo(parentInfoAndEntries[0].Id.Uri, parentInfoAndEntries[index])) resourceInfoList.Add(parentInfoAndEntries[index]); checked { ++index; } } return resourceInfoList.ToArray(); } public override ReturnedInfo CreateCollection(ResourceId parentid, string name) { EncryptFs.EncryptId encryptId = (EncryptFs.EncryptId) parentid; string name1 = this.EncryptName(name); ReturnedInfo collection = this.basefs.CreateCollection(encryptId.BaseId, name1); ResourceId baseid = !(collection is ResourceInfo) ? (ResourceId) collection : ((ResourceInfo) collection).Id; return (ReturnedInfo) new EncryptFs.EncryptId(UriUtil.AddLastSlash(UriUtil.CombineName(encryptId.Uri, name)), baseid, true, this); } public override void Delete(ResourceId id) { EncryptFs.EncryptId encryptId = (EncryptFs.EncryptId) id; if (!encryptId.Encrypted && (!encryptId.IsCollection || this.HideUnencryptedDirectory) && (encryptId.IsCollection || this.HideUnencryptedFile)) throw new Exception(); this.basefs.Delete(encryptId.BaseId); } public override ReturnedInfo Move(ResourceId id, ResourceId newparentid, string newname, bool overwrite) { EncryptFs.EncryptId encryptId = (EncryptFs.EncryptId) id; ReturnedInfo returnedInfo; Uri target; if (newname == null) { ResourceId baseId = ((EncryptFs.EncryptId) newparentid).BaseId; returnedInfo = this.basefs.Move(encryptId.BaseId, baseId, (string) null, overwrite); target = UriUtil.CombineName(newparentid.Uri, UriUtil.GetLastName(encryptId.Uri)); } else if ((object) newparentid == null) { string newname1 = !encryptId.Encrypted ? newname : this.EncryptName(newname); returnedInfo = this.basefs.Move(encryptId.BaseId, (ResourceId) null, newname1, overwrite); target = UriUtil.CombineName(UriUtil.GetParent(encryptId.Uri), newname); } else { ResourceId baseId = ((EncryptFs.EncryptId) newparentid).BaseId; string newname1 = !encryptId.Encrypted ? newname : this.EncryptName(newname); returnedInfo = this.basefs.Move(encryptId.BaseId, baseId, newname1, overwrite); target = UriUtil.CombineName(newparentid.Uri, newname); } ResourceId baseid = !(returnedInfo is ResourceInfo) ? (ResourceId) returnedInfo : ((ResourceInfo) returnedInfo).Id; if (encryptId.IsCollection) target = UriUtil.AddLastSlash(target); return (ReturnedInfo) new EncryptFs.EncryptId(target, baseid, encryptId.Encrypted, this); } public override ReturnedInfo Copy(ResourceId id, ResourceId newparentid, string newname, bool overwrite) { EncryptFs.EncryptId encryptId = (EncryptFs.EncryptId) id; ReturnedInfo returnedInfo; Uri target; if (newname == null) { ResourceId baseId = ((EncryptFs.EncryptId) newparentid).BaseId; returnedInfo = this.basefs.Copy(encryptId.BaseId, baseId, (string) null, overwrite); target = UriUtil.CombineName(newparentid.Uri, UriUtil.GetLastName(encryptId.Uri)); } else if ((object) newparentid == null) { string newname1 = !encryptId.Encrypted ? newname : this.EncryptName(newname); returnedInfo = this.basefs.Copy(encryptId.BaseId, (ResourceId) null, newname1, overwrite); target = UriUtil.CombineName(UriUtil.GetParent(encryptId.Uri), newname); } else { ResourceId baseId = ((EncryptFs.EncryptId) newparentid).BaseId; string newname1 = !encryptId.Encrypted ? newname : this.EncryptName(newname); returnedInfo = this.basefs.Copy(encryptId.BaseId, baseId, newname1, overwrite); target = UriUtil.CombineName(newparentid.Uri, newname); } ResourceId baseid = !(returnedInfo is ResourceInfo) ? (ResourceId) returnedInfo : ((ResourceInfo) returnedInfo).Id; if (encryptId.IsCollection) target = UriUtil.AddLastSlash(target); return (ReturnedInfo) new EncryptFs.EncryptId(target, baseid, encryptId.Encrypted, this); } public override ReturnedInfo SetResourceInfo(ResourceInfo info, ResourceInfo original) { EncryptFs.EncryptId id = (EncryptFs.EncryptId) info.Id; ResourceInfo info1 = (ResourceInfo) info.Clone(); ResourceInfo original1 = (ResourceInfo) original.Clone(); info1.Id = ((EncryptFs.EncryptId) info.Id).BaseId; original1.Id = info1.Id; if (id.Encrypted || id.IsCollection && !this.HideUnencryptedDirectory || !id.IsCollection && !this.HideUnencryptedFile) return this.basefs.SetResourceInfo(info1, original1); throw new Exception(); } public override ReturnedInfo SetTimes(ResourceId id, DateTime lastmodifiedtime, DateTime creationtime, DateTime lastaccesstime) { EncryptFs.EncryptId encryptId = id as EncryptFs.EncryptId; if (encryptId.Encrypted || encryptId.IsCollection && !this.HideUnencryptedDirectory || !encryptId.IsCollection && !this.HideUnencryptedFile) return this.basefs.SetTimes(encryptId.BaseId, lastmodifiedtime, creationtime, lastaccesstime); throw new Exception(); } public override Stream OpenRead(ResourceId id, ref long start, ref long length) { EncryptFs.EncryptId encryptId = (EncryptFs.EncryptId) id; if (start < 0L) throw new ArgumentOutOfRangeException(nameof (start)); if (length == 0L) throw new ArgumentOutOfRangeException(nameof (length)); if (encryptId.Encrypted) { FsBase basefs = this.basefs; ResourceId baseId = encryptId.BaseId; long start1 = 0; long length1 = -1; Stream basestream = basefs.OpenRead(baseId, ref start1, ref length1); start = 0L; length = -1L; return (Stream) new EncryptFs.CarotCryptStream(this, (ResourceId) encryptId, basestream, this.crypto_none.CreateDecryptor(), length); } if (encryptId.IsCollection && !this.HideUnencryptedDirectory || !encryptId.IsCollection && !this.HideUnencryptedFile) return this.basefs.OpenRead(encryptId.BaseId, ref start, ref length); throw new Exception(); } public override Stream OpenWrite(ResourceId parentid, string name, long length) { EncryptFs.EncryptId encryptId = (EncryptFs.EncryptId) parentid; string name1 = this.EncryptName(name); Stream basestream = length < 0L ? this.basefs.OpenWrite(encryptId.BaseId, name1, -1L) : this.basefs.OpenWrite(encryptId.BaseId, name1, checked (length + 144L)); return (Stream) new EncryptFs.CarotCryptStream(this, UriUtil.CombineName(encryptId.Uri, name), basestream, this.crypto_zero.CreateEncryptor(), length); } public override Stream OpenWriteOver(ResourceId id, long length) { EncryptFs.EncryptId encryptId = (EncryptFs.EncryptId) id; Stream basestream = length < 0L ? this.basefs.OpenWriteOver(encryptId.BaseId, -1L) : this.basefs.OpenWriteOver(encryptId.BaseId, checked (length + 144L)); return (Stream) new EncryptFs.CarotCryptStream(this, encryptId.Uri, basestream, this.crypto_zero.CreateEncryptor(), length); } public override Stream OpenWriteResume(ResourceId id, ref long start, ref long length) { throw new NotSupportedException(); } public override ReturnedInfo CloseWrite(Stream st) { st.Close(); return ((EncryptFs.CarotCryptStream) st).ReturnedInfo; } public override string GetLock(ResourceId id, string owner, int timeoutseconds, FsBase.LockScope scope) { return this.basefs.GetLock(((EncryptFs.EncryptId) id).BaseId, owner, timeoutseconds, scope); } public override void ReleaseLock(ResourceId id, string locktoken) { this.basefs.ReleaseLock(id, locktoken); } private string EncryptName(string name) { byte[] numArray; using (ICryptoTransform encryptor = this.crypto_none.CreateEncryptor()) { byte[] bytes = Encoding.UTF8.GetBytes(name); byte[] inputBuffer = new byte[16]; if (bytes.Length <= 16) { numArray = new byte[16]; Array.Copy((Array) bytes, (Array) inputBuffer, bytes.Length); encryptor.TransformBlock(inputBuffer, 0, 16, numArray, 0); } else { numArray = new byte[checked (bytes.Length - 1 + 1)]; int num1 = 0; int num2 = checked (bytes.Length - 1 - 32); int num3 = num1; while (num3 <= num2) { encryptor.TransformBlock(bytes, num3, 16, numArray, num3); checked { num3 += 16; } } encryptor.TransformBlock(bytes, num3, 16, numArray, num3); Array.Copy((Array) numArray, num3, (Array) numArray, checked (num3 + 16), checked (bytes.Length - num3 + 16)); Array.Copy((Array) bytes, checked (num3 + 16), (Array) inputBuffer, 0, checked (bytes.Length - num3 + 16)); encryptor.TransformBlock(inputBuffer, 0, 16, numArray, num3); } } return this.EscapeString + Convert.ToBase64String(numArray).Replace('/', '-').Replace('+', '_').Replace("=", ""); } private bool TryDecryptName(string name, ref string decrypted) { if (!name.StartsWith(this.EscapeString)) return false; name = name.Substring(this.EscapeString.Length).Replace("-", "/").Replace('_', '+').Replace(" ", ""); if (name.Length % 4 != 0) name += new string('=', checked (4 - unchecked (name.Length % 4))); byte[] inputBuffer; bool flag; try { inputBuffer = Convert.FromBase64String(name); } catch (Exception ex) { ProjectData.SetProjectError(ex); flag = false; ProjectData.ClearProjectError(); goto label_22; } byte[] numArray1 = new byte[checked (inputBuffer.Length - 1 + 1)]; using (ICryptoTransform decryptor1 = this.crypto_none.CreateDecryptor()) { byte[] numArray2 = new byte[16]; byte[] outputBuffer = new byte[16]; if (inputBuffer.Length <= 16) { numArray1 = new byte[16]; Array.Copy((Array) inputBuffer, (Array) numArray2, inputBuffer.Length); decryptor1.TransformBlock(numArray2, 0, 16, numArray1, 0); } else { int num1 = 0; int num2 = checked (inputBuffer.Length - 1 - 32); int num3 = num1; while (num3 <= num2) { decryptor1.TransformBlock(inputBuffer, num3, 16, numArray1, num3); checked { num3 += 16; } } Array.Copy((Array) inputBuffer, checked (num3 + 16), (Array) numArray2, 0, checked (inputBuffer.Length - num3 + 16)); using (ICryptoTransform decryptor2 = this.crypto_none.CreateDecryptor(this.crypto_none.Key, numArray2)) decryptor2.TransformBlock(inputBuffer, num3, 16, outputBuffer, 0); Array.Copy((Array) outputBuffer, checked (inputBuffer.Length - num3 + 16), (Array) numArray2, checked (inputBuffer.Length - num3 + 16), checked (num3 + 32 - inputBuffer.Length)); decryptor1.TransformBlock(numArray2, 0, 16, numArray1, num3); Array.Copy((Array) outputBuffer, 0, (Array) numArray1, checked (num3 + 16), checked (inputBuffer.Length - num3 + 16)); } } decrypted = Encoding.UTF8.GetString(numArray1).Replace("\0", ""); return true; label_22: return flag; } private bool CreateInfo(Uri parenturi, ResourceInfo ri) { string decrypted = (string) null; if (this.TryDecryptName(UriUtil.GetLastName(ri.Id.Uri), ref decrypted)) { Uri target = UriUtil.CombineName(parenturi, decrypted); if (ri.IsCollection) target = UriUtil.AddLastSlash(target); else if (ri.Size < 144L) { ri.Size = 0L; ri.StatusDescription = "Invalid Encrypted File (too small)"; ri.HasError = true; } else ri.Size = checked (ri.Size - 144L); ri.IsEncrypted = true; ri.Id = (ResourceId) new EncryptFs.EncryptId(target, ri.Id, true, this); return true; } if (!ri.IsCollection && this.HideUnencryptedFile) return false; if (ri.IsCollection && this.HideUnencryptedDirectory) { Uri uri = UriUtil.CombineName(parenturi, UriUtil.GetLastName(ri.Id.Uri)); if (uri.Segments.Length > this.BaseUri.Segments.Length) return false; int num1 = 1; int num2 = checked (uri.Segments.Length - 1); int index = num1; while (index <= num2) { if (!UriUtil.IsSameSegmentString(this.BaseUri.Segments[index], uri.Segments[index])) return false; checked { ++index; } } } Uri target1 = UriUtil.CombineName(parenturi, UriUtil.GetLastName(ri.Id.Uri)); if (ri.IsCollection) target1 = UriUtil.AddLastSlash(target1); ri.IsEncrypted = false; ri.Id = (ResourceId) new EncryptFs.EncryptId(target1, ri.Id, false, this); return true; } protected void CreateInfo2(Uri target, ResourceInfo ri, bool encrypted) { if (ri.IsCollection) { target = UriUtil.AddLastSlash(target); } else { target = UriUtil.RemoveLastSlash(target); if (encrypted) { if (ri.Size < 144L) { ri.Size = 0L; ri.StatusDescription = "Invalid Encrypted File (too small)"; ri.HasError = true; } else ri.Size = checked (ri.Size - 144L); } } ri.IsEncrypted = encrypted; ri.Id = (ResourceId) new EncryptFs.EncryptId(target, ri.Id, encrypted, this); } private class CarotCryptStream : Stream { private EncryptFs pFs; private ReturnedInfo pReturnedInfo; private Uri pUri; private Stream pStream; private ICryptoTransform pTransform; private CryptoStreamMode pMode; private SHA256Managed pSha; private long pLength; private long pPosition; private byte[] pReadBuf; private byte[] pDecryptBuf; public CarotCryptStream(EncryptFs fs, Uri uri, Stream basestream, ICryptoTransform transformer, long length) { this.pFs = fs; this.pUri = uri; this.pTransform = transformer; this.pMode = CryptoStreamMode.Write; this.pSha = new SHA256Managed(); this.pLength = length; this.pPosition = 0L; byte[] buffer = new byte[64]; Encoding.UTF8.GetBytes("CarotDAV Encryption 1.0 ").CopyTo((Array) buffer, 0); basestream.Write(buffer, 0, buffer.Length); CloseNotifyStream closeNotifyStream = new CloseNotifyStream(basestream); closeNotifyStream.ClosingEvent += new EventHandler(this.Stream_Closing); closeNotifyStream.ClosedEvent += new EventHandler(this.Stream_Closed); this.pStream = (Stream) new CryptoStream((Stream) closeNotifyStream, this.pTransform, this.pMode); } public CarotCryptStream(EncryptFs fs, ResourceId id, Stream basestream, ICryptoTransform transformer, long length) { this.pFs = fs; this.pReturnedInfo = (ReturnedInfo) id; this.pTransform = transformer; this.pMode = CryptoStreamMode.Read; this.pSha = new SHA256Managed(); this.pLength = length; this.pPosition = 0L; this.pStream = basestream; byte[] numArray = new byte[144]; int offset = 0; while (offset < numArray.Length) { int num = this.pStream.Read(numArray, offset, checked (numArray.Length - offset)); if (num == 0) throw new InconsistencyDetectedException(this.pUri, "Encrypted file broken"); checked { offset += num; } } if (Operators.CompareString(Encoding.UTF8.GetString(numArray, 0, 24), "CarotDAV Encryption 1.0 ", false) != 0) throw new InconsistencyDetectedException(this.pUri, "Encrypted file broken"); this.pReadBuf = new byte[80]; Array.Copy((Array) numArray, 64, (Array) this.pReadBuf, 0, this.pReadBuf.Length); this.pDecryptBuf = new byte[0]; } public ReturnedInfo ReturnedInfo { get { return this.pReturnedInfo; } } public override bool CanRead { get { return this.pMode == CryptoStreamMode.Read; } } public override bool CanWrite { get { return this.pMode == CryptoStreamMode.Write; } } public override bool CanSeek { get { return false; } } public override void Flush() { this.pStream.Flush(); } public override long Length { get { return this.pLength; } } public override long Position { get { return this.pPosition; } set { throw new NotImplementedException(); } } public override long Seek(long offset, SeekOrigin origin) { throw new NotImplementedException(); } public override void SetLength(long value) { throw new NotImplementedException(); } public override int Read(byte[] buffer, int offset, int count) { if (this.pMode != CryptoStreamMode.Read) throw new InvalidOperationException(); if (this.pStream == null) throw new ObjectDisposedException(this.GetType().FullName); if (this.pLength >= 0L && checked (this.pPosition + (long) count) > this.pLength) count = checked ((int) (this.pLength - this.pPosition)); if (count < 0) throw new ArgumentOutOfRangeException(nameof (count)); if (count == 0) return 0; int num1 = 0; label_11: int num2 = count; if (num2 > this.pDecryptBuf.Length) num2 = this.pDecryptBuf.Length; Array.Copy((Array) this.pDecryptBuf, 0, (Array) buffer, offset, num2); checked { count -= num2; } checked { offset += num2; } checked { num1 += num2; } this.pPosition = checked (this.pPosition + (long) num2); byte[] numArray1 = new byte[checked (this.pDecryptBuf.Length - num2 - 1 + 1)]; Array.Copy((Array) this.pDecryptBuf, num2, (Array) numArray1, 0, checked (this.pDecryptBuf.Length - num2)); this.pDecryptBuf = numArray1; if (count == 0) return num1; int num3 = checked (count + 15) & -16; byte[] numArray2 = new byte[checked (num3 - 1 + 1)]; int num4 = 0; while (num4 < numArray2.Length) { int num5 = this.pStream.Read(numArray2, num4, checked (numArray2.Length - num4)); if (num5 == 0) { byte[] inputBuffer = new byte[checked (this.pReadBuf.Length + num4 - 1 + 1)]; Array.Copy((Array) this.pReadBuf, 0, (Array) inputBuffer, 0, this.pReadBuf.Length); Array.Copy((Array) numArray2, 0, (Array) inputBuffer, this.pReadBuf.Length, num4); byte[] numArray3 = new byte[64]; Array.Copy((Array) inputBuffer, checked (inputBuffer.Length - numArray3.Length), (Array) numArray3, 0, numArray3.Length); byte[] numArray4 = this.pTransform.TransformFinalBlock(inputBuffer, 0, checked (num4 + 15) & -16); this.pDecryptBuf = new byte[checked (num4 - 1 + 1)]; Array.Copy((Array) numArray4, 0, (Array) this.pDecryptBuf, 0, this.pDecryptBuf.Length); this.pSha.TransformFinalBlock(this.pDecryptBuf, 0, this.pDecryptBuf.Length); string s = ""; int num6 = 0; int num7 = checked (this.pSha.Hash.Length - 1); int index1 = num6; while (index1 <= num7) { s += this.pSha.Hash[index1].ToString("X2"); checked { ++index1; } } byte[] bytes = Encoding.UTF8.GetBytes(s); if (bytes.Length != numArray3.Length) throw new IOException("File hash doesn't match."); int num8 = 0; int num9 = checked (bytes.Length - 1); int index2 = num8; while (index2 <= num9) { if ((int) bytes[index2] != (int) numArray3[index2]) throw new IOException("File hash doesn't match."); checked { ++index2; } } if (this.pLength < 0L) this.pLength = checked (this.pPosition + (long) num4); else if (this.pLength > checked (this.pPosition + (long) num4)) throw new InvalidRangeException(); if (count > num4) { count = num4; goto label_11; } else goto label_11; } else checked { num4 += num5; } } byte[] numArray5 = new byte[checked (num3 - 1 + 1)]; if (num3 < this.pReadBuf.Length) { numArray5 = new byte[checked (num3 - 1 + 1)]; this.pTransform.TransformBlock(this.pReadBuf, 0, num3, numArray5, 0); Array.Copy((Array) this.pReadBuf, num3, (Array) this.pReadBuf, 0, checked (this.pReadBuf.Length - num3)); Array.Copy((Array) numArray2, 0, (Array) this.pReadBuf, checked (this.pReadBuf.Length - num3), num3); } else { this.pTransform.TransformBlock(this.pReadBuf, 0, this.pReadBuf.Length, numArray5, 0); this.pTransform.TransformBlock(numArray2, 0, checked (numArray2.Length - this.pReadBuf.Length), numArray5, this.pReadBuf.Length); Array.Copy((Array) numArray2, checked (numArray2.Length - this.pReadBuf.Length), (Array) this.pReadBuf, 0, this.pReadBuf.Length); } this.pSha.TransformBlock(numArray5, 0, numArray2.Length, (byte[]) null, 0); Array.Copy((Array) numArray5, 0, (Array) buffer, offset, count); this.pPosition = checked (this.pPosition + (long) count); int num10 = checked (num1 + count); this.pDecryptBuf = new byte[checked (num3 - count - 1 + 1)]; Array.Copy((Array) numArray5, count, (Array) this.pDecryptBuf, 0, this.pDecryptBuf.Length); return num10; } public override void Write(byte[] buffer, int offset, int count) { if (this.pStream == null) throw new ObjectDisposedException(this.GetType().FullName); if (this.pMode != CryptoStreamMode.Write) throw new InvalidOperationException(); if (this.pLength >= 0L && checked (this.pPosition + (long) count) > this.pLength) throw new InvalidRangeException(); if (count == 0) return; this.pSha.TransformBlock(buffer, offset, count, (byte[]) null, 0); this.pStream.Write(buffer, offset, count); this.pPosition = checked (this.pPosition + (long) count); } protected override void Dispose(bool disposing) { try { if (!disposing) return; switch (this.pMode) { case CryptoStreamMode.Read: if (this.pStream == null) break; this.pStream.Close(); this.pStream = (Stream) null; break; case CryptoStreamMode.Write: if (this.pStream == null) break; this.pStream.Close(); this.pStream = (Stream) null; break; default: throw new Exception(); } } finally { base.Dispose(disposing); } } private void Stream_Closing(object sender, EventArgs e) { if (this.pMode != CryptoStreamMode.Write) throw new InvalidOperationException(); CloseNotifyStream closeNotifyStream = (CloseNotifyStream) sender; int num1 = checked ((int) unchecked (this.pPosition % (long) this.pTransform.OutputBlockSize)); if (num1 == 0) num1 = 16; byte[] buffer = new byte[checked (num1 - 1 + 1)]; closeNotifyStream.Write(buffer, 0, buffer.Length); this.pSha.TransformFinalBlock(new byte[0], 0, 0); string s = ""; int num2 = 0; int num3 = checked (this.pSha.Hash.Length - 1); int index = num2; while (index <= num3) { s += this.pSha.Hash[index].ToString("X2"); checked { ++index; } } byte[] bytes = Encoding.UTF8.GetBytes(s); if (bytes.Length != 64) throw new IOException(); closeNotifyStream.Write(bytes, 0, bytes.Length); } private void Stream_Closed(object sender, EventArgs e) { if (this.pMode != CryptoStreamMode.Write) throw new InvalidOperationException(); ReturnedInfo returnedInfo = this.pFs.basefs.CloseWrite(((CloseNotifyStream) sender).BaseStream); ResourceInfo ri = returnedInfo as ResourceInfo; if (ri != null) { this.pFs.CreateInfo2(this.pUri, ri, true); this.pReturnedInfo = (ReturnedInfo) ri; } else this.pReturnedInfo = (ReturnedInfo) new EncryptFs.EncryptId(this.pUri, returnedInfo as ResourceId, true, this.pFs); if (this.pLength >= 0L && this.pPosition != this.pLength) throw new InvalidRangeException(); } } [Serializable] public class EncryptId : ResourceId { private ResourceId pBaseId; private bool pEncrypted; public EncryptId(Uri target, ResourceId baseid, bool encrypted, EncryptFs fs) : base(target, (FsBase) fs) { this.pBaseId = baseid; this.pEncrypted = encrypted; } public ResourceId BaseId { get { return this.pBaseId; } } public bool Encrypted { get { return this.pEncrypted; } } } } }