mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-22 08:33:12 -05:00
PPSA11386 imports sceSslGetCaList and sceSslFreeCaList and PPSA15508 imports sceSslUnloadCert; on main all three are missing and the loaders of both titles stop on them. No root certificate bundle is shipped and no loaded certificate is kept, so an SSL context holds no certificates: sceSslGetCaList clears the list and returns NOT_FOUND, as sceSslGetCaCerts does; sceSslFreeCaList accepts only that cleared list; sceSslUnloadCert has nothing to drop and is assumed to return 0. A null list returns the invalid-argument code that sceSslGetCaCerts and KytyPS5 return. An unknown context and a list sceSslGetCaList did not return throw, as their codes are not confirmed. Signatures and the SceSslCaList layout follow SharpProspero and shadPS4. guest_ssl_tests now links libc, as guest_http2_tests does, so an exception thrown from libSceSsl unwinds with the same unwinder that resumes it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
157 lines
3.8 KiB
C++
157 lines
3.8 KiB
C++
#include <cstdint>
|
|
#include <cstddef>
|
|
#include "SceTypes.hpp"
|
|
#include "prx/libc/include/General.hpp"
|
|
#include <atomic>
|
|
#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.
|
|
static constexpr int ERROR_NETWORK = static_cast<int>(0x80435001);
|
|
static std::atomic<int> g_nextHandle{1};
|
|
static std::mutex g_poolsMutex;
|
|
static std::map<int, uint64_t> g_pools;
|
|
|
|
namespace {
|
|
|
|
constexpr int ERROR_NOT_FOUND = static_cast<int>(0x8095F004);
|
|
constexpr int ERROR_INVALID_ARG = static_cast<int>(0x8095177A);
|
|
|
|
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<SslCaCerts*>(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<SslCaCerts*>(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) APS5_INVALID_ARG_EX;
|
|
std::lock_guard lock(g_poolsMutex);
|
|
const auto pool = g_pools.find(ssl_ctx_id);
|
|
if (pool == g_pools.end()) throw std::invalid_argument("sceSslGetMemoryPoolStats: unknown context");
|
|
*stats = {static_cast<size_t>(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;
|
|
}
|
|
|
|
}
|