SSL services: Difference between revisions
No edit summary |
|||
| (10 intermediate revisions by 2 users not shown) | |||
| Line 6: | Line 6: | ||
! Cmd || Name | ! Cmd || Name | ||
|- | |- | ||
| 0 || CreateContext | | 0 || [[#CreateContext]] | ||
|- | |- | ||
| 1 || GetContextCount | | 1 || GetContextCount | ||
|- | |- | ||
| 2 || GetCertificates | | 2 || [[#GetCertificates]] | ||
|- | |- | ||
| 3 || GetCertificateBufSize | | 3 || [[#GetCertificateBufSize]] | ||
|- | |- | ||
| 4 || [3.0.0+] DebugIoctl | | 4 || [3.0.0+] [[#DebugIoctl]] | ||
|- | |- | ||
| 5 || [3.0.0+] SetInterfaceVersion | | 5 || [3.0.0+] [[#SetInterfaceVersion]] | ||
|- | |- | ||
| 6 || [5.0.0+] FlushSessionCache | | 6 || [5.0.0+] FlushSessionCache | ||
|- | |- | ||
| 7 || [6.0.0+] SetDebugOption | | 7 || [6.0.0+] [[#SetDebugOption]] | ||
|- | |- | ||
| 8 || [6.0.0+] GetDebugOption | | 8 || [6.0.0+] [[#GetDebugOption]] | ||
|} | |} | ||
[3.0.0+] | == 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 == | == ISslContext == | ||
| Line 38: | Line 69: | ||
| 1 || GetOption | | 1 || GetOption | ||
|- | |- | ||
| 2 || CreateConnection | | 2 || [[#CreateConnection]] | ||
|- | |- | ||
| 3 || GetConnectionCount | | 3 || GetConnectionCount | ||
| Line 58: | Line 89: | ||
| 11 || [3.0.0+] RemoveCrl | | 11 || [3.0.0+] RemoveCrl | ||
|} | |} | ||
=== CreateConnection === | |||
No input, returns an [[#ISslConnection]]. | |||
=== ISslConnection === | === ISslConnection === | ||
| Line 70: | Line 104: | ||
| 1 || SetHostName | | 1 || SetHostName | ||
|- | |- | ||
| 2 || SetVerifyOption | | 2 || [[#SetVerifyOption]] | ||
|- | |- | ||
| 3 || SetIoMode | | 3 || SetIoMode | ||
| Line 78: | Line 112: | ||
| 5 || GetHostName | | 5 || GetHostName | ||
|- | |- | ||
| 6 || GetVerifyOption | | 6 || [[#GetVerifyOption]] | ||
|- | |- | ||
| 7 || GetIoMode | | 7 || GetIoMode | ||
| Line 117: | Line 151: | ||
|- | |- | ||
| 25 || [4.0.0+] GetCipherInfo | | 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 = | |||
{| class="wikitable" border="1" | |||
|- | |||
! 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 = | |||
{| class="wikitable" border="1" | |||
|- | |||
! Value | |||
! Description | |||
|- | |||
| -1 | |||
| Invalid | |||
|- | |||
| 1 | |||
| Valid | |||
|} | |||
This is the "nn::ssl::detail::BuiltinDataInfo::BuiltinDataStatus" enum. | |||
= CaCertificateId = | |||
{| class="wikitable" border="1" | |||
|- | |||
! 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: | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset | |||
! Size | |||
! Description | |||
|- | |||
| 0x0 || 0x4 || Magic "sslT" | |||
|- | |||
| 0x4 || 0x4 || Total entries | |||
|- | |||
| 0x8 || 0x10*{total entries} || Array entries | |||
|} | |||
Array entry structure: | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset | |||
! Size | |||
! Description | |||
|- | |||
| 0x0 | |||
| 0x4 | |||
| ID | |||
|- | |||
| 0x4 | |||
| 0x4 | |||
| ? | |||
|- | |||
| 0x8 | |||
| 0x4 | |||
| Data size | |||
|- | |||
| 0xC | |||
| 0x4 | |||
| 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 = | = Client cert+privk = | ||
Revision as of 02:15, 17 September 2019
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 | 0x4 | Data size |
| 0xC | 0x4 | 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.