Beispiel #1
0
        public EncryptionInfo(DirectoryNode dir)
        {
            DocumentInputStream dis = dir.CreateDocumentInputStream("EncryptionInfo");
            versionMajor = dis.ReadShort();
            versionMinor = dis.ReadShort();

            encryptionFlags = dis.ReadInt();

            if (versionMajor == 4 && versionMinor == 4 && encryptionFlags == 0x40)
            {
                StringBuilder builder = new StringBuilder();
                byte[] xmlDescriptor = new byte[dis.Available()];
                dis.Read(xmlDescriptor);
                foreach (byte b in xmlDescriptor)
                    builder.Append((char)b);
                string descriptor = builder.ToString();
                header = new EncryptionHeader(descriptor);
                verifier = new EncryptionVerifier(descriptor);
            }
            else
            {
                int hSize = dis.ReadInt();
                header = new EncryptionHeader(dis);
                if (header.Algorithm == EncryptionHeader.ALGORITHM_RC4)
                {
                    verifier = new EncryptionVerifier(dis, 20);
                }
                else
                {
                    verifier = new EncryptionVerifier(dis, 32);
                }
            }
        }
        PropertySet GetPropertySet(DirectoryNode dir, string name)
        {
            DocumentInputStream dis = dir.CreateDocumentInputStream(name);
            PropertySet         set = PropertySetFactory.Create(dis);

            return(set);
        }
Beispiel #3
0
        public override Stream GetDataStream(DirectoryNode dir)
        {
            DocumentInputStream dr = dir.CreateDocumentInputStream("EncryptedPackage");
            long size = dr.ReadLong();

            return(new ChunkedCipherInputStream(dr, size, this));
        }
Beispiel #4
0
        public override Stream GetDataStream(DirectoryNode dir)
        {
            DocumentInputStream dis = dir.CreateDocumentInputStream("EncryptedPackage");

            _length = dis.ReadLong();
            return(new ChunkedCipherInputStream(dis, _length, this));
        }
Beispiel #5
0
        public EncryptionInfo(DirectoryNode dir)
        {
            DocumentInputStream dis = dir.CreateDocumentInputStream("EncryptionInfo");
            versionMajor = dis.ReadShort();
            versionMinor = dis.ReadShort();

            encryptionFlags = dis.ReadInt();

            if (versionMajor == 4 && versionMinor == 4 && encryptionFlags == 0x40)
            {
                StringBuilder builder = new StringBuilder();
                byte[] xmlDescriptor = new byte[dis.Available()];
                dis.Read(xmlDescriptor);
                foreach (byte b in xmlDescriptor)
                    builder.Append((char)b);
                string descriptor = builder.ToString();
                header = new EncryptionHeader(descriptor);
                verifier = new EncryptionVerifier(descriptor);
            }
            else
            {
                int hSize = dis.ReadInt();
                header = new EncryptionHeader(dis);
                if (header.Algorithm == EncryptionHeader.ALGORITHM_RC4)
                {
                    verifier = new EncryptionVerifier(dis, 20);
                }
                else
                {
                    verifier = new EncryptionVerifier(dis, 32);
                }
            }
        }
Beispiel #6
0
        public override Stream GetDataStream(DirectoryNode dir)
        {
            DocumentInputStream dr = dir.CreateDocumentInputStream("EncryptedPackage");
            long size = dr.ReadLong();
            SymmetricAlgorithm cipher = GetCipher();

            return(new CryptoStream(dr, cipher.CreateDecryptor(cipher.Key, cipher.IV), CryptoStreamMode.Read));
        }
Beispiel #7
0
        public override InputStream GetDataStream(DirectoryNode dir)
        {
            DocumentInputStream dis = dir.CreateDocumentInputStream(DEFAULT_POIFS_ENTRY);

            _length = dis.ReadLong();
            BinaryRC4CipherInputStream cipherStream = new BinaryRC4CipherInputStream(dis, _length, this);

            //return cipherStream.GetStream();
            throw new NotImplementedException("BinaryRC4CipherInputStream should be derived from InputStream");
        }
