SSL services
ssl
This is "nn::ssl::sf::ISslService".
| Cmd | Name | 
|---|---|
| 0 | #CreateContext | 
| 1 | GetContextCount | 
| 2 | #GetCertificates | 
| 3 | #GetCertificateBufSize | 
| 4 | [3.0.0+] #DebugIoctl | 
| 5 | [3.0.0+] #SetInterfaceVersion | 
| 6 | [5.0.0+] FlushSessionCache | 
| 7 | [6.0.0+] #SetDebugOption | 
| 8 | [6.0.0+] #GetDebugOption | 
CreateContext
Takes a PID, an input u32 #SslVersion, an input u64 pid_placeholder, and returns an output #ISslContext.
GetCertificates
Takes a type-0x6 output buffer and a type-0x5 input buffer containing an array of #CaCertificateId.
[3.0.0+] This now returns an output u32 for actual total output entries.
The output buffer starts with an array of #BuiltInCertificateInfo, with the DER cert data following afterwards.
GetCertificateBufSize
Takes a type-0x5 input buffer containing an array of #CaCertificateId, returns an output u32 for the size to use with #GetCertificates.
DebugIoctl
Stubbed on retail, just returns an error.
SetInterfaceVersion
Takes an input u32 version, no output.
Used by user-processes during service init.
SetDebugOption
Takes an input u32 DebugOptionType and a type-0x5 input buffer, no output.
The input u32 value must be 0, and the buffer addr/size must not be 0.
The u8 at buf+0 is copied to state.
GetDebugOption
Takes an input u32 DebugOptionType and a type-0x6 output buffer.
Same as #SetDebugOption except this copies state to the buffer instead.
ISslContext
This is "nn::ssl::sf::ISslContext".
| Cmd | Name | 
|---|---|
| 0 | SetOption | 
| 1 | GetOption | 
| 2 | #CreateConnection | 
| 3 | GetConnectionCount | 
| 4 | ImportServerPki | 
| 5 | ImportClientPki | 
| 6 | RemoveServerPki | 
| 7 | RemoveClientPki | 
| 8 | RegisterInternalPki | 
| 9 | AddPolicyOid | 
| 10 | [3.0.0+] ImportCrl | 
| 11 | [3.0.0+] RemoveCrl | 
CreateConnection
No input, returns an #ISslConnection.
ISslConnection
This is "nn::ssl::sf::ISslConnection".
| Cmd | Name | 
|---|---|
| 0 | SetSocketDescriptor | 
| 1 | SetHostName | 
| 2 | #SetVerifyOption | 
| 3 | SetIoMode | 
| 4 | GetSocketDescriptor | 
| 5 | GetHostName | 
| 6 | #GetVerifyOption | 
| 7 | GetIoMode | 
| 8 | DoHandshake | 
| 9 | DoHandshakeGetServerCert | 
| 10 | Read | 
| 11 | Write | 
| 12 | Pending | 
| 13 | Peek | 
| 14 | Poll | 
| 15 | GetVerifyCertError | 
| 16 | GetNeededServerCertBufferSize | 
| 17 | SetSessionCacheMode | 
| 18 | GetSessionCacheMode | 
| 19 | FlushSessionCache | 
| 20 | SetRenegotiationMode | 
| 21 | GetRenegotiationMode | 
| 22 | SetOption | 
| 23 | GetOption | 
| 24 | GetVerifyCertErrors | 
| 25 | [4.0.0+] GetCipherInfo | 
| 26 | [9.0.0+] SetNextAlpnProto | 
| 27 | [9.0.0+] GetNextAlpnProto | 
SetVerifyOption
Takes an input u32 #VerifyOption, no output.
Originally ssl-sysmodule just wrote the input field to state. With newer sysvers there's now validation for the input.
GetVerifyOption
No input, returns an output u32 #VerifyOption.
SslVersion
This is the "nn::ssl::sf::SslVersion" enum.
BuiltInCertificateInfo
| Offset | Size | Description | 
|---|---|---|
| 0x0 | 0x4 | #CaCertificateId | 
| 0x4 | 0x4 | #BuiltinDataStatus | 
| 0x8 | 0x8 | Data size | 
| 0x10 | 0x8 | Data offset | 
This is the struct returned by #GetCertificates. Official sw converts this to "nn::ssl::BuiltInManager::BuiltInCertificateInfo" with offset converted to a ptr.
BuiltinDataStatus
| Value | Description | 
|---|---|
| -1 | Invalid | 
| 1 | Valid | 
This is the "nn::ssl::detail::BuiltinDataInfo::BuiltinDataStatus" enum.
CaCertificateId
| Value | Description | 
|---|---|
| 1 | Nintendo {...} | 
| 2 | Nintendo {...} | 
This is the "nn::ssl::CaCertificateId" enum.
VerifyOption
This is the "nn::ssl::sf::VerifyOption" enum.
CertStore
This is the CertStore title, which contains the following files in RomFS:
- "/ssl_CaFingerprints.bdf"
- "/ssl_Crl.bdf"
- "/ssl_TrustedCerts.bdf"
On old system-versions, this only contains "/ssl_TrustedCerts.tcf", which seems to have the same format described below.
These have the following structure:
| Offset | Size | Description | 
|---|---|---|
| 0x0 | 0x4 | Magic "sslT" | 
| 0x4 | 0x4 | Total entries | 
| 0x8 | 0x10*{total entries} | Array entries | 
Array entry structure:
| Offset | Size | Description | 
|---|---|---|
| 0x0 | 0x4 | ID | 
| 0x4 | 0x4 | ? | 
| 0x8 | 0x8 | Data size | 
| 0x10 | 0x8 | Data offset | 
Data offset is relative to absolute offset 0x8.
The ID is the same one used by service commands to access these entries. For ssl_TrustedCerts, ID is #CaCertificateId.
Client cert+privk
SSL-sysmodule uses set:cal GetSslKey and GetSslCert. The rest of this section documents handling for the former, which can be decrypted with SPL.
key* below refers to the 3 0x10-byte input blocks passed to this code.
When actual_size is:
- 0x100+0x10: If the u32 actual_size is less than (u32)-0x11, and the last 0x10-bytes of the actual-data are all-zero, the data is copied to the output as raw plaintext. If a non-zero byte is found, it will continue with SPL usage, skipping over the SPL block for the devunit flag. In this case, key=key0 and the flag passed to SPL later is set to 0.
- 0x100+0x30: Size must match this if it's not the above, otherwise error 0xC81A is returned. The flag passed to SPL later is set to 1 in this case. Runs the devunit-flag-block: uses SPL_services#SPL#GetDevunitFlag. key = key1 when out_flag!=0, key2 otherwise.