| Index: net/socket/ssl_client_socket_nss.cc
|
| diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc
|
| index 0ac5a83a0fa3440830e5840fc900d69138263238..b0c392bb97cfe6a44c6f7a7cbd039e0c582dd760 100644
|
| --- a/net/socket/ssl_client_socket_nss.cc
|
| +++ b/net/socket/ssl_client_socket_nss.cc
|
| @@ -3432,15 +3432,26 @@ int SSLClientSocketNSS::DoVerifyCertComplete(int result) {
|
| // Pinning is only enabled for official builds to make sure that others don't
|
| // end up with pins that cannot be easily updated.
|
| //
|
| - // TODO(agl): we might have an issue here where a request for foo.example.com
|
| + // TODO(agl): We might have an issue here where a request for foo.example.com
|
| // merges into a SPDY connection to www.example.com, and gets a different
|
| // certificate.
|
|
|
| + // Perform pin validation if, and only if, all these conditions obtain:
|
| + //
|
| + // * a TransportSecurityState object is available;
|
| + // * the server's certificate chain is valid (or suffers from only a minor
|
| + // error);
|
| + // * the server's certificate chain chains up to a known root (i.e. not a
|
| + // user-installed trust anchor); and
|
| + // * the build is recent (very old builds should fail open so that users
|
| + // have some chance to recover).
|
| + //
|
| const CertStatus cert_status = server_cert_verify_result_.cert_status;
|
| - if ((result == OK || (IsCertificateError(result) &&
|
| - IsCertStatusMinorError(cert_status))) &&
|
| + if (transport_security_state_ &&
|
| + (result == OK ||
|
| + (IsCertificateError(result) && IsCertStatusMinorError(cert_status))) &&
|
| server_cert_verify_result_.is_issued_by_known_root &&
|
| - transport_security_state_) {
|
| + TransportSecurityState::IsBuildTimely()) {
|
| bool sni_available =
|
| ssl_config_.version_max >= SSL_PROTOCOL_VERSION_TLS1 ||
|
| ssl_config_.version_fallback;
|
| @@ -3451,13 +3462,10 @@ int SSLClientSocketNSS::DoVerifyCertComplete(int result) {
|
| &domain_state) &&
|
| domain_state.HasPublicKeyPins()) {
|
| if (!domain_state.CheckPublicKeyPins(
|
| - server_cert_verify_result_.public_key_hashes)) {
|
| - // Pins are not enforced if the build is too old.
|
| - if (TransportSecurityState::IsBuildTimely()) {
|
| - result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN;
|
| - UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", false);
|
| - TransportSecurityState::ReportUMAOnPinFailure(host);
|
| - }
|
| + server_cert_verify_result_.public_key_hashes)) {
|
| + result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN;
|
| + UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", false);
|
| + TransportSecurityState::ReportUMAOnPinFailure(host);
|
| } else {
|
| UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", true);
|
| }
|
|
|