Пример #1
0
        /// <summary>
        /// Read from a stream and get content chunk record, if possible
        /// </summary>
        /// <param name="reader">BinaryReader representing the input stream</param>
        /// <returns>Content chunk record object, null on error</returns>
        public static ContentChunkRecord Read(BinaryReader reader)
        {
            ContentChunkRecord ccr = new ContentChunkRecord();

            try
            {
                ccr.ContentId    = reader.ReadUInt32();
                ccr.ContentIndex = (ContentIndex)reader.ReadUInt16();
                ccr.ContentType  = (TMDContentType)reader.ReadUInt16();
                ccr.ContentSize  = reader.ReadUInt64();
                ccr.SHA256Hash   = reader.ReadBytes(0x20);
                return(ccr);
            }
            catch
            {
                return(null);
            }
        }
Пример #2
0
        /// <summary>
        /// Read from a stream and get ticket metadata, if possible
        /// </summary>
        /// <param name="reader">BinaryReader representing the input stream</param>
        /// <param name="metadataSize">Metadata size from the header</param>
        /// <returns>Title metadata object, null on error</returns>
        public static TitleMetadata Read(BinaryReader reader, int metadataSize)
        {
            TitleMetadata tm = new TitleMetadata();

            try
            {
                long startingPosition = reader.BaseStream.Position;

                tm.SignatureType = (SignatureType)reader.ReadUInt32();
                switch (tm.SignatureType)
                {
                case SignatureType.RSA_4096_SHA1:
                case SignatureType.RSA_4096_SHA256:
                    tm.SignatureSize = 0x200;
                    tm.PaddingSize   = 0x3C;
                    break;

                case SignatureType.RSA_2048_SHA1:
                case SignatureType.RSA_2048_SHA256:
                    tm.SignatureSize = 0x100;
                    tm.PaddingSize   = 0x3C;
                    break;

                case SignatureType.ECDSA_SHA1:
                case SignatureType.ECDSA_SHA256:
                    tm.SignatureSize = 0x03C;
                    tm.PaddingSize   = 0x40;
                    break;
                }

                tm.Signature = reader.ReadBytes(tm.SignatureSize);
                reader.ReadBytes(tm.PaddingSize); // Padding
                tm.SignatureIssuer              = reader.ReadBytes(0x40);
                tm.Version                      = reader.ReadByte();
                tm.CaCrlVersion                 = reader.ReadByte();
                tm.SignerCrlVersion             = reader.ReadByte();
                tm.Reserved1                    = reader.ReadByte();
                tm.SystemVersion                = reader.ReadUInt64();
                tm.TitleID                      = reader.ReadUInt64();
                tm.TitleType                    = reader.ReadUInt32();
                tm.GroupID                      = reader.ReadUInt16();
                tm.SaveDataSize                 = reader.ReadUInt32();
                tm.SRLPrivateSaveDataSize       = reader.ReadUInt32();
                tm.Reserved2                    = reader.ReadUInt32();
                tm.SRLFlag                      = reader.ReadByte();
                tm.Reserved3                    = reader.ReadBytes(0x31);
                tm.AccessRights                 = reader.ReadUInt32();
                tm.TitleVersion                 = reader.ReadUInt16();
                tm.ContentCount                 = BitConverter.ToUInt16(reader.ReadBytes(2).Reverse().ToArray(), 0);
                tm.BootContent                  = reader.ReadUInt16();
                tm.Padding                      = reader.ReadUInt16();
                tm.SHA256HashContentInfoRecords = reader.ReadBytes(0x20);

                tm.ContentInfoRecords = new ContentInfoRecord[64];
                for (int i = 0; i < 64; i++)
                {
                    tm.ContentInfoRecords[i] = ContentInfoRecord.Read(reader);
                }

                tm.ContentChunkRecords = new ContentChunkRecord[tm.ContentCount];
                for (int i = 0; i < tm.ContentCount; i++)
                {
                    tm.ContentChunkRecords[i] = ContentChunkRecord.Read(reader);
                }

                if (metadataSize > (reader.BaseStream.Position - startingPosition) + (2 * 0x200))
                {
                    tm.CertificateChain    = new Certificate[2];
                    tm.CertificateChain[0] = Certificate.Read(reader); // TMD
                    tm.CertificateChain[1] = Certificate.Read(reader); // CA
                }

                return(tm);
            }
            catch
            {
                return(null);
            }
        }