Esempio n. 1
0
        internal static Stream Decrypt(Stream aStream, TEncryptionData Encryption)
        {
            using (TOle2File DataStream = new TOle2File(aStream, false))
            {
                DataStream.SelectStream(XlsxConsts.EncryptionInfoString);
                byte[] RecordHeader = new byte[4 * 2];
                DataStream.Read(RecordHeader, RecordHeader.Length);
                int vMajor = BitOps.GetWord(RecordHeader, 0);
                int vMinor = BitOps.GetWord(RecordHeader, 2);


                if ((vMajor == 0x03 || vMajor == 0x04) && vMinor == 0x02)
                {
                    long Flags = BitOps.GetCardinal(RecordHeader, 4);
                    if (Flags == 0x10)
                    {
                        XlsMessages.ThrowException(XlsErr.ErrNotSupportedEncryption);                //external encryption
                    }
                    return(ReadStandardEncryptionInfo(DataStream, Encryption));
                }
                else if (vMajor == 4 && vMinor == 4 && BitOps.GetCardinal(RecordHeader, 4) == 0x040)
                {
                    return(ReadAgileEncryptionInfo(DataStream, Encryption));
                }

                XlsMessages.ThrowException(XlsErr.ErrNotSupportedEncryption);
                return(null);
            }
        }
Esempio n. 2
0
        private static object[] GetNameDictionary(TOle2File Ole2File)
        {
            byte[] PropCountArray = new byte[4];
            Ole2File.Read(PropCountArray, PropCountArray.Length);
            Int32 PropCount = BitOps.GetInt32(PropCountArray, 0);

            object[] Properties = new object[PropCount];
            for (int i = 0; i < Properties.Length; i++)
            {
                TUnconvertedOlePropertyName PropName = new TUnconvertedOlePropertyName();
                Ole2File.Read(PropCountArray, PropCountArray.Length);
                PropName.Id = BitConverter.ToUInt32(PropCountArray, 0);
                Ole2File.Read(PropCountArray, PropCountArray.Length);
                int StrLen = BitOps.GetInt32(PropCountArray, 0);

                if (StrLen <= 1)
                {
                    PropName.Name = new TUnconvertedString(new byte[0], false);  //StrLen includes the trailing #0
                }
                else
                {
                    byte[] Str = new byte[StrLen - 1];
                    Ole2File.Read(Str, Str.Length);
                    Ole2File.SeekForward(Ole2File.Position + 1); //go over the 0 byte. This is needed for vectors/arrays.
                    PropName.Name = new TUnconvertedString(Str, false);
                }
                Properties[i] = PropName;
            }

            return(Properties);
        }
Esempio n. 3
0
        private static Stream DecryptStream(TOle2File DataStream, TEncryptionParameters EncParams, TEncryptionKey Key)
        {
            DataStream.SelectStream(XlsxConsts.ContentString);
            byte[] EncryptedSize = new byte[8];
            DataStream.Read(EncryptedSize, EncryptedSize.Length);
            AesManaged       Engine    = null;
            ICryptoTransform Decryptor = null;

            try
            {
                Engine = TEncryptionUtils.CreateEngine(EncParams);
                if (!Key.VariableIV)
                {
                    Decryptor = Engine.CreateDecryptor(Key.Key, Key.IV);
                }
                return(new TXlsxCryptoStreamReader(DataStream, BitOps.GetCardinal(EncryptedSize, 0), Engine, Decryptor, Key));
            }
            catch
            {
                if (Engine != null)
                {
                    ((IDisposable)Engine).Dispose();
                }
                if (Decryptor != null)
                {
                    Decryptor.Dispose();
                }
                throw;
            }
        }
Esempio n. 4
0
        private void FinishEncryption()
        {
            TEncryptionParameters EncParams = GetEncryptionParams(Protection);
            AesManaged            EncEngine = TEncryptionUtils.CreateEngine(EncParams);

            TAgileEncryptionKey DataKey = TAgileEncryptionKey.CreateForWriting(null, EncEngine.KeySize / 8);

            DataKey.Key = TEncryptionUtils.GetRandom(DataKey.KeySizeInBytes);

            TAgileEncryptionKey KeyKey = TAgileEncryptionKey.CreateForWriting(Protection.OpenPassword, EncEngine.KeySize / 8);

            byte[] WorkLen = new byte[8];
            BitOps.SetCardinal(WorkLen, 0, WorkingStream.Length - WorkStreamZeroPos);

            EncryptStream(EncEngine, DataKey, WorkLen);

            using (MemoryStream ms = new MemoryStream())
            {
                using (TOle2File Ole2File = new TOle2File(GetEmptyEncryptedFile()))
                {
                    Ole2File.PrepareForWrite(ms, XlsxConsts.EncryptionInfoString, new string[0]);
                    CreateInfoStream(Ole2File, EncEngine, EncParams, KeyKey, DataKey);
                }

                ms.Position = 0;

                using (TOle2File Ole2File = new TOle2File(ms))
                {
                    Ole2File.PrepareForWrite(TargetStream, XlsxConsts.ContentString, new string[0]);
                    WorkingStream.Position = 0;
                    TEncryptionUtils.CopyStream(WorkingStream, Ole2File);
                }
            }
        }
