This is an enhancement proposal to simplify life of application programmers.
Besides the initial call NSS_Init* call, NSS applications are required to call various NSS functions, in order to enable or disable certain features of the library.
I propose that NSS implenents a new function NSS_SetContemporaryPolicy()
that would enable the set of features that is seen as reasonable by the NSS developers.
An application developer could decide to not research the full set of cipher and SSL/TLS features that are desired for proper contemporary operation, but rather want to rely on a reasonable standard set.
However, this simplicity would be combined with unsteadiness. The NSS developers have the explicit right to change the behaviour of NSS_SetContemporaryPolicy() with any new release. By making use ot the NSS_SetContemporaryPolicy() API the developers would explicitly accept this behaviour.
I suggest this for clients. Optionally, it might be worth considering a default policy functions for servers, too.
Things we could include in this policy:
- which ciphers are enabled/disabled
- which TLS protocol features are enabled/disabled
Thanks to Florian Weimer for the inspiration for this proposal.
Speaking as an application developer who is presently using NSS, I happen to consider it a bug that the NSS API is insecure by default (I consider bug 815990 to be a bug). I'm not a cryptographer, am too busy to keep up to date on modern cryptographic literature and thus do not consider myself qualified to determine what cipher suites should be enabled by default. I would like the cryptographic library to do that for me.
This enhancement is a good step in the right direction and I'd very much appreciate it. There's a related enhancement request in bug 358440.
FYI, my product currently ships with AES ciphers disabled by default because I'd prefer not to override the set of default cipher suites enabled by NSS without a very good reason. You can see the code I used as the attachment to bug 358440. I already had to override default NSS policy to turn off the weak ciphers and didn't like doing that.
> FYI, my product currently ships with AES ciphers disabled by default
> because I'd prefer not to override the set of default cipher suites
> enabled by NSS
The "good reason" to override is that NSS in its current form was not designed to be used without doing so. As painful as it is you're much much better off copying the choices made by a well-regarded open-source app. I don't know if your application is a client or server; if it's a client look at what Firefox does, if it's a server copy one of the nss-using servers shipped by Red Hat.
The feature request in this bug sounds like a fantastic idea to help library users get off to a good start. In the meantime, though, NSS's arcane API is not a great excuse for knowingly shipping a product with poor defaults.
Just noticed your @oracle address. In that case copy what the nss-using formerly-Sun servers do. Should be mostly equivalent (though I know Red Hat and Sun folks disagreed on the ECC ciphers).
(In reply to Daniel Veditz [:dveditz] from comment #4)
> In that case copy what the nss-using formerly-Sun servers do.
I guess this amounts to him copying his own code, then... see e.g. RFC 4642 for the former affiliation of Chris.
This might be classified as bike-shedding, anyway...
Should it be "...SystemPolicy" instead, to make it explicit that system's configuration might in principle override the defaults and policy (i.e. that a particular version of NSS is not guaranteed to always use the same "ContemporaryPolicy" on all systems and platforms)?
Even nicer would be to provide a single NSS_Init$something that would do all of this in a single step, using the system's policy, key storage etc - that's probably a separate discussion.
(In reply to Miloslav Trmač from comment #6)
> Should it be "...SystemPolicy" instead, to make it explicit that system's
> configuration might in principle override the defaults and policy (i.e. that
> a particular version of NSS is not guaranteed to always use the same
> "ContemporaryPolicy" on all systems and platforms)?
That's a different proposal. I think you suggest that in the future NSS might allow the operating system to define defaults, and that NSS respects them. I believe that's different from what we have today, and in order for that to work, we'd have to have implementations on each platform. Furthermore, what happens if the system doesn't define a policy, or doesn't have the technical infrastructure to define the systemwide preferences? In that case you need a fallback. What I'm suggesting to implement in this bug might or might be appropriate for such a fallback. But I believe these are different problems to solve.
> Even nicer would be to provide a single NSS_Init$something that would do all
> of this in a single step, using the system's policy, key storage etc -
> that's probably a separate discussion.
I'd also say that's a different proposal, which might or not be implemented, and could be discussed in a separate bug. Your proposal might be as simple as a forwarding function, which calls both NSS_Init* and the NSS_SetContemporaryPolicy().
The current idea of NSS is to be backwards compatible, and that the application is required in one way or the other, to define what behaviour the app wants. If the documentation for NSS_Init* clearly mentioned that one must set some policy afterwards, and mentions this function implemented here as a good default strategy, that might be sufficient.
(In reply to Kai Engert (:kaie) from comment #7)
> (In reply to Miloslav Trmač from comment #6)
> > Should it be "...SystemPolicy" instead, to make it explicit that system's
> > configuration might in principle override the defaults and policy (i.e. that
> > a particular version of NSS is not guaranteed to always use the same
> > "ContemporaryPolicy" on all systems and platforms)?
> That's a different proposal. I think you suggest that in the future NSS
> might allow the operating system to define defaults, and that NSS respects
Well, "NSS does the what it judges is best, taking respect to the OS policy" or something.
> I believe that's different from what we have today, and in order for
> that to work, we'd have to have implementations on each platform.
Not immediately; we can start with "SystemPolicy" being equal to "ContemporaryPolicy".
> Furthermore, what happens if the system doesn't define a policy, or doesn't
> have the technical infrastructure to define the systemwide preferences?
NSS policy governs.
> that case you need a fallback. What I'm suggesting to implement in this bug
> might or might be appropriate for such a fallback. But I believe these are
> different problems to solve.
The problem I'm trying to solve is allowing applications to get "good security" with zero maintenance or zero need to make similar policy decisions. The benefit of the original proposal is that applications don't need to choose specific ciphers or protocol versions, leaving such decisions to the experts.
The reason I bring up ...SystemPolicy now is this: Suppose we add ...ContemporaryPolicy now, and ...SystemPolicy in two or three years. Then we will end up with applications that again need to choose between ...ContemporaryPolicy and ...SystemPolicy, partially negating the benefit of the original change. So designing a long-term API, even if it does not change an implementation, would, I think, simplify the application writer's life.
(Of course it does not necessarily have to be named "System". It may be "Default", "HandsOff", "Experts" or anything else appropriate.)
> > Even nicer would be to provide a single NSS_Init$something that would do all
> > of this in a single step, using the system's policy, key storage etc -
> > that's probably a separate discussion.
> I'd also say that's a different proposal, which might or not be implemented,
> and could be discussed in a separate bug. Your proposal might be as simple
> as a forwarding function, which calls both NSS_Init* and the
Yes, that's exactly what I had in mind, and you're right that it can be considered separately.
Ok, so the thing I'm worried about here is the reason we need this function. If I'm following the argument correctly, it goes:
1) NSS defaults suck in the for a modern environment, enabling too many old ciphers that are obsolete/weak and not enabling new ciphers which are not.
2) NSS provides binary compatibility claims, which makes it difficult or impossible to change these defaults to something more rational.
Therefore let's create a function which sets these defaults appropriately.
The problem I have with this is 5 years from now what ContemporaryPolicy sets would either change (ABI issues again), or will be 5 years out of data.
Let me propose an alternative: Let's build a new rational list of defaults for NSS. An environment variable sets those defaults back to the old NSS traditional defaults for those applications that would absolutely break if we change these defaults. Then there would be no need to ContemporaryPolicy().
If we are worried about OS's that have to keep the old defaults globally, we could add this function of override that globally old defaults. On a 'modern' NSS that has the rational defaults, it would be a no op.
Longer term, I really want NSS to have it's defaults set by an administrator (independent of the running application). This would allow these defaults to update without changes to the underlying NSS code.
Created attachment 715653 [details] [diff] [review]
Patch that demonstrates NSS_SetDomesticPolicy could be cleaned up
Our solution to the NSS_SetDomesticPolicy problem should be to make it
unnecessary to call NSS_SetDomesticPolicy.
In theory it may break some apps. (It's instructive to think what kind of app
might be broken if NSS would call NSS_SetDomesticPolicy implicitly.) In
practice I believe it will be an uneventful change just like to recent change
to enable AES cipher suites by default.
I studied the NSS_SetDomesticPolicy code and immediately found bit rot,
demonstrated by this patch. Bob, I think you are the best person to advise
on the cleanup because the rest of us all joined the NSS team after Y2K.
Created attachment 715662 [details] [diff] [review]
Remove the unused 'export' and 'france' fields of the cipherPolicy structure
The 'export' and 'france' fields of the cipherPolicy structure
are now unused. Once we remove them, the cipherPolicy structure
is left with just an "int cipher" field, so I remove the
cipherPolicy structure type altogether.
I believe it is possible to use some other arrays of SSL and
TLS cipher suites instead of this ssl_ciphers array, but I don't
have time to look into that today.
I'll +1 to proposal in comment 9. API compatibility is important and is one area where NSS is a complete win over OpenSSL. However, I have heard that surveys have shown that customers are OK with breaking compatibility when it is done for the specific reason of improving security in a significant way. I think enabling more secure cipher suites by default and disabling weak ones by default meets that criteria.
At least with our versions of 3.14.0 and 3.14.3, NSS_SetDomesticPolicy automatically enables a reasonable set of cipher suites:
Cipher Suite: TLS_EMPTY_RENEGOTIATION_INFO_SCSV (0x00ff)
Cipher Suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x0039)
Cipher Suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA (0x0038)
Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0x0035)
Cipher Suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA (0x0033)
Cipher Suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA (0x0032)
Cipher Suite: TLS_RSA_WITH_RC4_128_SHA (0x0005)
Cipher Suite: TLS_RSA_WITH_RC4_128_MD5 (0x0004)
Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)
Cipher Suite: TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA (0x0016)
Cipher Suite: TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA (0x0013)
Cipher Suite: TLS_RSA_WITH_3DES_EDE_CBC_SHA (0x000a)
All of them appear reasonably secure (and we can't really avoid RC4 for interoperability purposes).
The changes in 3.14 were due to bug 792681.
This will be addressed in bug 848384.
*** This bug has been marked as a duplicate of bug 848384 ***
I marked this bug as a duplicate of bug 848384 incorrectly.