Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(231)

Side by Side Diff: net/socket/ssl_client_socket_nss.cc

Issue 83333003: Add support for fetching Certificate Transparency SCTs over a TLS extension (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698