Initial commit.
This commit is contained in:
jakcron 2018-06-06 20:38:42 +08:00
parent bd2e1dd927
commit 15ef72b4fe
13 changed files with 806 additions and 701 deletions

View file

@ -1,171 +0,0 @@
#pragma once
#include <string>
#include <fnd/MemoryBlob.h>
#include <fnd/ISerialiseableBinary.h>
#include <crypto/rsa.h>
namespace es
{
class ETicketBody_V2 :
public fnd::ISerialiseableBinary
{
public:
enum TitleKeyEncType
{
AES128_CBC,
RSA2048
};
enum LicenseType
{
ES_LICENSE_PERMANENT = 0,
ES_LICENSE_DEMO = 1,
ES_LICENSE_TRIAL = 2,
ES_LICENSE_RENTAL = 3,
ES_LICENSE_SUBSCRIPTION = 4,
ES_LICENSE_SERVICE = 5,
};
ETicketBody_V2();
ETicketBody_V2(const ETicketBody_V2& other);
ETicketBody_V2(const byte_t* bytes, size_t len);
bool operator==(const ETicketBody_V2& other) const;
bool operator!=(const ETicketBody_V2& other) const;
void operator=(const ETicketBody_V2& other);
// to be used after export
const byte_t* getBytes() const;
size_t getSize() const;
// export/import binary
virtual void exportBinary();
virtual void importBinary(const byte_t* bytes, size_t len);
// variables
virtual void clear();
const std::string& getIssuer() const;
void setIssuer(const std::string& issuer);
const byte_t* getEncTitleKey() const;
void setEncTitleKey(const byte_t* data, size_t len);
TitleKeyEncType getTitleKeyEncType() const;
void setTitleKeyEncType(TitleKeyEncType type);
uint16_t getTicketVersion() const;
void setTicketVersion(uint16_t version);
LicenseType getLicenseType() const;
void setLicenseType(LicenseType type);
byte_t getCommonKeyId() const;
void setCommonKeyId(byte_t id);
bool isPreInstall() const;
void setIsPreInstall(bool isPreInstall);
bool isSharedTitle() const;
void setIsSharedTitle(bool isSharedTitle);
bool allowAllContent() const;
void setAllowAllContent(bool allowAllContent);
const byte_t* getReservedRegion() const;
void setReservedRegion(const byte_t* data, size_t len);
uint64_t getTicketId() const;
void setTicketId(uint64_t id);
uint64_t getDeviceId() const;
void setDeviceId(uint64_t id);
const byte_t* getRightsId() const;
void setRightsId(const byte_t* id);
uint32_t getAccountId() const;
void setAccountId(uint32_t id);
uint32_t getSectionTotalSize() const;
void setSectionTotalSize(uint32_t size);
uint32_t getSectionHeaderOffset() const;
void setSectionHeaderOffset(uint32_t offset);
uint16_t getSectionNum() const;
void setSectionNum(uint16_t num);
uint16_t getSectionEntrySize() const;
void setSectionEntrySize(uint16_t size);
private:
const std::string kModuleName = "ES_ETICKET_BODY_V2";
static const size_t kIssuerLen = 0x40;
static const byte_t kFormatVersion = 2;
static const size_t kEncTitleKeyLen = crypto::rsa::kRsa2048Size;
static const size_t kReservedRegionLen = 8;
static const size_t kRightsIdLen = 16;
enum PropertyMaskFlags
{
FLAG_PRE_INSTALL,
FLAG_SHARED_TITLE,
FLAG_ALLOW_ALL_CONTENT
};
#pragma pack (push, 1)
struct sTicketBody_v2
{
char issuer[kIssuerLen];
byte_t enc_title_key[kEncTitleKeyLen];
byte_t format_version;
byte_t title_key_enc_type;
le_uint16_t ticket_version;
byte_t license_type;
byte_t common_key_id;
byte_t property_mask;
byte_t reserved_0;
byte_t reserved_region[kReservedRegionLen]; // explicitly reserved
le_uint64_t ticket_id;
le_uint64_t device_id;
byte_t rights_id[kRightsIdLen];
le_uint32_t account_id;
le_uint32_t sect_total_size;
le_uint32_t sect_header_offset;
le_uint16_t sect_num;
le_uint16_t sect_entry_size;
};
#pragma pack (pop)
// raw binary
fnd::MemoryBlob mBinaryBlob;
// variables
std::string mIssuer;
byte_t mEncTitleKey[kEncTitleKeyLen];
TitleKeyEncType mEncType; // 0 = aes-cbc, 1 = rsa2048
uint16_t mTicketVersion;
LicenseType mLicenseType;
byte_t mCommonKeyId;
bool mPreInstall;
bool mSharedTitle;
bool mAllowAllContent;
byte_t mReservedRegion[kReservedRegionLen]; // explicitly reserved
uint64_t mTicketId;
uint64_t mDeviceId;
byte_t mRightsId[kRightsIdLen];
uint32_t mAccountId;
uint32_t mSectTotalSize;
uint32_t mSectHeaderOffset;
uint16_t mSectNum;
uint16_t mSectEntrySize;
// helpers
bool isEqual(const ETicketBody_V2& other) const;
void copyFrom(const ETicketBody_V2& other);
};
}

View file

@ -1,47 +0,0 @@
#pragma once
#include <string>
#include <fnd/MemoryBlob.h>
#include <fnd/List.h>
#include <fnd/ISerialiseableBinary.h>
namespace es
{
class ETicketContentRecord_V1 :
public fnd::ISerialiseableBinary
{
public:
ETicketContentRecord_V1();
private:
const std::string kModuleName = "ETICKET_CONTENT_RECORD_V1";
#pragma pack (push, 1)
struct sContentRecord_v1
{
private:
static const size_t kAccessMaskSize = 0x80;
static const uint16_t kGroupMask = 0xFC00;
static const uint16_t kAccessMaskMask = 0x3FF;
be_uint32_t group;
byte_t access_mask[kAccessMaskSize];
public:
uint32_t index_group() const { return group.get(); }
bool is_index_enabled(uint16_t index) const
{
return (index_group() == get_group(index)) \
&& ((access_mask[get_access_mask(index) / 8] & BIT(get_access_mask(index) % 8)) != 0);
}
void clear() { memset(this, 0, sizeof(sContentRecord_v1)); }
void set_index_group(uint16_t index) { group = get_group(index); }
void enable_index(uint16_t index) { access_mask[get_access_mask(index) / 8] |= BIT(get_access_mask(index) % 8); }
void disable_index(uint16_t index) { access_mask[get_access_mask(index) / 8] &= ~BIT(get_access_mask(index) % 8); }
inline uint16_t get_access_mask(uint16_t index) const { return index & kAccessMaskMask; }
inline uint16_t get_group(uint16_t index) const { return index & kGroupMask; }
};
#pragma pack (pop)
};
}

