SSL services: Difference between revisions

 
(40 intermediate revisions by 3 users not shown)
Line 1: Line 1:
= ssl =
= 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.
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].
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.
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 27: Line 31:
|-
|-
| 8 || [6.0.0+] [[#GetDebugOption]]
| 8 || [6.0.0+] [[#GetDebugOption]]
|-
| 9 || [14.0.0+] [[#ClearTls12FallbackFlag]]
|}
|}


Line 64: Line 70:
|-
|-
| 0x3 || [6.0.0+]
| 0x3 || [6.0.0+]
|-
| 0x4 || [20.0.0+]
|}
|}


Line 84: Line 92:


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 115: Line 126:
|-
|-
| 11 || [3.0.0+] [[#RemoveCrl]]
| 11 || [3.0.0+] [[#RemoveCrl]]
|-
| 12 || [16.0.0+] [[#ImportClientCertKeyPki]]
|-
| 13 || [16.0.0+] [[#GeneratePrivateKeyAndCert]]
|}
|}


Line 143: Line 158:


The certs can be CAs or server certs (no pubkeys).
The certs can be CAs or server certs (no pubkeys).
The [[#CertificateFormat]] only validated, afterwards it's ignored.


=== ImportClientPki ===
=== ImportClientPki ===
Line 174: Line 191:
=== RemoveCrl ===
=== RemoveCrl ===
Takes an input u64 Id, no output.
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 237: Line 292:
|-
|-
| 27 || [9.0.0+] [[#GetNextAlpnProto]]
| 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]]
|-
| 36 || [20.0.0+] GetSessionTicket
|-
| 37 || [20.0.0+] SetSessionTicket
|}
|}


Line 410: Line 485:


The output will be all-zero/empty if not available - such as when this was used before DoHandshake*.
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]].
== VerifySignature ==
Takes three type-0x5 input buffers. No output.
[19.0.0+] Now takes an additional 4-bytes of input.
== 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 =
= SslVersion =
Line 418: Line 642:
Auto uses min=TlsV10 max=TlsV12.
Auto uses min=TlsV10 max=TlsV12.


[12.0.0+] Auto now uses min=TlsV10 max=((ApiVersion <= 1) ? TlsV12 : TlsV13).
[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.
[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"
{| class="wikitable" border="1"
Line 529: Line 759:
|-
|-
| 2 || NintendoClass2CAG3
| 2 || NintendoClass2CAG3
|-
| 3 || [16.0.0+] "Nintendo Root CA G4"
|-
|-
| 1000 || AmazonRootCA1
| 1000 || AmazonRootCA1
Line 639: Line 871:
|-
|-
| 1054 || [12.0.0+] "Security Communication RootCA"
| 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"
|-
| 32801 || [20.0.0+] "ssl-rr-01.netdev.ntd.nintendo.com"
|-
| 65536 (0x10000) || [16.0.0+] "Nintendo Temp Root CA G4" (Only in "ssl_TrustedCerts.Ounce.bdf") ([19.0.0+] Removed)
|-
| 32802 || [20.0.0+] "ssl-rr-02.netdev.ntd.nintendo.com"
|-
| 32803 || [20.0.0+] "ssl-rr-03.netdev.ntd.nintendo.com"
|-
| 32804 || [20.0.0+] "ssl-rr-04.netdev.ntd.nintendo.com"
|-
| 32805 || [20.0.0+] "ssl-rr-05.netdev.ntd.nintendo.com"
|-
| 32806 || [20.0.0+] "ssl-rr-06.netdev.ntd.nintendo.com"
|-
| 32807 || [20.0.0+] "ssl-rr-07.netdev.ntd.nintendo.com"
|-
| 32808 || [20.0.0+] "ssl-rr-08.netdev.ntd.nintendo.com"
|-
| 32809 || [20.0.0+] "ssl-rr-09.netdev.ntd.nintendo.com"
|-
| 32810 || [20.0.0+] "ssl-rr-10.netdev.ntd.nintendo.com"
|-
| 32811 || [20.0.0+] "ssl-rr-11.netdev.ntd.nintendo.com"
|-
| 32812 || [20.0.0+] "ssl-rr-12.netdev.ntd.nintendo.com"
|-
| 32813 || [20.0.0+] "ssl-rr-13.netdev.ntd.nintendo.com"
|-
| 32814 || [20.0.0+] "ssl-rr-14.netdev.ntd.nintendo.com"
|-
| 32815 || [20.0.0+] "ssl-rr-15.netdev.ntd.nintendo.com"
|-
| 32816 || [20.0.0+] "ssl-rr-16.netdev.ntd.nintendo.com"
|-
| 32817 || [20.0.0+] "ssl-rr-17.netdev.ntd.nintendo.com"
|-
| 32818 || [20.0.0+] "ssl-rr-18.netdev.ntd.nintendo.com"
|-
| 32819 || [20.0.0+] "ssl-rr-19.netdev.ntd.nintendo.com"
|-
| 32820 || [20.0.0+] "ssl-rr-20.netdev.ntd.nintendo.com"
|-
| 32821 || [20.0.0+] "ssl-rr-21.netdev.ntd.nintendo.com"
|-
| 32822 || [20.0.0+] "ssl-rr-22.netdev.ntd.nintendo.com"
|-
| 32823 || [20.0.0+] "ssl-rr-23.netdev.ntd.nintendo.com"
|-
| 32824 || [20.0.0+] "ssl-rr-24.netdev.ntd.nintendo.com"
|-
| 32825 || [20.0.0+] "ssl-rr-25.netdev.ntd.nintendo.com"
|-
| 32826 || [20.0.0+] "ssl-rr-26.netdev.ntd.nintendo.com"
|-
| 32827 || [20.0.0+] "ssl-rr-27.netdev.ntd.nintendo.com"
|-
| 32828 || [20.0.0+] "ssl-rr-28.netdev.ntd.nintendo.com"
|-
| 32829 || [20.0.0+] "ssl-rr-29.netdev.ntd.nintendo.com"
|-
| 32830 || [20.0.0+] "ssl-rr-30.netdev.ntd.nintendo.com"
|-
| 32831 || [20.0.0+] "ssl-rr-31.netdev.ntd.nintendo.com"
|-
| 32832 || [20.0.0+] "ssl-rr-32.netdev.ntd.nintendo.com"
|-
| 32833 || [20.0.0+] "ssl-rr-33.netdev.ntd.nintendo.com"
|-
| 32834 || [20.0.0+] "ssl-rr-34.netdev.ntd.nintendo.com"
|-
| 32835 || [20.0.0+] "ssl-rr-35.netdev.ntd.nintendo.com"
|-
| 32836 || [20.0.0+] "ssl-rr-36.netdev.ntd.nintendo.com"
|-
| 32837 || [20.0.0+] "ssl-rr-37.netdev.ntd.nintendo.com"
|-
| 32838 || [20.0.0+] "ssl-rr-38.netdev.ntd.nintendo.com"
|-
| 32839 || [20.0.0+] "ssl-rr-39.netdev.ntd.nintendo.com"
|-
| 32840 || [20.0.0+] "ssl-rr-40.netdev.ntd.nintendo.com"
|-
| 32841 || [20.0.0+] "ssl-rr-41.netdev.ntd.nintendo.com"
|-
| 32842 || [20.0.0+] "ssl-rr-42.netdev.ntd.nintendo.com"
|-
| 32843 || [20.0.0+] "ssl-rr-43.netdev.ntd.nintendo.com"
|-
| 32844 || [20.0.0+] "ssl-rr-44.netdev.ntd.nintendo.com"
|-
| 32845 || [20.0.0+] "ssl-rr-45.netdev.ntd.nintendo.com"
|-
| 32846 || [20.0.0+] "ssl-rr-46.netdev.ntd.nintendo.com"
|-
| 32847 || [20.0.0+] "ssl-rr-47.netdev.ntd.nintendo.com"
|-
| 32848 || [20.0.0+] "ssl-rr-48.netdev.ntd.nintendo.com"
|-
| 32849 || [20.0.0+] "ssl-rr-49.netdev.ntd.nintendo.com"
|-
| 32850 || [20.0.0+] "ssl-rr-50.netdev.ntd.nintendo.com"
|-
| 32851 || [20.0.0+] "ssl-rr-51.netdev.ntd.nintendo.com"
|-
| 32852 || [20.0.0+] "ssl-rr-52.netdev.ntd.nintendo.com"
|-
| 32853 || [20.0.0+] "ssl-rr-53.netdev.ntd.nintendo.com"
|-
| 32854 || [20.0.0+] "ssl-rr-54.netdev.ntd.nintendo.com"
|-
| 32855 || [20.0.0+] "ssl-rr-55.netdev.ntd.nintendo.com"
|-
| 32856 || [20.0.0+] "ssl-rr-56.netdev.ntd.nintendo.com"
|-
| 32857 || [20.0.0+] "ssl-rr-57.netdev.ntd.nintendo.com"
|-
| 32858 || [20.0.0+] "ssl-rr-58.netdev.ntd.nintendo.com"
|-
| 32859 || [20.0.0+] "ssl-rr-59.netdev.ntd.nintendo.com"
|-
| 32860 || [20.0.0+] "ssl-rr-60.netdev.ntd.nintendo.com"
|-
| 32861 || [20.0.0+] "ssl-rr-61.netdev.ntd.nintendo.com"
|-
| 32862 || [20.0.0+] "ssl-rr-62.netdev.ntd.nintendo.com"
|-
| 32863 || [20.0.0+] "ssl-rr-63.netdev.ntd.nintendo.com"
|-
| 32864 || [20.0.0+] "ssl-rr-64.netdev.ntd.nintendo.com"
|}
|}


Line 784: Line 1,156:
|}
|}


This corresponds to bool flags. At the time of [[#ISslConnection]] object creation, all of these bool flags are cleared.
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]].
"SkipDefaultVerify" is checked by [[#VerifyOption|SetVerifyOption]] and "EnableAlpn" is only available with [[#SetOption_2|SetOption]].
Line 823: Line 1,207:
|-
|-
| 0x40 || 0x8 || Protocol version 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).
|}
|}


Line 838: Line 1,246:


[12.0.0+] updated "/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).
[19.0.0+] "/ssl_TrustedCerts.Ounce.bdf" updated
[20.0.0+] "/ssl_TrustedCerts.bdf" updated, "/ssl_TrustedCerts.Ounce.bdf" updated ("/ssl_TrustedCerts.Ounce.bdf" is identical to "/ssl_TrustedCerts.bdf").


[[#ISslContext]] automatically uses this CertStore, regardless of the used cmds.
[[#ISslContext]] automatically uses this CertStore, regardless of the used cmds.