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