Ejemplo n.º 1
0
        public static void Decrypt(ref byte[] buffer, EbCryptMethod method, UInt32 key, int offset, int length)
        {
            switch (method)
            {
            case EbCryptMethod.NDB_CRYPT_NONE:
                return;

            case EbCryptMethod.NDB_CRYPT_PERMUTE:
                for (int i = offset; i < offset + length; i++)
                {
                    buffer[i] = Compressible[buffer[i]];
                }
                break;

            case EbCryptMethod.NDB_CRYPT_CYCLIC:
            {
                // We've never seen an actual example of this
                // This is what we hope is a valid implementation
                UInt16 salt = (UInt16)(((key & 0xffff0000) >> 16) ^ (key & 0x0000ffff));

                for (int i = offset; i < offset + length; i++)
                {
                    byte lower_salt = (byte)(salt & 0x00ff);
                    byte upper_salt = (byte)((salt & 0xff00) >> 8);
                    byte index      = buffer[i];
                    index    += lower_salt;
                    index     = Cyclic1[index];
                    index    += upper_salt;
                    index     = Cyclic2[index];
                    index    -= upper_salt;
                    index     = Compressible[index];
                    index    -= lower_salt;
                    buffer[i] = index;

                    salt++;
                }

                // Throw until the code has been validated
                throw new XstException("Decryption of Cyclic algorithm not validated");
                //break;
            }

            default:
                throw new XstException("Encryption method not known");
            }
        }
Ejemplo n.º 2
0
        // Read the file header, and the B trees that give us access to nodes and data blocks
        private void ReadHeaderAndIndexes()
        {
            using (var fs = GetReadStream())
            {
                var h = Map.ReadType <FileHeader1>(fs);

                if (h.dwMagic != 0x4e444221)
                {
                    throw new XstException("File is not a .ost or .pst file: the magic cookie is missing");
                }

                if (h.wVer == 0x15 || h.wVer == 0x17)
                {
                    var h2 = Map.ReadType <FileHeader2Unicode>(fs);
                    bCryptMethod = h2.bCryptMethod;
                    IsUnicode    = true;
                    ReadBTPageUnicode(fs, h2.root.BREFNBT.ib, nodeTree.Root);
                    ReadBTPageUnicode(fs, h2.root.BREFBBT.ib, dataTree.Root);
                }
                else if (h.wVer == 0x24)
                {
                    // This value indicates the use of 4K pages, as opposed to 512 bytes
                    // It is used only in .ost files, and was introduced in Office 2013
                    // It is not documented in [MS-PST], being .ost only
                    var h2 = Map.ReadType <FileHeader2Unicode>(fs);
                    bCryptMethod = h2.bCryptMethod;
                    IsUnicode    = true;
                    IsUnicode4K  = true;
                    ReadBTPageUnicode4K(fs, h2.root.BREFNBT.ib, nodeTree.Root);
                    ReadBTPageUnicode4K(fs, h2.root.BREFBBT.ib, dataTree.Root);
                }
                else if (h.wVer == 0x0e || h.wVer == 0x0f)
                {
                    var h2 = Map.ReadType <FileHeader2ANSI>(fs);
                    bCryptMethod = h2.bCryptMethod;
                    IsUnicode    = false;
                    ReadBTPageANSI(fs, h2.root.BREFNBT.ib, nodeTree.Root);
                    ReadBTPageANSI(fs, h2.root.BREFBBT.ib, dataTree.Root);
                }
                else
                {
                    throw new XstException("Unrecognised header type");
                }
            }
        }