private void LookForHeaderBlock() { byte[] lengthBytes = new byte[sizeof(Int32)]; if (!_inputStream.ReadExact(lengthBytes)) { CurrentItemType = AxCryptItemType.EndOfStream; return; } Int32 headerBlockLength = BitConverter.ToInt32(lengthBytes, 0) - 5; if (headerBlockLength < 0 || headerBlockLength > 0xfffff) { throw new FileFormatException("Invalid headerBlockLength {0}".InvariantFormat(headerBlockLength), ErrorStatus.FileFormatError); } int blockType = _inputStream.ReadByte(); if (blockType > 127) { throw new FileFormatException("Invalid block type {0}".InvariantFormat(blockType), ErrorStatus.FileFormatError); } HeaderBlockType headerBlockType = (HeaderBlockType)blockType; byte[] dataBLock = new byte[headerBlockLength]; if (!_inputStream.ReadExact(dataBLock)) { CurrentItemType = AxCryptItemType.EndOfStream; return; } ParseHeaderBlock(headerBlockType, dataBLock); DataHeaderBlock dataHeaderBlock = CurrentHeaderBlock as DataHeaderBlock; if (dataHeaderBlock != null) { CurrentItemType = AxCryptItemType.Data; } }
private bool VerifyInternalUnsafe() { if (!_inputStream.Locate(_axCrypt1GuidBytes)) { return(FailWithStatusReport("Not an AxCrypt file, No magic Guid was found.")); } _statusReport.Add($"{nameof(AxCryptItemType.MagicGuid)} Ok with length {0}".InvariantFormat(AxCrypt1Guid.Length)); AxCryptVersion version = AxCryptVersion.Unknown; ulong encryptedDataLength = 0; int dataBlocks = 0; while (true) { byte[] lengthBytes = new byte[sizeof(Int32)]; if (_inputStream.Read(lengthBytes, 0, lengthBytes.Length) != lengthBytes.Length) { return(FailWithStatusReport("End of stream reading header block length.")); } int headerBlockLength = BitConverter.ToInt32(lengthBytes, 0) - 5; int blockType = _inputStream.ReadByte(); if (blockType > 127 || blockType < 0) { return(FailWithStatusReport($"Unexpected header block type {blockType}")); } if (headerBlockLength < 0) { return(FailWithStatusReport($"Invalid block length {headerBlockLength}.")); } byte[] dataBlock = new byte[headerBlockLength]; if (_inputStream.Read(dataBlock, 0, headerBlockLength) != dataBlock.Length) { return(FailWithStatusReport($"End of stream reading block type {blockType}")); } HeaderBlockType headerBlockType = (HeaderBlockType)blockType; if (headerBlockType == HeaderBlockType.Data && version == AxCryptVersion.Version1) { return(ProcessVersion1DataBlock(dataBlock)); } if (headerBlockType != HeaderBlockType.EncryptedDataPart && dataBlocks > 0) { _statusReport.Add($"{HeaderBlockType.EncryptedDataPart} Ok with {dataBlocks} blocks and the total length {encryptedDataLength}."); dataBlocks = 0; encryptedDataLength = 0; } switch (headerBlockType) { case HeaderBlockType.Version: VersionHeaderBlock versionHeaderBlock = new VersionHeaderBlock(dataBlock); _statusReport.Add($"AxCrypt version {versionHeaderBlock.VersionMajor}.{versionHeaderBlock.VersionMinor}.{versionHeaderBlock.VersionMinuscule}. File format version {versionHeaderBlock.FileVersionMajor}.{versionHeaderBlock.FileVersionMinor}."); version = versionHeaderBlock.VersionMajor >= 2 ? AxCryptVersion.Version2 : AxCryptVersion.Version1; break; case HeaderBlockType.EncryptedDataPart: switch (version) { case AxCryptVersion.Version2: ++dataBlocks; encryptedDataLength += (uint)dataBlock.Length; break; case AxCryptVersion.Unknown: default: return(FailWithStatusReport($"{blockType} found but no {HeaderBlockType.Version} seen.")); } break; default: _statusReport.Add($"{headerBlockType} Ok with length {headerBlockLength}"); break; } if (headerBlockType == HeaderBlockType.V2Hmac) { return(ShowStatusReport()); } } }