| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2008 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2008 The WebRTC Project Authors. All rights reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 #include "webrtc/base/sslroots.h" | 34 #include "webrtc/base/sslroots.h" |
| 35 #include "webrtc/base/stringutils.h" | 35 #include "webrtc/base/stringutils.h" |
| 36 #include "webrtc/base/thread.h" | 36 #include "webrtc/base/thread.h" |
| 37 | 37 |
| 38 #ifndef OPENSSL_IS_BORINGSSL | 38 #ifndef OPENSSL_IS_BORINGSSL |
| 39 | 39 |
| 40 // TODO: Use a nicer abstraction for mutex. | 40 // TODO: Use a nicer abstraction for mutex. |
| 41 | 41 |
| 42 #if defined(WEBRTC_WIN) | 42 #if defined(WEBRTC_WIN) |
| 43 #define MUTEX_TYPE HANDLE | 43 #define MUTEX_TYPE HANDLE |
| 44 #define MUTEX_SETUP(x) (x) = CreateMutex(NULL, FALSE, NULL) | 44 #define MUTEX_SETUP(x) (x) = CreateMutex(nullptr, FALSE, nullptr) |
| 45 #define MUTEX_CLEANUP(x) CloseHandle(x) | 45 #define MUTEX_CLEANUP(x) CloseHandle(x) |
| 46 #define MUTEX_LOCK(x) WaitForSingleObject((x), INFINITE) | 46 #define MUTEX_LOCK(x) WaitForSingleObject((x), INFINITE) |
| 47 #define MUTEX_UNLOCK(x) ReleaseMutex(x) | 47 #define MUTEX_UNLOCK(x) ReleaseMutex(x) |
| 48 #define THREAD_ID GetCurrentThreadId() | 48 #define THREAD_ID GetCurrentThreadId() |
| 49 #elif defined(WEBRTC_POSIX) | 49 #elif defined(WEBRTC_POSIX) |
| 50 #define MUTEX_TYPE pthread_mutex_t | 50 #define MUTEX_TYPE pthread_mutex_t |
| 51 #define MUTEX_SETUP(x) pthread_mutex_init(&(x), NULL) | 51 #define MUTEX_SETUP(x) pthread_mutex_init(&(x), nullptr) |
| 52 #define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x)) | 52 #define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x)) |
| 53 #define MUTEX_LOCK(x) pthread_mutex_lock(&(x)) | 53 #define MUTEX_LOCK(x) pthread_mutex_lock(&(x)) |
| 54 #define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x)) | 54 #define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x)) |
| 55 #define THREAD_ID pthread_self() | 55 #define THREAD_ID pthread_self() |
| 56 #else | 56 #else |
| 57 #error You must define mutex operations appropriate for your platform! | 57 #error You must define mutex operations appropriate for your platform! |
| 58 #endif | 58 #endif |
| 59 | 59 |
| 60 struct CRYPTO_dynlock_value { | 60 struct CRYPTO_dynlock_value { |
| 61 MUTEX_TYPE mutex; | 61 MUTEX_TYPE mutex; |
| 62 }; | 62 }; |
| 63 | 63 |
| 64 #endif // #ifndef OPENSSL_IS_BORINGSSL | 64 #endif // #ifndef OPENSSL_IS_BORINGSSL |
| 65 | 65 |
| 66 ////////////////////////////////////////////////////////////////////// | 66 ////////////////////////////////////////////////////////////////////// |
| 67 // SocketBIO | 67 // SocketBIO |
| 68 ////////////////////////////////////////////////////////////////////// | 68 ////////////////////////////////////////////////////////////////////// |
| 69 | 69 |
| 70 static int socket_write(BIO* h, const char* buf, int num); | 70 static int socket_write(BIO* h, const char* buf, int num); |
| 71 static int socket_read(BIO* h, char* buf, int size); | 71 static int socket_read(BIO* h, char* buf, int size); |
| 72 static int socket_puts(BIO* h, const char* str); | 72 static int socket_puts(BIO* h, const char* str); |
| 73 static long socket_ctrl(BIO* h, int cmd, long arg1, void* arg2); | 73 static long socket_ctrl(BIO* h, int cmd, long arg1, void* arg2); |
| 74 static int socket_new(BIO* h); | 74 static int socket_new(BIO* h); |
| 75 static int socket_free(BIO* data); | 75 static int socket_free(BIO* data); |
| 76 | 76 |
| 77 // TODO(davidben): This should be const once BoringSSL is assumed. | 77 // TODO(davidben): This should be const once BoringSSL is assumed. |
| 78 static BIO_METHOD methods_socket = { | 78 static BIO_METHOD methods_socket = { |
| 79 BIO_TYPE_BIO, | 79 BIO_TYPE_BIO, "socket", socket_write, socket_read, socket_puts, 0, |
| 80 "socket", | 80 socket_ctrl, socket_new, socket_free, nullptr, |
| 81 socket_write, | |
| 82 socket_read, | |
| 83 socket_puts, | |
| 84 0, | |
| 85 socket_ctrl, | |
| 86 socket_new, | |
| 87 socket_free, | |
| 88 NULL, | |
| 89 }; | 81 }; |
| 90 | 82 |
| 91 static BIO_METHOD* BIO_s_socket2() { return(&methods_socket); } | 83 static BIO_METHOD* BIO_s_socket2() { return(&methods_socket); } |
| 92 | 84 |
| 93 static BIO* BIO_new_socket(rtc::AsyncSocket* socket) { | 85 static BIO* BIO_new_socket(rtc::AsyncSocket* socket) { |
| 94 BIO* ret = BIO_new(BIO_s_socket2()); | 86 BIO* ret = BIO_new(BIO_s_socket2()); |
| 95 if (ret == NULL) { | 87 if (ret == nullptr) { |
| 96 return NULL; | 88 return nullptr; |
| 97 } | 89 } |
| 98 ret->ptr = socket; | 90 ret->ptr = socket; |
| 99 return ret; | 91 return ret; |
| 100 } | 92 } |
| 101 | 93 |
| 102 static int socket_new(BIO* b) { | 94 static int socket_new(BIO* b) { |
| 103 b->shutdown = 0; | 95 b->shutdown = 0; |
| 104 b->init = 1; | 96 b->init = 1; |
| 105 b->num = 0; // 1 means socket closed | 97 b->num = 0; // 1 means socket closed |
| 106 b->ptr = 0; | 98 b->ptr = 0; |
| 107 return 1; | 99 return 1; |
| 108 } | 100 } |
| 109 | 101 |
| 110 static int socket_free(BIO* b) { | 102 static int socket_free(BIO* b) { |
| 111 if (b == NULL) | 103 if (b == nullptr) |
| 112 return 0; | 104 return 0; |
| 113 return 1; | 105 return 1; |
| 114 } | 106 } |
| 115 | 107 |
| 116 static int socket_read(BIO* b, char* out, int outl) { | 108 static int socket_read(BIO* b, char* out, int outl) { |
| 117 if (!out) | 109 if (!out) |
| 118 return -1; | 110 return -1; |
| 119 rtc::AsyncSocket* socket = static_cast<rtc::AsyncSocket*>(b->ptr); | 111 rtc::AsyncSocket* socket = static_cast<rtc::AsyncSocket*>(b->ptr); |
| 120 BIO_clear_retry_flags(b); | 112 BIO_clear_retry_flags(b); |
| 121 int result = socket->Recv(out, outl, nullptr); | 113 int result = socket->Recv(out, outl, nullptr); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 168 | 160 |
| 169 ///////////////////////////////////////////////////////////////////////////// | 161 ///////////////////////////////////////////////////////////////////////////// |
| 170 // OpenSSLAdapter | 162 // OpenSSLAdapter |
| 171 ///////////////////////////////////////////////////////////////////////////// | 163 ///////////////////////////////////////////////////////////////////////////// |
| 172 | 164 |
| 173 namespace rtc { | 165 namespace rtc { |
| 174 | 166 |
| 175 #ifndef OPENSSL_IS_BORINGSSL | 167 #ifndef OPENSSL_IS_BORINGSSL |
| 176 | 168 |
| 177 // This array will store all of the mutexes available to OpenSSL. | 169 // This array will store all of the mutexes available to OpenSSL. |
| 178 static MUTEX_TYPE* mutex_buf = NULL; | 170 static MUTEX_TYPE* mutex_buf = nullptr; |
| 179 | 171 |
| 180 static void locking_function(int mode, int n, const char * file, int line) { | 172 static void locking_function(int mode, int n, const char * file, int line) { |
| 181 if (mode & CRYPTO_LOCK) { | 173 if (mode & CRYPTO_LOCK) { |
| 182 MUTEX_LOCK(mutex_buf[n]); | 174 MUTEX_LOCK(mutex_buf[n]); |
| 183 } else { | 175 } else { |
| 184 MUTEX_UNLOCK(mutex_buf[n]); | 176 MUTEX_UNLOCK(mutex_buf[n]); |
| 185 } | 177 } |
| 186 } | 178 } |
| 187 | 179 |
| 188 static unsigned long id_function() { // NOLINT | 180 static unsigned long id_function() { // NOLINT |
| 189 // Use old-style C cast because THREAD_ID's type varies with the platform, | 181 // Use old-style C cast because THREAD_ID's type varies with the platform, |
| 190 // in some cases requiring static_cast, and in others requiring | 182 // in some cases requiring static_cast, and in others requiring |
| 191 // reinterpret_cast. | 183 // reinterpret_cast. |
| 192 return (unsigned long)THREAD_ID; // NOLINT | 184 return (unsigned long)THREAD_ID; // NOLINT |
| 193 } | 185 } |
| 194 | 186 |
| 195 static CRYPTO_dynlock_value* dyn_create_function(const char* file, int line) { | 187 static CRYPTO_dynlock_value* dyn_create_function(const char* file, int line) { |
| 196 CRYPTO_dynlock_value* value = new CRYPTO_dynlock_value; | 188 CRYPTO_dynlock_value* value = new CRYPTO_dynlock_value; |
| 197 if (!value) | 189 if (!value) |
| 198 return NULL; | 190 return nullptr; |
| 199 MUTEX_SETUP(value->mutex); | 191 MUTEX_SETUP(value->mutex); |
| 200 return value; | 192 return value; |
| 201 } | 193 } |
| 202 | 194 |
| 203 static void dyn_lock_function(int mode, CRYPTO_dynlock_value* l, | 195 static void dyn_lock_function(int mode, CRYPTO_dynlock_value* l, |
| 204 const char* file, int line) { | 196 const char* file, int line) { |
| 205 if (mode & CRYPTO_LOCK) { | 197 if (mode & CRYPTO_LOCK) { |
| 206 MUTEX_LOCK(l->mutex); | 198 MUTEX_LOCK(l->mutex); |
| 207 } else { | 199 } else { |
| 208 MUTEX_UNLOCK(l->mutex); | 200 MUTEX_UNLOCK(l->mutex); |
| 209 } | 201 } |
| 210 } | 202 } |
| 211 | 203 |
| 212 static void dyn_destroy_function(CRYPTO_dynlock_value* l, | 204 static void dyn_destroy_function(CRYPTO_dynlock_value* l, |
| 213 const char* file, int line) { | 205 const char* file, int line) { |
| 214 MUTEX_CLEANUP(l->mutex); | 206 MUTEX_CLEANUP(l->mutex); |
| 215 delete l; | 207 delete l; |
| 216 } | 208 } |
| 217 | 209 |
| 218 #endif // #ifndef OPENSSL_IS_BORINGSSL | 210 #endif // #ifndef OPENSSL_IS_BORINGSSL |
| 219 | 211 |
| 220 VerificationCallback OpenSSLAdapter::custom_verify_callback_ = NULL; | 212 VerificationCallback OpenSSLAdapter::custom_verify_callback_ = nullptr; |
| 221 | 213 |
| 222 bool OpenSSLAdapter::InitializeSSL(VerificationCallback callback) { | 214 bool OpenSSLAdapter::InitializeSSL(VerificationCallback callback) { |
| 223 if (!InitializeSSLThread() || !SSL_library_init()) | 215 if (!InitializeSSLThread() || !SSL_library_init()) |
| 224 return false; | 216 return false; |
| 225 #if !defined(ADDRESS_SANITIZER) || !defined(WEBRTC_MAC) || defined(WEBRTC_IOS) | 217 #if !defined(ADDRESS_SANITIZER) || !defined(WEBRTC_MAC) || defined(WEBRTC_IOS) |
| 226 // Loading the error strings crashes mac_asan. Omit this debugging aid there. | 218 // Loading the error strings crashes mac_asan. Omit this debugging aid there. |
| 227 SSL_load_error_strings(); | 219 SSL_load_error_strings(); |
| 228 #endif | 220 #endif |
| 229 ERR_load_BIO_strings(); | 221 ERR_load_BIO_strings(); |
| 230 OpenSSL_add_all_algorithms(); | 222 OpenSSL_add_all_algorithms(); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 251 CRYPTO_set_dynlock_lock_callback(dyn_lock_function); | 243 CRYPTO_set_dynlock_lock_callback(dyn_lock_function); |
| 252 CRYPTO_set_dynlock_destroy_callback(dyn_destroy_function); | 244 CRYPTO_set_dynlock_destroy_callback(dyn_destroy_function); |
| 253 #endif // #ifndef OPENSSL_IS_BORINGSSL | 245 #endif // #ifndef OPENSSL_IS_BORINGSSL |
| 254 return true; | 246 return true; |
| 255 } | 247 } |
| 256 | 248 |
| 257 bool OpenSSLAdapter::CleanupSSL() { | 249 bool OpenSSLAdapter::CleanupSSL() { |
| 258 #ifndef OPENSSL_IS_BORINGSSL | 250 #ifndef OPENSSL_IS_BORINGSSL |
| 259 if (!mutex_buf) | 251 if (!mutex_buf) |
| 260 return false; | 252 return false; |
| 261 CRYPTO_set_id_callback(NULL); | 253 CRYPTO_set_id_callback(nullptr); |
| 262 CRYPTO_set_locking_callback(NULL); | 254 CRYPTO_set_locking_callback(nullptr); |
| 263 CRYPTO_set_dynlock_create_callback(NULL); | 255 CRYPTO_set_dynlock_create_callback(nullptr); |
| 264 CRYPTO_set_dynlock_lock_callback(NULL); | 256 CRYPTO_set_dynlock_lock_callback(nullptr); |
| 265 CRYPTO_set_dynlock_destroy_callback(NULL); | 257 CRYPTO_set_dynlock_destroy_callback(nullptr); |
| 266 for (int i = 0; i < CRYPTO_num_locks(); ++i) | 258 for (int i = 0; i < CRYPTO_num_locks(); ++i) |
| 267 MUTEX_CLEANUP(mutex_buf[i]); | 259 MUTEX_CLEANUP(mutex_buf[i]); |
| 268 delete [] mutex_buf; | 260 delete [] mutex_buf; |
| 269 mutex_buf = NULL; | 261 mutex_buf = nullptr; |
| 270 #endif // #ifndef OPENSSL_IS_BORINGSSL | 262 #endif // #ifndef OPENSSL_IS_BORINGSSL |
| 271 return true; | 263 return true; |
| 272 } | 264 } |
| 273 | 265 |
| 274 OpenSSLAdapter::OpenSSLAdapter(AsyncSocket* socket) | 266 OpenSSLAdapter::OpenSSLAdapter(AsyncSocket* socket) |
| 275 : SSLAdapter(socket), | 267 : SSLAdapter(socket), |
| 276 state_(SSL_NONE), | 268 state_(SSL_NONE), |
| 277 ssl_read_needs_write_(false), | 269 ssl_read_needs_write_(false), |
| 278 ssl_write_needs_read_(false), | 270 ssl_write_needs_read_(false), |
| 279 restartable_(false), | 271 restartable_(false), |
| 280 ssl_(NULL), ssl_ctx_(NULL), | 272 ssl_(nullptr), |
| 281 ssl_mode_(SSL_MODE_TLS), | 273 ssl_ctx_(nullptr), |
| 282 custom_verification_succeeded_(false) { | 274 ssl_mode_(SSL_MODE_TLS), |
| 283 } | 275 custom_verification_succeeded_(false) {} |
| 284 | 276 |
| 285 OpenSSLAdapter::~OpenSSLAdapter() { | 277 OpenSSLAdapter::~OpenSSLAdapter() { |
| 286 Cleanup(); | 278 Cleanup(); |
| 287 } | 279 } |
| 288 | 280 |
| 289 void | 281 void |
| 290 OpenSSLAdapter::SetMode(SSLMode mode) { | 282 OpenSSLAdapter::SetMode(SSLMode mode) { |
| 291 RTC_DCHECK(state_ == SSL_NONE); | 283 RTC_DCHECK(state_ == SSL_NONE); |
| 292 ssl_mode_ = mode; | 284 ssl_mode_ = mode; |
| 293 } | 285 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 313 | 305 |
| 314 return 0; | 306 return 0; |
| 315 } | 307 } |
| 316 | 308 |
| 317 int | 309 int |
| 318 OpenSSLAdapter::BeginSSL() { | 310 OpenSSLAdapter::BeginSSL() { |
| 319 LOG(LS_INFO) << "BeginSSL: " << ssl_host_name_; | 311 LOG(LS_INFO) << "BeginSSL: " << ssl_host_name_; |
| 320 RTC_DCHECK(state_ == SSL_CONNECTING); | 312 RTC_DCHECK(state_ == SSL_CONNECTING); |
| 321 | 313 |
| 322 int err = 0; | 314 int err = 0; |
| 323 BIO* bio = NULL; | 315 BIO* bio = nullptr; |
| 324 | 316 |
| 325 // First set up the context | 317 // First set up the context |
| 326 if (!ssl_ctx_) | 318 if (!ssl_ctx_) |
| 327 ssl_ctx_ = SetupSSLContext(); | 319 ssl_ctx_ = SetupSSLContext(); |
| 328 | 320 |
| 329 if (!ssl_ctx_) { | 321 if (!ssl_ctx_) { |
| 330 err = -1; | 322 err = -1; |
| 331 goto ssl_error; | 323 goto ssl_error; |
| 332 } | 324 } |
| 333 | 325 |
| 334 bio = BIO_new_socket(socket_); | 326 bio = BIO_new_socket(socket_); |
| 335 if (!bio) { | 327 if (!bio) { |
| 336 err = -1; | 328 err = -1; |
| 337 goto ssl_error; | 329 goto ssl_error; |
| 338 } | 330 } |
| 339 | 331 |
| 340 ssl_ = SSL_new(ssl_ctx_); | 332 ssl_ = SSL_new(ssl_ctx_); |
| 341 if (!ssl_) { | 333 if (!ssl_) { |
| 342 err = -1; | 334 err = -1; |
| 343 goto ssl_error; | 335 goto ssl_error; |
| 344 } | 336 } |
| 345 | 337 |
| 346 SSL_set_app_data(ssl_, this); | 338 SSL_set_app_data(ssl_, this); |
| 347 | 339 |
| 348 SSL_set_bio(ssl_, bio, bio); | 340 SSL_set_bio(ssl_, bio, bio); |
| 349 SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE | | 341 SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE | |
| 350 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); | 342 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); |
| 351 | 343 |
| 352 // the SSL object owns the bio now | 344 // the SSL object owns the bio now |
| 353 bio = NULL; | 345 bio = nullptr; |
| 354 | 346 |
| 355 // Do the connect | 347 // Do the connect |
| 356 err = ContinueSSL(); | 348 err = ContinueSSL(); |
| 357 if (err != 0) | 349 if (err != 0) |
| 358 goto ssl_error; | 350 goto ssl_error; |
| 359 | 351 |
| 360 return err; | 352 return err; |
| 361 | 353 |
| 362 ssl_error: | 354 ssl_error: |
| 363 Cleanup(); | 355 Cleanup(); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 434 OpenSSLAdapter::Cleanup() { | 426 OpenSSLAdapter::Cleanup() { |
| 435 LOG(LS_INFO) << "Cleanup"; | 427 LOG(LS_INFO) << "Cleanup"; |
| 436 | 428 |
| 437 state_ = SSL_NONE; | 429 state_ = SSL_NONE; |
| 438 ssl_read_needs_write_ = false; | 430 ssl_read_needs_write_ = false; |
| 439 ssl_write_needs_read_ = false; | 431 ssl_write_needs_read_ = false; |
| 440 custom_verification_succeeded_ = false; | 432 custom_verification_succeeded_ = false; |
| 441 | 433 |
| 442 if (ssl_) { | 434 if (ssl_) { |
| 443 SSL_free(ssl_); | 435 SSL_free(ssl_); |
| 444 ssl_ = NULL; | 436 ssl_ = nullptr; |
| 445 } | 437 } |
| 446 | 438 |
| 447 if (ssl_ctx_) { | 439 if (ssl_ctx_) { |
| 448 SSL_CTX_free(ssl_ctx_); | 440 SSL_CTX_free(ssl_ctx_); |
| 449 ssl_ctx_ = NULL; | 441 ssl_ctx_ = nullptr; |
| 450 } | 442 } |
| 451 | 443 |
| 452 // Clear the DTLS timer | 444 // Clear the DTLS timer |
| 453 Thread::Current()->Clear(this, MSG_TIMEOUT); | 445 Thread::Current()->Clear(this, MSG_TIMEOUT); |
| 454 } | 446 } |
| 455 | 447 |
| 456 // | 448 // |
| 457 // AsyncSocket Implementation | 449 // AsyncSocket Implementation |
| 458 // | 450 // |
| 459 | 451 |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 707 // This code is taken from the "Network Security with OpenSSL" | 699 // This code is taken from the "Network Security with OpenSSL" |
| 708 // sample in chapter 5 | 700 // sample in chapter 5 |
| 709 | 701 |
| 710 bool OpenSSLAdapter::VerifyServerName(SSL* ssl, const char* host, | 702 bool OpenSSLAdapter::VerifyServerName(SSL* ssl, const char* host, |
| 711 bool ignore_bad_cert) { | 703 bool ignore_bad_cert) { |
| 712 if (!host) | 704 if (!host) |
| 713 return false; | 705 return false; |
| 714 | 706 |
| 715 // Checking the return from SSL_get_peer_certificate here is not strictly | 707 // Checking the return from SSL_get_peer_certificate here is not strictly |
| 716 // necessary. With our setup, it is not possible for it to return | 708 // necessary. With our setup, it is not possible for it to return |
| 717 // NULL. However, it is good form to check the return. | 709 // null. However, it is good form to check the return. |
| 718 X509* certificate = SSL_get_peer_certificate(ssl); | 710 X509* certificate = SSL_get_peer_certificate(ssl); |
| 719 if (!certificate) | 711 if (!certificate) |
| 720 return false; | 712 return false; |
| 721 | 713 |
| 722 // Logging certificates is extremely verbose. So it is disabled by default. | 714 // Logging certificates is extremely verbose. So it is disabled by default. |
| 723 #ifdef LOG_CERTIFICATES | 715 #ifdef LOG_CERTIFICATES |
| 724 { | 716 { |
| 725 LOG(LS_INFO) << "Certificate from server:"; | 717 LOG(LS_INFO) << "Certificate from server:"; |
| 726 BIO* mem = BIO_new(BIO_s_mem()); | 718 BIO* mem = BIO_new(BIO_s_mem()); |
| 727 X509_print_ex(mem, certificate, XN_FLAG_SEP_CPLUS_SPC, X509_FLAG_NO_HEADER); | 719 X509_print_ex(mem, certificate, XN_FLAG_SEP_CPLUS_SPC, X509_FLAG_NO_HEADER); |
| 728 BIO_write(mem, "\0", 1); | 720 BIO_write(mem, "\0", 1); |
| 729 char* buffer; | 721 char* buffer; |
| 730 BIO_get_mem_data(mem, &buffer); | 722 BIO_get_mem_data(mem, &buffer); |
| 731 LOG(LS_INFO) << buffer; | 723 LOG(LS_INFO) << buffer; |
| 732 BIO_free(mem); | 724 BIO_free(mem); |
| 733 | 725 |
| 734 char* cipher_description = | 726 char* cipher_description = |
| 735 SSL_CIPHER_description(SSL_get_current_cipher(ssl), NULL, 128); | 727 SSL_CIPHER_description(SSL_get_current_cipher(ssl), nullptr, 128); |
| 736 LOG(LS_INFO) << "Cipher: " << cipher_description; | 728 LOG(LS_INFO) << "Cipher: " << cipher_description; |
| 737 OPENSSL_free(cipher_description); | 729 OPENSSL_free(cipher_description); |
| 738 } | 730 } |
| 739 #endif | 731 #endif |
| 740 | 732 |
| 741 bool ok = false; | 733 bool ok = false; |
| 742 int extension_count = X509_get_ext_count(certificate); | 734 int extension_count = X509_get_ext_count(certificate); |
| 743 for (int i = 0; i < extension_count; ++i) { | 735 for (int i = 0; i < extension_count; ++i) { |
| 744 X509_EXTENSION* extension = X509_get_ext(certificate, i); | 736 X509_EXTENSION* extension = X509_get_ext(certificate, i); |
| 745 int extension_nid = OBJ_obj2nid(X509_EXTENSION_get_object(extension)); | 737 int extension_nid = OBJ_obj2nid(X509_EXTENSION_get_object(extension)); |
| 746 | 738 |
| 747 if (extension_nid == NID_subject_alt_name) { | 739 if (extension_nid == NID_subject_alt_name) { |
| 748 const X509V3_EXT_METHOD* meth = X509V3_EXT_get(extension); | 740 const X509V3_EXT_METHOD* meth = X509V3_EXT_get(extension); |
| 749 if (!meth) | 741 if (!meth) |
| 750 break; | 742 break; |
| 751 | 743 |
| 752 void* ext_str = NULL; | 744 void* ext_str = nullptr; |
| 753 | 745 |
| 754 // We assign this to a local variable, instead of passing the address | 746 // We assign this to a local variable, instead of passing the address |
| 755 // directly to ASN1_item_d2i. | 747 // directly to ASN1_item_d2i. |
| 756 // See http://readlist.com/lists/openssl.org/openssl-users/0/4761.html. | 748 // See http://readlist.com/lists/openssl.org/openssl-users/0/4761.html. |
| 757 unsigned char* ext_value_data = extension->value->data; | 749 unsigned char* ext_value_data = extension->value->data; |
| 758 | 750 |
| 759 const unsigned char **ext_value_data_ptr = | 751 const unsigned char **ext_value_data_ptr = |
| 760 (const_cast<const unsigned char **>(&ext_value_data)); | 752 (const_cast<const unsigned char **>(&ext_value_data)); |
| 761 | 753 |
| 762 if (meth->it) { | 754 if (meth->it) { |
| 763 ext_str = ASN1_item_d2i(NULL, ext_value_data_ptr, | 755 ext_str = |
| 764 extension->value->length, | 756 ASN1_item_d2i(nullptr, ext_value_data_ptr, extension->value->length, |
| 765 ASN1_ITEM_ptr(meth->it)); | 757 ASN1_ITEM_ptr(meth->it)); |
| 766 } else { | 758 } else { |
| 767 ext_str = meth->d2i(NULL, ext_value_data_ptr, extension->value->length); | 759 ext_str = |
| 760 meth->d2i(nullptr, ext_value_data_ptr, extension->value->length); |
| 768 } | 761 } |
| 769 | 762 |
| 770 STACK_OF(CONF_VALUE)* value = meth->i2v(meth, ext_str, NULL); | 763 STACK_OF(CONF_VALUE)* value = meth->i2v(meth, ext_str, nullptr); |
| 771 | 764 |
| 772 // Cast to size_t to be compilable for both OpenSSL and BoringSSL. | 765 // Cast to size_t to be compilable for both OpenSSL and BoringSSL. |
| 773 for (size_t j = 0; j < static_cast<size_t>(sk_CONF_VALUE_num(value)); | 766 for (size_t j = 0; j < static_cast<size_t>(sk_CONF_VALUE_num(value)); |
| 774 ++j) { | 767 ++j) { |
| 775 CONF_VALUE* nval = sk_CONF_VALUE_value(value, j); | 768 CONF_VALUE* nval = sk_CONF_VALUE_value(value, j); |
| 776 // The value for nval can contain wildcards | 769 // The value for nval can contain wildcards |
| 777 if (!strcmp(nval->name, "DNS") && string_match(host, nval->value)) { | 770 if (!strcmp(nval->name, "DNS") && string_match(host, nval->value)) { |
| 778 ok = true; | 771 ok = true; |
| 779 break; | 772 break; |
| 780 } | 773 } |
| 781 } | 774 } |
| 782 sk_CONF_VALUE_pop_free(value, X509V3_conf_free); | 775 sk_CONF_VALUE_pop_free(value, X509V3_conf_free); |
| 783 value = NULL; | 776 value = nullptr; |
| 784 | 777 |
| 785 if (meth->it) { | 778 if (meth->it) { |
| 786 ASN1_item_free(reinterpret_cast<ASN1_VALUE*>(ext_str), | 779 ASN1_item_free(reinterpret_cast<ASN1_VALUE*>(ext_str), |
| 787 ASN1_ITEM_ptr(meth->it)); | 780 ASN1_ITEM_ptr(meth->it)); |
| 788 } else { | 781 } else { |
| 789 meth->ext_free(ext_str); | 782 meth->ext_free(ext_str); |
| 790 } | 783 } |
| 791 ext_str = NULL; | 784 ext_str = nullptr; |
| 792 } | 785 } |
| 793 if (ok) | 786 if (ok) |
| 794 break; | 787 break; |
| 795 } | 788 } |
| 796 | 789 |
| 797 char data[256]; | 790 char data[256]; |
| 798 X509_NAME* subject; | 791 X509_NAME* subject; |
| 799 if (!ok | 792 if (!ok && ((subject = X509_get_subject_name(certificate)) != nullptr) && |
| 800 && ((subject = X509_get_subject_name(certificate)) != NULL) | 793 (X509_NAME_get_text_by_NID(subject, NID_commonName, data, sizeof(data)) > |
| 801 && (X509_NAME_get_text_by_NID(subject, NID_commonName, | 794 0)) { |
| 802 data, sizeof(data)) > 0)) { | |
| 803 data[sizeof(data)-1] = 0; | 795 data[sizeof(data)-1] = 0; |
| 804 if (_stricmp(data, host) == 0) | 796 if (_stricmp(data, host) == 0) |
| 805 ok = true; | 797 ok = true; |
| 806 } | 798 } |
| 807 | 799 |
| 808 X509_free(certificate); | 800 X509_free(certificate); |
| 809 | 801 |
| 810 // This should only ever be turned on for debugging and development. | 802 // This should only ever be turned on for debugging and development. |
| 811 if (!ok && ignore_bad_cert) { | 803 if (!ok && ignore_bad_cert) { |
| 812 LOG(LS_WARNING) << "TLS certificate check FAILED. " | 804 LOG(LS_WARNING) << "TLS certificate check FAILED. " |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 909 | 901 |
| 910 return ok; | 902 return ok; |
| 911 } | 903 } |
| 912 | 904 |
| 913 bool OpenSSLAdapter::ConfigureTrustedRootCertificates(SSL_CTX* ctx) { | 905 bool OpenSSLAdapter::ConfigureTrustedRootCertificates(SSL_CTX* ctx) { |
| 914 // Add the root cert that we care about to the SSL context | 906 // Add the root cert that we care about to the SSL context |
| 915 int count_of_added_certs = 0; | 907 int count_of_added_certs = 0; |
| 916 for (size_t i = 0; i < arraysize(kSSLCertCertificateList); i++) { | 908 for (size_t i = 0; i < arraysize(kSSLCertCertificateList); i++) { |
| 917 const unsigned char* cert_buffer = kSSLCertCertificateList[i]; | 909 const unsigned char* cert_buffer = kSSLCertCertificateList[i]; |
| 918 size_t cert_buffer_len = kSSLCertCertificateSizeList[i]; | 910 size_t cert_buffer_len = kSSLCertCertificateSizeList[i]; |
| 919 X509* cert = d2i_X509(NULL, &cert_buffer, | 911 X509* cert = |
| 920 checked_cast<long>(cert_buffer_len)); | 912 d2i_X509(nullptr, &cert_buffer, checked_cast<long>(cert_buffer_len)); |
| 921 if (cert) { | 913 if (cert) { |
| 922 int return_value = X509_STORE_add_cert(SSL_CTX_get_cert_store(ctx), cert); | 914 int return_value = X509_STORE_add_cert(SSL_CTX_get_cert_store(ctx), cert); |
| 923 if (return_value == 0) { | 915 if (return_value == 0) { |
| 924 LOG(LS_WARNING) << "Unable to add certificate."; | 916 LOG(LS_WARNING) << "Unable to add certificate."; |
| 925 } else { | 917 } else { |
| 926 count_of_added_certs++; | 918 count_of_added_certs++; |
| 927 } | 919 } |
| 928 X509_free(cert); | 920 X509_free(cert); |
| 929 } | 921 } |
| 930 } | 922 } |
| 931 return count_of_added_certs > 0; | 923 return count_of_added_certs > 0; |
| 932 } | 924 } |
| 933 | 925 |
| 934 SSL_CTX* | 926 SSL_CTX* |
| 935 OpenSSLAdapter::SetupSSLContext() { | 927 OpenSSLAdapter::SetupSSLContext() { |
| 936 SSL_CTX* ctx = SSL_CTX_new(ssl_mode_ == SSL_MODE_DTLS ? | 928 SSL_CTX* ctx = SSL_CTX_new(ssl_mode_ == SSL_MODE_DTLS ? |
| 937 DTLSv1_client_method() : TLSv1_client_method()); | 929 DTLSv1_client_method() : TLSv1_client_method()); |
| 938 if (ctx == NULL) { | 930 if (ctx == nullptr) { |
| 939 unsigned long error = ERR_get_error(); // NOLINT: type used by OpenSSL. | 931 unsigned long error = ERR_get_error(); // NOLINT: type used by OpenSSL. |
| 940 LOG(LS_WARNING) << "SSL_CTX creation failed: " | 932 LOG(LS_WARNING) << "SSL_CTX creation failed: " |
| 941 << '"' << ERR_reason_error_string(error) << "\" " | 933 << '"' << ERR_reason_error_string(error) << "\" " |
| 942 << "(error=" << error << ')'; | 934 << "(error=" << error << ')'; |
| 943 return NULL; | 935 return nullptr; |
| 944 } | 936 } |
| 945 if (!ConfigureTrustedRootCertificates(ctx)) { | 937 if (!ConfigureTrustedRootCertificates(ctx)) { |
| 946 SSL_CTX_free(ctx); | 938 SSL_CTX_free(ctx); |
| 947 return NULL; | 939 return nullptr; |
| 948 } | 940 } |
| 949 | 941 |
| 950 #if !defined(NDEBUG) | 942 #if !defined(NDEBUG) |
| 951 SSL_CTX_set_info_callback(ctx, SSLInfoCallback); | 943 SSL_CTX_set_info_callback(ctx, SSLInfoCallback); |
| 952 #endif | 944 #endif |
| 953 | 945 |
| 954 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, SSLVerifyCallback); | 946 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, SSLVerifyCallback); |
| 955 SSL_CTX_set_verify_depth(ctx, 4); | 947 SSL_CTX_set_verify_depth(ctx, 4); |
| 956 SSL_CTX_set_cipher_list(ctx, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); | 948 SSL_CTX_set_cipher_list(ctx, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); |
| 957 | 949 |
| 958 if (ssl_mode_ == SSL_MODE_DTLS) { | 950 if (ssl_mode_ == SSL_MODE_DTLS) { |
| 959 SSL_CTX_set_read_ahead(ctx, 1); | 951 SSL_CTX_set_read_ahead(ctx, 1); |
| 960 } | 952 } |
| 961 | 953 |
| 962 return ctx; | 954 return ctx; |
| 963 } | 955 } |
| 964 | 956 |
| 965 } // namespace rtc | 957 } // namespace rtc |
| OLD | NEW |