Ejemplo n.º 1
0
        public override int Read(byte[] buffer, int offset, int count)
        {
            int originalCount = count;

            while (count > 0)
            {
                int bytesRead = _blockBuffer.Read(buffer, offset, count);
                if (bytesRead > 0)
                {
                    offset += bytesRead;
                    count  -= bytesRead;
                    continue;
                }

                if (_inStream.IsEmpty(_blockBuffer.Length))
                {
                    break;
                }

                byte[] block = new byte[_blockBuffer.Length];
                bytesRead = _inStream.Read(block, 0, block.Length);
                if (_inStream.IsEmpty(_blockBuffer.Length))
                {
                    byte[] finalOutput = _transform.TransformFinalBlock(block, 0, bytesRead);
                    _blockBuffer = new ByteBuffer(finalOutput);
                    continue;
                }

                _blockBuffer.AvailableForWrite = _blockBuffer.Length;
                int bytesTransformed = _transform.TransformBlock(block, 0, bytesRead, _blockBuffer.GetBuffer(), 0);
                _blockBuffer.AvailableForRead = bytesTransformed;
            }
            return(originalCount - count);
        }
Ejemplo n.º 2
0
        private void LookForMagicGuid()
        {
            byte[] buffer = new byte[OS.Current.StreamBufferSize];
            while (true)
            {
                int bytesRead = _inputStream.Read(buffer, 0, buffer.Length);
                if (bytesRead < AxCrypt1Guid.Length)
                {
                    _inputStream.Pushback(buffer, 0, bytesRead);
                    CurrentItemType = AxCryptItemType.EndOfStream;
                    return;
                }

                int i = buffer.Locate(_axCrypt1GuidBytes, 0, bytesRead);
                if (i < 0)
                {
                    int offsetToBytesToKeep = bytesRead - AxCrypt1Guid.Length + 1;
                    _inputStream.Pushback(buffer, offsetToBytesToKeep, bytesRead - offsetToBytesToKeep);
                    continue;
                }
                int offsetJustAfterTheGuid = i + AxCrypt1Guid.Length;
                _inputStream.Pushback(buffer, offsetJustAfterTheGuid, bytesRead - offsetJustAfterTheGuid);
                CurrentItemType = AxCryptItemType.MagicGuid;
                return;
            }
        }
Ejemplo n.º 3
0
        public static void TestLookAheadStream()
        {
            Assert.Throws <ArgumentNullException>(() =>
            {
                using (Stream stream = new LookAheadStream(null)) { }
            }, "Input stream cannot be null.");

            Assert.Throws <ArgumentException>(() =>
            {
                using (Stream writeOnlyStream = new DeflateStream(new MemoryStream(), CompressionMode.Compress))
                {
                    using (Stream stream = new LookAheadStream(writeOnlyStream)) { }
                }
            }, "The input stream must support reading.");

            using (Stream inputStream = new MemoryStream())
            {
                byte[] inData = Encoding.UTF8.GetBytes("0123456789");
                inputStream.Write(inData, 0, inData.Length);
                inputStream.Position = 0;
                using (LookAheadStream lookAheadStream = new LookAheadStream(inputStream))
                {
                    Assert.That(lookAheadStream.CanRead, Is.True, "The stream always supports reading.");
                    Assert.That(lookAheadStream.CanSeek, Is.False, "The stream does not support seeking.");
                    Assert.That(lookAheadStream.CanWrite, Is.False, "The stream does not support writing.");
                    Assert.Throws <NotSupportedException>(() =>
                    {
                        long length = lookAheadStream.Length;

                        // Make FxCop not complain
                        Object.Equals(length, null);
                    });
                    Assert.Throws <NotSupportedException>(() =>
                    {
                        long position = lookAheadStream.Position;

                        // Make FxCop not complain
                        Object.Equals(position, null);
                    });
                    Assert.Throws <NotSupportedException>(() =>
                    {
                        lookAheadStream.Position = 0;
                    });
                    Assert.Throws <NotSupportedException>(() =>
                    {
                        lookAheadStream.Seek(0, SeekOrigin.Begin);
                    });
                    Assert.Throws <NotSupportedException>(() =>
                    {
                        lookAheadStream.SetLength(0);
                    });
                    Assert.Throws <NotSupportedException>(() =>
                    {
                        lookAheadStream.Write(new byte[1], 0, 1);
                    });

                    int    count;
                    byte[] buffer;

                    lookAheadStream.Pushback(new byte[] { 0x99 }, 0, 1);
                    buffer = new byte[1];
                    count  = lookAheadStream.Read(buffer, 0, 1);
                    Assert.That(count, Is.EqualTo(1), "One byte was read.");
                    Assert.That(buffer[0], Is.EqualTo(0x99), "A byte with value 0x99 was pushed back.");

                    buffer = new byte[5];
                    count  = lookAheadStream.Read(buffer, 0, buffer.Length);
                    Assert.That(count, Is.EqualTo(5), "Five bytes were read.");
                    Assert.That(buffer, Is.EquivalentTo(new byte[] { 48, 49, 50, 51, 52 }), "The string '01234' was read.");

                    lookAheadStream.Pushback(new byte[] { 52 }, 0, 1);
                    lookAheadStream.Pushback(new byte[] { 51 }, 0, 1);
                    lookAheadStream.Pushback(new byte[] { 48, 49, 50 }, 0, 3);

                    // Nothing should happen, this is a pure dummy call.
                    lookAheadStream.Flush();

                    buffer = new byte[10];
                    bool exactWasRead = lookAheadStream.ReadExact(buffer);
                    Assert.That(exactWasRead, Is.True, "Ten bytes were read.");
                    Assert.That(buffer, Is.EquivalentTo(new byte[] { 48, 49, 50, 51, 52, 53, 54, 55, 56, 57 }), "The string '0123456789' was read.");

                    // This also implicitly tests double-dispose since we're in a using block
                    lookAheadStream.Dispose();
                    Assert.Throws <ObjectDisposedException>(() =>
                    {
                        buffer = new byte[3];
                        lookAheadStream.Read(buffer, 0, 3);
                    });

                    Assert.Throws <ObjectDisposedException>(() =>
                    {
                        buffer = new byte[5];
                        lookAheadStream.ReadExact(buffer);
                    });

                    Assert.Throws <ObjectDisposedException>(() =>
                    {
                        buffer = new byte[5];
                        lookAheadStream.Pushback(buffer, 0, buffer.Length);
                    });
                }
            }
        }
