SSL services: Difference between revisions

 
(56 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.
This has IPC max_sessions = 0x40.


{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 25: Line 31:
|-
|-
| 8 || [6.0.0+] [[#GetDebugOption]]
| 8 || [6.0.0+] [[#GetDebugOption]]
|-
| 9 || [14.0.0+] [[#ClearTls12FallbackFlag]]
|}
|}


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


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


Line 140: Line 157:
The input buffer can contain multiple certs. A maximum of 71 ServerPki objects (associated with the output Id) can be imported.
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 rootCAs or server certs.
The certs can be CAs or server certs (no pubkeys).
 
The [[#CertificateFormat]] only validated, afterwards it's ignored.


=== ImportClientPki ===
=== ImportClientPki ===
Line 167: Line 186:
=== ImportCrl ===
=== ImportCrl ===
Takes a type-0x5 input buffer, returns an output u64 Id.
Takes a type-0x5 input buffer, returns an output u64 Id.
The input buffer contains the DER CRL.


=== 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 233: 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 406: 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 =
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=1.0/max=1.2.
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"
|-
|-
! Bit
! Bits
! Description
! Description
|-
|-
Line 422: Line 664:
|-
|-
| 5 || TlsV12
| 5 || TlsV12
|-
| 6 || [11.0.0+] TlsV13
|-
| 24-31 || [11.0.0+] ApiVersion
|}
|}


Line 513: Line 759:
|-
|-
| 2 || NintendoClass2CAG3
| 2 || NintendoClass2CAG3
|-
| 3 || [16.0.0+] "Nintendo Root CA G4"
|-
|-
| 1000 || AmazonRootCA1
| 1000 || AmazonRootCA1
Line 581: Line 829:
|-
|-
| 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"
|-
| 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 598: Line 1,028:
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 and the [[#CertStore]].
"DeviceClientCertDefault" enables using the DeviceCert.


= ContextOption =
= ContextOption =
Line 726: 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 765: 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 773: Line 1,239:
* [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]]. See [[#CaCertificateId]] for the ssl_TrustedCerts changes.
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
 
[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.


These have the following structure:
These have the following structure: