Part III

On 1/18/2012 4:23 PM, Brian Smith wrote:
Sean Leonard wrote:
>> We do not currently use HTTP or LDAP certificate stores with respect
>> to libpkix/the functionality that is exposed by CERT_PKIXVerifyCert.
>> That being said, it is conceivable that others could use this feature,
>> and we could use it in the future. We have definitely seen LDAP URLs in
>> certificates that we have to validate (for example), and although
>> Firefox does not ship with the Mozilla Directory (LDAP) SDK,
>> Thunderbird does. Therefore, we encourage the maintainers to leave it
>> in. We can contribute some test LDAP services if that is necessary for
>> real-world testing.
>
> Definitely, I am concerned about how to test and maintain the LDAP code. And, I am not sure LDAP support is important for a modern web browser at least. Email clients may be a different story. One option may be to provide an option to CERT_PKIXVerifyCert to disable LDAP fetching but keep HTTP fetching enabled, to allow applications to minimize exposure to any possible LDAP-related exploits.

I'll see what we can do about setting up some example LDAP servers. From my own experience, I have seen several major CAs run by governments in production that include LDAP URLs. If the web browsers are being used on internal/intranet networks (as is increasingly the case with webapps taking over the world) then LDAP URLs remain useful for web browsers. In my review of RFC 5280 vs. CERT_PKIXVerifyCert, I devoted a section to this topic (see "Access Methods").

nsNSSCallbacks.cpp is where the NSS<->Necko bindings live. See nsNSSHttpInterface. SEC_RegisterDefaultHttpClient registers these bindings with NSS; then, libpkix (in pkix_pl_httpcertstore.c, and pkix_pl_ocspresponse.c) obtains these pointers with SEC_GetRegisteredHttpClient.

LDAP services are channeled through pkix_pl_ldapcertstore.c, and serviced by the "default LDAP client", which exists in pkix_pl_ldapdefaultclient.c. This in turn relies on pkix_pl_socket.c for sundries such as pkix_pl_Socket_Create, which in turn (finally!) rely on NSPR sockets, with functions like PR_NewTCPSocket and PR_Send. Unlike HTTP, LDAP is actually implemented by libpkix itself. The advantage is that LDAP should work on every platform, without OpenLDAP or Wldap32, and without the Mozilla Directory (LDAP) SDK--which means that it ought to work in Firefox. The disadvantage is that LDAP may not take advantage of SOCKS or other proxies that are configured at the Necko layer.

>
>> Congruence or mostly-similar
>> behavior with Thunderbird is also important, as it is awkward to
>> explain to users why Penango provides materially different
>> validation results from Thunderbird.
>
> I expect that Thunderbird to change to use CERT_PKIXVerifyCert exclusively around the time that we make that change in Firefox, if not exactly at the same time.

"ok"

As I understand it, there are currently no less than six APIs (and four different sets of functionality) that can be used to verify certificates:

CERT_PKIXVerifyCert, "the long-term preferred one".


CERT_VerifyCertChain, which depending on CERT_GetUsePKIXForValidation/CERT_SetUsePKIXForValidation, calls cert_VerifyCertChainPkix (which uses libpkix but actually uses a slightly different code path compared to CERT_PKIXVerifyCert) or cert_VerifyCertChainOld [which is REALLY old] NB: by setting the not-really-documented-but-appears-in-a-few-scattered-bugzilla-bugs environment variable, NSS_ENABLE_PKIX_VERIFY, a user can flip the SetUsePKIXForValidation switch.


CERT_VerifyCertificate, which is a gross amalgamation of a lot of hairballs improved over time, but seems to be the one that is actually used by the vast majority of Mozilla applications; unless you call one of the PSM functions and set the boolean pref security.use_libpkix_verification, in which case PSM will attempt (mostly) to use CERT_PKIXVerifyCert. However, an application that calls CERT_VerifyCertificate directly will not be affected.
 -> CERT_VerifyCertificateNow (just uses PR_Now())