Esempio n. 5
0
 internal TXlsRecordLoader(TOle2File aDataStream, TBiff8XFMap aXFMap, TSST aSST, IFlexCelFontList aFontList, TBorderList aBorderList,
                           TPatternList aPatternList, TEncryptionData aEncryption, TXlsBiffVersion aXlsBiffVersion, TNameRecordList aNames, TVirtualReader VirtualReader)
     : base(aSST, aFontList, aEncryption, aXlsBiffVersion, aXFMap, aNames, VirtualReader)
 {
     DataStream  = aDataStream;
     BorderList  = aBorderList;
     PatternList = aPatternList;
 }
Esempio n. 6
0
        internal void Load(TOle2File OleFile)
        {
            PropertyList.Clear();

            CheckHeader(OleFile);
            ReadPropHeader(OleFile);
            ReadPropSectionHeader(OleFile);
        }
Esempio n. 7
0
 public TXlsxCryptoStreamReader(TOle2File aDataStream, long aStreamLen, AesManaged aEncEncgine, ICryptoTransform aDecryptor, TEncryptionKey aKey)
 {
     DataStream     = aDataStream;
     FStreamLen     = aStreamLen;
     EncEngine      = aEncEncgine;
     Decryptor      = aDecryptor;
     CurrentSegment = new byte[SegmentSize];
     Key            = aKey;
 }
Esempio n. 8
0
        internal void WriteHeader(TOle2File OleFile)
        {
            OleFile.WriteRaw(PropHeader, PropHeader.Length);
            int SectCount = (int)BitOps.GetCardinal(PropHeader, 24);

            for (int i = 0; i < SectCount; i++)
            {
                OleFile.WriteRaw(FmtSection[i], FmtSection[i].Length);
            }
        }
Esempio n. 9
0
        internal static void CopyStream(Stream SourceStream, TOle2File DataStream)
        {
            byte[] buffer = new byte[8192];
            int    read;

            while ((read = SourceStream.Read(buffer, 0, buffer.Length)) > 0)
            {
                DataStream.Write(buffer, 0, read);
            }
        }
Esempio n. 10
0
        private void ReadPropHeader(TOle2File OleFile)
        {
            int SectCount = (int)BitOps.GetCardinal(PropHeader, 24);

            FmtSection = new byte[SectCount][];
            for (int i = 0; i < SectCount; i++)
            {
                FmtSection[i] = new byte[16 + 4];
                OleFile.Read(FmtSection[i], FmtSection[i].Length);
            }

            long SectorOffset = BitOps.GetCardinal(FmtSection[0], 16);

            OleFile.SeekForward(SectorOffset);
        }
Esempio n. 11
0
        private void CreateInfoStream(TOle2File DataStream, AesManaged EncEngine, TEncryptionParameters EncParams, TAgileEncryptionKey KeyKey, TAgileEncryptionKey DataKey)
        {
            DataStream.Write16(0x0004);
            DataStream.Write16(0x0004);
            DataStream.Write32(0x00040);

            byte[] InfoStreamXml = GetInfoStreamXml(EncEngine, EncParams, KeyKey, DataKey);
            DataStream.Write(InfoStreamXml, InfoStreamXml.Length);
            byte[] pad = new byte[4098 - InfoStreamXml.Length]; //Our Ole2 implementation will fill a sector with 0 so it doesn't go to the ministream. Those 0 will confuse Excel, so we will write spaces.
            for (int i = 0; i < pad.Length; i++)
            {
                pad[i] = 32;
            }
            DataStream.Write(pad, pad.Length);
        }
