This message is long.  Please bear with me.

On 2008-12-18, Dan Kegel reported in this thread that
we can't call SSL_PeerCertificate after the
bad-certificate callback function returns because the
peer certificate has been destroyed:

http://www.nabble.com/A-tip-for-novice-users-of-SSL_BadCertHook-and-SSL_PeerCertificate-td21080085.html

However, recently while working with another Chromium
developer, I noticed that he is calling SSL_PeerCertificate
after the handshake is completed.  So I inspected the NSS
and PSM source code to understand why.

Note: The way Chromium uses NSS to verify SSL server
certificates has changed since Dan Kegel posted that message.
Since certificate verification can block indefinitely while
downloading CRLs or talking to OCSP responders, Chromium
is verifying certificates on a thread pool (so it won't block the
message loop of the main thread) after the handshake is completed.
Chromium now has an auth-certificate callback that always
returns SECSuccess, and is no longer using a bad-certificate
callback.

Here are my findings from inspecting the PSM and NSS source
code.

1. SSL_PeerCertificate can be called during the handshake
completion callback, because PSM does that:

http://bonsai.mozilla.org/cvsblame.cgi?file=mozilla/security/manager/ssl/src/nsNSSIOLayer.cpp&rev=1.165&mark=3092#3080

http://bonsai.mozilla.org/cvsblame.cgi?file=mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp&rev=1.73&mark=847,871,905#847

2. In the NSS source code, I didn't find any evidence
that the peer certificate is destroyed as soon as the
handshake is completed.  On the contrary, I only found
that we destroy the peer certificate when we close the
SSL socket.  Specifically, I found that peerCert and
peerCertChain are destroyed in the ssl_DestroySecurityInfo
and ssl3_DestroySSL3Info calls in

http://mxr.mozilla.org/security/ident?i=ssl_DestroySocketContents

which is called by ssl_FreeSocket.

So I believe that the Note that I added to our documentation
is wrong, or at least confusing:

  To obtain the certificate that was rejected by the certificate
  authentication callback, the bad-certificate callback function
  calls SSL_PeerCertificate. Since it is called immediately
  after the certificate authentication callback returns, the
  bad-certificate callback function can obtain the error code
  set by the certificate authentication callback by calling
  PR_GetError immediately, as the first operation it performs.

  Note: once the bad-certificate callback function returns,
  the peer certificate is destroyed, and SSL_PeerCertificate
  will fail.

It seems that the peer certificate is destroyed only if the
bad-certificate callback function returns SECFailure.  If
there is no certificate error or the bad-certificate callback
ignores a certificate error (returning SECSuccess), it seems
that we can call SSL_PeerCertificate all the way until the
SSL socket is closed.

Does anyone know exactly when we destroy the peer
certificate and peer certificate chain?

Thanks,
Wan-Teh Chang
-- 
dev-tech-crypto mailing list
dev-tech-crypto@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-tech-crypto

Reply via email to