Exemplo n.º 1
0
        public static void TryLoad(string path, ChunkLoader chunkLoader)
        {
            if (File.Exists(path) == false)
            {
                return;
            }

            var initFileSystem = InitFileSystemFile.Read(path);
            var entry          = initFileSystem.FirstOrDefault(
                e => e.File.FileSystemName == null && e.File.Name == "Scripts/CasEncrypt.yaml");

            if (entry == null)
            {
                return;
            }

            using (var temp = new MemoryStream(entry.File.Payload, false))
                using (var reader = new StreamReader(temp))
                {
                    var yaml = new YamlStream();
                    yaml.Load(reader);
                    var mapping = (YamlMappingNode)yaml.Documents[0].RootNode;
                    var start   = (YamlSequenceNode)mapping.Children[new YamlScalarNode("start")];
                    foreach (var child in start.Children.OfType <YamlMappingNode>())
                    {
                        var key   = ((YamlScalarNode)child.Children[new YamlScalarNode("key")]).Value;
                        var keyId = ((YamlScalarNode)child.Children[new YamlScalarNode("keyid")]).Value;
                        chunkLoader.AddCryptoKey(keyId, key);
                    }
                }
        }
Exemplo n.º 2
0
        private bool LoadPatchChunk(ChunkLoader chunkLoader,
                                    int index,
                                    long variantSize,
                                    long originalSize,
                                    Stream output)
        {
            var patch = chunkLoader.Catalog.PatchEntries[index];

            using (var input = new MemoryStream())
                using (var delta = new MemoryStream())
                {
                    if (this.LoadChunk(patch.BaseId, 0, 0, input, true) == false)
                    {
                        throw new DataLoadException(string.Format("could not load base chunk '{0}' for chunk '{1}'",
                                                                  patch.BaseId,
                                                                  patch.Id));
                    }

                    if (this.LoadChunk(patch.DeltaId, 0, 0, delta, true) == false)
                    {
                        throw new DataLoadException(string.Format("could not load delta chunk '{0}' for chunk '{1}'",
                                                                  patch.DeltaId,
                                                                  patch.Id));
                    }

                    input.Position = 0;
                    delta.Position = 0;
                    return(PatchHelper.Patch(input, delta, output));
                }
        }
Exemplo n.º 3
0
        private bool LoadNormalChunk(ChunkLoader chunkLoader,
                                     int index,
                                     long variantSize,
                                     long originalSize,
                                     Stream output)
        {
            var entry = chunkLoader.Catalog.NormalEntries[index];

            if ((variantSize != 0 || entry.TailSize != 0) && variantSize != entry.Size)
            {
                return(false);
            }

            var file = chunkLoader.Files[entry.DataIndex];

            using (var input = file.CreateViewStream(entry.Offset, entry.Size, MemoryMappedFileAccess.Read))
            {
                if (originalSize == 0 || originalSize == entry.Size)
                {
                    output.WriteFromStream(input, entry.Size);
                }
                else
                {
                    CompressionHelper.Decompress(input, output, originalSize);
                }
            }
            return(true);
        }
Exemplo n.º 4
0
        private bool FindChunk(SHA1Hash id, out ChunkLoader chunkLoader, out List <ChunkVariantInfo> chunkVariants)
        {
            foreach (var candidate in this._ChunkLoaders)
            {
                if (candidate.ChunkLookup.TryGetValue(id, out chunkVariants) == true)
                {
                    chunkLoader = candidate;
                    return(true);
                }
            }

            chunkLoader   = null;
            chunkVariants = null;
            return(false);
        }
Exemplo n.º 5
0
        private bool LoadEncryptedChunk(ChunkLoader chunkLoader,
                                        int index,
                                        long variantSize,
                                        long originalSize,
                                        Stream output)
        {
            var encryptedEntry = chunkLoader.Catalog.EncryptedEntries[index];

            if ((variantSize != 0 || encryptedEntry.Entry.TailSize != 0) && variantSize != encryptedEntry.Entry.Size)
            {
                return(false);
            }

            var entry       = encryptedEntry.Entry;
            var alignedSize = CryptoAlign(entry.Size, 16);
            var file        = chunkLoader.Files[entry.DataIndex];

            using (var input = file.CreateViewStream(entry.Offset, alignedSize, MemoryMappedFileAccess.Read))
            {
                var    keyId = encryptedEntry.CryptoInfo.KeyId;
                byte[] keyBytes;
                if (_TryGetCryptoKey == null || this._TryGetCryptoKey(keyId, out keyBytes) == false)
                {
                    throw new ChunkCryptoKeyMissingException(keyId);
                }

                using (var aes = Aes.Create())
                {
                    aes.Key     = keyBytes;
                    aes.IV      = keyBytes; // yes, it's that stupid
                    aes.Mode    = CipherMode.CBC;
                    aes.Padding = PaddingMode.PKCS7;
                    using (var decryptor = aes.CreateDecryptor())
                        using (var cryptoStream = new CryptoStream(input, decryptor, CryptoStreamMode.Read))
                        {
                            if (originalSize == 0 || originalSize == entry.Size)
                            {
                                output.WriteFromStream(cryptoStream, entry.Size);
                            }
                            else
                            {
                                CompressionHelper.Decompress(cryptoStream, output, originalSize);
                            }
                        }
                }
            }
            return(true);
        }
Exemplo n.º 6
0
        internal static InstallChunkManager Initialize(TryGetCryptoKeyDelegate tryGetCryptoKey,
                                                       Layout.InstallChunk installChunk,
                                                       IEnumerable <DataSource> sources)
        {
            if (installChunk == null)
            {
                throw new ArgumentNullException("installChunk");
            }

            var chunkLoaders = new List <ChunkLoader>();

            foreach (var source in sources)
            {
                var chunkPath   = Path.Combine(source.Path, Helpers.FilterPath(installChunk.InstallBundle));
                var chunkLoader = ChunkLoader.Load(chunkPath);
                if (chunkLoader == null)
                {
                    continue;
                }
                chunkLoaders.Add(chunkLoader);
            }

            return(new InstallChunkManager(tryGetCryptoKey, chunkLoaders));
        }