Exemplo n.º 1
0
 public void WhenI2OSPIsPerformedWithAnOutputLengthAndOffsetThatIsSmallerThanNeededForTheGivenByteArray()
 {
     ExpectedException.ExpectedType             = typeof(ArithmeticException);
     ExpectedException.MessageShouldContainText = "too large";
     byte[] result = new byte[3];
     Try(() => BigEndianUtils.ConvertIntegerToOrdinalStringPrimitive(944, 2, ref result, 2));
 }
Exemplo n.º 2
0
        /// <inheritdoc />
        /// <remarks>
        /// Base Mode Specification: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-voprf-06.txt#section-3.4.3.3
        /// Input:
        ///     ClientInput input
        ///     Scalar blind
        ///     SerializedElement evaluatedElement
        /// Output:
        ///     opaque output[Nh]
        /// def Finalize(input, blind, evaluatedElement):
        ///     unblindedElement = Unblind(blind, evaluatedElement)
        ///     finalizeDST = "VOPRF06-Finalize-" || self.contextString
        ///     hashInput = I2OSP(len(input), 2) || input ||
        ///                 I2OSP(len(unblindedElement), 2) || unblindedElement ||
        ///                 I2OSP(len(finalizeDST), 2) || finalizeDST
        ///     return Hash(hashInput)
        /// </remarks>
        public byte[] Finalise(byte[] clientInput, byte[] blindScalar, byte[] serverEvaluatedGroupElement)
        {
            // unblindedElement = Unblind(blind, evaluatedElement)
            byte[] unblindedGroupElement = Unblind(blindScalar, serverEvaluatedGroupElement);

            // DST, a domain separation tag
            // as per https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-voprf-06.txt#section-5.1
            // finalizeDST = "VOPRF06-Finalize-" || self.contextString
            byte[] finaliseDST = CipherSuite.CreateDomainSeparationTag("Finalize");

            // hashInput = I2OSP(len(input), 2) || input ||
            //             I2OSP(len(unblindedElement), 2) || unblindedElement ||
            //             I2OSP(len(finalizeDST), 2) || finalizeDST
            byte[] hashInput = ByteArrayUtils.Concatenate(new List <byte[]>
            {
                BigEndianUtils.ConvertIntegerToOrdinalStringPrimitive(clientInput.Length, 2),
                clientInput,
                BigEndianUtils.ConvertIntegerToOrdinalStringPrimitive(unblindedGroupElement.Length, 2),
                unblindedGroupElement,
                BigEndianUtils.ConvertIntegerToOrdinalStringPrimitive(finaliseDST.Length, 2),
                finaliseDST
            });

            // return Hash(hashInput)
            return(CipherSuite.HashFunction.HashData(hashInput));
        }
Exemplo n.º 3
0
 public void WhenI2OSPIsPerformedWithMultipleUnsignedIntegersAtDifferentOffsetsInTheSameByteArray()
 {
     _actualBytes = new byte[5];
     BigEndianUtils.ConvertIntegerToOrdinalStringPrimitive(944, 2, ref _actualBytes, 3); // offset 3 (positions 4 & 5)
     BigEndianUtils.ConvertIntegerToOrdinalStringPrimitive(257, 2, ref _actualBytes, 0); // offset 0
     _expectedBytes = new byte[] { 1, 1, 0, 3, 176 };                                    // 257 then 0 then 944 in base 256
 }
