diff options
author | wtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-15 22:29:03 +0000 |
---|---|---|
committer | wtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-15 22:29:03 +0000 |
commit | 2e9a5b698138c69caec06230cd841cc00301b415 (patch) | |
tree | d36382e88987e0dbdf23215d9f9fa730b474b192 /net | |
parent | 547ef14b0ea37bc32cdf7e9d2ded91edf5725629 (diff) | |
download | chromium_src-2e9a5b698138c69caec06230cd841cc00301b415.zip chromium_src-2e9a5b698138c69caec06230cd841cc00301b415.tar.gz chromium_src-2e9a5b698138c69caec06230cd841cc00301b415.tar.bz2 |
Add a context-sensitive error mapping function specific to SSL
handshake errors. It should never return a certificate error
because we don't have the server's certificate when handshake
fails.
R=agl
BUG=24064
TEST=Visit the test URL in issue 24064 comment 8 on Linux. Chromium
should not crash.
Review URL: http://codereview.chromium.org/550026
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@36426 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r-- | net/base/x509_certificate_nss.cc | 2 | ||||
-rw-r--r-- | net/socket/ssl_client_socket_nss.cc | 56 |
2 files changed, 26 insertions, 32 deletions
diff --git a/net/base/x509_certificate_nss.cc b/net/base/x509_certificate_nss.cc index f7dbd71..05ed979 100644 --- a/net/base/x509_certificate_nss.cc +++ b/net/base/x509_certificate_nss.cc @@ -121,6 +121,8 @@ int MapSecurityError(int err) { return ERR_NAME_NOT_RESOLVED; case SEC_ERROR_INVALID_ARGS: return ERR_INVALID_ARGUMENT; + case SSL_ERROR_BAD_CERT_DOMAIN: + return ERR_CERT_COMMON_NAME_INVALID; case SEC_ERROR_INVALID_TIME: case SEC_ERROR_EXPIRED_CERTIFICATE: return ERR_CERT_DATE_INVALID; diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc index 13f02ae..05c61dd 100644 --- a/net/socket/ssl_client_socket_nss.cc +++ b/net/socket/ssl_client_socket_nss.cc @@ -96,7 +96,9 @@ namespace net { namespace { -int NetErrorFromNSPRError(PRErrorCode err) { +// The default error mapping function. +// Maps an NSPR error code to a network error code. +int MapNSPRError(PRErrorCode err) { // TODO(port): fill this out as we learn what's important switch (err) { case PR_WOULD_BLOCK_ERROR: @@ -119,22 +121,8 @@ int NetErrorFromNSPRError(PRErrorCode err) { return ERR_ADDRESS_INVALID; case SSL_ERROR_NO_CYPHER_OVERLAP: + case SSL_ERROR_UNSUPPORTED_VERSION: return ERR_SSL_VERSION_OR_CIPHER_MISMATCH; - case SSL_ERROR_BAD_CERT_DOMAIN: - return ERR_CERT_COMMON_NAME_INVALID; - case SEC_ERROR_EXPIRED_CERTIFICATE: - return ERR_CERT_DATE_INVALID; - case SEC_ERROR_BAD_SIGNATURE: - return ERR_CERT_INVALID; - case SSL_ERROR_REVOKED_CERT_ALERT: - case SEC_ERROR_REVOKED_CERTIFICATE: - case SEC_ERROR_REVOKED_KEY: - return ERR_CERT_REVOKED; - case SEC_ERROR_CA_CERT_INVALID: - case SEC_ERROR_UNKNOWN_ISSUER: - case SEC_ERROR_UNTRUSTED_CERT: - case SEC_ERROR_UNTRUSTED_ISSUER: - return ERR_CERT_AUTHORITY_INVALID; case SSL_ERROR_HANDSHAKE_FAILURE_ALERT: return ERR_SSL_PROTOCOL_ERROR; @@ -144,12 +132,6 @@ int NetErrorFromNSPRError(PRErrorCode err) { " mapped to net::ERR_SSL_PROTOCOL_ERROR"; return ERR_SSL_PROTOCOL_ERROR; } - if (IS_SEC_ERROR(err)) { - // TODO(port): Probably not the best mapping - LOG(WARNING) << "Unknown SEC error " << err << - " mapped to net::ERR_CERT_INVALID"; - return ERR_CERT_INVALID; - } LOG(WARNING) << "Unknown error " << err << " mapped to net::ERR_FAILED"; return ERR_FAILED; @@ -157,6 +139,23 @@ int NetErrorFromNSPRError(PRErrorCode err) { } } +// Context-sensitive error mapping functions. + +int MapHandshakeError(PRErrorCode err) { + switch (err) { + // If the server closed on us, it is a protocol error. + // Some TLS-intolerant servers do this when we request TLS. + case PR_END_OF_FILE_ERROR: + // The handshake may fail because some signature (for example, the + // signature in the ServerKeyExchange message for an ephemeral + // Diffie-Hellman cipher suite) is invalid. + case SEC_ERROR_BAD_SIGNATURE: + return ERR_SSL_PROTOCOL_ERROR; + default: + return MapNSPRError(err); + } +} + } // namespace bool SSLClientSocketNSS::nss_options_initialized_ = false; @@ -1040,14 +1039,7 @@ int SSLClientSocketNSS::DoHandshake() { // Done! } else { PRErrorCode prerr = PR_GetError(); - - // If the server closed on us, it is a protocol error. - // Some TLS-intolerant servers do this when we request TLS. - if (prerr == PR_END_OF_FILE_ERROR) { - net_error = ERR_SSL_PROTOCOL_ERROR; - } else { - net_error = NetErrorFromNSPRError(prerr); - } + net_error = MapHandshakeError(prerr); // If not done, stay in this state if (net_error == ERR_IO_PENDING) { @@ -1161,7 +1153,7 @@ int SSLClientSocketNSS::DoPayloadRead() { return ERR_IO_PENDING; } LeaveFunction(""); - return NetErrorFromNSPRError(prerr); + return MapNSPRError(prerr); } int SSLClientSocketNSS::DoPayloadWrite() { @@ -1178,7 +1170,7 @@ int SSLClientSocketNSS::DoPayloadWrite() { return ERR_IO_PENDING; } LeaveFunction(""); - return NetErrorFromNSPRError(prerr); + return MapNSPRError(prerr); } } // namespace net |