View file

@ -1,85 +0,0 @@
#pragma once
#include <string>
#include <fnd/MemoryBlob.h>
#include <fnd/ISerialiseableBinary.h>
namespace es
{
class ETicketSectionHeader_V2 :
public fnd::ISerialiseableBinary
{
public:
enum SectionType
{
PERMANENT = 1,
SUBSCRIPTION = 2,
CONTENT = 3,
CONTENT_CONSUMPTION = 4,
ACCESS_TITLE = 5,
LIMITED_RESOURCE = 6,
};
ETicketSectionHeader_V2();
ETicketSectionHeader_V2(const ETicketSectionHeader_V2& other);
ETicketSectionHeader_V2(const byte_t* bytes, size_t len);
bool operator==(const ETicketSectionHeader_V2& other) const;
bool operator!=(const ETicketSectionHeader_V2& other) const;
void operator=(const ETicketSectionHeader_V2& other);
// to be used after export
const byte_t* getBytes() const;
size_t getSize() const;
// export/import binary
virtual void exportBinary();
virtual void importBinary(const byte_t* bytes, size_t len);
// variables
virtual void clear();
uint32_t getSectionOffset() const;
void setSectionOffset(uint32_t offset);
uint32_t getRecordSize() const;
void setRecordSize(uint32_t size);
uint32_t getSectionSize() const;
void getSectionSize(uint32_t size);
uint16_t getRecordNum() const;
void setRecordNum(uint16_t record_num);
SectionType getSectionType() const;
void setSectionType(SectionType type);
private:
const std::string kModuleName = "ETICKET_SECTION_HEADER_V2";
#pragma pack (push, 1)
struct sSectionHeader_v2
{
le_uint32_t section_offset;
le_uint32_t record_size;
le_uint32_t section_size;
le_uint16_t record_num;
le_uint16_t section_type;
};
#pragma pack (pop)
// raw binary
fnd::MemoryBlob mBinaryBlob;
// variables
uint32_t mSectionOffset;
uint32_t mRecordSize;
uint32_t mSectionSize;
uint16_t mRecordNum;
SectionType mSectionType;
// helpers
bool isEqual(const ETicketSectionHeader_V2& other) const;
void copyFrom(const ETicketSectionHeader_V2& other);
};
}

View file

@ -0,0 +1,66 @@
#pragma once
#include <string>
#include <fnd/MemoryBlob.h>
#include <fnd/ISerialiseableBinary.h>
#include <es/ticket.h>
namespace es
{
class SectionHeader_V2 :
public fnd::ISerialiseableBinary
{
public:
SectionHeader_V2();
SectionHeader_V2(const SectionHeader_V2& other);
SectionHeader_V2(const byte_t* bytes, size_t len);
bool operator==(const SectionHeader_V2& other) const;
bool operator!=(const SectionHeader_V2& other) const;
void operator=(const SectionHeader_V2& other);
// to be used after export
const byte_t* getBytes() const;
size_t getSize() const;
// export/import binary
virtual void exportBinary();
virtual void importBinary(const byte_t* bytes, size_t len);
// variables
virtual void clear();
uint32_t getSectionOffset() const;
void setSectionOffset(uint32_t offset);
uint32_t getRecordSize() const;
void setRecordSize(uint32_t size);
uint32_t getSectionSize() const;
void getSectionSize(uint32_t size);
uint16_t getRecordNum() const;
void setRecordNum(uint16_t record_num);
ticket::SectionType getSectionType() const;
void setSectionType(ticket::SectionType type);
private:
const std::string kModuleName = "SECTION_HEADER_V2";
// raw binary
fnd::MemoryBlob mBinaryBlob;
// variables
uint32_t mSectionOffset;
uint32_t mRecordSize;
uint32_t mSectionSize;
uint16_t mRecordNum;
ticket::SectionType mSectionType;
// helpers
bool isEqual(const SectionHeader_V2& other) const;
void copyFrom(const SectionHeader_V2& other);
};
}

View file

@ -0,0 +1,29 @@
#pragma once
#include <string>
#include <fnd/MemoryBlob.h>
#include <fnd/ISerialiseableBinary.h>
#include <es/ticket.h>
namespace es
{
class TicketBinary
: public fnd::ISerialiseableBinary
{
public:
TicketBinary();
TicketBinary(const TicketBinary& other);
void operator=(const TicketBinary& other);
bool operator==(const TicketBinary& other) const;
bool operator!=(const TicketBinary& other) const;
void importBinary(byte_t* src, size_t size);
void exportBinary();
const byte_t* getBytes() const;
size_t getSize() const;
private:
};
}

View file

