| 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 #include "net/socket/nss_ssl_util.h" | 5 #include "net/socket/nss_ssl_util.h" |
| 6 | 6 |
| 7 #include <nss.h> | 7 #include <nss.h> |
| 8 #include <secerr.h> | 8 #include <secerr.h> |
| 9 #include <ssl.h> | 9 #include <ssl.h> |
| 10 #include <sslerr.h> | 10 #include <sslerr.h> |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 #endif | 30 #endif |
| 31 | 31 |
| 32 namespace net { | 32 namespace net { |
| 33 | 33 |
| 34 namespace { | 34 namespace { |
| 35 | 35 |
| 36 // CiphersRemove takes a zero-terminated array of cipher suite ids in | 36 // CiphersRemove takes a zero-terminated array of cipher suite ids in |
| 37 // |to_remove| and sets every instance of them in |ciphers| to zero. It returns | 37 // |to_remove| and sets every instance of them in |ciphers| to zero. It returns |
| 38 // true if it found and removed every element of |to_remove|. It assumes that | 38 // true if it found and removed every element of |to_remove|. It assumes that |
| 39 // there are no duplicates in |ciphers| nor in |to_remove|. | 39 // there are no duplicates in |ciphers| nor in |to_remove|. |
| 40 bool CiphersRemove(const uint16* to_remove, uint16* ciphers, size_t num) { | 40 bool CiphersRemove(const uint16_t* to_remove, uint16_t* ciphers, size_t num) { |
| 41 size_t i, found = 0; | 41 size_t i, found = 0; |
| 42 | 42 |
| 43 for (i = 0; ; i++) { | 43 for (i = 0; ; i++) { |
| 44 if (to_remove[i] == 0) | 44 if (to_remove[i] == 0) |
| 45 break; | 45 break; |
| 46 | 46 |
| 47 for (size_t j = 0; j < num; j++) { | 47 for (size_t j = 0; j < num; j++) { |
| 48 if (to_remove[i] == ciphers[j]) { | 48 if (to_remove[i] == ciphers[j]) { |
| 49 ciphers[j] = 0; | 49 ciphers[j] = 0; |
| 50 found++; | 50 found++; |
| 51 break; | 51 break; |
| 52 } | 52 } |
| 53 } | 53 } |
| 54 } | 54 } |
| 55 | 55 |
| 56 return found == i; | 56 return found == i; |
| 57 } | 57 } |
| 58 | 58 |
| 59 // CiphersCompact takes an array of cipher suite ids in |ciphers|, where some | 59 // CiphersCompact takes an array of cipher suite ids in |ciphers|, where some |
| 60 // entries are zero, and moves the entries so that all the non-zero elements | 60 // entries are zero, and moves the entries so that all the non-zero elements |
| 61 // are compacted at the end of the array. | 61 // are compacted at the end of the array. |
| 62 void CiphersCompact(uint16* ciphers, size_t num) { | 62 void CiphersCompact(uint16_t* ciphers, size_t num) { |
| 63 size_t j = num - 1; | 63 size_t j = num - 1; |
| 64 | 64 |
| 65 for (size_t i = num - 1; i < num; i--) { | 65 for (size_t i = num - 1; i < num; i--) { |
| 66 if (ciphers[i] == 0) | 66 if (ciphers[i] == 0) |
| 67 continue; | 67 continue; |
| 68 ciphers[j--] = ciphers[i]; | 68 ciphers[j--] = ciphers[i]; |
| 69 } | 69 } |
| 70 } | 70 } |
| 71 | 71 |
| 72 // CiphersCopy copies the zero-terminated array |in| to |out|. It returns the | 72 // CiphersCopy copies the zero-terminated array |in| to |out|. It returns the |
| 73 // number of cipher suite ids copied. | 73 // number of cipher suite ids copied. |
| 74 size_t CiphersCopy(const uint16* in, uint16* out) { | 74 size_t CiphersCopy(const uint16_t* in, uint16_t* out) { |
| 75 for (size_t i = 0; ; i++) { | 75 for (size_t i = 0; ; i++) { |
| 76 if (in[i] == 0) | 76 if (in[i] == 0) |
| 77 return i; | 77 return i; |
| 78 out[i] = in[i]; | 78 out[i] = in[i]; |
| 79 } | 79 } |
| 80 } | 80 } |
| 81 | 81 |
| 82 scoped_ptr<base::Value> NetLogSSLErrorCallback( | 82 scoped_ptr<base::Value> NetLogSSLErrorCallback( |
| 83 int net_error, | 83 int net_error, |
| 84 int ssl_lib_error, | 84 int ssl_lib_error, |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 SSL_OptionSetDefault(SSL_SECURITY, PR_TRUE); | 139 SSL_OptionSetDefault(SSL_SECURITY, PR_TRUE); |
| 140 | 140 |
| 141 // Calculate the order of ciphers that we'll use for NSS sockets. (Note | 141 // Calculate the order of ciphers that we'll use for NSS sockets. (Note |
| 142 // that, even if a cipher is specified in the ordering, it must still be | 142 // that, even if a cipher is specified in the ordering, it must still be |
| 143 // enabled in order to be included in a ClientHello.) | 143 // enabled in order to be included in a ClientHello.) |
| 144 // | 144 // |
| 145 // Our top preference cipher suites are either forward-secret AES-GCM or | 145 // Our top preference cipher suites are either forward-secret AES-GCM or |
| 146 // forward-secret ChaCha20-Poly1305. If the local machine has AES-NI then | 146 // forward-secret ChaCha20-Poly1305. If the local machine has AES-NI then |
| 147 // we prefer AES-GCM, otherwise ChaCha20. The remainder of the cipher suite | 147 // we prefer AES-GCM, otherwise ChaCha20. The remainder of the cipher suite |
| 148 // preference is inheriented from NSS. */ | 148 // preference is inheriented from NSS. */ |
| 149 static const uint16 chacha_ciphers[] = { | 149 static const uint16_t chacha_ciphers[] = { |
| 150 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, | 150 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, |
| 151 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, | 151 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 0, |
| 152 0, | |
| 153 }; | 152 }; |
| 154 static const uint16 aes_gcm_ciphers[] = { | 153 static const uint16_t aes_gcm_ciphers[] = { |
| 155 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, | 154 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, |
| 156 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, | 155 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, |
| 157 TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, | 156 TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, 0, |
| 158 0, | |
| 159 }; | 157 }; |
| 160 scoped_ptr<uint16[]> ciphers(new uint16[num_ciphers]); | 158 scoped_ptr<uint16_t[]> ciphers(new uint16_t[num_ciphers]); |
| 161 memcpy(ciphers.get(), ssl_ciphers, sizeof(uint16)*num_ciphers); | 159 memcpy(ciphers.get(), ssl_ciphers, sizeof(uint16_t) * num_ciphers); |
| 162 | 160 |
| 163 if (CiphersRemove(chacha_ciphers, ciphers.get(), num_ciphers) && | 161 if (CiphersRemove(chacha_ciphers, ciphers.get(), num_ciphers) && |
| 164 CiphersRemove(aes_gcm_ciphers, ciphers.get(), num_ciphers)) { | 162 CiphersRemove(aes_gcm_ciphers, ciphers.get(), num_ciphers)) { |
| 165 CiphersCompact(ciphers.get(), num_ciphers); | 163 CiphersCompact(ciphers.get(), num_ciphers); |
| 166 | 164 |
| 167 const uint16* preference_ciphers = chacha_ciphers; | 165 const uint16_t* preference_ciphers = chacha_ciphers; |
| 168 const uint16* other_ciphers = aes_gcm_ciphers; | 166 const uint16_t* other_ciphers = aes_gcm_ciphers; |
| 169 base::CPU cpu; | 167 base::CPU cpu; |
| 170 | 168 |
| 171 if (cpu.has_aesni() && cpu.has_avx()) { | 169 if (cpu.has_aesni() && cpu.has_avx()) { |
| 172 preference_ciphers = aes_gcm_ciphers; | 170 preference_ciphers = aes_gcm_ciphers; |
| 173 other_ciphers = chacha_ciphers; | 171 other_ciphers = chacha_ciphers; |
| 174 } | 172 } |
| 175 unsigned i = CiphersCopy(preference_ciphers, ciphers.get()); | 173 unsigned i = CiphersCopy(preference_ciphers, ciphers.get()); |
| 176 CiphersCopy(other_ciphers, &ciphers[i]); | 174 CiphersCopy(other_ciphers, &ciphers[i]); |
| 177 | 175 |
| 178 if ((model_fd_ = memio_CreateIOLayer(1, 1)) == NULL || | 176 if ((model_fd_ = memio_CreateIOLayer(1, 1)) == NULL || |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 403 base::Bind(&NetLogSSLFailedNSSFunctionCallback, | 401 base::Bind(&NetLogSSLFailedNSSFunctionCallback, |
| 404 function, param, PR_GetError())); | 402 function, param, PR_GetError())); |
| 405 } | 403 } |
| 406 | 404 |
| 407 NetLog::ParametersCallback CreateNetLogSSLErrorCallback(int net_error, | 405 NetLog::ParametersCallback CreateNetLogSSLErrorCallback(int net_error, |
| 408 int ssl_lib_error) { | 406 int ssl_lib_error) { |
| 409 return base::Bind(&NetLogSSLErrorCallback, net_error, ssl_lib_error); | 407 return base::Bind(&NetLogSSLErrorCallback, net_error, ssl_lib_error); |
| 410 } | 408 } |
| 411 | 409 |
| 412 } // namespace net | 410 } // namespace net |
| OLD | NEW |