TLS Client NSS: Rely on NSS 3.14 cipher suite defaults

Older versions needed application code to actually enable strong
ciphers, but this changed in version 3.14.
This commit is contained in:
Florian Weimer 2013-04-02 17:12:57 +02:00
parent c861995515
commit 04d4055034
4 changed files with 21 additions and 76 deletions

View file

@ -768,8 +768,13 @@
<title>Implementing TLS Clients With NSS</title>
<para>
The following code shows how to implement a simple TLS client
using NSS. Note that the error handling needs replacing
before production use.
using NSS. These instructions apply to NSS version 3.14 and
later. Versions before 3.14 need different initialization
code.
</para>
<para>
Keep in mind that the error handling needs to be improved
before the code can be used in production.
</para>
<para>
Using NSS needs several header files, as shown in
@ -781,17 +786,13 @@
xmlns:xi="http://www.w3.org/2001/XInclude" />
</example>
<para>
Initializing the NSS library is a complex task (<xref
linkend="ex-Defensive_Coding-TLS-NSS-Init"/>). It is not
thread-safe. By default, the library is in export mode, and
all strong ciphers are disabled. Therefore, after creating
the <literal>NSSInitCContext</literal> object, we probe all
the strong ciphers we want to use, and check if at least one
of them is available. If not, we call
<function>NSS_SetDomesticPolicy</function> to switch to
unrestricted policy mode. This function replaces the existing
global cipher suite policy, that is why we avoid calling it
unless absolutely necessary.
Initializing the NSS library is shown in <xref
linkend="ex-Defensive_Coding-TLS-NSS-Init"/>. This
initialization procedure overrides global state. We only call
<function>NSS_SetDomesticPolicy</function> if there are no
strong ciphers available, assuming that it has already been
called otherwise. This avoids overriding the process-wide
cipher suite policy unnecessarily.
</para>
<para>
The simplest way to configured the trusted root certificates
@ -825,11 +826,7 @@
function is de-facto part of the NSS public ABI, so it will
not go away.) Creating the TLS-capable file descriptor
requires a <emphasis>model</emphasis> descriptor, which is
configured with the desired set of protocols and ciphers.
(The <literal>good_ciphers</literal> variable is part of <xref
linkend="ex-Defensive_Coding-TLS-NSS-Init"/>.) We cannot
resort to disabling ciphers not on a whitelist because by
default, the AES cipher suites are disabled. The model
configured with the desired set of protocols. The model
descriptor is not needed anymore after TLS support has been
activated for the existing connection descriptor.
</para>

View file

@ -39,32 +39,6 @@ sockfd = -1; // Has been taken over by NSPR.
exit(1);
}
// Disable all ciphers (except RC4-based ciphers, for backwards
// compatibility).
const PRUint16 *const ciphers = SSL_GetImplementedCiphers();
for (unsigned i = 0; i &#60; SSL_GetNumImplementedCiphers(); i++) {
if (ciphers[i] != SSL_RSA_WITH_RC4_128_SHA
&#38;&#38; ciphers[i] != SSL_RSA_WITH_RC4_128_MD5) {
if (SSL_CipherPrefSet(model, ciphers[i], PR_FALSE) != SECSuccess) {
const PRErrorCode err = PR_GetError();
fprintf(stderr, "error: disable cipher %u: error %d: %s\n",
(unsigned)ciphers[i], err, PR_ErrorToName(err));
exit(1);
}
}
}
// Enable the strong ciphers.
for (const PRUint16 *p = good_ciphers; *p != SSL_NULL_WITH_NULL_NULL;
++p) {
if (SSL_CipherPrefSet(model, *p, PR_TRUE) != SECSuccess) {
const PRErrorCode err = PR_GetError();
fprintf(stderr, "error: enable cipher %u: error %d: %s\n",
(unsigned)*p, err, PR_ErrorToName(err));
exit(1);
}
}
// Allow overriding invalid certificate.
if (SSL_BadCertHook(model, bad_certificate, (char *)host) != SECSuccess) {
const PRErrorCode err = PR_GetError();

View file

@ -23,9 +23,9 @@ static const PRUint16 good_ciphers[] = {
};
// Check if the current policy allows any strong ciphers. If it
// doesn't, switch to the "domestic" (unrestricted) policy. This is
// not thread-safe and has global impact. Consequently, we only do
// it if absolutely necessary.
// doesn't, set the cipher suite policy. This is not thread-safe
// and has global impact. Consequently, we only do it if absolutely
// necessary.
int found_good_cipher = 0;
for (const PRUint16 *p = good_ciphers; *p != SSL_NULL_WITH_NULL_NULL;
++p) {

View file

@ -114,9 +114,9 @@ main(int argc, char **argv)
};
// Check if the current policy allows any strong ciphers. If it
// doesn't, switch to the "domestic" (unrestricted) policy. This is
// not thread-safe and has global impact. Consequently, we only do
// it if absolutely necessary.
// doesn't, set the cipher suite policy. This is not thread-safe
// and has global impact. Consequently, we only do it if absolutely
// necessary.
int found_good_cipher = 0;
for (const PRUint16 *p = good_ciphers; *p != SSL_NULL_WITH_NULL_NULL;
++p) {
@ -190,32 +190,6 @@ main(int argc, char **argv)
exit(1);
}
// Disable all ciphers (except RC4-based ciphers, for backwards
// compatibility).
const PRUint16 *const ciphers = SSL_GetImplementedCiphers();
for (unsigned i = 0; i < SSL_GetNumImplementedCiphers(); i++) {
if (ciphers[i] != SSL_RSA_WITH_RC4_128_SHA
&& ciphers[i] != SSL_RSA_WITH_RC4_128_MD5) {
if (SSL_CipherPrefSet(model, ciphers[i], PR_FALSE) != SECSuccess) {
const PRErrorCode err = PR_GetError();
fprintf(stderr, "error: disable cipher %u: error %d: %s\n",
(unsigned)ciphers[i], err, PR_ErrorToName(err));
exit(1);
}
}
}
// Enable the strong ciphers.
for (const PRUint16 *p = good_ciphers; *p != SSL_NULL_WITH_NULL_NULL;
++p) {
if (SSL_CipherPrefSet(model, *p, PR_TRUE) != SECSuccess) {
const PRErrorCode err = PR_GetError();
fprintf(stderr, "error: enable cipher %u: error %d: %s\n",
(unsigned)*p, err, PR_ErrorToName(err));
exit(1);
}
}
// Allow overriding invalid certificate.
if (SSL_BadCertHook(model, bad_certificate, (char *)host) != SECSuccess) {
const PRErrorCode err = PR_GetError();