| OLD | NEW |
| 1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // This file includes code GetDefaultCertNickname(), derived from | 5 // This file includes code GetDefaultCertNickname(), derived from |
| 6 // nsNSSCertificate::defaultServerNickName() | 6 // nsNSSCertificate::defaultServerNickName() |
| 7 // in mozilla/security/manager/ssl/src/nsNSSCertificate.cpp | 7 // in mozilla/security/manager/ssl/src/nsNSSCertificate.cpp |
| 8 // and SSLClientSocketNSS::DoVerifyCertComplete() derived from | 8 // and SSLClientSocketNSS::DoVerifyCertComplete() derived from |
| 9 // AuthCertificateCallback() in | 9 // AuthCertificateCallback() in |
| 10 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp. | 10 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp. |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 * decision by deleting the provisions above and replace them with the notice | 44 * decision by deleting the provisions above and replace them with the notice |
| 45 * and other provisions required by the GPL or the LGPL. If you do not delete | 45 * and other provisions required by the GPL or the LGPL. If you do not delete |
| 46 * the provisions above, a recipient may use your version of this file under | 46 * the provisions above, a recipient may use your version of this file under |
| 47 * the terms of any one of the MPL, the GPL or the LGPL. | 47 * the terms of any one of the MPL, the GPL or the LGPL. |
| 48 * | 48 * |
| 49 * ***** END LICENSE BLOCK ***** */ | 49 * ***** END LICENSE BLOCK ***** */ |
| 50 | 50 |
| 51 #include "net/socket/ssl_client_socket_nss.h" | 51 #include "net/socket/ssl_client_socket_nss.h" |
| 52 | 52 |
| 53 #include <certdb.h> | 53 #include <certdb.h> |
| 54 #include <keyhi.h> |
| 54 #include <nspr.h> | 55 #include <nspr.h> |
| 55 #include <nss.h> | 56 #include <nss.h> |
| 56 #include <secerr.h> | 57 #include <secerr.h> |
| 57 // Work around https://bugzilla.mozilla.org/show_bug.cgi?id=455424 | 58 // Work around https://bugzilla.mozilla.org/show_bug.cgi?id=455424 |
| 58 // until NSS 3.12.2 comes out and we update to it. | 59 // until NSS 3.12.2 comes out and we update to it. |
| 59 #define Lock FOO_NSS_Lock | 60 #define Lock FOO_NSS_Lock |
| 60 #include <ssl.h> | 61 #include <ssl.h> |
| 61 #include <sslerr.h> | 62 #include <sslerr.h> |
| 62 #include <pk11pub.h> | 63 #include <pk11pub.h> |
| 63 #undef Lock | 64 #undef Lock |
| 64 | 65 |
| 65 #include "base/compiler_specific.h" | 66 #include "base/compiler_specific.h" |
| 66 #include "base/logging.h" | 67 #include "base/logging.h" |
| 67 #include "base/nss_init.h" | 68 #include "base/nss_init.h" |
| 68 #include "base/string_util.h" | 69 #include "base/string_util.h" |
| 69 #include "net/base/cert_verifier.h" | 70 #include "net/base/cert_verifier.h" |
| 70 #include "net/base/io_buffer.h" | 71 #include "net/base/io_buffer.h" |
| 71 #include "net/base/net_errors.h" | 72 #include "net/base/net_errors.h" |
| 73 #include "net/base/ssl_cert_request_info.h" |
| 72 #include "net/base/ssl_info.h" | 74 #include "net/base/ssl_info.h" |
| 73 #include "net/ocsp/nss_ocsp.h" | 75 #include "net/ocsp/nss_ocsp.h" |
| 74 | 76 |
| 75 static const int kRecvBufferSize = 4096; | 77 static const int kRecvBufferSize = 4096; |
| 76 | 78 |
| 77 namespace net { | 79 namespace net { |
| 78 | 80 |
| 79 // State machines are easier to debug if you log state transitions. | 81 // State machines are easier to debug if you log state transitions. |
| 80 // Enable these if you want to see what's going on. | 82 // Enable these if you want to see what's going on. |
| 81 #if 1 | 83 #if 1 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 157 return ERR_CERT_INVALID; | 159 return ERR_CERT_INVALID; |
| 158 case SSL_ERROR_REVOKED_CERT_ALERT: | 160 case SSL_ERROR_REVOKED_CERT_ALERT: |
| 159 case SEC_ERROR_REVOKED_CERTIFICATE: | 161 case SEC_ERROR_REVOKED_CERTIFICATE: |
| 160 case SEC_ERROR_REVOKED_KEY: | 162 case SEC_ERROR_REVOKED_KEY: |
| 161 return ERR_CERT_REVOKED; | 163 return ERR_CERT_REVOKED; |
| 162 case SEC_ERROR_CA_CERT_INVALID: | 164 case SEC_ERROR_CA_CERT_INVALID: |
| 163 case SEC_ERROR_UNKNOWN_ISSUER: | 165 case SEC_ERROR_UNKNOWN_ISSUER: |
| 164 case SEC_ERROR_UNTRUSTED_CERT: | 166 case SEC_ERROR_UNTRUSTED_CERT: |
| 165 case SEC_ERROR_UNTRUSTED_ISSUER: | 167 case SEC_ERROR_UNTRUSTED_ISSUER: |
| 166 return ERR_CERT_AUTHORITY_INVALID; | 168 return ERR_CERT_AUTHORITY_INVALID; |
| 169 case SSL_ERROR_HANDSHAKE_FAILURE_ALERT: |
| 170 return ERR_SSL_PROTOCOL_ERROR; |
| 167 | 171 |
| 168 default: { | 172 default: { |
| 169 if (IS_SSL_ERROR(err)) { | 173 if (IS_SSL_ERROR(err)) { |
| 170 LOG(WARNING) << "Unknown SSL error " << err << | 174 LOG(WARNING) << "Unknown SSL error " << err << |
| 171 " mapped to net::ERR_SSL_PROTOCOL_ERROR"; | 175 " mapped to net::ERR_SSL_PROTOCOL_ERROR"; |
| 172 return ERR_SSL_PROTOCOL_ERROR; | 176 return ERR_SSL_PROTOCOL_ERROR; |
| 173 } | 177 } |
| 174 if (IS_SEC_ERROR(err)) { | 178 if (IS_SEC_ERROR(err)) { |
| 175 // TODO(port): Probably not the best mapping | 179 // TODO(port): Probably not the best mapping |
| 176 LOG(WARNING) << "Unknown SEC error " << err << | 180 LOG(WARNING) << "Unknown SEC error " << err << |
| (...skipping 21 matching lines...) Expand all Loading... |
| 198 transport_recv_busy_(false), | 202 transport_recv_busy_(false), |
| 199 handshake_io_callback_(this, &SSLClientSocketNSS::OnHandshakeIOComplete), | 203 handshake_io_callback_(this, &SSLClientSocketNSS::OnHandshakeIOComplete), |
| 200 transport_(transport_socket), | 204 transport_(transport_socket), |
| 201 hostname_(hostname), | 205 hostname_(hostname), |
| 202 ssl_config_(ssl_config), | 206 ssl_config_(ssl_config), |
| 203 user_connect_callback_(NULL), | 207 user_connect_callback_(NULL), |
| 204 user_read_callback_(NULL), | 208 user_read_callback_(NULL), |
| 205 user_write_callback_(NULL), | 209 user_write_callback_(NULL), |
| 206 user_read_buf_len_(0), | 210 user_read_buf_len_(0), |
| 207 user_write_buf_len_(0), | 211 user_write_buf_len_(0), |
| 212 client_auth_ca_names_(NULL), |
| 213 client_auth_cert_needed_(false), |
| 208 completed_handshake_(false), | 214 completed_handshake_(false), |
| 209 next_handshake_state_(STATE_NONE), | 215 next_handshake_state_(STATE_NONE), |
| 210 nss_fd_(NULL), | 216 nss_fd_(NULL), |
| 211 nss_bufs_(NULL) { | 217 nss_bufs_(NULL) { |
| 212 EnterFunction(""); | 218 EnterFunction(""); |
| 213 } | 219 } |
| 214 | 220 |
| 215 SSLClientSocketNSS::~SSLClientSocketNSS() { | 221 SSLClientSocketNSS::~SSLClientSocketNSS() { |
| 216 EnterFunction(""); | 222 EnterFunction(""); |
| 217 Disconnect(); | 223 Disconnect(); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 311 #endif | 317 #endif |
| 312 | 318 |
| 313 rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE); | 319 rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE); |
| 314 if (rv != SECSuccess) | 320 if (rv != SECSuccess) |
| 315 return ERR_UNEXPECTED; | 321 return ERR_UNEXPECTED; |
| 316 | 322 |
| 317 rv = SSL_AuthCertificateHook(nss_fd_, OwnAuthCertHandler, this); | 323 rv = SSL_AuthCertificateHook(nss_fd_, OwnAuthCertHandler, this); |
| 318 if (rv != SECSuccess) | 324 if (rv != SECSuccess) |
| 319 return ERR_UNEXPECTED; | 325 return ERR_UNEXPECTED; |
| 320 | 326 |
| 327 rv = SSL_GetClientAuthDataHook(nss_fd_, ClientAuthHandler, this); |
| 328 if (rv != SECSuccess) |
| 329 return ERR_UNEXPECTED; |
| 330 |
| 321 rv = SSL_HandshakeCallback(nss_fd_, HandshakeCallback, this); | 331 rv = SSL_HandshakeCallback(nss_fd_, HandshakeCallback, this); |
| 322 if (rv != SECSuccess) | 332 if (rv != SECSuccess) |
| 323 return ERR_UNEXPECTED; | 333 return ERR_UNEXPECTED; |
| 324 | 334 |
| 325 // Tell SSL the hostname we're trying to connect to. | 335 // Tell SSL the hostname we're trying to connect to. |
| 326 SSL_SetURL(nss_fd_, hostname_.c_str()); | 336 SSL_SetURL(nss_fd_, hostname_.c_str()); |
| 327 | 337 |
| 328 // Tell SSL we're a client; needed if not letting NSPR do socket I/O | 338 // Tell SSL we're a client; needed if not letting NSPR do socket I/O |
| 329 SSL_ResetHandshake(nss_fd_, 0); | 339 SSL_ResetHandshake(nss_fd_, 0); |
| 330 | 340 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 366 user_read_callback_ = NULL; | 376 user_read_callback_ = NULL; |
| 367 user_write_callback_ = NULL; | 377 user_write_callback_ = NULL; |
| 368 user_read_buf_ = NULL; | 378 user_read_buf_ = NULL; |
| 369 user_read_buf_len_ = 0; | 379 user_read_buf_len_ = 0; |
| 370 user_write_buf_ = NULL; | 380 user_write_buf_ = NULL; |
| 371 user_write_buf_len_ = 0; | 381 user_write_buf_len_ = 0; |
| 372 server_cert_ = NULL; | 382 server_cert_ = NULL; |
| 373 server_cert_verify_result_.Reset(); | 383 server_cert_verify_result_.Reset(); |
| 374 completed_handshake_ = false; | 384 completed_handshake_ = false; |
| 375 nss_bufs_ = NULL; | 385 nss_bufs_ = NULL; |
| 386 if (client_auth_ca_names_) { |
| 387 CERT_FreeDistNames(client_auth_ca_names_); |
| 388 client_auth_ca_names_ = NULL; |
| 389 } |
| 390 client_auth_cert_needed_ = false; |
| 376 | 391 |
| 377 LeaveFunction(""); | 392 LeaveFunction(""); |
| 378 } | 393 } |
| 379 | 394 |
| 380 bool SSLClientSocketNSS::IsConnected() const { | 395 bool SSLClientSocketNSS::IsConnected() const { |
| 381 // Ideally, we should also check if we have received the close_notify alert | 396 // Ideally, we should also check if we have received the close_notify alert |
| 382 // message from the server, and return false in that case. We're not doing | 397 // message from the server, and return false in that case. We're not doing |
| 383 // that, so this function may return a false positive. Since the upper | 398 // that, so this function may return a false positive. Since the upper |
| 384 // layer (HttpNetworkTransaction) needs to handle a persistent connection | 399 // layer (HttpNetworkTransaction) needs to handle a persistent connection |
| 385 // closed by the server when we send a request anyway, a false positive in | 400 // closed by the server when we send a request anyway, a false positive in |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 501 UpdateServerCert(); | 516 UpdateServerCert(); |
| 502 } | 517 } |
| 503 ssl_info->cert_status = server_cert_verify_result_.cert_status; | 518 ssl_info->cert_status = server_cert_verify_result_.cert_status; |
| 504 DCHECK(server_cert_ != NULL); | 519 DCHECK(server_cert_ != NULL); |
| 505 ssl_info->cert = server_cert_; | 520 ssl_info->cert = server_cert_; |
| 506 LeaveFunction(""); | 521 LeaveFunction(""); |
| 507 } | 522 } |
| 508 | 523 |
| 509 void SSLClientSocketNSS::GetSSLCertRequestInfo( | 524 void SSLClientSocketNSS::GetSSLCertRequestInfo( |
| 510 SSLCertRequestInfo* cert_request_info) { | 525 SSLCertRequestInfo* cert_request_info) { |
| 511 // TODO(wtc): implement this. | 526 EnterFunction(""); |
| 527 cert_request_info->host_and_port = hostname_; |
| 528 cert_request_info->client_certs.clear(); |
| 529 |
| 530 void* wincx = SSL_RevealPinArg(nss_fd_); |
| 531 |
| 532 CERTCertNicknames* names = CERT_GetCertNicknames( |
| 533 CERT_GetDefaultCertDB(), SEC_CERT_NICKNAMES_USER, wincx); |
| 534 |
| 535 if (names) { |
| 536 for (int i = 0; i < names->numnicknames; ++i) { |
| 537 CERTCertificate* cert = CERT_FindUserCertByUsage( |
| 538 CERT_GetDefaultCertDB(), names->nicknames[i], |
| 539 certUsageSSLClient, PR_FALSE, wincx); |
| 540 if (!cert) |
| 541 continue; |
| 542 // Only check unexpired certs. |
| 543 if (CERT_CheckCertValidTimes(cert, PR_Now(), PR_TRUE) == |
| 544 secCertTimeValid && |
| 545 NSS_CmpCertChainWCANames(cert, client_auth_ca_names_) == |
| 546 SECSuccess) { |
| 547 SECKEYPrivateKey* privkey = PK11_FindKeyByAnyCert(cert, wincx); |
| 548 if (privkey) { |
| 549 X509Certificate* x509_cert = X509Certificate::CreateFromHandle( |
| 550 cert, X509Certificate::SOURCE_LONE_CERT_IMPORT); |
| 551 cert_request_info->client_certs.push_back(x509_cert); |
| 552 SECKEY_DestroyPrivateKey(privkey); |
| 553 continue; |
| 554 } |
| 555 } |
| 556 CERT_DestroyCertificate(cert); |
| 557 } |
| 558 CERT_FreeNicknames(names); |
| 559 } |
| 560 LeaveFunction(cert_request_info->client_certs.size()); |
| 512 } | 561 } |
| 513 | 562 |
| 514 void SSLClientSocketNSS::DoReadCallback(int rv) { | 563 void SSLClientSocketNSS::DoReadCallback(int rv) { |
| 515 EnterFunction(rv); | 564 EnterFunction(rv); |
| 516 DCHECK(rv != ERR_IO_PENDING); | 565 DCHECK(rv != ERR_IO_PENDING); |
| 517 DCHECK(user_read_callback_); | 566 DCHECK(user_read_callback_); |
| 518 | 567 |
| 519 // Since Run may result in Read being called, clear |user_read_callback_| | 568 // Since Run may result in Read being called, clear |user_read_callback_| |
| 520 // up front. | 569 // up front. |
| 521 CompletionCallback* c = user_read_callback_; | 570 CompletionCallback* c = user_read_callback_; |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 814 // in full handshake mode or in resumption handshake mode. | 863 // in full handshake mode or in resumption handshake mode. |
| 815 SECStatus SSLClientSocketNSS::OwnAuthCertHandler(void* arg, | 864 SECStatus SSLClientSocketNSS::OwnAuthCertHandler(void* arg, |
| 816 PRFileDesc* socket, | 865 PRFileDesc* socket, |
| 817 PRBool checksig, | 866 PRBool checksig, |
| 818 PRBool is_server) { | 867 PRBool is_server) { |
| 819 // Tell NSS to not verify the certificate. | 868 // Tell NSS to not verify the certificate. |
| 820 return SECSuccess; | 869 return SECSuccess; |
| 821 } | 870 } |
| 822 | 871 |
| 823 // static | 872 // static |
| 873 // NSS calls this if a client certificate is needed. |
| 874 // Based on Mozilla's NSS_GetClientAuthData. |
| 875 SECStatus SSLClientSocketNSS::ClientAuthHandler( |
| 876 void* arg, |
| 877 PRFileDesc* socket, |
| 878 CERTDistNames* ca_names, |
| 879 CERTCertificate** result_certificate, |
| 880 SECKEYPrivateKey** result_private_key) { |
| 881 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); |
| 882 |
| 883 that->client_auth_cert_needed_ = !that->ssl_config_.send_client_cert; |
| 884 |
| 885 // Second pass: a client certificate should have been selected. |
| 886 if (that->ssl_config_.send_client_cert) { |
| 887 if (that->ssl_config_.client_cert) { |
| 888 void* wincx = SSL_RevealPinArg(socket); |
| 889 CERTCertificate* cert = CERT_DupCertificate( |
| 890 that->ssl_config_.client_cert->os_cert_handle()); |
| 891 SECKEYPrivateKey* privkey = PK11_FindKeyByAnyCert(cert, wincx); |
| 892 if (privkey) { |
| 893 // TODO(jsorianopastor): We should wait for server certificate |
| 894 // verification before sending our credentials. See |
| 895 // http://crbug.com/13934. |
| 896 *result_certificate = cert; |
| 897 *result_private_key = privkey; |
| 898 return SECSuccess; |
| 899 } |
| 900 LOG(WARNING) << "Client cert found without private key"; |
| 901 } |
| 902 // Send no client certificate. |
| 903 return SECFailure; |
| 904 } |
| 905 |
| 906 PRArenaPool* arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
| 907 CERTDistNames* ca_names_copy = PORT_ArenaZNew(arena, CERTDistNames); |
| 908 |
| 909 ca_names_copy->arena = arena; |
| 910 ca_names_copy->head = NULL; |
| 911 ca_names_copy->nnames = ca_names->nnames; |
| 912 ca_names_copy->names = PORT_ArenaZNewArray(arena, SECItem, |
| 913 ca_names->nnames); |
| 914 for (int i = 0; i < ca_names->nnames; ++i) |
| 915 SECITEM_CopyItem(arena, &ca_names_copy->names[i], &ca_names->names[i]); |
| 916 |
| 917 that->client_auth_ca_names_ = ca_names_copy; |
| 918 return SECFailure; |
| 919 } |
| 920 |
| 921 // static |
| 824 // NSS calls this when handshake is completed. | 922 // NSS calls this when handshake is completed. |
| 825 // After the SSL handshake is finished, use CertVerifier to verify | 923 // After the SSL handshake is finished, use CertVerifier to verify |
| 826 // the saved server certificate. | 924 // the saved server certificate. |
| 827 void SSLClientSocketNSS::HandshakeCallback(PRFileDesc* socket, | 925 void SSLClientSocketNSS::HandshakeCallback(PRFileDesc* socket, |
| 828 void* arg) { | 926 void* arg) { |
| 829 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); | 927 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); |
| 830 | 928 |
| 831 that->UpdateServerCert(); | 929 that->UpdateServerCert(); |
| 832 } | 930 } |
| 833 | 931 |
| 834 int SSLClientSocketNSS::DoHandshake() { | 932 int SSLClientSocketNSS::DoHandshake() { |
| 835 EnterFunction(""); | 933 EnterFunction(""); |
| 836 int net_error = net::OK; | 934 int net_error = net::OK; |
| 837 int rv = SSL_ForceHandshake(nss_fd_); | 935 SECStatus rv = SSL_ForceHandshake(nss_fd_); |
| 838 | 936 |
| 839 if (rv == SECSuccess) { | 937 if (client_auth_cert_needed_) { |
| 938 net_error = ERR_SSL_CLIENT_AUTH_CERT_NEEDED; |
| 939 // If the handshake already succeeded (because the server requests but |
| 940 // doesn't require a client cert), we need to invalidate the SSL session |
| 941 // so that we won't try to resume the non-client-authenticated session in |
| 942 // the next handshake. This will cause the server to ask for a client |
| 943 // cert again. |
| 944 if (rv == SECSuccess && SSL_InvalidateSession(nss_fd_) != SECSuccess) { |
| 945 LOG(WARNING) << "Couldn't invalidate SSL session: " << PR_GetError(); |
| 946 } |
| 947 } else if (rv == SECSuccess) { |
| 840 // SSL handshake is completed. Let's verify the certificate. | 948 // SSL handshake is completed. Let's verify the certificate. |
| 841 GotoState(STATE_VERIFY_CERT); | 949 GotoState(STATE_VERIFY_CERT); |
| 842 // Done! | 950 // Done! |
| 843 } else { | 951 } else { |
| 844 PRErrorCode prerr = PR_GetError(); | 952 PRErrorCode prerr = PR_GetError(); |
| 845 | 953 |
| 846 // If the server closed on us, it is a protocol error. | 954 // If the server closed on us, it is a protocol error. |
| 847 // Some TLS-intolerant servers do this when we request TLS. | 955 // Some TLS-intolerant servers do this when we request TLS. |
| 848 if (prerr == PR_END_OF_FILE_ERROR) { | 956 if (prerr == PR_END_OF_FILE_ERROR) { |
| 849 net_error = ERR_SSL_PROTOCOL_ERROR; | 957 net_error = ERR_SSL_PROTOCOL_ERROR; |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 939 // Exit DoHandshakeLoop and return the result to the caller to Connect. | 1047 // Exit DoHandshakeLoop and return the result to the caller to Connect. |
| 940 DCHECK(next_handshake_state_ == STATE_NONE); | 1048 DCHECK(next_handshake_state_ == STATE_NONE); |
| 941 return result; | 1049 return result; |
| 942 } | 1050 } |
| 943 | 1051 |
| 944 int SSLClientSocketNSS::DoPayloadRead() { | 1052 int SSLClientSocketNSS::DoPayloadRead() { |
| 945 EnterFunction(user_read_buf_len_); | 1053 EnterFunction(user_read_buf_len_); |
| 946 DCHECK(user_read_buf_); | 1054 DCHECK(user_read_buf_); |
| 947 DCHECK(user_read_buf_len_ > 0); | 1055 DCHECK(user_read_buf_len_ > 0); |
| 948 int rv = PR_Read(nss_fd_, user_read_buf_->data(), user_read_buf_len_); | 1056 int rv = PR_Read(nss_fd_, user_read_buf_->data(), user_read_buf_len_); |
| 1057 if (client_auth_cert_needed_) { |
| 1058 // We don't need to invalidate the non-client-authenticated SSL session |
| 1059 // because the server will renegotiate anyway. |
| 1060 LeaveFunction(""); |
| 1061 return ERR_SSL_CLIENT_AUTH_CERT_NEEDED; |
| 1062 } |
| 949 if (rv >= 0) { | 1063 if (rv >= 0) { |
| 950 LogData(user_read_buf_->data(), rv); | 1064 LogData(user_read_buf_->data(), rv); |
| 951 LeaveFunction(""); | 1065 LeaveFunction(""); |
| 952 return rv; | 1066 return rv; |
| 953 } | 1067 } |
| 954 PRErrorCode prerr = PR_GetError(); | 1068 PRErrorCode prerr = PR_GetError(); |
| 955 if (prerr == PR_WOULD_BLOCK_ERROR) { | 1069 if (prerr == PR_WOULD_BLOCK_ERROR) { |
| 956 LeaveFunction(""); | 1070 LeaveFunction(""); |
| 957 return ERR_IO_PENDING; | 1071 return ERR_IO_PENDING; |
| 958 } | 1072 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 971 } | 1085 } |
| 972 PRErrorCode prerr = PR_GetError(); | 1086 PRErrorCode prerr = PR_GetError(); |
| 973 if (prerr == PR_WOULD_BLOCK_ERROR) { | 1087 if (prerr == PR_WOULD_BLOCK_ERROR) { |
| 974 return ERR_IO_PENDING; | 1088 return ERR_IO_PENDING; |
| 975 } | 1089 } |
| 976 LeaveFunction(""); | 1090 LeaveFunction(""); |
| 977 return NetErrorFromNSPRError(prerr); | 1091 return NetErrorFromNSPRError(prerr); |
| 978 } | 1092 } |
| 979 | 1093 |
| 980 } // namespace net | 1094 } // namespace net |
| OLD | NEW |