Esempio n. 12
0
        private void CheckHeader(TOle2File OleFile)
        {
            PropHeader = new byte[2 + 2 + 4 + 16 + 4];
            OleFile.Read(PropHeader, PropHeader.Length);
            byte[] ExpectedHeader = { 0xFE, 0xFF, 0x00, 0x00 };
            for (int i = 0; i < ExpectedHeader.Length; i++)
            {
                if (ExpectedHeader[i] != PropHeader[i])
                {
                    XlsMessages.ThrowException(XlsErr.ErrInvalidPropertySector);
                }
            }

            if (BitOps.GetCardinal(PropHeader, 24) < 1) //There should be at least one property section.
            {
                XlsMessages.ThrowException(XlsErr.ErrInvalidPropertySector);
            }
        }
Esempio n. 13
0
        private static Stream ReadAgileEncryptionInfo(TOle2File DataStream, TEncryptionData Encryption)
        {
            byte[] Enc = new byte[DataStream.Length - DataStream.Position];
            DataStream.Read(Enc, Enc.Length);

            TEncryptionParameters DataEncParams = new TEncryptionParameters();
            TAgileEncryptionKey   DataKey       = new TAgileEncryptionKey();

            TAgileEncryptionVerifier KeyVerifier  = new TAgileEncryptionVerifier();
            TEncryptionParameters    KeyEncParams = new TEncryptionParameters();
            TAgileEncryptionKey      KeyKey       = new TAgileEncryptionKey();

            using (MemoryStream ms = new MemoryStream(Enc))
            {
                using (XmlReader xml = XmlReader.Create(ms))
                {
                    xml.ReadStartElement("encryption"); //goes to keyData

                    ReadAgileCipherParams(xml, DataEncParams, DataKey);

                    xml.ReadStartElement("keyData"); //goes to dataIntegrity

                    //We are not checking data integrity at the moment.
                    //DataIntegrity.EncryptedHMacKey = Convert.FromBase64String(xml.GetAttribute("encryptedHmacKey"));
                    //DataIntegrity.EncryptedHmacValue = Convert.FromBase64String(xml.GetAttribute("encryptedHmacValue"));

                    xml.ReadStartElement("dataIntegrity"); //goes to keyEncryptors
                    xml.ReadStartElement("keyEncryptors"); //goes to keyEncryptor
                    xml.ReadStartElement("keyEncryptor");  //goes to encryptedKey
                    KeyKey.SpinCount = Convert.ToInt32(xml.GetAttribute("spinCount"), CultureInfo.InvariantCulture);
                    ReadAgileCipherParams(xml, KeyEncParams, KeyKey);
                    KeyVerifier.EncryptedVerifierHashInput = Convert.FromBase64String(xml.GetAttribute("encryptedVerifierHashInput"));
                    KeyVerifier.EncryptedVerifierHashValue = Convert.FromBase64String(xml.GetAttribute("encryptedVerifierHashValue"));
                    KeyVerifier.EncryptedKeyValue          = Convert.FromBase64String(xml.GetAttribute("encryptedKeyValue"));
                }
            }

            CheckPassword(Encryption, KeyVerifier, KeyEncParams, KeyKey);
            DataKey.Key      = KeyKey.Key;
            DataKey.Password = KeyKey.Password;
            DataKey.CalcDataIV(0);
            return(DecryptStream(DataStream, DataEncParams, DataKey));
        }
Esempio n. 14
0
        private void ReadPropSectionHeader(TOle2File OleFile)
        {
            long PropStart = OleFile.Position;

            byte[] PropSectionHeader = new byte[8];
            OleFile.Read(PropSectionHeader, PropSectionHeader.Length);

            int PropCount = (int)BitOps.GetWord(PropSectionHeader, 4);

            TPropIdOffset[] PropOffsets = new TPropIdOffset[PropCount];
            for (int i = 0; i < PropOffsets.Length; i++)
            {
                OleFile.Read(PropSectionHeader, 8); //Reuse the array to avoid allocate more memory
                PropOffsets[i].Id     = (UInt32)BitOps.GetInt32(PropSectionHeader, 0);
                PropOffsets[i].Offset = (UInt32)BitOps.GetInt32(PropSectionHeader, 4);
            }

            Array.Sort(PropOffsets);

            for (int i = 0; i < PropOffsets.Length; i++)
            {
                OleFile.SeekForward(PropOffsets[i].Offset + PropStart);
                ReadProperty(OleFile, PropOffsets[i].Id);
            }

            //Get the actual codepage and convert the strings
            int    Cp = 1252; //windows western encoding.
            object Cpo;

            if (PropertyList.TryGetValue(1, out Cpo))
            {
                Cp = Convert.ToInt32(Cpo);
            }

            Encoding CodePage = Encoding.GetEncoding(Cp);

            UInt32[] Keys = new UInt32[PropertyList.Count];
            PropertyList.Keys.CopyTo(Keys, 0);
            foreach (UInt32 key in Keys)
            {
                PropertyList[key] = ConvertStrings(PropertyList[key], CodePage);
            }
        }
