IOSC: Implement ImportCertificate
Same as VerifyPublicKeySign, we currently only support RSA keys (which is all we need right now).
This commit is contained in:
parent
1a8144c702
commit
4a3537285b
|
@ -19,6 +19,7 @@
|
|||
#include "Common/Crypto/AES.h"
|
||||
#include "Common/Crypto/ec.h"
|
||||
#include "Common/ScopeGuard.h"
|
||||
#include "Common/Swap.h"
|
||||
#include "Core/IOS/Device.h"
|
||||
#include "Core/IOS/IOSC.h"
|
||||
#include "Core/ec_wii.h"
|
||||
|
@ -243,6 +244,83 @@ ReturnCode IOSC::VerifyPublicKeySign(const std::array<u8, 20>& sha1, Handle sign
|
|||
}
|
||||
}
|
||||
|
||||
struct ImportCertParameters
|
||||
{
|
||||
size_t offset;
|
||||
size_t size;
|
||||
size_t signature_offset;
|
||||
size_t public_key_offset;
|
||||
size_t public_key_exponent_offset;
|
||||
};
|
||||
|
||||
static ReturnCode GetImportCertParameters(const u8* cert, ImportCertParameters* parameters)
|
||||
{
|
||||
// TODO: Add support for ECC signature type.
|
||||
const u32 signature_type = Common::swap32(cert + offsetof(Cert, type));
|
||||
switch (static_cast<SignatureType>(signature_type))
|
||||
{
|
||||
case SignatureType::RSA2048:
|
||||
{
|
||||
const u32 key_type = Common::swap32(cert + offsetof(Cert, rsa2048.header.public_key_type));
|
||||
|
||||
// TODO: Add support for ECC public key type.
|
||||
if (static_cast<PublicKeyType>(key_type) != PublicKeyType::RSA2048)
|
||||
return IOSC_INVALID_FORMAT;
|
||||
|
||||
parameters->offset = offsetof(Cert, rsa2048.signature.issuer);
|
||||
parameters->size = sizeof(Cert::rsa2048) - parameters->offset;
|
||||
parameters->signature_offset = offsetof(Cert, rsa2048.signature.sig);
|
||||
parameters->public_key_offset = offsetof(Cert, rsa2048.public_key);
|
||||
parameters->public_key_exponent_offset = offsetof(Cert, rsa2048.exponent);
|
||||
return IPC_SUCCESS;
|
||||
}
|
||||
case SignatureType::RSA4096:
|
||||
{
|
||||
parameters->offset = offsetof(Cert, rsa4096.signature.issuer);
|
||||
parameters->size = sizeof(Cert::rsa4096) - parameters->offset;
|
||||
parameters->signature_offset = offsetof(Cert, rsa4096.signature.sig);
|
||||
parameters->public_key_offset = offsetof(Cert, rsa4096.public_key);
|
||||
parameters->public_key_exponent_offset = offsetof(Cert, rsa4096.exponent);
|
||||
return IPC_SUCCESS;
|
||||
}
|
||||
default:
|
||||
WARN_LOG(IOS, "Unknown signature type: %08x", signature_type);
|
||||
return IOSC_INVALID_FORMAT;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnCode IOSC::ImportCertificate(const u8* cert, Handle signer_handle, Handle dest_handle,
|
||||
u32 pid)
|
||||
{
|
||||
if (!HasOwnership(signer_handle, pid) || !HasOwnership(dest_handle, pid))
|
||||
return IOSC_EACCES;
|
||||
|
||||
const KeyEntry* signer_entry = FindEntry(signer_handle, SearchMode::IncludeRootKey);
|
||||
const KeyEntry* dest_entry = FindEntry(dest_handle, SearchMode::IncludeRootKey);
|
||||
if (!signer_entry || !dest_entry)
|
||||
return IOSC_EINVAL;
|
||||
|
||||
if (signer_entry->type != TYPE_PUBLIC_KEY || dest_entry->type != TYPE_PUBLIC_KEY)
|
||||
return IOSC_INVALID_OBJTYPE;
|
||||
|
||||
ImportCertParameters parameters;
|
||||
const ReturnCode ret = GetImportCertParameters(cert, ¶meters);
|
||||
if (ret != IPC_SUCCESS)
|
||||
return ret;
|
||||
|
||||
std::array<u8, 20> sha1;
|
||||
mbedtls_sha1(cert + parameters.offset, parameters.size, sha1.data());
|
||||
|
||||
if (VerifyPublicKeySign(sha1, signer_handle, cert + parameters.signature_offset, pid) !=
|
||||
IPC_SUCCESS)
|
||||
{
|
||||
return IOSC_FAIL_CHECKVALUE;
|
||||
}
|
||||
|
||||
return ImportPublicKey(dest_handle, cert + parameters.public_key_offset,
|
||||
cert + parameters.public_key_exponent_offset, pid);
|
||||
}
|
||||
|
||||
ReturnCode IOSC::GetOwnership(Handle handle, u32* owner) const
|
||||
{
|
||||
const KeyEntry* entry = FindEntry(handle);
|
||||
|
|
|
@ -187,6 +187,8 @@ public:
|
|||
|
||||
ReturnCode VerifyPublicKeySign(const std::array<u8, 20>& sha1, Handle signer_handle,
|
||||
const u8* signature, u32 pid) const;
|
||||
// Import a certificate (signed by the certificate in signer_handle) into dest_handle.
|
||||
ReturnCode ImportCertificate(const u8* cert, Handle signer_handle, Handle dest_handle, u32 pid);
|
||||
|
||||
// Ownership
|
||||
ReturnCode GetOwnership(Handle handle, u32* owner) const;
|
||||
|
|
Loading…
Reference in New Issue