Merge pull request #2830 from SleglJan/feat/libscessl-ca-list
feat(libSceSsl): implement sceSslGetCaList, sceSslFreeCaList and sceSslUnloadCert
This commit is contained in:
commit
bf6e25a1dd
|
|
@ -5,7 +5,8 @@ configure_windows_unwind(libSceSsl)
|
|||
if(BUILD_TESTING)
|
||||
add_test_executable(guest_ssl_tests ${LIBS_INCLUDE_DIR}/tests/GuestSsl.cpp)
|
||||
target_include_directories(guest_ssl_tests PRIVATE ${LIBS_INCLUDE_DIR})
|
||||
target_link_libraries(guest_ssl_tests PRIVATE libSceSsl)
|
||||
target_link_libraries(guest_ssl_tests PRIVATE libSceSsl libc)
|
||||
configure_windows_unwind(guest_ssl_tests)
|
||||
add_test(NAME guest_ssl COMMAND guest_ssl_tests)
|
||||
if(WIN32)
|
||||
set_tests_properties(guest_ssl PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include <map>
|
||||
#include <mutex>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
// No network is emulated: contexts, templates and requests can be created, but any request
|
||||
// that would touch the network fails with the library's network error.
|
||||
|
|
@ -37,6 +38,17 @@ struct SslCaCerts {
|
|||
void* pool;
|
||||
};
|
||||
|
||||
struct SslCaList {
|
||||
void** certs;
|
||||
int num;
|
||||
};
|
||||
static_assert(sizeof(SslCaList) == 16);
|
||||
|
||||
void RequireContext(const char* function, int sslCtxId) {
|
||||
std::lock_guard lock(g_poolsMutex);
|
||||
if (!g_pools.contains(sslCtxId)) throw std::invalid_argument(std::string(function) + ": unknown context");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
|
@ -55,6 +67,20 @@ int APS5_VABI sceSslGetCaCerts(int ssl_ctx_id, void* ca_certs) {
|
|||
return ERROR_NOT_FOUND;
|
||||
}
|
||||
|
||||
int APS5_VABI sceSslGetCaList(int sslCtxId, SslCaList* caList) {
|
||||
if (!caList) return ERROR_INVALID_ARG;
|
||||
RequireContext(__func__, sslCtxId);
|
||||
*caList = {};
|
||||
return ERROR_NOT_FOUND;
|
||||
}
|
||||
|
||||
int APS5_VABI sceSslFreeCaList(int sslCtxId, SslCaList* caList) {
|
||||
if (!caList) return ERROR_INVALID_ARG;
|
||||
RequireContext(__func__, sslCtxId);
|
||||
if (caList->certs || caList->num) throw std::invalid_argument("sceSslFreeCaList: list not returned by sceSslGetCaList");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI sceSslInit_nid_postfix(uint64_t pool_size) {
|
||||
const int id = g_nextHandle.fetch_add(1, std::memory_order_relaxed);
|
||||
std::lock_guard lock(g_poolsMutex);
|
||||
|
|
@ -83,6 +109,11 @@ int APS5_VABI sceSslLoadCert() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI sceSslUnloadCert(int sslCtxId) {
|
||||
RequireContext(__func__, sslCtxId);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI sceSslGetMemoryPoolStats(int ssl_ctx_id, SslMemoryPoolStats* stats) {
|
||||
if (stats == nullptr) APS5_INVALID_ARG_EX;
|
||||
std::lock_guard lock(g_poolsMutex);
|
||||
|
|
|
|||
|
|
@ -2,11 +2,16 @@
|
|||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <exception>
|
||||
|
||||
extern "C" {
|
||||
int APS5_VABI sceSslInit_nid_postfix(std::size_t);
|
||||
int APS5_VABI sceSslTerm_nid_postfix(int);
|
||||
int APS5_VABI sceSslGetCaCerts(int, void*);
|
||||
int APS5_VABI sceSslFreeCaCerts(int, void*);
|
||||
int APS5_VABI sceSslGetCaList(int, void*);
|
||||
int APS5_VABI sceSslFreeCaList(int, void*);
|
||||
int APS5_VABI sceSslUnloadCert(int);
|
||||
}
|
||||
|
||||
struct SslMemoryPoolStats {
|
||||
|
|
@ -20,12 +25,27 @@ extern "C" int APS5_VABI sceSslGetMemoryPoolStats(int, SslMemoryPoolStats*);
|
|||
|
||||
static void Require(bool value) { if (!value) std::abort(); }
|
||||
|
||||
template <typename TCall>
|
||||
static bool Throws(TCall call) {
|
||||
try {
|
||||
call();
|
||||
} catch (const std::exception&) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
struct SslCaCerts {
|
||||
void* certs;
|
||||
std::size_t num;
|
||||
void* pool;
|
||||
};
|
||||
|
||||
struct SslCaList {
|
||||
void** certs;
|
||||
int num;
|
||||
};
|
||||
|
||||
int main() {
|
||||
constexpr int notFound = static_cast<int>(0x8095F004);
|
||||
constexpr int invalidArg = static_cast<int>(0x8095177A);
|
||||
|
|
@ -46,4 +66,33 @@ int main() {
|
|||
certs = {&marker, 3, &marker};
|
||||
Require(sceSslFreeCaCerts(context, &certs) == 0);
|
||||
Require(certs.certs == nullptr && certs.num == 0 && certs.pool == nullptr);
|
||||
|
||||
Require(sceSslGetCaList(context, nullptr) == invalidArg);
|
||||
Require(sceSslFreeCaList(context, nullptr) == invalidArg);
|
||||
|
||||
void* handle = ▮
|
||||
SslCaList list{&handle, 3};
|
||||
Require(sceSslGetCaList(context, &list) == notFound);
|
||||
Require(list.certs == nullptr && list.num == 0);
|
||||
Require(sceSslFreeCaList(context, &list) == 0);
|
||||
Require(list.certs == nullptr && list.num == 0);
|
||||
|
||||
SslCaList foreign{&handle, 1};
|
||||
Require(Throws([&] { sceSslFreeCaList(context, &foreign); }));
|
||||
foreign = {nullptr, 1};
|
||||
Require(Throws([&] { sceSslFreeCaList(context, &foreign); }));
|
||||
foreign = {&handle, 0};
|
||||
Require(Throws([&] { sceSslFreeCaList(context, &foreign); }));
|
||||
|
||||
Require(sceSslUnloadCert(context) == 0);
|
||||
Require(sceSslGetCaList(context, &list) == notFound);
|
||||
Require(list.certs == nullptr && list.num == 0);
|
||||
|
||||
Require(sceSslTerm_nid_postfix(context) == 0);
|
||||
Require(sceSslGetCaList(context, nullptr) == invalidArg);
|
||||
Require(sceSslFreeCaList(context, nullptr) == invalidArg);
|
||||
list = {&handle, 3};
|
||||
Require(Throws([&] { sceSslGetCaList(context, &list); }));
|
||||
Require(Throws([&] { sceSslFreeCaList(context, &list); }));
|
||||
Require(Throws([&] { sceSslUnloadCert(context); }));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -185,6 +185,7 @@ Throughout the project, every function at every stage either **does exactly what
|
|||
- [sceKernelGetOperationMode](../../core/libs/prx/libkernel/System/src/Process.cpp) (libkernel) - the signature `(int* mode, int* submode)` comes from PPSA12544, which logs both values after the call; the values are unknown and 0 is reported for both, as in the [prosper](https://github.com/mattias800/prosper/pull/4153) reimplementation. Null outputs throw
|
||||
- Font, Http2, Net, Ssl, SystemService and libkernel exports imported by PPSA12544 and added without an implementation have unknown signatures
|
||||
- [sceHttp2GetMemoryPoolStats, sceSslGetMemoryPoolStats, sceNetGetMemoryPoolStats](../../core/libs/prx/libSceNet/Export.cpp) (libSceHttp2, libSceSsl, libSceNet) - signatures `(int id, stats*)` and the statistics layouts (pool size, peak and current use, and for Http2 and Ssl a 32-bit reserved field) follow the PS4 SDK's `SceHttp2MemoryPoolStats`, `SceSslMemoryPoolStats` and `SceNetMemoryPoolStats`, not confirmed for the PS5. The pool size is the one given at init or pool creation; nothing is allocated from these pools, so the peak and current use are 0. Net returns `EBADF` for an unknown pool and `EINVAL` for a null output, as its other pool calls do; for Http2 and Ssl the error codes are unknown, so both cases throw
|
||||
- [sceSslGetCaList, sceSslFreeCaList, sceSslUnloadCert](../../core/libs/prx/libSceSsl/Export.cpp) (libSceSsl) - signatures and the 16-byte `SceSslCaList` layout (an array of certificate handles and a 32-bit count) follow [SharpProspero](https://github.com/SvenGDK/SharpProspero/blob/5dfdb4b0b166e83dc9ae275001afb695f12c7174/src/SharpProspero/Interop/Net/Http.cs) and shadPS4's `OrbisSslCaList`, not confirmed for the PS5. On the console the list holds the certificate authorities the SSL service has; [shadPS4](https://github.com/shadps4-emu/shadPS4/pull/4104) returns a placeholder certificate from `sceSslGetCaCerts` because Rise of the Tomb Raider fails its initialization checks without one. No root certificate bundle is shipped and no loaded certificate is kept, so here a context holds none: `sceSslGetCaList` clears the list and returns `NOT_FOUND`, as `sceSslGetCaCerts` does, `sceSslFreeCaList` accepts only that cleared list, and `sceSslUnloadCert` (imported by PPSA15508) has nothing to drop and is assumed to return 0. A null list returns `0x8095177A`, which `sceSslGetCaCerts` and [KytyPS5](https://github.com/KytyPS5/KytyPS5/blob/59183dbfa81ed7efdff6069177fed50de0552725/src/libs/network.cpp) return for a null argument (shadPS4, PS4, returns `0x8095F007`). An unknown context throws (KytyPS5 returns `SSL_ERROR_INVALID_ID`, `0x8095F006`, from `sceSslGetCaCerts`), and so does a list `sceSslGetCaList` did not return
|
||||
- [sceHttp2SetResolveRetry](../../core/libs/prx/libSceHttp2/Export.cpp) (libSceHttp2) - signature `(int id, int32_t retry)` from libSceHttp's `sceHttpSetResolveRetry`; the value is accepted and ignored like the other Http2 settings, since no request reaches the network
|
||||
- [sceHttp2WebSocketCreateRequest, sceHttp2WebSocketCloseAsync, sceHttp2WebSocketSendTextMessageAsync, sceHttp2WebSocketSendDataMessageAsync](../../core/libs/prx/libSceHttp2/Export.cpp) (libSceHttp2) - imported by PPSA16064 and not called during its start-up; unknown signatures
|
||||
- [libSceVrSetupDialog](../../core/libs/prx/libSceVrSetupDialog/Export.cpp), and the Share, NpTrophy2, NpEntitlementAccess and WebBrowserDialog exports imported by PPSA12544's Unity plugins and added without an implementation, have unknown signatures
|
||||
|
|
|
|||
Loading…
Reference in New Issue