CERT_VerifyCert, which is a likewise gross amalgamation, except that in the middle of the gross amalgamation it calls CERT_VerifyCertChain (so it has mostly equivalent but not exactly the same functionality as CERT_VerifyCertChain, including the NSS_ENABLE_PKIX_VERIFY detour). I thought this one was not supposed to be used, as there is a comment: "obsolete, do not use for new code" on CERT_VerifyCertNow, but there it is, plain as day, in nsNSSCallbacks.cpp, nsNSSCertificate.cpp, and nsNSSCertificateDB.cpp.
 -> CERT_VerifyCertNow (just uses PR_Now())


Firefox and Thunderbird appear to use CERT_PKIXVerifyCert and CERT_VerifyCertificate(Now), and CERT_VerifyCert(Now) in different places.

Consolidating these API calls to one API would seem to be sorely desired (and, if alternate APIs are removed or simplified, may result in a non-trivial size reduction); *except* that each API call has its own strange idiosyncrasies and are probably there because some application somewhere relied upon the behavior. CERT_PKIXVerifyCert ought to be vetted pretty heavily (and appropriate output parameters added) before trying to remove or manipulate old functionality.

>>    From our testing, libpkix/PKIX_CERTVerifyCert is pretty close to RFC
>> 5280 as it stands. It would be cheaper and more useful for the
>> Internet community if the maintainers put the 5% more effort necessary
>> to "finish the job", than the 95% to break compliance. If this is
>> something that you want to see to believe, I can try to compile some
>> kind of a spreadsheet that illustrates how RFC 5280 stacks up with
>> the current PKIX_CERTVerifyCert behavior.
>
> It would be really awesome if you could do so.

I have written a detailed Google Spreadsheet titled "RFC 5280 vs. CERT_PKIXVerifyCert":
http://goo.gl/r2sT3

In several places, I either stepped through the code manually with real certs, or examined the code using lookups and mental compilation to confirm the correct code paths. For the name constraints tests (permitted_subtrees and excluded_subtrees), I created a collapsible call hierarchy so that people can see how exactly the dependencies unwind: http://goo.gl/vfv1K (for that one, you should open it in Excel).

Once the spreadsheet gets to a more finished state, it can be moved to somewhere more permanent such as on a Mozilla wiki.

During my analysis, I was pleased to find that virtually all of RFC 5280 was implemented properly by libpkix--props to the designers for that. Yet it was disappointing to find that all of the juicy libpkix output (which is always computed) is not remembered by the NSS binding functions cert_VerifyCertChainPkix and CERT_PKIXVerifyCert! For example, RFC 5280 requires a policy_tree and working_public_key info output variables. These outputs might seem extremely complicated, but are actually computed properly by libpkix. What a shame to see that these outputs (in PKIX_BuildResultStruct and PKIX_ValidateResultStruct) are not marshaled into cert_po_* variables! There is even a cert_po_policyOID output variable that remains unimplemented (note: implementing an array of policy OIDs is actually much less helpful--and perhaps dangerous--compared with getting the original policy_tree).

>> As stated, we would like to move away from using
>> CERT_VerifyCertificate,
>> provided that CERT_PKIXVerifyCert is strictly better.
>> CERT_PKIXVerifyCert has significant gaps in functionality that need
>> to be addressed first.
>
> Thanks. Previously, we assumed it would be OK to switch all certificate path validation to libpkix, including callers of the old functions. (See bug 653572.) It is good to know that we need to be more careful here.

Yes. Per above, CERT_SetUsePKIXForValidation does not even cover all API calls.

>> As I indicated back in July in the thread "Validating custom extended
>> key usage (EKU) with NSS", the PKIX API doesn't provide a way to
>> validate usages of anything other than e-mail, code signing, and
>> SSL/TLS [...] I hope that this area of the code is improved and
>> exposed to apps, rather than put in the scrap heap.
>
> I am not opposed to having such enhancements made to libpkix. But, also, I don't think it would be a good idea to wait for Mozilla or Google or Red Hat to implement such improvements unless/until we ever need them for our products. However, it seems like a straightforward improvement that would be relatively easy to review, so I think we could at least get it reviewed in a (relatively) timely manner and checked in. I encourage you to file a bug and submit a patch and test cases.


Thanks. Hopefully I will have time, someday.

> Anyway, thanks again for the email. This was very useful.
>
> - Brian

You are welcome.

-Sean
--
dev-tech-crypto mailing list
dev-tech-crypto@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-tech-crypto

Reply via email to