1f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org/* 2f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org * Copyright 2004 The WebRTC Project Authors. All rights reserved. 3f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org * 4f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org * Use of this source code is governed by a BSD-style license 5f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org * that can be found in the LICENSE file in the root of the source 6f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org * tree. An additional intellectual property rights grant can be found 7f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org * in the file PATENTS. All contributing project authors may 8f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org */ 10f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 11f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#if HAVE_CONFIG_H 12f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#include "config.h" 13f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#endif // HAVE_CONFIG_H 14f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 15f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#if HAVE_OPENSSL_SSL_H 16f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 17f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#include "webrtc/base/opensslstreamadapter.h" 18f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 19f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#include <openssl/bio.h> 20f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#include <openssl/crypto.h> 21f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#include <openssl/err.h> 22f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#include <openssl/rand.h> 23f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#include <openssl/x509v3.h> 24f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 25f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#include <vector> 26f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 27f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#include "webrtc/base/common.h" 28f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#include "webrtc/base/logging.h" 29f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#include "webrtc/base/stream.h" 30f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#include "webrtc/base/openssl.h" 31f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#include "webrtc/base/openssladapter.h" 32f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#include "webrtc/base/openssldigest.h" 33f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#include "webrtc/base/opensslidentity.h" 34f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#include "webrtc/base/stringutils.h" 35f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#include "webrtc/base/thread.h" 36f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 37f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgnamespace rtc { 38f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 39f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#if (OPENSSL_VERSION_NUMBER >= 0x10001000L) 40f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#define HAVE_DTLS_SRTP 41f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#endif 42f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 43f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#ifdef HAVE_DTLS_SRTP 44f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org// SRTP cipher suite table 45f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgstruct SrtpCipherMapEntry { 46f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org const char* external_name; 47f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org const char* internal_name; 48f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org}; 49f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 50f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org// This isn't elegant, but it's better than an external reference 51f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgstatic SrtpCipherMapEntry SrtpCipherMap[] = { 52f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org {"AES_CM_128_HMAC_SHA1_80", "SRTP_AES128_CM_SHA1_80"}, 53f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org {"AES_CM_128_HMAC_SHA1_32", "SRTP_AES128_CM_SHA1_32"}, 54f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org {NULL, NULL} 55f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org}; 56f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#endif 57f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 58f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org////////////////////////////////////////////////////////////////////// 59f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org// StreamBIO 60f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org////////////////////////////////////////////////////////////////////// 61f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 62f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgstatic int stream_write(BIO* h, const char* buf, int num); 63f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgstatic int stream_read(BIO* h, char* buf, int size); 64f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgstatic int stream_puts(BIO* h, const char* str); 65f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgstatic long stream_ctrl(BIO* h, int cmd, long arg1, void* arg2); 66f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgstatic int stream_new(BIO* h); 67f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgstatic int stream_free(BIO* data); 68f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 69f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgstatic BIO_METHOD methods_stream = { 70f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org BIO_TYPE_BIO, 71f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org "stream", 72f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org stream_write, 73f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org stream_read, 74f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org stream_puts, 75f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 0, 76f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org stream_ctrl, 77f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org stream_new, 78f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org stream_free, 79f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org NULL, 80f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org}; 81f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 82f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgstatic BIO_METHOD* BIO_s_stream() { return(&methods_stream); } 83f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 84f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgstatic BIO* BIO_new_stream(StreamInterface* stream) { 85f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org BIO* ret = BIO_new(BIO_s_stream()); 86f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (ret == NULL) 87f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return NULL; 88f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ret->ptr = stream; 89f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return ret; 90f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org} 91f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 92f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org// bio methods return 1 (or at least non-zero) on success and 0 on failure. 93f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 94f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgstatic int stream_new(BIO* b) { 95f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org b->shutdown = 0; 96f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org b->init = 1; 97f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org b->num = 0; // 1 means end-of-stream 98f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org b->ptr = 0; 99f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return 1; 100f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org} 101f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 102f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgstatic int stream_free(BIO* b) { 103f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (b == NULL) 104f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return 0; 105f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return 1; 106f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org} 107f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 108f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgstatic int stream_read(BIO* b, char* out, int outl) { 109f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (!out) 110f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return -1; 111f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org StreamInterface* stream = static_cast<StreamInterface*>(b->ptr); 112f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org BIO_clear_retry_flags(b); 113f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org size_t read; 114f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org int error; 115f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org StreamResult result = stream->Read(out, outl, &read, &error); 116f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (result == SR_SUCCESS) { 117f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return read; 118f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } else if (result == SR_EOS) { 119f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org b->num = 1; 120f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } else if (result == SR_BLOCK) { 121f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org BIO_set_retry_read(b); 122f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 123f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return -1; 124f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org} 125f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 126f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgstatic int stream_write(BIO* b, const char* in, int inl) { 127f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (!in) 128f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return -1; 129f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org StreamInterface* stream = static_cast<StreamInterface*>(b->ptr); 130f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org BIO_clear_retry_flags(b); 131f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org size_t written; 132f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org int error; 133f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org StreamResult result = stream->Write(in, inl, &written, &error); 134f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (result == SR_SUCCESS) { 135f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return written; 136f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } else if (result == SR_BLOCK) { 137f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org BIO_set_retry_write(b); 138f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 139f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return -1; 140f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org} 141f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 142f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgstatic int stream_puts(BIO* b, const char* str) { 143f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return stream_write(b, str, strlen(str)); 144f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org} 145f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 146f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgstatic long stream_ctrl(BIO* b, int cmd, long num, void* ptr) { 147fda34e7b12a53d3f76e5bd2de658eebc8c5d711bhenrike@webrtc.org RTC_UNUSED(num); 148fda34e7b12a53d3f76e5bd2de658eebc8c5d711bhenrike@webrtc.org RTC_UNUSED(ptr); 149f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 150f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org switch (cmd) { 151f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org case BIO_CTRL_RESET: 152f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return 0; 153f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org case BIO_CTRL_EOF: 154f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return b->num; 155f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org case BIO_CTRL_WPENDING: 156f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org case BIO_CTRL_PENDING: 157f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return 0; 158f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org case BIO_CTRL_FLUSH: 159f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return 1; 160f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org default: 161f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return 0; 162f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 163f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org} 164f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 165f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org///////////////////////////////////////////////////////////////////////////// 166f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org// OpenSSLStreamAdapter 167f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org///////////////////////////////////////////////////////////////////////////// 168f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 169f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgOpenSSLStreamAdapter::OpenSSLStreamAdapter(StreamInterface* stream) 170f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org : SSLStreamAdapter(stream), 171f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org state_(SSL_NONE), 172f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org role_(SSL_CLIENT), 173f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ssl_read_needs_write_(false), ssl_write_needs_read_(false), 174f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ssl_(NULL), ssl_ctx_(NULL), 175f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org custom_verification_succeeded_(false), 176f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ssl_mode_(SSL_MODE_TLS) { 177f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org} 178f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 179f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgOpenSSLStreamAdapter::~OpenSSLStreamAdapter() { 180f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org Cleanup(); 181f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org} 182f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 183f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgvoid OpenSSLStreamAdapter::SetIdentity(SSLIdentity* identity) { 184f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ASSERT(!identity_); 185f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org identity_.reset(static_cast<OpenSSLIdentity*>(identity)); 186f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org} 187f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 188f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgvoid OpenSSLStreamAdapter::SetServerRole(SSLRole role) { 189f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org role_ = role; 190f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org} 191f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 192f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgbool OpenSSLStreamAdapter::GetPeerCertificate(SSLCertificate** cert) const { 193f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (!peer_certificate_) 194f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return false; 195f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 196f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org *cert = peer_certificate_->GetReference(); 197f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return true; 198f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org} 199f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 200f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgbool OpenSSLStreamAdapter::SetPeerCertificateDigest(const std::string 201f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org &digest_alg, 202f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org const unsigned char* 203f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org digest_val, 204f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org size_t digest_len) { 205f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ASSERT(!peer_certificate_); 206f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ASSERT(peer_certificate_digest_algorithm_.size() == 0); 207f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ASSERT(ssl_server_name_.empty()); 208f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org size_t expected_len; 209f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 210f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (!OpenSSLDigest::GetDigestSize(digest_alg, &expected_len)) { 211f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org LOG(LS_WARNING) << "Unknown digest algorithm: " << digest_alg; 212f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return false; 213f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 214f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (expected_len != digest_len) 215f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return false; 216f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 217f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org peer_certificate_digest_value_.SetData(digest_val, digest_len); 218f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org peer_certificate_digest_algorithm_ = digest_alg; 219f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 220f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return true; 221f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org} 222f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 223f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org// Key Extractor interface 224f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgbool OpenSSLStreamAdapter::ExportKeyingMaterial(const std::string& label, 225f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org const uint8* context, 226f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org size_t context_len, 227f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org bool use_context, 228f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org uint8* result, 229f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org size_t result_len) { 230f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#ifdef HAVE_DTLS_SRTP 231f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org int i; 232f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 233f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org i = SSL_export_keying_material(ssl_, result, result_len, 234f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org label.c_str(), label.length(), 235f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org const_cast<uint8 *>(context), 236f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org context_len, use_context); 237f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 238f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (i != 1) 239f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return false; 240f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 241f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return true; 242f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#else 243f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return false; 244f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#endif 245f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org} 246f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 247f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgbool OpenSSLStreamAdapter::SetDtlsSrtpCiphers( 248f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org const std::vector<std::string>& ciphers) { 249f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#ifdef HAVE_DTLS_SRTP 250f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org std::string internal_ciphers; 251f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 252f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (state_ != SSL_NONE) 253f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return false; 254f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 255f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org for (std::vector<std::string>::const_iterator cipher = ciphers.begin(); 256f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org cipher != ciphers.end(); ++cipher) { 257f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org bool found = false; 258f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org for (SrtpCipherMapEntry *entry = SrtpCipherMap; entry->internal_name; 259f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ++entry) { 260f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (*cipher == entry->external_name) { 261f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org found = true; 262f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (!internal_ciphers.empty()) 263f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org internal_ciphers += ":"; 264f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org internal_ciphers += entry->internal_name; 265f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org break; 266f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 267f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 268f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 269f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (!found) { 270f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org LOG(LS_ERROR) << "Could not find cipher: " << *cipher; 271f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return false; 272f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 273f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 274f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 275f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (internal_ciphers.empty()) 276f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return false; 277f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 278f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org srtp_ciphers_ = internal_ciphers; 279f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return true; 280f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#else 281f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return false; 282f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#endif 283f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org} 284f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 285f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgbool OpenSSLStreamAdapter::GetDtlsSrtpCipher(std::string* cipher) { 286f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#ifdef HAVE_DTLS_SRTP 287f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ASSERT(state_ == SSL_CONNECTED); 288f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (state_ != SSL_CONNECTED) 289f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return false; 290f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 291f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org SRTP_PROTECTION_PROFILE *srtp_profile = 292f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org SSL_get_selected_srtp_profile(ssl_); 293f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 294f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (!srtp_profile) 295f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return false; 296f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 297f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org for (SrtpCipherMapEntry *entry = SrtpCipherMap; 298f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org entry->internal_name; ++entry) { 299f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (!strcmp(entry->internal_name, srtp_profile->name)) { 300f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org *cipher = entry->external_name; 301f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return true; 302f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 303f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 304f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 305f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ASSERT(false); // This should never happen 306f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 307f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return false; 308f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#else 309f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return false; 310f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#endif 311f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org} 312f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 313f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgint OpenSSLStreamAdapter::StartSSLWithServer(const char* server_name) { 314f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ASSERT(server_name != NULL && server_name[0] != '\0'); 315f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ssl_server_name_ = server_name; 316f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return StartSSL(); 317f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org} 318f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 319f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgint OpenSSLStreamAdapter::StartSSLWithPeer() { 320f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ASSERT(ssl_server_name_.empty()); 321f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org // It is permitted to specify peer_certificate_ only later. 322f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return StartSSL(); 323f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org} 324f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 325f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgvoid OpenSSLStreamAdapter::SetMode(SSLMode mode) { 326f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ASSERT(state_ == SSL_NONE); 327f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ssl_mode_ = mode; 328f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org} 329f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 330f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org// 331f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org// StreamInterface Implementation 332f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org// 333f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 334f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgStreamResult OpenSSLStreamAdapter::Write(const void* data, size_t data_len, 335f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org size_t* written, int* error) { 336f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::Write(" << data_len << ")"; 337f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 338f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org switch (state_) { 339f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org case SSL_NONE: 340f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org // pass-through in clear text 341f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return StreamAdapterInterface::Write(data, data_len, written, error); 342f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 343f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org case SSL_WAIT: 344f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org case SSL_CONNECTING: 345f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return SR_BLOCK; 346f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 347f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org case SSL_CONNECTED: 348f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org break; 349f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 350f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org case SSL_ERROR: 351f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org case SSL_CLOSED: 352f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org default: 353f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (error) 354f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org *error = ssl_error_code_; 355f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return SR_ERROR; 356f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 357f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 358f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org // OpenSSL will return an error if we try to write zero bytes 359f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (data_len == 0) { 360f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (written) 361f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org *written = 0; 362f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return SR_SUCCESS; 363f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 364f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 365f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ssl_write_needs_read_ = false; 366f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 367f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org int code = SSL_write(ssl_, data, data_len); 368f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org int ssl_error = SSL_get_error(ssl_, code); 369f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org switch (ssl_error) { 370f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org case SSL_ERROR_NONE: 371f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org LOG(LS_VERBOSE) << " -- success"; 372f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ASSERT(0 < code && static_cast<unsigned>(code) <= data_len); 373f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (written) 374f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org *written = code; 375f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return SR_SUCCESS; 376f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org case SSL_ERROR_WANT_READ: 377f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org LOG(LS_VERBOSE) << " -- error want read"; 378f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ssl_write_needs_read_ = true; 379f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return SR_BLOCK; 380f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org case SSL_ERROR_WANT_WRITE: 381f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org LOG(LS_VERBOSE) << " -- error want write"; 382f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return SR_BLOCK; 383f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 384f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org case SSL_ERROR_ZERO_RETURN: 385f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org default: 386f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org Error("SSL_write", (ssl_error ? ssl_error : -1), false); 387f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (error) 388f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org *error = ssl_error_code_; 389f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return SR_ERROR; 390f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 391f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org // not reached 392f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org} 393f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 394f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgStreamResult OpenSSLStreamAdapter::Read(void* data, size_t data_len, 395f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org size_t* read, int* error) { 396f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::Read(" << data_len << ")"; 397f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org switch (state_) { 398f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org case SSL_NONE: 399f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org // pass-through in clear text 400f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return StreamAdapterInterface::Read(data, data_len, read, error); 401f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 402f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org case SSL_WAIT: 403f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org case SSL_CONNECTING: 404f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return SR_BLOCK; 405f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 406f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org case SSL_CONNECTED: 407f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org break; 408f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 409f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org case SSL_CLOSED: 410f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return SR_EOS; 411f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 412f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org case SSL_ERROR: 413f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org default: 414f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (error) 415f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org *error = ssl_error_code_; 416f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return SR_ERROR; 417f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 418f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 419f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org // Don't trust OpenSSL with zero byte reads 420f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (data_len == 0) { 421f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (read) 422f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org *read = 0; 423f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return SR_SUCCESS; 424f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 425f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 426f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ssl_read_needs_write_ = false; 427f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 428f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org int code = SSL_read(ssl_, data, data_len); 429f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org int ssl_error = SSL_get_error(ssl_, code); 430f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org switch (ssl_error) { 431f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org case SSL_ERROR_NONE: 432f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org LOG(LS_VERBOSE) << " -- success"; 433f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ASSERT(0 < code && static_cast<unsigned>(code) <= data_len); 434f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (read) 435f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org *read = code; 436f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 437f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (ssl_mode_ == SSL_MODE_DTLS) { 438f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org // Enforce atomic reads -- this is a short read 439f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org unsigned int pending = SSL_pending(ssl_); 440f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 441f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (pending) { 442f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org LOG(LS_INFO) << " -- short DTLS read. flushing"; 443f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org FlushInput(pending); 444f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (error) 445f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org *error = SSE_MSG_TRUNC; 446f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return SR_ERROR; 447f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 448f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 449f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return SR_SUCCESS; 450f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org case SSL_ERROR_WANT_READ: 451f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org LOG(LS_VERBOSE) << " -- error want read"; 452f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return SR_BLOCK; 453f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org case SSL_ERROR_WANT_WRITE: 454f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org LOG(LS_VERBOSE) << " -- error want write"; 455f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ssl_read_needs_write_ = true; 456f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return SR_BLOCK; 457f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org case SSL_ERROR_ZERO_RETURN: 458f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org LOG(LS_VERBOSE) << " -- remote side closed"; 459f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return SR_EOS; 460f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org break; 461f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org default: 462f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org LOG(LS_VERBOSE) << " -- error " << code; 463f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org Error("SSL_read", (ssl_error ? ssl_error : -1), false); 464f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (error) 465f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org *error = ssl_error_code_; 466f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return SR_ERROR; 467f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 468f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org // not reached 469f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org} 470f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 471f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgvoid OpenSSLStreamAdapter::FlushInput(unsigned int left) { 472f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org unsigned char buf[2048]; 473f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 474f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org while (left) { 475f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org // This should always succeed 476f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org int toread = (sizeof(buf) < left) ? sizeof(buf) : left; 477f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org int code = SSL_read(ssl_, buf, toread); 478f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 479f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org int ssl_error = SSL_get_error(ssl_, code); 480f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ASSERT(ssl_error == SSL_ERROR_NONE); 481f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 482f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (ssl_error != SSL_ERROR_NONE) { 483f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org LOG(LS_VERBOSE) << " -- error " << code; 484f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org Error("SSL_read", (ssl_error ? ssl_error : -1), false); 485f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return; 486f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 487f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 488f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org LOG(LS_VERBOSE) << " -- flushed " << code << " bytes"; 489f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org left -= code; 490f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 491f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org} 492f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 493f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgvoid OpenSSLStreamAdapter::Close() { 494f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org Cleanup(); 495f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ASSERT(state_ == SSL_CLOSED || state_ == SSL_ERROR); 496f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org StreamAdapterInterface::Close(); 497f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org} 498f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 499f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgStreamState OpenSSLStreamAdapter::GetState() const { 500f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org switch (state_) { 501f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org case SSL_WAIT: 502f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org case SSL_CONNECTING: 503f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return SS_OPENING; 504f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org case SSL_CONNECTED: 505f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return SS_OPEN; 506f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org default: 507f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return SS_CLOSED; 508f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org }; 509f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org // not reached 510f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org} 511f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 512f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgvoid OpenSSLStreamAdapter::OnEvent(StreamInterface* stream, int events, 513f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org int err) { 514f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org int events_to_signal = 0; 515f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org int signal_error = 0; 516f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ASSERT(stream == this->stream()); 517f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if ((events & SE_OPEN)) { 518f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent SE_OPEN"; 519f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (state_ != SSL_WAIT) { 520f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ASSERT(state_ == SSL_NONE); 521f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org events_to_signal |= SE_OPEN; 522f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } else { 523f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org state_ = SSL_CONNECTING; 524f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (int err = BeginSSL()) { 525f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org Error("BeginSSL", err, true); 526f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return; 527f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 528f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 529f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 530f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if ((events & (SE_READ|SE_WRITE))) { 531f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent" 532f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org << ((events & SE_READ) ? " SE_READ" : "") 533f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org << ((events & SE_WRITE) ? " SE_WRITE" : ""); 534f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (state_ == SSL_NONE) { 535f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org events_to_signal |= events & (SE_READ|SE_WRITE); 536f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } else if (state_ == SSL_CONNECTING) { 537f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (int err = ContinueSSL()) { 538f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org Error("ContinueSSL", err, true); 539f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return; 540f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 541f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } else if (state_ == SSL_CONNECTED) { 542f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (((events & SE_READ) && ssl_write_needs_read_) || 543f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org (events & SE_WRITE)) { 544f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org LOG(LS_VERBOSE) << " -- onStreamWriteable"; 545f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org events_to_signal |= SE_WRITE; 546f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 547f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (((events & SE_WRITE) && ssl_read_needs_write_) || 548f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org (events & SE_READ)) { 549f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org LOG(LS_VERBOSE) << " -- onStreamReadable"; 550f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org events_to_signal |= SE_READ; 551f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 552f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 553f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 554f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if ((events & SE_CLOSE)) { 555f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent(SE_CLOSE, " << err << ")"; 556f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org Cleanup(); 557f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org events_to_signal |= SE_CLOSE; 558f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org // SE_CLOSE is the only event that uses the final parameter to OnEvent(). 559f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ASSERT(signal_error == 0); 560f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org signal_error = err; 561f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 562f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (events_to_signal) 563f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org StreamAdapterInterface::OnEvent(stream, events_to_signal, signal_error); 564f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org} 565f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 566f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgint OpenSSLStreamAdapter::StartSSL() { 567f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ASSERT(state_ == SSL_NONE); 568f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 569f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (StreamAdapterInterface::GetState() != SS_OPEN) { 570f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org state_ = SSL_WAIT; 571f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return 0; 572f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 573f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 574f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org state_ = SSL_CONNECTING; 575f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (int err = BeginSSL()) { 576f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org Error("BeginSSL", err, false); 577f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return err; 578f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 579f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 580f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return 0; 581f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org} 582f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 583f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgint OpenSSLStreamAdapter::BeginSSL() { 584f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ASSERT(state_ == SSL_CONNECTING); 585f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org // The underlying stream has open. If we are in peer-to-peer mode 586f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org // then a peer certificate must have been specified by now. 587f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ASSERT(!ssl_server_name_.empty() || 588f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org !peer_certificate_digest_algorithm_.empty()); 589f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org LOG(LS_INFO) << "BeginSSL: " 590f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org << (!ssl_server_name_.empty() ? ssl_server_name_ : 591f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org "with peer"); 592f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 593f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org BIO* bio = NULL; 594f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 595f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org // First set up the context 596f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ASSERT(ssl_ctx_ == NULL); 597f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ssl_ctx_ = SetupSSLContext(); 598f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (!ssl_ctx_) 599f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return -1; 600f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 601f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org bio = BIO_new_stream(static_cast<StreamInterface*>(stream())); 602f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (!bio) 603f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return -1; 604f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 605f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ssl_ = SSL_new(ssl_ctx_); 606f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (!ssl_) { 607f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org BIO_free(bio); 608f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return -1; 609f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 610f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 611f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org SSL_set_app_data(ssl_, this); 612f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 613f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org SSL_set_bio(ssl_, bio, bio); // the SSL object owns the bio now. 614f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 615f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE | 616f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); 617f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 618b6dafc1db62c6f7e5114084713a3ad0bc329254fjiayl@webrtc.org // Specify an ECDH group for ECDHE ciphers, otherwise they cannot be 619b6dafc1db62c6f7e5114084713a3ad0bc329254fjiayl@webrtc.org // negotiated when acting as the server. Use NIST's P-256 which is commonly 620b6dafc1db62c6f7e5114084713a3ad0bc329254fjiayl@webrtc.org // supported. 621b6dafc1db62c6f7e5114084713a3ad0bc329254fjiayl@webrtc.org EC_KEY* ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); 622b6dafc1db62c6f7e5114084713a3ad0bc329254fjiayl@webrtc.org if (ecdh == NULL) 623b6dafc1db62c6f7e5114084713a3ad0bc329254fjiayl@webrtc.org return -1; 624b6dafc1db62c6f7e5114084713a3ad0bc329254fjiayl@webrtc.org SSL_set_options(ssl_, SSL_OP_SINGLE_ECDH_USE); 625b6dafc1db62c6f7e5114084713a3ad0bc329254fjiayl@webrtc.org SSL_set_tmp_ecdh(ssl_, ecdh); 626b6dafc1db62c6f7e5114084713a3ad0bc329254fjiayl@webrtc.org EC_KEY_free(ecdh); 627b6dafc1db62c6f7e5114084713a3ad0bc329254fjiayl@webrtc.org 628f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org // Do the connect 629f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return ContinueSSL(); 630f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org} 631f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 632f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgint OpenSSLStreamAdapter::ContinueSSL() { 633f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org LOG(LS_VERBOSE) << "ContinueSSL"; 634f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ASSERT(state_ == SSL_CONNECTING); 635f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 636f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org // Clear the DTLS timer 637f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org Thread::Current()->Clear(this, MSG_TIMEOUT); 638f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 639f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org int code = (role_ == SSL_CLIENT) ? SSL_connect(ssl_) : SSL_accept(ssl_); 640f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org int ssl_error; 641f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org switch (ssl_error = SSL_get_error(ssl_, code)) { 642f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org case SSL_ERROR_NONE: 643f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org LOG(LS_VERBOSE) << " -- success"; 644f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 645f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (!SSLPostConnectionCheck(ssl_, ssl_server_name_.c_str(), NULL, 646f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org peer_certificate_digest_algorithm_)) { 647f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org LOG(LS_ERROR) << "TLS post connection check failed"; 648f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return -1; 649f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 650f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 651f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org state_ = SSL_CONNECTED; 652f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org StreamAdapterInterface::OnEvent(stream(), SE_OPEN|SE_READ|SE_WRITE, 0); 653f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org break; 654f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 655f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org case SSL_ERROR_WANT_READ: { 656f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org LOG(LS_VERBOSE) << " -- error want read"; 657f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org struct timeval timeout; 658f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (DTLSv1_get_timeout(ssl_, &timeout)) { 659f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org int delay = timeout.tv_sec * 1000 + timeout.tv_usec/1000; 660f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 661f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org Thread::Current()->PostDelayed(delay, this, MSG_TIMEOUT, 0); 662f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 663f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 664f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org break; 665f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 666f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org case SSL_ERROR_WANT_WRITE: 667f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org LOG(LS_VERBOSE) << " -- error want write"; 668f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org break; 669f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 670f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org case SSL_ERROR_ZERO_RETURN: 671f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org default: 672f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org LOG(LS_VERBOSE) << " -- error " << code; 673f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return (ssl_error != 0) ? ssl_error : -1; 674f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 675f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 676f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return 0; 677f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org} 678f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 679f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgvoid OpenSSLStreamAdapter::Error(const char* context, int err, bool signal) { 680f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org LOG(LS_WARNING) << "OpenSSLStreamAdapter::Error(" 681f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org << context << ", " << err << ")"; 682f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org state_ = SSL_ERROR; 683f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ssl_error_code_ = err; 684f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org Cleanup(); 685f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (signal) 686f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org StreamAdapterInterface::OnEvent(stream(), SE_CLOSE, err); 687f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org} 688f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 689f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgvoid OpenSSLStreamAdapter::Cleanup() { 690f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org LOG(LS_INFO) << "Cleanup"; 691f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 692f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (state_ != SSL_ERROR) { 693f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org state_ = SSL_CLOSED; 694f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ssl_error_code_ = 0; 695f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 696f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 697f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (ssl_) { 6985cc77017d808f4e9c2c53115eadbc951e675269cjiayl@webrtc.org int ret = SSL_shutdown(ssl_); 6995cc77017d808f4e9c2c53115eadbc951e675269cjiayl@webrtc.org if (ret < 0) { 7005cc77017d808f4e9c2c53115eadbc951e675269cjiayl@webrtc.org LOG(LS_WARNING) << "SSL_shutdown failed, error = " 7015cc77017d808f4e9c2c53115eadbc951e675269cjiayl@webrtc.org << SSL_get_error(ssl_, ret); 7025cc77017d808f4e9c2c53115eadbc951e675269cjiayl@webrtc.org } 7035cc77017d808f4e9c2c53115eadbc951e675269cjiayl@webrtc.org 704f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org SSL_free(ssl_); 705f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ssl_ = NULL; 706f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 707f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (ssl_ctx_) { 708f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org SSL_CTX_free(ssl_ctx_); 709f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ssl_ctx_ = NULL; 710f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 711f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org identity_.reset(); 712f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org peer_certificate_.reset(); 713f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 714f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org // Clear the DTLS timer 715f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org Thread::Current()->Clear(this, MSG_TIMEOUT); 716f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org} 717f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 718f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 719f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgvoid OpenSSLStreamAdapter::OnMessage(Message* msg) { 720f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org // Process our own messages and then pass others to the superclass 721f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (MSG_TIMEOUT == msg->message_id) { 722f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org LOG(LS_INFO) << "DTLS timeout expired"; 723f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org DTLSv1_handle_timeout(ssl_); 724f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ContinueSSL(); 725f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } else { 726f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org StreamInterface::OnMessage(msg); 727f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 728f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org} 729f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 730f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgSSL_CTX* OpenSSLStreamAdapter::SetupSSLContext() { 731f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org SSL_CTX *ctx = NULL; 732f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 733f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (role_ == SSL_CLIENT) { 734f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ctx = SSL_CTX_new(ssl_mode_ == SSL_MODE_DTLS ? 735f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org DTLSv1_client_method() : TLSv1_client_method()); 736f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } else { 737f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ctx = SSL_CTX_new(ssl_mode_ == SSL_MODE_DTLS ? 738f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org DTLSv1_server_method() : TLSv1_server_method()); 739f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 740f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (ctx == NULL) 741f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return NULL; 742f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 743f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (identity_ && !identity_->ConfigureIdentity(ctx)) { 744f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org SSL_CTX_free(ctx); 745f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return NULL; 746f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 747f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 748f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#ifdef _DEBUG 749f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org SSL_CTX_set_info_callback(ctx, OpenSSLAdapter::SSLInfoCallback); 750f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#endif 751f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 752e987b732456ada71d1dee156e6aa3ee238da1e33tkchin@webrtc.org int mode = SSL_VERIFY_PEER; 753e987b732456ada71d1dee156e6aa3ee238da1e33tkchin@webrtc.org if (client_auth_enabled()) { 754e987b732456ada71d1dee156e6aa3ee238da1e33tkchin@webrtc.org // Require a certificate from the client. 755e987b732456ada71d1dee156e6aa3ee238da1e33tkchin@webrtc.org // Note: Normally this is always true in production, but it may be disabled 756e987b732456ada71d1dee156e6aa3ee238da1e33tkchin@webrtc.org // for testing purposes (e.g. SSLAdapter unit tests). 757e987b732456ada71d1dee156e6aa3ee238da1e33tkchin@webrtc.org mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT; 758e987b732456ada71d1dee156e6aa3ee238da1e33tkchin@webrtc.org } 759e987b732456ada71d1dee156e6aa3ee238da1e33tkchin@webrtc.org 760e987b732456ada71d1dee156e6aa3ee238da1e33tkchin@webrtc.org SSL_CTX_set_verify(ctx, mode, SSLVerifyCallback); 761f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org SSL_CTX_set_verify_depth(ctx, 4); 762f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org SSL_CTX_set_cipher_list(ctx, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); 763f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 764f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#ifdef HAVE_DTLS_SRTP 765f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (!srtp_ciphers_.empty()) { 766f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (SSL_CTX_set_tlsext_use_srtp(ctx, srtp_ciphers_.c_str())) { 767f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org SSL_CTX_free(ctx); 768f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return NULL; 769f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 770f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 771f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#endif 772f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 773f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return ctx; 774f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org} 775f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 776f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgint OpenSSLStreamAdapter::SSLVerifyCallback(int ok, X509_STORE_CTX* store) { 777f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org // Get our SSL structure from the store 778f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org SSL* ssl = reinterpret_cast<SSL*>(X509_STORE_CTX_get_ex_data( 779f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org store, 780f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org SSL_get_ex_data_X509_STORE_CTX_idx())); 781f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org OpenSSLStreamAdapter* stream = 782f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org reinterpret_cast<OpenSSLStreamAdapter*>(SSL_get_app_data(ssl)); 783f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 784f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (stream->peer_certificate_digest_algorithm_.empty()) { 785f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return 0; 786f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 787f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org X509* cert = X509_STORE_CTX_get_current_cert(store); 788005ef1e3a0b7d76568e6b80a3d6d67ae840501dbhenrike@webrtc.org int depth = X509_STORE_CTX_get_error_depth(store); 789005ef1e3a0b7d76568e6b80a3d6d67ae840501dbhenrike@webrtc.org 790005ef1e3a0b7d76568e6b80a3d6d67ae840501dbhenrike@webrtc.org // For now We ignore the parent certificates and verify the leaf against 791005ef1e3a0b7d76568e6b80a3d6d67ae840501dbhenrike@webrtc.org // the digest. 792005ef1e3a0b7d76568e6b80a3d6d67ae840501dbhenrike@webrtc.org // 793005ef1e3a0b7d76568e6b80a3d6d67ae840501dbhenrike@webrtc.org // TODO(jiayl): Verify the chain is a proper chain and report the chain to 794005ef1e3a0b7d76568e6b80a3d6d67ae840501dbhenrike@webrtc.org // |stream->peer_certificate_|, like what NSS does. 795005ef1e3a0b7d76568e6b80a3d6d67ae840501dbhenrike@webrtc.org if (depth > 0) { 796005ef1e3a0b7d76568e6b80a3d6d67ae840501dbhenrike@webrtc.org LOG(LS_INFO) << "Ignored chained certificate at depth " << depth; 797005ef1e3a0b7d76568e6b80a3d6d67ae840501dbhenrike@webrtc.org return 1; 798005ef1e3a0b7d76568e6b80a3d6d67ae840501dbhenrike@webrtc.org } 799005ef1e3a0b7d76568e6b80a3d6d67ae840501dbhenrike@webrtc.org 800f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org unsigned char digest[EVP_MAX_MD_SIZE]; 801f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org size_t digest_length; 802f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (!OpenSSLCertificate::ComputeDigest( 803f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org cert, 804f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org stream->peer_certificate_digest_algorithm_, 805f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org digest, sizeof(digest), 806f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org &digest_length)) { 807f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org LOG(LS_WARNING) << "Failed to compute peer cert digest."; 808f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return 0; 809f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 810005ef1e3a0b7d76568e6b80a3d6d67ae840501dbhenrike@webrtc.org 811f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org Buffer computed_digest(digest, digest_length); 812f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (computed_digest != stream->peer_certificate_digest_value_) { 813f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org LOG(LS_WARNING) << "Rejected peer certificate due to mismatched digest."; 814f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return 0; 815f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 816f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org // Ignore any verification error if the digest matches, since there is no 817f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org // value in checking the validity of a self-signed cert issued by untrusted 818f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org // sources. 819f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org LOG(LS_INFO) << "Accepted peer certificate."; 820005ef1e3a0b7d76568e6b80a3d6d67ae840501dbhenrike@webrtc.org 821f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org // Record the peer's certificate. 822f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org stream->peer_certificate_.reset(new OpenSSLCertificate(cert)); 823f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return 1; 824f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org} 825f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 826f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org// This code is taken from the "Network Security with OpenSSL" 827f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org// sample in chapter 5 828f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgbool OpenSSLStreamAdapter::SSLPostConnectionCheck(SSL* ssl, 829f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org const char* server_name, 830f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org const X509* peer_cert, 831f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org const std::string 832f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org &peer_digest) { 833f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ASSERT(server_name != NULL); 834f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org bool ok; 835f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (server_name[0] != '\0') { // traditional mode 836f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ok = OpenSSLAdapter::VerifyServerName(ssl, server_name, ignore_bad_cert()); 837f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 838f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (ok) { 839f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ok = (SSL_get_verify_result(ssl) == X509_V_OK || 840f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org custom_verification_succeeded_); 841f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 842f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } else { // peer-to-peer mode 843f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ASSERT((peer_cert != NULL) || (!peer_digest.empty())); 844f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org // no server name validation 845f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ok = true; 846f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 847f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 848f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org if (!ok && ignore_bad_cert()) { 849f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org LOG(LS_ERROR) << "SSL_get_verify_result(ssl) = " 850f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org << SSL_get_verify_result(ssl); 851f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org LOG(LS_INFO) << "Other TLS post connection checks failed."; 852f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org ok = true; 853f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org } 854f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 855f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return ok; 856f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org} 857f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 858f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgbool OpenSSLStreamAdapter::HaveDtls() { 859f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return true; 860f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org} 861f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 862f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgbool OpenSSLStreamAdapter::HaveDtlsSrtp() { 863f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#ifdef HAVE_DTLS_SRTP 864f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return true; 865f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#else 866f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return false; 867f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#endif 868f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org} 869f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 870f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.orgbool OpenSSLStreamAdapter::HaveExporter() { 871f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#ifdef HAVE_DTLS_SRTP 872f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return true; 873f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#else 874f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org return false; 875f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#endif 876f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org} 877f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 878f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org} // namespace rtc 879f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org 880f7795df4261877af9eaf982cccfafc3fc52aeb4ahenrike@webrtc.org#endif // HAVE_OPENSSL_SSL_H 881