| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 #include "net/socket/ssl_server_socket_nss.h" | 5 #include "net/socket/ssl_server_socket_nss.h" |
| 6 | 6 |
| 7 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
| 8 #include <winsock2.h> | 8 #include <winsock2.h> |
| 9 #endif | 9 #endif |
| 10 | 10 |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 155 } | 155 } |
| 156 | 156 |
| 157 int SSLServerSocketNSS::ExportKeyingMaterial(const base::StringPiece& label, | 157 int SSLServerSocketNSS::ExportKeyingMaterial(const base::StringPiece& label, |
| 158 bool has_context, | 158 bool has_context, |
| 159 const base::StringPiece& context, | 159 const base::StringPiece& context, |
| 160 unsigned char* out, | 160 unsigned char* out, |
| 161 unsigned int outlen) { | 161 unsigned int outlen) { |
| 162 if (!IsConnected()) | 162 if (!IsConnected()) |
| 163 return ERR_SOCKET_NOT_CONNECTED; | 163 return ERR_SOCKET_NOT_CONNECTED; |
| 164 SECStatus result = SSL_ExportKeyingMaterial( | 164 SECStatus result = SSL_ExportKeyingMaterial( |
| 165 nss_fd_, label.data(), label.size(), has_context, | 165 nss_fd_, |
| 166 label.data(), |
| 167 label.size(), |
| 168 has_context, |
| 166 reinterpret_cast<const unsigned char*>(context.data()), | 169 reinterpret_cast<const unsigned char*>(context.data()), |
| 167 context.length(), out, outlen); | 170 context.length(), |
| 171 out, |
| 172 outlen); |
| 168 if (result != SECSuccess) { | 173 if (result != SECSuccess) { |
| 169 LogFailedNSSFunction(net_log_, "SSL_ExportKeyingMaterial", ""); | 174 LogFailedNSSFunction(net_log_, "SSL_ExportKeyingMaterial", ""); |
| 170 return MapNSSError(PORT_GetError()); | 175 return MapNSSError(PORT_GetError()); |
| 171 } | 176 } |
| 172 return OK; | 177 return OK; |
| 173 } | 178 } |
| 174 | 179 |
| 175 int SSLServerSocketNSS::GetTLSUniqueChannelBinding(std::string* out) { | 180 int SSLServerSocketNSS::GetTLSUniqueChannelBinding(std::string* out) { |
| 176 if (!IsConnected()) | 181 if (!IsConnected()) |
| 177 return ERR_SOCKET_NOT_CONNECTED; | 182 return ERR_SOCKET_NOT_CONNECTED; |
| 178 unsigned char buf[64]; | 183 unsigned char buf[64]; |
| 179 unsigned int len; | 184 unsigned int len; |
| 180 SECStatus result = SSL_GetChannelBinding(nss_fd_, | 185 SECStatus result = SSL_GetChannelBinding( |
| 181 SSL_CHANNEL_BINDING_TLS_UNIQUE, | 186 nss_fd_, SSL_CHANNEL_BINDING_TLS_UNIQUE, buf, &len, arraysize(buf)); |
| 182 buf, &len, arraysize(buf)); | |
| 183 if (result != SECSuccess) { | 187 if (result != SECSuccess) { |
| 184 LogFailedNSSFunction(net_log_, "SSL_GetChannelBinding", ""); | 188 LogFailedNSSFunction(net_log_, "SSL_GetChannelBinding", ""); |
| 185 return MapNSSError(PORT_GetError()); | 189 return MapNSSError(PORT_GetError()); |
| 186 } | 190 } |
| 187 out->assign(reinterpret_cast<char*>(buf), len); | 191 out->assign(reinterpret_cast<char*>(buf), len); |
| 188 return OK; | 192 return OK; |
| 189 } | 193 } |
| 190 | 194 |
| 191 int SSLServerSocketNSS::Connect(const CompletionCallback& callback) { | 195 int SSLServerSocketNSS::Connect(const CompletionCallback& callback) { |
| 192 NOTIMPLEMENTED(); | 196 NOTIMPLEMENTED(); |
| 193 return ERR_NOT_IMPLEMENTED; | 197 return ERR_NOT_IMPLEMENTED; |
| 194 } | 198 } |
| 195 | 199 |
| 196 int SSLServerSocketNSS::Read(IOBuffer* buf, int buf_len, | 200 int SSLServerSocketNSS::Read(IOBuffer* buf, |
| 201 int buf_len, |
| 197 const CompletionCallback& callback) { | 202 const CompletionCallback& callback) { |
| 198 DCHECK(user_read_callback_.is_null()); | 203 DCHECK(user_read_callback_.is_null()); |
| 199 DCHECK(user_handshake_callback_.is_null()); | 204 DCHECK(user_handshake_callback_.is_null()); |
| 200 DCHECK(!user_read_buf_.get()); | 205 DCHECK(!user_read_buf_.get()); |
| 201 DCHECK(nss_bufs_); | 206 DCHECK(nss_bufs_); |
| 202 DCHECK(!callback.is_null()); | 207 DCHECK(!callback.is_null()); |
| 203 | 208 |
| 204 user_read_buf_ = buf; | 209 user_read_buf_ = buf; |
| 205 user_read_buf_len_ = buf_len; | 210 user_read_buf_len_ = buf_len; |
| 206 | 211 |
| 207 DCHECK(completed_handshake_); | 212 DCHECK(completed_handshake_); |
| 208 | 213 |
| 209 int rv = DoReadLoop(OK); | 214 int rv = DoReadLoop(OK); |
| 210 | 215 |
| 211 if (rv == ERR_IO_PENDING) { | 216 if (rv == ERR_IO_PENDING) { |
| 212 user_read_callback_ = callback; | 217 user_read_callback_ = callback; |
| 213 } else { | 218 } else { |
| 214 user_read_buf_ = NULL; | 219 user_read_buf_ = NULL; |
| 215 user_read_buf_len_ = 0; | 220 user_read_buf_len_ = 0; |
| 216 } | 221 } |
| 217 return rv; | 222 return rv; |
| 218 } | 223 } |
| 219 | 224 |
| 220 int SSLServerSocketNSS::Write(IOBuffer* buf, int buf_len, | 225 int SSLServerSocketNSS::Write(IOBuffer* buf, |
| 226 int buf_len, |
| 221 const CompletionCallback& callback) { | 227 const CompletionCallback& callback) { |
| 222 DCHECK(user_write_callback_.is_null()); | 228 DCHECK(user_write_callback_.is_null()); |
| 223 DCHECK(!user_write_buf_.get()); | 229 DCHECK(!user_write_buf_.get()); |
| 224 DCHECK(nss_bufs_); | 230 DCHECK(nss_bufs_); |
| 225 DCHECK(!callback.is_null()); | 231 DCHECK(!callback.is_null()); |
| 226 | 232 |
| 227 user_write_buf_ = buf; | 233 user_write_buf_ = buf; |
| 228 user_write_buf_len_ = buf_len; | 234 user_write_buf_len_ = buf_len; |
| 229 | 235 |
| 230 int rv = DoWriteLoop(OK); | 236 int rv = DoWriteLoop(OK); |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 SECSuccess) { | 364 SECSuccess) { |
| 359 if (strcmp(info.keaTypeName, "ECDHE") != 0) { | 365 if (strcmp(info.keaTypeName, "ECDHE") != 0) { |
| 360 SSL_CipherPrefSet(nss_fd_, ssl_ciphers[i], PR_FALSE); | 366 SSL_CipherPrefSet(nss_fd_, ssl_ciphers[i], PR_FALSE); |
| 361 } | 367 } |
| 362 } | 368 } |
| 363 } | 369 } |
| 364 } | 370 } |
| 365 | 371 |
| 366 for (std::vector<uint16>::const_iterator it = | 372 for (std::vector<uint16>::const_iterator it = |
| 367 ssl_config_.disabled_cipher_suites.begin(); | 373 ssl_config_.disabled_cipher_suites.begin(); |
| 368 it != ssl_config_.disabled_cipher_suites.end(); ++it) { | 374 it != ssl_config_.disabled_cipher_suites.end(); |
| 375 ++it) { |
| 369 // This will fail if the specified cipher is not implemented by NSS, but | 376 // This will fail if the specified cipher is not implemented by NSS, but |
| 370 // the failure is harmless. | 377 // the failure is harmless. |
| 371 SSL_CipherPrefSet(nss_fd_, *it, PR_FALSE); | 378 SSL_CipherPrefSet(nss_fd_, *it, PR_FALSE); |
| 372 } | 379 } |
| 373 | 380 |
| 374 // Server socket doesn't need session tickets. | 381 // Server socket doesn't need session tickets. |
| 375 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SESSION_TICKETS, PR_FALSE); | 382 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SESSION_TICKETS, PR_FALSE); |
| 376 if (rv != SECSuccess) { | 383 if (rv != SECSuccess) { |
| 377 LogFailedNSSFunction( | 384 LogFailedNSSFunction( |
| 378 net_log_, "SSL_OptionSet", "SSL_ENABLE_SESSION_TICKETS"); | 385 net_log_, "SSL_OptionSet", "SSL_ENABLE_SESSION_TICKETS"); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 414 LogFailedNSSFunction(net_log_, "SSL_HandshakeCallback", ""); | 421 LogFailedNSSFunction(net_log_, "SSL_HandshakeCallback", ""); |
| 415 return ERR_UNEXPECTED; | 422 return ERR_UNEXPECTED; |
| 416 } | 423 } |
| 417 | 424 |
| 418 // Get a certificate of CERTCertificate structure. | 425 // Get a certificate of CERTCertificate structure. |
| 419 std::string der_string; | 426 std::string der_string; |
| 420 if (!X509Certificate::GetDEREncoded(cert_->os_cert_handle(), &der_string)) | 427 if (!X509Certificate::GetDEREncoded(cert_->os_cert_handle(), &der_string)) |
| 421 return ERR_UNEXPECTED; | 428 return ERR_UNEXPECTED; |
| 422 | 429 |
| 423 SECItem der_cert; | 430 SECItem der_cert; |
| 424 der_cert.data = reinterpret_cast<unsigned char*>(const_cast<char*>( | 431 der_cert.data = |
| 425 der_string.data())); | 432 reinterpret_cast<unsigned char*>(const_cast<char*>(der_string.data())); |
| 426 der_cert.len = der_string.length(); | 433 der_cert.len = der_string.length(); |
| 427 der_cert.type = siDERCertBuffer; | 434 der_cert.type = siDERCertBuffer; |
| 428 | 435 |
| 429 // Parse into a CERTCertificate structure. | 436 // Parse into a CERTCertificate structure. |
| 430 CERTCertificate* cert = CERT_NewTempCertificate( | 437 CERTCertificate* cert = CERT_NewTempCertificate( |
| 431 CERT_GetDefaultCertDB(), &der_cert, NULL, PR_FALSE, PR_TRUE); | 438 CERT_GetDefaultCertDB(), &der_cert, NULL, PR_FALSE, PR_TRUE); |
| 432 if (!cert) { | 439 if (!cert) { |
| 433 LogFailedNSSFunction(net_log_, "CERT_NewTempCertificate", ""); | 440 LogFailedNSSFunction(net_log_, "CERT_NewTempCertificate", ""); |
| 434 return MapNSSError(PORT_GetError()); | 441 return MapNSSError(PORT_GetError()); |
| 435 } | 442 } |
| 436 | 443 |
| 437 // Get a key of SECKEYPrivateKey* structure. | 444 // Get a key of SECKEYPrivateKey* structure. |
| 438 std::vector<uint8> key_vector; | 445 std::vector<uint8> key_vector; |
| 439 if (!key_->ExportPrivateKey(&key_vector)) { | 446 if (!key_->ExportPrivateKey(&key_vector)) { |
| 440 CERT_DestroyCertificate(cert); | 447 CERT_DestroyCertificate(cert); |
| 441 return ERR_UNEXPECTED; | 448 return ERR_UNEXPECTED; |
| 442 } | 449 } |
| 443 | 450 |
| 444 SECKEYPrivateKeyStr* private_key = NULL; | 451 SECKEYPrivateKeyStr* private_key = NULL; |
| 445 PK11SlotInfo* slot = crypto::GetPrivateNSSKeySlot(); | 452 PK11SlotInfo* slot = crypto::GetPrivateNSSKeySlot(); |
| 446 if (!slot) { | 453 if (!slot) { |
| 447 CERT_DestroyCertificate(cert); | 454 CERT_DestroyCertificate(cert); |
| 448 return ERR_UNEXPECTED; | 455 return ERR_UNEXPECTED; |
| 449 } | 456 } |
| 450 | 457 |
| 451 SECItem der_private_key_info; | 458 SECItem der_private_key_info; |
| 452 der_private_key_info.data = | 459 der_private_key_info.data = const_cast<unsigned char*>(&key_vector.front()); |
| 453 const_cast<unsigned char*>(&key_vector.front()); | |
| 454 der_private_key_info.len = key_vector.size(); | 460 der_private_key_info.len = key_vector.size(); |
| 455 // The server's RSA private key must be imported into NSS with the | 461 // The server's RSA private key must be imported into NSS with the |
| 456 // following key usage bits: | 462 // following key usage bits: |
| 457 // - KU_KEY_ENCIPHERMENT, required for the RSA key exchange algorithm. | 463 // - KU_KEY_ENCIPHERMENT, required for the RSA key exchange algorithm. |
| 458 // - KU_DIGITAL_SIGNATURE, required for the DHE_RSA and ECDHE_RSA key | 464 // - KU_DIGITAL_SIGNATURE, required for the DHE_RSA and ECDHE_RSA key |
| 459 // exchange algorithms. | 465 // exchange algorithms. |
| 460 const unsigned int key_usage = KU_KEY_ENCIPHERMENT | KU_DIGITAL_SIGNATURE; | 466 const unsigned int key_usage = KU_KEY_ENCIPHERMENT | KU_DIGITAL_SIGNATURE; |
| 461 rv = PK11_ImportDERPrivateKeyInfoAndReturnKey( | 467 rv = PK11_ImportDERPrivateKeyInfoAndReturnKey(slot, |
| 462 slot, &der_private_key_info, NULL, NULL, PR_FALSE, PR_FALSE, | 468 &der_private_key_info, |
| 463 key_usage, &private_key, NULL); | 469 NULL, |
| 470 NULL, |
| 471 PR_FALSE, |
| 472 PR_FALSE, |
| 473 key_usage, |
| 474 &private_key, |
| 475 NULL); |
| 464 PK11_FreeSlot(slot); | 476 PK11_FreeSlot(slot); |
| 465 if (rv != SECSuccess) { | 477 if (rv != SECSuccess) { |
| 466 CERT_DestroyCertificate(cert); | 478 CERT_DestroyCertificate(cert); |
| 467 return ERR_UNEXPECTED; | 479 return ERR_UNEXPECTED; |
| 468 } | 480 } |
| 469 | 481 |
| 470 // Assign server certificate and private key. | 482 // Assign server certificate and private key. |
| 471 SSLKEAType cert_kea = NSS_FindCertKEAType(cert); | 483 SSLKEAType cert_kea = NSS_FindCertKEAType(cert); |
| 472 rv = SSL_ConfigSecureServer(nss_fd_, cert, private_key, cert_kea); | 484 rv = SSL_ConfigSecureServer(nss_fd_, cert, private_key, cert_kea); |
| 473 CERT_DestroyCertificate(cert); | 485 CERT_DestroyCertificate(cert); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 569 return rv; | 581 return rv; |
| 570 } | 582 } |
| 571 | 583 |
| 572 void SSLServerSocketNSS::BufferSendComplete(int result) { | 584 void SSLServerSocketNSS::BufferSendComplete(int result) { |
| 573 memio_PutWriteResult(nss_bufs_, MapErrorToNSS(result)); | 585 memio_PutWriteResult(nss_bufs_, MapErrorToNSS(result)); |
| 574 transport_send_busy_ = false; | 586 transport_send_busy_ = false; |
| 575 OnSendComplete(result); | 587 OnSendComplete(result); |
| 576 } | 588 } |
| 577 | 589 |
| 578 int SSLServerSocketNSS::BufferRecv(void) { | 590 int SSLServerSocketNSS::BufferRecv(void) { |
| 579 if (transport_recv_busy_) return ERR_IO_PENDING; | 591 if (transport_recv_busy_) |
| 592 return ERR_IO_PENDING; |
| 580 | 593 |
| 581 char* buf; | 594 char* buf; |
| 582 int nb = memio_GetReadParams(nss_bufs_, &buf); | 595 int nb = memio_GetReadParams(nss_bufs_, &buf); |
| 583 int rv; | 596 int rv; |
| 584 if (!nb) { | 597 if (!nb) { |
| 585 // buffer too full to read into, so no I/O possible at moment | 598 // buffer too full to read into, so no I/O possible at moment |
| 586 rv = ERR_IO_PENDING; | 599 rv = ERR_IO_PENDING; |
| 587 } else { | 600 } else { |
| 588 recv_buffer_ = new IOBuffer(nb); | 601 recv_buffer_ = new IOBuffer(nb); |
| 589 rv = transport_socket_->Read( | 602 rv = transport_socket_->Read( |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 815 PRBool checksig, | 828 PRBool checksig, |
| 816 PRBool is_server) { | 829 PRBool is_server) { |
| 817 // TODO(hclam): Implement. | 830 // TODO(hclam): Implement. |
| 818 // Tell NSS to not verify the certificate. | 831 // Tell NSS to not verify the certificate. |
| 819 return SECSuccess; | 832 return SECSuccess; |
| 820 } | 833 } |
| 821 | 834 |
| 822 // static | 835 // static |
| 823 // NSS calls this when handshake is completed. | 836 // NSS calls this when handshake is completed. |
| 824 // After the SSL handshake is finished we need to verify the certificate. | 837 // After the SSL handshake is finished we need to verify the certificate. |
| 825 void SSLServerSocketNSS::HandshakeCallback(PRFileDesc* socket, | 838 void SSLServerSocketNSS::HandshakeCallback(PRFileDesc* socket, void* arg) { |
| 826 void* arg) { | |
| 827 // TODO(hclam): Implement. | 839 // TODO(hclam): Implement. |
| 828 } | 840 } |
| 829 | 841 |
| 830 int SSLServerSocketNSS::Init() { | 842 int SSLServerSocketNSS::Init() { |
| 831 // Initialize the NSS SSL library in a threadsafe way. This also | 843 // Initialize the NSS SSL library in a threadsafe way. This also |
| 832 // initializes the NSS base library. | 844 // initializes the NSS base library. |
| 833 EnsureNSSSSLInit(); | 845 EnsureNSSSSLInit(); |
| 834 if (!NSS_IsInitialized()) | 846 if (!NSS_IsInitialized()) |
| 835 return ERR_UNEXPECTED; | 847 return ERR_UNEXPECTED; |
| 836 | 848 |
| 837 EnableSSLServerSockets(); | 849 EnableSSLServerSockets(); |
| 838 return OK; | 850 return OK; |
| 839 } | 851 } |
| 840 | 852 |
| 841 } // namespace net | 853 } // namespace net |
| OLD | NEW |