IOS/ESFormats: Add CertReader

This commit is contained in:
Léo Lam 2017-06-10 19:10:55 +02:00
parent 90280b3f84
commit e29f6e383f
2 changed files with 87 additions and 0 deletions

View File

@ -10,6 +10,7 @@
#include <cstddef>
#include <cstring>
#include <locale>
#include <map>
#include <optional>
#include <string>
#include <utility>
@ -614,5 +615,71 @@ u32 UIDSys::GetOrInsertUIDForTitle(const u64 title_id)
return uid;
}
CertReader::CertReader(std::vector<u8>&& bytes) : SignedBlobReader(std::move(bytes))
{
if (!IsSignatureValid())
return;
switch (GetSignatureType())
{
case SignatureType::RSA4096:
if (m_bytes.size() < sizeof(CertRSA4096))
return;
m_bytes.resize(sizeof(CertRSA4096));
break;
case SignatureType::RSA2048:
if (m_bytes.size() < sizeof(CertRSA2048))
return;
m_bytes.resize(sizeof(CertRSA2048));
break;
default:
return;
}
m_is_valid = true;
}
bool CertReader::IsValid() const
{
return m_is_valid;
}
u32 CertReader::GetId() const
{
const size_t offset = GetSignatureSize() + offsetof(CertHeader, id);
return Common::swap32(m_bytes.data() + offset);
}
std::string CertReader::GetName() const
{
const char* name = reinterpret_cast<const char*>(m_bytes.data() + GetSignatureSize() +
offsetof(CertHeader, name));
return std::string(name, strnlen(name, sizeof(CertHeader::name)));
}
PublicKeyType CertReader::GetPublicKeyType() const
{
const size_t offset = GetSignatureSize() + offsetof(CertHeader, public_key_type);
return static_cast<PublicKeyType>(Common::swap32(m_bytes.data() + offset));
}
std::vector<u8> CertReader::GetPublicKey() const
{
static const std::map<SignatureType, std::pair<size_t, size_t>> type_to_key_info = {{
{SignatureType::RSA4096,
{offsetof(CertRSA4096, public_key),
sizeof(CertRSA4096::public_key) + sizeof(CertRSA4096::exponent)}},
{SignatureType::RSA2048,
{offsetof(CertRSA2048, public_key),
sizeof(CertRSA2048::public_key) + sizeof(CertRSA2048::exponent)}},
}};
const auto info = type_to_key_info.at(GetSignatureType());
const auto key_begin = m_bytes.begin() + info.first;
return std::vector<u8>(key_begin, key_begin + info.second);
}
} // namespace ES
} // namespace IOS

View File

@ -16,6 +16,7 @@
#include "Common/CommonTypes.h"
#include "Common/NandPaths.h"
#include "Core/IOS/Device.h"
#include "Core/IOS/IOSC.h"
#include "DiscIO/Enums.h"
@ -264,5 +265,24 @@ private:
std::string m_file_path;
std::map<u32, u64> m_entries;
};
class CertReader final : public SignedBlobReader
{
public:
explicit CertReader(std::vector<u8>&& bytes);
bool IsValid() const;
u32 GetId() const;
// Returns the certificate name. Examples: XS00000003, CA00000001
std::string GetName() const;
PublicKeyType GetPublicKeyType() const;
// Returns the public key bytes + any other data associated with it.
// For RSA public keys, this includes 4 bytes for the exponent at the end.
std::vector<u8> GetPublicKey() const;
private:
bool m_is_valid = false;
};
} // namespace ES
} // namespace IOS