Changes

Line 1: Line 1:  
= ssl =
 
= ssl =
 
This is "nn::ssl::sf::ISslService".
 
This is "nn::ssl::sf::ISslService".
 +
 +
The 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.
 +
 +
This service implements client-mode TLS using [https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS NSS].
 +
 +
Note that SystemPrograms generally use [[#RegisterInternalPki]] (see [[libcurl]]). However, [[Internet_Browser|web-applets]] use [[#GetCertificates]] with [[#CaCertificateId]] All - [[#RegisterInternalPki]] is not used.
 +
 +
This has IPC max_sessions = 0x40.
    
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 6: Line 14:  
! Cmd || Name
 
! Cmd || Name
 
|-
 
|-
| 0 || CreateContext
+
| 0 || [[#CreateContext]]
 
|-
 
|-
| 1 || GetContextCount
+
| 1 || [[#GetContextCount]]
 
|-
 
|-
 
| 2 || [[#GetCertificates]]
 
| 2 || [[#GetCertificates]]
Line 18: Line 26:  
| 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]]
 +
|-
 +
| 9 || [14.0.0+] [[#ClearTls12FallbackFlag]]
 
|}
 
|}
 +
 +
== 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 ==
 
== GetCertificates ==
Line 42: Line 60:     
Used by user-processes during service init.
 
Used by user-processes during service init.
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
! 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 ==
 
== SetDebugOption ==
Takes an input u32 '''DebugOptionType''' and a type-0x5 input buffer, no output.
+
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 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 u8 at buf+0 is copied to state.
 +
 +
The <code>nn::ssl::SetDebugOption</code> func in sdknso just verifies the input and that the service is initialized, without actually using the cmd.
    
== GetDebugOption ==
 
== GetDebugOption ==
Takes an input u32 '''DebugOptionType''' and a type-0x6 output buffer.
+
Takes an input u32 [[#DebugOptionType]] and a type-0x6 output buffer.
    
Same as [[#SetDebugOption]] except this copies state to the buffer instead.
 
Same as [[#SetDebugOption]] except this copies state to the buffer instead.
 +
 +
== ClearTls12FallbackFlag ==
 +
No input/output.
    
== ISslContext ==
 
== ISslContext ==
Line 62: Line 101:  
! Cmd || Name
 
! Cmd || Name
 
|-
 
|-
| 0 || SetOption
+
| 0 || [[#SetOption]]
 +
|-
 +
| 1 || [[#GetOption]]
 +
|-
 +
| 2 || [[#CreateConnection]]
 
|-
 
|-
| 1 || GetOption
+
| 3 || [[#GetConnectionCount]]
 
|-
 
|-
| 2 || CreateConnection
+
| 4 || [[#ImportServerPki]]
 
|-
 
|-
| 3 || GetConnectionCount
+
| 5 || [[#ImportClientPki]]
 
|-
 
|-
| 4 || ImportServerPki
+
| 6 || [[#RemoveServerPki]]
 
|-
 
|-
| 5 || ImportClientPki
+
| 7 || [[#RemoveClientPki]]
 
|-
 
|-
| 6 || RemoveServerPki
+
| 8 || [[#RegisterInternalPki]]
 
|-
 
|-
| 7 || RemoveClientPki
+
| 9 || [[#AddPolicyOid]]
 
|-
 
|-
| 8 || RegisterInternalPki
+
| 10 || [3.0.0+] [[#ImportCrl]]
 
|-
 
|-
| 9 || AddPolicyOid
+
| 11 || [3.0.0+] [[#RemoveCrl]]
 
|-
 
|-
| 10 || [3.0.0+] ImportCrl
+
| 12 || [16.0.0+] [[#ImportClientCertKeyPki]]
 
|-
 
|-
| 11 || [3.0.0+] RemoveCrl
+
| 13 || [16.0.0+] [[#GeneratePrivateKeyAndCert]]
 
|}
 
|}
 +
 +
=== 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).
 +
 +
Prior to 4.x this is stubbed.
 +
 +
=== GetOption ===
 +
Takes an input [[#ContextOption]], returns an output s32.
 +
 +
Prior to 4.x this is stubbed.
 +
 +
=== CreateConnection ===
 +
No input, returns an [[#ISslConnection]].
 +
 +
=== GetConnectionCount ===
 +
No input, returns an output u32.
 +
 +
This is not exposed by sdknso. Immediately prior to closing the [[#ISslContext]] object, sdknso uses this cmd, returning the error from there on failure. An error is also thrown if the output count is non-zero.
 +
 +
=== ImportServerPki ===
 +
Takes a type-0x5 input buffer and a [[#CertificateFormat]], returns an output u64 Id.
 +
 +
The input buffer can contain multiple certs. A maximum of 71 ServerPki objects (associated with the output Id) can be imported.
 +
 +
The certs can be CAs or server certs (no pubkeys).
 +
 +
The [[#CertificateFormat]] only validated, afterwards it's ignored.
 +
 +
=== ImportClientPki ===
 +
Takes two type-0x5 input buffers, returns an output u64 Id.
 +
 +
The first buffer contains the PKCS#12 data, the second buffer contains the optional (addr=NULL/size=0) ASCII password. The password is copied to a heap buffer with size+1, for NUL-termination.
 +
 +
An error is thrown if this cmd or [[#RegisterInternalPki]] was already used previously.
 +
 +
=== RemoveServerPki ===
 +
Takes an input u64 Id, no output.
 +
 +
=== RemoveClientPki ===
 +
Takes an input u64 Id, no output.
 +
 +
=== RegisterInternalPki ===
 +
Takes an input [[#InternalPki]], returns an output u64 Id.
 +
 +
An error is thrown if this cmd or [[#ImportClientPki]] was already used previously.
 +
 +
=== 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 Id.
 +
 +
The input buffer contains the DER CRL.
 +
 +
=== RemoveCrl ===
 +
Takes an input u64 Id, no output.
 +
 +
=== ImportClientCertKeyPki ===
 +
Takes two type-0x5 input buffers and a [[#CertificateFormat]], returns an output u64 Id.
 +
 +
This imports the specified client cert (first inbuf) and key (second inbuf). The [[#CertificateFormat]] controls the format for the cert and key.
 +
 +
=== GeneratePrivateKeyAndCert ===
 +
Takes two type-0x6 output buffers, a type-0x5 input buffer containing a [[#KeyAndCertParams]], and an u32, returns two output u32s.
 +
 +
Official sw passes hard-coded value 1 for the u32. Sysmodule will throw an error if the u32 is not value 1.
 +
 +
The input buffer size must match the size of [[#KeyAndCertParams]] (0x58-bytes).
 +
 +
This generates a self-signed DER cert/key with algo sha256WithRSAEncryption, with the cert expiring in exactly 30 days from the begin-timestamp.
 +
 +
The first outbuf contains the cert, the second outbuf contains the key. The output u32s are the actual output size of the cert and key.
 +
 +
Sample cert:
 +
 +
  Certificate:
 +
    Data:
 +
        Version: 1 (0x0)
 +
        Serial Number: {...}
 +
        Signature Algorithm: sha256WithRSAEncryption
 +
        Issuer: CN = {input}
 +
        Validity
 +
            Not Before: {...}
 +
            Not After : {...}
 +
        Subject: CN = {input}
 +
        Subject Public Key Info:
 +
            Public Key Algorithm: rsaEncryption
 +
                Public-Key: {input bit-size}
 +
                Modulus:
 +
                    {...}
 +
                Exponent: {input}
 +
    Signature Algorithm: sha256WithRSAEncryption
 +
    Signature Value:
 +
        {...}
    
=== ISslConnection ===
 
=== ISslConnection ===
Line 94: Line 235:  
! Cmd || Name
 
! Cmd || Name
 
|-
 
|-
| 0 || SetSocketDescriptor
+
| 0 || [[#SetSocketDescriptor]]
 +
|-
 +
| 1 || [[#SetHostName]]
 
|-
 
|-
| 1 || SetHostName
+
| 2 || [[#SetVerifyOption]]
 
|-
 
|-
| 2 || SetVerifyOption
+
| 3 || [[#SetIoMode]]
 
|-
 
|-
| 3 || SetIoMode
+
| 4 || [[#GetSocketDescriptor]]
 
|-
 
|-
| 4 || GetSocketDescriptor
+
| 5 || [[#GetHostName]]
 
|-
 
|-
| 5 || GetHostName
+
| 6 || [[#GetVerifyOption]]
 
|-
 
|-
| 6 || GetVerifyOption
+
| 7 || [[#GetIoMode]]
 
|-
 
|-
| 7 || GetIoMode
+
| 8 || [[#DoHandshake]]
 
|-
 
|-
| 8 || DoHandshake
+
| 9 || [[#DoHandshakeGetServerCert]]
 
|-
 
|-
| 9 || DoHandshakeGetServerCert
+
| 10 || [[#Read]]
 
|-
 
|-
| 10 || Read
+
| 11 || [[#Write]]
 
|-
 
|-
| 11 || Write
+
| 12 || [[#Pending]]
 
|-
 
|-
| 12 || Pending
+
| 13 || [[#Peek]]
 
|-
 
|-
| 13 || Peek
+
| 14 || [[#Poll]]
 
|-
 
|-
| 14 || Poll
+
| 15 || [[#GetVerifyCertError]]
 
|-
 
|-
| 15 || GetVerifyCertError
+
| 16 || [[#GetNeededServerCertBufferSize]]
 
|-
 
|-
| 16 || GetNeededServerCertBufferSize
+
| 17 || [[#SetSessionCacheMode]]
 
|-
 
|-
| 17 || SetSessionCacheMode
+
| 18 || [[#GetSessionCacheMode]]
 
|-
 
|-
| 18 || GetSessionCacheMode
+
| 19 || [[#FlushSessionCache]]
 
|-
 
|-
| 19 || FlushSessionCache
+
| 20 || [[#SetRenegotiationMode]]
 
|-
 
|-
| 20 || SetRenegotiationMode
+
| 21 || [[#GetRenegotiationMode]]
 
|-
 
|-
| 21 || GetRenegotiationMode
+
| 22 || [[#SetOption_2|SetOption]]
 
|-
 
|-
| 22 || SetOption
+
| 23 || [[#GetOption_2|GetOption]]
 
|-
 
|-
| 23 || GetOption
+
| 24 || [[#GetVerifyCertErrors]]
 
|-
 
|-
| 24 || GetVerifyCertErrors
+
| 25 || [4.0.0+] [[#GetCipherInfo]]
 
|-
 
|-
| 25 || [4.0.0+] GetCipherInfo
+
| 26 || [9.0.0+] [[#SetNextAlpnProto]]
 +
|-
 +
| 27 || [9.0.0+] [[#GetNextAlpnProto]]
 +
|-
 +
| 28 || [16.0.0+] [[#SetDtlsSocketDescriptor]]
 +
|-
 +
| 29 || [16.0.0+] [[#GetDtlsHandshakeTimeout]]
 +
|-
 +
| 30 || [16.0.0+] [[#SetPrivateOption]]
 +
|-
 +
| 31 || [16.0.0+] [[#SetSrtpCiphers]]
 +
|-
 +
| 32 || [16.0.0+] [[#GetSrtpCipher]]
 +
|-
 +
| 33 || [16.0.0+] [[#ExportKeyingMaterial]]
 +
|-
 +
| 34 || [16.0.0+] [[#SetIoTimeout]]
 +
|-
 +
| 35 || [16.0.0+] [[#GetIoTimeout]]
 +
|}
 +
 
 +
==== SetSocketDescriptor ====
 +
Takes an input s32 sockfd, returns an output s32 sockfd.
 +
 
 +
An error is thrown if this was used previously.
 +
 
 +
internal_sockfd = output from [[Sockets_services#DuplicateSocket|DuplicateSocket]], with the input sockfd. If the field which would be used for the input u64 (PID set by [[#CreateContext]]) is zero however, it instead uses internal_sockfd=input_sockfd directly without DuplicateSocket and later returns -1 for the sockfd. An error is thrown if DuplicateSocket fails. The input sockfd is later returned as the output sockfd, however if [[#OptionType|DoNotCloseSocket]] is set it will instead return -1 for the sockfd. Then [[Sockets_services#GetPeerName|GetPeerName]] is used with internal_sockfd, throwing an error if this fails. internal_sockfd is used for state initialization, and the input_sockfd is written into state.
 +
 
 +
Immediately prior to closing the [[#ISslConnection]] object, sdknso will close the sockfd which was returned by this cmd if it is not negative.
 +
 
 +
==== SetHostName ====
 +
Takes a type-0x5 input buffer, no output.
 +
 
 +
The input buffer contains a string, the buffer size must be <=0xFF.
 +
 
 +
The buffer is copied to a tmpbuf, then [[Sockets_services|nsd]] ResolveEx is used with this tmpbuf to set the HostName in state.
 +
 
 +
==== SetVerifyOption ====
 +
Takes an input u32 [[#VerifyOption]], no output.
 +
 
 +
==== SetIoMode ====
 +
Takes an input [[#IoMode]], no output.
 +
 
 +
[[#SetSocketDescriptor]] must have been used prior to this successfully.
 +
 
 +
==== GetSocketDescriptor ====
 +
No input, returns an output s32.
 +
 
 +
[[#SetSocketDescriptor]] must have been used prior to this successfully.
 +
 
 +
This gets the input_sockfd which was previously saved in state by [[#SetSocketDescriptor]].
 +
 
 +
==== GetHostName ====
 +
Takes a type-0x6 output buffer, returns an output u32.
 +
 
 +
The output u32 is the string length (buffer must be large enough for the entire string).
 +
 
 +
==== GetVerifyOption ====
 +
No input, returns an output u32 [[#VerifyOption]].
 +
 
 +
==== GetIoMode ====
 +
No input, returns an output [[#IoMode]].
 +
 
 +
==== DoHandshake ====
 +
No input/output.
 +
 
 +
[[#SetSocketDescriptor]] must have been used prior to this successfully.
 +
 
 +
The [[#SetHostName|hostname]] must be set (non-empty string) when [[#VerifyOption]] HostName is set, otherwise an error is thrown.
 +
 
 +
This will also set a callback eventually for saving an [[Error_Report_services|error-report]] when needed, which just contains the ErrorCode loaded from a Result in state. This sysmodule doesn't save any other reports elsewhere.
 +
 
 +
==== DoHandshakeGetServerCert ====
 +
Takes a type-0x6 output buffer, returns two output u32s.
 +
 
 +
Same as [[#DoHandshake]] except the params for the func called internally are user-specified, instead of all 0.
 +
 
 +
The buffer contains the output server cert DER. The first u32 is the output size, the second u32 is the total certs in the buffer.
 +
 
 +
When [[#OptionType|GetServerCertChain]] is set, the output buffer contains the full chain. This buffer can then be parsed by a seperate sdknso func:
 +
* The header is at +0. +0 must match a magicnum (0x4E4D684374726543 "CertChMN"), and the u32 at +0x4 must be larger than the input cert_index.
 +
* The data at +0x10 is the 0x8-byte array-entries, for each cert. Entry +0x0 is the u32 size, and +0x4 is the u32 offset. These are copied to the output "nn::ssl::Connection::ServerCertDetail" struct, for the entry with the input cert_index: +0 = u32 size, +8 = address (input_buffer+offset).
 +
 
 +
No certs are returned when [[#VerifyOption|PeerCa]] is not set.
 +
 
 +
When [[#IoMode]] is NonBlocking the buffer will be only filled in once - when this cmd returns successfully the buffer will generally be empty.
 +
 
 +
==== Read ====
 +
Takes a type-0x6 output buffer, returns an output u32.
 +
 
 +
[[#SetSocketDescriptor]] must have been used prior to this successfully.
 +
 
 +
The output u32 is the actual transferred size.
 +
 
 +
==== Write ====
 +
Takes a type-0x5 input buffer, returns an output u32.
 +
 
 +
[[#SetSocketDescriptor]] must have been used prior to this successfully.
 +
 
 +
The output u32 is the actual transferred size.
 +
 
 +
==== Pending ====
 +
No input, returns an output s32.
 +
 
 +
[[#SetSocketDescriptor]] must have been used prior to this successfully.
 +
 
 +
==== Peek ====
 +
Takes a type-0x6 output buffer, returns an output u32 size.
 +
 
 +
[[#SetSocketDescriptor]] must have been used prior to this successfully.
 +
 
 +
==== Poll ====
 +
Takes an input [[#PollEvent]], an u32, returns an output [[#PollEvent]].
 +
 
 +
[[#SetSocketDescriptor]] must have been used prior to this successfully.
 +
 
 +
The u32 is the timeout in milliseconds.
 +
 
 +
==== GetVerifyCertError ====
 +
No input/output.
 +
 
 +
This loads a field from state, clears the original value in state, and returns the Result from calling a conversion func with the loaded value.
 +
 
 +
==== GetNeededServerCertBufferSize ====
 +
No input, returns an output u32.
 +
 
 +
This just copies an u32 from state to output and returns 0.
 +
 
 +
==== SetSessionCacheMode ====
 +
Takes an input [[#SessionCacheMode]], no output.
 +
 
 +
[[#SetSocketDescriptor]] must have been used prior to this successfully.
 +
 
 +
==== GetSessionCacheMode ====
 +
No input, returns an output [[#SessionCacheMode]].
 +
 
 +
[[#SetSocketDescriptor]] must have been used prior to this successfully.
 +
 
 +
==== FlushSessionCache ====
 +
No input/output.
 +
 
 +
[[#SetSocketDescriptor]] must have been used prior to this successfully.
 +
 
 +
==== SetRenegotiationMode ====
 +
Takes an input [[#RenegotiationMode]], no output.
 +
 
 +
[[#SetSocketDescriptor]] must have been used prior to this successfully.
 +
 
 +
==== GetRenegotiationMode ====
 +
No input, returns an output [[#RenegotiationMode]].
 +
 
 +
[[#SetSocketDescriptor]] must have been used prior to this successfully.
 +
 
 +
==== 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.
 +
 
 +
On success, sdknso will throw an error if the two output u32s don't match.
 +
 
 +
==== 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]].
 +
 
 +
Errors are thrown if the input u32 doesn't match 0x1, or if the buffer size doesn't match the size for [[#CipherInfo]].
 +
 
 +
[[#SetSocketDescriptor]] must have been used prior to this successfully.
 +
 
 +
==== SetNextAlpnProto ====
 +
Takes a type-0x5 input buffer, no output.
 +
 
 +
[[#SetSocketDescriptor]] must have been used prior to this successfully.
 +
 
 +
The buffer size must be at least 0x2.
 +
 
 +
[[#OptionType|EnableAlpn]] should be set at the time of using DoHandshake*, otherwise using this cmd will have no affect.
 +
 
 +
The buffer contains an array of {u8 size, {data with the specified size}}, which must be within the buffer-size bounds.
 +
 
 +
==== GetNextAlpnProto ====
 +
Takes a type-0x6 output buffer, returns an output [[#AlpnProtoState]] and an output u32.
 +
 
 +
[[#SetSocketDescriptor]] must have been used prior to this successfully.
 +
 
 +
The buffer contains the output string. The u32 is the output string length.
 +
 
 +
The output will be all-zero/empty if not available - such as when this was used before DoHandshake*.
 +
 
 +
==== SetDtlsSocketDescriptor ====
 +
Takes an input s32 sockfd and a type-0x5 input buffer, returns an output s32 sockfd.
 +
 
 +
The input buffer contains a "nn::socket::SockAddr".
 +
 
 +
The input buffer must be at least 0x10-bytes and the byte at buf+0 must match the buffer size, otherwise an error is thrown. Then the same func is called as [[#SetSocketDescriptor]] internally, except this passes the input buffer for the SockAddr, while SetSocketDescriptor passes NULL for SockAddr.
 +
 
 +
==== GetDtlsHandshakeTimeout ====
 +
Takes a type-0x6 output buffer containing a "nn::TimeSpan".
 +
 
 +
The buffer size must be 0x8.
 +
 
 +
==== SetPrivateOption ====
 +
Takes an input bool and an [[#OptionType]], no output.
 +
 
 +
[17.0.0+] Takes an input u32 value and an [[#OptionType]], no output.
 +
 
 +
==== SetSrtpCiphers ====
 +
Takes a type-0x5 input buffer, no output.
 +
 
 +
The buffer must be aligned to 2-bytes. The buffer contains an array of u16s, a maximum of 4 entries is allowed. Each entry must be value 1-2, otherwise the entry is ignored.
 +
 
 +
==== GetSrtpCipher ====
 +
No input, returns an output u16.
 +
 
 +
==== ExportKeyingMaterial ====
 +
Takes a type-0x6 output buffer and two type-0x5 input buffers.
 +
 
 +
The first inbuf contains the label string. The buffer size must match the output from strnlen(inbuf0, bufsize0), therefore the buffer size must not include the NUL-terminator.
 +
 
 +
The second inbuf is the optional context data, if specified the buffer size must be <0xFFFF.
 +
 
 +
This is for standard TLS keying material export.
 +
 
 +
==== SetIoTimeout ====
 +
Takes an input u32, no output.
 +
 
 +
This sets a field in the ISslConnection object, then returns 0.
 +
 
 +
==== GetIoTimeout ====
 +
No input, returns an output u32.
 +
 
 +
This gets the field set by [[#SetIoTimeout]], then returns 0.
 +
 
 +
= ssl:s =
 +
This is "nn::ssl::sf::ISslServiceForSystem".
 +
 
 +
This was added with [15.0.0+].
 +
 
 +
This has IPC max_sessions = 0x40.
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Cmd || Name
 +
|-
 +
| 0 || [[#CreateContext]]
 +
|-
 +
| 1 || [[#GetContextCount]]
 +
|-
 +
| 2 || [[#GetCertificates]]
 +
|-
 +
| 3 || [[#GetCertificateBufSize]]
 +
|-
 +
| 4 || [[#DebugIoctl]]
 +
|-
 +
| 5 || [[#SetInterfaceVersion]]
 +
|-
 +
| 6 || [[#FlushSessionCache]]
 +
|-
 +
| 7 || [[#SetDebugOption]]
 +
|-
 +
| 8 || [[#GetDebugOption]]
 +
|-
 +
| 9 || [[#ClearTls12FallbackFlag]]
 +
|-
 +
| 100 || [[#CreateContextForSystem]]
 +
|-
 +
| 101 || [[#SetThreadCoreMask]]
 +
|-
 +
| 102 || [[#GetThreadCoreMask]]
 +
|-
 +
| 103 || [18.0.0+] VerifySignature
 +
|}
 +
 
 +
== CreateContextForSystem ==
 +
Takes a PID, an input u32 [[#SslVersion]] and an input u64 pid_placeholder. Returns an output [[#ISslContextForSystem]].
 +
 
 +
== SetThreadCoreMask ==
 +
Takes an input u64 mask, no output.
 +
 
 +
An error is thrown if the mask is 0, or if any bits are set which are not present in CoreMask from [[SVC|svcGetInfo]].
 +
 
 +
This updates a global field and uses [[SVC|svcSetThreadCoreMask]].
 +
 
 +
== GetThreadCoreMask ==
 +
No input, returns an output u64.
 +
 
 +
This gets the global field which is also used by [[#SetThreadCoreMask]].
 +
 
 +
== ISslContextForSystem ==
 +
This is "nn::ssl::sf::ISslContextForSystem".
 +
 
 +
This was added with [15.0.0+].
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Cmd || Name
 +
|-
 +
| 0 || [[#SetOption]]
 +
|-
 +
| 1 || [[#GetOption]]
 +
|-
 +
| 2 || [[#CreateConnection]]
 +
|-
 +
| 3 || [[#GetConnectionCount]]
 +
|-
 +
| 4 || [[#ImportServerPki]]
 +
|-
 +
| 5 || [[#ImportClientPki]]
 +
|-
 +
| 6 || [[#RemoveServerPki]]
 +
|-
 +
| 7 || [[#RemoveClientPki]]
 +
|-
 +
| 8 || [[#RegisterInternalPki]]
 +
|-
 +
| 9 || [[#AddPolicyOid]]
 +
|-
 +
| 10 || [[#ImportCrl]]
 +
|-
 +
| 11 || [[#RemoveCrl]]
 +
|-
 +
| 12 || [16.0.0+] [[#ImportClientCertKeyPki]]
 +
|-
 +
| 13 || [16.0.0+] [[#GeneratePrivateKeyAndCert]]
 +
|-
 +
| 100 || [[#CreateConnectionEx]]
 +
|}
 +
 
 +
=== CreateConnectionEx ===
 +
No input. Returns an [[#ISslConnection]].
 +
 
 +
This is similar to [[#CreateConnection]], but allows a maximum of 10 connections instead of 8.
 +
 
 +
= SslVersion =
 +
This is "nn::ssl::sf::SslVersion" or "nn::ssl::Context::SslVersion".
 +
 
 +
This is a bitmask which controls the min/max TLS versions to use, depending on which lowest/highest bits are set (if Auto isn't set).
 +
 
 +
Auto uses min=TlsV10 max=TlsV12.
 +
 
 +
[11.0.0+] ApiVersion is 1.
 +
 
 +
[12.0.0+] ApiVersion is now 2. Auto now uses min=TlsV10 max=((ApiVersion < 2) ? TlsV12 : TlsV13).
 +
 
 +
[12.0.3+] TLS 1.3 is no longer used. The TlsV13 bit is now handled the same as TlsV12 (uses TLS 1.2), and Auto only uses TLS 1.2 for the maximum.
 +
 
 +
[14.0.0+] ApiVersion is now 3 and TLS 1.3 is supported again. Auto now uses min=TlsV10 max=((ApiVersion < 3) ? TlsV12 : TlsV13). If too many connection errors arise, TLS now automatically falls back to version 1.2 by setting an internal flag which can be manually cleared with [[#ClearTls12FallbackFlag]].
 +
 
 +
[17.0.0+] ApiVersion is now 4.
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Bits
 +
! Description
 +
|-
 +
| 0 || Auto
 +
|-
 +
| 3 || TlsV10
 +
|-
 +
| 4 || TlsV11
 +
|-
 +
| 5 || TlsV12
 +
|-
 +
| 6 || [11.0.0+] TlsV13
 +
|-
 +
| 24-31 || [11.0.0+] ApiVersion
 +
|}
 +
 
 +
= DebugOptionType =
 +
This is "nn::ssl::sf::DebugOptionType" or "nn::ssl::DebugOption".
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Value
 +
! Description
 +
|-
 +
| 0 || AllowDisableVerifyOption
 +
|}
 +
 
 +
= FlushSessionCacheOptionType =
 +
This is "nn::ssl::sf::FlushSessionCacheOptionType" or "nn::ssl::FlushSessionCacheOptionType".
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Value
 +
! Description
 +
|-
 +
| 0 || SingleHost
 +
|-
 +
| 1 || AllHosts
 
|}
 
|}
    
= BuiltInCertificateInfo =
 
= BuiltInCertificateInfo =
 +
This is "nn::ssl::BuiltInManager::BuiltInCertificateInfo".
 +
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
Line 156: Line 694:  
| 0x0
 
| 0x0
 
| 0x4
 
| 0x4
| CaCertificateId
+
| [[#CaCertificateId]]
 
|-
 
|-
 
| 0x4
 
| 0x4
 
| 0x4
 
| 0x4
| [[#BuiltinDataStatus]]
+
| [[#TrustedCertStatus]]
 
|-
 
|-
 
| 0x8
 
| 0x8
 
| 0x8
 
| 0x8
| Data size
+
| CertificateSize
 
|-
 
|-
 
| 0x10
 
| 0x10
 
| 0x8
 
| 0x8
| Data offset
+
| CertificateDataOffset
 
|}
 
|}
   −
This is the struct returned by [[#GetCertificates]]. Official sw converts this to "nn::ssl::BuiltInManager::BuiltInCertificateInfo" with offset converted to a ptr.
+
This is the struct returned by [[#GetCertificates]]. It is internally converted from "nn::ssl::detail::BuiltinDataInfo" by copying "nn::ssl::detail::BuiltinDataInfo::BuiltinDataStatus" into [[#TrustedCertStatus]] and official software then further converts this to "nn::ssl::BuiltInManager::BuiltInCertificateInfo" by transforming "CertificateDataOffset" into an actual pointer.
 +
 
 +
= TrustedCertStatus =
 +
This is "nn::ssl::TrustedCertStatus".
   −
= BuiltinDataStatus =
   
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
Line 181: Line 721:  
| -1
 
| -1
 
| Invalid
 
| Invalid
 +
|-
 +
| 0
 +
| Removed
 
|-
 
|-
 
| 1
 
| 1
| Valid
+
| EnabledTrusted
 +
|-
 +
| 2
 +
| EnabledNotTrusted
 +
|-
 +
| 3
 +
| Revoked
 
|}
 
|}
   −
This is the "nn::ssl::detail::BuiltinDataInfo::BuiltinDataStatus" enum.
+
= CaCertificateId =
 +
This is "nn::ssl::CaCertificateId".
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Value
 +
! Description
 +
|-
 +
| -1 || [3.0.0+] All
 +
|-
 +
| 1 || NintendoCAG3
 +
|-
 +
| 2 || NintendoClass2CAG3
 +
|-
 +
| 3 || [16.0.0+] "Nintendo Root CA G4"
 +
|-
 +
| 1000 || AmazonRootCA1
 +
|-
 +
| 1001 || StarfieldServicesRootCertificateAuthorityG2
 +
|-
 +
| 1002 || AddTrustExternalCARoot
 +
|-
 +
| 1003 || COMODOCertificationAuthority
 +
|-
 +
| 1004 || UTNDATACorpSGC
 +
|-
 +
| 1005 || UTNUSERFirstHardware
 +
|-
 +
| 1006 || BaltimoreCyberTrustRoot
 +
|-
 +
| 1007 || CybertrustGlobalRoot
 +
|-
 +
| 1008 || VerizonGlobalRootCA
 +
|-
 +
| 1009 || DigiCertAssuredIDRootCA
 +
|-
 +
| 1010 || DigiCertAssuredIDRootG2
 +
|-
 +
| 1011 || DigiCertGlobalRootCA
 +
|-
 +
| 1012 || DigiCertGlobalRootG2
 +
|-
 +
| 1013 || DigiCertHighAssuranceEVRootCA
 +
|-
 +
| 1014 || EntrustnetCertificationAuthority2048
 +
|-
 +
| 1015 || EntrustRootCertificationAuthority
 +
|-
 +
| 1016 || EntrustRootCertificationAuthorityG2
 +
|-
 +
| 1017 || GeoTrustGlobalCA2 ([8.0.0+] [[#TrustedCertStatus]] is EnabledNotTrusted)
 +
|-
 +
| 1018 || GeoTrustGlobalCA ([8.0.0+] [[#TrustedCertStatus]] is EnabledNotTrusted)
 +
|-
 +
| 1019 || GeoTrustPrimaryCertificationAuthorityG3 ([8.0.0+] [[#TrustedCertStatus]] is EnabledNotTrusted)
 +
|-
 +
| 1020 || GeoTrustPrimaryCertificationAuthority ([8.0.0+] [[#TrustedCertStatus]] is EnabledNotTrusted)
 +
|-
 +
| 1021 || GlobalSignRootCA
 +
|-
 +
| 1022 || GlobalSignRootCAR2
 +
|-
 +
| 1023 || GlobalSignRootCAR3
 +
|-
 +
| 1024 || GoDaddyClass2CertificationAuthority
 +
|-
 +
| 1025 || GoDaddyRootCertificateAuthorityG2
 +
|-
 +
| 1026 || StarfieldClass2CertificationAuthority
 +
|-
 +
| 1027 || StarfieldRootCertificateAuthorityG2
 +
|-
 +
| 1028 || thawtePrimaryRootCAG3 ([8.0.0+] [[#TrustedCertStatus]] is EnabledNotTrusted)
 +
|-
 +
| 1029 || thawtePrimaryRootCA ([8.0.0+] [[#TrustedCertStatus]] is EnabledNotTrusted)
 +
|-
 +
| 1030 || VeriSignClass3PublicPrimaryCertificationAuthorityG3 ([8.0.0+] [[#TrustedCertStatus]] is EnabledNotTrusted)
 +
|-
 +
| 1031 || VeriSignClass3PublicPrimaryCertificationAuthorityG5 ([8.0.0+] [[#TrustedCertStatus]] is EnabledNotTrusted)
 +
|-
 +
| 1032 || VeriSignUniversalRootCertificationAuthority ([8.0.0+] [[#TrustedCertStatus]] is EnabledNotTrusted)
 +
|-
 +
| 1033 || [6.0.0+] DSTRootCAX3
 +
|-
 +
| 1034 || [10.0.3+] "USERTrust RSA Certification Authority"
 +
|-
 +
| 1035 || [10.1.0+] "ISRG Root X10"
 +
|-
 +
| 1036 || [10.1.0+] "USERTrust ECC Certification Authority"
 +
|-
 +
| 1037 || [10.1.0+] "COMODO RSA Certification Authority"
 +
|-
 +
| 1038 || [10.1.0+] "COMODO ECC Certification Authority"
 +
|-
 +
| 1039 || [11.0.0+] "Amazon Root CA 2"
 +
|-
 +
| 1040 || [11.0.0+] "Amazon Root CA 3"
 +
|-
 +
| 1041 || [11.0.0+] "Amazon Root CA 4"
 +
|-
 +
| 1042 || [11.0.0+] "DigiCert Assured ID Root G3"
 +
|-
 +
| 1043 || [11.0.0+] "DigiCert Global Root G3"
 +
|-
 +
| 1044 || [11.0.0+] "DigiCert Trusted Root G4"
 +
|-
 +
| 1045 || [11.0.0+] "Entrust Root Certification Authority - EC1"
 +
|-
 +
| 1046 || [11.0.0+] "Entrust Root Certification Authority - G4"
 +
|-
 +
| 1047 || [11.0.0+] "GlobalSign ECC Root CA - R4"
 +
|-
 +
| 1048 || [11.0.0+] "GlobalSign ECC Root CA - R5"
 +
|-
 +
| 1049 || [11.0.0+] "GlobalSign ECC Root CA - R6"
 +
|-
 +
| 1050 || [11.0.0+] "GTS Root R1"
 +
|-
 +
| 1051 || [11.0.0+] "GTS Root R2"
 +
|-
 +
| 1052 || [11.0.0+] "GTS Root R3"
 +
|-
 +
| 1053 || [11.0.0+] "GTS Root R4"
 +
|-
 +
| 1054 || [12.0.0+] "Security Communication RootCA"
 +
|-
 +
| 1055 || [15.0.0+] "GlobalSign Root E4"
 +
|-
 +
| 1056 || [15.0.0+] "GlobalSign Root R4"
 +
|-
 +
| 1057 || [15.0.0+] "T-TeleSec GlobalRoot Class 2"
 +
|-
 +
| 1058 || [16.0.0+] "DigiCert TLS ECC P384 Root G5"
 +
|-
 +
| 1059 || [16.0.0+] "DigiCert TLS RSA4096 Root G5"
 +
|-
 +
| 65536 (0x10000) || [16.0.0+] "Nintendo Temp Root CA G4" (Only in "ssl_TrustedCerts.Ounce.bdf")
 +
|}
 +
 
 +
= InternalPki =
 +
This is "nn::ssl::sf::InternalPki" or "nn::ssl::Context::InternalPki".
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Value
 +
! Description
 +
|-
 +
| 0 || None
 +
|-
 +
| 1 || DeviceClientCertDefault
 +
|}
 +
 
 +
An error is thrown by [[#RegisterInternalPki]] when the input value does not match "DeviceClientCertDefault".
 +
 
 +
"DeviceClientCertDefault" enables using the DeviceCert.
 +
 
 +
= ContextOption =
 +
This is "nn::ssl::sf::ContextOption" or "nn::ssl::Context::ContextOption".
 +
 
 +
The default value for CrlImportDateCheckEnable at the time of [[#ISslContext]] object creation is value 1.
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Value
 +
! Description
 +
|-
 +
| 0 || None
 +
|-
 +
| 1 || CrlImportDateCheckEnable
 +
|}
 +
 
 +
= CertificateFormat =
 +
This is "nn::ssl::sf::CertificateFormat" or "nn::ssl::CertificateFormat".
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Value
 +
! Description
 +
|-
 +
| 1 || Pem
 +
|-
 +
| 2 || Der
 +
|}
 +
 
 +
= VerifyOption =
 +
This is "nn::ssl::sf::VerifyOption". This is a bitmask. At the time of [[#ISslConnection]] object creation, the default value is 0x3.
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Bit
 +
! Description
 +
|-
 +
| 0 || PeerCa
 +
|-
 +
| 1 || HostName
 +
|-
 +
| 2 || DateCheck
 +
|-
 +
| 3 || EvCertPartial
 +
|-
 +
| 4 || [6.0.0+] EvPolicyOid
 +
|-
 +
| 5 || [6.0.0+] EvCertFingerprint
 +
|}
 +
 
 +
Originally ssl-sysmodule ([[#SetVerifyOption]]) just wrote the input field to state. With [5.0.0+] there's now validation for the input, with the value written to state masked with {allowed bitmask}. When [[#SetInterfaceVersion|InterfaceVersion]] is >=0x2, the low 2-bits of VerifyOption must be set, unless {state flag for [[#OptionType|SkipDefaultVerify]]} is set or [9.0.0+] {bool [[#SetDebugOption|DebugOption]] state flag} is set, otherwise an error is thrown. [6.0.0+]: Following that, if VerifyOption bit4 is set, then VerifyOption & 0x15 must match 0x15 otherwise an error is thrown.
 +
 
 +
= IoMode =
 +
This is "nn::ssl::sf::IoMode" or "nn::ssl::Connection::IoMode". At the time of [[#ISslConnection]] object creation, the default value is 1.
 +
 
 +
The socket non-blocking flag is always set regardless of this field, this is only used for calculating the timeout (converted from milliseconds) passed to the NSS funcs used by various cmds. NonBlocking = 0, Blocking = 300000 (5 minutes).
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Value
 +
! Description
 +
|-
 +
| 1 || Blocking
 +
|-
 +
| 2 || NonBlocking
 +
|}
 +
 
 +
= PollEvent =
 +
This is "nn::ssl::sf::PollEvent" or "nn::ssl::Connection::PollEvent". This is a bitmask.
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Bit
 +
! Description
 +
|-
 +
| 0 || Read
 +
|-
 +
| 1 || Write
 +
|-
 +
| 2 || Except
 +
|}
 +
 
 +
= SessionCacheMode =
 +
This is "nn::ssl::sf::SessionCacheMode" or "nn::ssl::Connection::SessionCacheMode".
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Value
 +
! Description
 +
|-
 +
| 0 || None
 +
|-
 +
| 1 || SessionId
 +
|-
 +
| 2 || SessionTicket
 +
|}
 +
 
 +
= RenegotiationMode =
 +
This is "nn::ssl::sf::RenegotiationMode" or "nn::ssl::Connection::RenegotiationMode".
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Value
 +
! Description
 +
|-
 +
| 0 || None
 +
|-
 +
| 1 || Secure
 +
|}
 +
 
 +
= OptionType =
 +
This is "nn::ssl::sf::OptionType" or "nn::ssl::Connection::OptionType".
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Value
 +
! Description
 +
|-
 +
| 0 || DoNotCloseSocket
 +
|-
 +
| 1 || [3.0.0+] GetServerCertChain
 +
|-
 +
| 2 || [5.0.0+] SkipDefaultVerify
 +
|-
 +
| 3 || [9.0.0+] EnableAlpn
 +
|}
 +
 
 +
Or in the case of [[#SetPrivateOption]] which is also "nn::ssl::ConnectionPrivate::PrivateOptionType":
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Value
 +
! Description
 +
|-
 +
| 1 || [[#SetSessionCacheMode]] will throw an error if the input [[#SessionCacheMode]] is non-zero and this option flag is set.
 +
|-
 +
| 2 || [17.0.0+] This exclusively enables the cipher suite specified in the input u32 passed to [[#SetPrivateOption]] (all other ciphers disabled).
 +
|}
 +
 
 +
This corresponds to bool flags. At the time of [[#ISslConnection]] object creation, all of these fields are cleared (excluding PrivateOptionType val1 above?).
 +
 
 +
"SkipDefaultVerify" is checked by [[#VerifyOption|SetVerifyOption]] and "EnableAlpn" is only available with [[#SetOption_2|SetOption]].
 +
 
 +
[[#SetOption_2|SetOption]] with "DoNotCloseSocket" is only available when [[#SetSocketDescriptor]] was not used previously. "EnableAlpn" can optionally use the state setup by [[#SetSocketDescriptor]], but it will return 0 regardless.
 +
 
 +
See [[#SetNextAlpnProto]] for "EnableAlpn", and [[#DoHandshakeGetServerCert]] for "GetServerCertChain".
 +
 
 +
= AlpnProtoState =
 +
This is "nn::ssl::sf::AlpnProtoState" or "nn::ssl::Connection::AlpnProtoState".
   −
= CaCertificateId =
   
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
Line 194: Line 1,045:  
! Description
 
! Description
 
|-
 
|-
| 1
+
| 0 || NoSupport
| Nintendo {...}
+
|-
 +
| 1 || Negotiated
 +
|-
 +
| 2 || NoOverlap
 +
|-
 +
| 3 || Selected
 +
|-
 +
| 4 || EarlyValue
 +
|}
 +
 
 +
= CipherInfo =
 +
This is "nn::ssl::Connection::CipherInfo". This is a 0x48-byte struct.
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0 || 0x40 || Cipher string
 +
|-
 +
| 0x40 || 0x8 || Protocol version string
 +
|}
 +
 
 +
= KeyAndCertParams =
 +
This is "nn::ssl::ContextPrivate::KeyAndCertParams". This is a 0x58-byte struct.
 +
 
 +
This was added with [16.0.0+].
 +
 
 +
The constructor for this in official sw just clears this struct.
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0 || 0x4 || Must be value 1.
 +
|-
 +
| 0x4 || 0x4 || s32 Key size in bits.
 +
|-
 +
| 0x8 || 0x8 || Public exponent, must be non-zero. Only the low 4-bytes are used.
 +
|-
 +
| 0x10 || 0x40 || CN (Common Name) NUL-terminated string.
 +
|-
 +
| 0x50 || 0x4 || An error is thrown if this is value 0 or >0x3F. The official wrapper code for [[#GeneratePrivateKeyAndCert]] verifies that this matches the output from <code>strnlen(struct+0x10, 0x40)</code>, however the sysmodule version just throws an error if the strnlen output matches 0x40 (as in no NUL-terminator found).
 +
|}
 +
 
 +
= CertStore =
 +
This is the CertStore title, which contains the following files in RomFS:
 +
* "/ssl_TrustedCerts.bdf" ([1.0.0-2.3.0] "ssl_TrustedCerts.tcf") (file was renamed with [3.0.0], content is identical)
 +
* [3.0.0+] "/ssl_Crl.bdf"
 +
* [6.0.0+] "/ssl_CaFingerprints.bdf"
 +
 
 +
The content of this SystemData was updated with the following system-versions: [[3.0.0]], [[6.0.0]], [[8.0.0]], [[10.1.0]], [[11.0.0]], [[12.0.0]]. See [[#CaCertificateId]] for the ssl_TrustedCerts changes.
 +
 
 +
[10.1.0+] added 3 more fingerprints to "/ssl_CaFingerprints.bdf".
 +
 
 +
[11.0.0+] updated "/ssl_CaFingerprints.bdf" and "/ssl_TrustedCerts.bdf".
 +
 
 +
[12.0.0+] updated "/ssl_TrustedCerts.bdf".
 +
 
 +
[16.0.0+] updated "/ssl_TrustedCerts.bdf" and added "/ssl_TrustedCerts.Ounce.bdf". The latter is identical to the former except that it contains an additional cert. The latter also isn't used in ssl-sysmodule (in the retail build at least).
 +
 
 +
[[#ISslContext]] automatically uses this CertStore, regardless of the used cmds.
 +
 
 +
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
 +
| [[#TrustedCertStatus]]
 +
|-
 +
| 0x8
 +
| 0x4
 +
| Data size
 
|-
 
|-
| 2
+
| 0xC
| Nintendo {...}
+
| 0x4
 +
| Data offset
 
|}
 
|}
   −
This is the "nn::ssl::CaCertificateId" enum.
+
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 =