Closed Bug 1272858 Opened 4 years ago Closed 3 years ago

built-in root detection is broken if libnssckbi decides to call its built-in token something other than "Builtin Object Token"

Categories

(Core :: Security: PSM, defect, P1)

46 Branch
defect

Tracking

()

RESOLVED FIXED
mozilla50
Tracking Status
firefox50 --- fixed

People

(Reporter: bugzilla, Assigned: keeler)

Details

(Whiteboard: [psm-assigned])

Attachments

(1 file)

User Agent: Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:46.0) Gecko/20100101 Firefox/46.0
Build ID: 20160503092831

Steps to reproduce:

Visit an https site which is secured by an certificate which is issued by the DFN structure.   


Actual results:

Because of the structure of DFN most scientific and academic institutes have it's ons CA.
So the chain are: German Telekom->DFN->campus of the institute->server.
But only the German Telekom certificate are stored in the default store.
So all servers will deliver the DFN and campus intermediate certificate.
But than firefox will reject the HPKP settings. But there will exchange often very sensitive data(Healthcare). So every user must change the settings to protect MITM attacks.


Expected results:

The the HPKP settings send by the server's are accepted.
Here is the list of the DFN sub CA's:
https://info.pca.dfn.de
This are an very long list, so I think it will not practicable to add every sub CA to the store.
I don't know why we don't do this (Tim?), but it's certainly not a security-sensitive bug as the default setting is publicly available information.
Group: firefox-core-security
Component: Untriaged → Security: PSM
Flags: needinfo?(ttaubert)
Product: Firefox → Core
Summary: Default settings for security.cert_pinning.process_headers_from_non_builtin_roots useless in Germany. → Default security.cert_pinning.process_headers_from_non_builtin_roots to true
The default policy of not processing HPKP headers from non-built-in roots is to prevent a network DoSing a user when they go to another network (as in, if it were possible for network A that is doing MitM to set pins, when the user moves to network B, no certificate chain will satisfy those pins, so connections will fail).

