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 |