Beispiel #8
0
        /**
         * Decrypt the Document-/SummaryInformation and other optionally streams.
         * Opposed to other crypto modes, cryptoapi is record based and can't be used
         * to stream-decrypt a whole file
         *
         * @see <a href="http://msdn.microsoft.com/en-us/library/dd943321(v=office.12).aspx">2.3.5.4 RC4 CryptoAPI Encrypted Summary Stream</a>
         */

        public override InputStream GetDataStream(DirectoryNode dir)
        {
            NPOIFSFileSystem    fsOut = new NPOIFSFileSystem();
            DocumentNode        es    = (DocumentNode)dir.GetEntry("EncryptedSummary");
            DocumentInputStream dis   = dir.CreateDocumentInputStream(es);
            MemoryStream        bos   = new MemoryStream();

            IOUtils.Copy(dis, bos);
            dis.Close();
            SeekableMemoryStream    sbis    = new SeekableMemoryStream(bos.ToArray());
            LittleEndianInputStream leis    = new LittleEndianInputStream(sbis);
            int streamDescriptorArrayOffset = (int)leis.ReadUInt();
            int streamDescriptorArraySize   = (int)leis.ReadUInt();

            sbis.Seek(streamDescriptorArrayOffset - 8, SeekOrigin.Current);// sbis.Skip(streamDescriptorArrayOffset - 8);

            sbis.SetBlock(0);
            int encryptedStreamDescriptorCount = (int)leis.ReadUInt();

            StreamDescriptorEntry[] entries = new StreamDescriptorEntry[encryptedStreamDescriptorCount];
            for (int i = 0; i < encryptedStreamDescriptorCount; i++)
            {
                StreamDescriptorEntry entry = new StreamDescriptorEntry();
                entries[i]         = entry;
                entry.streamOffset = (int)leis.ReadUInt();
                entry.streamSize   = (int)leis.ReadUInt();
                entry.block        = leis.ReadUShort();
                int nameSize = leis.ReadUByte();
                entry.flags = leis.ReadUByte();
                bool IsStream = StreamDescriptorEntry.flagStream.IsSet(entry.flags);
                entry.reserved2  = leis.ReadInt();
                entry.streamName = StringUtil.ReadUnicodeLE(leis, nameSize);
                leis.ReadShort();
                Debug.Assert(entry.streamName.Length == nameSize);
            }

            foreach (StreamDescriptorEntry entry in entries)
            {
                sbis.Seek(entry.streamOffset);
                sbis.SetBlock(entry.block);
                Stream is1 = new BufferedStream(sbis, entry.streamSize);
                fsOut.CreateDocument(is1, entry.streamName);
            }

            leis.Close();
            sbis = null;

            bos.Seek(0, SeekOrigin.Begin); //bos.Reset();
            fsOut.WriteFileSystem(bos);
            fsOut.Close();
            _length = bos.Length;
            ByteArrayInputStream bis = new ByteArrayInputStream(bos.ToArray());

            throw new NotImplementedException("ByteArrayInputStream should be derived from InputStream");
        }
Beispiel #9
0
        public override InputStream GetDataStream(DirectoryNode dir)
        {
            DocumentInputStream dis = dir.CreateDocumentInputStream(DEFAULT_POIFS_ENTRY);

            _length = dis.ReadLong();

            var stream = new AgileCipherInputStream(dis, _length, builder, this);

            stream.Position = 0;
            return(stream);
        }
Beispiel #10
0
        private void Open(DirectoryNode directory)
        {
            DocumentNode book = (DocumentNode)directory.GetEntry("Book");

            if (book == null)
            {
                throw new IOException("No Excel 5/95 Book stream found");
            }

            ris = new RecordInputStream(directory.CreateDocumentInputStream(book));
            Prepare();
        }
