blob: 576b4245296de2c14324274f47166ba308a7ed49 [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
2 * libjingle
3 * Copyright 2004--2008, Google Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#if HAVE_CONFIG_H
29#include "config.h"
30#endif // HAVE_CONFIG_H
31
32#if HAVE_OPENSSL_SSL_H
33
34#include "talk/base/opensslstreamadapter.h"
35
36#include <openssl/bio.h>
37#include <openssl/crypto.h>
38#include <openssl/err.h>
39#include <openssl/rand.h>
wu@webrtc.org0de29502014-02-13 19:54:28 +000040#include <openssl/ssl.h>
henrike@webrtc.org28e20752013-07-10 00:45:36 +000041#include <openssl/x509v3.h>
42
43#include <vector>
44
45#include "talk/base/common.h"
46#include "talk/base/logging.h"
47#include "talk/base/stream.h"
48#include "talk/base/openssladapter.h"
49#include "talk/base/openssldigest.h"
50#include "talk/base/opensslidentity.h"
51#include "talk/base/stringutils.h"
52#include "talk/base/thread.h"
53
54namespace talk_base {
55
wu@webrtc.org0de29502014-02-13 19:54:28 +000056#if (OPENSSL_VERSION_NUMBER >= 0x10001000L)
57#define HAVE_DTLS_SRTP
58#endif
59
60#if (OPENSSL_VERSION_NUMBER >= 0x10000000L)
61#define HAVE_DTLS
62#endif
63
64#ifdef HAVE_DTLS_SRTP
henrike@webrtc.org28e20752013-07-10 00:45:36 +000065// SRTP cipher suite table
66struct SrtpCipherMapEntry {
67 const char* external_name;
68 const char* internal_name;
69};
70
71// This isn't elegant, but it's better than an external reference
72static SrtpCipherMapEntry SrtpCipherMap[] = {
73 {"AES_CM_128_HMAC_SHA1_80", "SRTP_AES128_CM_SHA1_80"},
74 {"AES_CM_128_HMAC_SHA1_32", "SRTP_AES128_CM_SHA1_32"},
75 {NULL, NULL}
76};
wu@webrtc.org0de29502014-02-13 19:54:28 +000077#endif
henrike@webrtc.org28e20752013-07-10 00:45:36 +000078
79//////////////////////////////////////////////////////////////////////
80// StreamBIO
81//////////////////////////////////////////////////////////////////////
82
83static int stream_write(BIO* h, const char* buf, int num);
84static int stream_read(BIO* h, char* buf, int size);
85static int stream_puts(BIO* h, const char* str);
86static long stream_ctrl(BIO* h, int cmd, long arg1, void* arg2);
87static int stream_new(BIO* h);
88static int stream_free(BIO* data);
89
90static BIO_METHOD methods_stream = {
91 BIO_TYPE_BIO,
92 "stream",
93 stream_write,
94 stream_read,
95 stream_puts,
96 0,
97 stream_ctrl,
98 stream_new,
99 stream_free,
100 NULL,
101};
102
103static BIO_METHOD* BIO_s_stream() { return(&methods_stream); }
104
105static BIO* BIO_new_stream(StreamInterface* stream) {
106 BIO* ret = BIO_new(BIO_s_stream());
107 if (ret == NULL)
108 return NULL;
109 ret->ptr = stream;
110 return ret;
111}
112
113// bio methods return 1 (or at least non-zero) on success and 0 on failure.
114
115static int stream_new(BIO* b) {
116 b->shutdown = 0;
117 b->init = 1;
118 b->num = 0; // 1 means end-of-stream
119 b->ptr = 0;
120 return 1;
121}
122
123static int stream_free(BIO* b) {
124 if (b == NULL)
125 return 0;
126 return 1;
127}
128
129static int stream_read(BIO* b, char* out, int outl) {
130 if (!out)
131 return -1;
132 StreamInterface* stream = static_cast<StreamInterface*>(b->ptr);
133 BIO_clear_retry_flags(b);
134 size_t read;
135 int error;
136 StreamResult result = stream->Read(out, outl, &read, &error);
137 if (result == SR_SUCCESS) {
138 return read;
139 } else if (result == SR_EOS) {
140 b->num = 1;
141 } else if (result == SR_BLOCK) {
142 BIO_set_retry_read(b);
143 }
144 return -1;
145}
146
147static int stream_write(BIO* b, const char* in, int inl) {
148 if (!in)
149 return -1;
150 StreamInterface* stream = static_cast<StreamInterface*>(b->ptr);
151 BIO_clear_retry_flags(b);
152 size_t written;
153 int error;
154 StreamResult result = stream->Write(in, inl, &written, &error);
155 if (result == SR_SUCCESS) {
156 return written;
157 } else if (result == SR_BLOCK) {
158 BIO_set_retry_write(b);
159 }
160 return -1;
161}
162
163static int stream_puts(BIO* b, const char* str) {
164 return stream_write(b, str, strlen(str));
165}
166
167static long stream_ctrl(BIO* b, int cmd, long num, void* ptr) {
168 UNUSED(num);
169 UNUSED(ptr);
170
171 switch (cmd) {
172 case BIO_CTRL_RESET:
173 return 0;
174 case BIO_CTRL_EOF:
175 return b->num;
176 case BIO_CTRL_WPENDING:
177 case BIO_CTRL_PENDING:
178 return 0;
179 case BIO_CTRL_FLUSH:
180 return 1;
181 default:
182 return 0;
183 }
184}
185
186/////////////////////////////////////////////////////////////////////////////
187// OpenSSLStreamAdapter
188/////////////////////////////////////////////////////////////////////////////
189
190OpenSSLStreamAdapter::OpenSSLStreamAdapter(StreamInterface* stream)
191 : SSLStreamAdapter(stream),
192 state_(SSL_NONE),
193 role_(SSL_CLIENT),
194 ssl_read_needs_write_(false), ssl_write_needs_read_(false),
195 ssl_(NULL), ssl_ctx_(NULL),
196 custom_verification_succeeded_(false),
197 ssl_mode_(SSL_MODE_TLS) {
198}
199
200OpenSSLStreamAdapter::~OpenSSLStreamAdapter() {
201 Cleanup();
202}
203
204void OpenSSLStreamAdapter::SetIdentity(SSLIdentity* identity) {
205 ASSERT(!identity_);
206 identity_.reset(static_cast<OpenSSLIdentity*>(identity));
207}
208
209void OpenSSLStreamAdapter::SetServerRole(SSLRole role) {
210 role_ = role;
211}
212
wu@webrtc.org4551b792013-10-09 15:37:36 +0000213bool OpenSSLStreamAdapter::GetPeerCertificate(SSLCertificate** cert) const {
214 if (!peer_certificate_)
215 return false;
216
217 *cert = peer_certificate_->GetReference();
218 return true;
219}
220
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000221bool OpenSSLStreamAdapter::SetPeerCertificateDigest(const std::string
222 &digest_alg,
223 const unsigned char*
224 digest_val,
225 size_t digest_len) {
226 ASSERT(!peer_certificate_);
227 ASSERT(peer_certificate_digest_algorithm_.size() == 0);
228 ASSERT(ssl_server_name_.empty());
229 size_t expected_len;
230
231 if (!OpenSSLDigest::GetDigestSize(digest_alg, &expected_len)) {
232 LOG(LS_WARNING) << "Unknown digest algorithm: " << digest_alg;
233 return false;
234 }
235 if (expected_len != digest_len)
236 return false;
237
238 peer_certificate_digest_value_.SetData(digest_val, digest_len);
239 peer_certificate_digest_algorithm_ = digest_alg;
240
241 return true;
242}
243
244// Key Extractor interface
245bool OpenSSLStreamAdapter::ExportKeyingMaterial(const std::string& label,
246 const uint8* context,
247 size_t context_len,
248 bool use_context,
249 uint8* result,
250 size_t result_len) {
wu@webrtc.org0de29502014-02-13 19:54:28 +0000251#ifdef HAVE_DTLS_SRTP
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000252 int i;
253
254 i = SSL_export_keying_material(ssl_, result, result_len,
255 label.c_str(), label.length(),
256 const_cast<uint8 *>(context),
257 context_len, use_context);
258
259 if (i != 1)
260 return false;
261
262 return true;
wu@webrtc.org0de29502014-02-13 19:54:28 +0000263#else
264 return false;
265#endif
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000266}
267
268bool OpenSSLStreamAdapter::SetDtlsSrtpCiphers(
269 const std::vector<std::string>& ciphers) {
270 std::string internal_ciphers;
271
272 if (state_ != SSL_NONE)
273 return false;
274
wu@webrtc.org0de29502014-02-13 19:54:28 +0000275#ifdef HAVE_DTLS_SRTP
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000276 for (std::vector<std::string>::const_iterator cipher = ciphers.begin();
277 cipher != ciphers.end(); ++cipher) {
278 bool found = false;
279 for (SrtpCipherMapEntry *entry = SrtpCipherMap; entry->internal_name;
280 ++entry) {
281 if (*cipher == entry->external_name) {
282 found = true;
283 if (!internal_ciphers.empty())
284 internal_ciphers += ":";
285 internal_ciphers += entry->internal_name;
286 break;
287 }
288 }
289
290 if (!found) {
291 LOG(LS_ERROR) << "Could not find cipher: " << *cipher;
292 return false;
293 }
294 }
295
296 if (internal_ciphers.empty())
297 return false;
298
299 srtp_ciphers_ = internal_ciphers;
300 return true;
wu@webrtc.org0de29502014-02-13 19:54:28 +0000301#else
302 return false;
303#endif
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000304}
305
306bool OpenSSLStreamAdapter::GetDtlsSrtpCipher(std::string* cipher) {
wu@webrtc.org0de29502014-02-13 19:54:28 +0000307#ifdef HAVE_DTLS_SRTP
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000308 ASSERT(state_ == SSL_CONNECTED);
309 if (state_ != SSL_CONNECTED)
310 return false;
311
312 SRTP_PROTECTION_PROFILE *srtp_profile =
313 SSL_get_selected_srtp_profile(ssl_);
314
315 if (!srtp_profile)
316 return false;
317
318 for (SrtpCipherMapEntry *entry = SrtpCipherMap;
319 entry->internal_name; ++entry) {
320 if (!strcmp(entry->internal_name, srtp_profile->name)) {
321 *cipher = entry->external_name;
322 return true;
323 }
324 }
325
326 ASSERT(false); // This should never happen
327
328 return false;
wu@webrtc.org0de29502014-02-13 19:54:28 +0000329#else
330 return false;
331#endif
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000332}
333
334int OpenSSLStreamAdapter::StartSSLWithServer(const char* server_name) {
335 ASSERT(server_name != NULL && server_name[0] != '\0');
336 ssl_server_name_ = server_name;
337 return StartSSL();
338}
339
340int OpenSSLStreamAdapter::StartSSLWithPeer() {
341 ASSERT(ssl_server_name_.empty());
342 // It is permitted to specify peer_certificate_ only later.
343 return StartSSL();
344}
345
346void OpenSSLStreamAdapter::SetMode(SSLMode mode) {
347 ASSERT(state_ == SSL_NONE);
348 ssl_mode_ = mode;
349}
350
351//
352// StreamInterface Implementation
353//
354
355StreamResult OpenSSLStreamAdapter::Write(const void* data, size_t data_len,
356 size_t* written, int* error) {
357 LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::Write(" << data_len << ")";
358
359 switch (state_) {
360 case SSL_NONE:
361 // pass-through in clear text
362 return StreamAdapterInterface::Write(data, data_len, written, error);
363
364 case SSL_WAIT:
365 case SSL_CONNECTING:
366 return SR_BLOCK;
367
368 case SSL_CONNECTED:
369 break;
370
371 case SSL_ERROR:
372 case SSL_CLOSED:
373 default:
374 if (error)
375 *error = ssl_error_code_;
376 return SR_ERROR;
377 }
378
379 // OpenSSL will return an error if we try to write zero bytes
380 if (data_len == 0) {
381 if (written)
382 *written = 0;
383 return SR_SUCCESS;
384 }
385
386 ssl_write_needs_read_ = false;
387
388 int code = SSL_write(ssl_, data, data_len);
389 int ssl_error = SSL_get_error(ssl_, code);
390 switch (ssl_error) {
391 case SSL_ERROR_NONE:
392 LOG(LS_VERBOSE) << " -- success";
393 ASSERT(0 < code && static_cast<unsigned>(code) <= data_len);
394 if (written)
395 *written = code;
396 return SR_SUCCESS;
397 case SSL_ERROR_WANT_READ:
398 LOG(LS_VERBOSE) << " -- error want read";
399 ssl_write_needs_read_ = true;
400 return SR_BLOCK;
401 case SSL_ERROR_WANT_WRITE:
402 LOG(LS_VERBOSE) << " -- error want write";
403 return SR_BLOCK;
404
405 case SSL_ERROR_ZERO_RETURN:
406 default:
407 Error("SSL_write", (ssl_error ? ssl_error : -1), false);
408 if (error)
409 *error = ssl_error_code_;
410 return SR_ERROR;
411 }
412 // not reached
413}
414
415StreamResult OpenSSLStreamAdapter::Read(void* data, size_t data_len,
416 size_t* read, int* error) {
417 LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::Read(" << data_len << ")";
418 switch (state_) {
419 case SSL_NONE:
420 // pass-through in clear text
421 return StreamAdapterInterface::Read(data, data_len, read, error);
422
423 case SSL_WAIT:
424 case SSL_CONNECTING:
425 return SR_BLOCK;
426
427 case SSL_CONNECTED:
428 break;
429
430 case SSL_CLOSED:
431 return SR_EOS;
432
433 case SSL_ERROR:
434 default:
435 if (error)
436 *error = ssl_error_code_;
437 return SR_ERROR;
438 }
439
440 // Don't trust OpenSSL with zero byte reads
441 if (data_len == 0) {
442 if (read)
443 *read = 0;
444 return SR_SUCCESS;
445 }
446
447 ssl_read_needs_write_ = false;
448
449 int code = SSL_read(ssl_, data, data_len);
450 int ssl_error = SSL_get_error(ssl_, code);
451 switch (ssl_error) {
452 case SSL_ERROR_NONE:
453 LOG(LS_VERBOSE) << " -- success";
454 ASSERT(0 < code && static_cast<unsigned>(code) <= data_len);
455 if (read)
456 *read = code;
457
458 if (ssl_mode_ == SSL_MODE_DTLS) {
459 // Enforce atomic reads -- this is a short read
460 unsigned int pending = SSL_pending(ssl_);
461
462 if (pending) {
463 LOG(LS_INFO) << " -- short DTLS read. flushing";
464 FlushInput(pending);
465 if (error)
466 *error = SSE_MSG_TRUNC;
467 return SR_ERROR;
468 }
469 }
470 return SR_SUCCESS;
471 case SSL_ERROR_WANT_READ:
472 LOG(LS_VERBOSE) << " -- error want read";
473 return SR_BLOCK;
474 case SSL_ERROR_WANT_WRITE:
475 LOG(LS_VERBOSE) << " -- error want write";
476 ssl_read_needs_write_ = true;
477 return SR_BLOCK;
478 case SSL_ERROR_ZERO_RETURN:
479 LOG(LS_VERBOSE) << " -- remote side closed";
480 return SR_EOS;
481 break;
482 default:
483 LOG(LS_VERBOSE) << " -- error " << code;
484 Error("SSL_read", (ssl_error ? ssl_error : -1), false);
485 if (error)
486 *error = ssl_error_code_;
487 return SR_ERROR;
488 }
489 // not reached
490}
491
492void OpenSSLStreamAdapter::FlushInput(unsigned int left) {
493 unsigned char buf[2048];
494
495 while (left) {
496 // This should always succeed
497 int toread = (sizeof(buf) < left) ? sizeof(buf) : left;
498 int code = SSL_read(ssl_, buf, toread);
499
500 int ssl_error = SSL_get_error(ssl_, code);
501 ASSERT(ssl_error == SSL_ERROR_NONE);
502
503 if (ssl_error != SSL_ERROR_NONE) {
504 LOG(LS_VERBOSE) << " -- error " << code;
505 Error("SSL_read", (ssl_error ? ssl_error : -1), false);
506 return;
507 }
508
509 LOG(LS_VERBOSE) << " -- flushed " << code << " bytes";
510 left -= code;
511 }
512}
513
514void OpenSSLStreamAdapter::Close() {
515 Cleanup();
516 ASSERT(state_ == SSL_CLOSED || state_ == SSL_ERROR);
517 StreamAdapterInterface::Close();
518}
519
520StreamState OpenSSLStreamAdapter::GetState() const {
521 switch (state_) {
522 case SSL_WAIT:
523 case SSL_CONNECTING:
524 return SS_OPENING;
525 case SSL_CONNECTED:
526 return SS_OPEN;
527 default:
528 return SS_CLOSED;
529 };
530 // not reached
531}
532
533void OpenSSLStreamAdapter::OnEvent(StreamInterface* stream, int events,
534 int err) {
535 int events_to_signal = 0;
536 int signal_error = 0;
537 ASSERT(stream == this->stream());
538 if ((events & SE_OPEN)) {
539 LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent SE_OPEN";
540 if (state_ != SSL_WAIT) {
541 ASSERT(state_ == SSL_NONE);
542 events_to_signal |= SE_OPEN;
543 } else {
544 state_ = SSL_CONNECTING;
545 if (int err = BeginSSL()) {
546 Error("BeginSSL", err, true);
547 return;
548 }
549 }
550 }
551 if ((events & (SE_READ|SE_WRITE))) {
552 LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent"
553 << ((events & SE_READ) ? " SE_READ" : "")
554 << ((events & SE_WRITE) ? " SE_WRITE" : "");
555 if (state_ == SSL_NONE) {
556 events_to_signal |= events & (SE_READ|SE_WRITE);
557 } else if (state_ == SSL_CONNECTING) {
558 if (int err = ContinueSSL()) {
559 Error("ContinueSSL", err, true);
560 return;
561 }
562 } else if (state_ == SSL_CONNECTED) {
563 if (((events & SE_READ) && ssl_write_needs_read_) ||
564 (events & SE_WRITE)) {
565 LOG(LS_VERBOSE) << " -- onStreamWriteable";
566 events_to_signal |= SE_WRITE;
567 }
568 if (((events & SE_WRITE) && ssl_read_needs_write_) ||
569 (events & SE_READ)) {
570 LOG(LS_VERBOSE) << " -- onStreamReadable";
571 events_to_signal |= SE_READ;
572 }
573 }
574 }
575 if ((events & SE_CLOSE)) {
576 LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent(SE_CLOSE, " << err << ")";
577 Cleanup();
578 events_to_signal |= SE_CLOSE;
579 // SE_CLOSE is the only event that uses the final parameter to OnEvent().
580 ASSERT(signal_error == 0);
581 signal_error = err;
582 }
583 if (events_to_signal)
584 StreamAdapterInterface::OnEvent(stream, events_to_signal, signal_error);
585}
586
587int OpenSSLStreamAdapter::StartSSL() {
588 ASSERT(state_ == SSL_NONE);
589
590 if (StreamAdapterInterface::GetState() != SS_OPEN) {
591 state_ = SSL_WAIT;
592 return 0;
593 }
594
595 state_ = SSL_CONNECTING;
596 if (int err = BeginSSL()) {
597 Error("BeginSSL", err, false);
598 return err;
599 }
600
601 return 0;
602}
603
604int OpenSSLStreamAdapter::BeginSSL() {
605 ASSERT(state_ == SSL_CONNECTING);
606 // The underlying stream has open. If we are in peer-to-peer mode
607 // then a peer certificate must have been specified by now.
608 ASSERT(!ssl_server_name_.empty() ||
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000609 !peer_certificate_digest_algorithm_.empty());
610 LOG(LS_INFO) << "BeginSSL: "
611 << (!ssl_server_name_.empty() ? ssl_server_name_ :
612 "with peer");
613
614 BIO* bio = NULL;
615
616 // First set up the context
617 ASSERT(ssl_ctx_ == NULL);
618 ssl_ctx_ = SetupSSLContext();
619 if (!ssl_ctx_)
620 return -1;
621
622 bio = BIO_new_stream(static_cast<StreamInterface*>(stream()));
623 if (!bio)
624 return -1;
625
626 ssl_ = SSL_new(ssl_ctx_);
627 if (!ssl_) {
628 BIO_free(bio);
629 return -1;
630 }
631
632 SSL_set_app_data(ssl_, this);
633
634 SSL_set_bio(ssl_, bio, bio); // the SSL object owns the bio now.
635
636 SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE |
637 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
638
639 // Do the connect
640 return ContinueSSL();
641}
642
643int OpenSSLStreamAdapter::ContinueSSL() {
644 LOG(LS_VERBOSE) << "ContinueSSL";
645 ASSERT(state_ == SSL_CONNECTING);
646
647 // Clear the DTLS timer
648 Thread::Current()->Clear(this, MSG_TIMEOUT);
649
650 int code = (role_ == SSL_CLIENT) ? SSL_connect(ssl_) : SSL_accept(ssl_);
651 int ssl_error;
652 switch (ssl_error = SSL_get_error(ssl_, code)) {
653 case SSL_ERROR_NONE:
654 LOG(LS_VERBOSE) << " -- success";
655
wu@webrtc.orgf6d6ed02014-01-03 22:08:47 +0000656 if (!SSLPostConnectionCheck(ssl_, ssl_server_name_.c_str(), NULL,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000657 peer_certificate_digest_algorithm_)) {
658 LOG(LS_ERROR) << "TLS post connection check failed";
659 return -1;
660 }
661
662 state_ = SSL_CONNECTED;
663 StreamAdapterInterface::OnEvent(stream(), SE_OPEN|SE_READ|SE_WRITE, 0);
664 break;
665
666 case SSL_ERROR_WANT_READ: {
667 LOG(LS_VERBOSE) << " -- error want read";
wu@webrtc.org0de29502014-02-13 19:54:28 +0000668#ifdef HAVE_DTLS
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000669 struct timeval timeout;
670 if (DTLSv1_get_timeout(ssl_, &timeout)) {
671 int delay = timeout.tv_sec * 1000 + timeout.tv_usec/1000;
672
673 Thread::Current()->PostDelayed(delay, this, MSG_TIMEOUT, 0);
674 }
wu@webrtc.org0de29502014-02-13 19:54:28 +0000675#endif
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000676 }
677 break;
678
679 case SSL_ERROR_WANT_WRITE:
680 LOG(LS_VERBOSE) << " -- error want write";
681 break;
682
683 case SSL_ERROR_ZERO_RETURN:
684 default:
685 LOG(LS_VERBOSE) << " -- error " << code;
686 return (ssl_error != 0) ? ssl_error : -1;
687 }
688
689 return 0;
690}
691
692void OpenSSLStreamAdapter::Error(const char* context, int err, bool signal) {
693 LOG(LS_WARNING) << "OpenSSLStreamAdapter::Error("
694 << context << ", " << err << ")";
695 state_ = SSL_ERROR;
696 ssl_error_code_ = err;
697 Cleanup();
698 if (signal)
699 StreamAdapterInterface::OnEvent(stream(), SE_CLOSE, err);
700}
701
702void OpenSSLStreamAdapter::Cleanup() {
703 LOG(LS_INFO) << "Cleanup";
704
705 if (state_ != SSL_ERROR) {
706 state_ = SSL_CLOSED;
707 ssl_error_code_ = 0;
708 }
709
710 if (ssl_) {
711 SSL_free(ssl_);
712 ssl_ = NULL;
713 }
714 if (ssl_ctx_) {
715 SSL_CTX_free(ssl_ctx_);
716 ssl_ctx_ = NULL;
717 }
718 identity_.reset();
719 peer_certificate_.reset();
720
721 // Clear the DTLS timer
722 Thread::Current()->Clear(this, MSG_TIMEOUT);
723}
724
725
726void OpenSSLStreamAdapter::OnMessage(Message* msg) {
727 // Process our own messages and then pass others to the superclass
728 if (MSG_TIMEOUT == msg->message_id) {
729 LOG(LS_INFO) << "DTLS timeout expired";
wu@webrtc.org0de29502014-02-13 19:54:28 +0000730#ifdef HAVE_DTLS
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000731 DTLSv1_handle_timeout(ssl_);
wu@webrtc.org0de29502014-02-13 19:54:28 +0000732#endif
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000733 ContinueSSL();
734 } else {
735 StreamInterface::OnMessage(msg);
736 }
737}
738
739SSL_CTX* OpenSSLStreamAdapter::SetupSSLContext() {
740 SSL_CTX *ctx = NULL;
741
742 if (role_ == SSL_CLIENT) {
wu@webrtc.org0de29502014-02-13 19:54:28 +0000743#ifdef HAVE_DTLS
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000744 ctx = SSL_CTX_new(ssl_mode_ == SSL_MODE_DTLS ?
745 DTLSv1_client_method() : TLSv1_client_method());
wu@webrtc.org0de29502014-02-13 19:54:28 +0000746#else
747 ctx = SSL_CTX_new(TLSv1_client_method());
748#endif
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000749 } else {
wu@webrtc.org0de29502014-02-13 19:54:28 +0000750#ifdef HAVE_DTLS
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000751 ctx = SSL_CTX_new(ssl_mode_ == SSL_MODE_DTLS ?
752 DTLSv1_server_method() : TLSv1_server_method());
wu@webrtc.org0de29502014-02-13 19:54:28 +0000753#else
754 ctx = SSL_CTX_new(TLSv1_server_method());
755#endif
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000756 }
757 if (ctx == NULL)
758 return NULL;
759
760 if (identity_ && !identity_->ConfigureIdentity(ctx)) {
761 SSL_CTX_free(ctx);
762 return NULL;
763 }
764
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000765#ifdef _DEBUG
766 SSL_CTX_set_info_callback(ctx, OpenSSLAdapter::SSLInfoCallback);
767#endif
768
769 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER |SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
770 SSLVerifyCallback);
771 SSL_CTX_set_verify_depth(ctx, 4);
772 SSL_CTX_set_cipher_list(ctx, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
773
wu@webrtc.org0de29502014-02-13 19:54:28 +0000774#ifdef HAVE_DTLS_SRTP
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000775 if (!srtp_ciphers_.empty()) {
776 if (SSL_CTX_set_tlsext_use_srtp(ctx, srtp_ciphers_.c_str())) {
777 SSL_CTX_free(ctx);
778 return NULL;
779 }
780 }
wu@webrtc.org0de29502014-02-13 19:54:28 +0000781#endif
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000782
783 return ctx;
784}
785
786int OpenSSLStreamAdapter::SSLVerifyCallback(int ok, X509_STORE_CTX* store) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000787 // Get our SSL structure from the store
788 SSL* ssl = reinterpret_cast<SSL*>(X509_STORE_CTX_get_ex_data(
789 store,
790 SSL_get_ex_data_X509_STORE_CTX_idx()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000791 OpenSSLStreamAdapter* stream =
792 reinterpret_cast<OpenSSLStreamAdapter*>(SSL_get_app_data(ssl));
793
wu@webrtc.orgf6d6ed02014-01-03 22:08:47 +0000794 if (stream->peer_certificate_digest_algorithm_.empty()) {
795 return 0;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000796 }
wu@webrtc.orgf6d6ed02014-01-03 22:08:47 +0000797 X509* cert = X509_STORE_CTX_get_current_cert(store);
798 unsigned char digest[EVP_MAX_MD_SIZE];
799 std::size_t digest_length;
800 if (!OpenSSLCertificate::ComputeDigest(
801 cert,
802 stream->peer_certificate_digest_algorithm_,
803 digest, sizeof(digest),
804 &digest_length)) {
805 LOG(LS_WARNING) << "Failed to compute peer cert digest.";
806 return 0;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000807 }
wu@webrtc.orgf6d6ed02014-01-03 22:08:47 +0000808 Buffer computed_digest(digest, digest_length);
809 if (computed_digest != stream->peer_certificate_digest_value_) {
810 LOG(LS_WARNING) << "Rejected peer certificate due to mismatched digest.";
811 return 0;
812 }
813 // Ignore any verification error if the digest matches, since there is no
814 // value in checking the validity of a self-signed cert issued by untrusted
815 // sources.
816 LOG(LS_INFO) << "Accepted peer certificate.";
817 // Record the peer's certificate.
818 stream->peer_certificate_.reset(new OpenSSLCertificate(cert));
819 return 1;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000820}
821
822// This code is taken from the "Network Security with OpenSSL"
823// sample in chapter 5
824bool OpenSSLStreamAdapter::SSLPostConnectionCheck(SSL* ssl,
825 const char* server_name,
826 const X509* peer_cert,
827 const std::string
828 &peer_digest) {
829 ASSERT(server_name != NULL);
830 bool ok;
831 if (server_name[0] != '\0') { // traditional mode
832 ok = OpenSSLAdapter::VerifyServerName(ssl, server_name, ignore_bad_cert());
833
834 if (ok) {
835 ok = (SSL_get_verify_result(ssl) == X509_V_OK ||
836 custom_verification_succeeded_);
837 }
838 } else { // peer-to-peer mode
839 ASSERT((peer_cert != NULL) || (!peer_digest.empty()));
840 // no server name validation
841 ok = true;
842 }
843
844 if (!ok && ignore_bad_cert()) {
845 LOG(LS_ERROR) << "SSL_get_verify_result(ssl) = "
846 << SSL_get_verify_result(ssl);
847 LOG(LS_INFO) << "Other TLS post connection checks failed.";
848 ok = true;
849 }
850
851 return ok;
852}
853
854bool OpenSSLStreamAdapter::HaveDtls() {
wu@webrtc.org0de29502014-02-13 19:54:28 +0000855#ifdef HAVE_DTLS
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000856 return true;
wu@webrtc.org0de29502014-02-13 19:54:28 +0000857#else
858 return false;
859#endif
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000860}
861
862bool OpenSSLStreamAdapter::HaveDtlsSrtp() {
wu@webrtc.org0de29502014-02-13 19:54:28 +0000863#ifdef HAVE_DTLS_SRTP
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000864 return true;
wu@webrtc.org0de29502014-02-13 19:54:28 +0000865#else
866 return false;
867#endif
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000868}
869
870bool OpenSSLStreamAdapter::HaveExporter() {
wu@webrtc.org0de29502014-02-13 19:54:28 +0000871#ifdef HAVE_DTLS_SRTP
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000872 return true;
wu@webrtc.org0de29502014-02-13 19:54:28 +0000873#else
874 return false;
875#endif
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000876}
877
878} // namespace talk_base
879
880#endif // HAVE_OPENSSL_SSL_H