diff options
author | wtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-05 17:36:27 +0000 |
---|---|---|
committer | wtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-05 17:36:27 +0000 |
commit | b1ade49d8e06ff9044f7a9973793c1bc35a75ccd (patch) | |
tree | f431fda8e5983ae8683c27304b2faa93c8a21c06 /net/ocsp | |
parent | 90b721e6713f6429a24fe03d4f0dbab588f7dc46 (diff) | |
download | chromium_src-b1ade49d8e06ff9044f7a9973793c1bc35a75ccd.zip chromium_src-b1ade49d8e06ff9044f7a9973793c1bc35a75ccd.tar.gz chromium_src-b1ade49d8e06ff9044f7a9973793c1bc35a75ccd.tar.bz2 |
Our HTTP client callback functions for NSS must set an NSS/NSPR error
code on failure to prevent NSS from using a residual error code from
an earlier, unrelated failure.
When we retry CERT_PKIXVerifyCert with AIA certificate fetch enabled,
handle two more error codes that may be set by the AIA certificate
fetch code on failure.
R=eroman,ukai
BUG=33126,36371
TEST=Visit https://student-partners.com/default.aspx. We should get
the certificate not trusted error page rather than net::ERR_FAILED.
Review URL: http://codereview.chromium.org/1600009
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@43624 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/ocsp')
-rw-r--r-- | net/ocsp/nss_ocsp.cc | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/net/ocsp/nss_ocsp.cc b/net/ocsp/nss_ocsp.cc index c135dfd..8b9cbca 100644 --- a/net/ocsp/nss_ocsp.cc +++ b/net/ocsp/nss_ocsp.cc @@ -97,6 +97,11 @@ class OCSPInitSingleton : public MessageLoop::DestructionObserver { : io_loop_(MessageLoopForIO::current()) { DCHECK(io_loop_); io_loop_->AddDestructionObserver(this); + + // NSS calls the functions in the function table to download certificates + // or CRLs or talk to OCSP responders over HTTP. These functions must + // set an NSS/NSPR error code when they fail. Otherwise NSS will get the + // residual error code from an earlier failed function call. client_fcn_.version = 1; SEC_HttpClientFcnV1Struct *ft = &client_fcn_.fcnTable.ftable1; ft->createSessionFcn = OCSPCreateSession; @@ -421,8 +426,10 @@ class OCSPServerSession { // We dont' support "https" because we haven't thought about // whether it's safe to re-enter this code from talking to an OCSP // responder over SSL. - if (strcmp(http_protocol_variant, "http") != 0) + if (strcmp(http_protocol_variant, "http") != 0) { + PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); return NULL; + } // TODO(ukai): If |host| is an IPv6 literal, we need to quote it with // square brackets []. @@ -455,6 +462,10 @@ SECStatus OCSPCreateSession(const char* host, PRUint16 portnum, DCHECK(!MessageLoop::current()); if (OCSPInitSingleton::url_request_context() == NULL) { LOG(ERROR) << "No URLRequestContext for OCSP handler."; + // The application failed to call SetURLRequestContextForOCSP, so we + // can't create and use URLRequest. PR_NOT_IMPLEMENTED_ERROR is not an + // accurate error code for this error condition, but is close enough. + PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); return SECFailure; } *pSession = new OCSPServerSession(host, portnum); @@ -532,20 +543,21 @@ SECStatus OCSPAddHeader(SEC_HTTP_REQUEST_SESSION request, // It is helper routine for OCSP trySendAndReceiveFcn. // |http_response_data_len| could be used as input parameter. If it has // non-zero value, it is considered as maximum size of |http_response_data|. -bool OCSPSetResponse(OCSPRequestSession* req, - PRUint16* http_response_code, - const char** http_response_content_type, - const char** http_response_headers, - const char** http_response_data, - PRUint32* http_response_data_len) { +SECStatus OCSPSetResponse(OCSPRequestSession* req, + PRUint16* http_response_code, + const char** http_response_content_type, + const char** http_response_headers, + const char** http_response_data, + PRUint32* http_response_data_len) { DCHECK(req->Finished()); const std::string& data = req->http_response_data(); if (http_response_data_len && *http_response_data_len) { if (*http_response_data_len < data.size()) { - LOG(ERROR) << "data size too large: " << *http_response_data_len + LOG(ERROR) << "response body too large: " << *http_response_data_len << " < " << data.size(); *http_response_data_len = data.size(); - return false; + PORT_SetError(SEC_ERROR_BAD_HTTP_RESPONSE); + return SECFailure; } } LOG(INFO) << "OCSP response " @@ -563,7 +575,7 @@ bool OCSPSetResponse(OCSPRequestSession* req, *http_response_data = data.data(); if (http_response_data_len) *http_response_data_len = data.size(); - return true; + return SECSuccess; } SECStatus OCSPTrySendAndReceive(SEC_HTTP_REQUEST_SESSION request, @@ -599,7 +611,7 @@ SECStatus OCSPTrySendAndReceive(SEC_HTTP_REQUEST_SESSION request, http_response_content_type, http_response_headers, http_response_data, - http_response_data_len) ? SECSuccess : SECFailure; + http_response_data_len); failed: if (http_response_data_len) { @@ -607,6 +619,7 @@ SECStatus OCSPTrySendAndReceive(SEC_HTTP_REQUEST_SESSION request, // means the failure was unrelated to the acceptable response data length. *http_response_data_len = 0; } + PORT_SetError(SEC_ERROR_BAD_HTTP_RESPONSE); // Simple approximation. return SECFailure; } |