From 15ef72b4fe07a5b14b2f928ab85d4d257a29b381 Mon Sep 17 00:00:00 2001 From: jakcron Date: Wed, 6 Jun 2018 20:38:42 +0800 Subject: [PATCH 01/10] [libes] Initial commit. --- lib/libes/include/es/ETicketBody_V2.h | 171 -------- .../include/es/ETicketContentRecord_V1.h | 47 --- .../include/es/ETicketSectionHeader_V2.h | 85 ---- lib/libes/include/es/SectionHeader_V2.h | 66 ++++ lib/libes/include/es/TicketBinary.h | 29 ++ lib/libes/include/es/TicketBody_V2.h | 118 ++++++ lib/libes/include/es/cert.h | 50 +++ lib/libes/include/es/sign.h | 43 ++ lib/libes/include/es/ticket.h | 108 ++++++ lib/libes/source/ETicketBody_V2.cpp | 366 ------------------ lib/libes/source/ETicketContentRecord_V1.cpp | 6 - ...tionHeader_V2.cpp => SectionHeader_V2.cpp} | 52 +-- lib/libes/source/TicketBody_V2.cpp | 366 ++++++++++++++++++ 13 files changed, 806 insertions(+), 701 deletions(-) delete mode 100644 lib/libes/include/es/ETicketBody_V2.h delete mode 100644 lib/libes/include/es/ETicketContentRecord_V1.h delete mode 100644 lib/libes/include/es/ETicketSectionHeader_V2.h create mode 100644 lib/libes/include/es/SectionHeader_V2.h create mode 100644 lib/libes/include/es/TicketBinary.h create mode 100644 lib/libes/include/es/TicketBody_V2.h create mode 100644 lib/libes/include/es/cert.h create mode 100644 lib/libes/include/es/sign.h create mode 100644 lib/libes/include/es/ticket.h delete mode 100644 lib/libes/source/ETicketBody_V2.cpp delete mode 100644 lib/libes/source/ETicketContentRecord_V1.cpp rename lib/libes/source/{ETicketSectionHeader_V2.cpp => SectionHeader_V2.cpp} (52%) create mode 100644 lib/libes/source/TicketBody_V2.cpp diff --git a/lib/libes/include/es/ETicketBody_V2.h b/lib/libes/include/es/ETicketBody_V2.h deleted file mode 100644 index 475a2f6..0000000 --- a/lib/libes/include/es/ETicketBody_V2.h +++ /dev/null @@ -1,171 +0,0 @@ -#pragma once -#include -#include -#include -#include - -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); - }; -} - - diff --git a/lib/libes/include/es/ETicketContentRecord_V1.h b/lib/libes/include/es/ETicketContentRecord_V1.h deleted file mode 100644 index 8f7de25..0000000 --- a/lib/libes/include/es/ETicketContentRecord_V1.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once -#include -#include -#include -#include - -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) - }; -} \ No newline at end of file diff --git a/lib/libes/include/es/ETicketSectionHeader_V2.h b/lib/libes/include/es/ETicketSectionHeader_V2.h deleted file mode 100644 index ba4d28d..0000000 --- a/lib/libes/include/es/ETicketSectionHeader_V2.h +++ /dev/null @@ -1,85 +0,0 @@ -#pragma once -#include -#include -#include - -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); - - }; - -} diff --git a/lib/libes/include/es/SectionHeader_V2.h b/lib/libes/include/es/SectionHeader_V2.h new file mode 100644 index 0000000..a69c7e1 --- /dev/null +++ b/lib/libes/include/es/SectionHeader_V2.h @@ -0,0 +1,66 @@ +#pragma once +#include +#include +#include +#include + +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); + + }; + +} diff --git a/lib/libes/include/es/TicketBinary.h b/lib/libes/include/es/TicketBinary.h new file mode 100644 index 0000000..a762336 --- /dev/null +++ b/lib/libes/include/es/TicketBinary.h @@ -0,0 +1,29 @@ +#pragma once +#include +#include +#include +#include + +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: + }; +} \ No newline at end of file diff --git a/lib/libes/include/es/TicketBody_V2.h b/lib/libes/include/es/TicketBody_V2.h new file mode 100644 index 0000000..b0310a6 --- /dev/null +++ b/lib/libes/include/es/TicketBody_V2.h @@ -0,0 +1,118 @@ +#pragma once +#include +#include +#include +#include + +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); + }; +} + + diff --git a/lib/libes/include/es/cert.h b/lib/libes/include/es/cert.h new file mode 100644 index 0000000..af261fc --- /dev/null +++ b/lib/libes/include/es/cert.h @@ -0,0 +1,50 @@ +#pragma once +#include +#include +#include +#include + +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) +} \ No newline at end of file diff --git a/lib/libes/include/es/sign.h b/lib/libes/include/es/sign.h new file mode 100644 index 0000000..c41182e --- /dev/null +++ b/lib/libes/include/es/sign.h @@ -0,0 +1,43 @@ +#pragma once +#include +#include +#include +#include + +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) +} \ No newline at end of file diff --git a/lib/libes/include/es/ticket.h b/lib/libes/include/es/ticket.h new file mode 100644 index 0000000..689ecce --- /dev/null +++ b/lib/libes/include/es/ticket.h @@ -0,0 +1,108 @@ +#pragma once +#include +#include +#include + +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) +} \ No newline at end of file diff --git a/lib/libes/source/ETicketBody_V2.cpp b/lib/libes/source/ETicketBody_V2.cpp deleted file mode 100644 index 8efb1be..0000000 --- a/lib/libes/source/ETicketBody_V2.cpp +++ /dev/null @@ -1,366 +0,0 @@ -#include - - - -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; -} diff --git a/lib/libes/source/ETicketContentRecord_V1.cpp b/lib/libes/source/ETicketContentRecord_V1.cpp deleted file mode 100644 index acc97fc..0000000 --- a/lib/libes/source/ETicketContentRecord_V1.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include - - - -es::ETicketContentRecord_V1::ETicketContentRecord_V1() -{} \ No newline at end of file diff --git a/lib/libes/source/ETicketSectionHeader_V2.cpp b/lib/libes/source/SectionHeader_V2.cpp similarity index 52% rename from lib/libes/source/ETicketSectionHeader_V2.cpp rename to lib/libes/source/SectionHeader_V2.cpp index d11d211..4470e3f 100644 --- a/lib/libes/source/ETicketSectionHeader_V2.cpp +++ b/lib/libes/source/SectionHeader_V2.cpp @@ -1,46 +1,46 @@ -#include +#include -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; } diff --git a/lib/libes/source/TicketBody_V2.cpp b/lib/libes/source/TicketBody_V2.cpp new file mode 100644 index 0000000..73b73c0 --- /dev/null +++ b/lib/libes/source/TicketBody_V2.cpp @@ -0,0 +1,366 @@ +#include + + + +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; +} From adfbc559226ac17e9296eeebe71df2c3ba1e7549 Mon Sep 17 00:00:00 2001 From: jakcron Date: Fri, 22 Jun 2018 20:54:35 +0800 Subject: [PATCH 02/10] [es] Add es::SignatureBlock --- lib/libes/include/es/SignatureBlock.h | 53 +++++++ lib/libes/source/SignatureBlock.cpp | 197 ++++++++++++++++++++++++++ 2 files changed, 250 insertions(+) create mode 100644 lib/libes/include/es/SignatureBlock.h create mode 100644 lib/libes/source/SignatureBlock.cpp diff --git a/lib/libes/include/es/SignatureBlock.h b/lib/libes/include/es/SignatureBlock.h new file mode 100644 index 0000000..86ab6c8 --- /dev/null +++ b/lib/libes/include/es/SignatureBlock.h @@ -0,0 +1,53 @@ +#pragma once +#include +#include +#include +#include + +namespace es +{ + class SignatureBlock + : public fnd::ISerialiseableBinary + { + public: + SignatureBlock(); + SignatureBlock(const SignatureBlock& other); + + void operator=(const SignatureBlock& other); + bool operator==(const SignatureBlock& other) const; + bool operator!=(const SignatureBlock& other) const; + + void importBinary(byte_t* src, size_t size); + void exportBinary(); + + const byte_t* getBytes() const; + size_t getSize() const; + + void clear(); + + es::sign::SignType getSignType() const; + void setSignType(es::sign::SignType type); + + bool isLittleEndian() const; + void setLittleEndian(bool isLE); + + const fnd::MemoryBlob& getSignature() const; + void setSignature(const fnd::MemoryBlob& signature); + + + private: + const std::string kModuleName = "SIGNATURE_BLOCK"; + + // raw binary + fnd::MemoryBlob mBinaryBlob; + + // variables + es::sign::SignType mSignType; + bool mIsLittleEndian; + fnd::MemoryBlob mSignature; + + // helpers + bool isEqual(const SignatureBlock& other) const; + void copyFrom(const SignatureBlock& other); + }; +} \ No newline at end of file diff --git a/lib/libes/source/SignatureBlock.cpp b/lib/libes/source/SignatureBlock.cpp new file mode 100644 index 0000000..d8d6fba --- /dev/null +++ b/lib/libes/source/SignatureBlock.cpp @@ -0,0 +1,197 @@ +#include + +es::SignatureBlock::SignatureBlock() +{ + clear(); +} + +es::SignatureBlock::SignatureBlock(const SignatureBlock& other) +{ + copyFrom(other); +} + +void es::SignatureBlock::operator=(const SignatureBlock& other) +{ + copyFrom(other); +} + +bool es::SignatureBlock::operator==(const SignatureBlock& other) const +{ + return isEqual(other); +} + +bool es::SignatureBlock::operator!=(const SignatureBlock& other) const +{ + return !(*this == other); +} + +void es::SignatureBlock::importBinary(byte_t* src, size_t size) +{ + clear(); + + size_t totalSize = 0; + size_t sigSize = 0; + uint32_t signType = 0; + + // try Big Endian sign type + signType = ((be_uint32_t*)src)->get(); + switch (signType) + { + case (sign::SIGN_RSA4096_SHA1): + case (sign::SIGN_RSA4096_SHA256): + totalSize = sizeof(sRsa4096SignBlock); + sigSize = crypto::rsa::kRsa4096Size; + break; + case (sign::SIGN_RSA2048_SHA1): + case (sign::SIGN_RSA2048_SHA256): + totalSize = sizeof(sRsa2048SignBlock); + sigSize = crypto::rsa::kRsa2048Size; + break; + case (sign::SIGN_ECDSA240_SHA1): + case (sign::SIGN_ECDSA240_SHA256): + totalSize = sizeof(sEcdsa240SignBlock); + sigSize = sign::kEcdsaSigSize; + break; + } + + // try Big Endian sign type + if (totalSize == 0) + { + signType = ((le_uint32_t*)src)->get(); + switch (signType) + { + case (sign::SIGN_RSA4096_SHA1): + case (sign::SIGN_RSA4096_SHA256): + totalSize = sizeof(sRsa4096SignBlock); + sigSize = crypto::rsa::kRsa4096Size; + break; + case (sign::SIGN_RSA2048_SHA1): + case (sign::SIGN_RSA2048_SHA256): + totalSize = sizeof(sRsa2048SignBlock); + sigSize = crypto::rsa::kRsa2048Size; + break; + case (sign::SIGN_ECDSA240_SHA1): + case (sign::SIGN_ECDSA240_SHA256): + totalSize = sizeof(sEcdsa240SignBlock); + sigSize = sign::kEcdsaSigSize; + break; + default: + throw fnd::Exception(kModuleName, "Unknown signature type"); + } + + mIsLittleEndian = true; + } + + if (totalSize > size) + { + throw fnd::Exception(kModuleName, "Certificate too small"); + } + + mBinaryBlob.alloc(totalSize); + memcpy(mBinaryBlob.getBytes(), src, totalSize); + + mSignType = (sign::SignType)signType; + mSignature.alloc(sigSize); + memcpy(mSignature.getBytes(), mBinaryBlob.getBytes() + 4, sigSize); +} + +void es::SignatureBlock::exportBinary() +{ + size_t totalSize = 0; + size_t sigSize = 0; + + switch (mSignType) + { + case (sign::SIGN_RSA4096_SHA1): + case (sign::SIGN_RSA4096_SHA256): + totalSize = sizeof(sRsa4096SignBlock); + sigSize = crypto::rsa::kRsa4096Size; + break; + case (sign::SIGN_RSA2048_SHA1): + case (sign::SIGN_RSA2048_SHA256): + totalSize = sizeof(sRsa2048SignBlock); + sigSize = crypto::rsa::kRsa2048Size; + break; + case (sign::SIGN_ECDSA240_SHA1): + case (sign::SIGN_ECDSA240_SHA256): + totalSize = sizeof(sEcdsa240SignBlock); + sigSize = sign::kEcdsaSigSize; + break; + default: + throw fnd::Exception(kModuleName, "Unknown signature type"); + } + + if (mSignature.getSize() != sigSize) + throw fnd::Exception(kModuleName, "Signature size is incorrect"); + + // commit to binary + mBinaryBlob.alloc(totalSize); + if (mIsLittleEndian) + *(le_uint32_t*)(mBinaryBlob.getBytes()) = mSignType; + else + *(be_uint32_t*)(mBinaryBlob.getBytes()) = mSignType; + memcpy(mBinaryBlob.getBytes() + 4, mSignature.getBytes(), sigSize); +} + +const byte_t* es::SignatureBlock::getBytes() const +{ + return mBinaryBlob.getBytes(); +} + +size_t es::SignatureBlock::getSize() const +{ + return mBinaryBlob.getSize(); +} + +void es::SignatureBlock::clear() +{ + mBinaryBlob.clear(); + mSignType = sign::SIGN_RSA4096_SHA1; + mIsLittleEndian = false; + mSignature.clear(); +} + +es::sign::SignType es::SignatureBlock::getSignType() const +{ + return mSignType; +} + +void es::SignatureBlock::setSignType(es::sign::SignType type) +{ + mSignType = type; +} + +bool es::SignatureBlock::isLittleEndian() const +{ + return mIsLittleEndian; +} + +void es::SignatureBlock::setLittleEndian(bool isLE) +{ + mIsLittleEndian = isLE; +} + +const fnd::MemoryBlob& es::SignatureBlock::getSignature() const +{ + return mSignature; +} + +void es::SignatureBlock::setSignature(const fnd::MemoryBlob& signature) +{ + mSignature = signature; +} + +bool es::SignatureBlock::isEqual(const SignatureBlock& other) const +{ + return (mSignType == other.mSignType) \ + && (mIsLittleEndian == other.mIsLittleEndian) \ + && (mSignature == other.mSignature); +} + +void es::SignatureBlock::copyFrom(const SignatureBlock& other) +{ + mBinaryBlob = other.mBinaryBlob; + mSignType = other.mSignType; + mIsLittleEndian = other.mIsLittleEndian; + mSignature = other.mSignature; +} From 8314a948f74bb2b68cc4fb9456ff7536e01864b5 Mon Sep 17 00:00:00 2001 From: jakcron Date: Fri, 22 Jun 2018 21:16:36 +0800 Subject: [PATCH 03/10] [crypto] Add header for ECDSA-240 defines. --- lib/libcrypto/include/crypto/ecdsa.h | 62 ++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 lib/libcrypto/include/crypto/ecdsa.h diff --git a/lib/libcrypto/include/crypto/ecdsa.h b/lib/libcrypto/include/crypto/ecdsa.h new file mode 100644 index 0000000..fdf1ff6 --- /dev/null +++ b/lib/libcrypto/include/crypto/ecdsa.h @@ -0,0 +1,62 @@ +#pragma once +#include +#include +#include + +namespace crypto +{ + namespace ecdsa + { + const size_t kEcdsa240Size = 0x1E; + + enum EcdsaType + { + ECDSA_240, + }; + +#pragma pack (push, 1) + struct sEcdsa240Point + { + uint8_t r[kEcdsa240Size]; + uint8_t s[kEcdsa240Size]; + + void operator=(const sEcdsa240Point& other) + { + memcpy(this->r, r, kEcdsa240Size); + memcpy(this->s, s, kEcdsa240Size); + } + + bool operator==(const sEcdsa240Point& other) const + { + return memcmp(this->r, other.r, kEcdsa240Size) == 0 \ + && memcmp(this->s, other.s, kEcdsa240Size) == 0; + } + + bool operator!=(const sEcdsa240Point& other) const + { + return !operator==(other); + } + }; + + struct sEcdsa240PrivateKey + { + uint8_t k[kEcdsa240Size]; + + void operator=(const sEcdsa240PrivateKey& other) + { + memcpy(this->k, k, kEcdsa240Size); + } + + bool operator==(const sEcdsa240PrivateKey& other) const + { + return memcmp(this->k, other.k, kEcdsa240Size) == 0; + } + + bool operator!=(const sEcdsa240PrivateKey& other) const + { + return !operator==(other); + } + }; +#pragma pack (pop) + } +} From 20689e9cbd9469129b8a37818e61e981d35ecea3 Mon Sep 17 00:00:00 2001 From: jakcron Date: Fri, 22 Jun 2018 21:18:03 +0800 Subject: [PATCH 04/10] [crypto] Removed unneeded header. --- lib/libcrypto/include/crypto/ecdsa.h | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/libcrypto/include/crypto/ecdsa.h b/lib/libcrypto/include/crypto/ecdsa.h index fdf1ff6..70f2803 100644 --- a/lib/libcrypto/include/crypto/ecdsa.h +++ b/lib/libcrypto/include/crypto/ecdsa.h @@ -1,7 +1,6 @@ #pragma once #include #include -#include namespace crypto { From c2b8223413607d2e31b087ea29d07375348ade92 Mon Sep 17 00:00:00 2001 From: jakcron Date: Fri, 22 Jun 2018 21:30:50 +0800 Subject: [PATCH 05/10] [es] Add a constant to sign.h --- lib/libes/include/es/sign.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/libes/include/es/sign.h b/lib/libes/include/es/sign.h index c41182e..61d352f 100644 --- a/lib/libes/include/es/sign.h +++ b/lib/libes/include/es/sign.h @@ -3,6 +3,7 @@ #include #include #include +#include namespace es { @@ -17,6 +18,8 @@ namespace es SIGN_RSA2048_SHA256, SIGN_ECDSA240_SHA256, }; + + static const size_t kEcdsaSigSize = 0x3C; } #pragma pack(push,1) struct sRsa4096SignBlock @@ -36,7 +39,7 @@ namespace es struct sEcdsa240SignBlock { be_uint32_t sign_type; - byte_t signature[0x3C]; + byte_t signature[sign::kEcdsaSigSize]; byte_t padding[0x40]; }; #pragma pack(pop) From 3089069c8b10baf5ad7a33886206f608f3fdeb35 Mon Sep 17 00:00:00 2001 From: jakcron Date: Fri, 22 Jun 2018 21:57:55 +0800 Subject: [PATCH 06/10] [es] Add es::CertificateBody --- lib/libes/include/es/CertificateBody.h | 69 +++++++ lib/libes/include/es/cert.h | 11 +- lib/libes/source/CertificateBody.cpp | 269 +++++++++++++++++++++++++ 3 files changed, 344 insertions(+), 5 deletions(-) create mode 100644 lib/libes/include/es/CertificateBody.h create mode 100644 lib/libes/source/CertificateBody.cpp diff --git a/lib/libes/include/es/CertificateBody.h b/lib/libes/include/es/CertificateBody.h new file mode 100644 index 0000000..2dd0cdb --- /dev/null +++ b/lib/libes/include/es/CertificateBody.h @@ -0,0 +1,69 @@ +#pragma once +#include +#include +#include +#include + +namespace es +{ + class CertificateBody + : public fnd::ISerialiseableBinary + { + public: + CertificateBody(); + CertificateBody(const CertificateBody& other); + + void operator=(const CertificateBody& other); + bool operator==(const CertificateBody& other) const; + bool operator!=(const CertificateBody& other) const; + + void importBinary(byte_t* src, size_t size); + void exportBinary(); + + const byte_t* getBytes() const; + size_t getSize() const; + + void clear(); + + const std::string& getIssuer() const; + void setIssuer(const std::string& issuer); + + es::cert::PublicKeyType getPublicKeyType() const; + void setPublicKeyType(cert::PublicKeyType type); + + const std::string& getSubject() const; + void setSubject(const std::string& subject); + + uint32_t getCertId() const; + void setCertId(uint32_t id); + + const crypto::rsa::sRsa4096Key& getRsa4098PublicKey() const; + void setRsa4098PublicKey(const crypto::rsa::sRsa4096Key& key); + + const crypto::rsa::sRsa2048Key& getRsa2048PublicKey() const; + void setRsa2048PublicKey(const crypto::rsa::sRsa2048Key& key); + + const crypto::ecdsa::sEcdsa240Point& getEcdsa240PublicKey() const; + void setEcdsa240PublicKey(const crypto::ecdsa::sEcdsa240Point& key); + + private: + const std::string kModuleName = "CERTIFICATE_BODY"; + + // raw binary + fnd::MemoryBlob mBinaryBlob; + + // variables + std::string mIssuer; + std::string mSubject; + uint32_t mCertId; + cert::PublicKeyType mPublicKeyType; + + crypto::rsa::sRsa4096Key mRsa4096PublicKey; + crypto::rsa::sRsa2048Key mRsa2048PublicKey; + crypto::ecdsa::sEcdsa240Point mEcdsa240PublicKey; + + // helpers + bool isEqual(const CertificateBody& other) const; + void copyFrom(const CertificateBody& other); + }; +} \ No newline at end of file diff --git a/lib/libes/include/es/cert.h b/lib/libes/include/es/cert.h index af261fc..ab4ec0a 100644 --- a/lib/libes/include/es/cert.h +++ b/lib/libes/include/es/cert.h @@ -3,6 +3,7 @@ #include #include #include +#include namespace es { @@ -19,31 +20,31 @@ namespace es static const size_t kSubjectSize = 0x40; } #pragma pack(push,1) - struct sCertificateBody + struct sCertificateHeader { 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 public_exponent[crypto::rsa::kRsaPublicExponentSize]; byte_t padding[0x34]; }; struct sRsa2048PublicKeyBlock { byte_t modulus[crypto::rsa::kRsa2048Size]; - byte_t public_exponent[0x4]; + byte_t public_exponent[crypto::rsa::kRsaPublicExponentSize]; byte_t padding[0x34]; }; struct sEcdsa240PublicKeyBlock { - byte_t public_key[0x3C]; + crypto::ecdsa::sEcdsa240Point public_key; byte_t padding[0x3C]; }; #pragma pack(pop) diff --git a/lib/libes/source/CertificateBody.cpp b/lib/libes/source/CertificateBody.cpp new file mode 100644 index 0000000..627720b --- /dev/null +++ b/lib/libes/source/CertificateBody.cpp @@ -0,0 +1,269 @@ +#include + +es::CertificateBody::CertificateBody() +{ + clear(); +} + +es::CertificateBody::CertificateBody(const CertificateBody& other) +{ + copyFrom(other); +} + +void es::CertificateBody::operator=(const CertificateBody& other) +{ + copyFrom(other); +} + +bool es::CertificateBody::operator==(const CertificateBody& other) const +{ + return isEqual(other); +} + +bool es::CertificateBody::operator!=(const CertificateBody& other) const +{ + return !(*this == other); +} + +void es::CertificateBody::importBinary(byte_t* src, size_t size) +{ + clear(); + + // check minimum size + if (size < sizeof(sCertificateHeader)) + { + throw fnd::Exception(kModuleName, "Certificate too small"); + } + + const sCertificateHeader* hdr = (const sCertificateHeader*)src; + + // get public key size + size_t pubkeySize = 0; + switch (hdr->key_type.get()) + { + case (cert::RSA4096): + pubkeySize = sizeof(sRsa4096PublicKeyBlock); + break; + case (cert::RSA2048): + pubkeySize = sizeof(sRsa2048PublicKeyBlock); + break; + case (cert::ECDSA240): + pubkeySize = sizeof(sEcdsa240PublicKeyBlock); + break; + default: + throw fnd::Exception(kModuleName, "Unknown public key type"); + } + + // check total size + if (size < (sizeof(sCertificateHeader) + pubkeySize)) + { + throw fnd::Exception(kModuleName, "Certificate too small"); + } + + // save raw binary + mBinaryBlob.alloc((sizeof(sCertificateHeader) + pubkeySize)); + memcpy(mBinaryBlob.getBytes(), src, mBinaryBlob.getSize()); + + // save hdr variables + hdr = (const sCertificateHeader*)mBinaryBlob.getBytes(); + + if (hdr->issuer[0] != 0) + mIssuer = std::string(hdr->issuer, cert::kIssuerSize); + mPublicKeyType = (cert::PublicKeyType)hdr->key_type.get(); + if (hdr->subject[0] != 0) + mSubject = std::string(hdr->subject, cert::kSubjectSize); + mCertId = hdr->cert_id.get(); + + // save public key + if (mPublicKeyType == cert::RSA4096) + { + const sRsa4096PublicKeyBlock* pubkey = (const sRsa4096PublicKeyBlock*)(mBinaryBlob.getBytes() + sizeof(sCertificateHeader)); + memcpy(mRsa4096PublicKey.modulus, pubkey->modulus, sizeof(mRsa4096PublicKey.modulus)); + memcpy(mRsa4096PublicKey.public_exponent, pubkey->public_exponent, sizeof(mRsa4096PublicKey.public_exponent)); + } + else if (mPublicKeyType == cert::RSA2048) + { + const sRsa2048PublicKeyBlock* pubkey = (const sRsa2048PublicKeyBlock*)(mBinaryBlob.getBytes() + sizeof(sCertificateHeader)); + memcpy(mRsa2048PublicKey.modulus, pubkey->modulus, sizeof(mRsa2048PublicKey.modulus)); + memcpy(mRsa2048PublicKey.public_exponent, pubkey->public_exponent, sizeof(mRsa2048PublicKey.public_exponent)); + } + else if (mPublicKeyType == cert::ECDSA240) + { + const sEcdsa240PublicKeyBlock* pubkey = (const sEcdsa240PublicKeyBlock*)(mBinaryBlob.getBytes() + sizeof(sCertificateHeader)); + mEcdsa240PublicKey = pubkey->public_key; + } +} + +void es::CertificateBody::exportBinary() +{ + // get public key size + size_t pubkeySize = 0; + switch (mPublicKeyType) + { + case (cert::RSA4096): + pubkeySize = sizeof(sRsa4096PublicKeyBlock); + break; + case (cert::RSA2048): + pubkeySize = sizeof(sRsa2048PublicKeyBlock); + break; + case (cert::ECDSA240): + pubkeySize = sizeof(sEcdsa240PublicKeyBlock); + break; + default: + throw fnd::Exception(kModuleName, "Unknown public key type"); + } + + mBinaryBlob.alloc(sizeof(sCertificateHeader) + pubkeySize); + sCertificateHeader* hdr = (sCertificateHeader*)mBinaryBlob.getBytes(); + + // copy header vars + strncpy(hdr->issuer, mIssuer.c_str(), cert::kIssuerSize); + hdr->key_type = mPublicKeyType; + strncpy(hdr->subject, mSubject.c_str(), cert::kSubjectSize); + hdr->cert_id = mCertId; + + // copy public key + if (mPublicKeyType == cert::RSA4096) + { + sRsa4096PublicKeyBlock* pubkey = (sRsa4096PublicKeyBlock*)(mBinaryBlob.getBytes() + sizeof(sCertificateHeader)); + memcpy(pubkey->modulus, mRsa4096PublicKey.modulus, sizeof(mRsa4096PublicKey.modulus)); + memcpy(pubkey->public_exponent, mRsa4096PublicKey.public_exponent, sizeof(mRsa4096PublicKey.public_exponent)); + } + else if (mPublicKeyType == cert::RSA2048) + { + sRsa2048PublicKeyBlock* pubkey = (sRsa2048PublicKeyBlock*)(mBinaryBlob.getBytes() + sizeof(sCertificateHeader)); + memcpy(pubkey->modulus, mRsa2048PublicKey.modulus, sizeof(mRsa2048PublicKey.modulus)); + memcpy(pubkey->public_exponent, mRsa2048PublicKey.public_exponent, sizeof(mRsa2048PublicKey.public_exponent)); + } + else if (mPublicKeyType == cert::ECDSA240) + { + sEcdsa240PublicKeyBlock* pubkey = (sEcdsa240PublicKeyBlock*)(mBinaryBlob.getBytes() + sizeof(sCertificateHeader)); + pubkey->public_key = mEcdsa240PublicKey; + } +} + +const byte_t* es::CertificateBody::getBytes() const +{ + return mBinaryBlob.getBytes(); +} + +size_t es::CertificateBody::getSize() const +{ + return mBinaryBlob.getSize(); +} + +void es::CertificateBody::clear() +{ + mIssuer.clear(); + mSubject.clear(); + mCertId = 0; + mPublicKeyType = cert::RSA2048; + + memset(&mRsa4096PublicKey, 0, sizeof(crypto::rsa::sRsa4096Key)); + memset(&mRsa2048PublicKey, 0, sizeof(crypto::rsa::sRsa2048Key)); + memset(&mEcdsa240PublicKey, 0, sizeof(crypto::ecdsa::sEcdsa240Point)); +} + +const std::string& es::CertificateBody::getIssuer() const +{ + return mIssuer; +} + +void es::CertificateBody::setIssuer(const std::string& issuer) +{ + if (issuer.size() > cert::kIssuerSize) + { + throw fnd::Exception(kModuleName, "Issuer name too long"); + } + + mIssuer = issuer; +} + +es::cert::PublicKeyType es::CertificateBody::getPublicKeyType() const +{ + return mPublicKeyType; +} + +void es::CertificateBody::setPublicKeyType(cert::PublicKeyType type) +{ + mPublicKeyType = type; +} + +const std::string& es::CertificateBody::getSubject() const +{ + return mSubject; +} + +void es::CertificateBody::setSubject(const std::string& subject) +{ + if (subject.size() > cert::kSubjectSize) + { + throw fnd::Exception(kModuleName, "Subject name too long"); + } + + mSubject = subject; +} + +uint32_t es::CertificateBody::getCertId() const +{ + return mCertId; +} + +void es::CertificateBody::setCertId(uint32_t id) +{ + mCertId = id; +} + +const crypto::rsa::sRsa4096Key& es::CertificateBody::getRsa4098PublicKey() const +{ + return mRsa4096PublicKey; +} + +void es::CertificateBody::setRsa4098PublicKey(const crypto::rsa::sRsa4096Key& key) +{ + mRsa4096PublicKey = key; +} + +const crypto::rsa::sRsa2048Key& es::CertificateBody::getRsa2048PublicKey() const +{ + return mRsa2048PublicKey; +} + +void es::CertificateBody::setRsa2048PublicKey(const crypto::rsa::sRsa2048Key& key) +{ + mRsa2048PublicKey = key; +} + +const crypto::ecdsa::sEcdsa240Point& es::CertificateBody::getEcdsa240PublicKey() const +{ + return mEcdsa240PublicKey; +} + +void es::CertificateBody::setEcdsa240PublicKey(const crypto::ecdsa::sEcdsa240Point& key) +{ + mEcdsa240PublicKey = key; +} + +bool es::CertificateBody::isEqual(const CertificateBody& other) const +{ + return (mIssuer == other.mIssuer) \ + && (mSubject == other.mSubject) \ + && (mCertId == other.mCertId) \ + && (mPublicKeyType == other.mPublicKeyType) \ + && (mRsa4096PublicKey == other.mRsa4096PublicKey) \ + && (mRsa2048PublicKey == other.mRsa2048PublicKey) \ + && (mEcdsa240PublicKey == other.mEcdsa240PublicKey); + +} + +void es::CertificateBody::copyFrom(const CertificateBody& other) +{ + mBinaryBlob = other.mBinaryBlob; + mIssuer = other.mIssuer; + mSubject = other.mSubject; + mCertId = other.mCertId; + mPublicKeyType = other.mPublicKeyType; + mRsa4096PublicKey = other.mRsa4096PublicKey; + mRsa2048PublicKey = other.mRsa2048PublicKey; + mEcdsa240PublicKey = other.mEcdsa240PublicKey; +} From d802197887c0046e1fc7822b27944fa1d1810558 Mon Sep 17 00:00:00 2001 From: jakcron Date: Sat, 23 Jun 2018 11:23:08 +0800 Subject: [PATCH 07/10] [es] Fixed inheritance mistakes. --- lib/libes/include/es/CertificateBody.h | 2 +- lib/libes/include/es/SignatureBlock.h | 2 +- lib/libes/source/CertificateBody.cpp | 2 +- lib/libes/source/SignatureBlock.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/libes/include/es/CertificateBody.h b/lib/libes/include/es/CertificateBody.h index 2dd0cdb..37c3e48 100644 --- a/lib/libes/include/es/CertificateBody.h +++ b/lib/libes/include/es/CertificateBody.h @@ -17,7 +17,7 @@ namespace es bool operator==(const CertificateBody& other) const; bool operator!=(const CertificateBody& other) const; - void importBinary(byte_t* src, size_t size); + void importBinary(const byte_t* src, size_t size); void exportBinary(); const byte_t* getBytes() const; diff --git a/lib/libes/include/es/SignatureBlock.h b/lib/libes/include/es/SignatureBlock.h index 86ab6c8..dcd5acb 100644 --- a/lib/libes/include/es/SignatureBlock.h +++ b/lib/libes/include/es/SignatureBlock.h @@ -17,7 +17,7 @@ namespace es bool operator==(const SignatureBlock& other) const; bool operator!=(const SignatureBlock& other) const; - void importBinary(byte_t* src, size_t size); + void importBinary(const byte_t* src, size_t size); void exportBinary(); const byte_t* getBytes() const; diff --git a/lib/libes/source/CertificateBody.cpp b/lib/libes/source/CertificateBody.cpp index 627720b..6dca809 100644 --- a/lib/libes/source/CertificateBody.cpp +++ b/lib/libes/source/CertificateBody.cpp @@ -25,7 +25,7 @@ bool es::CertificateBody::operator!=(const CertificateBody& other) const return !(*this == other); } -void es::CertificateBody::importBinary(byte_t* src, size_t size) +void es::CertificateBody::importBinary(const byte_t* src, size_t size) { clear(); diff --git a/lib/libes/source/SignatureBlock.cpp b/lib/libes/source/SignatureBlock.cpp index d8d6fba..d79ba96 100644 --- a/lib/libes/source/SignatureBlock.cpp +++ b/lib/libes/source/SignatureBlock.cpp @@ -25,7 +25,7 @@ bool es::SignatureBlock::operator!=(const SignatureBlock& other) const return !(*this == other); } -void es::SignatureBlock::importBinary(byte_t* src, size_t size) +void es::SignatureBlock::importBinary(const byte_t* src, size_t size) { clear(); From 92cf66eceaebc6260a30539673772ef214d99403 Mon Sep 17 00:00:00 2001 From: jakcron Date: Sat, 23 Jun 2018 11:31:59 +0800 Subject: [PATCH 08/10] [es] Change order of methods. --- lib/libes/source/TicketBody_V2.cpp | 100 ++++++++++++++--------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/lib/libes/source/TicketBody_V2.cpp b/lib/libes/source/TicketBody_V2.cpp index 73b73c0..a9da7f2 100644 --- a/lib/libes/source/TicketBody_V2.cpp +++ b/lib/libes/source/TicketBody_V2.cpp @@ -42,56 +42,6 @@ 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)); @@ -364,3 +314,53 @@ void es::TicketBody_V2::setSectionEntrySize(uint16_t size) { mSectEntrySize = size; } + +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; + } +} \ No newline at end of file From 8f15dd693ef7d8286eecf91d66ba4e38c560a87e Mon Sep 17 00:00:00 2001 From: jakcron Date: Sat, 23 Jun 2018 11:32:12 +0800 Subject: [PATCH 09/10] [es] Remove unneeded comment. --- lib/libes/include/es/TicketBody_V2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/libes/include/es/TicketBody_V2.h b/lib/libes/include/es/TicketBody_V2.h index b0310a6..8a93dc8 100644 --- a/lib/libes/include/es/TicketBody_V2.h +++ b/lib/libes/include/es/TicketBody_V2.h @@ -92,7 +92,7 @@ namespace es // variables std::string mIssuer; byte_t mEncTitleKey[ticket::kEncTitleKeySize]; - ticket::TitleKeyEncType mEncType; // 0 = aes-cbc, 1 = rsa2048 + ticket::TitleKeyEncType mEncType; uint16_t mTicketVersion; ticket::LicenseType mLicenseType; byte_t mCommonKeyId; From 40b1dad10e304ce5c79f24ef99dc62868ecb1289 Mon Sep 17 00:00:00 2001 From: jakcron Date: Sat, 23 Jun 2018 11:32:38 +0800 Subject: [PATCH 10/10] [es] Remove es::TicketBinary Add es::SignedData --- lib/libes/include/es/SignedData.h | 113 ++++++++++++++++++++++++++++ lib/libes/include/es/TicketBinary.h | 29 ------- 2 files changed, 113 insertions(+), 29 deletions(-) create mode 100644 lib/libes/include/es/SignedData.h delete mode 100644 lib/libes/include/es/TicketBinary.h diff --git a/lib/libes/include/es/SignedData.h b/lib/libes/include/es/SignedData.h new file mode 100644 index 0000000..6f4a7e1 --- /dev/null +++ b/lib/libes/include/es/SignedData.h @@ -0,0 +1,113 @@ +#pragma once +#include +#include +#include +#include + +namespace es +{ + template + class SignedData + : public fnd::ISerialiseableBinary + { + public: + SignedData() + { + clear(); + } + SignedData(const SignedData& other) + { + copyFrom(other); + } + + void operator=(const SignedData& other) + { + copyFrom(other); + } + bool operator==(const SignedData& other) const + { + return isEqual(other); + } + bool operator!=(const SignedData& other) const + { + return !(*this == other); + } + + void importBinary(const byte_t* src, size_t size) + { + mSignature.importBinary(src, size); + mBody.importBinary(src + mSignature.getSize(), size - mSignature.getSize()); + + mBinaryBlob.alloc(mSignature.getSize() + mBody.getSize()); + memcpy(mBinaryBlob.getBytes(), src, mBinaryBlob.getSize()); + } + + void exportBinary() + { + mSignature.exportBinary(); + mBody.exportBinary(); + + mBinaryBlob.alloc(mSignature.getSize() + mBody.getSize()); + + memcpy(mBinaryBlob.getBytes(), mSignature.getBytes(), mSignature.getSize()); + memcpy(mBinaryBlob.getBytes() + mSignature.getSize(), mBody.getBytes(), mBody.getSize()); + } + + const byte_t* getBytes() const + { + return mBinaryBlob.getBytes(); + } + size_t getSize() const + { + return mBinaryBlob.getSize(); + } + + void clear() + { + mBinaryBlob.clear(); + mSignature.clear(); + mBody.clear(); + } + + const es::SignatureBlock& getSignature() const + { + return mSignature; + } + void setSignature(const SignatureBlock& signature) + { + mSignature = signature; + } + + const T& getBody() const + { + return mBody; + } + void setBody(const T& body) + { + mBody = body; + } + private: + const std::string kModuleName = "SIGNED_DATA"; + + // raw binary + fnd::MemoryBlob mBinaryBlob; + + // variables + SignatureBlock mSignature; + T mBody; + + // helpers + bool isEqual(const SignedData& other) const + { + return (mSignature == other.mSignature) \ + && (mBody == other.mBody); + } + void copyFrom(const SignedData& other) + { + mBinaryBlob = other.mBinaryBlob; + mSignature = other.mSignature; + mBody = other.mBody; + } + }; +} + diff --git a/lib/libes/include/es/TicketBinary.h b/lib/libes/include/es/TicketBinary.h deleted file mode 100644 index a762336..0000000 --- a/lib/libes/include/es/TicketBinary.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once -#include -#include -#include -#include - -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: - }; -} \ No newline at end of file