mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-22 16:43:05 -05:00
Every unverified point of the libSceSsl debt entry was measured on a PS5 on system software 13.40 with a ps5-payload-dev payload against a TLS 1.2 test server presenting leaves issued by the test fixture root. The code follows the console where it differed: initial verify options 0x25 with the date checks off, bits outside 0x3F rejected, the verify callback called with the context id and the bitmask of failed checks and re-run from every later call after a negative return, sceSslRead flags 0 reading until the requested length, streams that end without close_notify reading as 0, resets reported with the libSceNet codes, receive timeouts as SSL_ERROR_WANT_POLLIN, a fatal alert ending the transport, sceSslClose as a repeatable no-op before the handshake, read and write before connect running the handshake, SSL_ERROR_INVALID_ID for unknown or deleted handles and terminated contexts, sceSslSetMinSslVersion accepting 2 to 5, an empty ALPN list rejected, long attribute names from sceSslGetNameEntryInfo and sceSslGetSerialNumber leaving the caller's length. The debt entries record the measured values and what stays unmeasured.
16 KiB
16 KiB
libSceSsl technical debt
Unknown function info
- sceSslCreateConnection, sceSslDeleteConnection, sceSslSetVerifyCallback, sceSslConnect, sceSslRead, sceSslWrite (libSceSsl) - imported by
ffmpeg.prx. Signatures follow SharpProspero, which also says the socket stays open aftersceSslDeleteConnection. 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 withsceSslLoadCert, from an elfldr process rather than a title); what differs for a title process is unknown. An unknown context returnsSSL_ERROR_INVALID_ID(0x8095F006) fromsceSslCreateConnection, and every connection call on an unknown or deleted connection id or on a connection whose context was terminated returnsSSL_ERROR_INVALID_ID.sceSslCreateConnectionreturnsSSL_ERROR_INVALID_VALUE(0x8095F007) for a null host and does not check the socket:sceSslConnecton a descriptor that is not a socket returnsSCE_NET_ERROR_EBADF(0x80410109).sceSslConnectruns 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, andsceSslReadandsceSslWritecarry 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 getsSSL_ERROR_FATAL_ALERT(0x8095F010) from it, as from this build. Connection state is allocated from the context's pool and returned to it bysceSslDeleteConnection; a connection keeps the pool alive aftersceSslTerm, whose connections returnSSL_ERROR_INVALID_IDfrom 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 aftersceSslInit, 12,000 after loading one CA); a 16 KiB pool fails the connect withSSL_ERROR_OUT_OF_MEMORY(0x809517D5) there and here. The server's chain is checked against the CAs loaded withsceSslLoadCert, 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 failsCN_CHECK) and, when enabled, its validity dates, andsceSslConnectreturns 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 returnsSSL_ERROR_UNKNOWN_CA(0x8095F00C), as on the console. A client certificate loaded withsceSslLoadCertis sent when the server asks for one. A failed verification is final: close_notify is sent, latersceSslConnectcalls return the same code (also after theWANT_POLLINrounds of a non-blocking socket), andsceSslReadandsceSslWritethrow, 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_CHECK0x20,CN_CHECK0x4, 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_CERTwithout 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 withSSL_ERROR_APPLICATION_VERIFICATION_CALLBACK_CHECK(0x8095F0FD) and the callback runs again, with the same chain, from every latersceSslConnect,sceSslReadandsceSslWriteof the connection, which return 0x8095F0FD while it keeps refusing and proceed once it accepts. AsceSslConnectfrom inside the callback, or from another thread while it runs, throws.sceSslReadandsceSslWritebeforesceSslConnectrun the handshake and verification themselves and return its code when it fails. A non-blocking socket that would block returnsSSL_ERROR_WANT_POLLIN(0x8095F013) orSSL_ERROR_WANT_POLLOUT(0x8095F014) fromsceSslConnect,sceSslReadandsceSslWrite; the nextsceSslConnectresumes the handshake, andsceSslWritereturns the part it sent before blocking (the console returned 32 KiB of a 64 KiB write). A blocking libSceNet socket whoseSO_RCVTIMEOexpires returnsSSL_ERROR_WANT_POLLINas 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.sceSslReadwith flags 0 reads untillenbytes arrived or the stream ended and with any other flags (MsgFlagPartialRead1 measured, 2 behaved the same) returns what the first record delivers; 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, andSSL_ERROR_EOF(0x8095177C) andSSL_ERROR_SOCKET_CLOSED(0x8095170D) never from a read. A reset (ECONNRESET,EPIPE,WSAECONNRESET,WSAECONNABORTED,WSAENETRESET) returnsSCE_NET_ERROR_ECONNRESET(0x80410136) fromsceSslReadandSCE_NET_ERROR_EPIPE(0x80410120) fromsceSslWrite, on every later call too; a record that fails its MAC returns 0x80951D55 fromsceSslReadafter the fatal alert goes out.sceSslWriteaccepts flags 0 only,SSL_ERROR_INVALID_VALUEotherwise, sends all oflen, capped atINT_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 returnsSSL_ERROR_FATAL_ALERTand ends the transport: latersceSslConnectcalls return 0,sceSslRead0 andsceSslWriteSSL_ERROR_SOCKET_CLOSED, as measured. A transport that ends without close_notify or a reset during the handshake returnsSSL_ERROR_SOCKET_CLOSED, the session is dropped and the nextsceSslConnectstarts over; those two handshake cases andSSL_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 aftersceSslClose, 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.sceSslDeleteConnectionsends no close_notify and returnsSSL_ERROR_INVALID_IDwhen repeated.sceSslTermleaves the context's connections tosceSslDeleteConnection, which then returnsSSL_ERROR_INVALID_ID; a secondsceSslTermreturnsSSL_ERROR_INVALID_IDandsceSslInitwith a pool size of 0 returnsSCE_KERNEL_ERROR_EINVAL(0x80020016).sceSslSetVerifyCallbackaccepts any callback, null included, and returns 0. The console's firstsceSslConnectin 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
sceSslConnectreturns 0 andsceSslRead0, as on the console;sceSslWriteafter it throws, as the console's code was not measured. A close_notify that a non-blocking socket cannot take at once returnsSSL_ERROR_WANT_POLLOUT(0x8095F014) and the close can be repeated; after a reset it returnsSCE_NET_ERROR_ECONNRESET(0x80410136) every time. The socket is left to the title; an unknown connection returnsSSL_ERROR_INVALID_ID(0x8095F006). Whether the console closes the socket is unknown - sceSslGetSerialNumber, sceSslGetSubjectName, sceSslGetIssuerName, sceSslGetNameEntryCount, sceSslGetNameEntryInfo, sceSslFreeSslCertName, sceSslGetNotBefore, sceSslGetNotAfter, sceSslGetFingerprint (libSceSsl) - signatures and context ownership follow SharpProspero, with hash types matching its
SceSslFingerprintHashAlgorithmenum. Operations take a context handle as their first argument and operate on certificate and name handles scoped to that context.sceSslGetSerialNumbercopies into a caller-allocated output buffer or queries the required length when the buffer is null or capacity is zero; a buffer smaller than the serial number returnsSSL_ERROR_INVALID_ARG(0x8095177a). Mbed TLS parses the certificate's serial number, validity period (converted to microseconds since Gregorian year 0001 epoch), fingerprint digests and X.509 subject and issuer distinguished names, writing the attribute long names the console writes (commonName,organizationName,countryName, measured on 13.40 through the verify callback's chain handles; numeric strings for attributes Mbed TLS cannot name) and value strings withvalueLenset to the value's length. An unknown context, unknown or expired certificate handle or invalid certificate name handle throws; null output pointers, unsupported hash types or out-of-range entry indices returnSSL_ERROR_INVALID_ARG(0x8095177a).sceSslGetSerialNumberwith a buffer large enough leaves*sboLenas the caller set it, as measured on 13.40 with a 32-byte buffer. The error codes, the zero-capacity length query, the NUL-terminated truncation of name entry strings, and the lifetime of name handles (released only bysceSslFreeSslCertNameor when the context is terminated) have not been measured on a PS5 - sceSslLoadCert, sceSslGetCaList, sceSslFreeCaList, sceSslGetCaCerts, sceSslFreeCaCerts, sceSslUnloadCert (libSceSsl) - signatures and layouts follow SharpProspero. PPSA15508/01.002.000 calls
sceSslLoadCertwith one 1,408-byte PEM CA and null client certificate/key arguments; this confirms that call shape, not console error behavior. Mbed TLS 3.6.7 parses DER/PEM chains and checks an optional client certificate/key pair. Imports are retained per context and committed together; a failed import preserves existing credentials. 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. No root bundle is shipped; an empty context still returnsNOT_FOUND. The existing null-list error, unknown-context behavior and legacy clearing of foreign raw CA lists remain unchanged. Certificate reader queries reflect active certificates or outstanding snapshots. Loading credentials does not start a TLS connection;sceSslConnectverifies 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 failuressceSslConnectreports (see the connection entry above), with the bit values SharpProspero'sSceSslVerifyOptiongives:SERVER_VERIFY0x1,CN_CHECK0x4,NOT_AFTER_CHECK0x8,NOT_BEFORE_CHECK0x10,KNOWN_CA_CHECK0x20. The initial options areSERVER_VERIFY,CN_CHECKandKNOWN_CA_CHECK(0x25): the console accepted an expired and a not-yet-valid server certificate until 0x8 or 0x10 was enabled, which then returnedSSL_ERROR_NOT_AFTER_CHECK(0x8095F00D) andSSL_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 returnSSL_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.sceSslSetMinSslVersionaccepts theSceSslVersionvalues 2 (SSL 3.0) to 5 (TLS 1.2) and returnsSSL_ERROR_INVALID_VALUEfor 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.sceSslSetAlpnstores the string up to its terminator, split on commas into the protocols offered in the handshake (the console senth2,http/1.1as the two names and a wire-format string as one name), a second call replaces the list, an empty string returnsSSL_ERROR_BAD_LENGTH(0x80951773), and a null list throws (not measured).sceSslGetAlpnSelectedreturns the protocol the server selected, still aftersceSslClose, 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 returnSSL_ERROR_INVALID_ID(0x8095F006) from the four setters and throw fromsceSslGetAlpnSelected, whose console return was not measured - sceSslGetPem (libSceSsl) - static inspection of PPSA28002 confirms the context-first four-argument call with a caller-owned buffer and an in/out 64-bit length. Mbed TLS serializes PEM including its trailing NUL. Buffers smaller than the required encoding throw; an unknown context or foreign or expired certificate handle throws. The exact console PEM length policy, error precedence and truncation behavior have not been measured on a PS5. Existing serial/name, validity and fingerprint readers and their documented uncertainties remain unchanged