Esempio n. 15
0
        internal static bool IsValidFile(Stream aStream)
        {
            using (TOle2File DataStream = new TOle2File(aStream, true))
            {
                if (DataStream.NotXls97)
                {
                    return(false);
                }
                if (!DataStream.SelectStream(XlsxConsts.EncryptionInfoString, true))
                {
                    return(false);
                }
                if (!DataStream.SelectStream(XlsxConsts.ContentString, true))
                {
                    return(false);
                }
            }

            return(true);
        }
Esempio n. 16
0
        private void ReadProperty(TOle2File Ole2File, uint Id)
        {
            if (Id == 0) //This is the name list.
            {
                PropertyList.Add(Id, GetNameDictionary(Ole2File));
                return;
            }

            byte[] PropTypeArray = new byte[4];
            Ole2File.Read(PropTypeArray, PropTypeArray.Length);
            Int32 PropType = BitOps.GetInt32(PropTypeArray, 0);

            if (Id == 1 && PropType == (int)TPropertyTypes.VT_I2) //H a c k to get the correct codepage. It should not be negative.
            {
                PropType = (int)TPropertyTypes.VT_UI2;
            }

            object Value = GetOneProperty(Ole2File, PropType);

            PropertyList.Add(Id, Value);
        }
Esempio n. 17
0
        private static Stream ReadStandardEncryptionInfo(TOle2File DataStream, TEncryptionData Encryption)
        {
            byte[] RecordHeaderLen = new byte[4];
            DataStream.Read(RecordHeaderLen, RecordHeaderLen.Length);

            long EncryptionHeaderSize = BitOps.GetCardinal(RecordHeaderLen, 0);

            byte[] EncryptionHeader = new byte[EncryptionHeaderSize];
            DataStream.Read(EncryptionHeader, EncryptionHeader.Length);
            long AlgId   = BitOps.GetCardinal(EncryptionHeader, 8);
            long KeyBits = BitOps.GetCardinal(EncryptionHeader, 16);

            TEncryptionParameters EncParams = TEncryptionParameters.CreateStandard(GetStandardEncAlg(AlgId));

            byte[] VerifierBytes = new byte[DataStream.Length - DataStream.Position];
            DataStream.Read(VerifierBytes, VerifierBytes.Length);
            TStandardEncryptionVerifier Verifier = ReadStandardVerifier(VerifierBytes);
            TEncryptionKey Key = new TStandardEncryptionKey(ReadStandardSalt(VerifierBytes), (int)KeyBits / 8);

            CheckPassword(Encryption, Verifier, EncParams, Key);

            return(DecryptStream(DataStream, EncParams, Key));
        }
Esempio n. 18
0
 internal void Write(TOle2File OleFile)
 {
     WriteHeader(OleFile);
 }
