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 |