Exemplo n.º 4
0
        /* Load the contents of an existing TexturePAK */
        public override PAKReturnType Load()
        {
            if (!File.Exists(FilePathPAK))
            {
                return(PAKReturnType.FAIL_TRIED_TO_LOAD_VIRTUAL_ARCHIVE);
            }

            try
            {
                /* First, parse the BIN and pull ALL info from it */
                BinaryReader ArchiveFileBin = new BinaryReader(File.OpenRead(FilePathBIN));

                //Read the header info from the BIN
                VersionNumber_BIN = ArchiveFileBin.ReadInt32();
                if (VersionNumber_BIN != 45)
                {
                    return(PAKReturnType.FAIL_ARCHIVE_IS_NOT_EXCPETED_TYPE);
                }                                                                                        //BIN version number is 45 for textures
                NumberOfEntriesBIN = ArchiveFileBin.ReadInt32();
                HeaderListBeginBIN = ArchiveFileBin.ReadInt32();

                //Read all file names from BIN
                string ThisFileName = "";
                for (int i = 0; i < NumberOfEntriesBIN; i++)
                {
                    ThisFileName = "";
                    for (byte b; (b = ArchiveFileBin.ReadByte()) != 0x00;)
                    {
                        ThisFileName += (char)b;
                    }
                    if (Path.GetExtension(ThisFileName).ToUpper() != ".DDS")
                    {
                        ThisFileName += ".dds";
                    }
                    //Create texture entry and add filename
                    TEX4 TextureEntry = new TEX4();
                    TextureEntry.FileName = ThisFileName;
                    TextureEntries.Add(TextureEntry);
                }

                //Read the texture headers from the BIN
                ArchiveFileBin.BaseStream.Position = HeaderListBeginBIN + 12;
                for (int i = 0; i < NumberOfEntriesBIN; i++)
                {
                    TextureEntries[i].HeaderPos = (int)ArchiveFileBin.BaseStream.Position;
                    for (int x = 0; x < 4; x++)
                    {
                        TextureEntries[i].Magic += ArchiveFileBin.ReadChar();
                    }
                    TextureEntries[i].Format             = (TextureFormat)ArchiveFileBin.ReadInt32();
                    TextureEntries[i].Length_V2          = ArchiveFileBin.ReadInt32();
                    TextureEntries[i].Length_V1          = ArchiveFileBin.ReadInt32();
                    TextureEntries[i].Texture_V1.Width   = ArchiveFileBin.ReadInt16();
                    TextureEntries[i].Texture_V1.Height  = ArchiveFileBin.ReadInt16();
                    TextureEntries[i].Unk_V1             = ArchiveFileBin.ReadInt16();
                    TextureEntries[i].Texture_V2.Width   = ArchiveFileBin.ReadInt16();
                    TextureEntries[i].Texture_V2.Height  = ArchiveFileBin.ReadInt16();
                    TextureEntries[i].Unk_V2             = ArchiveFileBin.ReadInt16();
                    TextureEntries[i].UnknownHeaderBytes = ArchiveFileBin.ReadBytes(20);
                }

                /* Second, parse the PAK and pull ONLY header info from it - we'll pull textures when requested (to save memory) */
                ArchiveFileBin.Close();
                BinaryReader ArchiveFile = new BinaryReader(File.OpenRead(FilePathPAK));

                //Read the header info from the PAK
                BigEndianUtils BigEndian = new BigEndianUtils();
                ArchiveFile.BaseStream.Position += 4; //Skip nulls
                VersionNumber_PAK = BigEndian.ReadInt32(ArchiveFile);
                if (BigEndian.ReadInt32(ArchiveFile) != VersionNumber_BIN)
                {
                    throw new Exception("Archive version mismatch!");
                }
                NumberOfEntriesPAK = BigEndian.ReadInt32(ArchiveFile);
                if (BigEndian.ReadInt32(ArchiveFile) != NumberOfEntriesPAK)
                {
                    throw new Exception("PAK entry count mismatch!");
                }
                ArchiveFile.BaseStream.Position += 12; //Skip unknowns (1,1,1)

                //Read the texture headers from the PAK
                int OffsetTracker = (NumberOfEntriesPAK * 48) + 32;
                for (int i = 0; i < NumberOfEntriesPAK; i++)
                {
                    //Header indexes are out of order, so optimise replacements by saving position
                    int HeaderPosition = (int)ArchiveFile.BaseStream.Position;

                    //Pull the entry info
                    byte[] UnknownHeaderLead = ArchiveFile.ReadBytes(8);
                    int    PartLength        = BigEndian.ReadInt32(ArchiveFile);
                    if (PartLength != BigEndian.ReadInt32(ArchiveFile))
                    {
                        continue;
                    }
                    byte[] UnknownHeaderTrail_1 = ArchiveFile.ReadBytes(18);

                    //Find the entry
                    TEX4      TextureEntry = TextureEntries[BigEndian.ReadInt16(ArchiveFile)];
                    TEX4_Part TexturePart  = (!TextureEntry.Texture_V1.Saved) ? TextureEntry.Texture_V1 : TextureEntry.Texture_V2;

                    //Write out the info
                    TexturePart.HeaderPos            = HeaderPosition;
                    TexturePart.StartPos             = OffsetTracker;
                    TexturePart.UnknownHeaderLead    = UnknownHeaderLead;
                    TexturePart.Length               = PartLength;
                    TexturePart.Saved                = true;
                    TexturePart.UnknownHeaderTrail_1 = UnknownHeaderTrail_1;
                    TexturePart.UnknownHeaderTrail_2 = ArchiveFile.ReadBytes(12);

                    //Keep file offset updated
                    OffsetTracker += TexturePart.Length;
                }
                HeaderListEndPAK = (int)ArchiveFile.BaseStream.Position;

                //Close PAK
                ArchiveFile.Close();
                return(PAKReturnType.SUCCESS);
            }
            catch (IOException) { return(PAKReturnType.FAIL_COULD_NOT_ACCESS_FILE); }
            catch (Exception) { return(PAKReturnType.FAIL_UNKNOWN); }
        }
