Exemple #1
0
        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;
            }
        }
Exemple #2
0
        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());
                }
            }
        }