Esempio n. 19
0
        private object GetOneProperty(TOle2File Ole2File, int PropType)
        {
            if ((PropType & (int)TPropertyTypes.VT_VECTOR) != 0)
            {
                byte[] i4 = new byte[4];
                Ole2File.Read(i4, i4.Length);

                object[] Vector = new object[BitOps.GetInt32(i4, 0)];
                for (int i = 0; i < Vector.Length; i++)
                {
                    Vector[i] = GetOneProperty(Ole2File, PropType & ~(int)TPropertyTypes.VT_VECTOR);
                }
                return(Vector);
            }

            switch ((TPropertyTypes)(PropType & 0xFF))
            {
            case TPropertyTypes.VT_EMPTY:
                return(null);

            case TPropertyTypes.VT_I2:
                byte[] i2 = new byte[2];
                Ole2File.Read(i2, i2.Length);
                return(BitConverter.ToInt16(i2, 0));

            case TPropertyTypes.VT_UI2:      //This is not really suported, but we need to convert the CodePage to a Signed int.
                byte[] ui2 = new byte[2];
                Ole2File.Read(ui2, ui2.Length);
                return((Int32)BitConverter.ToUInt16(ui2, 0));

            case TPropertyTypes.VT_I4:
                byte[] i4 = new byte[4];
                Ole2File.Read(i4, i4.Length);
                return(BitOps.GetInt32(i4, 0));

            case TPropertyTypes.VT_R4:
                byte[] d4 = new byte[4];
                Ole2File.Read(d4, d4.Length);
                return(BitConverter.ToSingle(d4, 0));

            case TPropertyTypes.VT_R8:
                byte[] d8 = new byte[8];
                Ole2File.Read(d8, d8.Length);
                return(BitConverter.ToDouble(d8, 0));

            case TPropertyTypes.VT_CY:
                byte[] cy = new byte[8];
                Ole2File.Read(cy, cy.Length);

                return(TCompactFramework.DecimalFromOACurrency(BitConverter.ToInt64(cy, 0)));

            case TPropertyTypes.VT_DATE:
                byte[] dd = new byte[8];
                Ole2File.Read(dd, dd.Length);
                DateTime Dt;
                if (!FlxDateTime.TryFromOADate(BitConverter.ToDouble(dd, 0), false, out Dt))
                {
                    return(DateTime.MinValue);
                }
                return(Dt.Date);

            case TPropertyTypes.VT_BSTR:
                byte[] sl = new byte[4];
                Ole2File.Read(sl, sl.Length);
                UInt32 StrLen = BitConverter.ToUInt32(sl, 0);
                if (StrLen <= 1)
                {
                    return(String.Empty);                  //StrLen includes the trailing #0
                }
                byte[] Str = new byte[StrLen - 1];
                Ole2File.Read(Str, Str.Length);
                Ole2File.SeekForward(Ole2File.Position + 1);     //go over the 0 byte. This is needed for vectors/arrays.
                return(new TUnconvertedString(Str, false));

            case TPropertyTypes.VT_BOOL:
                byte[] bl = new byte[2];
                Ole2File.Read(bl, bl.Length);
                return(BitConverter.ToInt16(bl, 0) == 0? false: true);

            case TPropertyTypes.VT_VARIANT:
                byte[] VariantTypeArray = new byte[4];
                Ole2File.Read(VariantTypeArray, VariantTypeArray.Length);
                Int32 VariantType = BitOps.GetInt32(VariantTypeArray, 0);
                return(GetOneProperty(Ole2File, VariantType));


            case TPropertyTypes.VT_I8:
                byte[] i8 = new byte[8];
                Ole2File.Read(i8, i8.Length);
                return(BitConverter.ToInt64(i8, 0));

            case TPropertyTypes.VT_LPSTR:
                byte[] sl2 = new byte[4];
                Ole2File.Read(sl2, sl2.Length);
                UInt32 StrLen2 = BitConverter.ToUInt32(sl2, 0);
                if (StrLen2 <= 1)
                {
                    return(String.Empty);                   //StrLen includes the trailing #0
                }
                byte[] Str2 = new byte[StrLen2 - 1];
                Ole2File.Read(Str2, Str2.Length);
                Ole2File.SeekForward(Ole2File.Position + 1);     //go over the 0 byte. This is needed for vectors/arrays.
                return(new TUnconvertedString(Str2, false));

            case TPropertyTypes.VT_LPWSTR:
                byte[] sl3 = new byte[4];
                Ole2File.Read(sl3, sl3.Length);
                UInt32 StrLen3 = BitConverter.ToUInt32(sl3, 0);
                if (StrLen3 <= 1)
                {
                    return(String.Empty);                   //StrLen includes the trailing #0
                }
                byte[] Str3 = new byte[(StrLen3 - 1) * 2];
                Ole2File.SeekForward(Ole2File.Position + 2);     //go over the 0 byte. This is needed for vectors/arrays.
                Ole2File.Read(Str3, Str3.Length);
                return(new TUnconvertedString(Str3, true));

            case TPropertyTypes.VT_FILETIME:
                byte[] ft = new byte[8];
                Ole2File.Read(ft, ft.Length);
                return(DateTime.FromFileTime(BitConverter.ToInt64(ft, 0)));

            case TPropertyTypes.VT_BLOB:
                byte[] blb = new byte[4];
                Ole2File.Read(blb, blb.Length);
                UInt32 BlobLen = BitConverter.ToUInt32(blb, 0);
                if (BlobLen <= 0)
                {
                    return(new byte[0]);                   //BlobLen does not includes trailing #0
                }
                byte[] Blob = new byte[BlobLen];
                Ole2File.Read(Blob, Blob.Length);
                return(Blob);
            }

            return(null);  //Not a supported type.
        }