#include #include #include #include "SceTypes.hpp" #include "prx/libc/include/General.hpp" #include #include #include #include #include // 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. static constexpr int ERROR_NETWORK = static_cast(0x80435001); static std::atomic g_nextHandle{1}; static std::mutex g_poolsMutex; static std::map g_pools; namespace { constexpr int ERROR_NOT_FOUND = static_cast(0x8095F004); constexpr int ERROR_INVALID_ARG = static_cast(0x8095177A); constexpr int ERROR_INVALID_ID = static_cast(0x8095F006); constexpr int ERROR_INVALID_VALUE = static_cast(0x8095F007); struct SslData { char* ptr; size_t size; }; struct SslMemoryPoolStats { size_t pool_size; size_t max_inuse_size; size_t current_inuse_size; int32_t reserved; }; struct SslCaCerts { SslData* certs; size_t num; 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" { int APS5_VABI sceSslFreeCaCerts(int ssl_ctx_id, void* ca_certs) { (void)ssl_ctx_id; if (!ca_certs) return ERROR_INVALID_ARG; *static_cast(ca_certs) = {}; return 0; } int APS5_VABI sceSslGetCaCerts(int ssl_ctx_id, void* ca_certs) { (void)ssl_ctx_id; if (!ca_certs) return ERROR_INVALID_ARG; *static_cast(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); g_pools[id] = pool_size; return id; } int APS5_VABI sceSslTerm_nid_postfix(int ssl_ctx_id) { std::lock_guard lock(g_poolsMutex); g_pools.erase(ssl_ctx_id); return 0; } int APS5_VABI sceSslClose() { NotImplemented_nid_no_patch(__func__); return 0; } int APS5_VABI sceSslGetSerialNumber() { NotImplemented_nid_no_patch(__func__); return 0; } int APS5_VABI sceSslLoadCert() { NotImplemented_nid_no_patch(__func__); 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) return ERROR_INVALID_VALUE; std::lock_guard lock(g_poolsMutex); const auto pool = g_pools.find(ssl_ctx_id); if (pool == g_pools.end()) { std::memset(stats, 0, sizeof(*stats)); return ERROR_INVALID_ID; } *stats = {static_cast(pool->second), 0, 0, 0}; return 0; } int APS5_VABI sceSslFreeSslCertName(void) { NotImplemented_nid_no_patch(__func__); return 0; } int APS5_VABI sceSslGetIssuerName(void) { NotImplemented_nid_no_patch(__func__); return 0; } int APS5_VABI sceSslGetNameEntryCount(void) { NotImplemented_nid_no_patch(__func__); return 0; } int APS5_VABI sceSslGetNameEntryInfo(void) { NotImplemented_nid_no_patch(__func__); return 0; } int APS5_VABI sceSslGetPem(void) { NotImplemented_nid_no_patch(__func__); return 0; } int APS5_VABI sceSslGetSubjectName(void) { NotImplemented_nid_no_patch(__func__); return 0; } }