Part II
On 1/18/2012 4:23 PM, Brian Smith wrote:
> Sean Leonard wrote:
>> and no log information.
>
> Firefox has also been bitten by this and this is one of the things
blocking the switch to libpkix as the default mechanism in Firefox.
However, sometime soon I may just propose that we change to handle
certificate overrides like Chrome does, in which case the log would
become much less important for us. See bug 699874 and the bugs that are
referred to by that bug.
>
>> The only output (in the revoked case) is
>> SEC_ERROR_REVOKED_CERTIFICATE. This is extremely unhelpful because it
>> is a material distinction to know that the EE cert was revoked,
>> versus an intermediary or root CA.
>
> Does libpkix return SEC_ERROR_REVOKED_CERTIFICATE in the case where
an intermediate has been revoked? I would kind of expect that it would
return whatever error it returns for "could not build a path to a trust
anchor" instead, for the same reason I think it cannot return a partial
chain.
When I last tested it, I recall that SEC_ERROR_REVOKED_CERTIFICATE was
returned for intermediate certs.
When certLog is returned from CERT_VerifyCertificate, all validation
errors with all certs (in the single path) are added. The
CERTVerifyLogNode (certt.h) includes the depth, so multiple log entries
can have the same depth (aka, same cert) but different error codes. It
is up to the application to make sense of it and to correlate them
together, but at least you can get all of the errors out.
>> Such an error also masks other possible problems, such as whether
>> a certificate has expired, lacks trust bits, or other information.
>
> Hopefully, libpkix at least returns the most serious problem. Have
you found this to be the case? I realize that "most serious" is a
judgement call that may vary by application, but at least Firefox
separates cert errors into two buckets: overridable (e.g. expriation,
untrusted issuer) and too-bad-to-allow-user-override (e.g. revocation).
As suggested in Part I, "most serious problem" really depends on your
perspective and application. Let's take "revoked" as an example.
Revocation has reason codes in CRLs, and in OCSP responses too under the
RevokedInfo -> revocationReason element. keyCompromise(1) is a fairly
serious situation, but in that case, you may actually want to invalidate
(i.e., treat as not valid) the cert *prior to* the revocation time, such
as with the RFC 5280 sec. 5.3.2 Invalidity Date extension.
Contrast this with privilegeWithdrawn(9), which we joke internally is
the "failure to pay" reason code. If someone fails to pay for their
cert, that is bad, but probably not *as* bad in the grand scheme of
things as keyCompromise(1). It also may trigger a different UI: "this
deadbeat failed to pay" versus "some Evil Eve stole this person's
private key". In contrast, expiration--particularly expiration from a
long time ago--is probably worse than privilegeWithdrawn(9).
Regarding the buckets: that is all well and good. It's worth driving
home that it would be nice if all applications that use NSS/libpkix are
starting with the same, fat deck of cards, that they can then separate
into buckets of their choosing.
>
>> Per above, we never used non-blocking I/O from libpkix; we use it in
>> blocking mode but call it on a worker thread. Non-blocking I/O never
>> seemed to work when we tried it, and in general we felt that doing
>> anything more than absolutely necessary on the main thread was a
>> recipe for non-deterministic behavior.
>
> This is also what Firefox and Chrome do internally, and this is why
the non-blocking I/O feature is not seen as being necessary.
"ok"
Removing non-blocking I/O completely from libpkix may also save a
non-negligible amount of codegen. Some libpkix entry points (such as
PKIX_ValidateChain_NB) are not used at all, and therefore should be
optimized away, but there are non-trivial parts of functions that check
if (nonblocking) and such that are almost certainly not optimized away
in the current code.
>> The downside to blocking mode is that the API is one-shot: it is not
>> possible to check on the "progress" of validation until it magically
>> completes. When you have CRLs that are>> 10MB, this is an issue.
>> However, this can be worked around (e.g., calling it twice: once for
>> constructing a chain without revocation checking, and another time
>> with revocation checking), and one-shot definitely simplifies the
>> API for everyone.
>
> As I mentioned in another thread, it may be the case that we have to
completely change the way CRL, OCSP, and cert fetching is done in
libpkix, or in libpkix-based applications anyway, for performance
reasons. I have definitely been thinking about doing things in Gecko in
a way that is similar to what you suggest above.
Which thread?
Correction: I said "a chain" but I should have said "a chain, but
ideally, chains".
On the topic of chains, comparing the behavior of
CertGetCertificateChain is very useful. In the MS API (which has been
around for over 13 years), they assign each path a quality score, and
return the "best" path in the primary return. However, an application
can get all the chains if it wishes with
CERT_CHAIN_RETURN_LOWER_QUALITY_CONTEXTS. (See struct
CERT_CHAIN_CONTEXT.) The fact that it assigns quality scores and picks
the best implies that the MS API actually computes all the chains, so
the option not to return lower quality contexts likely does not change
the overall speed. Aside from the cert/revocation
fetching-over-the-network issue, I don't think anyone can complain about
the slowness of CertGetCertificateChain. That API also returns
validation results on a per-chain and per-certificate basis using a bit
mask, so all possible validation errors can be conveyed in one swoop.
CertGetCertificateChain also identifies specific revocation information,
including reason codes and the actual CRL entry on which the revocation
result was derived. Use MSDN to look up:
CERT_CHAIN_CONTEXT / CERT_CHAIN_ELEMENT / CERT_REVOCATION_INFO /
CERT_REVOCATION_CRL_INFO.
-Sean
--
dev-tech-crypto mailing list
dev-tech-crypto@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-tech-crypto