@ -0,0 +1,118 @@
#pragma once
#include <string>
#include <fnd/MemoryBlob.h>
#include <fnd/ISerialiseableBinary.h>
#include <es/ticket.h>
namespace es
{
class TicketBody_V2 :
public fnd::ISerialiseableBinary
{
public:
TicketBody_V2();
TicketBody_V2(const TicketBody_V2& other);
TicketBody_V2(const byte_t* bytes, size_t len);
bool operator==(const TicketBody_V2& other) const;
bool operator!=(const TicketBody_V2& other) const;
void operator=(const TicketBody_V2& other);
// to be used after export
const byte_t* getBytes() const;
size_t getSize() const;
// export/import binary
virtual void exportBinary();
virtual void importBinary(const byte_t* bytes, size_t len);
// variables
virtual void clear();
const std::string& getIssuer() const;
void setIssuer(const std::string& issuer);
const byte_t* getEncTitleKey() const;
void setEncTitleKey(const byte_t* data, size_t len);
ticket::TitleKeyEncType getTitleKeyEncType() const;
void setTitleKeyEncType(ticket::TitleKeyEncType type);
uint16_t getTicketVersion() const;
void setTicketVersion(uint16_t version);
ticket::LicenseType getLicenseType() const;
void setLicenseType(ticket::LicenseType type);
byte_t getCommonKeyId() const;
void setCommonKeyId(byte_t id);
bool isPreInstall() const;
void setIsPreInstall(bool isPreInstall);
bool isSharedTitle() const;
void setIsSharedTitle(bool isSharedTitle);
bool allowAllContent() const;
void setAllowAllContent(bool allowAllContent);
const byte_t* getReservedRegion() const;
void setReservedRegion(const byte_t* data, size_t len);
uint64_t getTicketId() const;
void setTicketId(uint64_t id);
uint64_t getDeviceId() const;
void setDeviceId(uint64_t id);
const byte_t* getRightsId() const;
void setRightsId(const byte_t* id);
uint32_t getAccountId() const;
void setAccountId(uint32_t id);
uint32_t getSectionTotalSize() const;
void setSectionTotalSize(uint32_t size);
uint32_t getSectionHeaderOffset() const;
void setSectionHeaderOffset(uint32_t offset);
uint16_t getSectionNum() const;
void setSectionNum(uint16_t num);
uint16_t getSectionEntrySize() const;
void setSectionEntrySize(uint16_t size);
private:
const std::string kModuleName = "TICKET_BODY_V2";
// raw binary
fnd::MemoryBlob mBinaryBlob;
// variables
std::string mIssuer;
byte_t mEncTitleKey[ticket::kEncTitleKeySize];
ticket::TitleKeyEncType mEncType; // 0 = aes-cbc, 1 = rsa2048
uint16_t mTicketVersion;
ticket::LicenseType mLicenseType;
byte_t mCommonKeyId;
bool mPreInstall;
bool mSharedTitle;
bool mAllowAllContent;
byte_t mReservedRegion[ticket::kReservedRegionSize]; // explicitly reserved
uint64_t mTicketId;
uint64_t mDeviceId;
byte_t mRightsId[ticket::kRightsIdSize];
uint32_t mAccountId;
uint32_t mSectTotalSize;
uint32_t mSectHeaderOffset;
uint16_t mSectNum;
uint16_t mSectEntrySize;
// helpers
bool isEqual(const TicketBody_V2& other) const;
void copyFrom(const TicketBody_V2& other);
};
}

View file

@ -0,0 +1,50 @@
#pragma once
#include <string>
#include <fnd/types.h>
#include <crypto/aes.h>
#include <crypto/rsa.h>
namespace es
{
namespace cert
{
enum PublicKeyType
{
RSA4096,
RSA2048,
ECDSA240
};
static const size_t kIssuerSize = 0x40;
static const size_t kSubjectSize = 0x40;
}
#pragma pack(push,1)
struct sCertificateBody
{
char issuer[cert::kIssuerSize];
be_uint32_t key_type;
char subject[cert::kSubjectSize];
be_uint32_t cert_id;
}
struct sRsa4096PublicKeyBlock
{
byte_t modulus[crypto::rsa::kRsa4096Size];
byte_t public_exponent[0x4];
byte_t padding[0x34];
};
struct sRsa2048PublicKeyBlock
{
byte_t modulus[crypto::rsa::kRsa2048Size];
byte_t public_exponent[0x4];
byte_t padding[0x34];
};
struct sEcdsa240PublicKeyBlock
{
byte_t public_key[0x3C];
byte_t padding[0x3C];
};
#pragma pack(pop)
}

View file

@ -0,0 +1,43 @@
#pragma once
#include <string>
#include <fnd/types.h>
#include <crypto/aes.h>
#include <crypto/rsa.h>
namespace es
{
namespace sign
{
enum SignType
{
SIGN_RSA4096_SHA1 = 0x10000,
SIGN_RSA2048_SHA1,
SIGN_ECDSA240_SHA1,
SIGN_RSA4096_SHA256,
SIGN_RSA2048_SHA256,
SIGN_ECDSA240_SHA256,
};
}
#pragma pack(push,1)
struct sRsa4096SignBlock
{
be_uint32_t sign_type;
byte_t signature[crypto::rsa::kRsa4096Size];
byte_t padding[0x3C];
};
struct sRsa2048SignBlock
{
be_uint32_t sign_type;
byte_t signature[crypto::rsa::kRsa2048Size];
byte_t padding[0x3C];
};
struct sEcdsa240SignBlock
{
be_uint32_t sign_type;
byte_t signature[0x3C];
byte_t padding[0x40];
};
#pragma pack(pop)
}

View file

