Пример #1
0
        public Exceptional Deserialize(Byte[] mySerializedData, IIntegrityCheck myIntegrityCheckAlgorithm, ISymmetricEncryption myEncryptionAlgorithm, Boolean myIgnoreIntegrityCheckFailures)
        {
            #region Data

            Byte[] IntegrityCheckValue;
            int IntegrityCheckValue_Length;
            Int64 IntegrityCheckValue_Position;
            Byte[] actualIntegrityCheckValue;

            Byte[] EncryptionParameters;
            int EncryptionParameters_Length;

            int DataPadding_Length;
            int AdditionalPadding_Length = 0;

            #endregion

            #region Check if data is larger than the minimum allowed size

            if (mySerializedData == null)
                throw new GraphFSException_InvalidInformationHeader("The information header is invalid!");

            if (mySerializedData.Length < 8)
                throw new GraphFSException_InvalidInformationHeader("The information header is invalid!");

            #endregion

            try
            {

                #region Init reader

                var _SerializationReader = new SerializationReader(mySerializedData);

                #endregion

                #region Read HeaderVersion

                var _NewHeaderVersion = _SerializationReader.ReadByte();

                #endregion

                #region Read Length of the Integrity Check Value

                // Multiply the value of the first byte with 8
                IntegrityCheckValue_Length = _SerializationReader.ReadByte() << 3;

                if (IntegrityCheckValue_Length > mySerializedData.Length - HeaderLength)
                    throw new GraphFSException_InvalidIntegrityCheckLengthField("The length of the integrity check value is invalid!");

                // HACK: Remeber that a IntegrityCheckValue of 0 will circumvent the whole integrity checking!
                if (myIntegrityCheckAlgorithm != null)
                    if ((IntegrityCheckValue_Length > 0) && (IntegrityCheckValue_Length != myIntegrityCheckAlgorithm.HashSize))
                        throw new GraphFSException_InvalidIntegrityCheckLengthField("The length of the integrity check value is " + IntegrityCheckValue_Length + ", but " + myIntegrityCheckAlgorithm.HashSize + " was expected!");

                #endregion

                #region Read Length of the Encryption Parameters

                // Multiply the value of the second byte with 8
                EncryptionParameters_Length = _SerializationReader.ReadByte() << 3;

                if (EncryptionParameters_Length > mySerializedData.Length - HeaderLength - IntegrityCheckValue_Length)
                    throw new GraphFSException_InvalidEncryptionParametersLengthField("The length of the encryption parameters is invalid!");

                #endregion

                #region Read Padding lengths

                DataPadding_Length = (Int32)_SerializationReader.ReadByte();
                AdditionalPadding_Length = (Int32)(256 * _SerializationReader.ReadByte() + _SerializationReader.ReadByte()) << 3;

                if ((HeaderLength + IntegrityCheckValue_Length + EncryptionParameters_Length + AdditionalPadding_Length) >= mySerializedData.Length)
                    throw new GraphFSException_InvalidAdditionalPaddingLengthField("The length of the additional padding is invalid!");

                _SerializationReader.ReadBytesDirect(2);  // Read reserved bytes

                #endregion

                #region Read Integrity Check Value and Encryption Parameters

                IntegrityCheckValue_Position = _SerializationReader.BaseStream.Position;

                if (IntegrityCheckValue_Length > 0)
                    IntegrityCheckValue = _SerializationReader.ReadBytesDirect(IntegrityCheckValue_Length);

                if (EncryptionParameters_Length > 0)
                    EncryptionParameters = _SerializationReader.ReadBytesDirect(EncryptionParameters_Length);

                #endregion

                #region Verify the integrity of the data

                if (myIntegrityCheckAlgorithm != null && IntegrityCheckValue_Length > 0)
                {

                    // Save the read IntegrityCheckValue
                    IntegrityCheckValue = new Byte[IntegrityCheckValue_Length];
                    Array.Copy(mySerializedData, IntegrityCheckValue_Position, IntegrityCheckValue, 0, IntegrityCheckValue_Length);

                    // Zero the IntegrityCheckValue within the serialized data
                    Byte[] AllZeros = new Byte[IntegrityCheckValue_Length];
                    Array.Copy(AllZeros, 0, mySerializedData, IntegrityCheckValue_Position, IntegrityCheckValue_Length);

                    // Calculate the actual IntegrityCheckValue
                    actualIntegrityCheckValue = myIntegrityCheckAlgorithm.GetHashValueAsByteArray(mySerializedData);

                    // Compare read and actual IntegrityCheckValue
                    if (IntegrityCheckValue.CompareByteArray(actualIntegrityCheckValue) != 0 && myIgnoreIntegrityCheckFailures == false)
                        throw new GraphFSException_IntegrityCheckFailed(String.Concat("The IntegrityCheck failed as ", actualIntegrityCheckValue.ToHexString(), " is not equal to the expected ", IntegrityCheckValue.ToHexString()));

                }

                #endregion

                #region Decrypt the remaining data

                //EncryptedData_Length      = (UInt64) (mySerializedData.Length - (HeaderLength + IntegrityCheckValue_Length + EncryptionParameters_Length + AdditionalPadding_Length));
                //EncryptedData             = new Byte[EncryptedData_Length];
                //Array.Copy(mySerializedData, HeaderLength + IntegrityCheckValue_Length + EncryptionParameters_Length, EncryptedData, 0, (Int64) EncryptedData_Length);

                //#endregion

                //#region Decrypt Data

                // Decrypt Data, sooon...!

                //if ( (UInt64) DataPadding_Length >= EncryptedData_Length)
                //    throw new GraphFSException_InvalidDataPaddingLengthField("The length of the data padding is invalid!");

                //DecryptedData = new Byte[EncryptedData_Length - (UInt64) DataPadding_Length];
                //Array.Copy(EncryptedData, 0, DecryptedData, 0, (Int64) (EncryptedData_Length - (UInt64) DataPadding_Length));

                #endregion

                #region Deserialize Inner Object

                _StructureVersion = BitConverter.ToUInt16(_SerializationReader.ReadBytesDirect(2), 0);
                ObjectUUID = new ObjectUUID();
                ObjectUUID.Deserialize(ref _SerializationReader); // n or at least 16 Bytes

                Deserialize(ref _SerializationReader);

                #endregion

            }

            catch (GraphFSException_IntegrityCheckFailed e)
            {
                throw new GraphFSException_IntegrityCheckFailed("The AGraphStructure could not be deserialized as its integrity is corrupted!\n\n" + e);
            }

            catch (Exception e)
            {
                throw new GraphFSException_AGraphStructureCouldNotBeDeserialized("The AGraphStructure could not be deserialized!\n\n" + e);
            }

            _SerializedAGraphStructure = mySerializedData;

            return new Exceptional();
        }