147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org/* 247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * Copyright 2008 The WebRTC Project Authors. All rights reserved. 347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * 447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * Use of this source code is governed by a BSD-style license 547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * that can be found in the LICENSE file in the root of the source 647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * tree. An additional intellectual property rights grant can be found 747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * in the file PATENTS. All contributing project authors may 847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * be found in the AUTHORS file in the root of the source tree. 947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org */ 1047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 1147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if HAVE_OPENSSL_SSL_H 1247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 1347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/openssladapter.h" 1447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 1547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_POSIX) 1647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <unistd.h> 1747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif 1847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 1947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Must be included first before openssl headers. 2047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/win32.h" // NOLINT 2147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 2247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <openssl/bio.h> 2347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <openssl/crypto.h> 2447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <openssl/err.h> 2547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <openssl/opensslv.h> 2647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <openssl/rand.h> 27222d84ad848886a7123d3ad47c4daf188ecac574henrike@webrtc.org#include <openssl/x509.h> 2847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <openssl/x509v3.h> 2947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 3047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if HAVE_CONFIG_H 3147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "config.h" 3247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif // HAVE_CONFIG_H 3347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 3447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/common.h" 3547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/logging.h" 3647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/openssl.h" 3747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/sslroots.h" 3847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/stringutils.h" 3947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 4047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// TODO: Use a nicer abstraction for mutex. 4147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 4247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN) 4347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org #define MUTEX_TYPE HANDLE 4447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org #define MUTEX_SETUP(x) (x) = CreateMutex(NULL, FALSE, NULL) 4547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org #define MUTEX_CLEANUP(x) CloseHandle(x) 4647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org #define MUTEX_LOCK(x) WaitForSingleObject((x), INFINITE) 4747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org #define MUTEX_UNLOCK(x) ReleaseMutex(x) 4847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org #define THREAD_ID GetCurrentThreadId() 4947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#elif defined(WEBRTC_POSIX) 5047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org #define MUTEX_TYPE pthread_mutex_t 5147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org #define MUTEX_SETUP(x) pthread_mutex_init(&(x), NULL) 5247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org #define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x)) 5347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org #define MUTEX_LOCK(x) pthread_mutex_lock(&(x)) 5447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org #define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x)) 5547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org #define THREAD_ID pthread_self() 5647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#else 5747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org #error You must define mutex operations appropriate for your platform! 5847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif 5947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 6047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstruct CRYPTO_dynlock_value { 6147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org MUTEX_TYPE mutex; 6247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}; 6347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 6447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org////////////////////////////////////////////////////////////////////// 6547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// SocketBIO 6647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org////////////////////////////////////////////////////////////////////// 6747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 6847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic int socket_write(BIO* h, const char* buf, int num); 6947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic int socket_read(BIO* h, char* buf, int size); 7047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic int socket_puts(BIO* h, const char* str); 7147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic long socket_ctrl(BIO* h, int cmd, long arg1, void* arg2); 7247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic int socket_new(BIO* h); 7347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic int socket_free(BIO* data); 7447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 7547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic BIO_METHOD methods_socket = { 7647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org BIO_TYPE_BIO, 7747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org "socket", 7847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org socket_write, 7947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org socket_read, 8047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org socket_puts, 8147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 0, 8247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org socket_ctrl, 8347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org socket_new, 8447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org socket_free, 8547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org NULL, 8647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}; 8747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 88b2eea5cf51211d6d4fd735380705f9626a1ebff9henrike@webrtc.orgstatic BIO_METHOD* BIO_s_socket2() { return(&methods_socket); } 8947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 90b2eea5cf51211d6d4fd735380705f9626a1ebff9henrike@webrtc.orgstatic BIO* BIO_new_socket(rtc::AsyncSocket* socket) { 9147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org BIO* ret = BIO_new(BIO_s_socket2()); 9247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (ret == NULL) { 9347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return NULL; 9447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 9547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ret->ptr = socket; 9647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return ret; 9747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 9847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 9947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic int socket_new(BIO* b) { 10047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org b->shutdown = 0; 10147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org b->init = 1; 10247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org b->num = 0; // 1 means socket closed 10347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org b->ptr = 0; 10447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return 1; 10547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 10647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 10747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic int socket_free(BIO* b) { 10847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (b == NULL) 10947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return 0; 11047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return 1; 11147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 11247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 11347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic int socket_read(BIO* b, char* out, int outl) { 11447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!out) 11547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return -1; 11647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org rtc::AsyncSocket* socket = static_cast<rtc::AsyncSocket*>(b->ptr); 11747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org BIO_clear_retry_flags(b); 11847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int result = socket->Recv(out, outl); 11947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (result > 0) { 12047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return result; 12147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else if (result == 0) { 12247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org b->num = 1; 12347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else if (socket->IsBlocking()) { 12447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org BIO_set_retry_read(b); 12547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 12647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return -1; 12747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 12847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 12947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic int socket_write(BIO* b, const char* in, int inl) { 13047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!in) 13147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return -1; 13247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org rtc::AsyncSocket* socket = static_cast<rtc::AsyncSocket*>(b->ptr); 13347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org BIO_clear_retry_flags(b); 13447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int result = socket->Send(in, inl); 13547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (result > 0) { 13647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return result; 13747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else if (socket->IsBlocking()) { 13847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org BIO_set_retry_write(b); 13947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 14047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return -1; 14147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 14247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 14347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic int socket_puts(BIO* b, const char* str) { 14447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return socket_write(b, str, strlen(str)); 14547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 14647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 14747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic long socket_ctrl(BIO* b, int cmd, long num, void* ptr) { 1485199d1ddc1a2d8bb9feeadc5bc684f8a1fd6b76bhenrike@webrtc.org RTC_UNUSED(num); 1495199d1ddc1a2d8bb9feeadc5bc684f8a1fd6b76bhenrike@webrtc.org RTC_UNUSED(ptr); 15047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 15147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org switch (cmd) { 15247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org case BIO_CTRL_RESET: 15347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return 0; 15447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org case BIO_CTRL_EOF: 15547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return b->num; 15647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org case BIO_CTRL_WPENDING: 15747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org case BIO_CTRL_PENDING: 15847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return 0; 15947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org case BIO_CTRL_FLUSH: 16047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return 1; 16147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org default: 16247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return 0; 16347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 16447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 16547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 16647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////// 16747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// OpenSSLAdapter 16847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////// 16947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 17047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgnamespace rtc { 17147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 17247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// This array will store all of the mutexes available to OpenSSL. 17347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic MUTEX_TYPE* mutex_buf = NULL; 17447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 17547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic void locking_function(int mode, int n, const char * file, int line) { 17647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (mode & CRYPTO_LOCK) { 17747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org MUTEX_LOCK(mutex_buf[n]); 17847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else { 17947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org MUTEX_UNLOCK(mutex_buf[n]); 18047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 18147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 18247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 18347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic unsigned long id_function() { // NOLINT 18447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Use old-style C cast because THREAD_ID's type varies with the platform, 18547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // in some cases requiring static_cast, and in others requiring 18647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // reinterpret_cast. 18747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return (unsigned long)THREAD_ID; // NOLINT 18847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 18947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 19047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic CRYPTO_dynlock_value* dyn_create_function(const char* file, int line) { 19147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org CRYPTO_dynlock_value* value = new CRYPTO_dynlock_value; 19247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!value) 19347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return NULL; 19447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org MUTEX_SETUP(value->mutex); 19547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return value; 19647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 19747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 19847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic void dyn_lock_function(int mode, CRYPTO_dynlock_value* l, 19947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const char* file, int line) { 20047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (mode & CRYPTO_LOCK) { 20147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org MUTEX_LOCK(l->mutex); 20247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else { 20347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org MUTEX_UNLOCK(l->mutex); 20447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 20547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 20647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 20747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic void dyn_destroy_function(CRYPTO_dynlock_value* l, 20847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const char* file, int line) { 20947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org MUTEX_CLEANUP(l->mutex); 21047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org delete l; 21147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 21247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 21347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgVerificationCallback OpenSSLAdapter::custom_verify_callback_ = NULL; 21447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 21547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool OpenSSLAdapter::InitializeSSL(VerificationCallback callback) { 21647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!InitializeSSLThread() || !SSL_library_init()) 21747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 21847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if !defined(ADDRESS_SANITIZER) || !defined(WEBRTC_MAC) || defined(WEBRTC_IOS) 21947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Loading the error strings crashes mac_asan. Omit this debugging aid there. 22047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SSL_load_error_strings(); 22147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif 22247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ERR_load_BIO_strings(); 22347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org OpenSSL_add_all_algorithms(); 22447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org RAND_poll(); 22547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org custom_verify_callback_ = callback; 22647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return true; 22747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 22847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 22947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool OpenSSLAdapter::InitializeSSLThread() { 23047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org mutex_buf = new MUTEX_TYPE[CRYPTO_num_locks()]; 23147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!mutex_buf) 23247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 23347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org for (int i = 0; i < CRYPTO_num_locks(); ++i) 23447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org MUTEX_SETUP(mutex_buf[i]); 23547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 23647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // we need to cast our id_function to return an unsigned long -- pthread_t is 23747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // a pointer 23847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org CRYPTO_set_id_callback(id_function); 23947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org CRYPTO_set_locking_callback(locking_function); 24047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org CRYPTO_set_dynlock_create_callback(dyn_create_function); 24147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org CRYPTO_set_dynlock_lock_callback(dyn_lock_function); 24247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org CRYPTO_set_dynlock_destroy_callback(dyn_destroy_function); 24347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return true; 24447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 24547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 24647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool OpenSSLAdapter::CleanupSSL() { 24747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!mutex_buf) 24847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 24947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org CRYPTO_set_id_callback(NULL); 25047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org CRYPTO_set_locking_callback(NULL); 25147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org CRYPTO_set_dynlock_create_callback(NULL); 25247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org CRYPTO_set_dynlock_lock_callback(NULL); 25347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org CRYPTO_set_dynlock_destroy_callback(NULL); 25447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org for (int i = 0; i < CRYPTO_num_locks(); ++i) 25547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org MUTEX_CLEANUP(mutex_buf[i]); 25647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org delete [] mutex_buf; 25747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org mutex_buf = NULL; 25847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return true; 25947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 26047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 26147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgOpenSSLAdapter::OpenSSLAdapter(AsyncSocket* socket) 26247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org : SSLAdapter(socket), 26347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org state_(SSL_NONE), 26447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ssl_read_needs_write_(false), 26547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ssl_write_needs_read_(false), 26647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org restartable_(false), 26747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ssl_(NULL), ssl_ctx_(NULL), 26847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org custom_verification_succeeded_(false) { 26947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 27047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 27147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgOpenSSLAdapter::~OpenSSLAdapter() { 27247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Cleanup(); 27347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 27447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 27547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgint 27647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgOpenSSLAdapter::StartSSL(const char* hostname, bool restartable) { 27747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (state_ != SSL_NONE) 27847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return -1; 27947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 28047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ssl_host_name_ = hostname; 28147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org restartable_ = restartable; 28247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 28347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (socket_->GetState() != Socket::CS_CONNECTED) { 28447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org state_ = SSL_WAIT; 28547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return 0; 28647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 28747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 28847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org state_ = SSL_CONNECTING; 28947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (int err = BeginSSL()) { 29047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Error("BeginSSL", err, false); 29147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return err; 29247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 29347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 29447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return 0; 29547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 29647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 29747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgint 29847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgOpenSSLAdapter::BeginSSL() { 29947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_INFO) << "BeginSSL: " << ssl_host_name_; 30047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ASSERT(state_ == SSL_CONNECTING); 30147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 30247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int err = 0; 30347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org BIO* bio = NULL; 30447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 30547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // First set up the context 30647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!ssl_ctx_) 30747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ssl_ctx_ = SetupSSLContext(); 30847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 30947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!ssl_ctx_) { 31047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org err = -1; 31147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org goto ssl_error; 31247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 31347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 31447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bio = BIO_new_socket(static_cast<AsyncSocketAdapter*>(socket_)); 31547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!bio) { 31647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org err = -1; 31747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org goto ssl_error; 31847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 31947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 32047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ssl_ = SSL_new(ssl_ctx_); 32147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!ssl_) { 32247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org err = -1; 32347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org goto ssl_error; 32447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 32547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 32647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SSL_set_app_data(ssl_, this); 32747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 32847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SSL_set_bio(ssl_, bio, bio); 32947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE | 33047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); 33147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 33247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // the SSL object owns the bio now 33347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bio = NULL; 33447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 33547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Do the connect 33647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org err = ContinueSSL(); 33747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (err != 0) 33847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org goto ssl_error; 33947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 34047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return err; 34147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 34247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgssl_error: 34347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Cleanup(); 34447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (bio) 34547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org BIO_free(bio); 34647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 34747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return err; 34847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 34947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 35047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgint 35147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgOpenSSLAdapter::ContinueSSL() { 35247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ASSERT(state_ == SSL_CONNECTING); 35347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 35447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int code = SSL_connect(ssl_); 35547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org switch (SSL_get_error(ssl_, code)) { 35647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org case SSL_ERROR_NONE: 35747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!SSLPostConnectionCheck(ssl_, ssl_host_name_.c_str())) { 35847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_ERROR) << "TLS post connection check failed"; 35947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // make sure we close the socket 36047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Cleanup(); 36147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // The connect failed so return -1 to shut down the socket 36247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return -1; 36347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 36447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 36547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org state_ = SSL_CONNECTED; 36647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org AsyncSocketAdapter::OnConnectEvent(this); 36747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if 0 // TODO: worry about this 36847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Don't let ourselves go away during the callbacks 36947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org PRefPtr<OpenSSLAdapter> lock(this); 37047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_INFO) << " -- onStreamReadable"; 37147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org AsyncSocketAdapter::OnReadEvent(this); 37247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_INFO) << " -- onStreamWriteable"; 37347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org AsyncSocketAdapter::OnWriteEvent(this); 37447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif 37547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org break; 37647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 37747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org case SSL_ERROR_WANT_READ: 37847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org case SSL_ERROR_WANT_WRITE: 37947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org break; 38047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 38147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org case SSL_ERROR_ZERO_RETURN: 38247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org default: 38347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_WARNING) << "ContinueSSL -- error " << code; 38447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return (code != 0) ? code : -1; 38547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 38647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 38747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return 0; 38847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 38947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 39047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid 39147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgOpenSSLAdapter::Error(const char* context, int err, bool signal) { 39247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_WARNING) << "OpenSSLAdapter::Error(" 39347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org << context << ", " << err << ")"; 39447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org state_ = SSL_ERROR; 39547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SetError(err); 39647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (signal) 39747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org AsyncSocketAdapter::OnCloseEvent(this, err); 39847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 39947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 40047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid 40147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgOpenSSLAdapter::Cleanup() { 40247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_INFO) << "Cleanup"; 40347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 40447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org state_ = SSL_NONE; 40547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ssl_read_needs_write_ = false; 40647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ssl_write_needs_read_ = false; 40747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org custom_verification_succeeded_ = false; 40847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 40947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (ssl_) { 41047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SSL_free(ssl_); 41147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ssl_ = NULL; 41247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 41347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 41447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (ssl_ctx_) { 41547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SSL_CTX_free(ssl_ctx_); 41647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ssl_ctx_ = NULL; 41747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 41847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 41947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 42047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// 42147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// AsyncSocket Implementation 42247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// 42347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 42447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgint 42547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgOpenSSLAdapter::Send(const void* pv, size_t cb) { 42647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org //LOG(LS_INFO) << "OpenSSLAdapter::Send(" << cb << ")"; 42747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 42847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org switch (state_) { 42947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org case SSL_NONE: 43047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return AsyncSocketAdapter::Send(pv, cb); 43147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 43247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org case SSL_WAIT: 43347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org case SSL_CONNECTING: 43447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SetError(EWOULDBLOCK); 43547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return SOCKET_ERROR; 43647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 43747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org case SSL_CONNECTED: 43847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org break; 43947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 44047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org case SSL_ERROR: 44147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org default: 44247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return SOCKET_ERROR; 44347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 44447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 44547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // OpenSSL will return an error if we try to write zero bytes 44647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (cb == 0) 44747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return 0; 44847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 44947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ssl_write_needs_read_ = false; 45047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 45147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int code = SSL_write(ssl_, pv, cb); 45247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org switch (SSL_get_error(ssl_, code)) { 45347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org case SSL_ERROR_NONE: 45447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org //LOG(LS_INFO) << " -- success"; 45547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return code; 45647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org case SSL_ERROR_WANT_READ: 45747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org //LOG(LS_INFO) << " -- error want read"; 45847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ssl_write_needs_read_ = true; 45947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SetError(EWOULDBLOCK); 46047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org break; 46147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org case SSL_ERROR_WANT_WRITE: 46247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org //LOG(LS_INFO) << " -- error want write"; 46347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SetError(EWOULDBLOCK); 46447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org break; 46547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org case SSL_ERROR_ZERO_RETURN: 46647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org //LOG(LS_INFO) << " -- remote side closed"; 46747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SetError(EWOULDBLOCK); 46847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // do we need to signal closure? 46947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org break; 47047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org default: 47147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org //LOG(LS_INFO) << " -- error " << code; 47247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Error("SSL_write", (code ? code : -1), false); 47347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org break; 47447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 47547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 47647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return SOCKET_ERROR; 47747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 47847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 47947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgint 48047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgOpenSSLAdapter::Recv(void* pv, size_t cb) { 48147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org //LOG(LS_INFO) << "OpenSSLAdapter::Recv(" << cb << ")"; 48247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org switch (state_) { 48347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 48447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org case SSL_NONE: 48547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return AsyncSocketAdapter::Recv(pv, cb); 48647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 48747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org case SSL_WAIT: 48847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org case SSL_CONNECTING: 48947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SetError(EWOULDBLOCK); 49047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return SOCKET_ERROR; 49147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 49247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org case SSL_CONNECTED: 49347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org break; 49447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 49547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org case SSL_ERROR: 49647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org default: 49747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return SOCKET_ERROR; 49847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 49947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 50047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Don't trust OpenSSL with zero byte reads 50147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (cb == 0) 50247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return 0; 50347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 50447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ssl_read_needs_write_ = false; 50547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 50647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int code = SSL_read(ssl_, pv, cb); 50747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org switch (SSL_get_error(ssl_, code)) { 50847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org case SSL_ERROR_NONE: 50947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org //LOG(LS_INFO) << " -- success"; 51047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return code; 51147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org case SSL_ERROR_WANT_READ: 51247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org //LOG(LS_INFO) << " -- error want read"; 51347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SetError(EWOULDBLOCK); 51447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org break; 51547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org case SSL_ERROR_WANT_WRITE: 51647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org //LOG(LS_INFO) << " -- error want write"; 51747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ssl_read_needs_write_ = true; 51847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SetError(EWOULDBLOCK); 51947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org break; 52047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org case SSL_ERROR_ZERO_RETURN: 52147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org //LOG(LS_INFO) << " -- remote side closed"; 52247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SetError(EWOULDBLOCK); 52347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // do we need to signal closure? 52447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org break; 52547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org default: 52647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org //LOG(LS_INFO) << " -- error " << code; 52747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Error("SSL_read", (code ? code : -1), false); 52847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org break; 52947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 53047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 53147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return SOCKET_ERROR; 53247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 53347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 53447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgint 53547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgOpenSSLAdapter::Close() { 53647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Cleanup(); 53747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org state_ = restartable_ ? SSL_WAIT : SSL_NONE; 53847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return AsyncSocketAdapter::Close(); 53947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 54047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 54147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgSocket::ConnState 54247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgOpenSSLAdapter::GetState() const { 54347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org //if (signal_close_) 54447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // return CS_CONNECTED; 54547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ConnState state = socket_->GetState(); 54647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if ((state == CS_CONNECTED) 54747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org && ((state_ == SSL_WAIT) || (state_ == SSL_CONNECTING))) 54847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org state = CS_CONNECTING; 54947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return state; 55047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 55147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 55247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid 55347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgOpenSSLAdapter::OnConnectEvent(AsyncSocket* socket) { 55447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_INFO) << "OpenSSLAdapter::OnConnectEvent"; 55547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (state_ != SSL_WAIT) { 55647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ASSERT(state_ == SSL_NONE); 55747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org AsyncSocketAdapter::OnConnectEvent(socket); 55847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return; 55947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 56047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 56147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org state_ = SSL_CONNECTING; 56247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (int err = BeginSSL()) { 56347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org AsyncSocketAdapter::OnCloseEvent(socket, err); 56447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 56547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 56647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 56747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid 56847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgOpenSSLAdapter::OnReadEvent(AsyncSocket* socket) { 56947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org //LOG(LS_INFO) << "OpenSSLAdapter::OnReadEvent"; 57047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 57147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (state_ == SSL_NONE) { 57247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org AsyncSocketAdapter::OnReadEvent(socket); 57347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return; 57447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 57547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 57647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (state_ == SSL_CONNECTING) { 57747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (int err = ContinueSSL()) { 57847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Error("ContinueSSL", err); 57947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 58047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return; 58147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 58247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 58347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (state_ != SSL_CONNECTED) 58447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return; 58547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 58647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Don't let ourselves go away during the callbacks 58747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org //PRefPtr<OpenSSLAdapter> lock(this); // TODO: fix this 58847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (ssl_write_needs_read_) { 58947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org //LOG(LS_INFO) << " -- onStreamWriteable"; 59047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org AsyncSocketAdapter::OnWriteEvent(socket); 59147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 59247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 59347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org //LOG(LS_INFO) << " -- onStreamReadable"; 59447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org AsyncSocketAdapter::OnReadEvent(socket); 59547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 59647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 59747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid 59847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgOpenSSLAdapter::OnWriteEvent(AsyncSocket* socket) { 59947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org //LOG(LS_INFO) << "OpenSSLAdapter::OnWriteEvent"; 60047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 60147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (state_ == SSL_NONE) { 60247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org AsyncSocketAdapter::OnWriteEvent(socket); 60347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return; 60447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 60547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 60647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (state_ == SSL_CONNECTING) { 60747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (int err = ContinueSSL()) { 60847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Error("ContinueSSL", err); 60947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 61047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return; 61147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 61247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 61347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (state_ != SSL_CONNECTED) 61447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return; 61547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 61647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Don't let ourselves go away during the callbacks 61747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org //PRefPtr<OpenSSLAdapter> lock(this); // TODO: fix this 61847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 61947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (ssl_read_needs_write_) { 62047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org //LOG(LS_INFO) << " -- onStreamReadable"; 62147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org AsyncSocketAdapter::OnReadEvent(socket); 62247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 62347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 62447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org //LOG(LS_INFO) << " -- onStreamWriteable"; 62547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org AsyncSocketAdapter::OnWriteEvent(socket); 62647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 62747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 62847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid 62947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgOpenSSLAdapter::OnCloseEvent(AsyncSocket* socket, int err) { 63047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_INFO) << "OpenSSLAdapter::OnCloseEvent(" << err << ")"; 63147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org AsyncSocketAdapter::OnCloseEvent(socket, err); 63247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 63347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 63447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// This code is taken from the "Network Security with OpenSSL" 63547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// sample in chapter 5 63647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 63747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool OpenSSLAdapter::VerifyServerName(SSL* ssl, const char* host, 63847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool ignore_bad_cert) { 63947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!host) 64047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 64147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 64247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Checking the return from SSL_get_peer_certificate here is not strictly 64347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // necessary. With our setup, it is not possible for it to return 64447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // NULL. However, it is good form to check the return. 64547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org X509* certificate = SSL_get_peer_certificate(ssl); 64647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!certificate) 64747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 64847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 64947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Logging certificates is extremely verbose. So it is disabled by default. 65047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#ifdef LOG_CERTIFICATES 65147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org { 65247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_INFO) << "Certificate from server:"; 65347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org BIO* mem = BIO_new(BIO_s_mem()); 65447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org X509_print_ex(mem, certificate, XN_FLAG_SEP_CPLUS_SPC, X509_FLAG_NO_HEADER); 65547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org BIO_write(mem, "\0", 1); 65647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org char* buffer; 65747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org BIO_get_mem_data(mem, &buffer); 65847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_INFO) << buffer; 65947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org BIO_free(mem); 66047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 66147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org char* cipher_description = 66247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SSL_CIPHER_description(SSL_get_current_cipher(ssl), NULL, 128); 66347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_INFO) << "Cipher: " << cipher_description; 66447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org OPENSSL_free(cipher_description); 66547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 66647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif 66747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 66847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool ok = false; 66947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int extension_count = X509_get_ext_count(certificate); 67047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org for (int i = 0; i < extension_count; ++i) { 67147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org X509_EXTENSION* extension = X509_get_ext(certificate, i); 67247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int extension_nid = OBJ_obj2nid(X509_EXTENSION_get_object(extension)); 67347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 67447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (extension_nid == NID_subject_alt_name) { 67547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const X509V3_EXT_METHOD* meth = X509V3_EXT_get(extension); 67647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!meth) 67747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org break; 67847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 67947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org void* ext_str = NULL; 68047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 68147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // We assign this to a local variable, instead of passing the address 68247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // directly to ASN1_item_d2i. 68347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // See http://readlist.com/lists/openssl.org/openssl-users/0/4761.html. 68447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org unsigned char* ext_value_data = extension->value->data; 68547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 68647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const unsigned char **ext_value_data_ptr = 68747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org (const_cast<const unsigned char **>(&ext_value_data)); 68847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 68947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (meth->it) { 69047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ext_str = ASN1_item_d2i(NULL, ext_value_data_ptr, 69147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org extension->value->length, 69247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ASN1_ITEM_ptr(meth->it)); 69347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else { 69447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ext_str = meth->d2i(NULL, ext_value_data_ptr, extension->value->length); 69547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 69647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 69747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org STACK_OF(CONF_VALUE)* value = meth->i2v(meth, ext_str, NULL); 698d3de227a946cf9f65c5255743efb920977061278henrike@webrtc.org 699d3de227a946cf9f65c5255743efb920977061278henrike@webrtc.org // Cast to size_t to be compilable for both OpenSSL and BoringSSL. 700d3de227a946cf9f65c5255743efb920977061278henrike@webrtc.org for (size_t j = 0; j < static_cast<size_t>(sk_CONF_VALUE_num(value)); 701d3de227a946cf9f65c5255743efb920977061278henrike@webrtc.org ++j) { 70247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org CONF_VALUE* nval = sk_CONF_VALUE_value(value, j); 70347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // The value for nval can contain wildcards 70447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!strcmp(nval->name, "DNS") && string_match(host, nval->value)) { 70547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ok = true; 70647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org break; 70747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 70847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 70947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org sk_CONF_VALUE_pop_free(value, X509V3_conf_free); 71047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org value = NULL; 71147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 71247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (meth->it) { 71347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ASN1_item_free(reinterpret_cast<ASN1_VALUE*>(ext_str), 71447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ASN1_ITEM_ptr(meth->it)); 71547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else { 71647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org meth->ext_free(ext_str); 71747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 71847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ext_str = NULL; 71947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 72047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (ok) 72147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org break; 72247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 72347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 72447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org char data[256]; 725222d84ad848886a7123d3ad47c4daf188ecac574henrike@webrtc.org X509_NAME* subject; 72647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!ok 72747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org && ((subject = X509_get_subject_name(certificate)) != NULL) 72847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org && (X509_NAME_get_text_by_NID(subject, NID_commonName, 72947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org data, sizeof(data)) > 0)) { 73047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org data[sizeof(data)-1] = 0; 73147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (_stricmp(data, host) == 0) 73247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ok = true; 73347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 73447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 73547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org X509_free(certificate); 73647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 73747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // This should only ever be turned on for debugging and development. 73847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!ok && ignore_bad_cert) { 73947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_WARNING) << "TLS certificate check FAILED. " 74047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org << "Allowing connection anyway."; 74147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ok = true; 74247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 74347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 74447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return ok; 74547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 74647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 74747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool OpenSSLAdapter::SSLPostConnectionCheck(SSL* ssl, const char* host) { 74847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool ok = VerifyServerName(ssl, host, ignore_bad_cert()); 74947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 75047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (ok) { 75147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ok = (SSL_get_verify_result(ssl) == X509_V_OK || 75247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org custom_verification_succeeded_); 75347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 75447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 75547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!ok && ignore_bad_cert()) { 75647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_INFO) << "Other TLS post connection checks failed."; 75747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ok = true; 75847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 75947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 76047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return ok; 76147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 76247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 76347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if _DEBUG 76447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 76547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// We only use this for tracing and so it is only needed in debug mode 76647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 76747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid 76847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgOpenSSLAdapter::SSLInfoCallback(const SSL* s, int where, int ret) { 76947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const char* str = "undefined"; 77047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int w = where & ~SSL_ST_MASK; 77147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (w & SSL_ST_CONNECT) { 77247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org str = "SSL_connect"; 77347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else if (w & SSL_ST_ACCEPT) { 77447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org str = "SSL_accept"; 77547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 77647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (where & SSL_CB_LOOP) { 77747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_INFO) << str << ":" << SSL_state_string_long(s); 77847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else if (where & SSL_CB_ALERT) { 77947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org str = (where & SSL_CB_READ) ? "read" : "write"; 78047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_INFO) << "SSL3 alert " << str 78147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org << ":" << SSL_alert_type_string_long(ret) 78247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org << ":" << SSL_alert_desc_string_long(ret); 78347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else if (where & SSL_CB_EXIT) { 78447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (ret == 0) { 78547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_INFO) << str << ":failed in " << SSL_state_string_long(s); 78647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else if (ret < 0) { 78747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_INFO) << str << ":error in " << SSL_state_string_long(s); 78847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 78947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 79047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 79147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 79247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif // _DEBUG 79347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 79447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgint 79547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgOpenSSLAdapter::SSLVerifyCallback(int ok, X509_STORE_CTX* store) { 79647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if _DEBUG 79747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!ok) { 79847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org char data[256]; 79947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org X509* cert = X509_STORE_CTX_get_current_cert(store); 80047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int depth = X509_STORE_CTX_get_error_depth(store); 80147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int err = X509_STORE_CTX_get_error(store); 80247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 80347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_INFO) << "Error with certificate at depth: " << depth; 80447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org X509_NAME_oneline(X509_get_issuer_name(cert), data, sizeof(data)); 80547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_INFO) << " issuer = " << data; 80647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org X509_NAME_oneline(X509_get_subject_name(cert), data, sizeof(data)); 80747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_INFO) << " subject = " << data; 80847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_INFO) << " err = " << err 80947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org << ":" << X509_verify_cert_error_string(err); 81047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 81147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif 81247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 81347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Get our stream pointer from the store 81447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SSL* ssl = reinterpret_cast<SSL*>( 81547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org X509_STORE_CTX_get_ex_data(store, 81647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SSL_get_ex_data_X509_STORE_CTX_idx())); 81747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 81847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org OpenSSLAdapter* stream = 81947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org reinterpret_cast<OpenSSLAdapter*>(SSL_get_app_data(ssl)); 82047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 82147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!ok && custom_verify_callback_) { 82247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org void* cert = 82347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org reinterpret_cast<void*>(X509_STORE_CTX_get_current_cert(store)); 82447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (custom_verify_callback_(cert)) { 82547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org stream->custom_verification_succeeded_ = true; 82647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_INFO) << "validated certificate using custom callback"; 82747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ok = true; 82847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 82947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 83047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 83147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Should only be used for debugging and development. 83247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!ok && stream->ignore_bad_cert()) { 83347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_WARNING) << "Ignoring cert error while verifying cert chain"; 83447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ok = 1; 83547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 83647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 83747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return ok; 83847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 83947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 84047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool OpenSSLAdapter::ConfigureTrustedRootCertificates(SSL_CTX* ctx) { 84147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Add the root cert that we care about to the SSL context 84247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int count_of_added_certs = 0; 84347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org for (int i = 0; i < ARRAY_SIZE(kSSLCertCertificateList); i++) { 84447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const unsigned char* cert_buffer = kSSLCertCertificateList[i]; 84547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org size_t cert_buffer_len = kSSLCertCertificateSizeList[i]; 84647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org X509* cert = d2i_X509(NULL, &cert_buffer, cert_buffer_len); 84747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (cert) { 84847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int return_value = X509_STORE_add_cert(SSL_CTX_get_cert_store(ctx), cert); 84947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (return_value == 0) { 85047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_WARNING) << "Unable to add certificate."; 85147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else { 85247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org count_of_added_certs++; 85347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 85447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org X509_free(cert); 85547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 85647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 85747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return count_of_added_certs > 0; 85847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 85947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 86047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgSSL_CTX* 86147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgOpenSSLAdapter::SetupSSLContext() { 86247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SSL_CTX* ctx = SSL_CTX_new(TLSv1_client_method()); 86347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (ctx == NULL) { 86447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org unsigned long error = ERR_get_error(); // NOLINT: type used by OpenSSL. 86547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org LOG(LS_WARNING) << "SSL_CTX creation failed: " 86647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org << '"' << ERR_reason_error_string(error) << "\" " 86747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org << "(error=" << error << ')'; 86847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return NULL; 86947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 87047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!ConfigureTrustedRootCertificates(ctx)) { 87147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SSL_CTX_free(ctx); 87247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return NULL; 87347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 87447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 87547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#ifdef _DEBUG 87647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SSL_CTX_set_info_callback(ctx, SSLInfoCallback); 87747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif 87847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 87947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, SSLVerifyCallback); 88047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SSL_CTX_set_verify_depth(ctx, 4); 88147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SSL_CTX_set_cipher_list(ctx, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); 88247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 88347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return ctx; 88447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 88547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 88647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} // namespace rtc 88747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 88847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif // HAVE_OPENSSL_SSL_H 889