mirror of
https://github.com/d0k3/GodMode9.git
synced 2025-06-26 05:32:47 +00:00
Certificate static storage
Decrease repeated load times At least for retail/dev certs
This commit is contained in:
parent
8427e0776c
commit
1f96b5e9e6
@ -13,6 +13,58 @@ static void GetCertDBPath(char* path, bool emunand) {
|
||||
strcpy(&path[1], ":/dbs/certs.db");
|
||||
}
|
||||
|
||||
#define CERT_RETAIL_CA3_IDENT BIT(0)
|
||||
#define CERT_RETAIL_XSc_IDENT BIT(1)
|
||||
#define CERT_RETAIL_CPb_IDENT BIT(2)
|
||||
#define CERT_DEV_CA4_IDENT BIT(3)
|
||||
#define CERT_DEV_XS9_IDENT BIT(4)
|
||||
#define CERT_DEV_CPa_IDENT BIT(5)
|
||||
#define CERT_NO_STORE_SPACE (0xFF)
|
||||
|
||||
static struct {
|
||||
u32 loaded_certs_flg;
|
||||
u8 retail_CA3_raw[CERT_RSA4096_SIG_SIZE + CERT_RSA2048_BODY_SIZE];
|
||||
u8 retail_XSc_raw[CERT_RSA2048_SIG_SIZE + CERT_RSA2048_BODY_SIZE];
|
||||
u8 retail_CPb_raw[CERT_RSA2048_SIG_SIZE + CERT_RSA2048_BODY_SIZE];
|
||||
u8 dev_CA4_raw[CERT_RSA4096_SIG_SIZE + CERT_RSA2048_BODY_SIZE];
|
||||
u8 dev_XS9_raw[CERT_RSA2048_SIG_SIZE + CERT_RSA2048_BODY_SIZE];
|
||||
u8 dev_CPa_raw[CERT_RSA2048_SIG_SIZE + CERT_RSA2048_BODY_SIZE];
|
||||
Certificate retail_CA3;
|
||||
Certificate retail_XSc;
|
||||
Certificate retail_CPb;
|
||||
Certificate dev_CA4;
|
||||
Certificate dev_XS9;
|
||||
Certificate dev_CPa;
|
||||
} _CommonCertsStorage = {
|
||||
0, // none loaded yet, ident defines used to say what's loaded
|
||||
{0}, {0}, {0}, {0}, {0}, {0}, // no data yet
|
||||
// cert structs pre-point already to raw certs
|
||||
{
|
||||
(CertificateSignature*)&_CommonCertsStorage.retail_CA3_raw[0],
|
||||
(CertificateBody*)&_CommonCertsStorage.retail_CA3_raw[CERT_RSA4096_SIG_SIZE]
|
||||
},
|
||||
{
|
||||
(CertificateSignature*)&_CommonCertsStorage.retail_XSc_raw[0],
|
||||
(CertificateBody*)&_CommonCertsStorage.retail_XSc_raw[CERT_RSA2048_SIG_SIZE]
|
||||
},
|
||||
{
|
||||
(CertificateSignature*)&_CommonCertsStorage.retail_CPb_raw[0],
|
||||
(CertificateBody*)&_CommonCertsStorage.retail_CPb_raw[CERT_RSA2048_SIG_SIZE]
|
||||
},
|
||||
{
|
||||
(CertificateSignature*)&_CommonCertsStorage.dev_CA4_raw[0],
|
||||
(CertificateBody*)&_CommonCertsStorage.dev_CA4_raw[CERT_RSA4096_SIG_SIZE]
|
||||
},
|
||||
{
|
||||
(CertificateSignature*)&_CommonCertsStorage.dev_XS9_raw[0],
|
||||
(CertificateBody*)&_CommonCertsStorage.dev_XS9_raw[CERT_RSA2048_SIG_SIZE]
|
||||
},
|
||||
{
|
||||
(CertificateSignature*)&_CommonCertsStorage.dev_CPa_raw[0],
|
||||
(CertificateBody*)&_CommonCertsStorage.dev_CPa_raw[CERT_RSA2048_SIG_SIZE]
|
||||
}
|
||||
};
|
||||
|
||||
bool Certificate_IsValid(const Certificate* cert) {
|
||||
if (!cert || !cert->sig || !cert->data)
|
||||
return false;
|
||||
@ -191,20 +243,176 @@ u32 Certificate_RawCopy(const Certificate* cert, void* raw) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ptr free check, to not free if ptr is pointing to static storage!!
|
||||
static inline void _Certificate_SafeFree(void* ptr) {
|
||||
if ((u32)ptr >= (u32)&_CommonCertsStorage && (u32)ptr < (u32)&_CommonCertsStorage + sizeof(_CommonCertsStorage))
|
||||
return;
|
||||
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
u32 Certificate_Cleanup(Certificate* cert) {
|
||||
if (!cert) return 1;
|
||||
|
||||
free(cert->sig);
|
||||
free(cert->data);
|
||||
_Certificate_SafeFree(cert->sig);
|
||||
_Certificate_SafeFree(cert->data);
|
||||
cert->sig = NULL;
|
||||
cert->data = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 _Issuer_To_StorageIdent(const char* issuer) {
|
||||
if (strncmp(issuer, "Root-CA0000000", 14) != 0)
|
||||
return CERT_NO_STORE_SPACE;
|
||||
|
||||
if (issuer[14] == '3') { // retail
|
||||
if (issuer[15] == 0)
|
||||
return CERT_RETAIL_CA3_IDENT;
|
||||
if (issuer[15] != '-')
|
||||
return CERT_NO_STORE_SPACE;
|
||||
if (!strcmp(&issuer[16], "XS0000000c"))
|
||||
return CERT_RETAIL_XSc_IDENT;
|
||||
if (!strcmp(&issuer[16], "CP0000000b"))
|
||||
return CERT_RETAIL_CPb_IDENT;
|
||||
}
|
||||
|
||||
if (issuer[14] == '4') { // dev
|
||||
if (issuer[15] == 0)
|
||||
return CERT_DEV_CA4_IDENT;
|
||||
if (issuer[15] != '-')
|
||||
return CERT_NO_STORE_SPACE;
|
||||
if (!strcmp(&issuer[16], "XS00000009"))
|
||||
return CERT_DEV_XS9_IDENT;
|
||||
if (!strcmp(&issuer[16], "CP0000000a"))
|
||||
return CERT_DEV_CPa_IDENT;
|
||||
}
|
||||
|
||||
return CERT_NO_STORE_SPACE;
|
||||
}
|
||||
|
||||
static bool _LoadFromCertStorage(Certificate* cert, u32 ident) {
|
||||
if (ident == CERT_NO_STORE_SPACE)
|
||||
return false;
|
||||
|
||||
Certificate* _cert = NULL;
|
||||
|
||||
switch (ident) {
|
||||
case CERT_RETAIL_CA3_IDENT:
|
||||
if (_CommonCertsStorage.loaded_certs_flg & CERT_RETAIL_CA3_IDENT)
|
||||
_cert = &_CommonCertsStorage.retail_CA3;
|
||||
break;
|
||||
case CERT_RETAIL_XSc_IDENT:
|
||||
if (_CommonCertsStorage.loaded_certs_flg & CERT_RETAIL_XSc_IDENT)
|
||||
_cert = &_CommonCertsStorage.retail_XSc;
|
||||
break;
|
||||
case CERT_RETAIL_CPb_IDENT:
|
||||
if (_CommonCertsStorage.loaded_certs_flg & CERT_RETAIL_CPb_IDENT)
|
||||
_cert = &_CommonCertsStorage.retail_CPb;
|
||||
break;
|
||||
case CERT_DEV_CA4_IDENT:
|
||||
if (_CommonCertsStorage.loaded_certs_flg & CERT_DEV_CA4_IDENT)
|
||||
_cert = &_CommonCertsStorage.dev_CA4;
|
||||
break;
|
||||
case CERT_DEV_XS9_IDENT:
|
||||
if (_CommonCertsStorage.loaded_certs_flg & CERT_DEV_XS9_IDENT)
|
||||
_cert = &_CommonCertsStorage.dev_XS9;
|
||||
break;
|
||||
case CERT_DEV_CPa_IDENT:
|
||||
if (_CommonCertsStorage.loaded_certs_flg & CERT_DEV_CPa_IDENT)
|
||||
_cert = &_CommonCertsStorage.dev_CPa;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!_cert)
|
||||
return false;
|
||||
|
||||
*cert = *_cert;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void _SaveToCertStorage(const Certificate* cert, u32 ident) {
|
||||
if (ident == CERT_NO_STORE_SPACE)
|
||||
return;
|
||||
|
||||
Certificate* _cert = NULL;
|
||||
u8* raw_space = NULL;
|
||||
u32 raw_size = 0;
|
||||
|
||||
switch (ident) {
|
||||
case CERT_RETAIL_CA3_IDENT:
|
||||
if (!(_CommonCertsStorage.loaded_certs_flg & CERT_RETAIL_CA3_IDENT)) {
|
||||
_cert = &_CommonCertsStorage.retail_CA3;
|
||||
raw_space = &_CommonCertsStorage.retail_CA3_raw[0];
|
||||
raw_size = sizeof(_CommonCertsStorage.retail_CA3_raw);
|
||||
}
|
||||
break;
|
||||
case CERT_RETAIL_XSc_IDENT:
|
||||
if (!(_CommonCertsStorage.loaded_certs_flg & CERT_RETAIL_XSc_IDENT)) {
|
||||
_cert = &_CommonCertsStorage.retail_XSc;
|
||||
raw_space = &_CommonCertsStorage.retail_XSc_raw[0];
|
||||
raw_size = sizeof(_CommonCertsStorage.retail_XSc_raw);
|
||||
}
|
||||
break;
|
||||
case CERT_RETAIL_CPb_IDENT:
|
||||
if (!(_CommonCertsStorage.loaded_certs_flg & CERT_RETAIL_CPb_IDENT)) {
|
||||
_cert = &_CommonCertsStorage.retail_CPb;
|
||||
raw_space = &_CommonCertsStorage.retail_CPb_raw[0];
|
||||
raw_size = sizeof(_CommonCertsStorage.retail_CPb_raw);
|
||||
}
|
||||
break;
|
||||
case CERT_DEV_CA4_IDENT:
|
||||
if (!(_CommonCertsStorage.loaded_certs_flg & CERT_DEV_CA4_IDENT)) {
|
||||
_cert = &_CommonCertsStorage.dev_CA4;
|
||||
raw_space = &_CommonCertsStorage.dev_CA4_raw[0];
|
||||
raw_size = sizeof(_CommonCertsStorage.dev_CA4_raw);
|
||||
}
|
||||
break;
|
||||
case CERT_DEV_XS9_IDENT:
|
||||
if (!(_CommonCertsStorage.loaded_certs_flg & CERT_DEV_XS9_IDENT)) {
|
||||
_cert = &_CommonCertsStorage.dev_XS9;
|
||||
raw_space = &_CommonCertsStorage.dev_XS9_raw[0];
|
||||
raw_size = sizeof(_CommonCertsStorage.dev_XS9_raw);
|
||||
}
|
||||
break;
|
||||
case CERT_DEV_CPa_IDENT:
|
||||
if (!(_CommonCertsStorage.loaded_certs_flg & CERT_DEV_CPa_IDENT)) {
|
||||
_cert = &_CommonCertsStorage.dev_CPa;
|
||||
raw_space = &_CommonCertsStorage.dev_CPa_raw[0];
|
||||
raw_size = sizeof(_CommonCertsStorage.dev_CPa_raw);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!_cert || !raw_space || !raw_size)
|
||||
return;
|
||||
|
||||
u32 sig_size = _Certificate_GetSignatureChunkSizeFromType(getbe32(cert->sig->sig_type));
|
||||
u32 data_size = _Certificate_GetDataChunkSizeFromType(getbe32(cert->data->keytype));
|
||||
|
||||
if (sig_size == 0 || data_size == 0)
|
||||
return;
|
||||
|
||||
if (sig_size + data_size != raw_size)
|
||||
return;
|
||||
|
||||
if (!Certificate_RawCopy(cert, raw_space)) {
|
||||
_CommonCertsStorage.loaded_certs_flg |= ident;
|
||||
}
|
||||
}
|
||||
|
||||
u32 LoadCertFromCertDb(bool emunand, Certificate* cert, const char* issuer) {
|
||||
if (!issuer || !cert) return 1;
|
||||
|
||||
u32 _ident = _Issuer_To_StorageIdent(issuer);
|
||||
if (_LoadFromCertStorage(cert, _ident)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Certificate cert_local = {NULL, NULL};
|
||||
|
||||
char path[16];
|
||||
@ -304,6 +512,8 @@ u32 LoadCertFromCertDb(bool emunand, Certificate* cert, const char* issuer) {
|
||||
|
||||
if (ret) {
|
||||
Certificate_Cleanup(&cert_local);
|
||||
} else {
|
||||
_SaveToCertStorage(&cert_local, _ident);
|
||||
}
|
||||
|
||||
*cert = cert_local;
|
||||
|
Loading…
x
Reference in New Issue
Block a user