1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Use of this source code is governed by a BSD-style license that can be 321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// found in the LICENSE file. 421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "net/socket/ssl_server_socket_nss.h" 621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#if defined(OS_WIN) 821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <winsock2.h> 921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#endif 1021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 1121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#if defined(USE_SYSTEM_SSL) 1221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <dlfcn.h> 1321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#endif 1421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#if defined(OS_MACOSX) 1521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <Security/Security.h> 1621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#endif 1721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <certdb.h> 1821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <cryptohi.h> 1921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <hasht.h> 2021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <keyhi.h> 2121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <nspr.h> 2221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <nss.h> 2321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <pk11pub.h> 2421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <secerr.h> 2521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <sechash.h> 2621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <ssl.h> 2721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <sslerr.h> 2821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <sslproto.h> 2921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 3021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <limits> 3121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/ref_counted.h" 33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "crypto/rsa_private_key.h" 34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "crypto/nss_util_internal.h" 3521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "net/base/io_buffer.h" 3621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "net/base/net_errors.h" 3721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "net/base/net_log.h" 3821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "net/ocsp/nss_ocsp.h" 3921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "net/socket/nss_ssl_util.h" 4021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "net/socket/ssl_error_params.h" 4121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 4221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenstatic const int kRecvBufferSize = 4096; 4321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 4421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define GotoState(s) next_handshake_state_ = s 4521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 4621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsennamespace net { 4721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 4821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenSSLServerSocket* CreateSSLServerSocket( 49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Socket* socket, X509Certificate* cert, crypto::RSAPrivateKey* key, 5021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const SSLConfig& ssl_config) { 5121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return new SSLServerSocketNSS(socket, cert, key, ssl_config); 5221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 5321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 5421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenSSLServerSocketNSS::SSLServerSocketNSS( 5521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen Socket* transport_socket, 5621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen scoped_refptr<X509Certificate> cert, 57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen crypto::RSAPrivateKey* key, 5821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const SSLConfig& ssl_config) 5921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen : ALLOW_THIS_IN_INITIALIZER_LIST(buffer_send_callback_( 6021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen this, &SSLServerSocketNSS::BufferSendComplete)), 6121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ALLOW_THIS_IN_INITIALIZER_LIST(buffer_recv_callback_( 6221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen this, &SSLServerSocketNSS::BufferRecvComplete)), 6321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen transport_send_busy_(false), 6421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen transport_recv_busy_(false), 6521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen user_accept_callback_(NULL), 6621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen user_read_callback_(NULL), 6721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen user_write_callback_(NULL), 6821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen nss_fd_(NULL), 6921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen nss_bufs_(NULL), 7021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen transport_socket_(transport_socket), 7121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ssl_config_(ssl_config), 7221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen cert_(cert), 7321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen next_handshake_state_(STATE_NONE), 7421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen completed_handshake_(false) { 7521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ssl_config_.false_start_enabled = false; 7621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ssl_config_.ssl3_enabled = true; 7721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ssl_config_.tls1_enabled = true; 7821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 7921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // TODO(hclam): Need a better way to clone a key. 8021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen std::vector<uint8> key_bytes; 8121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen CHECK(key->ExportPrivateKey(&key_bytes)); 82ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen key_.reset(crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_bytes)); 8321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen CHECK(key_.get()); 8421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 8521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 8621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenSSLServerSocketNSS::~SSLServerSocketNSS() { 8721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (nss_fd_ != NULL) { 8821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen PR_Close(nss_fd_); 8921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen nss_fd_ = NULL; 9021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 9121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 9221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 9321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenint SSLServerSocketNSS::Accept(CompletionCallback* callback) { 9421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net_log_.BeginEvent(NetLog::TYPE_SSL_ACCEPT, NULL); 9521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 9621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int rv = Init(); 9721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (rv != OK) { 9821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen LOG(ERROR) << "Failed to initialize NSS"; 9972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_ACCEPT, rv); 10021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return rv; 10121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 10221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 10321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen rv = InitializeSSLOptions(); 10421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (rv != OK) { 10521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen LOG(ERROR) << "Failed to initialize SSL options"; 10672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_ACCEPT, rv); 10721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return rv; 10821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 10921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 11021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Set peer address. TODO(hclam): This should be in a separate method. 11121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen PRNetAddr peername; 11221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen memset(&peername, 0, sizeof(peername)); 11321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen peername.raw.family = AF_INET; 11421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen memio_SetPeerName(nss_fd_, &peername); 11521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 11621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen GotoState(STATE_HANDSHAKE); 11721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen rv = DoHandshakeLoop(net::OK); 11821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (rv == ERR_IO_PENDING) { 11921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen user_accept_callback_ = callback; 12021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } else { 12172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_ACCEPT, rv); 12221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 12321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 12421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return rv > OK ? OK : rv; 12521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 12621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 12721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenint SSLServerSocketNSS::Read(IOBuffer* buf, int buf_len, 12821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen CompletionCallback* callback) { 12921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(!user_read_callback_); 13021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(!user_accept_callback_); 13121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(!user_read_buf_); 13221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(nss_bufs_); 13321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 13421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen user_read_buf_ = buf; 13521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen user_read_buf_len_ = buf_len; 13621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 13721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(completed_handshake_); 13821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 13921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int rv = DoReadLoop(OK); 14021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 14121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (rv == ERR_IO_PENDING) { 14221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen user_read_callback_ = callback; 14321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } else { 14421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen user_read_buf_ = NULL; 14521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen user_read_buf_len_ = 0; 14621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 14721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return rv; 14821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 14921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 15021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenint SSLServerSocketNSS::Write(IOBuffer* buf, int buf_len, 15121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen CompletionCallback* callback) { 15221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(!user_write_callback_); 15321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(!user_write_buf_); 15421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(nss_bufs_); 15521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 15621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen user_write_buf_ = buf; 15721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen user_write_buf_len_ = buf_len; 15821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 15921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int rv = DoWriteLoop(OK); 16021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 16121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (rv == ERR_IO_PENDING) { 16221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen user_write_callback_ = callback; 16321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } else { 16421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen user_write_buf_ = NULL; 16521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen user_write_buf_len_ = 0; 16621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 16721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return rv; 16821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 16921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 17072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool SSLServerSocketNSS::SetReceiveBufferSize(int32 size) { 17172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 17221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 17321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 17472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool SSLServerSocketNSS::SetSendBufferSize(int32 size) { 17572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 17621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 17721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 17821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenint SSLServerSocketNSS::InitializeSSLOptions() { 17921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Transport connected, now hook it up to nss 18021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // TODO(port): specify rx and tx buffer sizes separately 18121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen nss_fd_ = memio_CreateIOLayer(kRecvBufferSize); 18221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (nss_fd_ == NULL) { 18321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ERR_OUT_OF_MEMORY; // TODO(port): map NSPR error code. 18421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 18521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 18621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Grab pointer to buffers 18721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen nss_bufs_ = memio_GetSecret(nss_fd_); 18821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 18921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen /* Create SSL state machine */ 19021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen /* Push SSL onto our fake I/O socket */ 19121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen nss_fd_ = SSL_ImportFD(NULL, nss_fd_); 19221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (nss_fd_ == NULL) { 19321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen LogFailedNSSFunction(net_log_, "SSL_ImportFD", ""); 19421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ERR_OUT_OF_MEMORY; // TODO(port): map NSPR/NSS error code. 19521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 19621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // TODO(port): set more ssl options! Check errors! 19721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 19821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int rv; 19921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 20021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen rv = SSL_OptionSet(nss_fd_, SSL_SECURITY, PR_TRUE); 20121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (rv != SECSuccess) { 20221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_SECURITY"); 20321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ERR_UNEXPECTED; 20421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 20521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 20621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SSL2, PR_FALSE); 20721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (rv != SECSuccess) { 20821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_SSL2"); 20921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ERR_UNEXPECTED; 21021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 21121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 21221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SSL3, PR_TRUE); 21321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (rv != SECSuccess) { 21421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_SSL3"); 21521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ERR_UNEXPECTED; 21621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 21721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 21821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_TLS, ssl_config_.tls1_enabled); 21921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (rv != SECSuccess) { 22021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_TLS"); 22121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ERR_UNEXPECTED; 22221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 22321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 22421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen for (std::vector<uint16>::const_iterator it = 22521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ssl_config_.disabled_cipher_suites.begin(); 22621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen it != ssl_config_.disabled_cipher_suites.end(); ++it) { 22721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // This will fail if the specified cipher is not implemented by NSS, but 22821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // the failure is harmless. 22921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen SSL_CipherPrefSet(nss_fd_, *it, PR_FALSE); 23021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 23121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 23221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Server socket doesn't need session tickets. 23321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SESSION_TICKETS, PR_FALSE); 23421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (rv != SECSuccess) { 23521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen LogFailedNSSFunction( 23621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net_log_, "SSL_OptionSet", "SSL_ENABLE_SESSION_TICKETS"); 23721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 23821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 23921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Doing this will force PR_Accept perform handshake as server. 24021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_FALSE); 24121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (rv != SECSuccess) { 24221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_HANDSHAKE_AS_CLIENT"); 24321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ERR_UNEXPECTED; 24421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 24521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 24621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_SERVER, PR_TRUE); 24721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (rv != SECSuccess) { 24821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_HANDSHAKE_AS_SERVER"); 24921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ERR_UNEXPECTED; 25021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 25121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 25221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen rv = SSL_OptionSet(nss_fd_, SSL_REQUEST_CERTIFICATE, PR_FALSE); 25321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (rv != SECSuccess) { 25421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_REQUEST_CERTIFICATE"); 25521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ERR_UNEXPECTED; 25621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 25721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 25821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen rv = SSL_OptionSet(nss_fd_, SSL_REQUIRE_CERTIFICATE, PR_FALSE); 25921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (rv != SECSuccess) { 26021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_REQUIRE_CERTIFICATE"); 26121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ERR_UNEXPECTED; 26221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 26321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 26421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen rv = SSL_ConfigServerSessionIDCache(1024, 5, 5, NULL); 26521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (rv != SECSuccess) { 26621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen LogFailedNSSFunction(net_log_, "SSL_ConfigureServerSessionIDCache", ""); 26721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ERR_UNEXPECTED; 26821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 26921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 27021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen rv = SSL_AuthCertificateHook(nss_fd_, OwnAuthCertHandler, this); 27121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (rv != SECSuccess) { 27221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen LogFailedNSSFunction(net_log_, "SSL_AuthCertificateHook", ""); 27321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ERR_UNEXPECTED; 27421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 27521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 27621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen rv = SSL_HandshakeCallback(nss_fd_, HandshakeCallback, this); 27721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (rv != SECSuccess) { 27821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen LogFailedNSSFunction(net_log_, "SSL_HandshakeCallback", ""); 27921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ERR_UNEXPECTED; 28021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 28121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 28221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Get a certificate of CERTCertificate structure. 28321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen std::string der_string; 28421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (!cert_->GetDEREncoded(&der_string)) 28521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ERR_UNEXPECTED; 28621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 28721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen SECItem der_cert; 28821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen der_cert.data = reinterpret_cast<unsigned char*>(const_cast<char*>( 28921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen der_string.data())); 29021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen der_cert.len = der_string.length(); 29121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen der_cert.type = siDERCertBuffer; 29221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 29321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Parse into a CERTCertificate structure. 29421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen CERTCertificate* cert = CERT_NewTempCertificate( 29521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen CERT_GetDefaultCertDB(), &der_cert, NULL, PR_FALSE, PR_TRUE); 29621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 29721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Get a key of SECKEYPrivateKey* structure. 29821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen std::vector<uint8> key_vector; 29921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (!key_->ExportPrivateKey(&key_vector)) { 30021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen CERT_DestroyCertificate(cert); 30121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ERR_UNEXPECTED; 30221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 30321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 30421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen SECKEYPrivateKeyStr* private_key = NULL; 305ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen PK11SlotInfo* slot = crypto::GetPrivateNSSKeySlot(); 30621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (!slot) { 30721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen CERT_DestroyCertificate(cert); 30821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ERR_UNEXPECTED; 30921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 31021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 31121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen SECItem der_private_key_info; 31221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen der_private_key_info.data = 31321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const_cast<unsigned char*>(&key_vector.front()); 31421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen der_private_key_info.len = key_vector.size(); 31572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // The server's RSA private key must be imported into NSS with the 31672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // following key usage bits: 31772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // - KU_KEY_ENCIPHERMENT, required for the RSA key exchange algorithm. 31872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // - KU_DIGITAL_SIGNATURE, required for the DHE_RSA and ECDHE_RSA key 31972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // exchange algorithms. 32072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const unsigned int key_usage = KU_KEY_ENCIPHERMENT | KU_DIGITAL_SIGNATURE; 32121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen rv = PK11_ImportDERPrivateKeyInfoAndReturnKey( 32221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen slot, &der_private_key_info, NULL, NULL, PR_FALSE, PR_FALSE, 32372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen key_usage, &private_key, NULL); 32421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen PK11_FreeSlot(slot); 32521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (rv != SECSuccess) { 32621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen CERT_DestroyCertificate(cert); 32721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ERR_UNEXPECTED; 32821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 32921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 33021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Assign server certificate and private key. 33121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen SSLKEAType cert_kea = NSS_FindCertKEAType(cert); 33221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen rv = SSL_ConfigSecureServer(nss_fd_, cert, private_key, cert_kea); 33321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen CERT_DestroyCertificate(cert); 33421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen SECKEY_DestroyPrivateKey(private_key); 33521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 33621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (rv != SECSuccess) { 33721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen PRErrorCode prerr = PR_GetError(); 33821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen LOG(ERROR) << "Failed to config SSL server: " << prerr; 33921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen LogFailedNSSFunction(net_log_, "SSL_ConfigureSecureServer", ""); 34021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ERR_UNEXPECTED; 34121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 34221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 34321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Tell SSL we're a server; needed if not letting NSPR do socket I/O 34421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen rv = SSL_ResetHandshake(nss_fd_, PR_TRUE); 34521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (rv != SECSuccess) { 34621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen LogFailedNSSFunction(net_log_, "SSL_ResetHandshake", ""); 34721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ERR_UNEXPECTED; 34821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 34921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 35021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return OK; 35121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 35221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 35372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid SSLServerSocketNSS::OnSendComplete(int result) { 35472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (next_handshake_state_ == STATE_HANDSHAKE) { 35572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // In handshake phase. 35672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen OnHandshakeIOComplete(result); 35772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return; 35872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 35972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 36072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!user_write_buf_ || !completed_handshake_) 36172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return; 36272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 36372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int rv = DoWriteLoop(result); 36472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (rv != ERR_IO_PENDING) 36572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DoWriteCallback(rv); 36672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 36772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 36872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid SSLServerSocketNSS::OnRecvComplete(int result) { 36972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (next_handshake_state_ == STATE_HANDSHAKE) { 37072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // In handshake phase. 37172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen OnHandshakeIOComplete(result); 37272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return; 37372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 37472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 37572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Network layer received some data, check if client requested to read 37672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // decrypted data. 37772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!user_read_buf_ || !completed_handshake_) 37872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return; 37972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 38072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int rv = DoReadLoop(result); 38172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (rv != ERR_IO_PENDING) 38272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DoReadCallback(rv); 38372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 38472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 38572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid SSLServerSocketNSS::OnHandshakeIOComplete(int result) { 38672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int rv = DoHandshakeLoop(result); 38772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (rv != ERR_IO_PENDING) { 38872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net_log_.EndEventWithNetErrorCode(net::NetLog::TYPE_SSL_ACCEPT, rv); 38972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (user_accept_callback_) 39072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DoAcceptCallback(rv); 39172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 39272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 39372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 39421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Return 0 for EOF, 39521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// > 0 for bytes transferred immediately, 39621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// < 0 for error (or the non-error ERR_IO_PENDING). 39721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenint SSLServerSocketNSS::BufferSend(void) { 39821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (transport_send_busy_) 39921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ERR_IO_PENDING; 40021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 40121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const char* buf1; 40221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const char* buf2; 40321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen unsigned int len1, len2; 40421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen memio_GetWriteParams(nss_bufs_, &buf1, &len1, &buf2, &len2); 40521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const unsigned int len = len1 + len2; 40621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 40721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int rv = 0; 40821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (len) { 40921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen scoped_refptr<IOBuffer> send_buffer(new IOBuffer(len)); 41021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen memcpy(send_buffer->data(), buf1, len1); 41121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen memcpy(send_buffer->data() + len1, buf2, len2); 41221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen rv = transport_socket_->Write(send_buffer, len, 41321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen &buffer_send_callback_); 41421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (rv == ERR_IO_PENDING) { 41521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen transport_send_busy_ = true; 41621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } else { 41721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen memio_PutWriteResult(nss_bufs_, MapErrorToNSS(rv)); 41821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 41921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 42021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 42121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return rv; 42221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 42321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 42421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid SSLServerSocketNSS::BufferSendComplete(int result) { 42521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen memio_PutWriteResult(nss_bufs_, MapErrorToNSS(result)); 42621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen transport_send_busy_ = false; 42721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen OnSendComplete(result); 42821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 42921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 43021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenint SSLServerSocketNSS::BufferRecv(void) { 43121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (transport_recv_busy_) return ERR_IO_PENDING; 43221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 43321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen char *buf; 43421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int nb = memio_GetReadParams(nss_bufs_, &buf); 43521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int rv; 43621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (!nb) { 43721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // buffer too full to read into, so no I/O possible at moment 43821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen rv = ERR_IO_PENDING; 43921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } else { 44021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen recv_buffer_ = new IOBuffer(nb); 44121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen rv = transport_socket_->Read(recv_buffer_, nb, &buffer_recv_callback_); 44221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (rv == ERR_IO_PENDING) { 44321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen transport_recv_busy_ = true; 44421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } else { 44521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (rv > 0) 44621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen memcpy(buf, recv_buffer_->data(), rv); 44721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen memio_PutReadResult(nss_bufs_, MapErrorToNSS(rv)); 44821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen recv_buffer_ = NULL; 44921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 45021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 45121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return rv; 45221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 45321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 45421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid SSLServerSocketNSS::BufferRecvComplete(int result) { 45521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (result > 0) { 45621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen char *buf; 45721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen memio_GetReadParams(nss_bufs_, &buf); 45821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen memcpy(buf, recv_buffer_->data(), result); 45921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 46021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen recv_buffer_ = NULL; 46121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen memio_PutReadResult(nss_bufs_, MapErrorToNSS(result)); 46221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen transport_recv_busy_ = false; 46321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen OnRecvComplete(result); 46421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 46521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 46621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Do network I/O between the given buffer and the given socket. 46721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Return true if some I/O performed, false otherwise (error or ERR_IO_PENDING) 46821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool SSLServerSocketNSS::DoTransportIO() { 46921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen bool network_moved = false; 47021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (nss_bufs_ != NULL) { 47121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int nsent = BufferSend(); 47221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int nreceived = BufferRecv(); 47321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen network_moved = (nsent > 0 || nreceived >= 0); 47421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 47521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return network_moved; 47621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 47721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 47821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenint SSLServerSocketNSS::DoPayloadRead() { 47921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(user_read_buf_); 48021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK_GT(user_read_buf_len_, 0); 48121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int rv = PR_Read(nss_fd_, user_read_buf_->data(), user_read_buf_len_); 48221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (rv >= 0) 48321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return rv; 48421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen PRErrorCode prerr = PR_GetError(); 48521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (prerr == PR_WOULD_BLOCK_ERROR) { 48621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ERR_IO_PENDING; 48721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 48821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen rv = MapNSSError(prerr); 48921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net_log_.AddEvent(NetLog::TYPE_SSL_READ_ERROR, 49021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen make_scoped_refptr(new SSLErrorParams(rv, prerr))); 49121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return rv; 49221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 49321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 49421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenint SSLServerSocketNSS::DoPayloadWrite() { 49521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(user_write_buf_); 49621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int rv = PR_Write(nss_fd_, user_write_buf_->data(), user_write_buf_len_); 49721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (rv >= 0) 49821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return rv; 49921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen PRErrorCode prerr = PR_GetError(); 50021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (prerr == PR_WOULD_BLOCK_ERROR) { 50121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ERR_IO_PENDING; 50221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 50321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen rv = MapNSSError(prerr); 50421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net_log_.AddEvent(NetLog::TYPE_SSL_WRITE_ERROR, 50521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen make_scoped_refptr(new SSLErrorParams(rv, prerr))); 50621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return rv; 50721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 50821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 50921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenint SSLServerSocketNSS::DoHandshakeLoop(int last_io_result) { 51021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen bool network_moved; 51121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int rv = last_io_result; 51221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen do { 51321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Default to STATE_NONE for next state. 51421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // (This is a quirk carried over from the windows 51521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // implementation. It makes reading the logs a bit harder.) 51621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // State handlers can and often do call GotoState just 51721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // to stay in the current state. 51821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen State state = next_handshake_state_; 51921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen GotoState(STATE_NONE); 52021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen switch (state) { 52121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case STATE_NONE: 52221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // we're just pumping data between the buffer and the network 52321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen break; 52421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen case STATE_HANDSHAKE: 52521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen rv = DoHandshake(); 52621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen break; 52721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen default: 52821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen rv = ERR_UNEXPECTED; 52921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen LOG(DFATAL) << "unexpected state " << state; 53021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen break; 53121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 53221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 53321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Do the actual network I/O 53421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen network_moved = DoTransportIO(); 53521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } while ((rv != ERR_IO_PENDING || network_moved) && 53621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen next_handshake_state_ != STATE_NONE); 53721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return rv; 53821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 53921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 54021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenint SSLServerSocketNSS::DoReadLoop(int result) { 54121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(completed_handshake_); 54221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(next_handshake_state_ == STATE_NONE); 54321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 54421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (result < 0) 54521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return result; 54621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 54721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (!nss_bufs_) { 54821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen LOG(DFATAL) << "!nss_bufs_"; 54921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int rv = ERR_UNEXPECTED; 55021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net_log_.AddEvent(NetLog::TYPE_SSL_READ_ERROR, 55121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen make_scoped_refptr(new SSLErrorParams(rv, 0))); 55221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return rv; 55321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 55421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 55521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen bool network_moved; 55621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int rv; 55721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen do { 55821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen rv = DoPayloadRead(); 55921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen network_moved = DoTransportIO(); 56021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } while (rv == ERR_IO_PENDING && network_moved); 56121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return rv; 56221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 56321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 56421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenint SSLServerSocketNSS::DoWriteLoop(int result) { 56521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(completed_handshake_); 56621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(next_handshake_state_ == STATE_NONE); 56721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 56821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (result < 0) 56921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return result; 57021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 57121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (!nss_bufs_) { 57221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen LOG(DFATAL) << "!nss_bufs_"; 57321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int rv = ERR_UNEXPECTED; 57421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net_log_.AddEvent(NetLog::TYPE_SSL_WRITE_ERROR, 57521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen make_scoped_refptr(new SSLErrorParams(rv, 0))); 57621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return rv; 57721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 57821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 57921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen bool network_moved; 58021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int rv; 58121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen do { 58221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen rv = DoPayloadWrite(); 58321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen network_moved = DoTransportIO(); 58421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } while (rv == ERR_IO_PENDING && network_moved); 58521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return rv; 58621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 58721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 58821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenint SSLServerSocketNSS::DoHandshake() { 58921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int net_error = net::OK; 59021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen SECStatus rv = SSL_ForceHandshake(nss_fd_); 59121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 59221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (rv == SECSuccess) { 59321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen completed_handshake_ = true; 59421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } else { 59521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen PRErrorCode prerr = PR_GetError(); 59621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net_error = MapNSSHandshakeError(prerr); 59721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 59821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // If not done, stay in this state 59921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (net_error == ERR_IO_PENDING) { 60021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen GotoState(STATE_HANDSHAKE); 60121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } else { 60221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen LOG(ERROR) << "handshake failed; NSS error code " << prerr 60321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen << ", net_error " << net_error; 60421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net_log_.AddEvent( 60521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen NetLog::TYPE_SSL_HANDSHAKE_ERROR, 60621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen make_scoped_refptr(new SSLErrorParams(net_error, prerr))); 60721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 60821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 60921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return net_error; 61021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 61121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 61272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid SSLServerSocketNSS::DoAcceptCallback(int rv) { 61372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK_NE(rv, ERR_IO_PENDING); 61472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 61572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen CompletionCallback* c = user_accept_callback_; 61672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen user_accept_callback_ = NULL; 61772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen c->Run(rv > OK ? OK : rv); 61872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 61972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 62072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid SSLServerSocketNSS::DoReadCallback(int rv) { 62172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(rv != ERR_IO_PENDING); 62272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(user_read_callback_); 62372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 62472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Since Run may result in Read being called, clear |user_read_callback_| 62572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // up front. 62672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen CompletionCallback* c = user_read_callback_; 62772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen user_read_callback_ = NULL; 62872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen user_read_buf_ = NULL; 62972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen user_read_buf_len_ = 0; 63072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen c->Run(rv); 63172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 63272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 63372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid SSLServerSocketNSS::DoWriteCallback(int rv) { 63472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(rv != ERR_IO_PENDING); 63572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(user_write_callback_); 63672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 63772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Since Run may result in Write being called, clear |user_write_callback_| 63872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // up front. 63972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen CompletionCallback* c = user_write_callback_; 64072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen user_write_callback_ = NULL; 64172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen user_write_buf_ = NULL; 64272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen user_write_buf_len_ = 0; 64372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen c->Run(rv); 64472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 64572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 64672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// static 64772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// NSS calls this if an incoming certificate needs to be verified. 64872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Do nothing but return SECSuccess. 64972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// This is called only in full handshake mode. 65072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Peer certificate is retrieved in HandshakeCallback() later, which is called 65172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// in full handshake mode or in resumption handshake mode. 65272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenSECStatus SSLServerSocketNSS::OwnAuthCertHandler(void* arg, 65372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen PRFileDesc* socket, 65472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen PRBool checksig, 65572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen PRBool is_server) { 65672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // TODO(hclam): Implement. 65772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Tell NSS to not verify the certificate. 65872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return SECSuccess; 65972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 66072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 66172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// static 66272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// NSS calls this when handshake is completed. 66372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// After the SSL handshake is finished we need to verify the certificate. 66472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid SSLServerSocketNSS::HandshakeCallback(PRFileDesc* socket, 66572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen void* arg) { 66672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // TODO(hclam): Implement. 66772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 66872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 66972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenint SSLServerSocketNSS::Init() { 67072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Initialize the NSS SSL library in a threadsafe way. This also 67172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // initializes the NSS base library. 67272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EnsureNSSSSLInit(); 67372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!NSS_IsInitialized()) 67472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return ERR_UNEXPECTED; 67572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#if !defined(OS_MACOSX) && !defined(OS_WIN) 67672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // We must call EnsureOCSPInit() here, on the IO thread, to get the IO loop 67772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // by MessageLoopForIO::current(). 67872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // X509Certificate::Verify() runs on a worker thread of CertVerifier. 67972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EnsureOCSPInit(); 68072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#endif 68172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 68272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return OK; 68372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 68472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 68521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} // namespace net 686