@ -0,0 +1,108 @@
#pragma once
#include <string>
#include <fnd/types.h>
#include <crypto/rsa.h>
namespace es
{
namespace ticket
{
enum TitleKeyEncType
{
AES128_CBC,
RSA2048
};
enum LicenseType
{
LICENSE_PERMANENT = 0,
LICENSE_DEMO = 1,
LICENSE_TRIAL = 2,
LICENSE_RENTAL = 3,
LICENSE_SUBSCRIPTION = 4,
LICENSE_SERVICE = 5,
};
enum PropertyMaskFlags
{
FLAG_PRE_INSTALL,
FLAG_SHARED_TITLE,
FLAG_ALLOW_ALL_CONTENT
};
enum SectionType
{
SECTION_PERMANENT = 1,
SECTION_SUBSCRIPTION = 2,
SECTION_CONTENT = 3,
SECTION_CONTENT_CONSUMPTION = 4,
SECTION_ACCESS_TITLE = 5,
SECTION_LIMITED_RESOURCE = 6,
};
static const size_t kIssuerSize = 0x40;
static const byte_t kFormatVersion = 2;
static const size_t kEncTitleKeySize = crypto::rsa::kRsa2048Size;
static const size_t kReservedRegionSize = 8;
static const size_t kRightsIdSize = 16;
}
#pragma pack(push,1)
struct sTicketBody_v2
{
char issuer[ticket::kIssuerSize];
byte_t enc_title_key[ticket::kEncTitleKeySize];
byte_t format_version;
byte_t title_key_enc_type;
le_uint16_t ticket_version;
byte_t license_type;
byte_t common_key_id;
byte_t property_mask;
byte_t reserved_0;
byte_t reserved_region[ticket::kReservedRegionSize]; // explicitly reserved
le_uint64_t ticket_id;
le_uint64_t device_id;
byte_t rights_id[ticket::kRightsIdSize];
le_uint32_t account_id;
le_uint32_t sect_total_size;
le_uint32_t sect_header_offset;
le_uint16_t sect_num;
le_uint16_t sect_entry_size;
};
struct sSectionHeader_v2
{
le_uint32_t section_offset;
le_uint32_t record_size;
le_uint32_t section_size;
le_uint16_t record_num;
le_uint16_t section_type;
};
struct sContentRecord_v1
{
private:
static const size_t kAccessMaskSize = 0x80;
static const uint16_t kGroupMask = 0xFC00;
static const uint16_t kAccessMaskMask = 0x3FF;
be_uint32_t group;
byte_t access_mask[kAccessMaskSize];
public:
uint32_t index_group() const { return group.get(); }
bool is_index_enabled(uint16_t index) const
{
return (index_group() == get_group(index)) \
&& ((access_mask[get_access_mask(index) / 8] & BIT(get_access_mask(index) % 8)) != 0);
}
void clear() { memset(this, 0, sizeof(sContentRecord_v1)); }
void set_index_group(uint16_t index) { group = get_group(index); }
void enable_index(uint16_t index) { access_mask[get_access_mask(index) / 8] |= BIT(get_access_mask(index) % 8); }
void disable_index(uint16_t index) { access_mask[get_access_mask(index) / 8] &= ~BIT(get_access_mask(index) % 8); }
inline uint16_t get_access_mask(uint16_t index) const { return index & kAccessMaskMask; }
inline uint16_t get_group(uint16_t index) const { return index & kGroupMask; }
};
#pragma pack(pop)
}

View file