Exemplo n.º 5
0
        /* Replace an existing file in the TexturePAK archive */
        public override PAKReturnType ReplaceFile(string PathToNewFile, string FileName)
        {
            try
            {
                //Get the texture entry & parse new DDS
                int EntryIndex = GetFileIndex(FileName);
                if (EntryIndex == -1)
                {
                    return(PAKReturnType.FAIL_GENERAL_LOGIC_ERROR);                  //CHANGED FOR OPENCAGE
                }
                TEX4      TextureEntry = TextureEntries[EntryIndex];
                DDSReader NewTexture   = new DDSReader(PathToNewFile);

                //Currently we only apply the new texture to the "biggest", some have lower mips that we don't edit (TODO)
                TEX4_Part BiggestPart = TextureEntry.Texture_V2;
                if (BiggestPart.HeaderPos == -1 || !BiggestPart.Saved)
                {
                    BiggestPart = TextureEntry.Texture_V1;
                }
                if (BiggestPart.HeaderPos == -1 || !BiggestPart.Saved)
                {
                    return(PAKReturnType.FAIL_REQUEST_IS_UNSUPPORTED); //Shouldn't reach this.
                }

                //CATHODE seems to ignore texture header information regarding size, so as default, resize any imported textures to the original size.
                //An option is provided in the toolkit to write size information to the header (done above) however, so don't resize if that's the case.
                //More work needs to be done to figure out why CATHODE doesn't honour the header's size value.
                int OriginalLength = BiggestPart.Length;
                Array.Resize(ref NewTexture.DataBlock, OriginalLength);

                //Update our internal knowledge of the textures
                BiggestPart.Length  = (int)NewTexture.DataBlock.Length;
                BiggestPart.Width   = (Int16)NewTexture.Width;
                BiggestPart.Height  = (Int16)NewTexture.Height;
                TextureEntry.Format = NewTexture.Format;
                //TODO: Update smallest here too if it exists!
                //Will need to be written into the PAK at "Pull PAK sections before/after V2" too - headers are handled already.

                //Load the BIN and write out updated BIN texture header
                BinaryWriter     ArchiveFileBinWriter = new BinaryWriter(File.OpenWrite(FilePathBIN));
                ExtraBinaryUtils BinaryUtils          = new ExtraBinaryUtils();
                ArchiveFileBinWriter.BaseStream.Position = TextureEntry.HeaderPos;
                BinaryUtils.WriteString(TextureEntry.Magic, ArchiveFileBinWriter);
                ArchiveFileBinWriter.Write(BitConverter.GetBytes((int)TextureEntry.Format));
                ArchiveFileBinWriter.Write((TextureEntry.Texture_V2.Length == -1) ? 0 : TextureEntry.Texture_V2.Length);
                ArchiveFileBinWriter.Write(TextureEntry.Texture_V1.Length);
                ArchiveFileBinWriter.Write(TextureEntry.Texture_V1.Width);
                ArchiveFileBinWriter.Write(TextureEntry.Texture_V1.Height);
                ArchiveFileBinWriter.Write(TextureEntry.Unk_V1);
                ArchiveFileBinWriter.Write(TextureEntry.Texture_V2.Width);
                ArchiveFileBinWriter.Write(TextureEntry.Texture_V2.Height);
                ArchiveFileBinWriter.Write(TextureEntry.Unk_V2);
                ArchiveFileBinWriter.Write(TextureEntry.UnknownHeaderBytes);
                ArchiveFileBinWriter.Close();

                //Update headers for V1+2 in PAK if they exist
                BinaryWriter   ArchiveFileWriter = new BinaryWriter(File.OpenWrite(FilePathPAK));
                BigEndianUtils BigEndian         = new BigEndianUtils();
                if (TextureEntry.Texture_V1.HeaderPos != -1)
                {
                    ArchiveFileWriter.BaseStream.Position = TextureEntry.Texture_V1.HeaderPos;
                    ArchiveFileWriter.Write(TextureEntry.Texture_V1.UnknownHeaderLead);
                    ArchiveFileWriter.Write(BigEndian.FlipEndian(BitConverter.GetBytes(TextureEntry.Texture_V1.Length)));
                    ArchiveFileWriter.Write(BigEndian.FlipEndian(BitConverter.GetBytes(TextureEntry.Texture_V1.Length)));
                    ArchiveFileWriter.Write(TextureEntry.Texture_V1.UnknownHeaderTrail_1);
                    ArchiveFileWriter.Write(BigEndian.FlipEndian(BitConverter.GetBytes((Int16)EntryIndex)));
                    ArchiveFileWriter.Write(TextureEntry.Texture_V1.UnknownHeaderTrail_2);
                }
                if (TextureEntry.Texture_V2.HeaderPos != -1)
                {
                    ArchiveFileWriter.BaseStream.Position = TextureEntry.Texture_V2.HeaderPos;
                    ArchiveFileWriter.Write(TextureEntry.Texture_V2.UnknownHeaderLead);
                    ArchiveFileWriter.Write(BigEndian.FlipEndian(BitConverter.GetBytes(TextureEntry.Texture_V2.Length)));
                    ArchiveFileWriter.Write(BigEndian.FlipEndian(BitConverter.GetBytes(TextureEntry.Texture_V2.Length)));
                    ArchiveFileWriter.Write(TextureEntry.Texture_V2.UnknownHeaderTrail_1);
                    ArchiveFileWriter.Write(BigEndian.FlipEndian(BitConverter.GetBytes((Int16)EntryIndex)));
                    ArchiveFileWriter.Write(TextureEntry.Texture_V2.UnknownHeaderTrail_2);
                }
                ArchiveFileWriter.Close();

                //Pull PAK sections before/after V2
                BinaryReader ArchiveFile = new BinaryReader(File.OpenRead(FilePathPAK));
                byte[]       PAK_Pt1     = ArchiveFile.ReadBytes(BiggestPart.StartPos);
                ArchiveFile.BaseStream.Position += OriginalLength;
                byte[] PAK_Pt2 = ArchiveFile.ReadBytes((int)ArchiveFile.BaseStream.Length - (int)ArchiveFile.BaseStream.Position);
                ArchiveFile.Close();

                //Write the PAK back out with new content
                ArchiveFileWriter = new BinaryWriter(File.OpenWrite(FilePathPAK));
                ArchiveFileWriter.BaseStream.SetLength(0);
                ArchiveFileWriter.Write(PAK_Pt1);
                ArchiveFileWriter.Write(NewTexture.DataBlock);
                ArchiveFileWriter.Write(PAK_Pt2);
                ArchiveFileWriter.Close();

                return(PAKReturnType.SUCCESS);
            }
            catch (IOException) { return(PAKReturnType.FAIL_COULD_NOT_ACCESS_FILE); }
            catch (Exception) { return(PAKReturnType.FAIL_UNKNOWN); }
        }
