mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-11-04 13:07:32 +00:00
Merge pull request #13760 from hyvvs/feat/libressl-general-name-free
feat(libSceLibreSsl): free GENERAL_NAME and GENERAL_NAMES allocations
This commit is contained in:
6 files changed
+471
-12
No files matched your search
@@ -106,6 +106,17 @@ if(BUILD_TESTING)
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libSceLibreSsl>")
|
||||
endif()
|
||||
|
||||
add_test_executable(guest_libressl_general_name_tests ${LIBS_INCLUDE_DIR}/tests/GuestLibreSslGeneralName.cpp)
|
||||
target_include_directories(guest_libressl_general_name_tests PRIVATE ${LIBS_INCLUDE_DIR})
|
||||
target_link_libraries(guest_libressl_general_name_tests PRIVATE libSceLibreSsl libc)
|
||||
configure_windows_unwind(guest_libressl_general_name_tests)
|
||||
add_test(NAME guest_libressl_general_name COMMAND guest_libressl_general_name_tests)
|
||||
set_tests_properties(guest_libressl_general_name PROPERTIES TIMEOUT 30)
|
||||
if(WIN32)
|
||||
set_tests_properties(guest_libressl_general_name PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libSceLibreSsl>")
|
||||
endif()
|
||||
|
||||
add_test_executable(guest_libressl_ui_tests ${LIBS_INCLUDE_DIR}/tests/GuestLibreSslUi.cpp)
|
||||
target_include_directories(guest_libressl_ui_tests PRIVATE ${LIBS_INCLUDE_DIR})
|
||||
target_link_libraries(guest_libressl_ui_tests PRIVATE libSceLibreSsl libc)
|
||||
@@ -253,6 +264,7 @@ if(BUILD_TESTING)
|
||||
endif()
|
||||
|
||||
target_sources(libSceLibreSsl PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/X509VerifyParam.cpp)
|
||||
target_sources(libSceLibreSsl PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/GeneralName.cpp)
|
||||
|
||||
if(BUILD_TESTING)
|
||||
add_test_executable(guest_libressl_x509_verify_param_tests ${CMAKE_CURRENT_SOURCE_DIR}/tests/X509VerifyParam.cpp)
|
||||
|
||||
@@ -719,16 +719,6 @@ int APS5_VABI EVP_sha512_nid_postfix(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI GENERAL_NAMES_free_nid_postfix(void) {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI GENERAL_NAME_free_nid_postfix(void) {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI HMAC_nid_postfix(void) {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
|
||||
@@ -9,6 +9,11 @@ struct Asn1String {
|
||||
std::int64_t flags;
|
||||
};
|
||||
|
||||
struct LibreSslGeneralName {
|
||||
std::int32_t type;
|
||||
void* value;
|
||||
};
|
||||
|
||||
struct LibreSslX509VerifyParamId {
|
||||
void* hosts;
|
||||
std::uint32_t hostFlags;
|
||||
@@ -395,8 +400,8 @@ int APS5_VABI EVP_md5_nid_postfix(void);
|
||||
int APS5_VABI EVP_sha256_nid_postfix(void);
|
||||
int APS5_VABI EVP_sha384_nid_postfix(void);
|
||||
int APS5_VABI EVP_sha512_nid_postfix(void);
|
||||
int APS5_VABI GENERAL_NAMES_free_nid_postfix(void);
|
||||
int APS5_VABI GENERAL_NAME_free_nid_postfix(void);
|
||||
void APS5_VABI GENERAL_NAMES_free_nid_postfix(LibreSslStack* names);
|
||||
void APS5_VABI GENERAL_NAME_free_nid_postfix(LibreSslGeneralName* name);
|
||||
int APS5_VABI HMAC_nid_postfix(void);
|
||||
int APS5_VABI HMAC_CTX_cleanup_nid_postfix(void);
|
||||
int APS5_VABI HMAC_CTX_init_nid_postfix(void);
|
||||
|
||||
@@ -0,0 +1,185 @@
|
||||
#include "prx/libSceLibreSsl/include/Api.hpp"
|
||||
#include "prx/libc/include/Api.hpp"
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <stdexcept>
|
||||
|
||||
static_assert(sizeof(LibreSslGeneralName) == 16);
|
||||
static_assert(offsetof(LibreSslGeneralName, value) == 8);
|
||||
static_assert(sizeof(Asn1String) == 24);
|
||||
static_assert(sizeof(LibreSslAsn1Object) == 40);
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr std::int64_t Asn1StringNdef = 0x10;
|
||||
constexpr int Asn1Boolean = 1;
|
||||
constexpr int Asn1Null = 5;
|
||||
constexpr int Asn1Object = 6;
|
||||
constexpr int Asn1Any = -4;
|
||||
constexpr int DynamicObject = 0x01;
|
||||
constexpr int DynamicStrings = 0x04;
|
||||
constexpr int DynamicData = 0x08;
|
||||
|
||||
struct Asn1Type {
|
||||
int type;
|
||||
void* value;
|
||||
};
|
||||
|
||||
struct OtherName {
|
||||
LibreSslAsn1Object* typeId;
|
||||
Asn1Type* value;
|
||||
};
|
||||
|
||||
struct EdiPartyName {
|
||||
Asn1String* nameAssigner;
|
||||
Asn1String* partyName;
|
||||
};
|
||||
|
||||
struct Buffer {
|
||||
std::size_t length;
|
||||
char* data;
|
||||
std::size_t capacity;
|
||||
};
|
||||
|
||||
struct X509NameEntry {
|
||||
LibreSslAsn1Object* object;
|
||||
Asn1String* value;
|
||||
int set;
|
||||
int size;
|
||||
};
|
||||
|
||||
struct X509Name {
|
||||
LibreSslStack* entries;
|
||||
int modified;
|
||||
Buffer* bytes;
|
||||
unsigned char* canonical;
|
||||
int canonicalLength;
|
||||
};
|
||||
|
||||
static_assert(sizeof(Asn1Type) == 16 && offsetof(Asn1Type, value) == 8);
|
||||
static_assert(sizeof(OtherName) == 16 && sizeof(EdiPartyName) == 16);
|
||||
static_assert(sizeof(Buffer) == 24 && offsetof(Buffer, capacity) == 16);
|
||||
static_assert(sizeof(X509NameEntry) == 24 && offsetof(X509NameEntry, set) == 16);
|
||||
static_assert(sizeof(X509Name) == 40 && offsetof(X509Name, bytes) == 16);
|
||||
static_assert(offsetof(X509Name, canonical) == 24);
|
||||
|
||||
void Wipe(void* pointer, std::size_t size) {
|
||||
auto* bytes = static_cast<volatile unsigned char*>(pointer);
|
||||
for (std::size_t i = 0; i < size; ++i) bytes[i] = 0;
|
||||
}
|
||||
|
||||
void FreeString(Asn1String* string) {
|
||||
if (!string) return;
|
||||
if (string->data && !(string->flags & Asn1StringNdef)) {
|
||||
if (string->length < 0) throw std::invalid_argument("ASN1_STRING_free: negative length");
|
||||
Wipe(string->data, static_cast<std::size_t>(string->length));
|
||||
free_nid_postfix(string->data);
|
||||
}
|
||||
free_nid_postfix(string);
|
||||
}
|
||||
|
||||
void FreeObject(LibreSslAsn1Object* object) {
|
||||
if (!object) return;
|
||||
if (object->flags & DynamicStrings) {
|
||||
free_nid_postfix(const_cast<char*>(object->shortName));
|
||||
free_nid_postfix(const_cast<char*>(object->longName));
|
||||
object->shortName = nullptr;
|
||||
object->longName = nullptr;
|
||||
}
|
||||
if (object->flags & DynamicData) {
|
||||
if (object->data) {
|
||||
if (object->length < 0) throw std::invalid_argument("ASN1_OBJECT_free: negative length");
|
||||
Wipe(const_cast<unsigned char*>(object->data), static_cast<std::size_t>(object->length));
|
||||
}
|
||||
free_nid_postfix(const_cast<unsigned char*>(object->data));
|
||||
object->data = nullptr;
|
||||
object->length = 0;
|
||||
}
|
||||
if (object->flags & DynamicObject) free_nid_postfix(object);
|
||||
}
|
||||
|
||||
void FreeAny(Asn1Type* any) {
|
||||
if (!any) return;
|
||||
if (any->value) {
|
||||
if (any->type == Asn1Object) FreeObject(static_cast<LibreSslAsn1Object*>(any->value));
|
||||
else if (any->type == Asn1Any) FreeAny(static_cast<Asn1Type*>(any->value));
|
||||
else if (any->type != Asn1Boolean && any->type != Asn1Null) FreeString(static_cast<Asn1String*>(any->value));
|
||||
}
|
||||
free_nid_postfix(any);
|
||||
}
|
||||
|
||||
void FreeBuffer(Buffer* buffer) {
|
||||
if (!buffer) return;
|
||||
if (buffer->data) {
|
||||
Wipe(buffer->data, buffer->capacity);
|
||||
free_nid_postfix(buffer->data);
|
||||
}
|
||||
free_nid_postfix(buffer);
|
||||
}
|
||||
|
||||
void FreeX509Name(X509Name* name) {
|
||||
if (!name) return;
|
||||
FreeBuffer(name->bytes);
|
||||
sk_pop_free_nid_postfix(name->entries, +[](void* pointer) APS5_VABI {
|
||||
auto* entry = static_cast<X509NameEntry*>(pointer);
|
||||
if (!entry) return;
|
||||
|
||||
FreeString(entry->value);
|
||||
FreeObject(entry->object);
|
||||
free_nid_postfix(entry);
|
||||
});
|
||||
free_nid_postfix(name->canonical);
|
||||
free_nid_postfix(name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
void APS5_VABI GENERAL_NAME_free_nid_postfix(LibreSslGeneralName* name) {
|
||||
if (!name) return;
|
||||
switch (name->type) {
|
||||
case 0: {
|
||||
auto* other = static_cast<OtherName*>(name->value);
|
||||
if (other) {
|
||||
FreeAny(other->value);
|
||||
FreeObject(other->typeId);
|
||||
free_nid_postfix(other);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 6:
|
||||
case 7:
|
||||
FreeString(static_cast<Asn1String*>(name->value));
|
||||
break;
|
||||
case 4:
|
||||
FreeX509Name(static_cast<X509Name*>(name->value));
|
||||
break;
|
||||
case 5: {
|
||||
auto* edi = static_cast<EdiPartyName*>(name->value);
|
||||
if (edi) {
|
||||
FreeString(edi->partyName);
|
||||
FreeString(edi->nameAssigner);
|
||||
free_nid_postfix(edi);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 8:
|
||||
FreeObject(static_cast<LibreSslAsn1Object*>(name->value));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
free_nid_postfix(name);
|
||||
}
|
||||
|
||||
void APS5_VABI GENERAL_NAMES_free_nid_postfix(LibreSslStack* names) {
|
||||
sk_pop_free_nid_postfix(names, +[](void* pointer) APS5_VABI {
|
||||
GENERAL_NAME_free_nid_postfix(static_cast<LibreSslGeneralName*>(pointer));
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,266 @@
|
||||
#include "prx/libSceLibreSsl/include/Api.hpp"
|
||||
#include "prx/libc/include/Api.hpp"
|
||||
#include "prx/libc/include/ApplicationHeap.hpp"
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <source_location>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
using FreeName = void (APS5_VABI*)(LibreSslGeneralName*);
|
||||
using FreeNames = void (APS5_VABI*)(LibreSslStack*);
|
||||
static_assert(std::is_same_v<decltype(&GENERAL_NAME_free_nid_postfix), FreeName>);
|
||||
static_assert(std::is_same_v<decltype(&GENERAL_NAMES_free_nid_postfix), FreeNames>);
|
||||
static_assert(sizeof(LibreSslGeneralName) == 16);
|
||||
|
||||
namespace {
|
||||
|
||||
void Require(bool success, std::source_location where = std::source_location::current()) {
|
||||
if (success) return;
|
||||
std::fprintf(stderr, "GENERAL_NAME free test failed at line %u\n", where.line());
|
||||
std::abort();
|
||||
}
|
||||
|
||||
std::unordered_map<void*, std::size_t> live;
|
||||
std::unordered_map<void*, std::size_t> wipes;
|
||||
std::vector<void*> freed;
|
||||
|
||||
void* APS5_VABI Allocate(std::size_t bytes) {
|
||||
void* pointer = std::malloc(bytes);
|
||||
if (pointer) live.emplace(pointer, bytes);
|
||||
return pointer;
|
||||
}
|
||||
|
||||
void APS5_VABI Free(void* pointer) {
|
||||
if (!pointer) return;
|
||||
Require(live.erase(pointer) == 1);
|
||||
const auto it = wipes.find(pointer);
|
||||
if (it != wipes.end()) {
|
||||
const auto* bytes = static_cast<const unsigned char*>(pointer);
|
||||
for (std::size_t i = 0; i < it->second; ++i) Require(bytes[i] == 0);
|
||||
wipes.erase(it);
|
||||
}
|
||||
freed.push_back(pointer);
|
||||
std::free(pointer);
|
||||
}
|
||||
|
||||
void* APS5_VABI NoCalloc(std::size_t, std::size_t) { throw std::runtime_error("unexpected calloc"); }
|
||||
void* APS5_VABI NoRealloc(void*, std::size_t) { throw std::runtime_error("unexpected realloc"); }
|
||||
void* APS5_VABI NoAlign(std::size_t, std::size_t) { throw std::runtime_error("unexpected align"); }
|
||||
void* APS5_VABI NoRealign(void*, std::size_t, std::size_t) { throw std::runtime_error("unexpected realign"); }
|
||||
int APS5_VABI NoPosixAlign(void**, std::size_t, std::size_t) { throw std::runtime_error("unexpected posix_memalign"); }
|
||||
|
||||
void InitializeHeap() {
|
||||
void* const api[10] {reinterpret_cast<void*>(Allocate), reinterpret_cast<void*>(Free),
|
||||
reinterpret_cast<void*>(NoCalloc), reinterpret_cast<void*>(NoRealloc),
|
||||
reinterpret_cast<void*>(NoAlign), reinterpret_cast<void*>(NoRealign),
|
||||
reinterpret_cast<void*>(NoPosixAlign)};
|
||||
ApplicationHeapRegister_nid_no_patch(api);
|
||||
}
|
||||
|
||||
template<typename T> T* New() {
|
||||
auto* pointer = static_cast<T*>(malloc_nid_postfix(sizeof(T)));
|
||||
Require(pointer != nullptr);
|
||||
std::memset(pointer, 0, sizeof(T));
|
||||
return pointer;
|
||||
}
|
||||
|
||||
unsigned char* Bytes(std::size_t size, std::size_t wipeLength = 0) {
|
||||
auto* pointer = static_cast<unsigned char*>(malloc_nid_postfix(size));
|
||||
Require(pointer != nullptr);
|
||||
std::memset(pointer, 0xa5, size);
|
||||
if (wipeLength) wipes.emplace(pointer, wipeLength);
|
||||
return pointer;
|
||||
}
|
||||
|
||||
Asn1String* String(int size = 7, int flags = 0) {
|
||||
auto* result = New<Asn1String>();
|
||||
result->length = size;
|
||||
result->type = 22;
|
||||
result->flags = flags;
|
||||
if (size > 0 && !(flags & 0x10)) result->data = Bytes(static_cast<std::size_t>(size), static_cast<std::size_t>(size));
|
||||
return result;
|
||||
}
|
||||
|
||||
LibreSslAsn1Object* Object(int flags = 0x0d) {
|
||||
auto* object = New<LibreSslAsn1Object>();
|
||||
object->flags = flags;
|
||||
if (flags & 0x04) {
|
||||
object->shortName = reinterpret_cast<char*>(Bytes(6));
|
||||
object->longName = reinterpret_cast<char*>(Bytes(9));
|
||||
}
|
||||
if (flags & 0x08) {
|
||||
object->length = 5;
|
||||
object->data = Bytes(5, 5);
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
LibreSslGeneralName* Name(int type, void* value) {
|
||||
auto* result = New<LibreSslGeneralName>();
|
||||
result->type = type;
|
||||
result->value = value;
|
||||
return result;
|
||||
}
|
||||
|
||||
struct Any { int type; void* value; };
|
||||
struct Other { LibreSslAsn1Object* typeId; Any* value; };
|
||||
struct Edi { Asn1String* assigner; Asn1String* party; };
|
||||
struct Buffer { std::size_t length; char* data; std::size_t capacity; };
|
||||
struct NameEntry { LibreSslAsn1Object* object; Asn1String* value; int set; int size; };
|
||||
struct X509Name { LibreSslStack* entries; int modified; Buffer* bytes; unsigned char* canonical; int canonicalLength; };
|
||||
|
||||
static_assert(sizeof(Any) == 16 && sizeof(Other) == 16 && sizeof(Edi) == 16);
|
||||
static_assert(sizeof(Buffer) == 24 && sizeof(NameEntry) == 24 && sizeof(X509Name) == 40);
|
||||
|
||||
LibreSslStack* Stack(const std::vector<void*>& elements) {
|
||||
auto* stack = New<LibreSslStack>();
|
||||
stack->num = static_cast<int>(elements.size());
|
||||
stack->numAlloc = stack->num;
|
||||
stack->data = reinterpret_cast<char**>(malloc_nid_postfix(sizeof(void*) * (elements.size() ? elements.size() : 1)));
|
||||
Require(stack->data != nullptr);
|
||||
for (std::size_t i = 0; i < elements.size(); ++i) stack->data[i] = static_cast<char*>(elements[i]);
|
||||
return stack;
|
||||
}
|
||||
|
||||
void CheckClean() {
|
||||
Require(live.empty());
|
||||
Require(wipes.empty());
|
||||
}
|
||||
|
||||
void TestSimpleNames() {
|
||||
GENERAL_NAME_free_nid_postfix(nullptr);
|
||||
GENERAL_NAMES_free_nid_postfix(nullptr);
|
||||
for (int choice : {1, 2, 3, 6, 7}) {
|
||||
GENERAL_NAME_free_nid_postfix(Name(choice, String()));
|
||||
CheckClean();
|
||||
}
|
||||
auto* string = String(0);
|
||||
GENERAL_NAME_free_nid_postfix(Name(1, string));
|
||||
CheckClean();
|
||||
|
||||
std::array<unsigned char, 6> borrowed{1, 2, 3, 4, 5, 6};
|
||||
string = String(0, 0x10);
|
||||
string->length = static_cast<int>(borrowed.size());
|
||||
string->data = borrowed.data();
|
||||
GENERAL_NAME_free_nid_postfix(Name(2, string));
|
||||
Require(borrowed == (std::array<unsigned char, 6>{1, 2, 3, 4, 5, 6}));
|
||||
CheckClean();
|
||||
}
|
||||
|
||||
void TestOtherName() {
|
||||
for (int type : {1, 5, 6, 12, -4}) {
|
||||
auto* other = New<Other>();
|
||||
other->typeId = Object();
|
||||
other->value = New<Any>();
|
||||
other->value->type = type;
|
||||
if (type == 6) other->value->value = Object(0x09);
|
||||
if (type == 12) other->value->value = String();
|
||||
if (type == -4) {
|
||||
auto* nested = New<Any>();
|
||||
nested->type = 12;
|
||||
nested->value = String();
|
||||
other->value->value = nested;
|
||||
}
|
||||
GENERAL_NAME_free_nid_postfix(Name(0, other));
|
||||
CheckClean();
|
||||
}
|
||||
|
||||
auto* other = New<Other>();
|
||||
static LibreSslAsn1Object staticOid{};
|
||||
other->typeId = &staticOid;
|
||||
GENERAL_NAME_free_nid_postfix(Name(0, other));
|
||||
CheckClean();
|
||||
}
|
||||
|
||||
void TestEdiPartyName() {
|
||||
auto* edi = New<Edi>();
|
||||
edi->assigner = String();
|
||||
edi->party = String();
|
||||
GENERAL_NAME_free_nid_postfix(Name(5, edi));
|
||||
CheckClean();
|
||||
edi = New<Edi>();
|
||||
edi->party = String();
|
||||
GENERAL_NAME_free_nid_postfix(Name(5, edi));
|
||||
CheckClean();
|
||||
}
|
||||
|
||||
void TestDirectoryName() {
|
||||
auto* name = New<X509Name>();
|
||||
auto* buffer = New<Buffer>();
|
||||
buffer->capacity = 16;
|
||||
buffer->length = 4;
|
||||
buffer->data = reinterpret_cast<char*>(Bytes(16, 16));
|
||||
name->bytes = buffer;
|
||||
auto* entry = New<NameEntry>();
|
||||
entry->object = Object();
|
||||
entry->value = String();
|
||||
auto* another = New<NameEntry>();
|
||||
another->object = Object(0x01);
|
||||
another->value = String();
|
||||
name->entries = Stack({entry, nullptr, another});
|
||||
name->canonical = Bytes(12);
|
||||
name->canonicalLength = 12;
|
||||
GENERAL_NAME_free_nid_postfix(Name(4, name));
|
||||
CheckClean();
|
||||
}
|
||||
|
||||
void TestOidAndStack() {
|
||||
GENERAL_NAME_free_nid_postfix(Name(8, Object()));
|
||||
CheckClean();
|
||||
|
||||
static LibreSslAsn1Object staticOid{};
|
||||
staticOid.length = 5;
|
||||
staticOid.flags = 0x08;
|
||||
staticOid.data = Bytes(5, 5);
|
||||
GENERAL_NAME_free_nid_postfix(Name(8, &staticOid));
|
||||
Require(staticOid.data == nullptr);
|
||||
Require(staticOid.length == 0);
|
||||
GENERAL_NAME_free_nid_postfix(Name(8, &staticOid));
|
||||
CheckClean();
|
||||
|
||||
static LibreSslAsn1Object staticNamedOid{};
|
||||
staticNamedOid.flags = 0x0c;
|
||||
staticNamedOid.shortName = reinterpret_cast<char*>(Bytes(6));
|
||||
staticNamedOid.longName = reinterpret_cast<char*>(Bytes(9));
|
||||
staticNamedOid.length = 7;
|
||||
staticNamedOid.data = Bytes(7, 7);
|
||||
GENERAL_NAME_free_nid_postfix(Name(8, &staticNamedOid));
|
||||
Require(staticNamedOid.shortName == nullptr);
|
||||
Require(staticNamedOid.longName == nullptr);
|
||||
Require(staticNamedOid.data == nullptr);
|
||||
Require(staticNamedOid.length == 0);
|
||||
GENERAL_NAME_free_nid_postfix(Name(8, &staticNamedOid));
|
||||
CheckClean();
|
||||
|
||||
auto* first = Name(1, String());
|
||||
auto* last = Name(7, String());
|
||||
freed.clear();
|
||||
GENERAL_NAMES_free_nid_postfix(Stack({first, nullptr, last}));
|
||||
CheckClean();
|
||||
Require(freed.size() >= 8);
|
||||
GENERAL_NAMES_free_nid_postfix(Stack({}));
|
||||
CheckClean();
|
||||
|
||||
auto* unusual = Name(42, nullptr);
|
||||
GENERAL_NAME_free_nid_postfix(unusual);
|
||||
CheckClean();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main() {
|
||||
InitializeHeap();
|
||||
TestSimpleNames();
|
||||
TestOtherName();
|
||||
TestEdiPartyName();
|
||||
TestDirectoryName();
|
||||
TestOidAndStack();
|
||||
std::puts("libSceLibreSsl GENERAL_NAME tests passed");
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
- [SSL_select_next_proto](../../../core/libs/prx/libSceLibreSsl/src/ProtocolSelection.cpp) (libSceLibreSsl) follows LibreSSL 3.4.1 [`ssl_lib.c`](https://github.com/libressl/openbsd/blob/d7513e7d4daf94905fd4cb0a5e5c89109d2874f7/src/lib/libssl/ssl_lib.c), which validates neither list: a zero-length entry is negotiated, no overlap returns `supported + 1` with the unchecked length byte `supported[0]`, read even for an empty supported list, and each pair of entries with equal length bytes is compared over that many bytes, past the end of a truncated list. [Firmware 13.42 host-PC evidence](https://github.com/boykopovar/AnyPS5/pull/9785#issuecomment-6406712390) of `libSceLibreSsl.sprx` (`0xda6d0`) reports the same status, pointer and length for 700,000 valid pairs and for the six unvalidated cases. Null outputs, a null supported list and a null peer list with a non-zero length throw, where the module faults; nothing is measured on a console.
|
||||
- [SHA384_Init and SHA512_Init](../../../core/libs/prx/libSceLibreSsl/src/Digest.cpp) (libSceLibreSsl) - clear the 128-byte block buffer of the context, which LibreSSL 2.5.4 leaves as it was; digests are unaffected. `guest_libressl_oracle` (`ANYPS5_LIBRESSL_ORACLE`) compares the rest of the context with LibreSSL 2.5.4
|
||||
- [GENERAL_NAME_free and GENERAL_NAMES_free](../../../core/libs/prx/libSceLibreSsl/src/GeneralName.cpp) (libSceLibreSsl) - release all nine GENERAL_NAME choices and STACK_OF(GENERAL_NAME) using the guest allocator, following [LibreSSL 2.5.4 `v3_genn.c`](https://github.com/libressl/openbsd/blob/2e2c612066aa993717528a0249c15c51128d61cb/src/lib/libcrypto/x509v3/v3_genn.c) and its [ASN.1 free dispatcher](https://github.com/libressl/openbsd/blob/2e2c612066aa993717528a0249c15c51128d61cb/src/lib/libcrypto/asn1/tasn_fre.c). ASN1_STRING and dynamically allocated OID contents are wiped before freeing; NDEF strings and static OIDs retain their borrowed memory. Nested X509_NAME entries and cached data are freed as in 2.5.4. Guest allocator tests check owned/borrowed memory and disposal of nested allocations. PS5 native module behavior and malformed-memory failure cases are not verified; negative owned data lengths throw rather than risk out-of-bounds memory erasure.
|
||||
|
||||
### Unknown function info
|
||||
|
||||
|
||||
Reference in new issue
Block a user