コード例 #1
0
        // Helper methods

        protected void LoadOuterManifest()
        {
            if (InnerProxy.Manifest.RootDirectory.Files.ContainsKey(
                    DefaultOuterManifestFileName) == false)
            {
                throw new Exception("Encrypted manifest is not present.");
            }

            ManifestFileInfo outerManifestManifestFileInfo =
                InnerProxy.Manifest.RootDirectory.Files[
                    DefaultOuterManifestFileName];

            FileInfo outerManifestFileInfo =
                InnerProxy.GetFile(outerManifestManifestFileInfo);

            Stream outerManifestFileStream =
                outerManifestFileInfo.OpenRead();

            byte[] outerKeyBytes = CryptUtilities.MakeKeyBytesFromString(
                OuterKeyString,
                InnerProxy.Manifest.Guid.ToByteArray());

            Stream outerManifestCryptoStream =
                CryptUtilities.MakeDecryptionReadStreamFrom(
                    outerManifestFileStream,
                    outerKeyBytes);

            OuterManifest =
                Manifest.ReadManifestStream(outerManifestCryptoStream);

            outerManifestCryptoStream.Close();
        }
コード例 #2
0
        public FileInfo CloneFile(
            ManifestFileInfo copyFile,
            DirectoryInfo copyToDirectory)
        {
            ManifestFileInfo innerManifestFileInfo =
                HashToInnerFileMap[copyFile.FileHash];

            FileInfo innerFileInfo =
                InnerProxy.GetFile(innerManifestFileInfo);

            byte[] keyData = CryptUtilities.MakeKeyBytesFromString(
                OuterKeyString,
                copyFile.FileHash.HashData);

            String destFilePath =
                Path.Combine(
                    copyToDirectory.FullName,
                    DefaultDecryptedTempFileName);

            ReadCryptFile(
                innerFileInfo,
                keyData,
                destFilePath);

            FileInfo fileInfo =
                new FileInfo(destFilePath);

            // Make sure that the last-modified date matches that of the
            // expected outer file.  This is necessary because one inner file
            // may correspond to several outer files - each of which might
            // have separate dates.
            fileInfo.LastWriteTimeUtc = copyFile.LastModifiedUtc;

            return(fileInfo);
        }
コード例 #3
0
        protected void SaveOuterManifest()
        {
            // Serialize the manifest to memory
            MemoryStream serializedManifestStream =
                new MemoryStream();

            OuterManifest.WriteManifestStream(serializedManifestStream);
            serializedManifestStream.Position = 0;

            String tempFilePath =
                Path.Combine(
                    InnerProxy.TempDirectory.FullName,
                    DefaultOuterManifestFileName);

            // We use the inner GUID as salt for the outer manifest, so update
            // it each time we write the outer manifest.  The inner GUID is
            // really useless anyways.
            InnerProxy.Manifest.ChangeGUID();

            byte[] outerKeyData = CryptUtilities.MakeKeyBytesFromString(
                OuterKeyString,
                InnerProxy.Manifest.Guid.ToByteArray());

            byte[] cryptHash = WriteCryptFileAndHash(
                serializedManifestStream,
                outerKeyData,
                tempFilePath);

            // The new ManifestFileInfo is actually rooted in the inner
            // Manifest object, but that is ok - although it is kind of a
            // hack.  The fact is that we don't maintain an actual Manifest
            // object to mirror the inner manifest - and we know that the
            // implementation of PutFile won't be affected by doing this.
            ManifestDirectoryInfo parentDirectory =
                InnerProxy.Manifest.RootDirectory;

            ManifestFileInfo destManifestFile =
                new ManifestFileInfo(
                    DefaultOuterManifestFileName,
                    parentDirectory);

            destManifestFile.RegisteredUtc = DateTime.Now;

            FileInfo outerManifestFileInfo = new FileInfo(tempFilePath);

            destManifestFile.LastModifiedUtc =
                outerManifestFileInfo.LastWriteTimeUtc;

            destManifestFile.FileLength =
                outerManifestFileInfo.Length;

            destManifestFile.FileHash =
                new FileHash(cryptHash, CryptUtilities.DefaultHashType);

            InnerProxy.PutFile(ProxyToInner, destManifestFile);
        }
