Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions core/libs/prx/libSceLibreSsl3/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ if(WIN32)
target_sources(libSceLibreSsl3 PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/ParentExports.cpp)
endif()
target_sources(libSceLibreSsl3 PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/PkeyGetters.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/PkeyLifecycle.cpp)
target_sources(libSceLibreSsl3 PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/Asn1Free.cpp)
target_sources(libSceLibreSsl3 PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/Time.cpp)

if(BUILD_TESTING)
Expand Down Expand Up @@ -105,6 +106,16 @@ if(BUILD_TESTING)
configure_windows_unwind(guest_libressl3_asn1_tests)
add_test(NAME guest_libressl3_asn1 COMMAND guest_libressl3_asn1_tests)
set_tests_properties(guest_libressl3_asn1 PROPERTIES TIMEOUT 30)
add_test_executable(guest_libressl3_asn1_free_tests ${CMAKE_CURRENT_SOURCE_DIR}/tests/Asn1Free.cpp)
target_include_directories(guest_libressl3_asn1_free_tests PRIVATE ${LIBS_INCLUDE_DIR})
target_link_libraries(guest_libressl3_asn1_free_tests PRIVATE libSceLibreSsl3)
configure_windows_unwind(guest_libressl3_asn1_free_tests)
add_test(NAME guest_libressl3_asn1_free COMMAND guest_libressl3_asn1_free_tests)
set_tests_properties(guest_libressl3_asn1_free PROPERTIES TIMEOUT 20)
if(WIN32)
set_tests_properties(guest_libressl3_asn1_free PROPERTIES ENVIRONMENT_MODIFICATION
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libSceLibreSsl3>")
endif()
add_test_executable(guest_libressl3_x509_verify_param_tests ${CMAKE_CURRENT_SOURCE_DIR}/tests/X509VerifyParam.cpp)
target_include_directories(guest_libressl3_x509_verify_param_tests PRIVATE ${LIBS_INCLUDE_DIR})
target_link_libraries(guest_libressl3_x509_verify_param_tests PRIVATE libSceLibreSsl3)
Expand Down
15 changes: 0 additions & 15 deletions core/libs/prx/libSceLibreSsl3/Export.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,11 +134,6 @@ int APS5_VABI OBJ_txt2obj_nid_postfix(void) {
return 0;
}

int APS5_VABI OCSP_CERTID_free_nid_postfix(void) {
NotImplemented_nid_no_patch(__func__);
return 0;
}

int APS5_VABI OCSP_cert_to_id_nid_postfix(void) {
NotImplemented_nid_no_patch(__func__);
return 0;
Expand Down Expand Up @@ -166,16 +161,6 @@ int APS5_VABI PEM_read_RSAPrivateKey_nid_disambig1_nid_postfix(void) {
return 0;
}

int APS5_VABI PKCS7_free_nid_postfix(void) {
NotImplemented_nid_no_patch(__func__);
return 0;
}

int APS5_VABI PKCS8_PRIV_KEY_INFO_free_nid_postfix(void) {
NotImplemented_nid_no_patch(__func__);
return 0;
}

int APS5_VABI RSA_check_key_nid_postfix(void) {
NotImplemented_nid_no_patch(__func__);
return 0;
Expand Down
6 changes: 3 additions & 3 deletions core/libs/prx/libSceLibreSsl3/include/Api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,13 +164,13 @@ const LibreSsl3::DigestMethod* APS5_VABI EVP_sha1_nid_postfix();
const LibreSsl3::DigestMethod* APS5_VABI EVP_sha224_nid_postfix();
int APS5_VABI OBJ_cmp_nid_postfix(const void* first, const void* second);
int APS5_VABI OBJ_txt2obj_nid_postfix(void);
int APS5_VABI OCSP_CERTID_free_nid_postfix(void);
void APS5_VABI OCSP_CERTID_free_nid_postfix(void* id);
int APS5_VABI OCSP_cert_to_id_nid_postfix(void);
int APS5_VABI OCSP_resp_find_status_nid_postfix(void);
const char* APS5_VABI OpenSSL_version_nid_postfix(int type);
int APS5_VABI PEM_read_RSAPrivateKey_nid_disambig1_nid_postfix(void);
int APS5_VABI PKCS7_free_nid_postfix(void);
int APS5_VABI PKCS8_PRIV_KEY_INFO_free_nid_postfix(void);
void APS5_VABI PKCS7_free_nid_postfix(void* pkcs7);
void APS5_VABI PKCS8_PRIV_KEY_INFO_free_nid_postfix(void* info);
int APS5_VABI RSA_check_key_nid_postfix(void);
void APS5_VABI RSA_get0_key_nid_postfix(const LibreSsl3Rsa* rsa, const void** n, const void** e, const void** d);
int APS5_VABI RSA_new_nid_disambig1_nid_postfix(void);
Expand Down
21 changes: 21 additions & 0 deletions core/libs/prx/libSceLibreSsl3/src/Asn1Free.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#include "prx/libSceLibreSsl3/include/Api.hpp"
#include "prx/libc/include/General.hpp"

extern "C" {

void APS5_VABI OCSP_CERTID_free_nid_postfix(void* id) {
if (!id) return;
NotImplemented_nid_no_patch(__func__);
}

void APS5_VABI PKCS7_free_nid_postfix(void* pkcs7) {
if (!pkcs7) return;
NotImplemented_nid_no_patch(__func__);
}

void APS5_VABI PKCS8_PRIV_KEY_INFO_free_nid_postfix(void* info) {
if (!info) return;
NotImplemented_nid_no_patch(__func__);
}

}
54 changes: 54 additions & 0 deletions core/libs/prx/libSceLibreSsl3/tests/Asn1Free.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#include "prx/libSceLibreSsl3/include/Api.hpp"

#include <cstdio>
#include <cstdlib>
#include <source_location>
#include <stdexcept>

namespace {

void Require(bool condition, std::source_location location = std::source_location::current()) {
if (condition) return;
std::fprintf(stderr, "LibreSSL3 ASN1 free check failed at line %u\n", location.line());
std::abort();
}

void TestOcspCertidFreeNull() {
bool threw = false;
try {
OCSP_CERTID_free_nid_postfix(nullptr);
} catch (const std::exception&) {
threw = true;
}
Require(!threw);
}

void TestPkcs7FreeNull() {
bool threw = false;
try {
PKCS7_free_nid_postfix(nullptr);
} catch (const std::exception&) {
threw = true;
}
Require(!threw);
}

void TestPkcs8PrivKeyInfoFreeNull() {
bool threw = false;
try {
PKCS8_PRIV_KEY_INFO_free_nid_postfix(nullptr);
} catch (const std::exception&) {
threw = true;
}
Require(!threw);
}

}

int main() {
TestOcspCertidFreeNull();
TestPkcs7FreeNull();
TestPkcs8PrivKeyInfoFreeNull();
std::puts("libSceLibreSsl3 ASN1 free tests passed");
return EXIT_SUCCESS;
}
4 changes: 3 additions & 1 deletion docs/dev/debt/libSceLibreSsl3.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
- [`X509_PUBKEY_get0_param`](../../../core/libs/prx/libSceLibreSsl3/src/X509PubkeyParam.cpp) follows LibreSSL 4.0.0 `crypto/asn1/x_pubkey.c` at [`ce488b78e0bd994780569df718596b9776ff681a`](https://github.com/libressl/openbsd/blob/ce488b78e0bd994780569df718596b9776ff681a/src/lib/libcrypto/asn1/x_pubkey.c) and its `x509_local.h`, `x509.h` and `asn1.h` layouts. The function returns borrowed pointers and writes the encoded key length only when the key output is requested. The PS5 layout and malformed-object behavior are not verified on hardware; layout assertions match the pinned x86-64 source declarations.
### Functional

- [PKCS7_free, PKCS8_PRIV_KEY_INFO_free and OCSP_CERTID_free](../../../core/libs/prx/libSceLibreSsl3/src/Asn1Free.cpp) (libSceLibreSsl3) - only NULL is handled: it returns without action, as LibreSSL 4.0.0 [`ASN1_item_free`](https://github.com/libressl/openbsd/blob/ce488b78e0bd994780569df718596b9776ff681a/src/lib/libcrypto/asn1/tasn_fre.c) does. A non-null object throws, since this module has no constructor for these types. Not measured on a PS5.

- [OpenSSL_version](../../../core/libs/prx/libSceLibreSsl3/Export.cpp) - other firmware revisions are unverified. Selectors 0 through 5 follow the public firmware 13.40 measurements in [discussion #8981](https://github.com/boykopovar/AnyPS5/discussions/8981#discussioncomment-19111214); unknown selectors follow LibreSSL 4.0.0 and return `not available`. No independent console test was run.

- [ERR_load_crypto_strings and ERR_peek_last_error](../../../core/libs/prx/libSceLibreSsl3/Export.cpp) have no console execution verification. [Firmware 13.42 modules run on a PC](https://github.com/boykopovar/AnyPS5/pull/9535#issuecomment-6407060914) retained numeric-only output after loaders and matched queue order/overflow; whether the two firmware modules share a queue was not tested. This implementation reads libSceLibreSsl's calling-thread queue. `ERR_print_errors_cb` remains throwing because guest thread identifiers and diagnostic metadata are unverified.
Expand All @@ -12,7 +14,7 @@

- [EVP_PKEY_new, EVP_PKEY_free, EVP_PKEY_set1_RSA, EVP_PKEY_copy_parameters](../../../core/libs/prx/libSceLibreSsl3/src/PkeyLifecycle.cpp) - not checked on a console. Native allocation and release follow the 32-byte [LibreSSL 4.0.0 layout and p_lib.c](https://github.com/libressl/openbsd/tree/ce488b78e0bd994780569df718596b9776ff681a/src/lib/libcrypto/evp). Allocation failure returns null without its allocation error. Final release of a nonnull method or payload throws and restores the reference instead of calling the method; no native payload destruction is implemented. Empty objects are cleared before release. set1_RSA and copy_parameters throw locally instead of forwarding to the incompatible 56-byte legacy layout. The native RSA producers and get1_RSA remain local throwing stubs. Objects from the two modules must not be mixed.
- [Native PKEY forwarding gaps](../../../core/libs/prx/libSceLibreSsl3/ParentExports.cpp) - `X509_get_pubkey` and `PEM_read_bio_PrivateKey` still forward to legacy throwing stubs. `SSL_get_privatekey` forwards to the parent library and returns its legacy PKEY. The consumers `EVP_PKEY_get1_EC_KEY`, `EVP_DigestVerifyInit`, `SSL_CTX_use_PrivateKey`, `SSL_CTX_use_PrivateKey_ASN1`, `SSL_CTX_use_PrivateKey_file` and `SSL_use_PrivateKey_ASN1` do too. Each needs a native wrapper before its legacy implementation can run, to prevent mixing the incompatible PKEY layouts.
- [libSceLibreSsl3 pending exports](../../../core/libs/prx/libSceLibreSsl3/Export.cpp) - 45 named callable exports, excluding `ASN1_OBJECT_free`, `CRYPTO_memcmp`, `MD5`, `SHA1`, `d2i_ASN1_INTEGER`, `EVP_PKEY_up_ref`, `EC_KEY_up_ref`, `RSA_up_ref`, `SSL_CTX_up_ref`, `SSL_up_ref`, `SSL_SESSION_up_ref`, `SSL_CTX_set_min_proto_version`, `SSL_CTX_set_max_proto_version`, `SSL_get_client_random`, `X509_up_ref`, `X509_get_version`, `EVP_PKEY_get0_RSA`, `EVP_PKEY_get0_DSA`, `EVP_PKEY_get0_DH`, `EVP_MD_CTX_new`, `EVP_MD_CTX_free`, `EVP_DigestInit`, `EVP_sha1`, `EVP_sha224`, `ERR_load_crypto_strings`, `ERR_peek_last_error`, `OpenSSL_version`, `X509_PUBKEY_get0_param`, `OBJ_cmp`, `ASN1_STRING_get0_data`, `ASN1_INTEGER_free`, `X509_get0_extensions`, `X509_get_ext_count`, `X509_get_ext`, `EVP_PKEY_size`, `X509_getm_notBefore`, `X509_getm_notAfter`, `X509_get0_notBefore`, `X509_get0_notAfter`, `X509_get0_signature`, `RSA_get0_key`, `DH_get0_pqg`, `DH_get0_key`, `DSA_get0_pqg`, `DSA_get0_key` and `BIO_up_ref`, remain unimplemented from the [PS5 3.20 export table](https://github.com/DNNDHH/PS5-3.20_Libs/blob/b2a77c09cd71c01f34c790cfbe98c751a13262ad/libSceLibreSsl3.c), cross-checked against the same module in PS5 firmware 13.60. Their signatures and behaviour are unverified; the declarations use the no-parameter unknown-signature convention and throw through `NotImplemented_nid_no_patch`.
- [libSceLibreSsl3 pending exports](../../../core/libs/prx/libSceLibreSsl3/Export.cpp) - 42 named callable exports, excluding `ASN1_OBJECT_free`, `CRYPTO_memcmp`, `MD5`, `SHA1`, `d2i_ASN1_INTEGER`, `EVP_PKEY_up_ref`, `EC_KEY_up_ref`, `RSA_up_ref`, `SSL_CTX_up_ref`, `SSL_up_ref`, `SSL_SESSION_up_ref`, `SSL_CTX_set_min_proto_version`, `SSL_CTX_set_max_proto_version`, `SSL_get_client_random`, `X509_up_ref`, `X509_get_version`, `EVP_PKEY_get0_RSA`, `EVP_PKEY_get0_DSA`, `EVP_PKEY_get0_DH`, `EVP_MD_CTX_new`, `EVP_MD_CTX_free`, `EVP_DigestInit`, `EVP_sha1`, `EVP_sha224`, `ERR_load_crypto_strings`, `ERR_peek_last_error`, `OpenSSL_version`, `X509_PUBKEY_get0_param`, `OBJ_cmp`, `ASN1_STRING_get0_data`, `ASN1_INTEGER_free`, `X509_get0_extensions`, `X509_get_ext_count`, `X509_get_ext`, `EVP_PKEY_size`, `X509_getm_notBefore`, `X509_getm_notAfter`, `X509_get0_notBefore`, `X509_get0_notAfter`, `X509_get0_signature`, `RSA_get0_key`, `DH_get0_pqg`, `DH_get0_key`, `DSA_get0_pqg`, `DSA_get0_key`, `BIO_up_ref`, `PKCS7_free`, `PKCS8_PRIV_KEY_INFO_free` and `OCSP_CERTID_free`, remain unimplemented from the [PS5 3.20 export table](https://github.com/DNNDHH/PS5-3.20_Libs/blob/b2a77c09cd71c01f34c790cfbe98c751a13262ad/libSceLibreSsl3.c), cross-checked against the same module in PS5 firmware 13.60. Their signatures and behaviour are unverified; the declarations use the no-parameter unknown-signature convention and throw through `NotImplemented_nid_no_patch`.

Check warning on line 17 in docs/dev/debt/libSceLibreSsl3.md

View workflow job for this annotation

GitHub Actions / conventions

debt-length

Technical debt entry over 1000 characters: state the gap first (what differs from the console, what is unverified, what throws) and keep only the behaviour it needs: 1455 characters

### Functional

Expand Down
Loading