Skip to content

Commit

Permalink
IOSC: Implement ImportCertificate
Browse files Browse the repository at this point in the history
Same as VerifyPublicKeySign, we currently only support RSA keys
(which is all we need right now).
  • Loading branch information
leoetlino committed Jun 12, 2017
1 parent 1a8144c commit 4a35372
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 0 deletions.
78 changes: 78 additions & 0 deletions Source/Core/Core/IOS/IOSC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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, &parameters);
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);
Expand Down
2 changes: 2 additions & 0 deletions Source/Core/Core/IOS/IOSC.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,8 @@ class IOSC final

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;
Expand Down

0 comments on commit 4a35372

Please sign in to comment.