Exemplo n.º 6
0
        /* Load the contents of an existing ModelPAK */
        public override PAKReturnType Load()
        {
            if (!File.Exists(FilePathPAK))
            {
                return(PAKReturnType.FAIL_TRIED_TO_LOAD_VIRTUAL_ARCHIVE);
            }

            /* TODO: Verify the PAK loading is a ModelPAK by BIN version number */

            try
            {
                //First, parse the MTL file to find material info
                string       PathToMTL      = FilePathPAK.Substring(0, FilePathPAK.Length - 3) + "MTL";
                BinaryReader ArchiveFileMtl = new BinaryReader(File.OpenRead(PathToMTL));

                //Header
                ArchiveFileMtl.BaseStream.Position += 40; //There are some knowns here, just not required for us yet
                int MaterialEntryCount = ArchiveFileMtl.ReadInt16();
                ArchiveFileMtl.BaseStream.Position += 2;  //Skip unknown

                //Strings - more work will be done on materials eventually,
                //but taking their names for now is good enough for model export
                List <string> MaterialEntries    = new List <string>();
                string        ThisMaterialString = "";
                for (int i = 0; i < MaterialEntryCount; i++)
                {
                    while (true)
                    {
                        byte ThisByte = ArchiveFileMtl.ReadByte();
                        if (ThisByte == 0x00)
                        {
                            MaterialEntries.Add(ThisMaterialString);
                            ThisMaterialString = "";
                            break;
                        }
                        ThisMaterialString += (char)ThisByte;
                    }
                }
                ArchiveFileMtl.Close();

                //Read the header info from BIN
                BinaryReader ArchiveFileBin = new BinaryReader(File.OpenRead(FilePathBIN));
                ArchiveFileBin.BaseStream.Position += 4; //Skip magic
                TableCountPt2 = ArchiveFileBin.ReadInt32();
                ArchiveFileBin.BaseStream.Position += 4; //Skip unknown
                TableCountPt1 = ArchiveFileBin.ReadInt32();

                //Skip past table 1
                for (int i = 0; i < TableCountPt1; i++)
                {
                    byte ThisByte = 0x00;
                    while (ThisByte != 0xFF)
                    {
                        ThisByte = ArchiveFileBin.ReadByte();
                    }
                }
                ArchiveFileBin.BaseStream.Position += 23;

                //Read file list info
                FilenameListEnd = ArchiveFileBin.ReadInt32();
                int FilenameListStart = (int)ArchiveFileBin.BaseStream.Position;

                //Read all file names (bytes)
                byte[] filename_bytes = ArchiveFileBin.ReadBytes(FilenameListEnd);

                //Read table 2 (skipping all unknowns for now)
                ExtraBinaryUtils BinaryUtils = new ExtraBinaryUtils();
                for (int i = 0; i < TableCountPt2; i++)
                {
                    CS2 new_entry = new CS2();
                    new_entry.FilenameOffset            = ArchiveFileBin.ReadInt32();
                    new_entry.Filename                  = BinaryUtils.GetStringFromByteArray(filename_bytes, new_entry.FilenameOffset);
                    ArchiveFileBin.BaseStream.Position += 4;
                    new_entry.ModelPartNameOffset       = ArchiveFileBin.ReadInt32();
                    new_entry.ModelPartName             = BinaryUtils.GetStringFromByteArray(filename_bytes, new_entry.ModelPartNameOffset);
                    ArchiveFileBin.BaseStream.Position += 44;
                    new_entry.MaterialLibaryIndex       = ArchiveFileBin.ReadInt32();
                    new_entry.MaterialName              = MaterialEntries[new_entry.MaterialLibaryIndex];
                    ArchiveFileBin.BaseStream.Position += 8;
                    new_entry.BlockSize                 = ArchiveFileBin.ReadInt32();
                    ArchiveFileBin.BaseStream.Position += 14;
                    new_entry.ScaleFactor               = ArchiveFileBin.ReadInt16(); //Maybe?
                    ArchiveFileBin.BaseStream.Position += 2;
                    new_entry.VertCount                 = ArchiveFileBin.ReadInt16();
                    new_entry.FaceCount                 = ArchiveFileBin.ReadInt16();
                    new_entry.BoneCount                 = ArchiveFileBin.ReadInt16();
                    ModelEntries.Add(new_entry);
                }
                ArchiveFileBin.Close();

                //Get extra info from each header in the PAK
                BinaryReader   ArchiveFile = new BinaryReader(File.OpenRead(FilePathPAK));
                BigEndianUtils BigEndian   = new BigEndianUtils();
                ArchiveFile.BaseStream.Position += 32; //Skip header
                for (int i = 0; i < TableCountPt2; i++)
                {
                    ArchiveFile.BaseStream.Position += 8; //Skip unknowns
                    int ThisPakSize = BigEndian.ReadInt32(ArchiveFile);
                    if (ThisPakSize != BigEndian.ReadInt32(ArchiveFile))
                    {
                        //Dud entry... handle this somehow?
                    }
                    int ThisPakOffset = BigEndian.ReadInt32(ArchiveFile);
                    ArchiveFile.BaseStream.Position += 14;
                    int ThisIndex = BigEndian.ReadInt16(ArchiveFile);
                    ArchiveFile.BaseStream.Position += 12;

                    if (ThisIndex == -1)
                    {
                        continue; //Again, dud entry. Need to look into this!
                    }

                    //Push it into the correct entry
                    ModelEntries[ThisIndex].PakSize   = ThisPakSize;
                    ModelEntries[ThisIndex].PakOffset = ThisPakOffset;
                }
                HeaderListEnd = (int)ArchiveFile.BaseStream.Position;

                //Done!
                ArchiveFile.Close();
                return(PAKReturnType.SUCCESS);
            }
            catch (IOException) { return(PAKReturnType.FAIL_COULD_NOT_ACCESS_FILE); }
            catch (Exception) { return(PAKReturnType.FAIL_UNKNOWN); }
        }