Ejemplo n.º 4
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());
                }
            }
        }
Ejemplo n.º 5
0
        private static void ReadMultiPartFormData(Connection con, WebRequest request, string contentType, Stream bodyStream)
        {
            request.PostVars = new NameValueCollection();
            int boundaryOffset = contentType.IndexOf("boundary=");

            if (boundaryOffset < 0)
            {
                return;
            }
            string          boundary        = contentType.Substring(boundaryOffset + 9);
            LookAheadStream lookAheadStream = new LookAheadStream(bodyStream, 200);

            // Read and discard the preamble.
            MultiPartMIMEStream multiPartStream = new MultiPartMIMEStream(lookAheadStream, "--" + boundary);

            for (; ;)
            {
                byte[] discardBuffer = new byte[100];
                if (multiPartStream.Read(discardBuffer, 0, discardBuffer.Length) == 0)
                {
                    break;
                }
            }
            multiPartStream.SkipBoundary();

            // Read and save any following parts.
            for (; ;)
            {
                if (multiPartStream.LastPartRead || multiPartStream.TotalBytesRead == 0)
                {
                    break;
                }
                multiPartStream = new MultiPartMIMEStream(lookAheadStream, "\r\n--" + boundary);
                bool connectionBroken;
                NameValueCollection headers = ReadAllHeaders(multiPartStream, out connectionBroken);
                if (connectionBroken)
                {
                    con.ConnectionBroken = true;
                }
                using (MemoryStream memStream = new MemoryStream())
                {
                    using (BufferedStream partBody = new BufferedStream(memStream, 1024))
                    {
                        multiPartStream.CopyTo(partBody, 1024);
                        multiPartStream.SkipBoundary();
                        partBody.Flush();
                        partBody.Seek(0, SeekOrigin.Begin);
                        string contentDisposition = headers.Get(HttpHeaders.ContentDisposition);
                        if (contentDisposition != null)
                        {
                            // save uploaded files in data structures compatible with the way ASP.NET exposes them
                            string[] parts         = contentDisposition.Split(';');
                            bool     formDataFound = false;
                            string   name          = null;
                            string   filename      = null;
                            foreach (string part in parts)
                            {
                                string trimmedPart = part.Trim();
                                if (trimmedPart == "form-data")
                                {
                                    formDataFound = true;
                                }
                                else if (trimmedPart.StartsWith("name=\""))
                                {
                                    name = trimmedPart.Substring(6, trimmedPart.Length - 7);
                                }
                                else if (trimmedPart.StartsWith("filename=\""))
                                {
                                    filename = trimmedPart.Substring(10, trimmedPart.Length - 11);
                                }
                            }
                            if (!formDataFound)
                            {
                                throw new InvalidDataException();
                            }
                            if (filename != null)
                            {
                                AddNameValuePair(request.PostVars, name, filename);
                                partBody.Seek(0, SeekOrigin.Begin);
                                string fileContentType = headers.Get(HttpHeaders.ContentType);
                                if (string.IsNullOrEmpty(fileContentType))
                                {
                                    fileContentType = HttpHeaders.ContentType_TextPlain;
                                }
                                WebUploadedFile file = new WebUploadedFile(filename, partBody, partBody.Length, fileContentType);
                                request.UploadedFiles.Add(name, file);
                            }
                            else
                            {
                                string value;
                                bool   ignoreConnectionBroken;
                                Connection.ReadAsciiUntilEnd(partBody, out value, out ignoreConnectionBroken);
                                AddNameValuePair(request.PostVars, name, value);
                            }
                        }
                    }
                }
            }

            // Discard the epilogue
            for (; ;)
            {
                byte[] discardBuffer = new byte[100];
                if (lookAheadStream.Read(discardBuffer, 0, discardBuffer.Length) == 0)
                {
                    break;
                }
            }
        }