Merge pull request #19 from HookedBehemoth/master

Fix ticket listing and minor libnx update
This commit is contained in:
shchmue 2020-03-16 15:27:35 -06:00 committed by GitHub
commit b150d20957
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 33 additions and 76 deletions

View file

@ -35,7 +35,6 @@
extern "C" { extern "C" {
#include "nx/es.h" #include "nx/es.h"
#include "nx/set_ext.h"
} }
#define TITLEKEY_BUFFER_SIZE 0x40000 #define TITLEKEY_BUFFER_SIZE 0x40000
@ -486,7 +485,7 @@ void KeyCollection::derive_keys() {
FRESULT fr; FRESULT fr;
FIL save_file; FIL save_file;
fsOpenBisStorage(&storage, FsBisStorageId_System); fsOpenBisStorage(&storage, FsBisPartitionId_System);
if (f_mount(&fs, "", 1) || if (f_mount(&fs, "", 1) ||
f_chdir("/save") || f_chdir("/save") ||
f_open(&save_file, "8000000000000043", FA_READ | FA_OPEN_EXISTING)) f_open(&save_file, "8000000000000043", FA_READ | FA_OPEN_EXISTING))
@ -592,7 +591,7 @@ void KeyCollection::get_titlekeys() {
esInitialize(); esInitialize();
esCountCommonTicket(&common_count); esCountCommonTicket(&common_count);
esCountPersonalizedTicket(&personalized_count); esCountPersonalizedTicket(&personalized_count);
NcmRightsId common_rights_ids[common_count], personalized_rights_ids[personalized_count]; RightsId common_rights_ids[common_count], personalized_rights_ids[personalized_count];
esListCommonTicket(&ids_written, common_rights_ids, sizeof(common_rights_ids)); esListCommonTicket(&ids_written, common_rights_ids, sizeof(common_rights_ids));
esListPersonalizedTicket(&ids_written, personalized_rights_ids, sizeof(personalized_rights_ids)); esListPersonalizedTicket(&ids_written, personalized_rights_ids, sizeof(personalized_rights_ids));
esExit(); esExit();
@ -608,27 +607,27 @@ void KeyCollection::get_titlekeys() {
std::unordered_set<std::string> rights_ids; std::unordered_set<std::string> rights_ids;
for (size_t i = 0; i < common_count; i++) { for (size_t i = 0; i < common_count; i++) {
for (size_t j = 0; j < 0x10; j++) { for (size_t j = 0; j < 0x10; j++) {
sprintf(&rights_id_string[j*2], "%02x", common_rights_ids[i].rights_id.c[j]); sprintf(&rights_id_string[j*2], "%02x", common_rights_ids[i].c[j]);
} }
rights_ids.insert(rights_id_string); rights_ids.insert(rights_id_string);
} }
for (size_t i = 0; i < personalized_count; i++) { for (size_t i = 0; i < personalized_count; i++) {
for (size_t j = 0; j < 0x10; j++) { for (size_t j = 0; j < 0x10; j++) {
sprintf(&rights_id_string[j*2], "%02x", personalized_rights_ids[i].rights_id.c[j]); sprintf(&rights_id_string[j*2], "%02x", personalized_rights_ids[i].c[j]);
} }
rights_ids.insert(rights_id_string); rights_ids.insert(rights_id_string);
} }
// get extended eticket RSA key from PRODINFO // get extended eticket RSA key from PRODINFO
u8 eticket_data[0x244] = {}; SetCalRsa2048DeviceKey eticket_data = {};
setcalInitialize(); setcalInitialize();
setcalGetEticketDeviceKey(eticket_data); setcalGetEticketDeviceKey(&eticket_data);
setcalExit(); setcalExit();
byte_vector dec_keypair = eticket_rsa_kek.aes_decrypt_ctr( byte_vector dec_keypair = eticket_rsa_kek.aes_decrypt_ctr(
byte_vector(eticket_data + 0x14, eticket_data + 0x244), byte_vector(eticket_data.key + 0x10, eticket_data.key + 0x240),
byte_vector(eticket_data + 4, eticket_data + 0x14) byte_vector(eticket_data.key, eticket_data.key + 0x10)
); );
// public exponent must be 65537 == 0x10001 (big endian) // public exponent must be 65537 == 0x10001 (big endian)
@ -646,7 +645,7 @@ void KeyCollection::get_titlekeys() {
// map of all found rights ids and corresponding titlekeys // map of all found rights ids and corresponding titlekeys
std::unordered_map<std::string, std::string> titlekeys; std::unordered_map<std::string, std::string> titlekeys;
fsOpenBisStorage(&storage, FsBisStorageId_System); fsOpenBisStorage(&storage, FsBisPartitionId_System);
if (f_mount(&fs, "", 1) || f_chdir("/save")) return; if (f_mount(&fs, "", 1) || f_chdir("/save")) return;
if (f_open(&save_file, "80000000000000e1", FA_READ | FA_OPEN_EXISTING)) return; if (f_open(&save_file, "80000000000000e1", FA_READ | FA_OPEN_EXISTING)) return;
while ((common_count != 0) && (titlekeys_dumped < common_count)) { while ((common_count != 0) && (titlekeys_dumped < common_count)) {

View file

@ -101,7 +101,7 @@ void KeyLocation::get_from_memory(u64 tid, u8 seg_mask) {
void KeyLocation::get_keyblobs() { void KeyLocation::get_keyblobs() {
FsStorage boot0; FsStorage boot0;
fsOpenBisStorage(&boot0, FsBisStorageId_Boot0); fsOpenBisStorage(&boot0, FsBisPartitionId_BootPartition1Root);
data.resize(0x200 * KNOWN_KEYBLOBS); data.resize(0x200 * KNOWN_KEYBLOBS);
fsStorageRead(&boot0, KEYBLOB_OFFSET, data.data(), data.size()); fsStorageRead(&boot0, KEYBLOB_OFFSET, data.data(), data.size());
fsStorageClose(&boot0); fsStorageClose(&boot0);

View file

@ -17,56 +17,48 @@ void _esCleanup() {
serviceClose(&g_esSrv); serviceClose(&g_esSrv);
} }
Result esCountCommonTicket(u32 *num_tickets) Result esCountCommonTicket(u32 *out_count)
{ {
struct { u32 num_tickets;
u32 num_tickets;
} out;
Result rc = serviceDispatchOut(&g_esSrv, 9, out); Result rc = serviceDispatchOut(&g_esSrv, 9, num_tickets);
if (R_SUCCEEDED(rc) && num_tickets) *num_tickets = out.num_tickets; if (R_SUCCEEDED(rc) && out_count) *out_count = num_tickets;
return rc; return rc;
} }
Result esCountPersonalizedTicket(u32 *num_tickets) Result esCountPersonalizedTicket(u32 *out_count)
{ {
struct { u32 num_tickets;
u32 num_tickets;
} out;
Result rc = serviceDispatchOut(&g_esSrv, 10, out); Result rc = serviceDispatchOut(&g_esSrv, 10, num_tickets);
if (R_SUCCEEDED(rc) && num_tickets) *num_tickets = out.num_tickets; if (R_SUCCEEDED(rc) && out_count) *out_count = num_tickets;
return rc; return rc;
} }
Result esListCommonTicket(u32 *numRightsIdsWritten, NcmRightsId *outBuf, size_t bufSize) Result esListCommonTicket(u32 *numRightsIdsWritten, RightsId *outBuf, size_t bufSize)
{ {
struct { u32 num_rights_ids_written;
u32 num_rights_ids_written;
} out;
Result rc = serviceDispatchInOut(&g_esSrv, 11, *numRightsIdsWritten, out, Result rc = serviceDispatchOut(&g_esSrv, 11, num_rights_ids_written,
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
.buffers = { { outBuf, bufSize } }, .buffers = { { outBuf, bufSize } },
); );
if (R_SUCCEEDED(rc) && numRightsIdsWritten) *numRightsIdsWritten = out.num_rights_ids_written; if (R_SUCCEEDED(rc) && numRightsIdsWritten) *numRightsIdsWritten = num_rights_ids_written;
return rc; return rc;
} }
Result esListPersonalizedTicket(u32 *numRightsIdsWritten, NcmRightsId *outBuf, size_t bufSize) Result esListPersonalizedTicket(u32 *numRightsIdsWritten, RightsId *outBuf, size_t bufSize)
{ {
struct { u32 num_rights_ids_written;
u32 num_rights_ids_written;
} out;
Result rc = serviceDispatchInOut(&g_esSrv, 12, *numRightsIdsWritten, out, Result rc = serviceDispatchOut(&g_esSrv, 12, num_rights_ids_written,
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
.buffers = { { outBuf, bufSize } }, .buffers = { { outBuf, bufSize } },
); );
if (R_SUCCEEDED(rc) && numRightsIdsWritten) *numRightsIdsWritten = out.num_rights_ids_written; if (R_SUCCEEDED(rc) && numRightsIdsWritten) *numRightsIdsWritten = num_rights_ids_written;
return rc; return rc;
} }

View file

@ -3,10 +3,14 @@
#include <switch/types.h> #include <switch/types.h>
#include <switch/services/ncm.h> #include <switch/services/ncm.h>
typedef struct {
u8 c[0x10];
} RightsId;
Result esInitialize(); Result esInitialize();
void esExit(); void esExit();
Result esCountCommonTicket(u32 *num_tickets); //9 Result esCountCommonTicket(u32 *num_tickets); //9
Result esCountPersonalizedTicket(u32 *num_tickets); // 10 Result esCountPersonalizedTicket(u32 *num_tickets); // 10
Result esListCommonTicket(u32 *numRightsIdsWritten, NcmRightsId *outBuf, size_t bufSize); Result esListCommonTicket(u32 *numRightsIdsWritten, RightsId *outBuf, size_t bufSize);
Result esListPersonalizedTicket(u32 *numRightsIdsWritten, NcmRightsId *outBuf, size_t bufSize); Result esListPersonalizedTicket(u32 *numRightsIdsWritten, RightsId *outBuf, size_t bufSize);

View file

@ -1,26 +0,0 @@
#include "set_ext.h"
#include "../service_guard.h"
#include <switch/services/sm.h>
#include <switch/types.h>
static Service g_setcalSrv;
NX_GENERATE_SERVICE_GUARD(setcal);
Result _setcalInitialize() {
return smGetService(&g_setcalSrv, "set:cal");
}
void _setcalCleanup() {
serviceClose(&g_setcalSrv);
}
Result setcalGetEticketDeviceKey(void *key)
{
return serviceDispatch(&g_setcalSrv, 21,
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
.buffers = { { key, 0x244 } },
);
}

View file

@ -1,12 +0,0 @@
#pragma once
#include <switch/result.h>
Result setcalInitialize(void);
void setcalExit(void);
/**
* @brief Gets the extended ETicket RSA-2048 Key from CAL0
* @param key Pointer to 0x244-byte output buffer.
*/
Result setcalGetEticketDeviceKey(void *key);