| 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 22 matching lines...) Expand all Loading... |
| 33 #include "webrtc/base/sslroots.h" | 33 #include "webrtc/base/sslroots.h" |
| 34 #include "webrtc/base/stringutils.h" | 34 #include "webrtc/base/stringutils.h" |
| 35 #include "webrtc/base/thread.h" | 35 #include "webrtc/base/thread.h" |
| 36 | 36 |
| 37 #ifndef OPENSSL_IS_BORINGSSL | 37 #ifndef OPENSSL_IS_BORINGSSL |
| 38 | 38 |
| 39 // TODO: Use a nicer abstraction for mutex. | 39 // TODO: Use a nicer abstraction for mutex. |
| 40 | 40 |
| 41 #if defined(WEBRTC_WIN) | 41 #if defined(WEBRTC_WIN) |
| 42 #define MUTEX_TYPE HANDLE | 42 #define MUTEX_TYPE HANDLE |
| 43 #define MUTEX_SETUP(x) (x) = CreateMutex(NULL, FALSE, NULL) | 43 #define MUTEX_SETUP(x) (x) = CreateMutex(nullptr, FALSE, nullptr) |
| 44 #define MUTEX_CLEANUP(x) CloseHandle(x) | 44 #define MUTEX_CLEANUP(x) CloseHandle(x) |
| 45 #define MUTEX_LOCK(x) WaitForSingleObject((x), INFINITE) | 45 #define MUTEX_LOCK(x) WaitForSingleObject((x), INFINITE) |
| 46 #define MUTEX_UNLOCK(x) ReleaseMutex(x) | 46 #define MUTEX_UNLOCK(x) ReleaseMutex(x) |
| 47 #define THREAD_ID GetCurrentThreadId() | 47 #define THREAD_ID GetCurrentThreadId() |
| 48 #elif defined(WEBRTC_POSIX) | 48 #elif defined(WEBRTC_POSIX) |
| 49 #define MUTEX_TYPE pthread_mutex_t | 49 #define MUTEX_TYPE pthread_mutex_t |
| 50 #define MUTEX_SETUP(x) pthread_mutex_init(&(x), NULL) | 50 #define MUTEX_SETUP(x) pthread_mutex_init(&(x), nullptr) |
| 51 #define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x)) | 51 #define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x)) |
| 52 #define MUTEX_LOCK(x) pthread_mutex_lock(&(x)) | 52 #define MUTEX_LOCK(x) pthread_mutex_lock(&(x)) |
| 53 #define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x)) | 53 #define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x)) |
| 54 #define THREAD_ID pthread_self() | 54 #define THREAD_ID pthread_self() |
| 55 #else | 55 #else |
| 56 #error You must define mutex operations appropriate for your platform! | 56 #error You must define mutex operations appropriate for your platform! |
| 57 #endif | 57 #endif |
| 58 | 58 |
| 59 struct CRYPTO_dynlock_value { | 59 struct CRYPTO_dynlock_value { |
| 60 MUTEX_TYPE mutex; | 60 MUTEX_TYPE mutex; |
| 61 }; | 61 }; |
| 62 | 62 |
| 63 #endif // #ifndef OPENSSL_IS_BORINGSSL | 63 #endif // #ifndef OPENSSL_IS_BORINGSSL |
| 64 | 64 |
| 65 ////////////////////////////////////////////////////////////////////// | 65 ////////////////////////////////////////////////////////////////////// |
| 66 // SocketBIO | 66 // SocketBIO |
| 67 ////////////////////////////////////////////////////////////////////// | 67 ////////////////////////////////////////////////////////////////////// |
| 68 | 68 |
| 69 static int socket_write(BIO* h, const char* buf, int num); | 69 static int socket_write(BIO* h, const char* buf, int num); |
| 70 static int socket_read(BIO* h, char* buf, int size); | 70 static int socket_read(BIO* h, char* buf, int size); |
| 71 static int socket_puts(BIO* h, const char* str); | 71 static int socket_puts(BIO* h, const char* str); |
| 72 static long socket_ctrl(BIO* h, int cmd, long arg1, void* arg2); | 72 static long socket_ctrl(BIO* h, int cmd, long arg1, void* arg2); |
| 73 static int socket_new(BIO* h); | 73 static int socket_new(BIO* h); |
| 74 static int socket_free(BIO* data); | 74 static int socket_free(BIO* data); |
| 75 | 75 |
| 76 // TODO(davidben): This should be const once BoringSSL is assumed. | 76 // TODO(davidben): This should be const once BoringSSL is assumed. |
| 77 static BIO_METHOD methods_socket = { | 77 static BIO_METHOD methods_socket = { |
| 78 BIO_TYPE_BIO, | 78 BIO_TYPE_BIO, "socket", socket_write, socket_read, socket_puts, 0, |
| 79 "socket", | 79 socket_ctrl, socket_new, socket_free, nullptr, |
| 80 socket_write, | |
| 81 socket_read, | |
| 82 socket_puts, | |
| 83 0, | |
| 84 socket_ctrl, | |
| 85 socket_new, | |
| 86 socket_free, | |
| 87 NULL, | |
| 88 }; | 80 }; |
| 89 | 81 |
| 90 static BIO_METHOD* BIO_s_socket2() { return(&methods_socket); } | 82 static BIO_METHOD* BIO_s_socket2() { return(&methods_socket); } |
| 91 | 83 |
| 92 static BIO* BIO_new_socket(rtc::AsyncSocket* socket) { | 84 static BIO* BIO_new_socket(rtc::AsyncSocket* socket) { |
| 93 BIO* ret = BIO_new(BIO_s_socket2()); | 85 BIO* ret = BIO_new(BIO_s_socket2()); |
| 94 if (ret == NULL) { | 86 if (ret == nullptr) { |
| 95 return NULL; | 87 return nullptr; |
| 96 } | 88 } |
| 97 ret->ptr = socket; | 89 ret->ptr = socket; |
| 98 return ret; | 90 return ret; |
| 99 } | 91 } |
| 100 | 92 |
| 101 static int socket_new(BIO* b) { | 93 static int socket_new(BIO* b) { |
| 102 b->shutdown = 0; | 94 b->shutdown = 0; |
| 103 b->init = 1; | 95 b->init = 1; |
| 104 b->num = 0; // 1 means socket closed | 96 b->num = 0; // 1 means socket closed |
| 105 b->ptr = 0; | 97 b->ptr = 0; |
| 106 return 1; | 98 return 1; |
| 107 } | 99 } |
| 108 | 100 |
| 109 static int socket_free(BIO* b) { | 101 static int socket_free(BIO* b) { |
| 110 if (b == NULL) | 102 if (b == nullptr) |
| 111 return 0; | 103 return 0; |
| 112 return 1; | 104 return 1; |
| 113 } | 105 } |
| 114 | 106 |
| 115 static int socket_read(BIO* b, char* out, int outl) { | 107 static int socket_read(BIO* b, char* out, int outl) { |
| 116 if (!out) | 108 if (!out) |
| 117 return -1; | 109 return -1; |
| 118 rtc::AsyncSocket* socket = static_cast<rtc::AsyncSocket*>(b->ptr); | 110 rtc::AsyncSocket* socket = static_cast<rtc::AsyncSocket*>(b->ptr); |
| 119 BIO_clear_retry_flags(b); | 111 BIO_clear_retry_flags(b); |
| 120 int result = socket->Recv(out, outl, nullptr); | 112 int result = socket->Recv(out, outl, nullptr); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 | 156 |
| 165 ///////////////////////////////////////////////////////////////////////////// | 157 ///////////////////////////////////////////////////////////////////////////// |
| 166 // OpenSSLAdapter | 158 // OpenSSLAdapter |
| 167 ///////////////////////////////////////////////////////////////////////////// | 159 ///////////////////////////////////////////////////////////////////////////// |
| 168 | 160 |
| 169 namespace rtc { | 161 namespace rtc { |
| 170 | 162 |
| 171 #ifndef OPENSSL_IS_BORINGSSL | 163 #ifndef OPENSSL_IS_BORINGSSL |
| 172 | 164 |
| 173 // This array will store all of the mutexes available to OpenSSL. | 165 // This array will store all of the mutexes available to OpenSSL. |
| 174 static MUTEX_TYPE* mutex_buf = NULL; | 166 static MUTEX_TYPE* mutex_buf = nullptr; |
| 175 | 167 |
| 176 static void locking_function(int mode, int n, const char * file, int line) { | 168 static void locking_function(int mode, int n, const char * file, int line) { |
| 177 if (mode & CRYPTO_LOCK) { | 169 if (mode & CRYPTO_LOCK) { |
| 178 MUTEX_LOCK(mutex_buf[n]); | 170 MUTEX_LOCK(mutex_buf[n]); |
| 179 } else { | 171 } else { |
| 180 MUTEX_UNLOCK(mutex_buf[n]); | 172 MUTEX_UNLOCK(mutex_buf[n]); |
| 181 } | 173 } |
| 182 } | 174 } |
| 183 | 175 |
| 184 static unsigned long id_function() { // NOLINT | 176 static unsigned long id_function() { // NOLINT |
| 185 // Use old-style C cast because THREAD_ID's type varies with the platform, | 177 // Use old-style C cast because THREAD_ID's type varies with the platform, |
| 186 // in some cases requiring static_cast, and in others requiring | 178 // in some cases requiring static_cast, and in others requiring |
| 187 // reinterpret_cast. | 179 // reinterpret_cast. |
| 188 return (unsigned long)THREAD_ID; // NOLINT | 180 return (unsigned long)THREAD_ID; // NOLINT |
| 189 } | 181 } |
| 190 | 182 |
| 191 static CRYPTO_dynlock_value* dyn_create_function(const char* file, int line) { | 183 static CRYPTO_dynlock_value* dyn_create_function(const char* file, int line) { |
| 192 CRYPTO_dynlock_value* value = new CRYPTO_dynlock_value; | 184 CRYPTO_dynlock_value* value = new CRYPTO_dynlock_value; |
| 193 if (!value) | 185 if (!value) |
| 194 return NULL; | 186 return nullptr; |
| 195 MUTEX_SETUP(value->mutex); | 187 MUTEX_SETUP(value->mutex); |
| 196 return value; | 188 return value; |
| 197 } | 189 } |
| 198 | 190 |
| 199 static void dyn_lock_function(int mode, CRYPTO_dynlock_value* l, | 191 static void dyn_lock_function(int mode, CRYPTO_dynlock_value* l, |
| 200 const char* file, int line) { | 192 const char* file, int line) { |
| 201 if (mode & CRYPTO_LOCK) { | 193 if (mode & CRYPTO_LOCK) { |
| 202 MUTEX_LOCK(l->mutex); | 194 MUTEX_LOCK(l->mutex); |
| 203 } else { | 195 } else { |
| 204 MUTEX_UNLOCK(l->mutex); | 196 MUTEX_UNLOCK(l->mutex); |
| 205 } | 197 } |
| 206 } | 198 } |
| 207 | 199 |
| 208 static void dyn_destroy_function(CRYPTO_dynlock_value* l, | 200 static void dyn_destroy_function(CRYPTO_dynlock_value* l, |
| 209 const char* file, int line) { | 201 const char* file, int line) { |
| 210 MUTEX_CLEANUP(l->mutex); | 202 MUTEX_CLEANUP(l->mutex); |
| 211 delete l; | 203 delete l; |
| 212 } | 204 } |
| 213 | 205 |
| 214 #endif // #ifndef OPENSSL_IS_BORINGSSL | 206 #endif // #ifndef OPENSSL_IS_BORINGSSL |
| 215 | 207 |
| 216 VerificationCallback OpenSSLAdapter::custom_verify_callback_ = NULL; | 208 VerificationCallback OpenSSLAdapter::custom_verify_callback_ = nullptr; |
| 217 | 209 |
| 218 bool OpenSSLAdapter::InitializeSSL(VerificationCallback callback) { | 210 bool OpenSSLAdapter::InitializeSSL(VerificationCallback callback) { |
| 219 if (!InitializeSSLThread() || !SSL_library_init()) | 211 if (!InitializeSSLThread() || !SSL_library_init()) |
| 220 return false; | 212 return false; |
| 221 #if !defined(ADDRESS_SANITIZER) || !defined(WEBRTC_MAC) || defined(WEBRTC_IOS) | 213 #if !defined(ADDRESS_SANITIZER) || !defined(WEBRTC_MAC) || defined(WEBRTC_IOS) |
| 222 // Loading the error strings crashes mac_asan. Omit this debugging aid there. | 214 // Loading the error strings crashes mac_asan. Omit this debugging aid there. |
| 223 SSL_load_error_strings(); | 215 SSL_load_error_strings(); |
| 224 #endif | 216 #endif |
| 225 ERR_load_BIO_strings(); | 217 ERR_load_BIO_strings(); |
| 226 OpenSSL_add_all_algorithms(); | 218 OpenSSL_add_all_algorithms(); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 247 CRYPTO_set_dynlock_lock_callback(dyn_lock_function); | 239 CRYPTO_set_dynlock_lock_callback(dyn_lock_function); |
| 248 CRYPTO_set_dynlock_destroy_callback(dyn_destroy_function); | 240 CRYPTO_set_dynlock_destroy_callback(dyn_destroy_function); |
| 249 #endif // #ifndef OPENSSL_IS_BORINGSSL | 241 #endif // #ifndef OPENSSL_IS_BORINGSSL |
| 250 return true; | 242 return true; |
| 251 } | 243 } |
| 252 | 244 |
| 253 bool OpenSSLAdapter::CleanupSSL() { | 245 bool OpenSSLAdapter::CleanupSSL() { |
| 254 #ifndef OPENSSL_IS_BORINGSSL | 246 #ifndef OPENSSL_IS_BORINGSSL |
| 255 if (!mutex_buf) | 247 if (!mutex_buf) |
| 256 return false; | 248 return false; |
| 257 CRYPTO_set_id_callback(NULL); | 249 CRYPTO_set_id_callback(nullptr); |
| 258 CRYPTO_set_locking_callback(NULL); | 250 CRYPTO_set_locking_callback(nullptr); |
| 259 CRYPTO_set_dynlock_create_callback(NULL); | 251 CRYPTO_set_dynlock_create_callback(nullptr); |
| 260 CRYPTO_set_dynlock_lock_callback(NULL); | 252 CRYPTO_set_dynlock_lock_callback(nullptr); |
| 261 CRYPTO_set_dynlock_destroy_callback(NULL); | 253 CRYPTO_set_dynlock_destroy_callback(nullptr); |
| 262 for (int i = 0; i < CRYPTO_num_locks(); ++i) | 254 for (int i = 0; i < CRYPTO_num_locks(); ++i) |
| 263 MUTEX_CLEANUP(mutex_buf[i]); | 255 MUTEX_CLEANUP(mutex_buf[i]); |
| 264 delete [] mutex_buf; | 256 delete [] mutex_buf; |
| 265 mutex_buf = NULL; | 257 mutex_buf = nullptr; |
| 266 #endif // #ifndef OPENSSL_IS_BORINGSSL | 258 #endif // #ifndef OPENSSL_IS_BORINGSSL |
| 267 return true; | 259 return true; |
| 268 } | 260 } |
| 269 | 261 |
| 270 OpenSSLAdapter::OpenSSLAdapter(AsyncSocket* socket) | 262 OpenSSLAdapter::OpenSSLAdapter(AsyncSocket* socket) |
| 271 : SSLAdapter(socket), | 263 : SSLAdapter(socket), |
| 272 state_(SSL_NONE), | 264 state_(SSL_NONE), |
| 273 ssl_read_needs_write_(false), | 265 ssl_read_needs_write_(false), |
| 274 ssl_write_needs_read_(false), | 266 ssl_write_needs_read_(false), |
| 275 restartable_(false), | 267 restartable_(false), |
| 276 ssl_(NULL), ssl_ctx_(NULL), | 268 ssl_(nullptr), |
| 277 ssl_mode_(SSL_MODE_TLS), | 269 ssl_ctx_(nullptr), |
| 278 custom_verification_succeeded_(false) { | 270 ssl_mode_(SSL_MODE_TLS), |
| 279 } | 271 custom_verification_succeeded_(false) {} |
| 280 | 272 |
| 281 OpenSSLAdapter::~OpenSSLAdapter() { | 273 OpenSSLAdapter::~OpenSSLAdapter() { |
| 282 Cleanup(); | 274 Cleanup(); |
| 283 } | 275 } |
| 284 | 276 |
| 285 void | 277 void |
| 286 OpenSSLAdapter::SetMode(SSLMode mode) { | 278 OpenSSLAdapter::SetMode(SSLMode mode) { |
| 287 RTC_DCHECK(state_ == SSL_NONE); | 279 RTC_DCHECK(state_ == SSL_NONE); |
| 288 ssl_mode_ = mode; | 280 ssl_mode_ = mode; |
| 289 } | 281 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 309 | 301 |
| 310 return 0; | 302 return 0; |
| 311 } | 303 } |
| 312 | 304 |
| 313 int | 305 int |
| 314 OpenSSLAdapter::BeginSSL() { | 306 OpenSSLAdapter::BeginSSL() { |
| 315 LOG(LS_INFO) << "BeginSSL: " << ssl_host_name_; | 307 LOG(LS_INFO) << "BeginSSL: " << ssl_host_name_; |
| 316 RTC_DCHECK(state_ == SSL_CONNECTING); | 308 RTC_DCHECK(state_ == SSL_CONNECTING); |
| 317 | 309 |
| 318 int err = 0; | 310 int err = 0; |
| 319 BIO* bio = NULL; | 311 BIO* bio = nullptr; |
| 320 | 312 |
| 321 // First set up the context | 313 // First set up the context |
| 322 if (!ssl_ctx_) | 314 if (!ssl_ctx_) |
| 323 ssl_ctx_ = SetupSSLContext(); | 315 ssl_ctx_ = SetupSSLContext(); |
| 324 | 316 |
| 325 if (!ssl_ctx_) { | 317 if (!ssl_ctx_) { |
| 326 err = -1; | 318 err = -1; |
| 327 goto ssl_error; | 319 goto ssl_error; |
| 328 } | 320 } |
| 329 | 321 |
| 330 bio = BIO_new_socket(socket_); | 322 bio = BIO_new_socket(socket_); |
| 331 if (!bio) { | 323 if (!bio) { |
| 332 err = -1; | 324 err = -1; |
| 333 goto ssl_error; | 325 goto ssl_error; |
| 334 } | 326 } |
| 335 | 327 |
| 336 ssl_ = SSL_new(ssl_ctx_); | 328 ssl_ = SSL_new(ssl_ctx_); |
| 337 if (!ssl_) { | 329 if (!ssl_) { |
| 338 err = -1; | 330 err = -1; |
| 339 goto ssl_error; | 331 goto ssl_error; |
| 340 } | 332 } |
| 341 | 333 |
| 342 SSL_set_app_data(ssl_, this); | 334 SSL_set_app_data(ssl_, this); |
| 343 | 335 |
| 344 SSL_set_bio(ssl_, bio, bio); | 336 SSL_set_bio(ssl_, bio, bio); |
| 345 SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE | | 337 SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE | |
| 346 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); | 338 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); |
| 347 | 339 |
| 348 // the SSL object owns the bio now | 340 // the SSL object owns the bio now |
| 349 bio = NULL; | 341 bio = nullptr; |
| 350 | 342 |
| 351 // Do the connect | 343 // Do the connect |
| 352 err = ContinueSSL(); | 344 err = ContinueSSL(); |
| 353 if (err != 0) | 345 if (err != 0) |
| 354 goto ssl_error; | 346 goto ssl_error; |
| 355 | 347 |
| 356 return err; | 348 return err; |
| 357 | 349 |
| 358 ssl_error: | 350 ssl_error: |
| 359 Cleanup(); | 351 Cleanup(); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 430 OpenSSLAdapter::Cleanup() { | 422 OpenSSLAdapter::Cleanup() { |
| 431 LOG(LS_INFO) << "Cleanup"; | 423 LOG(LS_INFO) << "Cleanup"; |
| 432 | 424 |
| 433 state_ = SSL_NONE; | 425 state_ = SSL_NONE; |
| 434 ssl_read_needs_write_ = false; | 426 ssl_read_needs_write_ = false; |
| 435 ssl_write_needs_read_ = false; | 427 ssl_write_needs_read_ = false; |
| 436 custom_verification_succeeded_ = false; | 428 custom_verification_succeeded_ = false; |
| 437 | 429 |
| 438 if (ssl_) { | 430 if (ssl_) { |
| 439 SSL_free(ssl_); | 431 SSL_free(ssl_); |
| 440 ssl_ = NULL; | 432 ssl_ = nullptr; |
| 441 } | 433 } |
| 442 | 434 |
| 443 if (ssl_ctx_) { | 435 if (ssl_ctx_) { |
| 444 SSL_CTX_free(ssl_ctx_); | 436 SSL_CTX_free(ssl_ctx_); |
| 445 ssl_ctx_ = NULL; | 437 ssl_ctx_ = nullptr; |
| 446 } | 438 } |
| 447 | 439 |
| 448 // Clear the DTLS timer | 440 // Clear the DTLS timer |
| 449 Thread::Current()->Clear(this, MSG_TIMEOUT); | 441 Thread::Current()->Clear(this, MSG_TIMEOUT); |
| 450 } | 442 } |
| 451 | 443 |
| 452 // | 444 // |
| 453 // AsyncSocket Implementation | 445 // AsyncSocket Implementation |
| 454 // | 446 // |
| 455 | 447 |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 700 AsyncSocketAdapter::OnCloseEvent(socket, err); | 692 AsyncSocketAdapter::OnCloseEvent(socket, err); |
| 701 } | 693 } |
| 702 | 694 |
| 703 bool OpenSSLAdapter::VerifyServerName(SSL* ssl, const char* host, | 695 bool OpenSSLAdapter::VerifyServerName(SSL* ssl, const char* host, |
| 704 bool ignore_bad_cert) { | 696 bool ignore_bad_cert) { |
| 705 if (!host) | 697 if (!host) |
| 706 return false; | 698 return false; |
| 707 | 699 |
| 708 // Checking the return from SSL_get_peer_certificate here is not strictly | 700 // Checking the return from SSL_get_peer_certificate here is not strictly |
| 709 // necessary. With our setup, it is not possible for it to return | 701 // necessary. With our setup, it is not possible for it to return |
| 710 // NULL. However, it is good form to check the return. | 702 // null. However, it is good form to check the return. |
| 711 X509* certificate = SSL_get_peer_certificate(ssl); | 703 X509* certificate = SSL_get_peer_certificate(ssl); |
| 712 if (!certificate) | 704 if (!certificate) |
| 713 return false; | 705 return false; |
| 714 | 706 |
| 715 // Logging certificates is extremely verbose. So it is disabled by default. | 707 // Logging certificates is extremely verbose. So it is disabled by default. |
| 716 #ifdef LOG_CERTIFICATES | 708 #ifdef LOG_CERTIFICATES |
| 717 { | 709 { |
| 718 LOG(LS_INFO) << "Certificate from server:"; | 710 LOG(LS_INFO) << "Certificate from server:"; |
| 719 BIO* mem = BIO_new(BIO_s_mem()); | 711 BIO* mem = BIO_new(BIO_s_mem()); |
| 720 X509_print_ex(mem, certificate, XN_FLAG_SEP_CPLUS_SPC, X509_FLAG_NO_HEADER); | 712 X509_print_ex(mem, certificate, XN_FLAG_SEP_CPLUS_SPC, X509_FLAG_NO_HEADER); |
| 721 BIO_write(mem, "\0", 1); | 713 BIO_write(mem, "\0", 1); |
| 722 char* buffer; | 714 char* buffer; |
| 723 BIO_get_mem_data(mem, &buffer); | 715 BIO_get_mem_data(mem, &buffer); |
| 724 LOG(LS_INFO) << buffer; | 716 LOG(LS_INFO) << buffer; |
| 725 BIO_free(mem); | 717 BIO_free(mem); |
| 726 | 718 |
| 727 char* cipher_description = | 719 char* cipher_description = |
| 728 SSL_CIPHER_description(SSL_get_current_cipher(ssl), NULL, 128); | 720 SSL_CIPHER_description(SSL_get_current_cipher(ssl), nullptr, 128); |
| 729 LOG(LS_INFO) << "Cipher: " << cipher_description; | 721 LOG(LS_INFO) << "Cipher: " << cipher_description; |
| 730 OPENSSL_free(cipher_description); | 722 OPENSSL_free(cipher_description); |
| 731 } | 723 } |
| 732 #endif | 724 #endif |
| 733 | 725 |
| 734 bool ok = false; | 726 bool ok = false; |
| 735 GENERAL_NAMES* names = reinterpret_cast<GENERAL_NAMES*>( | 727 GENERAL_NAMES* names = reinterpret_cast<GENERAL_NAMES*>( |
| 736 X509_get_ext_d2i(certificate, NID_subject_alt_name, nullptr, nullptr)); | 728 X509_get_ext_d2i(certificate, NID_subject_alt_name, nullptr, nullptr)); |
| 737 if (names) { | 729 if (names) { |
| 738 for (size_t i = 0; i < sk_GENERAL_NAME_num(names); i++) { | 730 for (size_t i = 0; i < sk_GENERAL_NAME_num(names); i++) { |
| 739 const GENERAL_NAME* name = sk_GENERAL_NAME_value(names, i); | 731 const GENERAL_NAME* name = sk_GENERAL_NAME_value(names, i); |
| 740 if (name->type != GEN_DNS) | 732 if (name->type != GEN_DNS) |
| 741 continue; | 733 continue; |
| 742 std::string value( | 734 std::string value( |
| 743 reinterpret_cast<const char*>(ASN1_STRING_data(name->d.dNSName)), | 735 reinterpret_cast<const char*>(ASN1_STRING_data(name->d.dNSName)), |
| 744 ASN1_STRING_length(name->d.dNSName)); | 736 ASN1_STRING_length(name->d.dNSName)); |
| 745 // string_match takes NUL-terminated strings, so check for embedded NULs. | 737 // string_match takes NUL-terminated strings, so check for embedded NULs. |
| 746 if (value.find('\0') != std::string::npos) | 738 if (value.find('\0') != std::string::npos) |
| 747 continue; | 739 continue; |
| 748 if (string_match(host, value.c_str())) { | 740 if (string_match(host, value.c_str())) { |
| 749 ok = true; | 741 ok = true; |
| 750 break; | 742 break; |
| 751 } | 743 } |
| 752 } | 744 } |
| 753 GENERAL_NAMES_free(names); | 745 GENERAL_NAMES_free(names); |
| 754 } | 746 } |
| 755 | 747 |
| 756 char data[256]; | 748 char data[256]; |
| 757 X509_NAME* subject; | 749 X509_NAME* subject; |
| 758 if (!ok | 750 if (!ok && ((subject = X509_get_subject_name(certificate)) != nullptr) && |
| 759 && ((subject = X509_get_subject_name(certificate)) != NULL) | 751 (X509_NAME_get_text_by_NID(subject, NID_commonName, data, sizeof(data)) > |
| 760 && (X509_NAME_get_text_by_NID(subject, NID_commonName, | 752 0)) { |
| 761 data, sizeof(data)) > 0)) { | |
| 762 data[sizeof(data)-1] = 0; | 753 data[sizeof(data)-1] = 0; |
| 763 if (_stricmp(data, host) == 0) | 754 if (_stricmp(data, host) == 0) |
| 764 ok = true; | 755 ok = true; |
| 765 } | 756 } |
| 766 | 757 |
| 767 X509_free(certificate); | 758 X509_free(certificate); |
| 768 | 759 |
| 769 // This should only ever be turned on for debugging and development. | 760 // This should only ever be turned on for debugging and development. |
| 770 if (!ok && ignore_bad_cert) { | 761 if (!ok && ignore_bad_cert) { |
| 771 LOG(LS_WARNING) << "TLS certificate check FAILED. " | 762 LOG(LS_WARNING) << "TLS certificate check FAILED. " |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 868 | 859 |
| 869 return ok; | 860 return ok; |
| 870 } | 861 } |
| 871 | 862 |
| 872 bool OpenSSLAdapter::ConfigureTrustedRootCertificates(SSL_CTX* ctx) { | 863 bool OpenSSLAdapter::ConfigureTrustedRootCertificates(SSL_CTX* ctx) { |
| 873 // Add the root cert that we care about to the SSL context | 864 // Add the root cert that we care about to the SSL context |
| 874 int count_of_added_certs = 0; | 865 int count_of_added_certs = 0; |
| 875 for (size_t i = 0; i < arraysize(kSSLCertCertificateList); i++) { | 866 for (size_t i = 0; i < arraysize(kSSLCertCertificateList); i++) { |
| 876 const unsigned char* cert_buffer = kSSLCertCertificateList[i]; | 867 const unsigned char* cert_buffer = kSSLCertCertificateList[i]; |
| 877 size_t cert_buffer_len = kSSLCertCertificateSizeList[i]; | 868 size_t cert_buffer_len = kSSLCertCertificateSizeList[i]; |
| 878 X509* cert = d2i_X509(NULL, &cert_buffer, | 869 X509* cert = |
| 879 checked_cast<long>(cert_buffer_len)); | 870 d2i_X509(nullptr, &cert_buffer, checked_cast<long>(cert_buffer_len)); |
| 880 if (cert) { | 871 if (cert) { |
| 881 int return_value = X509_STORE_add_cert(SSL_CTX_get_cert_store(ctx), cert); | 872 int return_value = X509_STORE_add_cert(SSL_CTX_get_cert_store(ctx), cert); |
| 882 if (return_value == 0) { | 873 if (return_value == 0) { |
| 883 LOG(LS_WARNING) << "Unable to add certificate."; | 874 LOG(LS_WARNING) << "Unable to add certificate."; |
| 884 } else { | 875 } else { |
| 885 count_of_added_certs++; | 876 count_of_added_certs++; |
| 886 } | 877 } |
| 887 X509_free(cert); | 878 X509_free(cert); |
| 888 } | 879 } |
| 889 } | 880 } |
| 890 return count_of_added_certs > 0; | 881 return count_of_added_certs > 0; |
| 891 } | 882 } |
| 892 | 883 |
| 893 SSL_CTX* | 884 SSL_CTX* |
| 894 OpenSSLAdapter::SetupSSLContext() { | 885 OpenSSLAdapter::SetupSSLContext() { |
| 895 SSL_CTX* ctx = SSL_CTX_new(ssl_mode_ == SSL_MODE_DTLS ? | 886 SSL_CTX* ctx = SSL_CTX_new(ssl_mode_ == SSL_MODE_DTLS ? |
| 896 DTLSv1_client_method() : TLSv1_client_method()); | 887 DTLSv1_client_method() : TLSv1_client_method()); |
| 897 if (ctx == NULL) { | 888 if (ctx == nullptr) { |
| 898 unsigned long error = ERR_get_error(); // NOLINT: type used by OpenSSL. | 889 unsigned long error = ERR_get_error(); // NOLINT: type used by OpenSSL. |
| 899 LOG(LS_WARNING) << "SSL_CTX creation failed: " | 890 LOG(LS_WARNING) << "SSL_CTX creation failed: " |
| 900 << '"' << ERR_reason_error_string(error) << "\" " | 891 << '"' << ERR_reason_error_string(error) << "\" " |
| 901 << "(error=" << error << ')'; | 892 << "(error=" << error << ')'; |
| 902 return NULL; | 893 return nullptr; |
| 903 } | 894 } |
| 904 if (!ConfigureTrustedRootCertificates(ctx)) { | 895 if (!ConfigureTrustedRootCertificates(ctx)) { |
| 905 SSL_CTX_free(ctx); | 896 SSL_CTX_free(ctx); |
| 906 return NULL; | 897 return nullptr; |
| 907 } | 898 } |
| 908 | 899 |
| 909 #if !defined(NDEBUG) | 900 #if !defined(NDEBUG) |
| 910 SSL_CTX_set_info_callback(ctx, SSLInfoCallback); | 901 SSL_CTX_set_info_callback(ctx, SSLInfoCallback); |
| 911 #endif | 902 #endif |
| 912 | 903 |
| 913 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, SSLVerifyCallback); | 904 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, SSLVerifyCallback); |
| 914 SSL_CTX_set_verify_depth(ctx, 4); | 905 SSL_CTX_set_verify_depth(ctx, 4); |
| 915 SSL_CTX_set_cipher_list(ctx, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); | 906 SSL_CTX_set_cipher_list(ctx, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); |
| 916 | 907 |
| 917 if (ssl_mode_ == SSL_MODE_DTLS) { | 908 if (ssl_mode_ == SSL_MODE_DTLS) { |
| 918 SSL_CTX_set_read_ahead(ctx, 1); | 909 SSL_CTX_set_read_ahead(ctx, 1); |
| 919 } | 910 } |
| 920 | 911 |
| 921 return ctx; | 912 return ctx; |
| 922 } | 913 } |
| 923 | 914 |
| 924 } // namespace rtc | 915 } // namespace rtc |
| OLD | NEW |