コード例 #4
0
        protected void ValidateFile(
            ManifestFileInfo outerManFileInfo,
            Utilities.Console console)
        {
            ManifestFileInfo innerManifestFileInfo = null;

            try
            {
                innerManifestFileInfo =
                    HashToInnerFileMap[outerManFileInfo.FileHash];

                FileInfo innerFileInfo =
                    InnerProxy.GetFile(innerManifestFileInfo);

                byte[] keyData = CryptUtilities.MakeKeyBytesFromString(
                    OuterKeyString,
                    outerManFileInfo.FileHash.HashData);

                Stream sourceFileStream =
                    innerFileInfo.OpenRead();

                Stream cryptoStream =
                    CryptUtilities.MakeDecryptionReadStreamFrom(
                        sourceFileStream,
                        keyData);

                FileHash computedHash = FileHash.ComputeHash(
                    cryptoStream,
                    outerManFileInfo.FileHash.HashType);

                if (computedHash.Equals(outerManFileInfo.FileHash) == false)
                {
                    throw new Exception("FAILED VALIDATION");
                }
            }
            catch (Exception e)
            {
                console.WriteLine(
                    Manifest.MakeStandardPathString(outerManFileInfo));

                console.WriteLine(
                    Manifest.MakeNativePathString(innerManifestFileInfo));

                console.WriteLine(e.Message);

                console.WriteLine();
            }
        }
コード例 #5
0
        /// <summary>
        /// Get rid of temp directory and cleanup orphaned files.
        /// </summary>
        public void CleanupBeforeExit()
        {
            if (myReadOnly == false &&
                TempDirectory != null)
            {
                SaveOuterManifest();

                // Removed orphaned data files
                ResolveInnerOuter();
                foreach (ManifestFileInfo nextFile in OrphanedInnerFiles)
                {
                    InnerProxy.RemoveFile(nextFile);
                }

                TempDirectory.Delete(true);
                TempDirectory = null;

                InnerProxy.CleanupBeforeExit();
            }
        }
コード例 #6
0
        public void PutFile(
            IRepositoryProxy sourceRepository,
            ManifestFileInfo sourceManifestFile)
        {
            // Name the inner file with the hash of the hash.  We protect
            // the hash in this way because it is used as the salt to
            // encrypt the data in the file, and it might provide some
            // benefit to a cryptographic attack.
            FileHash hashedHash = FileHash.ComputeHash(
                sourceManifestFile.FileHash.HashData);

            String hashedHashString = hashedHash.ToString();

            // Only add the file data if we don't have it already.
            if (myHashedStringMap.ContainsKey(hashedHashString) == false)
            {
                FileInfo sourceFileInfo =
                    sourceRepository.GetFile(sourceManifestFile);

                byte[] keyData = CryptUtilities.MakeKeyBytesFromString(
                    OuterKeyString,
                    sourceManifestFile.FileHash.HashData);

                // Use the inner proxy temp directory because that is likely
                // the ultimate destination of the file and we don't want to
                // copy the data if we can avoid it.  This is a minor break in
                // encapsulation but has a significant impact on performance.
                String destFilePath =
                    Path.Combine(
                        InnerProxy.TempDirectory.FullName,
                        hashedHashString);

                Stream sourceFileStream = sourceFileInfo.OpenRead();

                byte[] cryptHash = WriteCryptFileAndHash(
                    sourceFileStream,
                    keyData,
                    destFilePath);

                FileInfo cryptFileInfo =
                    new FileInfo(destFilePath);

                // Make a dummy parent manifest directory to give to the inner
                // proxy.  This is actually rooted in the inner manifest, but
                // that is ok - although it is kind of a hack.  The fact is
                // that we don't maintain an actual manifest to mirror the
                // inner manifest - and we know that the implementation of
                // PutFile won't be affected by doing this.
                ManifestDirectoryInfo parentDirectory =
                    MakeInnerParentDirectory(
                        hashedHashString,
                        InnerProxy.Manifest.RootDirectory);

                ManifestFileInfo destManifestFile =
                    new ManifestFileInfo(
                        hashedHashString,
                        parentDirectory);

                destManifestFile.RegisteredUtc =
                    DateTime.UtcNow;

                destManifestFile.LastModifiedUtc =
                    cryptFileInfo.LastWriteTimeUtc;

                destManifestFile.FileLength =
                    cryptFileInfo.Length;

                destManifestFile.FileHash =
                    new FileHash(cryptHash, CryptUtilities.DefaultHashType);

                InnerProxy.PutFile(ProxyToInner, destManifestFile);

                myHashedStringMap.Add(hashedHashString, destManifestFile);

                myNeedToRegenerateFileMap = true;
            }

            ManifestFileInfo outerManifestFileInfo =
                Manifest.PutFileFromOtherManifest(sourceManifestFile);

            myManifestChanged = true;
        }