Difference between revisions of "SSL services"
(→ssl:s) |
|||
(81 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]. | ||
+ | |||
+ | 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 23: | Line 31: | ||
|- | |- | ||
| 8 || [6.0.0+] [[#GetDebugOption]] | | 8 || [6.0.0+] [[#GetDebugOption]] | ||
+ | |- | ||
+ | | 9 || [14.0.0+] [[#ClearTls12FallbackFlag]] | ||
|} | |} | ||
Line 80: | Line 90: | ||
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 111: | Line 124: | ||
|- | |- | ||
| 11 || [3.0.0+] [[#RemoveCrl]] | | 11 || [3.0.0+] [[#RemoveCrl]] | ||
+ | |- | ||
+ | | 12 || [16.0.0+] [[#ImportClientCertKeyPki]] | ||
+ | |- | ||
+ | | 13 || [16.0.0+] [[#GeneratePrivateKeyAndCert]] | ||
|} | |} | ||
Line 134: | Line 151: | ||
=== ImportServerPki === | === ImportServerPki === | ||
− | Takes a type-0x5 input buffer and a [[#CertificateFormat]], returns an output u64. | + | 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 === | === ImportClientPki === | ||
− | Takes two type-0x5 input buffers, returns an output u64. | + | 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 === | === RemoveServerPki === | ||
− | Takes an input u64, no output. | + | Takes an input u64 Id, no output. |
=== RemoveClientPki === | === RemoveClientPki === | ||
− | Takes an input u64, no output. | + | Takes an input u64 Id, no output. |
=== RegisterInternalPki === | === RegisterInternalPki === | ||
− | Takes an input [[#InternalPki]], returns an output u64. | + | Takes an input [[#InternalPki]], returns an output u64 Id. |
+ | |||
+ | An error is thrown if this cmd or [[#ImportClientPki]] was already used previously. | ||
=== AddPolicyOid === | === AddPolicyOid === | ||
Line 154: | Line 183: | ||
=== ImportCrl === | === ImportCrl === | ||
− | Takes a type-0x5 input buffer, returns an output u64. | + | Takes a type-0x5 input buffer, returns an output u64 Id. |
+ | |||
+ | The input buffer contains the DER CRL. | ||
=== RemoveCrl === | === RemoveCrl === | ||
− | Takes an input u64, 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 221: | Line 290: | ||
|- | |- | ||
| 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]] | ||
|} | |} | ||
Line 228: | Line 313: | ||
An error is thrown if this was used previously. | 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. | Immediately prior to closing the [[#ISslConnection]] object, sdknso will close the sockfd which was returned by this cmd if it is not negative. | ||
Line 251: | Line 336: | ||
[[#SetSocketDescriptor]] must have been used prior to this successfully. | [[#SetSocketDescriptor]] must have been used prior to this successfully. | ||
+ | |||
+ | This gets the input_sockfd which was previously saved in state by [[#SetSocketDescriptor]]. | ||
==== GetHostName ==== | ==== GetHostName ==== | ||
Line 265: | Line 352: | ||
==== DoHandshake ==== | ==== DoHandshake ==== | ||
No input/output. | 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. | 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. | ||
Line 272: | Line 363: | ||
Same as [[#DoHandshake]] except the params for the func called internally are user-specified, instead of all 0. | 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 ==== | ==== Read ==== | ||
Line 277: | Line 378: | ||
[[#SetSocketDescriptor]] must have been used prior to this successfully. | [[#SetSocketDescriptor]] must have been used prior to this successfully. | ||
+ | |||
+ | The output u32 is the actual transferred size. | ||
==== Write ==== | ==== Write ==== | ||
Line 282: | Line 385: | ||
[[#SetSocketDescriptor]] must have been used prior to this successfully. | [[#SetSocketDescriptor]] must have been used prior to this successfully. | ||
+ | |||
+ | The output u32 is the actual transferred size. | ||
==== Pending ==== | ==== Pending ==== | ||
Line 289: | Line 394: | ||
==== Peek ==== | ==== Peek ==== | ||
− | Takes a type-0x6 output buffer, returns an output u32. | + | Takes a type-0x6 output buffer, returns an output u32 size. |
[[#SetSocketDescriptor]] must have been used prior to this successfully. | [[#SetSocketDescriptor]] must have been used prior to this successfully. | ||
Line 297: | Line 402: | ||
[[#SetSocketDescriptor]] must have been used prior to this successfully. | [[#SetSocketDescriptor]] must have been used prior to this successfully. | ||
+ | |||
+ | The u32 is the timeout in milliseconds. | ||
==== GetVerifyCertError ==== | ==== GetVerifyCertError ==== | ||
Line 341: | Line 448: | ||
==== GetVerifyCertErrors ==== | ==== GetVerifyCertErrors ==== | ||
Takes a type-0x6 output buffer, returns two output u32s. | 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 ==== | ==== GetCipherInfo ==== | ||
Line 355: | Line 464: | ||
[[#SetSocketDescriptor]] must have been used prior to this successfully. | [[#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 ==== | ==== GetNextAlpnProto ==== | ||
Line 360: | Line 475: | ||
[[#SetSocketDescriptor]] must have been used prior to this successfully. | [[#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]]. | ||
+ | |||
+ | == 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 = | ||
This is "nn::ssl::sf::SslVersion" or "nn::ssl::Context::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" | {| class="wikitable" border="1" | ||
|- | |- | ||
− | ! | + | ! Bits |
! Description | ! Description | ||
|- | |- | ||
− | | | + | | 0 || Auto |
+ | |- | ||
+ | | 3 || TlsV10 | ||
+ | |- | ||
+ | | 4 || TlsV11 | ||
|- | |- | ||
− | | | + | | 5 || TlsV12 |
|- | |- | ||
− | | | + | | 6 || [11.0.0+] TlsV13 |
|- | |- | ||
− | | | + | | 24-31 || [11.0.0+] ApiVersion |
|} | |} | ||
Line 462: | Line 748: | ||
! Description | ! Description | ||
|- | |- | ||
− | | -1 || All | + | | -1 || [3.0.0+] All |
|- | |- | ||
| 1 || NintendoCAG3 | | 1 || NintendoCAG3 | ||
|- | |- | ||
| 2 || NintendoClass2CAG3 | | 2 || NintendoClass2CAG3 | ||
+ | |- | ||
+ | | 3 || [16.0.0+] "Nintendo Root CA G4" | ||
|- | |- | ||
| 1000 || AmazonRootCA1 | | 1000 || AmazonRootCA1 | ||
Line 502: | Line 790: | ||
| 1016 || EntrustRootCertificationAuthorityG2 | | 1016 || EntrustRootCertificationAuthorityG2 | ||
|- | |- | ||
− | | 1017 || GeoTrustGlobalCA2 | + | | 1017 || GeoTrustGlobalCA2 ([8.0.0+] [[#TrustedCertStatus]] is EnabledNotTrusted) |
|- | |- | ||
− | | 1018 || GeoTrustGlobalCA | + | | 1018 || GeoTrustGlobalCA ([8.0.0+] [[#TrustedCertStatus]] is EnabledNotTrusted) |
|- | |- | ||
− | | 1019 || GeoTrustPrimaryCertificationAuthorityG3 | + | | 1019 || GeoTrustPrimaryCertificationAuthorityG3 ([8.0.0+] [[#TrustedCertStatus]] is EnabledNotTrusted) |
|- | |- | ||
− | | 1020 || GeoTrustPrimaryCertificationAuthority | + | | 1020 || GeoTrustPrimaryCertificationAuthority ([8.0.0+] [[#TrustedCertStatus]] is EnabledNotTrusted) |
|- | |- | ||
| 1021 || GlobalSignRootCA | | 1021 || GlobalSignRootCA | ||
Line 524: | Line 812: | ||
| 1027 || StarfieldRootCertificateAuthorityG2 | | 1027 || StarfieldRootCertificateAuthorityG2 | ||
|- | |- | ||
− | | 1028 || thawtePrimaryRootCAG3 | + | | 1028 || thawtePrimaryRootCAG3 ([8.0.0+] [[#TrustedCertStatus]] is EnabledNotTrusted) |
|- | |- | ||
− | | 1029 || thawtePrimaryRootCA | + | | 1029 || thawtePrimaryRootCA ([8.0.0+] [[#TrustedCertStatus]] is EnabledNotTrusted) |
|- | |- | ||
− | | 1030 || VeriSignClass3PublicPrimaryCertificationAuthorityG3 | + | | 1030 || VeriSignClass3PublicPrimaryCertificationAuthorityG3 ([8.0.0+] [[#TrustedCertStatus]] is EnabledNotTrusted) |
|- | |- | ||
− | | 1031 || VeriSignClass3PublicPrimaryCertificationAuthorityG5 | + | | 1031 || VeriSignClass3PublicPrimaryCertificationAuthorityG5 ([8.0.0+] [[#TrustedCertStatus]] is EnabledNotTrusted) |
|- | |- | ||
− | | 1032 || VeriSignUniversalRootCertificationAuthority | + | | 1032 || VeriSignUniversalRootCertificationAuthority ([8.0.0+] [[#TrustedCertStatus]] is EnabledNotTrusted) |
|- | |- | ||
| 1033 || [6.0.0+] DSTRootCAX3 | | 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") ([19.0.0+] Removed) | ||
|} | |} | ||
Line 551: | Line 893: | ||
An error is thrown by [[#RegisterInternalPki]] when the input value does not match "DeviceClientCertDefault". | An error is thrown by [[#RegisterInternalPki]] when the input value does not match "DeviceClientCertDefault". | ||
+ | |||
+ | "DeviceClientCertDefault" enables using the DeviceCert. | ||
= ContextOption = | = ContextOption = | ||
This is "nn::ssl::sf::ContextOption" or "nn::ssl::Context::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" | {| class="wikitable" border="1" | ||
Line 603: | Line 949: | ||
= IoMode = | = IoMode = | ||
This is "nn::ssl::sf::IoMode" or "nn::ssl::Connection::IoMode". At the time of [[#ISslConnection]] object creation, the default value is 1. | 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" | {| class="wikitable" border="1" | ||
Line 674: | Line 1,022: | ||
|} | |} | ||
− | This corresponds to bool flags. At the time of [[#ISslConnection]] object creation, all of these | + | 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]]. | ||
[[#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. | [[#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 = | = AlpnProtoState = | ||
Line 711: | Line 1,073: | ||
|- | |- | ||
| 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 719: | Line 1,105: | ||
* [6.0.0+] "/ssl_CaFingerprints.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]]. | + | 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). | ||
+ | |||
+ | [19.0.0+] "/ssl_TrustedCerts.Ounce.bdf" updated | ||
+ | |||
+ | [[#ISslContext]] automatically uses this CertStore, regardless of the used cmds. | ||
These have the following structure: | These have the following structure: | ||
Line 748: | Line 1,146: | ||
| 0x4 | | 0x4 | ||
| 0x4 | | 0x4 | ||
− | | | + | | [[#TrustedCertStatus]] |
|- | |- | ||
| 0x8 | | 0x8 |
Latest revision as of 04:32, 23 October 2024
ssl
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 NSS.
Note that SystemPrograms generally use #RegisterInternalPki (see libcurl). However, web-applets use #GetCertificates with #CaCertificateId All - #RegisterInternalPki is not used.
This has IPC max_sessions = 0x40.
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 |
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
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.
ClearTls12FallbackFlag
No input/output.
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 |
12 | [16.0.0+] #ImportClientCertKeyPki |
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
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 |
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 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 DoNotCloseSocket is set it will instead return -1 for the sockfd. Then 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 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 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 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 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 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.
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.
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 svcGetInfo.
This updates a global field and uses 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+].
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.
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".
Value | Description |
---|---|
0 | AllowDisableVerifyOption |
FlushSessionCacheOptionType
This is "nn::ssl::sf::FlushSessionCacheOptionType" or "nn::ssl::FlushSessionCacheOptionType".
Value | Description |
---|---|
0 | SingleHost |
1 | AllHosts |
BuiltInCertificateInfo
This is "nn::ssl::BuiltInManager::BuiltInCertificateInfo".
Offset | Size | Description |
---|---|---|
0x0 | 0x4 | #CaCertificateId |
0x4 | 0x4 | #TrustedCertStatus |
0x8 | 0x8 | CertificateSize |
0x10 | 0x8 | CertificateDataOffset |
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".
Value | Description |
---|---|
-1 | Invalid |
0 | Removed |
1 | EnabledTrusted |
2 | EnabledNotTrusted |
3 | Revoked |
CaCertificateId
This is "nn::ssl::CaCertificateId".
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") ([19.0.0+] Removed) |
InternalPki
This is "nn::ssl::sf::InternalPki" or "nn::ssl::Context::InternalPki".
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.
Value | Description |
---|---|
0 | None |
1 | CrlImportDateCheckEnable |
CertificateFormat
This is "nn::ssl::sf::CertificateFormat" or "nn::ssl::CertificateFormat".
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.
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 InterfaceVersion is >=0x2, the low 2-bits of VerifyOption must be set, unless {state flag for SkipDefaultVerify} is set or [9.0.0+] {bool 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).
Value | Description |
---|---|
1 | Blocking |
2 | NonBlocking |
PollEvent
This is "nn::ssl::sf::PollEvent" or "nn::ssl::Connection::PollEvent". This is a bitmask.
Bit | Description |
---|---|
0 | Read |
1 | Write |
2 | Except |
SessionCacheMode
This is "nn::ssl::sf::SessionCacheMode" or "nn::ssl::Connection::SessionCacheMode".
Value | Description |
---|---|
0 | None |
1 | SessionId |
2 | SessionTicket |
RenegotiationMode
This is "nn::ssl::sf::RenegotiationMode" or "nn::ssl::Connection::RenegotiationMode".
Value | Description |
---|---|
0 | None |
1 | Secure |
OptionType
This is "nn::ssl::sf::OptionType" or "nn::ssl::Connection::OptionType".
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":
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 SetVerifyOption and "EnableAlpn" is only available with SetOption.
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".
Value | Description |
---|---|
0 | NoSupport |
1 | Negotiated |
2 | NoOverlap |
3 | Selected |
4 | EarlyValue |
CipherInfo
This is "nn::ssl::Connection::CipherInfo". This is a 0x48-byte struct.
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.
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 strnlen(struct+0x10, 0x40) , 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).
[19.0.0+] "/ssl_TrustedCerts.Ounce.bdf" updated
#ISslContext automatically uses this CertStore, regardless of the used cmds.
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 | #TrustedCertStatus |
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.