2018-08-07 07:17:51 +00:00
|
|
|
#include <nn/es/TicketBody_V2.h>
|
2018-06-06 12:38:42 +00:00
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
nn::es::TicketBody_V2::TicketBody_V2()
|
2018-06-06 12:38:42 +00:00
|
|
|
{
|
|
|
|
clear();
|
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
nn::es::TicketBody_V2::TicketBody_V2(const TicketBody_V2 & other)
|
2018-06-06 12:38:42 +00:00
|
|
|
{
|
2018-06-24 04:46:11 +00:00
|
|
|
*this = other;
|
2018-06-06 12:38:42 +00:00
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
void nn::es::TicketBody_V2::operator=(const TicketBody_V2 & other)
|
2018-06-06 12:38:42 +00:00
|
|
|
{
|
2018-06-24 04:46:11 +00:00
|
|
|
if (other.getBytes().size())
|
|
|
|
{
|
|
|
|
fromBytes(other.getBytes().data(), other.getBytes().size());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
clear();
|
|
|
|
mIssuer = other.mIssuer;
|
|
|
|
memcpy(mEncTitleKey, other.mEncTitleKey, ticket::kEncTitleKeySize);
|
|
|
|
mEncType = other.mEncType;
|
|
|
|
mTicketVersion = other.mTicketVersion;
|
|
|
|
mLicenseType = other.mLicenseType;
|
2018-07-04 05:35:35 +00:00
|
|
|
mCommonKeyId = other.mCommonKeyId;
|
2018-07-04 06:00:45 +00:00
|
|
|
mPropertyFlags = other.mPropertyFlags;
|
2018-06-24 04:46:11 +00:00
|
|
|
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;
|
|
|
|
}
|
2018-06-06 12:38:42 +00:00
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
bool nn::es::TicketBody_V2::operator==(const TicketBody_V2 & other) const
|
2018-06-24 05:20:56 +00:00
|
|
|
{
|
|
|
|
return (mIssuer == other.mIssuer) \
|
|
|
|
&& (memcmp(mEncTitleKey, other.mEncTitleKey, ticket::kEncTitleKeySize) == 0) \
|
|
|
|
&& (mEncType == other.mEncType) \
|
|
|
|
&& (mTicketVersion == other.mTicketVersion) \
|
|
|
|
&& (mLicenseType == other.mLicenseType) \
|
2018-07-04 06:00:45 +00:00
|
|
|
&& (mPropertyFlags == other.mPropertyFlags) \
|
2018-06-24 05:20:56 +00:00
|
|
|
&& (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);
|
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
bool nn::es::TicketBody_V2::operator!=(const TicketBody_V2 & other) const
|
2018-06-24 05:20:56 +00:00
|
|
|
{
|
|
|
|
return !(*this == other);
|
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
void nn::es::TicketBody_V2::toBytes()
|
2018-06-06 12:38:42 +00:00
|
|
|
{
|
2018-06-24 04:46:11 +00:00
|
|
|
mRawBinary.alloc(sizeof(sTicketBody_v2));
|
|
|
|
sTicketBody_v2* body = (sTicketBody_v2*)mRawBinary.data();
|
2018-06-06 12:38:42 +00:00
|
|
|
|
|
|
|
body->format_version = (ticket::kFormatVersion);
|
|
|
|
|
2018-07-04 05:35:35 +00:00
|
|
|
strncpy(body->issuer, mIssuer.c_str(), ticket::kIssuerSize);
|
2018-06-06 12:38:42 +00:00
|
|
|
memcpy(body->enc_title_key, mEncTitleKey, ticket::kEncTitleKeySize);
|
|
|
|
body->title_key_enc_type = (mEncType);
|
|
|
|
body->ticket_version = (mTicketVersion);
|
2018-07-04 05:35:35 +00:00
|
|
|
body->license_type = mLicenseType;
|
|
|
|
body->common_key_id = mCommonKeyId;
|
2018-06-06 12:38:42 +00:00
|
|
|
byte_t property_mask = 0;
|
2018-07-04 06:00:45 +00:00
|
|
|
for (size_t i = 0; i < mPropertyFlags.size(); i++)
|
|
|
|
{
|
|
|
|
property_mask |= _BIT(mPropertyFlags[i]);
|
|
|
|
}
|
2018-06-06 12:38:42 +00:00
|
|
|
body->property_mask = (property_mask);
|
|
|
|
memcpy(body->reserved_region, mReservedRegion, ticket::kReservedRegionSize);
|
|
|
|
body->ticket_id = (mTicketId);
|
|
|
|
body->device_id = (mDeviceId);
|
2018-07-04 05:01:12 +00:00
|
|
|
memcpy(body->rights_id, mRightsId, ticket::kRightsIdSize);
|
2018-06-06 12:38:42 +00:00
|
|
|
body->account_id = (mAccountId);
|
|
|
|
body->sect_total_size = (mSectTotalSize);
|
|
|
|
body->sect_header_offset = (mSectHeaderOffset);
|
|
|
|
body->sect_num = (mSectNum);
|
|
|
|
body->sect_entry_size = (mSectEntrySize);
|
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
void nn::es::TicketBody_V2::fromBytes(const byte_t * bytes, size_t len)
|
2018-06-06 12:38:42 +00:00
|
|
|
{
|
|
|
|
if (len < sizeof(sTicketBody_v2))
|
|
|
|
{
|
|
|
|
throw fnd::Exception(kModuleName, "Header size too small");
|
|
|
|
}
|
|
|
|
|
|
|
|
clear();
|
|
|
|
|
2018-06-24 04:46:11 +00:00
|
|
|
mRawBinary.alloc(sizeof(sTicketBody_v2));
|
|
|
|
memcpy(mRawBinary.data(), bytes, mRawBinary.size());
|
|
|
|
sTicketBody_v2* body = (sTicketBody_v2*)mRawBinary.data();
|
2018-06-06 12:38:42 +00:00
|
|
|
|
|
|
|
if (body->format_version != ticket::kFormatVersion)
|
|
|
|
{
|
|
|
|
throw fnd::Exception(kModuleName, "Unsupported format version");
|
|
|
|
}
|
|
|
|
|
2018-07-29 11:51:15 +00:00
|
|
|
mIssuer = std::string(body->issuer, _MIN(strlen(body->issuer), ticket::kIssuerSize));
|
2018-06-06 12:38:42 +00:00
|
|
|
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;
|
2018-07-04 05:35:35 +00:00
|
|
|
mCommonKeyId = body->common_key_id;
|
2018-07-04 06:00:45 +00:00
|
|
|
for (size_t i = 0; i < mPropertyFlags.size(); i++)
|
|
|
|
{
|
|
|
|
if (_HAS_BIT(body->property_mask, i))
|
|
|
|
mPropertyFlags.addElement((ticket::PropertyMaskFlags)i);
|
|
|
|
}
|
2018-06-06 12:38:42 +00:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
const fnd::Vec<byte_t>& nn::es::TicketBody_V2::getBytes() const
|
2018-06-24 04:46:11 +00:00
|
|
|
{
|
|
|
|
return mRawBinary;
|
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
void nn::es::TicketBody_V2::clear()
|
2018-06-06 12:38:42 +00:00
|
|
|
{
|
2018-06-24 04:46:11 +00:00
|
|
|
mRawBinary.clear();
|
2018-06-06 12:38:42 +00:00
|
|
|
mIssuer.clear();
|
|
|
|
memset(mEncTitleKey, 0, ticket::kEncTitleKeySize);
|
|
|
|
mEncType = ticket::AES128_CBC;
|
|
|
|
mTicketVersion = 0;
|
|
|
|
mLicenseType = ticket::LICENSE_PERMANENT;
|
2018-07-04 05:35:35 +00:00
|
|
|
mCommonKeyId = 0;
|
2018-07-04 06:00:45 +00:00
|
|
|
mPropertyFlags.clear();
|
2018-06-06 12:38:42 +00:00
|
|
|
memset(mReservedRegion, 0, ticket::kReservedRegionSize);
|
|
|
|
mTicketId = 0;
|
|
|
|
mDeviceId = 0;
|
|
|
|
memset(mRightsId, 0, ticket::kRightsIdSize);
|
|
|
|
mAccountId = 0;
|
|
|
|
mSectTotalSize = 0;
|
|
|
|
mSectHeaderOffset = 0;
|
|
|
|
mSectNum = 0;
|
|
|
|
mSectEntrySize = 0;
|
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
const std::string & nn::es::TicketBody_V2::getIssuer() const
|
2018-06-06 12:38:42 +00:00
|
|
|
{
|
|
|
|
return mIssuer;
|
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
void nn::es::TicketBody_V2::setIssuer(const std::string & issuer)
|
2018-06-06 12:38:42 +00:00
|
|
|
{
|
|
|
|
if (issuer.length() > ticket::kIssuerSize)
|
|
|
|
{
|
|
|
|
throw fnd::Exception(kModuleName, "Issuer is too long");
|
|
|
|
}
|
|
|
|
|
|
|
|
mIssuer = issuer;
|
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
const byte_t * nn::es::TicketBody_V2::getEncTitleKey() const
|
2018-06-06 12:38:42 +00:00
|
|
|
{
|
|
|
|
return mEncTitleKey;
|
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
void nn::es::TicketBody_V2::setEncTitleKey(const byte_t * data, size_t len)
|
2018-06-06 12:38:42 +00:00
|
|
|
{
|
|
|
|
memset(mEncTitleKey, 0, ticket::kEncTitleKeySize);
|
2018-06-24 15:01:16 +00:00
|
|
|
memcpy(mEncTitleKey, data, _MIN(len, ticket::kEncTitleKeySize));
|
2018-06-06 12:38:42 +00:00
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
nn::es::ticket::TitleKeyEncType nn::es::TicketBody_V2::getTitleKeyEncType() const
|
2018-06-06 12:38:42 +00:00
|
|
|
{
|
|
|
|
return mEncType;
|
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
void nn::es::TicketBody_V2::setTitleKeyEncType(ticket::TitleKeyEncType type)
|
2018-06-06 12:38:42 +00:00
|
|
|
{
|
|
|
|
mEncType = type;
|
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
uint16_t nn::es::TicketBody_V2::getTicketVersion() const
|
2018-06-06 12:38:42 +00:00
|
|
|
{
|
|
|
|
return mTicketVersion;
|
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
void nn::es::TicketBody_V2::setTicketVersion(uint16_t version)
|
2018-06-06 12:38:42 +00:00
|
|
|
{
|
|
|
|
mTicketVersion = version;
|
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
nn::es::ticket::LicenseType nn::es::TicketBody_V2::getLicenseType() const
|
2018-06-06 12:38:42 +00:00
|
|
|
{
|
|
|
|
return mLicenseType;
|
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
void nn::es::TicketBody_V2::setLicenseType(ticket::LicenseType type)
|
2018-06-06 12:38:42 +00:00
|
|
|
{
|
|
|
|
mLicenseType = type;
|
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
byte_t nn::es::TicketBody_V2::getCommonKeyId() const
|
2018-06-06 12:38:42 +00:00
|
|
|
{
|
|
|
|
return mCommonKeyId;
|
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
void nn::es::TicketBody_V2::setCommonKeyId(byte_t id)
|
2018-06-06 12:38:42 +00:00
|
|
|
{
|
|
|
|
mCommonKeyId = id;
|
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
const fnd::List<nn::es::ticket::PropertyMaskFlags>& nn::es::TicketBody_V2::getPropertyFlags() const
|
2018-06-06 12:38:42 +00:00
|
|
|
{
|
2018-07-04 06:00:45 +00:00
|
|
|
return mPropertyFlags;
|
2018-06-06 12:38:42 +00:00
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
void nn::es::TicketBody_V2::setPropertyFlags(const fnd::List<nn::es::ticket::PropertyMaskFlags>& flags)
|
2018-06-06 12:38:42 +00:00
|
|
|
{
|
2018-07-04 06:00:45 +00:00
|
|
|
mPropertyFlags = flags;
|
2018-06-06 12:38:42 +00:00
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
const byte_t * nn::es::TicketBody_V2::getReservedRegion() const
|
2018-06-06 12:38:42 +00:00
|
|
|
{
|
|
|
|
return mReservedRegion;
|
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
void nn::es::TicketBody_V2::setReservedRegion(const byte_t * data, size_t len)
|
2018-06-06 12:38:42 +00:00
|
|
|
{
|
|
|
|
memset(mReservedRegion, 0, ticket::kReservedRegionSize);
|
2018-06-24 15:01:16 +00:00
|
|
|
memcpy(mReservedRegion, data, _MIN(len, ticket::kReservedRegionSize));
|
2018-06-06 12:38:42 +00:00
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
uint64_t nn::es::TicketBody_V2::getTicketId() const
|
2018-06-06 12:38:42 +00:00
|
|
|
{
|
|
|
|
return mTicketId;
|
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
void nn::es::TicketBody_V2::setTicketId(uint64_t id)
|
2018-06-06 12:38:42 +00:00
|
|
|
{
|
|
|
|
mTicketId = id;
|
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
uint64_t nn::es::TicketBody_V2::getDeviceId() const
|
2018-06-06 12:38:42 +00:00
|
|
|
{
|
|
|
|
return mDeviceId;
|
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
void nn::es::TicketBody_V2::setDeviceId(uint64_t id)
|
2018-06-06 12:38:42 +00:00
|
|
|
{
|
|
|
|
mDeviceId = id;
|
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
const byte_t * nn::es::TicketBody_V2::getRightsId() const
|
2018-06-06 12:38:42 +00:00
|
|
|
{
|
|
|
|
return mRightsId;
|
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
void nn::es::TicketBody_V2::setRightsId(const byte_t * id)
|
2018-06-06 12:38:42 +00:00
|
|
|
{
|
|
|
|
memcpy(mRightsId, id, ticket::kRightsIdSize);
|
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
uint32_t nn::es::TicketBody_V2::getAccountId() const
|
2018-06-06 12:38:42 +00:00
|
|
|
{
|
|
|
|
return mAccountId;
|
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
void nn::es::TicketBody_V2::setAccountId(uint32_t id)
|
2018-06-06 12:38:42 +00:00
|
|
|
{
|
|
|
|
mAccountId = id;
|
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
uint32_t nn::es::TicketBody_V2::getSectionTotalSize() const
|
2018-06-06 12:38:42 +00:00
|
|
|
{
|
|
|
|
return mSectTotalSize;
|
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
void nn::es::TicketBody_V2::setSectionTotalSize(uint32_t size)
|
2018-06-06 12:38:42 +00:00
|
|
|
{
|
|
|
|
mSectTotalSize = size;
|
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
uint32_t nn::es::TicketBody_V2::getSectionHeaderOffset() const
|
2018-06-06 12:38:42 +00:00
|
|
|
{
|
|
|
|
return mSectHeaderOffset;
|
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
void nn::es::TicketBody_V2::setSectionHeaderOffset(uint32_t offset)
|
2018-06-06 12:38:42 +00:00
|
|
|
{
|
|
|
|
mSectHeaderOffset = offset;
|
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
uint16_t nn::es::TicketBody_V2::getSectionNum() const
|
2018-06-06 12:38:42 +00:00
|
|
|
{
|
|
|
|
return mSectNum;
|
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
void nn::es::TicketBody_V2::setSectionNum(uint16_t num)
|
2018-06-06 12:38:42 +00:00
|
|
|
{
|
|
|
|
mSectNum = num;
|
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
uint16_t nn::es::TicketBody_V2::getSectionEntrySize() const
|
2018-06-06 12:38:42 +00:00
|
|
|
{
|
|
|
|
return mSectEntrySize;
|
|
|
|
}
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
void nn::es::TicketBody_V2::setSectionEntrySize(uint16_t size)
|
2018-06-06 12:38:42 +00:00
|
|
|
{
|
|
|
|
mSectEntrySize = size;
|
2018-06-23 03:31:59 +00:00
|
|
|
}
|