Esempio n. 1
0
        public FileMeta3 GetFileMeta()
        {
            byte metaTag = this._binaryReader.ReadByte();

            if (metaTag != 0x42)
            {
                throw new InvalidDataException($"File {this._fileItem.Name} fails to extract meta");
            }

            IFileStreamHandler <IDictionary <string, object> > metaHandler =
                this._handlerFactory.GetHandler <IDictionary <string, object> >(metaTag);
            IDictionary <string, object> metaDict = metaHandler.Handle(this._binaryReader);

            if (!(metaDict.ContainsKey("type") && "metadata".Equals(metaDict["type"])))
            {
                throw new InvalidDataException($"File {this._fileItem.Name} fails to extract meta");
            }

            return(FileMeta3.fromDictionary(metaDict));
        }
Esempio n. 2
0
        public bool ProcessFile(string sourcePath, string destDir, bool respectFileNameInMeta = true)
        {
            string destPath = null;

            try
            {
                FileItem fi = new FileItem(sourcePath);
                using (CloudSyncFile cloudSyncFile = new CloudSyncFile(fi, _handlerFactory))
                {
                    cloudSyncFile.InitParsing();
                    FileMeta3 fileMeta = cloudSyncFile.GetFileMeta();

                    //Generate session key and make sure it matches the file
                    byte[] sessionKeyComputed =
                        CryptoUtils.RsaOaepDeciper(fileMeta.EncKey2, this._cloudSyncKey.KeyPair.Private);
                    string sessionKeyHashStrComputed = CryptoUtils.SaltedMd5(
                        fileMeta.SessionKeyHash.Substring(0, 10), sessionKeyComputed);

                    if (!fileMeta.SessionKeyHash.Equals(sessionKeyHashStrComputed))
                    {
                        throw new InvalidDataException($"File {fi.Name}, Computed session key is incorrect.");
                    }

                    //decrypt content
                    byte[] sessionKeyBytes = BytesUtils.HexStringToByteArray(
                        Encoding.ASCII.GetString(sessionKeyComputed));
                    ParametersWithIV keys =
                        CryptoUtils.DeriveAESKeyParameters(sessionKeyBytes, null);
                    AesCbcCryptor decryptor =
                        new AesCbcCryptor(((KeyParameter)keys.Parameters).GetKey(), keys.GetIV());

                    destPath = Path.Join(destDir,
                                         respectFileNameInMeta ? fileMeta.FileName : Path.GetFileName(sourcePath));

                    using (var hasher = MD5.Create())
                    {
                        using (AesCryptoServiceProvider aes = new AesCryptoServiceProvider())
                        {
                            aes.Mode = CipherMode.CBC;
                            aes.Key  = ((KeyParameter)keys.Parameters).GetKey();
                            aes.IV   = keys.GetIV();
                            //Stopwatch stopwatch =  new Stopwatch();
                            //stopwatch.Start();
                            //byte[] buffer = new byte[1024 * 1024];
                            long             bytesRead = 0;
                            ICryptoTransform decoder   = aes.CreateDecryptor();
                            using (CloudSyncPayloadStream cspls =
                                       new CloudSyncPayloadStream(cloudSyncFile.GetDataBlocks(decryptor)))
                                using (CryptoStream aesStream = new CryptoStream(cspls, decoder, CryptoStreamMode.Read))
                                    using (LZ4DecoderStream lz4ds = LZ4Stream.Decode(aesStream))
                                        using (FileStream writeFs = new FileStream(destPath, FileMode.OpenOrCreate,
                                                                                   FileAccess.ReadWrite, FileShare.ReadWrite, 1024 * 1024))
                                            using (CryptoStream md5HashStream =
                                                       new CryptoStream(writeFs, hasher, CryptoStreamMode.Write))
                                            {
                                                lz4ds.CopyTo(md5HashStream, 1024 * 1024);
                                                // int read;
                                                // while ((read = md5HashStream.Read(buffer, 0, buffer.Length)) > 0)
                                                // {
                                                //     //do nothing
                                                //     bytesRead += read;
                                                //     long elapsed = stopwatch.ElapsedMilliseconds;
                                                //     if (elapsed > 1000)
                                                //     {
                                                //         double readInM = (double) bytesRead / 1024.0 / 1024.0/elapsed*1000.0;
                                                //         bytesRead = 0;
                                                //         Console.WriteLine($"Speed:{readInM} M/s");
                                                //         stopwatch.Reset();
                                                //         stopwatch.Start();
                                                //     }
                                                // }
                                            }

                            //stopwatch.Stop();
                            if (!cloudSyncFile.VerifyContentHash(hasher.Hash))
                            {
                                throw new InvalidDataException("File Md5 doesn't match.");
                            }
                        }
                    }

                    return(true);
                }
            }
            catch (Exception ex)
            {
                if (File.Exists(destPath))
                {
                    File.Delete(destPath);
                }

                this._exceptionHandler.Handle(ex);
            }

            return(false);
        }
Esempio n. 3
0
        public static FileMeta3 fromDictionary(IDictionary <string, object> dict)
        {
            FileMeta3 instance = new FileMeta3();

            foreach (KeyValuePair <string, object> entry in dict)
            {
                switch (entry.Key)
                {
                case "compress":
                    instance.Compress = (int)entry.Value > 0;
                    break;

                case "digest":
                    instance.Digest = (string)entry.Value;
                    break;

                case "enc_key1":
                    instance.EncKey1 = Convert.FromBase64String((string)entry.Value);
                    break;

                case "enc_key2":
                    instance.EncKey2 = Convert.FromBase64String((string)entry.Value);
                    break;

                case "encrypt":
                    instance.Encrypt = (int)entry.Value > 0;
                    break;

                case "file_name":
                    instance.FileName = (string)entry.Value;
                    break;

                case "key1_hash":
                    instance.Key1Hash = (string)entry.Value;
                    break;

                case "key2_hash":
                    instance.Key2Hash = (string)entry.Value;
                    break;

                case "salt":
                    instance.Salt = (string)entry.Value;
                    break;

                case "session_key_hash":
                    instance.SessionKeyHash = (string)entry.Value;
                    break;

                case "version":
                    IDictionary <string, object> versionDict = (IDictionary <string, object>)entry.Value;
                    int major = (int)versionDict["major"];
                    int minor = (int)versionDict["minor"];
                    instance.Version = new FileVersion(major, minor);
                    break;

                default:
                    //TODO log not supported key
                    break;
                }
            }

            return(instance);
        }