@ -1,366 +0,0 @@
#include <es/ETicketBody_V2.h>
es::ETicketBody_V2::ETicketBody_V2()
{
clear();
}
es::ETicketBody_V2::ETicketBody_V2(const ETicketBody_V2 & other)
{
copyFrom(other);
}
es::ETicketBody_V2::ETicketBody_V2(const byte_t * bytes, size_t len)
{
importBinary(bytes, len);
}
bool es::ETicketBody_V2::operator==(const ETicketBody_V2 & other) const
{
return isEqual(other);
}
bool es::ETicketBody_V2::operator!=(const ETicketBody_V2 & other) const
{
return !isEqual(other);
}
void es::ETicketBody_V2::operator=(const ETicketBody_V2 & other)
{
copyFrom(other);
}
const byte_t * es::ETicketBody_V2::getBytes() const
{
return mBinaryBlob.getBytes();
}
size_t es::ETicketBody_V2::getSize() const
{
return mBinaryBlob.getSize();
}
bool es::ETicketBody_V2::isEqual(const ETicketBody_V2 & other) const
{
return (mIssuer == other.mIssuer) \
&& (memcmp(mEncTitleKey, other.mEncTitleKey, kEncTitleKeyLen) == 0) \
&& (mEncType == other.mEncType) \
&& (mTicketVersion == other.mTicketVersion) \
&& (mLicenseType == other.mLicenseType) \
&& (mPreInstall == other.mPreInstall) \
&& (mSharedTitle == other.mSharedTitle) \
&& (mAllowAllContent == other.mAllowAllContent) \
&& (memcmp(mReservedRegion, other.mReservedRegion, kReservedRegionLen) == 0) \
&& (mTicketId == other.mTicketId) \
&& (mDeviceId == other.mDeviceId) \
&& (memcmp(mRightsId, other.mRightsId, kRightsIdLen) == 0) \
&& (mAccountId == other.mAccountId) \
&& (mSectTotalSize == other.mSectTotalSize) \
&& (mSectHeaderOffset == other.mSectHeaderOffset) \
&& (mSectNum == other.mSectNum) \
&& (mSectEntrySize == other.mSectEntrySize);
}
void es::ETicketBody_V2::copyFrom(const ETicketBody_V2 & other)
{
if (other.getSize())
{
importBinary(other.getBytes(), other.getSize());
}
else
{
clear();
mIssuer = other.mIssuer;
memcpy(mEncTitleKey, other.mEncTitleKey, kEncTitleKeyLen);
mEncType = other.mEncType;
mTicketVersion = other.mTicketVersion;
mLicenseType = other.mLicenseType;
mPreInstall = other.mPreInstall;
mSharedTitle = other.mSharedTitle;
mAllowAllContent = other.mAllowAllContent;
memcpy(mReservedRegion, other.mReservedRegion, kReservedRegionLen);
mTicketId = other.mTicketId;
mDeviceId = other.mDeviceId;
memcpy(mRightsId, other.mRightsId, kRightsIdLen);
mAccountId = other.mAccountId;
mSectTotalSize = other.mSectTotalSize;
mSectHeaderOffset = other.mSectHeaderOffset;
mSectNum = other.mSectNum;
mSectEntrySize = other.mSectEntrySize;
}
}
void es::ETicketBody_V2::exportBinary()
{
mBinaryBlob.alloc(sizeof(sTicketBody_v2));
sTicketBody_v2* body = (sTicketBody_v2*)mBinaryBlob.getBytes();
body->format_version = (kFormatVersion);
strncmp(body->issuer, mIssuer.c_str(), kIssuerLen);
memcpy(body->enc_title_key, mEncTitleKey, kEncTitleKeyLen);
body->title_key_enc_type = (mEncType);
body->ticket_version = (mTicketVersion);
byte_t property_mask = 0;
property_mask |= mPreInstall ? BIT(FLAG_PRE_INSTALL) : 0;
property_mask |= mSharedTitle ? BIT(FLAG_SHARED_TITLE) : 0;
property_mask |= mAllowAllContent ? BIT(FLAG_ALLOW_ALL_CONTENT) : 0;
body->property_mask = (property_mask);
memcpy(body->reserved_region, mReservedRegion, kReservedRegionLen);
body->ticket_id = (mTicketId);
body->device_id = (mDeviceId);
memcmp(body->rights_id, mRightsId, kRightsIdLen);
body->account_id = (mAccountId);
body->sect_total_size = (mSectTotalSize);
body->sect_header_offset = (mSectHeaderOffset);
body->sect_num = (mSectNum);
body->sect_entry_size = (mSectEntrySize);
}
void es::ETicketBody_V2::importBinary(const byte_t * bytes, size_t len)
{
if (len < sizeof(sTicketBody_v2))
{
throw fnd::Exception(kModuleName, "Header size too small");
}
clear();
mBinaryBlob.alloc(sizeof(sTicketBody_v2));
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize());
sTicketBody_v2* body = (sTicketBody_v2*)mBinaryBlob.getBytes();
if (body->format_version != kFormatVersion)
{
throw fnd::Exception(kModuleName, "Unsupported format version");
}
mIssuer.append(body->issuer, kIssuerLen);
memcpy(mEncTitleKey, body->enc_title_key, kEncTitleKeyLen);
mEncType = (TitleKeyEncType)body->title_key_enc_type;
mTicketVersion = body->ticket_version.get();
mLicenseType = (LicenseType)body->license_type;
mPreInstall = (body->property_mask & BIT(FLAG_PRE_INSTALL)) == BIT(FLAG_PRE_INSTALL);
mSharedTitle = (body->property_mask & BIT(FLAG_SHARED_TITLE)) == BIT(FLAG_SHARED_TITLE);
mAllowAllContent = (body->property_mask & BIT(FLAG_ALLOW_ALL_CONTENT)) == BIT(FLAG_ALLOW_ALL_CONTENT);
memcpy(mReservedRegion, body->reserved_region, kReservedRegionLen);
mTicketId = body->ticket_id.get();
mDeviceId = body->device_id.get();
memcpy(mRightsId, body->rights_id, kRightsIdLen);
mAccountId = body->account_id.get();
mSectTotalSize = body->sect_total_size.get();
mSectHeaderOffset = body->sect_header_offset.get();
mSectNum = body->sect_num.get();
mSectEntrySize = body->sect_entry_size.get();
}
void es::ETicketBody_V2::clear()
{
mBinaryBlob.clear();
mIssuer.clear();
memset(mEncTitleKey, 0, kEncTitleKeyLen);
mEncType = AES128_CBC;
mTicketVersion = 0;
mLicenseType = ES_LICENSE_PERMANENT;
mPreInstall = false;
mSharedTitle = false;
mAllowAllContent = false;
memset(mReservedRegion, 0, kReservedRegionLen);
mTicketId = 0;
mDeviceId = 0;
memset(mRightsId, 0, kRightsIdLen);
mAccountId = 0;
mSectTotalSize = 0;
mSectHeaderOffset = 0;
mSectNum = 0;
mSectEntrySize = 0;
}
const std::string & es::ETicketBody_V2::getIssuer() const
{
return mIssuer;
}
void es::ETicketBody_V2::setIssuer(const std::string & issuer)
{
if (issuer.length() > kIssuerLen)
{
throw fnd::Exception(kModuleName, "Issuer is too long");
}
mIssuer = issuer;
}
const byte_t * es::ETicketBody_V2::getEncTitleKey() const
{
return mEncTitleKey;
}
void es::ETicketBody_V2::setEncTitleKey(const byte_t * data, size_t len)
{
memset(mEncTitleKey, 0, kEncTitleKeyLen);
memcpy(mEncTitleKey, data, MIN(len, kEncTitleKeyLen));
}
es::ETicketBody_V2::TitleKeyEncType es::ETicketBody_V2::getTitleKeyEncType() const
{
return mEncType;
}
void es::ETicketBody_V2::setTitleKeyEncType(TitleKeyEncType type)
{
mEncType = type;
}
uint16_t es::ETicketBody_V2::getTicketVersion() const
{
return mTicketVersion;
}
void es::ETicketBody_V2::setTicketVersion(uint16_t version)
{
mTicketVersion = version;
}
es::ETicketBody_V2::LicenseType es::ETicketBody_V2::getLicenseType() const
{
return mLicenseType;
}
void es::ETicketBody_V2::setLicenseType(LicenseType type)
{
mLicenseType = type;
}
byte_t es::ETicketBody_V2::getCommonKeyId() const
{
return mCommonKeyId;
}
void es::ETicketBody_V2::setCommonKeyId(byte_t id)
{
mCommonKeyId = id;
}
bool es::ETicketBody_V2::isPreInstall() const
{
return mPreInstall;
}
void es::ETicketBody_V2::setIsPreInstall(bool isPreInstall)
{
mPreInstall = isPreInstall;
}
bool es::ETicketBody_V2::isSharedTitle() const
{
return mSharedTitle;
}
void es::ETicketBody_V2::setIsSharedTitle(bool isSharedTitle)
{
mSharedTitle = isSharedTitle;
}
bool es::ETicketBody_V2::allowAllContent() const
{
return mAllowAllContent;
}
void es::ETicketBody_V2::setAllowAllContent(bool allowAllContent)
{
mAllowAllContent = allowAllContent;
}
const byte_t * es::ETicketBody_V2::getReservedRegion() const
{
return mReservedRegion;
}
void es::ETicketBody_V2::setReservedRegion(const byte_t * data, size_t len)
{
memset(mReservedRegion, 0, kReservedRegionLen);
memcpy(mReservedRegion, data, MIN(len, kReservedRegionLen));
}
uint64_t es::ETicketBody_V2::getTicketId() const
{
return mTicketId;
}
void es::ETicketBody_V2::setTicketId(uint64_t id)
{
mTicketId = id;
}
uint64_t es::ETicketBody_V2::getDeviceId() const
{
return mDeviceId;
}
void es::ETicketBody_V2::setDeviceId(uint64_t id)
{
mDeviceId = id;
}
const byte_t * es::ETicketBody_V2::getRightsId() const
{
return mRightsId;
}
void es::ETicketBody_V2::setRightsId(const byte_t * id)
{
memcpy(mRightsId, id, kRightsIdLen);
}
uint32_t es::ETicketBody_V2::getAccountId() const
{
return mAccountId;
}
void es::ETicketBody_V2::setAccountId(uint32_t id)
{
mAccountId = id;
}
uint32_t es::ETicketBody_V2::getSectionTotalSize() const
{
return mSectTotalSize;
}
void es::ETicketBody_V2::setSectionTotalSize(uint32_t size)
{
mSectTotalSize = size;
}
uint32_t es::ETicketBody_V2::getSectionHeaderOffset() const
{
return mSectHeaderOffset;
}
void es::ETicketBody_V2::setSectionHeaderOffset(uint32_t offset)
{
mSectHeaderOffset = offset;
}
uint16_t es::ETicketBody_V2::getSectionNum() const
{
return mSectNum;
}
void es::ETicketBody_V2::setSectionNum(uint16_t num)
{
mSectNum = num;
}
uint16_t es::ETicketBody_V2::getSectionEntrySize() const
{
return mSectEntrySize;
}
void es::ETicketBody_V2::setSectionEntrySize(uint16_t size)
{
mSectEntrySize = size;
}

