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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 61 #include <sslproto.h> | 61 #include <sslproto.h> |
| 62 | 62 |
| 63 #include <algorithm> | 63 #include <algorithm> |
| 64 #include <limits> | 64 #include <limits> |
| 65 #include <map> | 65 #include <map> |
| 66 | 66 |
| 67 #include "base/bind.h" | 67 #include "base/bind.h" |
| 68 #include "base/bind_helpers.h" | 68 #include "base/bind_helpers.h" |
| 69 #include "base/callback_helpers.h" | 69 #include "base/callback_helpers.h" |
| 70 #include "base/compiler_specific.h" | 70 #include "base/compiler_specific.h" |
| 71 #include "base/cpu.h" | |
| 71 #include "base/logging.h" | 72 #include "base/logging.h" |
| 72 #include "base/memory/singleton.h" | 73 #include "base/memory/singleton.h" |
| 73 #include "base/metrics/histogram.h" | 74 #include "base/metrics/histogram.h" |
| 74 #include "base/single_thread_task_runner.h" | 75 #include "base/single_thread_task_runner.h" |
| 75 #include "base/stl_util.h" | 76 #include "base/stl_util.h" |
| 76 #include "base/strings/string_number_conversions.h" | 77 #include "base/strings/string_number_conversions.h" |
| 77 #include "base/strings/string_util.h" | 78 #include "base/strings/string_util.h" |
| 78 #include "base/strings/stringprintf.h" | 79 #include "base/strings/stringprintf.h" |
| 79 #include "base/thread_task_runner_handle.h" | 80 #include "base/thread_task_runner_handle.h" |
| 80 #include "base/threading/thread_restrictions.h" | 81 #include "base/threading/thread_restrictions.h" |
| (...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 483 switch (err) { | 484 switch (err) { |
| 484 // If the server closed on us, it is a protocol error. | 485 // If the server closed on us, it is a protocol error. |
| 485 // Some TLS-intolerant servers do this when we request TLS. | 486 // Some TLS-intolerant servers do this when we request TLS. |
| 486 case PR_END_OF_FILE_ERROR: | 487 case PR_END_OF_FILE_ERROR: |
| 487 return ERR_SSL_PROTOCOL_ERROR; | 488 return ERR_SSL_PROTOCOL_ERROR; |
| 488 default: | 489 default: |
| 489 return MapNSSClientError(err); | 490 return MapNSSClientError(err); |
| 490 } | 491 } |
| 491 } | 492 } |
| 492 | 493 |
| 494 // CiphersRemove takes a zero-terminated array of cipher suite ids in | |
| 495 // |to_remove| and sets every instance of them in |ciphers| to zero. It returns | |
| 496 // true if it found and removed every element of |to_remove|. It assumes that | |
| 497 // there are no duplicates in |ciphers| nor in |to_remove|. | |
| 498 bool CiphersRemove(const uint16* to_remove, uint16* ciphers, size_t num) { | |
| 499 size_t num_remove, found = 0; | |
| 500 | |
| 501 for (num_remove = 0; ; num_remove++) { | |
| 502 if (to_remove[num_remove] == 0) | |
| 503 break; | |
| 504 } | |
| 505 | |
| 506 for (size_t i = 0; i < num; i++) { | |
| 507 for (size_t j = 0; j < num_remove; j++) { | |
| 508 if (to_remove[j] == ciphers[i]) { | |
| 509 ciphers[i] = 0; | |
| 510 found++; | |
| 511 break; | |
| 512 } | |
| 513 } | |
| 514 } | |
| 515 | |
| 516 return found == num_remove; | |
| 517 } | |
| 518 | |
| 519 // CiphersCompact takes an array of cipher suite ids in |ciphers|, where some | |
| 520 // entries are zero, and moves the entries so that all the non-zero elements | |
| 521 // are compacted at the end of the array. | |
| 522 size_t CiphersCompact(uint16* ciphers, size_t num) { | |
| 523 size_t j = num - 1; | |
| 524 | |
| 525 for (size_t i = num - 1; i < num; i--) { | |
| 526 printf("@%u %d %u\n", (unsigned) i, ciphers[i], (unsigned) j); | |
| 527 if (ciphers[i] == 0) | |
| 528 continue; | |
| 529 ciphers[j--] = ciphers[i]; | |
| 530 } | |
| 531 return j+1; | |
| 532 } | |
| 533 | |
| 534 // CiphersCopy copies the zero-terminated array |in| to |out|. | |
| 535 size_t CiphersCopy(const uint16* in, uint16* out) { | |
| 536 for (size_t i = 0; ; i++) { | |
| 537 if (in[i] == 0) | |
| 538 return i; | |
| 539 out[i] = in[i]; | |
| 540 } | |
| 541 } | |
| 542 | |
| 493 } // namespace | 543 } // namespace |
| 494 | 544 |
| 495 // SSLClientSocketNSS::Core provides a thread-safe, ref-counted core that is | 545 // SSLClientSocketNSS::Core provides a thread-safe, ref-counted core that is |
| 496 // able to marshal data between NSS functions and an underlying transport | 546 // able to marshal data between NSS functions and an underlying transport |
| 497 // socket. | 547 // socket. |
| 498 // | 548 // |
| 499 // All public functions are meant to be called from the network task runner, | 549 // All public functions are meant to be called from the network task runner, |
| 500 // and any callbacks supplied will be invoked there as well, provided that | 550 // and any callbacks supplied will be invoked there as well, provided that |
| 501 // Detach() has not been called yet. | 551 // Detach() has not been called yet. |
| 502 // | 552 // |
| (...skipping 2608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3111 } | 3161 } |
| 3112 | 3162 |
| 3113 for (std::vector<uint16>::const_iterator it = | 3163 for (std::vector<uint16>::const_iterator it = |
| 3114 ssl_config_.disabled_cipher_suites.begin(); | 3164 ssl_config_.disabled_cipher_suites.begin(); |
| 3115 it != ssl_config_.disabled_cipher_suites.end(); ++it) { | 3165 it != ssl_config_.disabled_cipher_suites.end(); ++it) { |
| 3116 // This will fail if the specified cipher is not implemented by NSS, but | 3166 // This will fail if the specified cipher is not implemented by NSS, but |
| 3117 // the failure is harmless. | 3167 // the failure is harmless. |
| 3118 SSL_CipherPrefSet(nss_fd_, *it, PR_FALSE); | 3168 SSL_CipherPrefSet(nss_fd_, *it, PR_FALSE); |
| 3119 } | 3169 } |
| 3120 | 3170 |
| 3171 /* Our top preference cipher suites are either forward-secure AES-GCM or | |
| 3172 * forward secure ChaCha20-Poly1305. If the local machine has AES-NI then we | |
| 3173 * prefer AES-GCM, otherwise ChaCha20. The remainder of the cipher suite | |
| 3174 * preference is inheriented from NSS. */ | |
| 3175 static const uint16 chacha_ciphers[] = { | |
| 3176 0xcc14 /* TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 */, | |
| 3177 0xcc13 /* TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 */, | |
| 3178 0, | |
| 3179 }; | |
| 3180 static const uint16 aes_gcm_ciphers[] = { | |
| 3181 0xc02b /* TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 */, | |
| 3182 0xc02f /* TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 */, | |
| 3183 0x9e /* TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 */, | |
| 3184 0, | |
| 3185 }; | |
| 3186 const PRUint16 *all_ciphers = SSL_GetImplementedCiphers(); | |
| 3187 const size_t num_ciphers = SSL_GetNumImplementedCiphers(); | |
| 3188 scoped_ptr<uint16[]> ciphers(new uint16[num_ciphers]); | |
| 3189 memcpy(ciphers.get(), all_ciphers, sizeof(uint16)*num_ciphers); | |
| 3190 | |
| 3191 if (CiphersRemove(chacha_ciphers, ciphers.get(), num_ciphers) && | |
| 3192 CiphersRemove(aes_gcm_ciphers, ciphers.get(), num_ciphers)) { | |
| 3193 CiphersCompact(ciphers.get(), num_ciphers); | |
| 3194 | |
| 3195 const uint16 *preference_ciphers = chacha_ciphers; | |
| 3196 const uint16 *other_ciphers = aes_gcm_ciphers; | |
| 3197 if (base::CPU().has_aesni()) { | |
|
wtc
2013/11/19 23:00:44
Since this won't change over time, we should ideal
agl
2013/11/20 18:21:07
Done.
| |
| 3198 preference_ciphers = aes_gcm_ciphers; | |
| 3199 other_ciphers = chacha_ciphers; | |
| 3200 } | |
| 3201 unsigned i = CiphersCopy(preference_ciphers, ciphers.get()); | |
| 3202 CiphersCopy(other_ciphers, &ciphers[i]); | |
| 3203 | |
| 3204 rv = SSL_CipherOrderSet(nss_fd_, ciphers.get(), num_ciphers); | |
| 3205 if (rv != SECSuccess) { | |
| 3206 LogFailedNSSFunction(net_log_, "SSL_CipherOrderSet", ""); | |
| 3207 } | |
| 3208 } | |
| 3209 | |
| 3121 // Support RFC 5077 | 3210 // Support RFC 5077 |
| 3122 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SESSION_TICKETS, PR_TRUE); | 3211 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SESSION_TICKETS, PR_TRUE); |
| 3123 if (rv != SECSuccess) { | 3212 if (rv != SECSuccess) { |
| 3124 LogFailedNSSFunction( | 3213 LogFailedNSSFunction( |
| 3125 net_log_, "SSL_OptionSet", "SSL_ENABLE_SESSION_TICKETS"); | 3214 net_log_, "SSL_OptionSet", "SSL_ENABLE_SESSION_TICKETS"); |
| 3126 } | 3215 } |
| 3127 | 3216 |
| 3128 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_FALSE_START, | 3217 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_FALSE_START, |
| 3129 ssl_config_.false_start_enabled); | 3218 ssl_config_.false_start_enabled); |
| 3130 if (rv != SECSuccess) | 3219 if (rv != SECSuccess) |
| (...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3479 EnsureThreadIdAssigned(); | 3568 EnsureThreadIdAssigned(); |
| 3480 base::AutoLock auto_lock(lock_); | 3569 base::AutoLock auto_lock(lock_); |
| 3481 return valid_thread_id_ == base::PlatformThread::CurrentId(); | 3570 return valid_thread_id_ == base::PlatformThread::CurrentId(); |
| 3482 } | 3571 } |
| 3483 | 3572 |
| 3484 ServerBoundCertService* SSLClientSocketNSS::GetServerBoundCertService() const { | 3573 ServerBoundCertService* SSLClientSocketNSS::GetServerBoundCertService() const { |
| 3485 return server_bound_cert_service_; | 3574 return server_bound_cert_service_; |
| 3486 } | 3575 } |
| 3487 | 3576 |
| 3488 } // namespace net | 3577 } // namespace net |
| OLD | NEW |