Exemplo n.º 7
0
 public void WhenOS2IPIsPerformedWithAByteArrayForTheMaxSizeOfAnUnsignedInteger()
 {
     byte[] bytes = { 255, 255, 255, 255 }; // max in base 256
     _expectedInt = uint.MaxValue;
     _actualInt   = BigEndianUtils.ConvertOrdinalStringToIntegerPrimitive(bytes);
 }
Exemplo n.º 8
0
 public void WhenOS2IPIsPerformedWithAByteArrayThatIsNotPaddedWithZeros()
 {
     byte[] bytes = { 3, 176 }; // 944 in base 256
     _expectedInt = 944;
     _actualInt   = BigEndianUtils.ConvertOrdinalStringToIntegerPrimitive(bytes);
 }
Exemplo n.º 9
0
 public void WhenI2OSPIsPerformedWithAnOutputLengthThatIsSmallerThanNeeded()
 {
     ExpectedException.ExpectedType             = typeof(ArithmeticException);
     ExpectedException.MessageShouldContainText = "too large";
     Try(() => BigEndianUtils.ConvertIntegerToOrdinalStringPrimitive(944, 1));
 }
Exemplo n.º 10
0
 public void WhenI2OSPIsPerformedWithAnExactlyCorrectOutputLength()
 {
     _actualBytes   = BigEndianUtils.ConvertIntegerToOrdinalStringPrimitive(944, 2).ToArray();
     _expectedBytes = new byte[] { 3, 176 }; // 944 in base 256
 }
Exemplo n.º 11
0
 public void WhenI2OSPIsPerformedWithALargerOutputLengthThanIsNeeded()
 {
     _actualBytes   = BigEndianUtils.ConvertIntegerToOrdinalStringPrimitive(944, 3).ToArray();
     _expectedBytes = new byte[] { 0, 3, 176 }; // 944 in base 256
 }