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 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
441 ssl_connection_status_(0), | 441 ssl_connection_status_(0), |
442 client_auth_cert_needed_(false), | 442 client_auth_cert_needed_(false), |
443 cert_verifier_(context.cert_verifier), | 443 cert_verifier_(context.cert_verifier), |
444 domain_bound_cert_xtn_negotiated_(false), | 444 domain_bound_cert_xtn_negotiated_(false), |
445 server_bound_cert_service_(context.server_bound_cert_service), | 445 server_bound_cert_service_(context.server_bound_cert_service), |
446 domain_bound_cert_type_(CLIENT_CERT_INVALID_TYPE), | 446 domain_bound_cert_type_(CLIENT_CERT_INVALID_TYPE), |
447 domain_bound_cert_request_handle_(NULL), | 447 domain_bound_cert_request_handle_(NULL), |
448 handshake_callback_called_(false), | 448 handshake_callback_called_(false), |
449 completed_handshake_(false), | 449 completed_handshake_(false), |
450 ssl_session_cache_shard_(context.ssl_session_cache_shard), | 450 ssl_session_cache_shard_(context.ssl_session_cache_shard), |
451 eset_mitm_detected_(false), | |
452 predicted_cert_chain_correct_(false), | 451 predicted_cert_chain_correct_(false), |
453 next_handshake_state_(STATE_NONE), | 452 next_handshake_state_(STATE_NONE), |
454 nss_fd_(NULL), | 453 nss_fd_(NULL), |
455 nss_bufs_(NULL), | 454 nss_bufs_(NULL), |
456 net_log_(transport_socket->socket()->NetLog()), | 455 net_log_(transport_socket->socket()->NetLog()), |
457 ssl_host_info_(ssl_host_info), | 456 ssl_host_info_(ssl_host_info), |
458 transport_security_state_(context.transport_security_state), | 457 transport_security_state_(context.transport_security_state), |
459 next_proto_status_(kNextProtoUnsupported), | 458 next_proto_status_(kNextProtoUnsupported), |
460 valid_thread_id_(base::kInvalidThreadId) { | 459 valid_thread_id_(base::kInvalidThreadId) { |
461 EnterFunction(""); | 460 EnterFunction(""); |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
641 user_write_buf_len_ = 0; | 640 user_write_buf_len_ = 0; |
642 server_cert_ = NULL; | 641 server_cert_ = NULL; |
643 if (server_cert_nss_) { | 642 if (server_cert_nss_) { |
644 CERT_DestroyCertificate(server_cert_nss_); | 643 CERT_DestroyCertificate(server_cert_nss_); |
645 server_cert_nss_ = NULL; | 644 server_cert_nss_ = NULL; |
646 } | 645 } |
647 local_server_cert_verify_result_.Reset(); | 646 local_server_cert_verify_result_.Reset(); |
648 server_cert_verify_result_ = NULL; | 647 server_cert_verify_result_ = NULL; |
649 ssl_connection_status_ = 0; | 648 ssl_connection_status_ = 0; |
650 completed_handshake_ = false; | 649 completed_handshake_ = false; |
651 eset_mitm_detected_ = false; | |
652 start_cert_verification_time_ = base::TimeTicks(); | 650 start_cert_verification_time_ = base::TimeTicks(); |
653 predicted_cert_chain_correct_ = false; | 651 predicted_cert_chain_correct_ = false; |
654 nss_bufs_ = NULL; | 652 nss_bufs_ = NULL; |
655 client_certs_.clear(); | 653 client_certs_.clear(); |
656 client_auth_cert_needed_ = false; | 654 client_auth_cert_needed_ = false; |
657 domain_bound_cert_xtn_negotiated_ = false; | 655 domain_bound_cert_xtn_negotiated_ = false; |
658 | 656 |
659 LeaveFunction(""); | 657 LeaveFunction(""); |
660 } | 658 } |
661 | 659 |
(...skipping 776 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1438 // doesn't require a client cert), we need to invalidate the SSL session | 1436 // doesn't require a client cert), we need to invalidate the SSL session |
1439 // so that we won't try to resume the non-client-authenticated session in | 1437 // so that we won't try to resume the non-client-authenticated session in |
1440 // the next handshake. This will cause the server to ask for a client | 1438 // the next handshake. This will cause the server to ask for a client |
1441 // cert again. | 1439 // cert again. |
1442 if (rv == SECSuccess && SSL_InvalidateSession(nss_fd_) != SECSuccess) { | 1440 if (rv == SECSuccess && SSL_InvalidateSession(nss_fd_) != SECSuccess) { |
1443 LOG(WARNING) << "Couldn't invalidate SSL session: " << PR_GetError(); | 1441 LOG(WARNING) << "Couldn't invalidate SSL session: " << PR_GetError(); |
1444 } | 1442 } |
1445 } | 1443 } |
1446 } else if (rv == SECSuccess) { | 1444 } else if (rv == SECSuccess) { |
1447 if (handshake_callback_called_) { | 1445 if (handshake_callback_called_) { |
1448 if (eset_mitm_detected_) { | 1446 // We need to see if the predicted certificate chain (in |
1449 net_error = ERR_ESET_ANTI_VIRUS_SSL_INTERCEPTION; | 1447 // |ssl_host_info_->state().certs) matches the actual certificate chain |
1450 } else { | 1448 // before we call SaveSSLHostInfo, as that will update |
1451 // We need to see if the predicted certificate chain (in | 1449 // |ssl_host_info_|. |
1452 // |ssl_host_info_->state().certs) matches the actual certificate chain | 1450 if (ssl_host_info_.get() && !ssl_host_info_->state().certs.empty()) { |
1453 // before we call SaveSSLHostInfo, as that will update | 1451 PeerCertificateChain certs(nss_fd_); |
1454 // |ssl_host_info_|. | 1452 const SSLHostInfo::State& state = ssl_host_info_->state(); |
1455 if (ssl_host_info_.get() && !ssl_host_info_->state().certs.empty()) { | 1453 predicted_cert_chain_correct_ = certs.size() == state.certs.size(); |
1456 PeerCertificateChain certs(nss_fd_); | 1454 if (predicted_cert_chain_correct_) { |
1457 const SSLHostInfo::State& state = ssl_host_info_->state(); | 1455 for (unsigned i = 0; i < certs.size(); i++) { |
1458 predicted_cert_chain_correct_ = certs.size() == state.certs.size(); | 1456 if (certs[i]->derCert.len != state.certs[i].size() || |
1459 if (predicted_cert_chain_correct_) { | 1457 memcmp(certs[i]->derCert.data, state.certs[i].data(), |
1460 for (unsigned i = 0; i < certs.size(); i++) { | 1458 certs[i]->derCert.len) != 0) { |
1461 if (certs[i]->derCert.len != state.certs[i].size() || | 1459 predicted_cert_chain_correct_ = false; |
1462 memcmp(certs[i]->derCert.data, state.certs[i].data(), | 1460 break; |
1463 certs[i]->derCert.len) != 0) { | |
1464 predicted_cert_chain_correct_ = false; | |
1465 break; | |
1466 } | |
1467 } | 1461 } |
1468 } | 1462 } |
1469 } | 1463 } |
| 1464 } |
1470 | 1465 |
1471 #if defined(SSL_ENABLE_OCSP_STAPLING) | 1466 #if defined(SSL_ENABLE_OCSP_STAPLING) |
1472 // TODO(agl): figure out how to plumb an OCSP response into the Mac | 1467 // TODO(agl): figure out how to plumb an OCSP response into the Mac |
1473 // system library and update IsOCSPStaplingSupported for Mac. | 1468 // system library and update IsOCSPStaplingSupported for Mac. |
1474 if (!predicted_cert_chain_correct_ && IsOCSPStaplingSupported()) { | 1469 if (!predicted_cert_chain_correct_ && IsOCSPStaplingSupported()) { |
1475 unsigned int len = 0; | 1470 unsigned int len = 0; |
1476 SSL_GetStapledOCSPResponse(nss_fd_, NULL, &len); | 1471 SSL_GetStapledOCSPResponse(nss_fd_, NULL, &len); |
1477 if (len) { | 1472 if (len) { |
1478 const unsigned int orig_len = len; | 1473 const unsigned int orig_len = len; |
1479 scoped_array<uint8> ocsp_response(new uint8[orig_len]); | 1474 scoped_array<uint8> ocsp_response(new uint8[orig_len]); |
1480 SSL_GetStapledOCSPResponse(nss_fd_, ocsp_response.get(), &len); | 1475 SSL_GetStapledOCSPResponse(nss_fd_, ocsp_response.get(), &len); |
1481 DCHECK_EQ(orig_len, len); | 1476 DCHECK_EQ(orig_len, len); |
1482 | 1477 |
1483 #if defined(OS_WIN) | 1478 #if defined(OS_WIN) |
1484 CRYPT_DATA_BLOB ocsp_response_blob; | 1479 CRYPT_DATA_BLOB ocsp_response_blob; |
1485 ocsp_response_blob.cbData = len; | 1480 ocsp_response_blob.cbData = len; |
1486 ocsp_response_blob.pbData = ocsp_response.get(); | 1481 ocsp_response_blob.pbData = ocsp_response.get(); |
1487 BOOL ok = CertSetCertificateContextProperty( | 1482 BOOL ok = CertSetCertificateContextProperty( |
1488 server_cert_->os_cert_handle(), | 1483 server_cert_->os_cert_handle(), |
1489 CERT_OCSP_RESPONSE_PROP_ID, | 1484 CERT_OCSP_RESPONSE_PROP_ID, |
1490 CERT_SET_PROPERTY_IGNORE_PERSIST_ERROR_FLAG, | 1485 CERT_SET_PROPERTY_IGNORE_PERSIST_ERROR_FLAG, |
1491 &ocsp_response_blob); | 1486 &ocsp_response_blob); |
1492 if (!ok) { | 1487 if (!ok) { |
1493 VLOG(1) << "Failed to set OCSP response property: " | 1488 VLOG(1) << "Failed to set OCSP response property: " |
1494 << GetLastError(); | 1489 << GetLastError(); |
1495 } | 1490 } |
1496 #elif defined(USE_NSS) | 1491 #elif defined(USE_NSS) |
1497 CacheOCSPResponseFromSideChannelFunction cache_ocsp_response = | 1492 CacheOCSPResponseFromSideChannelFunction cache_ocsp_response = |
1498 GetCacheOCSPResponseFromSideChannelFunction(); | 1493 GetCacheOCSPResponseFromSideChannelFunction(); |
1499 SECItem ocsp_response_item; | 1494 SECItem ocsp_response_item; |
1500 ocsp_response_item.type = siBuffer; | 1495 ocsp_response_item.type = siBuffer; |
1501 ocsp_response_item.data = ocsp_response.get(); | 1496 ocsp_response_item.data = ocsp_response.get(); |
1502 ocsp_response_item.len = len; | 1497 ocsp_response_item.len = len; |
1503 | 1498 |
1504 cache_ocsp_response( | 1499 cache_ocsp_response( |
1505 CERT_GetDefaultCertDB(), server_cert_nss_, PR_Now(), | 1500 CERT_GetDefaultCertDB(), server_cert_nss_, PR_Now(), |
1506 &ocsp_response_item, NULL); | 1501 &ocsp_response_item, NULL); |
1507 #endif | 1502 #endif |
1508 } | |
1509 } | 1503 } |
| 1504 } |
1510 #endif | 1505 #endif |
1511 | 1506 |
1512 SaveSSLHostInfo(); | 1507 SaveSSLHostInfo(); |
1513 // SSL handshake is completed. Let's verify the certificate. | 1508 // SSL handshake is completed. Let's verify the certificate. |
1514 GotoState(STATE_VERIFY_DNSSEC); | 1509 GotoState(STATE_VERIFY_DNSSEC); |
1515 } | |
1516 // Done! | 1510 // Done! |
1517 } else { | 1511 } else { |
1518 // Workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=562434 - | 1512 // Workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=562434 - |
1519 // SSL_ForceHandshake returned SECSuccess prematurely. | 1513 // SSL_ForceHandshake returned SECSuccess prematurely. |
1520 rv = SECFailure; | 1514 rv = SECFailure; |
1521 net_error = ERR_SSL_PROTOCOL_ERROR; | 1515 net_error = ERR_SSL_PROTOCOL_ERROR; |
1522 net_log_.AddEvent(NetLog::TYPE_SSL_HANDSHAKE_ERROR, | 1516 net_log_.AddEvent(NetLog::TYPE_SSL_HANDSHAKE_ERROR, |
1523 make_scoped_refptr(new SSLErrorParams(net_error, 0))); | 1517 make_scoped_refptr(new SSLErrorParams(net_error, 0))); |
1524 } | 1518 } |
1525 } else { | 1519 } else { |
(...skipping 1122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2648 EnsureThreadIdAssigned(); | 2642 EnsureThreadIdAssigned(); |
2649 base::AutoLock auto_lock(lock_); | 2643 base::AutoLock auto_lock(lock_); |
2650 return valid_thread_id_ == base::PlatformThread::CurrentId(); | 2644 return valid_thread_id_ == base::PlatformThread::CurrentId(); |
2651 } | 2645 } |
2652 | 2646 |
2653 ServerBoundCertService* SSLClientSocketNSS::GetServerBoundCertService() const { | 2647 ServerBoundCertService* SSLClientSocketNSS::GetServerBoundCertService() const { |
2654 return server_bound_cert_service_; | 2648 return server_bound_cert_service_; |
2655 } | 2649 } |
2656 | 2650 |
2657 } // namespace net | 2651 } // namespace net |
OLD | NEW |