View file

@ -1,6 +0,0 @@
#include <es/ETicketContentRecord_V1.h>
es::ETicketContentRecord_V1::ETicketContentRecord_V1()
{}

View file

@ -1,46 +1,46 @@
#include <es/ETicketSectionHeader_V2.h>
#include <es/SectionHeader_V2.h>
es::ETicketSectionHeader_V2::ETicketSectionHeader_V2()
es::SectionHeader_V2::SectionHeader_V2()
{}
es::ETicketSectionHeader_V2::ETicketSectionHeader_V2(const ETicketSectionHeader_V2 & other)
es::SectionHeader_V2::SectionHeader_V2(const SectionHeader_V2 & other)
{
copyFrom(other);
}
es::ETicketSectionHeader_V2::ETicketSectionHeader_V2(const byte_t * bytes, size_t len)
es::SectionHeader_V2::SectionHeader_V2(const byte_t * bytes, size_t len)
{
importBinary(bytes, len);
}
bool es::ETicketSectionHeader_V2::operator==(const ETicketSectionHeader_V2 & other) const
bool es::SectionHeader_V2::operator==(const SectionHeader_V2 & other) const
{
return isEqual(other);
}
bool es::ETicketSectionHeader_V2::operator!=(const ETicketSectionHeader_V2 & other) const
bool es::SectionHeader_V2::operator!=(const SectionHeader_V2 & other) const
{
return !isEqual(other);
}
void es::ETicketSectionHeader_V2::operator=(const ETicketSectionHeader_V2 & other)
void es::SectionHeader_V2::operator=(const SectionHeader_V2 & other)
{
copyFrom(other);
}
const byte_t * es::ETicketSectionHeader_V2::getBytes() const
const byte_t * es::SectionHeader_V2::getBytes() const
{
return mBinaryBlob.getBytes();
}
size_t es::ETicketSectionHeader_V2::getSize() const
size_t es::SectionHeader_V2::getSize() const
{
return mBinaryBlob.getSize();
}
void es::ETicketSectionHeader_V2::exportBinary()
void es::SectionHeader_V2::exportBinary()
{
mBinaryBlob.alloc(sizeof(sSectionHeader_v2));
sSectionHeader_v2* hdr = (sSectionHeader_v2*)mBinaryBlob.getBytes();
@ -52,7 +52,7 @@ void es::ETicketSectionHeader_V2::exportBinary()
hdr->section_type = (mSectionType);
}
void es::ETicketSectionHeader_V2::importBinary(const byte_t * bytes, size_t len)
void es::SectionHeader_V2::importBinary(const byte_t * bytes, size_t len)
{
if (len < sizeof(sSectionHeader_v2))
{
@ -69,10 +69,10 @@ void es::ETicketSectionHeader_V2::importBinary(const byte_t * bytes, size_t len)
mRecordSize = hdr->record_size.get();
mSectionSize = hdr->section_size.get();
mRecordNum = hdr->record_num.get();
mSectionType = (SectionType)hdr->section_type.get();
mSectionType = (ticket::SectionType)hdr->section_type.get();
}
bool es::ETicketSectionHeader_V2::isEqual(const ETicketSectionHeader_V2 & other) const
bool es::SectionHeader_V2::isEqual(const SectionHeader_V2 & other) const
{
return (mSectionOffset == other.mSectionOffset) \
&& (mRecordSize == other.mRecordSize) \
@ -81,7 +81,7 @@ bool es::ETicketSectionHeader_V2::isEqual(const ETicketSectionHeader_V2 & other)
&& (mSectionType == other.mSectionType);
}
void es::ETicketSectionHeader_V2::copyFrom(const ETicketSectionHeader_V2 & other)
void es::SectionHeader_V2::copyFrom(const SectionHeader_V2 & other)
{
if (other.getSize())
{
@ -98,62 +98,62 @@ void es::ETicketSectionHeader_V2::copyFrom(const ETicketSectionHeader_V2 & other
}
}
void es::ETicketSectionHeader_V2::clear()
void es::SectionHeader_V2::clear()
{
mBinaryBlob.clear();
mSectionOffset = 0;
mRecordSize = 0;
mSectionSize = 0;
mRecordNum = 0;
mSectionType = PERMANENT;
mSectionType = ticket::SECTION_PERMANENT;
}
uint32_t es::ETicketSectionHeader_V2::getSectionOffset() const
uint32_t es::SectionHeader_V2::getSectionOffset() const
{
return mSectionOffset;
}
void es::ETicketSectionHeader_V2::setSectionOffset(uint32_t offset)
void es::SectionHeader_V2::setSectionOffset(uint32_t offset)
{
mSectionOffset = offset;
}
uint32_t es::ETicketSectionHeader_V2::getRecordSize() const
uint32_t es::SectionHeader_V2::getRecordSize() const
{
return mRecordSize;
}
void es::ETicketSectionHeader_V2::setRecordSize(uint32_t size)
void es::SectionHeader_V2::setRecordSize(uint32_t size)
{
mRecordSize = size;
}
uint32_t es::ETicketSectionHeader_V2::getSectionSize() const
uint32_t es::SectionHeader_V2::getSectionSize() const
{
return mSectionSize;
}
void es::ETicketSectionHeader_V2::getSectionSize(uint32_t size)
void es::SectionHeader_V2::getSectionSize(uint32_t size)
{
mSectionSize = size;
}
uint16_t es::ETicketSectionHeader_V2::getRecordNum() const
uint16_t es::SectionHeader_V2::getRecordNum() const
{
return mRecordNum;
}
void es::ETicketSectionHeader_V2::setRecordNum(uint16_t record_num)
void es::SectionHeader_V2::setRecordNum(uint16_t record_num)
{
mRecordNum = record_num;
}
es::ETicketSectionHeader_V2::SectionType es::ETicketSectionHeader_V2::getSectionType() const
es::ticket::SectionType es::SectionHeader_V2::getSectionType() const
{
return mSectionType;
}
void es::ETicketSectionHeader_V2::setSectionType(SectionType type)
void es::SectionHeader_V2::setSectionType(ticket::SectionType type)
{
mSectionType = type;
}

View file

@ -0,0 +1,366 @@
#include <es/TicketBody_V2.h>
es::TicketBody_V2::TicketBody_V2()
{
clear();
}
es::TicketBody_V2::TicketBody_V2(const TicketBody_V2 & other)
{
copyFrom(other);
}
es::TicketBody_V2::TicketBody_V2(const byte_t * bytes, size_t len)
{
importBinary(bytes, len);
}
bool es::TicketBody_V2::operator==(const TicketBody_V2 & other) const
{
return isEqual(other);
}
bool es::TicketBody_V2::operator!=(const TicketBody_V2 & other) const
{
return !isEqual(other);
}
void es::TicketBody_V2::operator=(const TicketBody_V2 & other)
{
copyFrom(other);
}
const byte_t * es::TicketBody_V2::getBytes() const
{
return mBinaryBlob.getBytes();
}
size_t es::TicketBody_V2::getSize() const
{
return mBinaryBlob.getSize();
}
bool es::TicketBody_V2::isEqual(const TicketBody_V2 & other) const
{
return (mIssuer == other.mIssuer) \
&& (memcmp(mEncTitleKey, other.mEncTitleKey, ticket::kEncTitleKeySize) == 0) \
&& (mEncType == other.mEncType) \
&& (mTicketVersion == other.mTicketVersion) \
&& (mLicenseType == other.mLicenseType) \
&& (mPreInstall == other.mPreInstall) \
&& (mSharedTitle == other.mSharedTitle) \
&& (mAllowAllContent == other.mAllowAllContent) \
&& (memcmp(mReservedRegion, other.mReservedRegion, ticket::kReservedRegionSize) == 0) \
&& (mTicketId == other.mTicketId) \
&& (mDeviceId == other.mDeviceId) \
&& (memcmp(mRightsId, other.mRightsId, ticket::kRightsIdSize) == 0) \
&& (mAccountId == other.mAccountId) \
&& (mSectTotalSize == other.mSectTotalSize) \
&& (mSectHeaderOffset == other.mSectHeaderOffset) \
&& (mSectNum == other.mSectNum) \
&& (mSectEntrySize == other.mSectEntrySize);
}
void es::TicketBody_V2::copyFrom(const TicketBody_V2 & other)
{
if (other.getSize())
{
importBinary(other.getBytes(), other.getSize());
}
else
{
clear();
mIssuer = other.mIssuer;
memcpy(mEncTitleKey, other.mEncTitleKey, ticket::kEncTitleKeySize);
mEncType = other.mEncType;
mTicketVersion = other.mTicketVersion;
mLicenseType = other.mLicenseType;
mPreInstall = other.mPreInstall;
mSharedTitle = other.mSharedTitle;
mAllowAllContent = other.mAllowAllContent;
memcpy(mReservedRegion, other.mReservedRegion, ticket::kReservedRegionSize);
mTicketId = other.mTicketId;
mDeviceId = other.mDeviceId;
memcpy(mRightsId, other.mRightsId, ticket::kRightsIdSize);
mAccountId = other.mAccountId;
mSectTotalSize = other.mSectTotalSize;
mSectHeaderOffset = other.mSectHeaderOffset;
mSectNum = other.mSectNum;
mSectEntrySize = other.mSectEntrySize;
}
}
void es::TicketBody_V2::exportBinary()
{
mBinaryBlob.alloc(sizeof(sTicketBody_v2));
sTicketBody_v2* body = (sTicketBody_v2*)mBinaryBlob.getBytes();
body->format_version = (ticket::kFormatVersion);
strncmp(body->issuer, mIssuer.c_str(), ticket::kIssuerSize);
memcpy(body->enc_title_key, mEncTitleKey, ticket::kEncTitleKeySize);
body->title_key_enc_type = (mEncType);
body->ticket_version = (mTicketVersion);
byte_t property_mask = 0;
property_mask |= mPreInstall ? _BIT(ticket::FLAG_PRE_INSTALL) : 0;
property_mask |= mSharedTitle ? _BIT(ticket::FLAG_SHARED_TITLE) : 0;
property_mask |= mAllowAllContent ? _BIT(ticket::FLAG_ALLOW_ALL_CONTENT) : 0;
body->property_mask = (property_mask);
memcpy(body->reserved_region, mReservedRegion, ticket::kReservedRegionSize);
body->ticket_id = (mTicketId);
body->device_id = (mDeviceId);
memcmp(body->rights_id, mRightsId, ticket::kRightsIdSize);
body->account_id = (mAccountId);
body->sect_total_size = (mSectTotalSize);
body->sect_header_offset = (mSectHeaderOffset);
body->sect_num = (mSectNum);
body->sect_entry_size = (mSectEntrySize);
}
void es::TicketBody_V2::importBinary(const byte_t * bytes, size_t len)
{
if (len < sizeof(sTicketBody_v2))
{
throw fnd::Exception(kModuleName, "Header size too small");
}
clear();
mBinaryBlob.alloc(sizeof(sTicketBody_v2));
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize());
sTicketBody_v2* body = (sTicketBody_v2*)mBinaryBlob.getBytes();
if (body->format_version != ticket::kFormatVersion)
{
throw fnd::Exception(kModuleName, "Unsupported format version");
}
mIssuer.append(body->issuer, ticket::kIssuerSize);
memcpy(mEncTitleKey, body->enc_title_key, ticket::kEncTitleKeySize);
mEncType = (ticket::TitleKeyEncType)body->title_key_enc_type;
mTicketVersion = body->ticket_version.get();
mLicenseType = (ticket::LicenseType)body->license_type;
mPreInstall = _HAS_BIT(body->property_mask, ticket::FLAG_PRE_INSTALL);
mSharedTitle = _HAS_BIT(body->property_mask, ticket::FLAG_SHARED_TITLE);
mAllowAllContent = _HAS_BIT(body->property_mask, ticket::FLAG_ALLOW_ALL_CONTENT);
memcpy(mReservedRegion, body->reserved_region, ticket::kReservedRegionSize);
mTicketId = body->ticket_id.get();
mDeviceId = body->device_id.get();
memcpy(mRightsId, body->rights_id, ticket::kRightsIdSize);
mAccountId = body->account_id.get();
mSectTotalSize = body->sect_total_size.get();
mSectHeaderOffset = body->sect_header_offset.get();
mSectNum = body->sect_num.get();
mSectEntrySize = body->sect_entry_size.get();
}
void es::TicketBody_V2::clear()
{
mBinaryBlob.clear();
mIssuer.clear();
memset(mEncTitleKey, 0, ticket::kEncTitleKeySize);
mEncType = ticket::AES128_CBC;
mTicketVersion = 0;
mLicenseType = ticket::LICENSE_PERMANENT;
mPreInstall = false;
mSharedTitle = false;
mAllowAllContent = false;
memset(mReservedRegion, 0, ticket::kReservedRegionSize);
mTicketId = 0;
mDeviceId = 0;
memset(mRightsId, 0, ticket::kRightsIdSize);
mAccountId = 0;
mSectTotalSize = 0;
mSectHeaderOffset = 0;
mSectNum = 0;
mSectEntrySize = 0;
}
const std::string & es::TicketBody_V2::getIssuer() const
{
return mIssuer;
}
void es::TicketBody_V2::setIssuer(const std::string & issuer)
{
if (issuer.length() > ticket::kIssuerSize)
{
throw fnd::Exception(kModuleName, "Issuer is too long");
}
mIssuer = issuer;
}
const byte_t * es::TicketBody_V2::getEncTitleKey() const
{
return mEncTitleKey;
}
void es::TicketBody_V2::setEncTitleKey(const byte_t * data, size_t len)
{
memset(mEncTitleKey, 0, ticket::kEncTitleKeySize);
memcpy(mEncTitleKey, data, MIN(len, ticket::kEncTitleKeySize));
}
es::ticket::TitleKeyEncType es::TicketBody_V2::getTitleKeyEncType() const
{
return mEncType;
}
void es::TicketBody_V2::setTitleKeyEncType(ticket::TitleKeyEncType type)
{
mEncType = type;
}
uint16_t es::TicketBody_V2::getTicketVersion() const
{
return mTicketVersion;
}
void es::TicketBody_V2::setTicketVersion(uint16_t version)
{
mTicketVersion = version;
}
es::ticket::LicenseType es::TicketBody_V2::getLicenseType() const
{
return mLicenseType;
}
void es::TicketBody_V2::setLicenseType(ticket::LicenseType type)
{
mLicenseType = type;
}
byte_t es::TicketBody_V2::getCommonKeyId() const
{
return mCommonKeyId;
}
void es::TicketBody_V2::setCommonKeyId(byte_t id)
{
mCommonKeyId = id;
}
bool es::TicketBody_V2::isPreInstall() const
{
return mPreInstall;
}
void es::TicketBody_V2::setIsPreInstall(bool isPreInstall)
{
mPreInstall = isPreInstall;
}
bool es::TicketBody_V2::isSharedTitle() const
{
return mSharedTitle;
}
void es::TicketBody_V2::setIsSharedTitle(bool isSharedTitle)
{
mSharedTitle = isSharedTitle;
}
bool es::TicketBody_V2::allowAllContent() const
{
return mAllowAllContent;
}
void es::TicketBody_V2::setAllowAllContent(bool allowAllContent)
{
mAllowAllContent = allowAllContent;
}
const byte_t * es::TicketBody_V2::getReservedRegion() const
{
return mReservedRegion;
}
void es::TicketBody_V2::setReservedRegion(const byte_t * data, size_t len)
{
memset(mReservedRegion, 0, ticket::kReservedRegionSize);
memcpy(mReservedRegion, data, MIN(len, ticket::kReservedRegionSize));
}
uint64_t es::TicketBody_V2::getTicketId() const
{
return mTicketId;
}
void es::TicketBody_V2::setTicketId(uint64_t id)
{
mTicketId = id;
}
uint64_t es::TicketBody_V2::getDeviceId() const
{
return mDeviceId;
}
void es::TicketBody_V2::setDeviceId(uint64_t id)
{
mDeviceId = id;
}
const byte_t * es::TicketBody_V2::getRightsId() const
{
return mRightsId;
}
void es::TicketBody_V2::setRightsId(const byte_t * id)
{
memcpy(mRightsId, id, ticket::kRightsIdSize);
}
uint32_t es::TicketBody_V2::getAccountId() const
{
return mAccountId;
}
void es::TicketBody_V2::setAccountId(uint32_t id)
{
mAccountId = id;
}
uint32_t es::TicketBody_V2::getSectionTotalSize() const
{
return mSectTotalSize;
}
void es::TicketBody_V2::setSectionTotalSize(uint32_t size)
{
mSectTotalSize = size;
}
uint32_t es::TicketBody_V2::getSectionHeaderOffset() const
{
return mSectHeaderOffset;
}
void es::TicketBody_V2::setSectionHeaderOffset(uint32_t offset)
{
mSectHeaderOffset = offset;
}
uint16_t es::TicketBody_V2::getSectionNum() const
{
return mSectNum;
}
void es::TicketBody_V2::setSectionNum(uint16_t num)
{
mSectNum = num;
}
uint16_t es::TicketBody_V2::getSectionEntrySize() const
{
return mSectEntrySize;
}
void es::TicketBody_V2::setSectionEntrySize(uint16_t size)
{
mSectEntrySize = size;
}