Beispiel #11
0
        public void TestReadMultipleTreeLevels()
        {
            POIDataSamples _samples = POIDataSamples.GetPublisherInstance();
            FileStream     sample   = _samples.GetFile("Sample.pub");

            DocumentInputStream stream;

            NPOIFSFileSystem npoifs = new NPOIFSFileSystem(sample);

            try
            {
                sample = _samples.GetFile("Sample.pub");
                OPOIFSFileSystem opoifs = new OPOIFSFileSystem(sample);

                // Ensure we have what we expect on the root
                Assert.AreEqual(npoifs, npoifs.Root.NFileSystem);
                Assert.AreEqual(npoifs, npoifs.Root.FileSystem);
                Assert.AreEqual(null, npoifs.Root.OFileSystem);
                Assert.AreEqual(null, opoifs.Root.FileSystem);
                Assert.AreEqual(opoifs, opoifs.Root.OFileSystem);
                Assert.AreEqual(null, opoifs.Root.NFileSystem);

                // Check inside
                foreach (DirectoryNode root in new DirectoryNode[] { opoifs.Root, npoifs.Root })
                {
                    // Top Level
                    Entry top = root.GetEntry("Contents");
                    Assert.AreEqual(true, top.IsDocumentEntry);
                    stream = root.CreateDocumentInputStream(top);
                    stream.Read();

                    // One Level Down
                    DirectoryNode escher = (DirectoryNode)root.GetEntry("Escher");
                    Entry         one    = escher.GetEntry("EscherStm");
                    Assert.AreEqual(true, one.IsDocumentEntry);
                    stream = escher.CreateDocumentInputStream(one);
                    stream.Read();

                    // Two Levels Down
                    DirectoryNode quill    = (DirectoryNode)root.GetEntry("Quill");
                    DirectoryNode quillSub = (DirectoryNode)quill.GetEntry("QuillSub");
                    Entry         two      = quillSub.GetEntry("CONTENTS");
                    Assert.AreEqual(true, two.IsDocumentEntry);
                    stream = quillSub.CreateDocumentInputStream(two);
                    stream.Read();
                }
            }
            finally
            {
                npoifs.Close();
            }
        }
Beispiel #12
0
        public override InputStream GetDataStream(DirectoryNode dir)
        {
            DocumentInputStream dis = dir.CreateDocumentInputStream(Encryptor.DEFAULT_POIFS_ENTRY);

            _length = dis.ReadLong();

            // limit wrong calculated ole entries - (bug #57080)
            // standard encryption always uses aes encoding, so blockSize is always 16
            // http://stackoverflow.com/questions/3283787/size-of-data-after-aes-encryption
            int    blockSize = builder.GetHeader().CipherAlgorithm.blockSize;
            long   cipherLen = (_length / blockSize + 1) * blockSize;
            Cipher cipher    = GetCipher(GetSecretKey());


            ByteArrayInputStream boundedDis = new BoundedInputStream(dis, cipherLen);

            return(new BoundedInputStream(new CipherInputStream(boundedDis, cipher), _length));
        }
Beispiel #13
0
        private void Open(DirectoryNode directory)
        {
            DocumentNode book;

            try
            {
                book = (DocumentNode)directory.GetEntry(InternalWorkbook.OLD_WORKBOOK_DIR_ENTRY_NAME);
            }
            catch (FileNotFoundException)
            {
                // some files have "Workbook" instead
                book = (DocumentNode)directory.GetEntry(InternalWorkbook.WORKBOOK_DIR_ENTRY_NAMES[0]);
            }
            if (book == null)
            {
                throw new IOException("No Excel 5/95 Book stream found");
            }

            ris = new RecordInputStream(directory.CreateDocumentInputStream(book));
            Prepare();
        }
Beispiel #14
0
        /// <summary>
        /// For a given named property entry, either return it or null if
        /// if it wasn't found
        /// </summary>
        /// <param name="SetName">Name of the set.</param>
        /// <returns></returns>
        protected PropertySet GetPropertySet(String SetName)
        {
            //directory can be null when creating new documents
            if (directory == null)
            {
                return(null);
            }
            DocumentInputStream dis;

            try
            {
                // Find the entry, and Get an input stream for it
                dis = directory.CreateDocumentInputStream(SetName);
            }
            catch (IOException)
            {
                // Oh well, doesn't exist
                //logger.Log(POILogger.WARN, "Error Getting property Set with name " + SetName + "\n" + ie);
                return(null);
            }

            try
            {
                // Create the Property Set
                PropertySet Set = PropertySetFactory.Create(dis);
                return(Set);
            }
            catch (IOException)
            {
                // Must be corrupt or something like that
                //logger.Log(POILogger.WARN, "Error creating property Set with name " + SetName + "\n" + ie);
            }
            catch (HPSFException)
            {
                // Oh well, doesn't exist
                //logger.Log(POILogger.WARN, "Error creating property Set with name " + SetName + "\n" + he);
            }
            return(null);
        }
