SSL services

Revision as of 03:18, 13 April 2020 by Yellows8 (talk | contribs)

ssl

This is "nn::ssl::sf::ISslService". sdknso uses SessionManager with this, where the additional session-count is user-specified (default is 0x2). An error is thrown when the input value is less than 1 or >4.

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.

GetContextCount

No input, returns an output u32.

This is not exposed by sdknso.

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.

Value SystemVersion
0x1 [3.0.0+]
0x2 [5.0.0+]
0x3 [6.0.0+]

FlushSessionCache

Takes a type-0x5 input buffer, an input u32 #FlushSessionCacheOptionType, returns an output u32.

The input buffer contains a NUL-terminated string, which is only used when the type is value 0. For type 1, an empty buffer is passed (addr=NULL/size=0).

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.

The nn::ssl::SetDebugOption func in sdknso just verifies the input and that the service is initialized, without actually using the cmd.

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

SetOption

Takes an input #ContextOption and an input s32, no output.

With #ContextOption value 1, the s32 has to be 0 or 1 (state field is set to the s32 value).

GetOption

Takes an input #ContextOption, returns an output s32.

CreateConnection

No input, returns an #ISslConnection.

GetConnectionCount

No input, returns an output u32.

This is not exposed by sdknso.

ImportServerPki

Takes a type-0x5 input buffer and a #CertificateFormat, returns an output u64.

ImportClientPki

Takes two type-0x5 input buffers, returns an output u64.

RemoveServerPki

Takes an input u64, no output.

RemoveClientPki

Takes an input u64, no output.

RegisterInternalPki

Takes an input #InternalPki, returns an output u64.

AddPolicyOid

Takes a type-0x5 input buffer, no output.

The buffer contains a string. The string length must not match the buffer size, and the string length must be <=0xFE.

ImportCrl

Takes a type-0x5 input buffer, returns an output u64.

RemoveCrl

Takes an input u64, no output.

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

SetSocketDescriptor

Takes an input s32, returns an output s32.

SetHostName

Takes a type-0x5 input buffer, no output.

The input buffer contains a string, the buffer size must be <=0xFF.

SetVerifyOption

Takes an input u32 #VerifyOption, no output.

SetIoMode

Takes an input #IoMode, no output.

GetSocketDescriptor

No input, returns an output s32.

GetHostName

Takes a type-0x6 output buffer, returns an output u32.

GetVerifyOption

No input, returns an output u32 #VerifyOption.

GetIoMode

No input, returns an output #IoMode.

DoHandshake

No input/output.

DoHandshakeGetServerCert

Takes a type-0x6 output buffer, returns two output u32s.

Read

Takes a type-0x6 output buffer, returns an output u32.

Write

Takes a type-0x5 input buffer, returns an output u32.

Pending

No input, returns an output s32.

Peek

Takes a type-0x6 output buffer, returns an output u32.

Poll

Takes an input #PollEvent, an u32, returns an output #PollEvent.

GetVerifyCertError

No input/output.

GetNeededServerCertBufferSize

No input, returns an output u32.

SetSessionCacheMode

Takes an input #SessionCacheMode, no output.

GetSessionCacheMode

No input, returns an output #SessionCacheMode.

FlushSessionCache

No input/output.

SetRenegotiationMode

Takes an input #RenegotiationMode, no output.

GetRenegotiationMode

No input, returns an output #RenegotiationMode.

SetOption

Takes an input u8 bool and an #OptionType, no output.

GetOption

Takes an input #OptionType, returns an output u8 bool.

GetVerifyCertErrors

Takes a type-0x6 output buffer, returns two output u32s.

GetCipherInfo

Takes an input u32 and a type-0x6 output buffer.

sdknso uses hard-coded value 0x1 for the u32. The output buffer contains #CipherInfo.

SetNextAlpnProto

Takes a type-0x5 input buffer, no output.

GetNextAlpnProto

Takes a type-0x6 output buffer, returns an output #AlpnProtoState and an output u32.

SslVersion

This is the "nn::ssl::sf::SslVersion" / "nn::ssl::Context::SslVersion" enum.

FlushSessionCacheOptionType

This is the "nn::ssl::sf::FlushSessionCacheOptionType" / "nn::ssl::FlushSessionCacheOptionType" enum.

Value Description
0
1

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. Note: the above is missing the non-Nintendo certs.

InternalPki

This is the "nn::ssl::sf::InternalPki" / "nn::ssl::Context::InternalPki" enum.

An error is thrown by #RegisterInternalPki when the input value does not match 1.

Value Description
1

ContextOption

This is the "nn::ssl::sf::ContextOption" / "nn::ssl::Context::ContextOption" enum.

Value Description
1

CertificateFormat

This is the "nn::ssl::sf::CertificateFormat" / "nn::ssl::CertificateFormat" enum.

Value Description
1
2

VerifyOption

This is the "nn::ssl::sf::VerifyOption" enum. This is a bitmask.

Originally ssl-sysmodule (#SetVerifyOption) just wrote the input field to state. With newer sysvers there's now validation for the input, with the value written to state masked with 0x3F. When InterfaceVersion is >=0x2, the low 2-bits of VerifyOption must be set, unless {state flag for #OptionType value 2} is set or {bool DebugOption state flag} is set, otherwise an error is thrown. Following that, if VerifyOption bit4 is set, then VerifyOption & 0x15 must match 0x15 otherwise an error is thrown.

Bit Description
0
1
2
3
4
5

IoMode

This is the "nn::ssl::sf::IoMode" / "nn::ssl::Connection::IoMode" enum.

Value Description
1
2

PollEvent

This is the "nn::ssl::sf::PollEvent" / "nn::ssl::Connection::PollEvent" enum.

SessionCacheMode

This is the "nn::ssl::sf::SessionCacheMode" / "nn::ssl::Connection::SessionCacheMode" enum.

RenegotiationMode

This is the "nn::ssl::sf::RenegotiationMode" / "nn::ssl::Connection::RenegotiationMode" enum.

OptionType

This is the "nn::ssl::sf::OptionType" / "nn::ssl::Connection::OptionType" enum.

This corresponds to bool flags.

Value Description
0
1
2 This flag is checked by SetVerifyOption.
3 Only available with SetOption.

AlpnProtoState

This is the "nn::ssl::sf::AlpnProtoState" / "nn::ssl::Connection::AlpnProtoState" enum.

CipherInfo

This is "nn::ssl::Connection::CipherInfo". This is a 0x48-byte struct.

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.