However, that doesn't sound like what's going on here. Original reporter - do users have to import additional root certificates for connections to these servers to succeed in the first place? If not, it just sounds like the headers as presented to Firefox are deficient in some way. Maybe they're missing a backup key? Is there any output in either the web console or the browser console?
Flags: needinfo?(ttaubert) → needinfo?(bugzilla)
No, the user don't need to import an certificate.
The certificate chain is clean. And an backup pin is also provided.
Using chrome, will work as it shut do.
In the output the firebug console I get error, that pinning is not done because the server certificate are not from build in ca.
I think the problem are the intermediate ca certificates.
Flags: needinfo?(bugzilla)
Interesting - are you seeing the same behavior with a new profile? Also, it might help to have some specifics. Can you post an HPKP header that one of the servers is trying to set, as well as the certificate chain as verified? (click the lock icon, then the right arrow icon, then "more information", then "view certificate", then "details", and then "export" (and choose "export certificate with chain (PEM)" in the drop-down). Thanks!
Flags: needinfo?(bugzilla)
(In reply to David Keeler [:keeler] (use needinfo?) from comment #3)
> The default policy of not processing HPKP headers from non-built-in roots is
> to prevent a network DoSing a user when they go to another network (as in,
> if it were possible for network A that is doing MitM to set pins, when the
> user moves to network B, no certificate chain will satisfy those pins, so
> connections will fail).

Could you elaborate on why this scenario is applicable only to non-builtin roots? It seems to me it is no different with builtin roots in case of MitM.
If network A is not performing MitM and a site sets pins, when the user moves to network B that is performing MitM (and where the user has the MitM root imported and trusted), Firefox will find a trusted path to a non-built-in root. By default, Firefox doesn't enforce pins for non-built-in roots, so the connection succeeds (this is controlled by the pref security.cert_pinning.enforcement_level, which can be 0: disable pinning, 1: don't enforce pinning for non-built-in roots (default), 2: enforce pinning, 3: enforce pinning even for preloaded pins in "test mode").
I understand this is what happens with current default settings but why is this a desirable behaviour? If a user deliberately adds a root CA to the store, it seems useful for it to support HPKP out of the box. The utility of HPKP support doesn't seem to depend on it being a builtin root.
I will try to show you an sample site tomorrow for it.
Example: https://alpha-labs.net
It use another chain, but the same result.
The top ca are in the store, but not the intermediate ca.
Message from the browser console:
Public-Key-Pins: The certificate used by the site was not issued by a certificate in the default root certificate store. To prevent accidental breakage, the specified header was ignored.
Flags: needinfo?(bugzilla)
I'm not seeing that error message in the console on my profile, which suggests there's something different between the root certificates in our two profiles. If you run Firefox with a new profile, are you seeing the same behavior? Are you using a version of Firefox you downloaded from Mozilla or a version from a Linux distribution (for example)?
Flags: needinfo?(bugzilla)
I can reproduce it with an new profile on CentOS 7 with the ESR version and on Fedora 23 using 46.01.
Flags: needinfo?(bugzilla)
Looks like Fedora is calling the builtin root token "Default Trust" rather than "Builtin Object Token", so anything that relies on that is broken.
Assignee: nobody → dkeeler
Status: UNCONFIRMED → ASSIGNED
Ever confirmed: true
Summary: Default security.cert_pinning.process_headers_from_non_builtin_roots to true → built-in root detection is broken if libnssckbi decides to call its built-in token something other than "Builtin Object Token"
Whiteboard: [psm-assigned]
Previously this implementation would use the expected names of the built-in
module and slot to get a handle on them. This doesn't work on distributions that
use other names. The new implementation searches through the slots from the
default module list for one where PK11_HasRootCerts returns true (which
indicates that NSS considers that slot to contain the default built-in root
list).

Review commit: https://reviewboard.mozilla.org/r/60436/diff/#index_header
See other reviews: https://reviewboard.mozilla.org/r/60436/
Attachment #8764759 - Flags: review?(cykesiopka.bmo)
Priority: -- → P1
Attachment #8764759 - Flags: review?(cykesiopka.bmo) → review+
Comment on attachment 8764759 [details]
bug 1272858 - use a name-agnostic method to find the built-in root PKCS#11 slot

https://reviewboard.mozilla.org/r/60436/#review57592

Looks good.

::: security/certverifier/CertVerifier.cpp:103
(Diff revision 1)
> -  nsAutoString modName;
> -  rv = component->GetPIPNSSBundleString("RootCertModuleName", modName);
> +  SECMODListLock* lock = SECMOD_GetDefaultModuleListLock();
> +  if (!lock) {
> -  if (NS_FAILED(rv)) {
>      return Result::FATAL_ERROR_LIBRARY_FAILURE;
>    }
> -  NS_ConvertUTF16toUTF8 modNameUTF8(modName);
> +  SECMOD_GetReadLock(lock);

Probably follow up material, but something like AutoSECMODListReadLock might be nicer here:
https://hg.mozilla.org/mozilla-central/file/71b02a7c2340/security/manager/ssl/nsPKCS11Slot.h#l83

Maybe we can move that to a common location, and modify it so that the constructor takes a bool outparam indicating success or failure?
I see a few more places in PSM where manual calls are used to take and free the SECMOD read lock.
Comment on attachment 8764759 [details]
bug 1272858 - use a name-agnostic method to find the built-in root PKCS#11 slot

Review request updated; see interdiff: https://reviewboard.mozilla.org/r/60436/diff/1-2/
(In reply to :Cykesiopka from comment #15)
> Probably follow up material, but something like AutoSECMODListReadLock might
> be nicer here:
> https://hg.mozilla.org/mozilla-central/file/71b02a7c2340/security/manager/
> ssl/nsPKCS11Slot.h#l83
> 
> Maybe we can move that to a common location, and modify it so that the
> constructor takes a bool outparam indicating success or failure?
> I see a few more places in PSM where manual calls are used to take and free
> the SECMOD read lock.

Good call. I think the success/failure of AutoSECMODListReadLock as an assertion is fine, since that really should only fail when NSS hasn't been initialized (and if NSS hasn't been initialized, things would have failed before reaching that point). I'll file a follow-up for using AutoSECMODListReadLock elsewhere where appropriate.
Pushed by dkeeler@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/50a6f462a97c
use a name-agnostic method to find the built-in root PKCS#11 slot r=Cykesiopka
https://hg.mozilla.org/mozilla-central/rev/50a6f462a97c
Status: ASSIGNED → RESOLVED
Closed: 3 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla50
You need to log in before you can comment on or make changes to this bug.