public static byte[] Get(string name, TimeSpan cachePeriod) { var key = Hex.ToHexString(Sha256.Compute(Encoding.UTF8.GetBytes(name))); var fileExtension = "cache"; var fileName = $"{key}.{fileExtension}"; var filePath = Path.Combine(DefaultCacheFolder, fileName); try { if (!Directory.Exists(DefaultCacheFolder)) { Directory.CreateDirectory(DefaultCacheFolder); } var fileInfo = new FileInfo(filePath); if (fileInfo.Length > MaxCacheFileSize) { return(null); } if (cachePeriod != TimeSpan.MaxValue && fileInfo.LastWriteTimeUtc + cachePeriod < DateTime.UtcNow) { return(null); } return(File.ReadAllBytes(filePath)); } catch (Exception e) { Log.Error(e, "FileCache.Get error."); } return(null); }
public string GetUserId(uint keyIndex = 0) { using var servicePublicKey = Wallet.GetServicePublicKey(keyIndex); using var publicKey = servicePublicKey.ToUnsecuredBytes(); return(Sha256.Compute(Sha256.Compute(publicKey)).ToHexString()); }
// FIXME: This is duplicate of beacon node, need to clean up public byte[] GeneratePrivateKey(ulong index) { Span <byte> input = new Span <byte>(new byte[32]); BigInteger bigIndex = new BigInteger(index); bool indexWriteSuccess = bigIndex.TryWriteBytes(input, out int indexBytesWritten, isUnsigned: true, isBigEndian: false); if (!indexWriteSuccess || indexBytesWritten == 0) { throw new Exception("Error getting input for quick start private key generation."); } Bytes32 bytes32 = Sha256.Compute(input); ReadOnlySpan <byte> hash = bytes32.AsSpan(); // Mocked start interop specifies to convert the hash as little endian (which is the default for BigInteger) BigInteger value = new BigInteger(hash.ToArray(), isUnsigned: true); BigInteger privateKey = value % s_curveOrder; // Note that the private key is an *unsigned*, *big endian* number // However, we want to pad the big endian on the left to get 32 bytes. // So, write as little endian (will pad to right), then reverse. // NOTE: Alternative, write to Span 64, and then slice based on bytesWritten to get the padding. Span <byte> privateKeySpan = new Span <byte>(new byte[32]); bool keyWriteSuccess = privateKey.TryWriteBytes(privateKeySpan, out int keyBytesWritten, isUnsigned: true, isBigEndian: false); if (!keyWriteSuccess) { throw new Exception("Error generating quick start private key."); } privateKeySpan.Reverse(); return(privateKeySpan.ToArray()); }
private static Stream RemoveHash(Stream stream) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } int type = (int)Varint.GetUInt64(stream); if (type == (int)ConvertHashAlgorithm.Sha256) { var value = new byte[32]; stream.Read(value, 0, value.Length); var dataStream = new RangeStream(stream, true); if (!Unsafe.Equals(value, Sha256.Compute(new WrapperStream(dataStream)))) { throw new ArgumentException("Hash"); } dataStream.Seek(0, SeekOrigin.Begin); return(dataStream); } else { throw new NotSupportedException(); } }
public static byte[] GetSessionPasswordBytes( SecureString password, int hashIterationsCount = DefaultHashIterationsCount) { var passwordBytes = password.ToBytes(); var passwordHash = Sha256.Compute(passwordBytes, hashIterationsCount); Array.Clear(passwordBytes, 0, passwordBytes.Length); return(passwordHash); }
private static void BuildZeroHashes() { Span <UInt256> concatenation = stackalloc UInt256[2]; UInt256.CreateFromLittleEndian(out ZeroHashes[0], Hash32.Zero.Bytes); for (int i = 1; i < 64; i++) { var previous = ZeroHashes[i - 1]; MemoryMarshal.CreateSpan(ref previous, 1).CopyTo(concatenation.Slice(0, 1)); MemoryMarshal.CreateSpan(ref previous, 1).CopyTo(concatenation.Slice(1, 1)); UInt256.CreateFromLittleEndian(out ZeroHashes[i], Sha256.Compute(MemoryMarshal.Cast <UInt256, byte>(concatenation)).Bytes); } }
public AutoMapper_UserAPI_UsersProfile() { #region DB -> API CreateMap <UsersDB_UserDTO, UserAPI_GetProfileDTO>(); #endregion #region API -> DB CreateMap <UserAPI_SignUpDTO, UsersDB_UserDTO>() .ForMember(x => x.PasswordHash, x => x.MapFrom(m => Sha256.Compute(m.Password))) .ForMember(x => x.RegistrationDate, x => x.MapFrom(m => DateTime.UtcNow)); #endregion }
public void MessageUpload() { _callback.Invoke("----- CoreManager Message Upload Test (Start) -----"); _callback.Invoke(""); var random = RandomProvider.GetThreadRandom(); _coreManager.Resize((long)1024 * 1024 * 1024 * 32).Wait(); Metadata metadata = null; Hash hash; using (var stream = new RecyclableMemoryStream(_bufferManager)) { using (var safeBuffer = _bufferManager.CreateSafeBuffer(1024 * 4)) { for (long remain = (long)1024 * 1024 * 256; 0 < remain; remain -= safeBuffer.Value.Length) { int length = (int)Math.Min(remain, safeBuffer.Value.Length); random.NextBytes(safeBuffer.Value); stream.Write(safeBuffer.Value, 0, length); } } stream.Seek(0, SeekOrigin.Begin); hash = new Hash(HashAlgorithm.Sha256, Sha256.Compute(new WrapperStream(stream))); stream.Seek(0, SeekOrigin.Begin); metadata = _coreManager.VolatileSetStream(stream, new TimeSpan(1, 0, 0, 0), CancellationToken.None).Result; } using (var stream = metadata.Export(_bufferManager)) using (var safeBuffer = _bufferManager.CreateSafeBuffer((int)stream.Length)) { stream.Read(safeBuffer.Value, 0, (int)stream.Length); Console.WriteLine(NetworkConverter.ToBase64UrlString(safeBuffer.Value, 0, (int)stream.Length)); } using (var stream = hash.Export(_bufferManager)) using (var safeBuffer = _bufferManager.CreateSafeBuffer((int)stream.Length)) { stream.Read(safeBuffer.Value, 0, (int)stream.Length); Console.WriteLine(NetworkConverter.ToBase64UrlString(safeBuffer.Value, 0, (int)stream.Length)); } _callback.Invoke("----- CoreManager Message Upload Test (End) -----"); }
public static void Set(string name, byte[] data) { var key = Hex.ToHexString(Sha256.Compute(Encoding.UTF8.GetBytes(name))); var fileExtension = "cache"; var fileName = $"{key}.{fileExtension}"; var filePath = Path.Combine(DefaultCacheFolder, fileName); try { File.WriteAllBytes(filePath, data); } catch (Exception e) { Log.Error(e, "FileCache.Set error."); } }
public AutoMapper_MemberAPI_MembersProfile() { #region DB -> API CreateMap <MembersDB_MemberDTO, UserAPI_GetMembersItemDTO>(); #endregion #region API -> DB CreateMap <MemberAPI_SignUpDTO, MembersDB_MemberDTO>() .ForMember(x => x.PasswordHash, x => x.MapFrom(m => Sha256.Compute(m.Password))) .ForMember(x => x.RoomId, x => x.MapFrom(m => ObjectId.Parse(m.RoomId))); #endregion }
private static Stream AddHash(Stream stream) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } var hashStream = new RecyclableMemoryStream(_bufferManager); { Varint.SetUInt64(hashStream, (uint)ConvertHashAlgorithm.Sha256); var value = Sha256.Compute(new WrapperStream(stream)); hashStream.Write(value, 0, value.Length); } return(new UniteStream(hashStream, stream)); }
public void ReadWriteTest() { for (int i = 0; i < 256; i++) { int size = _random.Next(1, 1024 * 1024 * 4); using (var safeBuffer = _bufferManager.CreateSafeBuffer(size)) { _random.NextBytes(safeBuffer.Value); var block = new ArraySegment <byte>(safeBuffer.Value, 0, size); var hash = new Hash(HashAlgorithm.Sha256, Sha256.Compute(block)); _cacheManager.Set(hash, block); var result = _cacheManager.GetBlock(hash); Assert.True(Unsafe.Equals(block.Array, block.Offset, result.Array, result.Offset, size)); _bufferManager.ReturnBuffer(result.Array); } } }
public static byte[] CreateSwapSecretHash(byte[] secretBytes) => Sha256.Compute(secretBytes, 2);
public static ImportExternalTransactionDataResults ImportExternalTransactionData(ExternalBankData import, ImportExternalTransactionDataArgs args) { FinancialAccount assetAccount = args.Account; FinancialAccount autoDepositAccount = args.Organization.FinancialAccounts.IncomeDonations; int autoDepositLimit = 0; // Disabled; TODO: this.CurrentOrganization.Parameters.AutoDonationLimit; bool autosetInitialBalance = false; ImportExternalTransactionDataResults result = new ImportExternalTransactionDataResults(); int count = 0; int progressUpdateInterval = import.Records.Length / 40; Int64 importedCentsTotal = 0; if (progressUpdateInterval > 100) { progressUpdateInterval = 100; } ProgressBarBackend progressDisplay = new ProgressBarBackend(args.Guid); Currency organizationCurrency = assetAccount.Organization.Currency; Currency accountCurrency = assetAccount.ForeignCurrency; if (accountCurrency == null) { accountCurrency = organizationCurrency; } FinancialAccountRows existingRows = assetAccount.GetRows(Constants.DateTimeLow, Constants.DateTimeHigh); // gets all if (existingRows.Count == 0) { autosetInitialBalance = true; } foreach (ExternalBankDataRecord row in import.Records) { // Update progress. count++; if (progressUpdateInterval < 2 || count % progressUpdateInterval == 0) { int percent = (count * 99) / import.Records.Length; progressDisplay.Set(percent); } // Update high- and low-water marks. if (row.DateTime < result.EarliestTransaction) { result.EarliestTransaction = row.DateTime; } if (row.DateTime > result.LatestTransaction) { result.LatestTransaction = row.DateTime; } string importKey = row.ImportHash; Int64 amountCents = row.TransactionNetCents; if (amountCents == 0) // defensive programming - these _should_ be duplicated in the interpreter if no "fee" field { amountCents = row.TransactionGrossCents; } Int64 foreignCents = amountCents; importedCentsTotal += amountCents; if (accountCurrency.Identity != organizationCurrency.Identity) { amountCents = new Money(amountCents, accountCurrency, row.DateTime).ToCurrency(organizationCurrency).Cents; } FinancialTransaction transaction = FinancialTransaction.ImportWithStub(args.Organization.Identity, row.DateTime, assetAccount.Identity, amountCents, row.Description, importKey, Sha256.Compute(row.RawData), args.CurrentUser.Identity); if (transaction != null) { // The transaction was created. result.TransactionsImported++; // If non-presentation currency, log the account currency amount as well. if (accountCurrency.Identity != organizationCurrency.Identity) { transaction.Rows[0].AmountForeignCents = new Money(foreignCents, accountCurrency); } if (row.Description.ToLowerInvariant().StartsWith(args.Organization.IncomingPaymentTag)) { // Check for previously imported payment group // TODO: MAKE FLEXIBLE - CALL PAYMENTREADERINTERFACE! // HACK HACK HACK HACK PaymentGroup group = PaymentGroup.FromTag(args.Organization, "SEBGM" + DateTime.Today.Year + // TODO: Get tags from org row.Description.Substring(args.Organization.IncomingPaymentTag.Length).Trim()); if (group != null && group.Open) { // There was a previously imported and not yet closed payment group matching this transaction // Close the payment group and match the transaction against accounts receivable transaction.Dependency = group; group.Open = false; transaction.AddRow(args.Organization.FinancialAccounts.AssetsOutboundInvoices, -amountCents, args.CurrentUser); } } else if (amountCents < 0) { // Autowithdrawal mechanisms removed, condition kept because of downstream else-if conditions } else if (amountCents > 0) { if (row.FeeCents < 0) { // This is always an autodeposit, if there is a fee (which is never > 0.0) transaction.AddRow(args.Organization.FinancialAccounts.CostsBankFees, -row.FeeCents, args.CurrentUser); transaction.AddRow(autoDepositAccount, -row.TransactionGrossCents, args.CurrentUser); } else if (amountCents < autoDepositLimit * 100) { // Book against autoDeposit account. transaction.AddRow(autoDepositAccount, -amountCents, args.CurrentUser); } } } else { // Transaction was not imported; assume duplicate result.DuplicateTransactions++; } } // Import complete. Return true if the bookkeeping account matches the bank data. Int64 databaseAccountBalanceCents; if (accountCurrency.Identity == organizationCurrency.Identity) { databaseAccountBalanceCents = assetAccount.BalanceTotalCents; } else { // foreign-currency account databaseAccountBalanceCents = assetAccount.ForeignCurrencyBalance.Cents; } // Subtract any transactions made after the most recent imported transaction. // This is necessary in case of Paypal and others which continuously feed the // bookkeeping account with new transactions; it will already have fed transactions // beyond the end-of-file. Int64 beyondEofCents = assetAccount.GetDeltaCents(result.LatestTransaction.AddSeconds(1), DateTime.Now.AddDays(2)); // Caution: the "AddSeconds(1)" is not foolproof, there may be other new txs on the same second. if (databaseAccountBalanceCents - beyondEofCents == import.LatestAccountBalanceCents) { Payouts.AutomatchAgainstUnbalancedTransactions(args.Organization); OutboundInvoices.AutomatchAgainstUnbalancedTransactions(args.Organization, args.CurrentUser); result.AccountBalanceMatchesBank = true; result.BalanceMismatchCents = 0; } else { result.AccountBalanceMatchesBank = false; result.BalanceMismatchCents = (databaseAccountBalanceCents - beyondEofCents) - import.LatestAccountBalanceCents; if (autosetInitialBalance) { Int64 newInitialBalanceCents = -result.BalanceMismatchCents; Money initialBalance = new Money(newInitialBalanceCents, accountCurrency); assetAccount.InitialBalance = initialBalance; result.InitialBalanceCents = newInitialBalanceCents; result.InitialBalanceCurrencyCode = accountCurrency.Code; // make an approximation of conversion rate set for initial balance in presentation to tell user initialBalance.ValuationDateTime = new DateTime(assetAccount.Organization.FirstFiscalYear, 1, 1); result.BalanceMismatchCents = initialBalance.ToCurrency(assetAccount.Organization.Currency).Cents; } } result.CurrencyCode = args.Organization.Currency.Code; GuidCache.Set(args.Guid + "-Results", result); return(result); }
public bool Run() { try { // スリープを禁止する。 NativeMethods.SetThreadExecutionState(NativeMethods.ExecutionState.Continuous); // カレントディレクトリをexeと同じディレクトリパスへ変更。 Directory.SetCurrentDirectory(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)); // ハンドルしていない例外をログ出力させる。 Thread.GetDomain().UnhandledException += this.Program_UnhandledException; string sessionId = NetworkConverter.ToHexString(Sha256.Compute(Path.GetFullPath(Assembly.GetEntryAssembly().Location))); // 多重起動防止 { _mutex = new Mutex(false, sessionId); if (!_mutex.WaitOne(0)) { return(false); } } // 既定のフォルダを作成する。 { foreach (var propertyInfo in typeof(AmoebaEnvironment.PathsEnvironment).GetProperties()) { string path = propertyInfo.GetValue(AmoebaEnvironment.Paths) as string; if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } } } // Tempフォルダを環境変数に登録。 { // Tempフォルダ内を掃除。 try { foreach (string path in Directory.GetFiles(AmoebaEnvironment.Paths.TempDirectoryPath, "*", SearchOption.AllDirectories)) { File.Delete(path); } foreach (string path in Directory.GetDirectories(AmoebaEnvironment.Paths.TempDirectoryPath, "*", SearchOption.AllDirectories)) { Directory.Delete(path, true); } } catch (Exception) { } Environment.SetEnvironmentVariable("TMP", Path.GetFullPath(AmoebaEnvironment.Paths.TempDirectoryPath), EnvironmentVariableTarget.Process); Environment.SetEnvironmentVariable("TEMP", Path.GetFullPath(AmoebaEnvironment.Paths.TempDirectoryPath), EnvironmentVariableTarget.Process); } // ログファイルを設定する。 this.Setting_Log(); // アップデート { // 一時的に作成された"Amoeba.Update.exe"を削除する。 { string tempUpdateExeFilePath = Path.Combine(AmoebaEnvironment.Paths.WorkDirectoryPath, "Amoeba.Update.exe"); if (File.Exists(tempUpdateExeFilePath)) { File.Delete(tempUpdateExeFilePath); } } if (Directory.Exists(AmoebaEnvironment.Paths.UpdateDirectoryPath)) { string zipFilePath = null; // 最新のバージョンのzipを検索。 { var map = new Dictionary <string, Version>(); var regex = new Regex(@"Amoeba.+?((\d*)\.(\d*)\.(\d*)).*?\.zip", RegexOptions.Compiled); foreach (string path in Directory.GetFiles(AmoebaEnvironment.Paths.UpdateDirectoryPath)) { var match = regex.Match(Path.GetFileName(path)); if (!match.Success) { continue; } var version = new Version(match.Groups[1].Value); if (version < AmoebaEnvironment.Version) { continue; } map.Add(path, version); } if (map.Count > 0) { var sortedList = map.ToList(); sortedList.Sort((x, y) => y.Value.CompareTo(x.Value)); zipFilePath = sortedList.First().Key; } } if (zipFilePath != null) { string tempUpdateDirectoryPath = Path.Combine(AmoebaEnvironment.Paths.WorkDirectoryPath, "Update"); if (Directory.Exists(tempUpdateDirectoryPath)) { Directory.Delete(tempUpdateDirectoryPath, true); } using (var zipfile = new ZipFile(zipFilePath)) { zipfile.ExtractExistingFile = ExtractExistingFileAction.OverwriteSilently; zipfile.ExtractAll(tempUpdateDirectoryPath); } if (File.Exists(zipFilePath)) { File.Delete(zipFilePath); } string tempUpdateExeFilePath = Path.Combine(AmoebaEnvironment.Paths.WorkDirectoryPath, "Amoeba.Update.exe"); File.Copy("Amoeba.Update.exe", tempUpdateExeFilePath); var startInfo = new ProcessStartInfo(); startInfo.FileName = Path.GetFullPath(tempUpdateExeFilePath); startInfo.Arguments = string.Format("\"{0}\" \"{1}\" \"{2}\" \"{3}\"", sessionId, Path.GetFullPath(Path.Combine(tempUpdateDirectoryPath, "Core")), Path.GetFullPath(AmoebaEnvironment.Paths.CoreDirectoryPath), Path.GetFullPath(Assembly.GetEntryAssembly().Location)); startInfo.WorkingDirectory = Path.GetFullPath(Path.GetDirectoryName(tempUpdateExeFilePath)); Process.Start(startInfo); return(false); } } } // マイグレーション { if (AmoebaEnvironment.Config.Version <= new Version(5, 0, 60)) { try { var basePath = Path.Combine(AmoebaEnvironment.Paths.ConfigDirectoryPath, @"Service\Core\Cache"); if (!Directory.Exists(Path.Combine(basePath, "Blocks"))) { Directory.CreateDirectory(Path.Combine(basePath, "Blocks")); } var renameList = new List <(string oldPath, string newPath)>(); renameList.Add((@"CacheInfos.json.gz", @"ContentInfos.json.gz")); renameList.Add((@"Size.json.gz", @"Blocks\Size.json.gz")); renameList.Add((@"ClusterIndex.json.gz", @"Blocks\ClusterIndex.json.gz")); foreach (var(oldPath, newPath) in renameList) { if (File.Exists(Path.Combine(basePath, newPath)) || !File.Exists(Path.Combine(basePath, oldPath))) { continue; } File.Copy(Path.Combine(basePath, oldPath), Path.Combine(basePath, newPath)); } } catch (Exception e) { Log.Error(e); } } if (AmoebaEnvironment.Config.Version <= new Version(5, 1, 1)) { try { var sourcePath = Path.Combine(AmoebaEnvironment.Paths.ConfigDirectoryPath, @"View\Settings"); var destPath = Path.Combine(AmoebaEnvironment.Paths.ConfigDirectoryPath, @"Control\Settings"); if (Directory.Exists(sourcePath)) { if (!Directory.Exists(destPath)) { Directory.CreateDirectory(destPath); } foreach (var oldPath in Directory.GetFiles(sourcePath)) { var newPath = Path.Combine(destPath, Path.GetFileName(oldPath)); if (File.Exists(newPath) || !File.Exists(oldPath)) { continue; } File.Copy(oldPath, newPath); } } } catch (Exception e) { Log.Error(e); } try { var basePath = Path.Combine(AmoebaEnvironment.Paths.ConfigDirectoryPath, @"Control\Settings"); var renameList = new List <(string oldPath, string newPath)>(); renameList.Add((@"AccountInfo.json.gz", @"AccountSetting.json.gz")); renameList.Add((@"UpdateInfo.json.gz", @"UpdateSetting.json.gz")); foreach (var(oldPath, newPath) in renameList .Select(tuple => (Path.Combine(basePath, tuple.oldPath), Path.Combine(basePath, tuple.newPath)))) { if (File.Exists(newPath) || !File.Exists(oldPath)) { continue; } File.Copy(oldPath, newPath); } } catch (Exception e) { Log.Error(e); } } } #if !DEBUG // デーモンプロセス起動。 { var daemonExeFilePath = Path.Combine(AmoebaEnvironment.Paths.DaemonDirectoryPath, "Amoeba.Daemon.exe"); var daemonConfigFilePath = Path.Combine(AmoebaEnvironment.Paths.ConfigDirectoryPath, "Daemon.toml"); if (!File.Exists(daemonConfigFilePath)) { // 「Amoeba/Core/Daemon」のような階層を想定。 var basePath = "../../"; var config = new DaemonConfig( new Version(0, 0, 0), new DaemonConfig.CommunicationConfig("tcp:127.0.0.1:4040"), new DaemonConfig.CacheConfig(Path.Combine(basePath, "Config", "Cache.blocks")), new DaemonConfig.PathsConfig( Path.Combine(basePath, "Temp"), Path.Combine(basePath, "Config", "Service"), Path.Combine(basePath, "Log"))); var tomlSettings = TomlSettings.Create(builder => builder .ConfigureType <Version>(type => type .WithConversionFor <TomlString>(convert => convert .ToToml(tt => tt.ToString()) .FromToml(ft => Version.Parse(ft.Value))))); Toml.WriteFile(config, daemonConfigFilePath, tomlSettings); } var startInfo = new ProcessStartInfo(); startInfo.FileName = daemonExeFilePath; startInfo.Arguments = string.Format("-c \"{0}\"", daemonConfigFilePath); startInfo.CreateNoWindow = true; startInfo.UseShellExecute = false; try { _process = Process.Start(startInfo); } catch (Exception) { return(false); } } #endif return(true); } catch (Exception ex) { Log.Error(ex); return(false); } }
private static Chunk Compute(Span <Chunk> span) { return(MemoryMarshal.Cast <byte, Chunk>(Sha256.Compute(MemoryMarshal.Cast <Chunk, byte>(span)).Bytes)[0]); }
public ArraySegment <byte>?Get(Hash hash) { ArraySegment <byte> result; lock (_lockObject) { ClusterInfo clusterInfo = null; if (_clusterIndex.TryGetValue(hash, out clusterInfo)) { clusterInfo.UpdateTime = DateTime.UtcNow; } if (clusterInfo == null) { return(null); } var buffer = _bufferManager.TakeBuffer(clusterInfo.Length); try { for (int i = 0, remain = clusterInfo.Length; i < clusterInfo.Indexes.Length; i++, remain -= SectorSize) { long posision = clusterInfo.Indexes[i] * SectorSize; if (posision > _fileStream.Length) { throw new ArgumentOutOfRangeException(); } if (_fileStream.Position != posision) { _fileStream.Seek(posision, SeekOrigin.Begin); } int length = Math.Min(remain, SectorSize); _fileStream.Read(_sectorBuffer, 0, _sectorBuffer.Length); Unsafe.Copy(_sectorBuffer, 0, buffer, SectorSize * i, length); } result = new ArraySegment <byte>(buffer, 0, clusterInfo.Length); } catch (Exception e) { _bufferManager.ReturnBuffer(buffer); Log.Error(e); return(null); } } if (hash.Algorithm == HashAlgorithm.Sha256) { if (Unsafe.Equals(Sha256.Compute(result), hash.Value)) { return(result); } else { _bufferManager.ReturnBuffer(result.Array); this.Remove(hash); return(null); } } else { throw new FormatException(); } }
public void Set(Hash hash, ArraySegment <byte> value) { if (value.Count > 1024 * 1024 * 32) { throw new BadBlockException(); } if (hash.Algorithm == HashAlgorithm.Sha256) { if (!Unsafe.Equals(Sha256.Compute(value), hash.Value)) { throw new BadBlockException(); } } else { throw new FormatException(); } lock (_lockObject) { if (this.Contains(hash)) { return; } var sectorList = new List <long>(); try { sectorList.AddRange(this.GetFreeSectors((value.Count + (SectorSize - 1)) / SectorSize)); for (int i = 0, remain = value.Count; i < sectorList.Count && 0 < remain; i++, remain -= SectorSize) { long posision = sectorList[i] * SectorSize; if ((_fileStream.Length < posision + SectorSize)) { int unit = 1024 * 1024 * 256; // 256MB long size = Roundup((posision + SectorSize), unit); _fileStream.SetLength(Math.Min(size, this.Size)); } if (_fileStream.Position != posision) { _fileStream.Seek(posision, SeekOrigin.Begin); } int length = Math.Min(remain, SectorSize); Unsafe.Copy(value.Array, value.Offset + (SectorSize * i), _sectorBuffer, 0, length); Unsafe.Zero(_sectorBuffer, length, _sectorBuffer.Length - length); _fileStream.Write(_sectorBuffer, 0, _sectorBuffer.Length); } _fileStream.Flush(); } catch (SpaceNotFoundException e) { Log.Error(e); throw e; } catch (Exception e) { Log.Error(e); throw e; } _clusterIndex[hash] = new ClusterInfo(sectorList.ToArray(), value.Count, DateTime.UtcNow); // Event _addedBlockEventQueue.Enqueue(hash); } }
public Task <Metadata> Import(string path, DateTime creationTime, CancellationToken token) { if (path == null) { throw new ArgumentNullException(nameof(path)); } return(Task.Run(() => { // Check lock (_lockObject) { var info = _contentInfoManager.GetFileContentInfo(path); if (info != null) { return info.Metadata; } } Metadata metadata = null; var lockedHashes = new HashSet <Hash>(); ShareInfo shareInfo = null; { const int blockLength = 1024 * 1024; const HashAlgorithm hashAlgorithm = HashAlgorithm.Sha256; const CorrectionAlgorithm correctionAlgorithm = CorrectionAlgorithm.ReedSolomon8; int depth = 0; var groupList = new List <Group>(); // File using (var stream = new UnbufferedFileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, FileOptions.None, _bufferManager)) { if (stream.Length <= blockLength) { Hash hash; using (var safeBuffer = _bufferManager.CreateSafeBuffer(blockLength)) { int length = (int)stream.Length; stream.Read(safeBuffer.Value, 0, length); if (hashAlgorithm == HashAlgorithm.Sha256) { hash = new Hash(HashAlgorithm.Sha256, Sha256.Compute(safeBuffer.Value, 0, length)); } } shareInfo = new ShareInfo(path, stream.Length, (int)stream.Length, new Hash[] { hash }); metadata = new Metadata(depth, hash); } else { var sharedHashes = new List <Hash>(); for (; ;) { var targetHashes = new List <Hash>(); var targetBuffers = new List <ArraySegment <byte> >(); long sumLength = 0; try { for (int i = 0; stream.Position < stream.Length; i++) { token.ThrowIfCancellationRequested(); var buffer = new ArraySegment <byte>(); try { int length = (int)Math.Min(stream.Length - stream.Position, blockLength); buffer = new ArraySegment <byte>(_bufferManager.TakeBuffer(length), 0, length); stream.Read(buffer.Array, 0, length); sumLength += length; } catch (Exception) { if (buffer.Array != null) { _bufferManager.ReturnBuffer(buffer.Array); } throw; } Hash hash; if (hashAlgorithm == HashAlgorithm.Sha256) { hash = new Hash(HashAlgorithm.Sha256, Sha256.Compute(buffer)); } sharedHashes.Add(hash); targetHashes.Add(hash); targetBuffers.Add(buffer); if (targetBuffers.Count >= 128) { break; } } var parityHashes = this.ParityEncoding(targetBuffers, hashAlgorithm, correctionAlgorithm, token); lockedHashes.UnionWith(parityHashes); groupList.Add(new Group(correctionAlgorithm, sumLength, CollectionUtils.Unite(targetHashes, parityHashes).ToArray())); } finally { foreach (var buffer in targetBuffers) { if (buffer.Array == null) { continue; } _bufferManager.ReturnBuffer(buffer.Array); } } if (stream.Position == stream.Length) { break; } } shareInfo = new ShareInfo(path, stream.Length, blockLength, sharedHashes); depth++; } } while (groupList.Count > 0) { // Index using (var stream = (new Index(groupList)).Export(_bufferManager)) { groupList.Clear(); if (stream.Length <= blockLength) { Hash hash; using (var safeBuffer = _bufferManager.CreateSafeBuffer(blockLength)) { int length = (int)stream.Length; stream.Read(safeBuffer.Value, 0, length); if (hashAlgorithm == HashAlgorithm.Sha256) { hash = new Hash(HashAlgorithm.Sha256, Sha256.Compute(safeBuffer.Value, 0, length)); } _blocksManager.Lock(hash); _blocksManager.Set(hash, new ArraySegment <byte>(safeBuffer.Value, 0, length)); lockedHashes.Add(hash); } metadata = new Metadata(depth, hash); } else { for (; ;) { var targetHashes = new List <Hash>(); var targetBuffers = new List <ArraySegment <byte> >(); long sumLength = 0; try { for (int i = 0; stream.Position < stream.Length; i++) { token.ThrowIfCancellationRequested(); var buffer = new ArraySegment <byte>(); try { int length = (int)Math.Min(stream.Length - stream.Position, blockLength); buffer = new ArraySegment <byte>(_bufferManager.TakeBuffer(length), 0, length); stream.Read(buffer.Array, 0, length); sumLength += length; } catch (Exception) { if (buffer.Array != null) { _bufferManager.ReturnBuffer(buffer.Array); } throw; } Hash hash; if (hashAlgorithm == HashAlgorithm.Sha256) { hash = new Hash(HashAlgorithm.Sha256, Sha256.Compute(buffer)); } _blocksManager.Lock(hash); _blocksManager.Set(hash, buffer); lockedHashes.Add(hash); targetHashes.Add(hash); targetBuffers.Add(buffer); if (targetBuffers.Count >= 128) { break; } } var parityHashes = this.ParityEncoding(targetBuffers, hashAlgorithm, correctionAlgorithm, token); lockedHashes.UnionWith(parityHashes); groupList.Add(new Group(correctionAlgorithm, sumLength, CollectionUtils.Unite(targetHashes, parityHashes).ToArray())); } finally { foreach (var buffer in targetBuffers) { if (buffer.Array == null) { continue; } _bufferManager.ReturnBuffer(buffer.Array); } } if (stream.Position == stream.Length) { break; } } depth++; } } } } lock (_lockObject) { if (!_contentInfoManager.ContainsFileContentInfo(path)) { _contentInfoManager.Add(new ContentInfo(creationTime, Timeout.InfiniteTimeSpan, metadata, lockedHashes, shareInfo)); foreach (var hash in lockedHashes) { _blocksManager.Lock(hash); } } } return metadata; }, token)); }
private IEnumerable <Hash> ParityEncoding(IEnumerable <ArraySegment <byte> > buffers, HashAlgorithm hashAlgorithm, CorrectionAlgorithm correctionAlgorithm, CancellationToken token) { if (correctionAlgorithm == CorrectionAlgorithm.ReedSolomon8) { if (buffers.Count() > 128) { throw new ArgumentOutOfRangeException(nameof(buffers)); } var createBuffers = new List <ArraySegment <byte> >(); try { var targetBuffers = new ArraySegment <byte> [buffers.Count()]; var parityBuffers = new ArraySegment <byte> [buffers.Count()]; int blockLength = buffers.Max(n => n.Count); // Normalize { int index = 0; foreach (var buffer in buffers) { token.ThrowIfCancellationRequested(); if (buffer.Count < blockLength) { var tempBuffer = new ArraySegment <byte>(_bufferManager.TakeBuffer(blockLength), 0, blockLength); Unsafe.Copy(buffer.Array, buffer.Offset, tempBuffer.Array, tempBuffer.Offset, buffer.Count); Unsafe.Zero(tempBuffer.Array, tempBuffer.Offset + buffer.Count, tempBuffer.Count - buffer.Count); createBuffers.Add(tempBuffer); targetBuffers[index] = tempBuffer; } else { targetBuffers[index] = buffer; } index++; } } for (int i = 0; i < parityBuffers.Length; i++) { parityBuffers[i] = new ArraySegment <byte>(_bufferManager.TakeBuffer(blockLength), 0, blockLength); } var indexes = new int[parityBuffers.Length]; for (int i = 0; i < parityBuffers.Length; i++) { indexes[i] = targetBuffers.Length + i; } using (var reedSolomon = new ReedSolomon8(targetBuffers.Length, targetBuffers.Length + parityBuffers.Length, _threadCount, _bufferManager)) { reedSolomon.Encode(targetBuffers, parityBuffers, indexes, blockLength, token).Wait(); } token.ThrowIfCancellationRequested(); var parityHashes = new List <Hash>(); for (int i = 0; i < parityBuffers.Length; i++) { Hash hash; if (hashAlgorithm == HashAlgorithm.Sha256) { hash = new Hash(HashAlgorithm.Sha256, Sha256.Compute(parityBuffers[i])); } else { throw new NotSupportedException(); } _blocksManager.Lock(hash); _blocksManager.Set(hash, parityBuffers[i]); parityHashes.Add(hash); } return(parityHashes); } finally { foreach (var buffer in createBuffers) { if (buffer.Array == null) { continue; } _bufferManager.ReturnBuffer(buffer.Array); } } } else { throw new NotSupportedException(); } }
public Task <Metadata> Import(Stream stream, TimeSpan lifeSpan, CancellationToken token) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } return(Task.Run(() => { Metadata metadata = null; var lockedHashes = new HashSet <Hash>(); try { const int blockLength = 1024 * 1024; const HashAlgorithm hashAlgorithm = HashAlgorithm.Sha256; const CorrectionAlgorithm correctionAlgorithm = CorrectionAlgorithm.ReedSolomon8; int depth = 0; var creationTime = DateTime.UtcNow; var groupList = new List <Group>(); for (; ;) { if (stream.Length <= blockLength) { Hash hash; using (var safeBuffer = _bufferManager.CreateSafeBuffer(blockLength)) { int length = (int)stream.Length; stream.Read(safeBuffer.Value, 0, length); if (hashAlgorithm == HashAlgorithm.Sha256) { hash = new Hash(HashAlgorithm.Sha256, Sha256.Compute(safeBuffer.Value, 0, length)); } _blocksManager.Lock(hash); _blocksManager.Set(hash, new ArraySegment <byte>(safeBuffer.Value, 0, length)); lockedHashes.Add(hash); } // Stream Dispose { stream.Dispose(); stream = null; } metadata = new Metadata(depth, hash); break; } else { for (; ;) { var targetHashes = new List <Hash>(); var targetBuffers = new List <ArraySegment <byte> >(); long sumLength = 0; try { for (int i = 0; stream.Position < stream.Length; i++) { token.ThrowIfCancellationRequested(); var buffer = new ArraySegment <byte>(); try { int length = (int)Math.Min(stream.Length - stream.Position, blockLength); buffer = new ArraySegment <byte>(_bufferManager.TakeBuffer(length), 0, length); stream.Read(buffer.Array, 0, length); sumLength += length; } catch (Exception) { if (buffer.Array != null) { _bufferManager.ReturnBuffer(buffer.Array); } throw; } Hash hash; if (hashAlgorithm == HashAlgorithm.Sha256) { hash = new Hash(HashAlgorithm.Sha256, Sha256.Compute(buffer)); } _blocksManager.Lock(hash); _blocksManager.Set(hash, buffer); lockedHashes.Add(hash); targetHashes.Add(hash); targetBuffers.Add(buffer); if (targetBuffers.Count >= 128) { break; } } var parityHashes = this.ParityEncoding(targetBuffers, hashAlgorithm, correctionAlgorithm, token); lockedHashes.UnionWith(parityHashes); groupList.Add(new Group(correctionAlgorithm, sumLength, CollectionUtils.Unite(targetHashes, parityHashes).ToArray())); } finally { foreach (var buffer in targetBuffers) { if (buffer.Array == null) { continue; } _bufferManager.ReturnBuffer(buffer.Array); } } if (stream.Position == stream.Length) { break; } } depth++; // Stream Dispose { stream.Dispose(); stream = null; } stream = (new Index(groupList)).Export(_bufferManager); } } } finally { if (stream != null) { stream.Dispose(); stream = null; } } lock (_lockObject) { if (!_contentInfoManager.ContainsMessageContentInfo(metadata)) { _contentInfoManager.Add(new ContentInfo(DateTime.UtcNow, lifeSpan, metadata, lockedHashes, null)); foreach (var hash in lockedHashes) { _blocksManager.Lock(hash); } } } return metadata; }, token)); }
private void Application_Startup(object sender, StartupEventArgs e) { try { string sessionId = NetworkConverter.ToHexString(Sha256.Compute(Path.GetFullPath(Assembly.GetEntryAssembly().Location))); // 多重起動防止 { _mutex = new Mutex(false, sessionId); if (!_mutex.WaitOne(0)) { this.Shutdown(); return; } } // アップデート { // 一時的に作成された"Amoeba.Update.exe"を削除する。 { string tempUpdateExeFilePath = Path.Combine(AmoebaEnvironment.Paths.WorkPath, "Amoeba.Update.exe"); if (File.Exists(tempUpdateExeFilePath)) { File.Delete(tempUpdateExeFilePath); } } if (Directory.Exists(AmoebaEnvironment.Paths.UpdatePath)) { string zipFilePath = null; // 最新のバージョンのzipを検索。 { var map = new Dictionary <string, Version>(); var regex = new Regex(@"Amoeba.+?((\d*)\.(\d*)\.(\d*)).*?\.zip", RegexOptions.Compiled); foreach (string path in Directory.GetFiles(AmoebaEnvironment.Paths.UpdatePath)) { var match = regex.Match(Path.GetFileName(path)); if (!match.Success) { continue; } var version = new Version(match.Groups[1].Value); if (version < AmoebaEnvironment.Version) { continue; } map.Add(path, version); } if (map.Count > 0) { var sortedList = map.ToList(); sortedList.Sort((x, y) => y.Value.CompareTo(x.Value)); zipFilePath = sortedList.First().Key; } } if (zipFilePath != null) { string tempUpdateDirectoryPath = Path.Combine(AmoebaEnvironment.Paths.WorkPath, "Update"); if (Directory.Exists(tempUpdateDirectoryPath)) { Directory.Delete(tempUpdateDirectoryPath, true); } using (var zipfile = new ZipFile(zipFilePath)) { zipfile.ExtractExistingFile = ExtractExistingFileAction.OverwriteSilently; zipfile.ExtractAll(tempUpdateDirectoryPath); } if (File.Exists(zipFilePath)) { File.Delete(zipFilePath); } string tempUpdateExeFilePath = Path.Combine(AmoebaEnvironment.Paths.WorkPath, "Amoeba.Update.exe"); File.Copy("Amoeba.Update.exe", tempUpdateExeFilePath); var startInfo = new ProcessStartInfo(); startInfo.FileName = Path.GetFullPath(tempUpdateExeFilePath); startInfo.Arguments = string.Format("\"{0}\" \"{1}\" \"{2}\" \"{3}\"", sessionId, Path.Combine(tempUpdateDirectoryPath, "Core"), Directory.GetCurrentDirectory(), Path.Combine(Directory.GetCurrentDirectory(), "Amoeba.Interface.exe")); startInfo.WorkingDirectory = Path.GetFullPath(Path.GetDirectoryName(tempUpdateExeFilePath)); Process.Start(startInfo); this.Shutdown(); return; } } } // 既定のフォルダを作成する。 { foreach (var propertyInfo in typeof(AmoebaEnvironment.EnvironmentPaths).GetProperties()) { string path = propertyInfo.GetValue(AmoebaEnvironment.Paths) as string; if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } } } // Tempフォルダを環境変数に登録。 { // Tempフォルダ内を掃除。 try { foreach (string path in Directory.GetFiles(AmoebaEnvironment.Paths.TempPath, "*", SearchOption.AllDirectories)) { File.Delete(path); } foreach (string path in Directory.GetDirectories(AmoebaEnvironment.Paths.TempPath, "*", SearchOption.AllDirectories)) { Directory.Delete(path, true); } } catch (Exception) { } Environment.SetEnvironmentVariable("TMP", Path.GetFullPath(AmoebaEnvironment.Paths.TempPath), EnvironmentVariableTarget.Process); Environment.SetEnvironmentVariable("TEMP", Path.GetFullPath(AmoebaEnvironment.Paths.TempPath), EnvironmentVariableTarget.Process); } // アップグレード処理。 { if (AmoebaEnvironment.Config.Version <= new Version(5, 0, 60)) { var basePath = Path.Combine(AmoebaEnvironment.Paths.ConfigPath, @"Service\Core\Cache"); Directory.CreateDirectory(Path.Combine(basePath, "Blocks")); var renameList = new List <(string oldPath, string newPath)>(); renameList.Add((@"CacheInfos.json.gz", @"ContentInfos.json.gz")); renameList.Add((@"Size.json.gz", @"Blocks\Size.json.gz")); renameList.Add((@"ClusterIndex.json.gz", @"Blocks\ClusterIndex.json.gz")); foreach (var(oldPath, newPath) in renameList) { File.Copy(Path.Combine(basePath, oldPath), Path.Combine(basePath, newPath)); } } } this.StartupUri = new Uri("Mvvm/Windows/Main/MainWindow.xaml", UriKind.Relative); } catch (Exception ex) { Log.Error(ex); this.Shutdown(); return; } }
public static byte[] CreateSwapSecretHash160(byte[] secretBytes) { return(Ripemd160.Compute(Sha256.Compute(secretBytes))); }
private void Init() { { IObservable <object> clipboardObservable; { var returnObservable = Observable.Return((object)null); var watchObservable = Observable.FromEventPattern <EventHandler, EventArgs>(h => Clipboard.ClipboardChanged += h, h => Clipboard.ClipboardChanged -= h).Select(n => (object)null); clipboardObservable = Observable.Merge(returnObservable, watchObservable); } this.TabViewModel = new ReactiveProperty <ChatCategoryViewModel>().AddTo(_disposable); this.TabSelectedItem = new ReactiveProperty <TreeViewModelBase>().AddTo(_disposable); this.TabSelectedItem.Subscribe((viewModel) => this.TabSelectChanged(viewModel)).AddTo(_disposable); this.Info = new ReactiveProperty <AvalonEditChatMessagesInfo>().AddTo(_disposable); this.SelectedText = new ReactiveProperty <string>().AddTo(_disposable); this.TabClickCommand = new ReactiveCommand().AddTo(_disposable); this.TabClickCommand.Where(n => n == this.TabSelectedItem.Value).Subscribe((_) => this.Refresh()).AddTo(_disposable); this.TabNewCategoryCommand = this.TabSelectedItem.Select(n => n is ChatCategoryViewModel).ToReactiveCommand().AddTo(_disposable); this.TabNewCategoryCommand.Subscribe(() => this.TabNewCategory()).AddTo(_disposable); this.TabEditCommand = this.TabSelectedItem.Select(n => n is ChatCategoryViewModel).ToReactiveCommand().AddTo(_disposable); this.TabEditCommand.Subscribe(() => this.TabEdit()).AddTo(_disposable); this.TabDeleteCommand = this.TabSelectedItem.Select(n => n != this.TabViewModel.Value).ToReactiveCommand().AddTo(_disposable); this.TabDeleteCommand.Subscribe(() => this.TabDelete()).AddTo(_disposable); this.TabCutCommand = new ReactiveCommand().AddTo(_disposable); this.TabCutCommand.Subscribe(() => this.TabCut()).AddTo(_disposable); this.TabCopyCommand = new ReactiveCommand().AddTo(_disposable); this.TabCopyCommand.Subscribe(() => this.TabCopy()).AddTo(_disposable); this.TabPasteCommand = this.TabSelectedItem.Select(n => n is ChatCategoryViewModel) .CombineLatest(clipboardObservable.Select(n => Clipboard.ContainsTags() || Clipboard.ContainsChatCategoryInfo() || Clipboard.ContainsChatThreadInfo()), (r1, r2) => r1 && r2).ToReactiveCommand().AddTo(_disposable); this.TabPasteCommand.Subscribe(() => this.TabPaste()).AddTo(_disposable); this.TabTagListCommand = this.TabSelectedItem.Select(n => n is ChatCategoryViewModel).ToReactiveCommand().AddTo(_disposable); this.TabTagListCommand.Subscribe(() => this.TabTagList()).AddTo(_disposable); this.TrustFilterCommand = this.TabSelectedItem.Select(n => n is ChatThreadViewModel).ToReactiveCommand().AddTo(_disposable); this.TrustFilterCommand.Subscribe(() => this.TrustFilter()).AddTo(_disposable); this.IsTrustFilterEnable = new ReactiveProperty <bool>().AddTo(_disposable); this.NewFilterCommand = this.TabSelectedItem.Select(n => n is ChatThreadViewModel).ToReactiveCommand().AddTo(_disposable); this.NewFilterCommand.Subscribe(() => this.NewFilter()).AddTo(_disposable); this.IsNewFilterEnable = new ReactiveProperty <bool>().AddTo(_disposable); this.MiningLimits = new ObservableCollection <int>(Enumerable.Range(0, 256 + 1)); this.SelectedMiningLimit = new ReactiveProperty <int>().AddTo(_disposable); this.SelectedMiningLimit.Subscribe((_) => this.Refresh()).AddTo(_disposable); this.NewMessageCommand = this.TabSelectedItem.Select(n => n is ChatThreadViewModel).ToReactiveCommand().AddTo(_disposable); this.NewMessageCommand.Subscribe(() => this.NewMessage()).AddTo(_disposable); this.CopyCommand = this.SelectedText.Select(n => !string.IsNullOrEmpty(n)).ToReactiveCommand().AddTo(_disposable); this.CopyCommand.Subscribe(() => this.Copy()).AddTo(_disposable); this.ResponseCommand = this.SelectedText.Select(n => !string.IsNullOrEmpty(n)).ToReactiveCommand().AddTo(_disposable); this.ResponseCommand.Subscribe(() => this.Response()).AddTo(_disposable); } { string configPath = Path.Combine(AmoebaEnvironment.Paths.ConfigPath, "View", nameof(ChatControl)); if (!Directory.Exists(configPath)) { Directory.CreateDirectory(configPath); } _settings = new Settings(configPath); int version = _settings.Load("Version", () => 0); { var model = _settings.Load("ChatCategoryInfo", () => { var categoryInfo = new ChatCategoryInfo() { Name = "Category", IsExpanded = true }; categoryInfo.ThreadInfos.Add(new ChatThreadInfo() { Tag = new Tag("Amoeba", Sha256.Compute("Amoeba")) }); categoryInfo.ThreadInfos.Add(new ChatThreadInfo() { Tag = new Tag("Random", Sha256.Compute("Random")) }); return(categoryInfo); }); this.TabViewModel.Value = new ChatCategoryViewModel(null, model); } this.SelectedMiningLimit.Value = _settings.Load("MiningLimit", () => 0); this.DynamicOptions.SetProperties(_settings.Load(nameof(DynamicOptions), () => Array.Empty <DynamicOptions.DynamicPropertyInfo>())); } { Backup.Instance.SaveEvent += this.Save; } }
public string UserId() { return(Sha256.Compute(Sha256.Compute(PublicKey)).ToHexString()); }
public void Save(Stream output, IList <IArchiveFileInfo> files) { var ciaAfis = files.Cast <CiaArchiveFileInfo>().ToArray(); var sha = new Sha256(); // Update content chunks foreach (var ciaAfi in ciaAfis) { var ncchStream = ciaAfi.GetFileData().Result; ciaAfi.ContentChunkRecord.sha256 = sha.Compute(ncchStream); ciaAfi.ContentChunkRecord.contentSize = ncchStream.Length; } _tmd.contentChunkRecords = ciaAfis.Select(x => x.ContentChunkRecord).ToArray(); // Write content chunks var contentChunkStream = new MemoryStream(); using (var chunkBw = new BinaryWriterX(contentChunkStream, true)) chunkBw.WriteMultiple(_tmd.contentChunkRecords); // Update content info records foreach (var contentInfoRecord in _tmd.contentInfoRecords) { if (contentInfoRecord.contentChunkCount == 0) { continue; } var offset = contentInfoRecord.contentChunkIndex * _contentChunkRecordSize; var size = contentInfoRecord.contentChunkCount * _contentChunkRecordSize; contentInfoRecord.sha256 = sha.Compute(new SubStream(contentChunkStream, offset, size)); } // Write content info records var contentInfoStream = new MemoryStream(); using (var infoBw = new BinaryWriterX(contentInfoStream, true)) infoBw.WriteMultiple(_tmd.contentInfoRecords); // Update content info hash contentInfoStream.Position = 0; _tmd.header.sha256 = sha.Compute(contentInfoStream); // --- Write CIA --- using var bw = new BinaryWriterX(output); var ciaOffset = bw.BaseStream.Position = _headerSize; // Write certificate chain bw.WriteType(_certChain); _header.certChainSize = (int)(bw.BaseStream.Length - ciaOffset); bw.WriteAlignment(0x40); ciaOffset = bw.BaseStream.Length; // Write ticket bw.WriteType(_ticket); _header.ticketSize = (int)(bw.BaseStream.Length - ciaOffset); bw.WriteAlignment(0x40); ciaOffset = bw.BaseStream.Length; // Write TMD bw.WriteType(_tmd); _header.tmdSize = (int)(bw.BaseStream.Length - ciaOffset); bw.WriteAlignment(0x40); ciaOffset = bw.BaseStream.Length; // Write content foreach (var ciaAfi in ciaAfis) { ciaAfi.SaveFileData(bw.BaseStream); } _header.contentSize = bw.BaseStream.Length - ciaOffset; bw.WriteAlignment(0x40); ciaOffset = bw.BaseStream.Length; // Write meta data if (_meta != null) { bw.WriteType(_meta); _header.metaSize = (int)(bw.BaseStream.Length - ciaOffset); bw.WriteAlignment(0x40); } // Write header bw.BaseStream.Position = 0; bw.WriteType(_header); }
public void CheckBrokenTest() { string targetPath = Path.Combine(_workPath, "CheckBroken"); string configPath = Path.Combine(targetPath, "CacheManager"); string blockPath = Path.Combine(targetPath, "cache.blocks");; Directory.CreateDirectory(targetPath); Directory.CreateDirectory(configPath); var list = new List <Hash>(); { var cacheManager = new CacheManager(configPath, blockPath, _bufferManager); cacheManager.Load(); for (int i = 0; i < 256; i++) { int size = _random.Next(1, 1024 * 256); using (var safeBuffer = _bufferManager.CreateSafeBuffer(size)) { _random.NextBytes(safeBuffer.Value); var block = new ArraySegment <byte>(safeBuffer.Value, 0, size); var hash = new Hash(HashAlgorithm.Sha256, Sha256.Compute(block)); cacheManager.Set(hash, block); list.Add(hash); } } cacheManager.Save(); cacheManager.Dispose(); } using (var stream = new FileStream(blockPath, FileMode.Open)) { int b = stream.ReadByte(); stream.Seek(0, SeekOrigin.Begin); stream.WriteByte((byte)(b ^ 0xFF)); } { var cacheManager = new CacheManager(configPath, blockPath, _bufferManager); cacheManager.Load(); Assert.True(new HashSet <Hash>(list).SetEquals(cacheManager.ToArray())); Assert.Throws <BlockNotFoundException>(() => { var result = cacheManager.GetBlock(list[0]); }); foreach (var hash in list.Skip(1)) { var result = cacheManager.GetBlock(hash); _bufferManager.ReturnBuffer(result.Array); } cacheManager.Save(); cacheManager.Dispose(); } }
public static byte[] CreateSwapSecretHash(byte[] secretBytes) { return(Sha256.Compute(secretBytes, 2)); }
public ArraySegment <byte> GetBlock(Hash hash) { // Cache { var result = _blocksManager.Get(hash); if (result != null) { return(result.Value); } } // Share { ArraySegment <byte>?result = null; string path = null; lock (_lockObject) { var shareInfo = _contentInfoManager.GetShareInfo(hash); if (shareInfo != null) { var buffer = _bufferManager.TakeBuffer(shareInfo.BlockLength); try { int length; try { using (var stream = new UnbufferedFileStream(shareInfo.Path, FileMode.Open, FileAccess.Read, FileShare.Read, FileOptions.None, _bufferManager)) { stream.Seek((long)shareInfo.GetIndex(hash) * shareInfo.BlockLength, SeekOrigin.Begin); length = (int)Math.Min(stream.Length - stream.Position, shareInfo.BlockLength); stream.Read(buffer, 0, length); } } catch (ArgumentOutOfRangeException) { throw new BlockNotFoundException(); } catch (IOException) { throw new BlockNotFoundException(); } result = new ArraySegment <byte>(buffer, 0, length); path = shareInfo.Path; } catch (Exception) { _bufferManager.ReturnBuffer(buffer); throw; } } } if (result != null) { if (hash.Algorithm == HashAlgorithm.Sha256 && Unsafe.Equals(Sha256.Compute(result.Value), hash.Value)) { return(result.Value); } else { _bufferManager.ReturnBuffer(result.Value.Array); result = null; this.RemoveContent(path); } } } throw new BlockNotFoundException(); }