Beispiel #15
0
        /// <summary>
        /// Creates an instance of this class from an embedded OLE Object. The OLE Object is expected
        /// to include a stream &quot;{01}Ole10Native&quot; which contains the actual
        /// data relevant for this class.
        /// </summary>
        /// <param name="directory">directory POI Filesystem object</param>
        /// <returns>Returns an instance of this class</returns>
        public static Ole10Native CreateFromEmbeddedOleObject(DirectoryNode directory)
        {
            DocumentEntry nativeEntry =
               (DocumentEntry)directory.GetEntry(OLE10_NATIVE);
            byte[] data = new byte[nativeEntry.Size];
            directory.CreateDocumentInputStream(nativeEntry).Read(data);

            return new Ole10Native(data, 0);
        }
Beispiel #16
0
        /**
         * Opens for decryption
         */

        public EncryptionInfo(DirectoryNode dir)
            : this(dir.CreateDocumentInputStream("EncryptionInfo"), false)
        {
        }
Beispiel #17
0
 public override Stream GetDataStream(DirectoryNode dir)
 {
     DocumentInputStream dr = dir.CreateDocumentInputStream("EncryptedPackage");
     long size = dr.ReadLong();
     SymmetricAlgorithm cipher=GetCipher();
     return new CryptoStream(dr, cipher.CreateDecryptor(cipher.Key, cipher.IV), CryptoStreamMode.Read);
 }
 public override Stream GetDataStream(DirectoryNode dir)
 {
     DocumentInputStream dr = dir.CreateDocumentInputStream("EncryptedPackage");
     long size = dr.ReadLong();
     return new ChunkedCipherInputStream(dr, size, this);
 }
Beispiel #19
0
        /// <summary>
        /// For a given named property entry, either return it or null if
        /// if it wasn't found
        /// </summary>
        /// <param name="setName">The property to read</param>
        /// <param name="encryptionInfo">the encryption descriptor in case of cryptoAPI encryption</param>
        /// <returns>The value of the given property or null if it wasn't found.</returns>
        /// <exception cref="IOException">If retrieving properties fails</exception>
        protected PropertySet GetPropertySet(string setName, EncryptionInfo encryptionInfo)
        {
            DirectoryNode dirNode = directory;

            NPOIFSFileSystem encPoifs = null;
            String           step     = "getting";

            try
            {
                if (encryptionInfo != null)
                {
                    step = "getting encrypted";
                    InputStream is1 = encryptionInfo.Decryptor.GetDataStream(directory);
                    try
                    {
                        encPoifs = new NPOIFSFileSystem(is1);
                        dirNode  = encPoifs.Root;
                    }
                    finally
                    {
                        is1.Close();
                    }
                }

                //directory can be null when creating new documents
                if (dirNode == null || !dirNode.HasEntry(setName))
                {
                    return(null);
                }

                // Find the entry, and get an input stream for it
                step = "getting";
                DocumentInputStream dis = dirNode.CreateDocumentInputStream(dirNode.GetEntry(setName));
                try
                {
                    // Create the Property Set
                    step = "creating";
                    return(PropertySetFactory.Create(dis));
                }
                finally
                {
                    dis.Close();
                }
            }
            catch (Exception e)
            {
                logger.Log(POILogger.WARN, "Error " + step + " property set with name " + setName, e);
                return(null);
            }
            finally
            {
                if (encPoifs != null)
                {
                    try
                    {
                        encPoifs.Close();
                    }
                    catch (IOException e)
                    {
                        logger.Log(POILogger.WARN, "Error closing encrypted property poifs", e);
                    }
                }
            }
        }
