Chromium Code Reviews| 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 // This file includes code SSLClientSocketNSS::DoVerifyCertComplete() derived | 5 // This file includes code SSLClientSocketNSS::DoVerifyCertComplete() derived |
| 6 // from AuthCertificateCallback() in | 6 // from AuthCertificateCallback() in |
| 7 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp. | 7 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp. |
| 8 | 8 |
| 9 /* ***** BEGIN LICENSE BLOCK ***** | 9 /* ***** BEGIN LICENSE BLOCK ***** |
| 10 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 | 10 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
| (...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 407 struct HandshakeState { | 407 struct HandshakeState { |
| 408 HandshakeState() { Reset(); } | 408 HandshakeState() { Reset(); } |
| 409 | 409 |
| 410 void Reset() { | 410 void Reset() { |
| 411 next_proto_status = SSLClientSocket::kNextProtoUnsupported; | 411 next_proto_status = SSLClientSocket::kNextProtoUnsupported; |
| 412 next_proto.clear(); | 412 next_proto.clear(); |
| 413 server_protos.clear(); | 413 server_protos.clear(); |
| 414 channel_id_sent = false; | 414 channel_id_sent = false; |
| 415 server_cert_chain.Reset(NULL); | 415 server_cert_chain.Reset(NULL); |
| 416 server_cert = NULL; | 416 server_cert = NULL; |
| 417 sct_list_from_tls_extension.clear(); | |
| 417 resumed_handshake = false; | 418 resumed_handshake = false; |
| 418 ssl_connection_status = 0; | 419 ssl_connection_status = 0; |
| 419 } | 420 } |
| 420 | 421 |
| 421 // Set to kNextProtoNegotiated if NPN was successfully negotiated, with the | 422 // Set to kNextProtoNegotiated if NPN was successfully negotiated, with the |
| 422 // negotiated protocol stored in |next_proto|. | 423 // negotiated protocol stored in |next_proto|. |
| 423 SSLClientSocket::NextProtoStatus next_proto_status; | 424 SSLClientSocket::NextProtoStatus next_proto_status; |
| 424 std::string next_proto; | 425 std::string next_proto; |
| 425 // If the server supports NPN, the protocols supported by the server. | 426 // If the server supports NPN, the protocols supported by the server. |
| 426 std::string server_protos; | 427 std::string server_protos; |
| 427 | 428 |
| 428 // True if a channel ID was sent. | 429 // True if a channel ID was sent. |
| 429 bool channel_id_sent; | 430 bool channel_id_sent; |
| 430 | 431 |
| 431 // List of DER-encoded X.509 DistinguishedName of certificate authorities | 432 // List of DER-encoded X.509 DistinguishedName of certificate authorities |
| 432 // allowed by the server. | 433 // allowed by the server. |
| 433 std::vector<std::string> cert_authorities; | 434 std::vector<std::string> cert_authorities; |
| 434 | 435 |
| 435 // Set when the handshake fully completes. | 436 // Set when the handshake fully completes. |
| 436 // | 437 // |
| 437 // The server certificate is first received from NSS as an NSS certificate | 438 // The server certificate is first received from NSS as an NSS certificate |
| 438 // chain (|server_cert_chain|) and then converted into a platform-specific | 439 // chain (|server_cert_chain|) and then converted into a platform-specific |
| 439 // X509Certificate object (|server_cert|). It's possible for some | 440 // X509Certificate object (|server_cert|). It's possible for some |
| 440 // certificates to be successfully parsed by NSS, and not by the platform | 441 // certificates to be successfully parsed by NSS, and not by the platform |
| 441 // libraries (i.e.: when running within a sandbox, different parsing | 442 // libraries (i.e.: when running within a sandbox, different parsing |
| 442 // algorithms, etc), so it's not safe to assume that |server_cert| will | 443 // algorithms, etc), so it's not safe to assume that |server_cert| will |
| 443 // always be non-NULL. | 444 // always be non-NULL. |
| 444 PeerCertificateChain server_cert_chain; | 445 PeerCertificateChain server_cert_chain; |
| 445 scoped_refptr<X509Certificate> server_cert; | 446 scoped_refptr<X509Certificate> server_cert; |
| 447 // SignedCertificateTimestampList received via TLS extension (RFC 6962). | |
| 448 std::string sct_list_from_tls_extension; | |
| 446 | 449 |
| 447 // True if the current handshake was the result of TLS session resumption. | 450 // True if the current handshake was the result of TLS session resumption. |
| 448 bool resumed_handshake; | 451 bool resumed_handshake; |
| 449 | 452 |
| 450 // The negotiated security parameters (TLS version, cipher, extensions) of | 453 // The negotiated security parameters (TLS version, cipher, extensions) of |
| 451 // the SSL connection. | 454 // the SSL connection. |
| 452 int ssl_connection_status; | 455 int ssl_connection_status; |
| 453 }; | 456 }; |
| 454 | 457 |
| 455 // Client-side error mapping functions. | 458 // Client-side error mapping functions. |
| (...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 755 // Updates the NSS and platform specific certificates. | 758 // Updates the NSS and platform specific certificates. |
| 756 void UpdateServerCert(); | 759 void UpdateServerCert(); |
| 757 // Updates the nss_handshake_state_ with the negotiated security parameters. | 760 // Updates the nss_handshake_state_ with the negotiated security parameters. |
| 758 void UpdateConnectionStatus(); | 761 void UpdateConnectionStatus(); |
| 759 // Record histograms for channel id support during full handshakes - resumed | 762 // Record histograms for channel id support during full handshakes - resumed |
| 760 // handshakes are ignored. | 763 // handshakes are ignored. |
| 761 void RecordChannelIDSupportOnNSSTaskRunner(); | 764 void RecordChannelIDSupportOnNSSTaskRunner(); |
| 762 // UpdateNextProto gets any application-layer protocol that may have been | 765 // UpdateNextProto gets any application-layer protocol that may have been |
| 763 // negotiated by the TLS connection. | 766 // negotiated by the TLS connection. |
| 764 void UpdateNextProto(); | 767 void UpdateNextProto(); |
| 768 // Update the nss_handshake_state_ with SignedCertificateTimestampLists | |
| 769 // received in the handshake, via a TLS extension or (to be implemented) | |
| 770 // OCSP stapling. | |
| 771 void UpdateSignedCertTimestamps(); | |
|
wtc
2013/11/26 17:32:55
Nit: declare this immediately after UpdateServerCe
ekasper
2013/11/26 19:33:54
Done.
| |
| 765 | 772 |
| 766 //////////////////////////////////////////////////////////////////////////// | 773 //////////////////////////////////////////////////////////////////////////// |
| 767 // Methods that are ONLY called on the network task runner: | 774 // Methods that are ONLY called on the network task runner: |
| 768 //////////////////////////////////////////////////////////////////////////// | 775 //////////////////////////////////////////////////////////////////////////// |
| 769 int DoBufferRecv(IOBuffer* buffer, int len); | 776 int DoBufferRecv(IOBuffer* buffer, int len); |
| 770 int DoBufferSend(IOBuffer* buffer, int len); | 777 int DoBufferSend(IOBuffer* buffer, int len); |
| 771 int DoGetDomainBoundCert(const std::string& host); | 778 int DoGetDomainBoundCert(const std::string& host); |
| 772 | 779 |
| 773 void OnGetDomainBoundCertComplete(int result); | 780 void OnGetDomainBoundCertComplete(int result); |
| 774 void OnHandshakeStateUpdated(const HandshakeState& state); | 781 void OnHandshakeStateUpdated(const HandshakeState& state); |
| (...skipping 872 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1647 if (rv == SECSuccess && last_handshake_resumed) { | 1654 if (rv == SECSuccess && last_handshake_resumed) { |
| 1648 nss_handshake_state_.resumed_handshake = true; | 1655 nss_handshake_state_.resumed_handshake = true; |
| 1649 } else { | 1656 } else { |
| 1650 nss_handshake_state_.resumed_handshake = false; | 1657 nss_handshake_state_.resumed_handshake = false; |
| 1651 } | 1658 } |
| 1652 | 1659 |
| 1653 RecordChannelIDSupportOnNSSTaskRunner(); | 1660 RecordChannelIDSupportOnNSSTaskRunner(); |
| 1654 UpdateServerCert(); | 1661 UpdateServerCert(); |
| 1655 UpdateConnectionStatus(); | 1662 UpdateConnectionStatus(); |
| 1656 UpdateNextProto(); | 1663 UpdateNextProto(); |
| 1664 UpdateSignedCertTimestamps(); | |
|
wtc
2013/11/26 17:32:55
Nit: call this immediately after UpdateServerCert(
ekasper
2013/11/26 19:33:54
Done.
| |
| 1657 | 1665 |
| 1658 // Update the network task runners view of the handshake state whenever | 1666 // Update the network task runners view of the handshake state whenever |
| 1659 // a handshake has completed. | 1667 // a handshake has completed. |
| 1660 PostOrRunCallback( | 1668 PostOrRunCallback( |
| 1661 FROM_HERE, base::Bind(&Core::OnHandshakeStateUpdated, this, | 1669 FROM_HERE, base::Bind(&Core::OnHandshakeStateUpdated, this, |
| 1662 nss_handshake_state_)); | 1670 nss_handshake_state_)); |
| 1663 } | 1671 } |
| 1664 | 1672 |
| 1665 int SSLClientSocketNSS::Core::HandleNSSError(PRErrorCode nss_error, | 1673 int SSLClientSocketNSS::Core::HandleNSSError(PRErrorCode nss_error, |
| 1666 bool handshake_error) { | 1674 bool handshake_error) { |
| (...skipping 845 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2512 break; | 2520 break; |
| 2513 case SSL_NEXT_PROTO_NO_SUPPORT: | 2521 case SSL_NEXT_PROTO_NO_SUPPORT: |
| 2514 nss_handshake_state_.next_proto_status = kNextProtoUnsupported; | 2522 nss_handshake_state_.next_proto_status = kNextProtoUnsupported; |
| 2515 break; | 2523 break; |
| 2516 default: | 2524 default: |
| 2517 NOTREACHED(); | 2525 NOTREACHED(); |
| 2518 break; | 2526 break; |
| 2519 } | 2527 } |
| 2520 } | 2528 } |
| 2521 | 2529 |
| 2530 void SSLClientSocketNSS::Core::UpdateSignedCertTimestamps() { | |
| 2531 const SECItem* signed_cert_timestamps = | |
| 2532 SSL_PeerSignedCertTimestamps(nss_fd_); | |
| 2533 | |
| 2534 if (!signed_cert_timestamps || !signed_cert_timestamps->len) | |
| 2535 return; | |
| 2536 | |
| 2537 nss_handshake_state_.sct_list_from_tls_extension = std::string( | |
| 2538 reinterpret_cast<char*>(signed_cert_timestamps->data), | |
| 2539 signed_cert_timestamps->len); | |
|
wtc
2013/11/26 17:32:55
This should be aligned with reinterpret_cast. (I g
ekasper
2013/11/26 19:33:54
Done. (No reason other than my own sloppiness for
| |
| 2540 } | |
| 2541 | |
| 2522 void SSLClientSocketNSS::Core::RecordChannelIDSupportOnNSSTaskRunner() { | 2542 void SSLClientSocketNSS::Core::RecordChannelIDSupportOnNSSTaskRunner() { |
| 2523 DCHECK(OnNSSTaskRunner()); | 2543 DCHECK(OnNSSTaskRunner()); |
| 2524 if (nss_handshake_state_.resumed_handshake) | 2544 if (nss_handshake_state_.resumed_handshake) |
| 2525 return; | 2545 return; |
| 2526 | 2546 |
| 2527 // Copy the NSS task runner-only state to the network task runner and | 2547 // Copy the NSS task runner-only state to the network task runner and |
| 2528 // log histograms from there, since the histograms also need access to the | 2548 // log histograms from there, since the histograms also need access to the |
| 2529 // network task runner state. | 2549 // network task runner state. |
| 2530 PostOrRunCallback( | 2550 PostOrRunCallback( |
| 2531 FROM_HERE, | 2551 FROM_HERE, |
| (...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3168 #ifdef SSL_ENABLE_OCSP_STAPLING | 3188 #ifdef SSL_ENABLE_OCSP_STAPLING |
| 3169 if (IsOCSPStaplingSupported()) { | 3189 if (IsOCSPStaplingSupported()) { |
| 3170 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_OCSP_STAPLING, PR_TRUE); | 3190 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_OCSP_STAPLING, PR_TRUE); |
| 3171 if (rv != SECSuccess) { | 3191 if (rv != SECSuccess) { |
| 3172 LogFailedNSSFunction(net_log_, "SSL_OptionSet", | 3192 LogFailedNSSFunction(net_log_, "SSL_OptionSet", |
| 3173 "SSL_ENABLE_OCSP_STAPLING"); | 3193 "SSL_ENABLE_OCSP_STAPLING"); |
| 3174 } | 3194 } |
| 3175 } | 3195 } |
| 3176 #endif | 3196 #endif |
| 3177 | 3197 |
| 3198 // Chromium patch to libssl. | |
| 3199 // TODO(ekasper): does this need a guard? Seems like libssl-only changes | |
| 3200 // aren't guarded (ChannelID). | |
|
wtc
2013/11/26 17:32:55
You can remove this whole comment. Correct, we no
ekasper
2013/11/26 19:33:54
Done.
| |
| 3201 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SIGNED_CERT_TIMESTAMPS, | |
| 3202 ssl_config_.signed_cert_timestamps_enabled); | |
| 3203 if (rv != SECSuccess) | |
| 3204 LogFailedNSSFunction(net_log_, "SSL_OptionSet", | |
| 3205 "SSL_ENABLE_SIGNED_CERT_TIMESTAMPS"); | |
|
wtc
2013/11/26 17:32:55
Add curly braces (because the if statement's body
ekasper
2013/11/26 19:33:54
Done.
| |
| 3206 | |
| 3178 // Chromium patch to libssl | 3207 // Chromium patch to libssl |
| 3179 #ifdef SSL_ENABLE_CACHED_INFO | 3208 #ifdef SSL_ENABLE_CACHED_INFO |
| 3180 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_CACHED_INFO, | 3209 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_CACHED_INFO, |
| 3181 ssl_config_.cached_info_enabled); | 3210 ssl_config_.cached_info_enabled); |
| 3182 if (rv != SECSuccess) | 3211 if (rv != SECSuccess) |
| 3183 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_CACHED_INFO"); | 3212 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_CACHED_INFO"); |
| 3184 #endif | 3213 #endif |
| 3185 | 3214 |
| 3186 rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE); | 3215 rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE); |
| 3187 if (rv != SECSuccess) { | 3216 if (rv != SECSuccess) { |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3313 | 3342 |
| 3314 int SSLClientSocketNSS::DoHandshakeComplete(int result) { | 3343 int SSLClientSocketNSS::DoHandshakeComplete(int result) { |
| 3315 EnterFunction(result); | 3344 EnterFunction(result); |
| 3316 | 3345 |
| 3317 if (result == OK) { | 3346 if (result == OK) { |
| 3318 // SSL handshake is completed. Let's verify the certificate. | 3347 // SSL handshake is completed. Let's verify the certificate. |
| 3319 GotoState(STATE_VERIFY_CERT); | 3348 GotoState(STATE_VERIFY_CERT); |
| 3320 // Done! | 3349 // Done! |
| 3321 } | 3350 } |
| 3322 set_channel_id_sent(core_->state().channel_id_sent); | 3351 set_channel_id_sent(core_->state().channel_id_sent); |
| 3352 set_signed_cert_timestamps_received( | |
| 3353 !core_->state().sct_list_from_tls_extension.empty()); | |
| 3323 | 3354 |
| 3324 LeaveFunction(result); | 3355 LeaveFunction(result); |
| 3325 return result; | 3356 return result; |
| 3326 } | 3357 } |
| 3327 | 3358 |
| 3328 | 3359 |
| 3329 int SSLClientSocketNSS::DoVerifyCert(int result) { | 3360 int SSLClientSocketNSS::DoVerifyCert(int result) { |
| 3330 DCHECK(!core_->state().server_cert_chain.empty()); | 3361 DCHECK(!core_->state().server_cert_chain.empty()); |
| 3331 DCHECK(core_->state().server_cert_chain[0]); | 3362 DCHECK(core_->state().server_cert_chain[0]); |
| 3332 | 3363 |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3497 EnsureThreadIdAssigned(); | 3528 EnsureThreadIdAssigned(); |
| 3498 base::AutoLock auto_lock(lock_); | 3529 base::AutoLock auto_lock(lock_); |
| 3499 return valid_thread_id_ == base::PlatformThread::CurrentId(); | 3530 return valid_thread_id_ == base::PlatformThread::CurrentId(); |
| 3500 } | 3531 } |
| 3501 | 3532 |
| 3502 ServerBoundCertService* SSLClientSocketNSS::GetServerBoundCertService() const { | 3533 ServerBoundCertService* SSLClientSocketNSS::GetServerBoundCertService() const { |
| 3503 return server_bound_cert_service_; | 3534 return server_bound_cert_service_; |
| 3504 } | 3535 } |
| 3505 | 3536 |
| 3506 } // namespace net | 3537 } // namespace net |
| OLD | NEW |