fix(ssl): use context-scoped PS5 certificate reader arguments

This commit is contained in:
JJenkx committed 2026-10-18 22:17:13 -04:00
1 parent f2d31a0b14
commit e8ec260bae
3 files changed
+43 -3

No files matched your search

+22 -2
View File
@@ -11,12 +11,14 @@
#include "prx/libkernel/Socket/include/SocketPoll.hpp"
#include <mbedtls/asn1.h>
#include <mbedtls/base64.h>
#include <mbedtls/ctr_drbg.h>
#include <mbedtls/entropy.h>
#include <mbedtls/error.h>
#include <mbedtls/md.h>
#include <mbedtls/net_sockets.h>
#include <mbedtls/oid.h>
#include <mbedtls/pem.h>
#include <mbedtls/pk.h>
#include <mbedtls/platform.h>
#include <mbedtls/platform_util.h>
@@ -1053,8 +1055,26 @@ int APS5_VABI sceSslGetFingerprint(int sslCtxId, void* sslCert, int hashType, un
return 0;
}
int APS5_VABI sceSslGetPem(void) {
NotImplemented_nid_no_patch(__func__);
int APS5_VABI sceSslGetPem(int sslCtxId, void* sslCert, char* buf, std::size_t* bufLen) {
if (!bufLen) return ErrorInvalidArg;
std::lock_guard lock(State().mutex);
auto& context = GetContext(sslCtxId);
const auto* crt = RequireCertificate(__func__, sslCtxId, sslCert);
PoolScope scope(context.pool);
std::size_t required = 0;
const auto encode = [&](unsigned char* output, std::size_t capacity, std::size_t* written) {
return mbedtls_pem_write_buffer("-----BEGIN CERTIFICATE-----\n", "-----END CERTIFICATE-----\n", crt->raw.p, crt->raw.len, output, capacity, written);
};
const int sizing = encode(nullptr, 0, &required);
if (sizing != MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL) CheckBackend(sizing, "SSL PEM sizing failed");
if (!buf) {
*bufLen = required;
return 0;
}
if (*bufLen < required) throw std::length_error("SSL PEM buffer is too small");
std::size_t written = 0;
CheckBackend(encode(reinterpret_cast<unsigned char*>(buf), required, &written), "SSL PEM encoding failed");
*bufLen = written;
return 0;
}
+20
View File
@@ -33,6 +33,7 @@ int APS5_VABI sceSslClose(int);
int APS5_VABI sceSslGetNotBefore(int, void*, SceSsl::RtcTick*);
int APS5_VABI sceSslGetNotAfter(int, void*, SceSsl::RtcTick*);
int APS5_VABI sceSslGetFingerprint(int, void*, int, unsigned char*);
int APS5_VABI sceSslGetPem(int, void*, char*, std::size_t*);
}
namespace {
@@ -278,6 +279,23 @@ void CertificateReaders() {
Throws([&] { sceSslGetFingerprint(id, fake, 3, sha256); });
Throws([&] { sceSslGetFingerprint(9999, cert, 3, sha256); });
std::size_t pemLen = 0;
Check(sceSslGetPem(id, cert, nullptr, &pemLen) == 0, "query pem size failed");
Check(pemLen > 0, "pem length is 0");
std::vector<char> pemBuf(pemLen);
std::size_t writtenLen = pemBuf.size();
Check(sceSslGetPem(id, cert, pemBuf.data(), &writtenLen) == 0, "write pem failed");
Check(writtenLen == pemLen, "written pem length mismatch");
Check(std::strstr(pemBuf.data(), "-----BEGIN CERTIFICATE-----\n") != nullptr, "pem header missing");
Check(std::strstr(pemBuf.data(), "-----END CERTIFICATE-----\n") != nullptr, "pem footer missing");
char smallPem[8]{};
std::size_t smallPemLen = sizeof(smallPem);
Throws([&] { sceSslGetPem(id, cert, smallPem, &smallPemLen); });
Check(sceSslGetPem(id, cert, pemBuf.data(), nullptr) == static_cast<int>(0x8095177a), "null pem len accepted");
Throws([&] { sceSslGetPem(id, nullptr, pemBuf.data(), &writtenLen); });
Throws([&] { sceSslGetPem(id, fake, pemBuf.data(), &writtenLen); });
Throws([&] { sceSslClose(1); });
Check(sceSslFreeCaList(id, &handles) == 0, "free ca list failed");
@@ -288,6 +306,7 @@ void CertificateReaders() {
Throws([&] { sceSslGetNotBefore(id, cert, &begin); });
Throws([&] { sceSslGetNotAfter(id, cert, &limit); });
Throws([&] { sceSslGetFingerprint(id, cert, 3, sha256); });
Throws([&] { sceSslGetPem(id, cert, pemBuf.data(), &writtenLen); });
const int id2 = sceSslInit_nid_postfix(1024 * 1024);
Check(sceSslLoadCert(id2, 1, &pointer, nullptr, nullptr) == 0, "CA load failed");
@@ -304,6 +323,7 @@ void CertificateReaders() {
Throws([&] { sceSslGetNotBefore(id2, cert2, &begin); });
Throws([&] { sceSslGetNotAfter(id2, cert2, &limit); });
Throws([&] { sceSslGetFingerprint(id2, cert2, 3, sha256); });
Throws([&] { sceSslGetPem(id2, cert2, pemBuf.data(), &writtenLen); });
Check(sceSslTerm_nid_postfix(id2) == 0, "term failed");
Throws([&] { sceSslGetNameEntryCount(id2, subject2); });
Throws([&] { sceSslFreeSslCertName(id2, subject2); });
+1 -1
View File
@@ -55,7 +55,7 @@ void Readers() {
Check(serial == std::array<unsigned char, 5>{0x00, 0x80, 0xa1, 0xa5, 0xa5}, "serial copy changed its bytes or guards");
serial.fill(0xa5);
length = 2;
Throws([&] { sceSslGetSerialNumber(context, certificate, serial.data(), &length); });
Check(sceSslGetSerialNumber(context, certificate, serial.data(), &length) == static_cast<int>(0x8095177a) && length == 3, "short serial buffer did not report its required size");
Check(std::all_of(serial.begin(), serial.end(), [](auto byte) { return byte == 0xa5; }), "short serial buffer was modified");
Throws([&] { sceSslGetSerialNumber(other, certificate, nullptr, &length); });