Beispiel #20
0
        /**
         * Encrypt the Document-/SummaryInformation and other optionally streams.
         * Opposed to other crypto modes, cryptoapi is record based and can't be used
         * to stream-encrypt a whole file
         *
         * @see <a href="http://msdn.microsoft.com/en-us/library/dd943321(v=office.12).aspx">2.3.5.4 RC4 CryptoAPI Encrypted Summary Stream</a>
         */
        public override OutputStream GetDataStream(DirectoryNode dir)
        {
            CipherByteArrayOutputStream bos = new CipherByteArrayOutputStream(this);

            byte[] buf = new byte[8];

            bos.Write(buf, 0, 8); // skip header
            String[] entryNames =
            {
                SummaryInformation.DEFAULT_STREAM_NAME,
                DocumentSummaryInformation.DEFAULT_STREAM_NAME
            };

            List <CryptoAPIDecryptor.StreamDescriptorEntry> descList = new List <CryptoAPIDecryptor.StreamDescriptorEntry>();

            int block = 0;

            foreach (String entryName in entryNames)
            {
                if (!dir.HasEntry(entryName))
                {
                    continue;
                }
                CryptoAPIDecryptor.StreamDescriptorEntry descEntry = new CryptoAPIDecryptor.StreamDescriptorEntry();
                descEntry.block        = block;
                descEntry.streamOffset = (int)bos.Length;
                descEntry.streamName   = entryName;
                descEntry.flags        = CryptoAPIDecryptor.StreamDescriptorEntry.flagStream.SetValue(0, 1);
                descEntry.reserved2    = 0;

                bos.SetBlock(block);
                DocumentInputStream dis = dir.CreateDocumentInputStream(entryName);
                IOUtils.Copy(dis, bos);
                dis.Close();

                descEntry.streamSize = (int)(bos.Length - descEntry.streamOffset);
                descList.Add(descEntry);

                dir.GetEntry(entryName).Delete();

                block++;
            }

            int streamDescriptorArrayOffset = (int)bos.Length;

            bos.SetBlock(0);
            LittleEndian.PutUInt(buf, 0, descList.Count);
            bos.Write(buf, 0, 4);

            foreach (CryptoAPIDecryptor.StreamDescriptorEntry sde in descList)
            {
                LittleEndian.PutUInt(buf, 0, sde.streamOffset);
                bos.Write(buf, 0, 4);
                LittleEndian.PutUInt(buf, 0, sde.streamSize);
                bos.Write(buf, 0, 4);
                LittleEndian.PutUShort(buf, 0, sde.block);
                bos.Write(buf, 0, 2);
                LittleEndian.PutUByte(buf, 0, (short)sde.streamName.Length);
                bos.Write(buf, 0, 1);
                LittleEndian.PutUByte(buf, 0, (short)sde.flags);
                bos.Write(buf, 0, 1);
                LittleEndian.PutUInt(buf, 0, sde.reserved2);
                bos.Write(buf, 0, 4);
                byte[] nameBytes = StringUtil.GetToUnicodeLE(sde.streamName);
                bos.Write(nameBytes, 0, nameBytes.Length);
                LittleEndian.PutShort(buf, 0, (short)0); // null-termination
                bos.Write(buf, 0, 2);
            }

            int savedSize = (int)bos.Length;
            int streamDescriptorArraySize = savedSize - streamDescriptorArrayOffset;

            LittleEndian.PutUInt(buf, 0, streamDescriptorArrayOffset);
            LittleEndian.PutUInt(buf, 4, streamDescriptorArraySize);

            bos.Reset();
            bos.SetBlock(0);
            bos.Write(buf, 0, 8);
            bos.SetSize(savedSize);

            dir.CreateDocument("EncryptedSummary", new MemoryStream(bos.GetBuf(), 0, savedSize));
            DocumentSummaryInformation dsi = PropertySetFactory.NewDocumentSummaryInformation();

            try
            {
                dsi.Write(dir, DocumentSummaryInformation.DEFAULT_STREAM_NAME);
            }
            catch (WritingNotSupportedException e)
            {
                throw new IOException(e.Message);
            }

            //return bos;
            throw new NotImplementedException("CipherByteArrayOutputStream should be derived from OutputStream");
        }