Files

17 KiB

libSceSsl technical debt

Unknown function info

  • CA_MGMT_extractKeyBlobEx, CA_MGMT_extractPublicKeyInfo, CA_MGMT_freeKeyBlob, CRYPTO_initAsymmetricKey, CRYPTO_uninitAsymmetricKey, RSA_verifySignature, VLONG_freeVlongQueue, sceSslCheckRecvPending, sceSslCreateSslConnection and sceSslDeleteSslConnection (libSceSsl) - the list is the intersection of the export table of the console's libSceSsl (function symbols only), the pinned aerolib names and the functions not yet defined anywhere in the repo. Names and NIDs appear in the PS5 3.20 export inventory and verified NID name database; no credible prototypes were found. They are declared without parameters solely to resolve known imports, not as an ABI claim; callers must not call them until signatures are verified.

  • sceSslDisableOption, sceSslDisableOptionInternal, sceSslDisableOptionInternalInsecure, sceSslEnableOption, sceSslEnableOptionInternal, sceSslGetNanoSSLModuleId, sceSslGetPeerCert, sceSslGetSslError, sceSslLoadRootCACert and sceSslSetSslVersion (libSceSsl) - the list is the intersection of the export table of the console's libSceSsl (function symbols only), the pinned aerolib names and the functions not yet defined anywhere in the repo. Names and NIDs appear in the PS5 3.20 export inventory and verified NID name database; no credible prototypes were found. They are declared without parameters solely to resolve known imports, not as an ABI claim; callers must not call them until signatures are verified.

  • sceSslRecv, sceSslReuseConnection and sceSslSend (libSceSsl) - the list is the intersection of the export table of the console's libSceSsl (function symbols only), the pinned aerolib names and the functions not yet defined anywhere in the repo. Names and NIDs appear in the PS5 3.20 export inventory and verified NID name database. Their parameter shapes follow SharpProspero's pinned bindings, and are not measured on a PS5.

  • sceSslCreateConnection, sceSslDeleteConnection, sceSslSetVerifyCallback, sceSslConnect, sceSslRead, sceSslWrite (libSceSsl) - imported by ffmpeg.prx. Signatures follow SharpProspero, which also says the socket stays open after sceSslDeleteConnection. The behaviour below was measured on a PS5 on system software 13.40 with a ps5-payload-dev payload (every call printed with its return, a TLS 1.2 test server on the LAN presenting leaves issued by the test fixture root loaded with sceSslLoadCert, from an elfldr process rather than a title); what differs for a title process is unknown. An unknown context returns SSL_ERROR_INVALID_ID (0x8095F006) from sceSslCreateConnection, and every connection call on an unknown or deleted connection id or on a connection whose context was terminated returns SSL_ERROR_INVALID_ID. sceSslCreateConnection returns SSL_ERROR_INVALID_VALUE (0x8095F007) for a null host and does not check the socket: sceSslConnect on a descriptor that is not a socket returns SCE_NET_ERROR_EBADF (0x80410109). sceSslConnect runs a TLS 1.2 client handshake with Mbed TLS 3.6.7 over the host socket that the guest number maps to in the libkernel or libSceNet socket table, and sceSslRead and sceSslWrite carry application data over it. TLS 1.3 is compiled out: the console offers TLS 1.2 only (its ClientHello carries 12 suites and no supported_versions extension) and a TLS 1.3-only server gets SSL_ERROR_FATAL_ALERT (0x8095F010) from it, as from this build. Connection state is allocated from the context's pool and returned to it by sceSslDeleteConnection; a connection keeps the pool alive after sceSslTerm, whose connections return SSL_ERROR_INVALID_ID from then on. The console's pool use for one connection with a two-certificate chain peaked at 80,544 bytes in a 256 KiB pool (5,568 after sceSslInit, 12,000 after loading one CA); a 16 KiB pool fails the connect with SSL_ERROR_OUT_OF_MEMORY (0x809517D5) there and here. The server's chain is checked against the CAs loaded with sceSslLoadCert, the host name the connection was created with (case-insensitively; an IP literal sends no SNI and matches an IP subject alternative name; an empty host sends an empty SNI and fails CN_CHECK) and, when enabled, its validity dates, and sceSslConnect returns the first failure the connection's verify options select (the verify option entry below lists the bits, codes and initial options); no root bundle is shipped and the console's built-in roots are unknown, so with no CA loaded a connection with the initial options returns SSL_ERROR_UNKNOWN_CA (0x8095F00C), as on the console. A client certificate loaded with sceSslLoadCert is sent when the server asks for one. A failed verification is final: close_notify is sent, later sceSslConnect calls return the same code (also after the WANT_POLLIN rounds of a non-blocking socket), and sceSslRead and sceSslWrite throw, as the console's codes for them were not measured. With a verify callback set it is called once after the handshake, outside the connection's lock, with the context id, the bits of the enabled checks that failed (KNOWN_CA_CHECK 0x20, CN_CHECK 0x4, the date checks when enabled, 0 when the chain passed), handles to a copy of the peer chain as received (the leaf first, the root last when the server sent it) that the certificate readers of the connection's context accept until the connection is deleted (the handles stay registered in the context until it is terminated; the console frees them at the delete), the chain length and the user argument. A chain fault that no option names (SSL_ERROR_INVALID_CERT without a callback) throws when a callback is set, as the bits the console passes for it were not measured. A non-negative return accepts the connection whatever the bits were; a negative return fails the connect with SSL_ERROR_APPLICATION_VERIFICATION_CALLBACK_CHECK (0x8095F0FD) and the callback runs again, with the same chain, from every later sceSslConnect, sceSslRead and sceSslWrite of the connection, which return 0x8095F0FD while it keeps refusing and proceed once it accepts. A sceSslConnect from inside the callback, or from another thread while it runs, throws. sceSslRead and sceSslWrite before sceSslConnect run the handshake and verification themselves and return its code when it fails. A non-blocking socket that would block returns SSL_ERROR_WANT_POLLIN (0x8095F013) or SSL_ERROR_WANT_POLLOUT (0x8095F014) from sceSslConnect, sceSslRead and sceSslWrite; the next sceSslConnect resumes the handshake, and sceSslWrite returns the part it sent before blocking (the console returned 32 KiB of a 64 KiB write). A blocking libSceNet socket whose SO_RCVTIMEO expires returns SSL_ERROR_WANT_POLLIN as well, and the call can be repeated; SSL_ERROR_READ_TIMEOUT (0x80951710) is never returned. libkernel keeps its timeouts above the host socket, so they do not bound SSL reads and writes on a libkernel socket. sceSslRead with flags 0 reads until len bytes arrived or the stream ended and with flags 1 or 2 returns what the first record delivers. Native flags 3 peek without consuming data; values outside 0 through 3 return SSL_ERROR_INVALID_VALUE before connection lookup. A non-blocking read that got some bytes returns them. It returns 0 after the server's close_notify and after a transport that ends without one, every later read 0 again, and SSL_ERROR_EOF (0x8095177C) and SSL_ERROR_SOCKET_CLOSED (0x8095170D) never from a read. A reset (ECONNRESET, EPIPE, WSAECONNRESET, WSAECONNABORTED, WSAENETRESET) returns SCE_NET_ERROR_ECONNRESET (0x80410136) from sceSslRead and SCE_NET_ERROR_EPIPE (0x80410120) from sceSslWrite, on every later call too; a record that fails its MAC returns 0x80951D55 from sceSslRead after the fatal alert goes out. sceSslWrite accepts flags 0 only, SSL_ERROR_INVALID_VALUE otherwise, sends all of len, capped at INT_MAX, and returns the count; it keeps writing after the peer's close_notify or a stream that ended without one, as the console does. A fatal alert during the handshake returns SSL_ERROR_FATAL_ALERT and ends the transport: later sceSslConnect calls return 0, sceSslRead 0 and sceSslWrite SSL_ERROR_SOCKET_CLOSED, as measured. A transport that ends without close_notify or a reset during the handshake returns SSL_ERROR_SOCKET_CLOSED, the session is dropped and the next sceSslConnect starts over; those two handshake cases and SSL_ERROR_INVALID_CERT (0x8095F00A) for a verification failure no option names were not measured. Other handshake and socket failures, a read or write after a failed verification, a write after sceSslClose, a null buffer and a read or write from inside the callback throw, as their console codes are unknown. A connection serializes its reads and writes, so a read blocked in one thread holds back a write on the same connection from another. sceSslDeleteConnection sends no close_notify and returns SSL_ERROR_INVALID_ID when repeated. sceSslTerm leaves the context's connections to sceSslDeleteConnection, which then returns SSL_ERROR_INVALID_ID; a second sceSslTerm returns SSL_ERROR_INVALID_ID and sceSslInit with a pool size of 0 returns SCE_KERNEL_ERROR_EINVAL (0x80020016). sceSslSetVerifyCallback accepts any callback, null included, and returns 0. The console's first sceSslConnect in a process took 23.8 s before its ClientHello left, a one-time initialisation not emulated. SSL_ERROR_BEFORE_INIT (0x8095F001) is never returned, as the library keeps no state apart from its contexts

  • sceSslClose (libSceSsl) - takes the connection id, as in SharpProspero. Measured on 13.40 as the connection entry describes: it sends close_notify once if the handshake completed and returns 0, 0 again when repeated and 0 on a connection that never connected, already failed verification or lost its transport to a fatal alert; a close before the handshake changes nothing, so the connection can still connect. After the close sceSslConnect returns 0 and sceSslRead 0, as on the console; sceSslWrite after it throws, as the console's code was not measured. A close_notify that a non-blocking socket cannot take at once returns SSL_ERROR_WANT_POLLOUT (0x8095F014) and the close can be repeated; after a reset it returns SCE_NET_ERROR_ECONNRESET (0x80410136) every time. The socket is left to the title; an unknown connection returns SSL_ERROR_INVALID_ID (0x8095F006). Whether the console closes the socket is unknown

  • Certificate readers: foreign and expired certificate/name handles throw instead of following native unchecked pointers. Name views track certificate lifetime and preserve identity; the native no-op name release is implemented. View storage remains allocated until context destruction. Numeric names for attributes Mbed TLS cannot identify may differ from native names. Fingerprint stack-space validation and backend digest failures are not reproduced. Signatures, valid-context/null-argument precedence, serial truncation, name copy bounds, validity timestamps and supported hash selectors are confirmed by the supplied module.

  • sceSslLoadCert, sceSslGetCaList, sceSslFreeCaList, sceSslGetCaCerts, sceSslFreeCaCerts, sceSslUnloadCert (libSceSsl) - signatures and layouts follow SharpProspero. PPSA15508/01.002.000 calls sceSslLoadCert with one 1,408-byte PEM CA and null client certificate/key arguments; this confirms that call shape, not console error behavior. Mbed TLS parses DER/PEM chains. CA imports still commit together instead of preserving successful entries before a later failure. Client certificate replacement clears the previous identity; raw private keys load independently and are parsed when configuring TLS. Partial client chains on decode failure, native key parse errors and incomplete identities during TLS setup remain unsupported. CA queries return independently owned snapshots; unload clears active credentials while outstanding snapshots remain valid. Appending repeated CA imports, snapshot lifetime across unload, memory overhead and error precedence have not been measured on a PS5. Invalid loads, malformed material, exhausted pools and unsupported keys throw rather than inventing console error codes. Native CA queries include built-in roots; the host still queries loaded authorities and returns NOT_FOUND for an empty context. No native root bundle is copied. Null-output and invalid-context precedence, output preservation on invalid contexts and the SDK 7.50 unload error boundary are recovered. Legacy clearing of foreign raw CA lists remains unchanged. Certificate reader queries reflect active certificates or outstanding snapshots. Loading credentials does not start a TLS connection; sceSslConnect verifies the server against the loaded CAs and offers the loaded client certificate

  • sceSslEnableVerifyOption, sceSslDisableVerifyOption, sceSslSetMinSslVersion, sceSslSetAlpn, sceSslGetAlpnSelected (libSceSsl) - signatures follow SharpProspero, the source of the other connection signatures; the behaviour was measured on a PS5 on system software 13.40 with a ps5-payload-dev payload (every call printed with its return, a TLS 1.2 test server on the LAN presenting leaves issued by the test fixture root loaded with sceSslLoadCert, from an elfldr process rather than a title). The verify options select which verification failures sceSslConnect reports (see the connection entry above), with the bit values SharpProspero's SceSslVerifyOption gives: SERVER_VERIFY 0x1, CN_CHECK 0x4, NOT_AFTER_CHECK 0x8, NOT_BEFORE_CHECK 0x10, KNOWN_CA_CHECK 0x20. The initial options are SERVER_VERIFY, CN_CHECK and KNOWN_CA_CHECK (0x25): the console accepted an expired and a not-yet-valid server certificate until 0x8 or 0x10 was enabled, which then returned SSL_ERROR_NOT_AFTER_CHECK (0x8095F00D) and SSL_ERROR_NOT_BEFORE_CHECK (0x8095F00E); whether 0x2 (CLIENT_VERIFY) starts enabled was not determined and it is kept off. A check that is disabled is not reported, whatever the chain. Bits outside 0x3F return SSL_ERROR_INVALID_VALUE (0x8095F007) from both calls. Disabling 0x1, 0x4 or 0x20 from the payload stopped its process through the kernel's debug exception path (mDBG: Sending signal ... signo: 0xa0020101, 6 of 6 attempts; disabling 0x2, 0x8 and 0x10 returned 0), so whether a title may clear them is unknown; this build clears them, as titles import the call. sceSslSetMinSslVersion accepts the SceSslVersion values 2 (SSL 3.0) to 5 (TLS 1.2) and returns SSL_ERROR_INVALID_VALUE for 0, 1 and anything above 5; the console has no TLS 1.3 value. Every accepted value gives the same handshake, as Mbed TLS 3 speaks TLS 1.2 and nothing older and TLS 1.3 is compiled out, which matches the console offering TLS 1.2 only. sceSslSetAlpn stores the string up to its terminator, split on commas into the protocols offered in the handshake (the console sent h2,http/1.1 as the two names and a wire-format string as one name), a second call replaces the list, an empty string returns SSL_ERROR_BAD_LENGTH (0x80951773), and a null list clears the configured protocols. Native inspection confirms that replacement clears the old list even on failure, that each comma-separated name must contain 1-255 bytes and that the whole string must be shorter than 65535 bytes. sceSslGetAlpnSelected returns the protocol the server selected, still after sceSslClose, or null before the handshake and when none was selected; the pointer is owned by the connection. An unknown connection and a connection whose context was terminated return SSL_ERROR_INVALID_ID (0x8095F006) from the four setters and null from sceSslGetAlpnSelected, as confirmed by the supplied native module

  • sceSslGetPem: native argument validation, CRLF line endings, 64-character Base64 lines, NUL-inclusive length and buffer clearing on insufficient capacity are recovered. Foreign and expired certificate handles throw instead of performing native unchecked pointer access. DER reserialization differences for noncanonical certificates remain unverified.