blob: cafef9266edd864ba39860c0fe01a30275bcbbc9 [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>
henrike@webrtc.org28e20752013-07-10 00:45:36 +000040#include <openssl/x509v3.h>
41
42#include <vector>
43
44#include "talk/base/common.h"
45#include "talk/base/logging.h"
46#include "talk/base/stream.h"
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +000047#include "talk/base/openssl.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000048#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
henrike@webrtc.org28e20752013-07-10 00:45:36 +000056// SRTP cipher suite table
57struct SrtpCipherMapEntry {
58 const char* external_name;
59 const char* internal_name;
60};
61
62// This isn't elegant, but it's better than an external reference
63static SrtpCipherMapEntry SrtpCipherMap[] = {
64 {"AES_CM_128_HMAC_SHA1_80", "SRTP_AES128_CM_SHA1_80"},
65 {"AES_CM_128_HMAC_SHA1_32", "SRTP_AES128_CM_SHA1_32"},
66 {NULL, NULL}
67};
henrike@webrtc.org28e20752013-07-10 00:45:36 +000068
69//////////////////////////////////////////////////////////////////////
70// StreamBIO
71//////////////////////////////////////////////////////////////////////
72
73static int stream_write(BIO* h, const char* buf, int num);
74static int stream_read(BIO* h, char* buf, int size);
75static int stream_puts(BIO* h, const char* str);
76static long stream_ctrl(BIO* h, int cmd, long arg1, void* arg2);
77static int stream_new(BIO* h);
78static int stream_free(BIO* data);
79
80static BIO_METHOD methods_stream = {
81 BIO_TYPE_BIO,
82 "stream",
83 stream_write,
84 stream_read,
85 stream_puts,
86 0,
87 stream_ctrl,
88 stream_new,
89 stream_free,
90 NULL,
91};
92
93static BIO_METHOD* BIO_s_stream() { return(&methods_stream); }
94
95static BIO* BIO_new_stream(StreamInterface* stream) {
96 BIO* ret = BIO_new(BIO_s_stream());
97 if (ret == NULL)
98 return NULL;
99 ret->ptr = stream;
100 return ret;
101}
102
103// bio methods return 1 (or at least non-zero) on success and 0 on failure.
104
105static int stream_new(BIO* b) {
106 b->shutdown = 0;
107 b->init = 1;
108 b->num = 0; // 1 means end-of-stream
109 b->ptr = 0;
110 return 1;
111}
112
113static int stream_free(BIO* b) {
114 if (b == NULL)
115 return 0;
116 return 1;
117}
118
119static int stream_read(BIO* b, char* out, int outl) {
120 if (!out)
121 return -1;
122 StreamInterface* stream = static_cast<StreamInterface*>(b->ptr);
123 BIO_clear_retry_flags(b);
124 size_t read;
125 int error;
126 StreamResult result = stream->Read(out, outl, &read, &error);
127 if (result == SR_SUCCESS) {
128 return read;
129 } else if (result == SR_EOS) {
130 b->num = 1;
131 } else if (result == SR_BLOCK) {
132 BIO_set_retry_read(b);
133 }
134 return -1;
135}
136
137static int stream_write(BIO* b, const char* in, int inl) {
138 if (!in)
139 return -1;
140 StreamInterface* stream = static_cast<StreamInterface*>(b->ptr);
141 BIO_clear_retry_flags(b);
142 size_t written;
143 int error;
144 StreamResult result = stream->Write(in, inl, &written, &error);
145 if (result == SR_SUCCESS) {
146 return written;
147 } else if (result == SR_BLOCK) {
148 BIO_set_retry_write(b);
149 }
150 return -1;
151}
152
153static int stream_puts(BIO* b, const char* str) {
154 return stream_write(b, str, strlen(str));
155}
156
157static long stream_ctrl(BIO* b, int cmd, long num, void* ptr) {
158 UNUSED(num);
159 UNUSED(ptr);
160
161 switch (cmd) {
162 case BIO_CTRL_RESET:
163 return 0;
164 case BIO_CTRL_EOF:
165 return b->num;
166 case BIO_CTRL_WPENDING:
167 case BIO_CTRL_PENDING:
168 return 0;
169 case BIO_CTRL_FLUSH:
170 return 1;
171 default:
172 return 0;
173 }
174}
175
176/////////////////////////////////////////////////////////////////////////////
177// OpenSSLStreamAdapter
178/////////////////////////////////////////////////////////////////////////////
179
180OpenSSLStreamAdapter::OpenSSLStreamAdapter(StreamInterface* stream)
181 : SSLStreamAdapter(stream),
182 state_(SSL_NONE),
183 role_(SSL_CLIENT),
184 ssl_read_needs_write_(false), ssl_write_needs_read_(false),
185 ssl_(NULL), ssl_ctx_(NULL),
186 custom_verification_succeeded_(false),
187 ssl_mode_(SSL_MODE_TLS) {
188}
189
190OpenSSLStreamAdapter::~OpenSSLStreamAdapter() {
191 Cleanup();
192}
193
194void OpenSSLStreamAdapter::SetIdentity(SSLIdentity* identity) {
195 ASSERT(!identity_);
196 identity_.reset(static_cast<OpenSSLIdentity*>(identity));
197}
198
199void OpenSSLStreamAdapter::SetServerRole(SSLRole role) {
200 role_ = role;
201}
202
wu@webrtc.org4551b792013-10-09 15:37:36 +0000203bool OpenSSLStreamAdapter::GetPeerCertificate(SSLCertificate** cert) const {
204 if (!peer_certificate_)
205 return false;
206
207 *cert = peer_certificate_->GetReference();
208 return true;
209}
210
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000211bool OpenSSLStreamAdapter::SetPeerCertificateDigest(const std::string
212 &digest_alg,
213 const unsigned char*
214 digest_val,
215 size_t digest_len) {
216 ASSERT(!peer_certificate_);
217 ASSERT(peer_certificate_digest_algorithm_.size() == 0);
218 ASSERT(ssl_server_name_.empty());
219 size_t expected_len;
220
221 if (!OpenSSLDigest::GetDigestSize(digest_alg, &expected_len)) {
222 LOG(LS_WARNING) << "Unknown digest algorithm: " << digest_alg;
223 return false;
224 }
225 if (expected_len != digest_len)
226 return false;
227
228 peer_certificate_digest_value_.SetData(digest_val, digest_len);
229 peer_certificate_digest_algorithm_ = digest_alg;
230
231 return true;
232}
233
234// Key Extractor interface
235bool OpenSSLStreamAdapter::ExportKeyingMaterial(const std::string& label,
236 const uint8* context,
237 size_t context_len,
238 bool use_context,
239 uint8* result,
240 size_t result_len) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000241 int i;
242
243 i = SSL_export_keying_material(ssl_, result, result_len,
244 label.c_str(), label.length(),
245 const_cast<uint8 *>(context),
246 context_len, use_context);
247
248 if (i != 1)
249 return false;
250
251 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000252}
253
254bool OpenSSLStreamAdapter::SetDtlsSrtpCiphers(
255 const std::vector<std::string>& ciphers) {
256 std::string internal_ciphers;
257
258 if (state_ != SSL_NONE)
259 return false;
260
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000261 for (std::vector<std::string>::const_iterator cipher = ciphers.begin();
262 cipher != ciphers.end(); ++cipher) {
263 bool found = false;
264 for (SrtpCipherMapEntry *entry = SrtpCipherMap; entry->internal_name;
265 ++entry) {
266 if (*cipher == entry->external_name) {
267 found = true;
268 if (!internal_ciphers.empty())
269 internal_ciphers += ":";
270 internal_ciphers += entry->internal_name;
271 break;
272 }
273 }
274
275 if (!found) {
276 LOG(LS_ERROR) << "Could not find cipher: " << *cipher;
277 return false;
278 }
279 }
280
281 if (internal_ciphers.empty())
282 return false;
283
284 srtp_ciphers_ = internal_ciphers;
285 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000286}
287
288bool OpenSSLStreamAdapter::GetDtlsSrtpCipher(std::string* cipher) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000289 ASSERT(state_ == SSL_CONNECTED);
290 if (state_ != SSL_CONNECTED)
291 return false;
292
293 SRTP_PROTECTION_PROFILE *srtp_profile =
294 SSL_get_selected_srtp_profile(ssl_);
295
296 if (!srtp_profile)
297 return false;
298
299 for (SrtpCipherMapEntry *entry = SrtpCipherMap;
300 entry->internal_name; ++entry) {
301 if (!strcmp(entry->internal_name, srtp_profile->name)) {
302 *cipher = entry->external_name;
303 return true;
304 }
305 }
306
307 ASSERT(false); // This should never happen
308
309 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000310}
311
312int OpenSSLStreamAdapter::StartSSLWithServer(const char* server_name) {
313 ASSERT(server_name != NULL && server_name[0] != '\0');
314 ssl_server_name_ = server_name;
315 return StartSSL();
316}
317
318int OpenSSLStreamAdapter::StartSSLWithPeer() {
319 ASSERT(ssl_server_name_.empty());
320 // It is permitted to specify peer_certificate_ only later.
321 return StartSSL();
322}
323
324void OpenSSLStreamAdapter::SetMode(SSLMode mode) {
325 ASSERT(state_ == SSL_NONE);
326 ssl_mode_ = mode;
327}
328
329//
330// StreamInterface Implementation
331//
332
333StreamResult OpenSSLStreamAdapter::Write(const void* data, size_t data_len,
334 size_t* written, int* error) {
335 LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::Write(" << data_len << ")";
336
337 switch (state_) {
338 case SSL_NONE:
339 // pass-through in clear text
340 return StreamAdapterInterface::Write(data, data_len, written, error);
341
342 case SSL_WAIT:
343 case SSL_CONNECTING:
344 return SR_BLOCK;
345
346 case SSL_CONNECTED:
347 break;
348
349 case SSL_ERROR:
350 case SSL_CLOSED:
351 default:
352 if (error)
353 *error = ssl_error_code_;
354 return SR_ERROR;
355 }
356
357 // OpenSSL will return an error if we try to write zero bytes
358 if (data_len == 0) {
359 if (written)
360 *written = 0;
361 return SR_SUCCESS;
362 }
363
364 ssl_write_needs_read_ = false;
365
366 int code = SSL_write(ssl_, data, data_len);
367 int ssl_error = SSL_get_error(ssl_, code);
368 switch (ssl_error) {
369 case SSL_ERROR_NONE:
370 LOG(LS_VERBOSE) << " -- success";
371 ASSERT(0 < code && static_cast<unsigned>(code) <= data_len);
372 if (written)
373 *written = code;
374 return SR_SUCCESS;
375 case SSL_ERROR_WANT_READ:
376 LOG(LS_VERBOSE) << " -- error want read";
377 ssl_write_needs_read_ = true;
378 return SR_BLOCK;
379 case SSL_ERROR_WANT_WRITE:
380 LOG(LS_VERBOSE) << " -- error want write";
381 return SR_BLOCK;
382
383 case SSL_ERROR_ZERO_RETURN:
384 default:
385 Error("SSL_write", (ssl_error ? ssl_error : -1), false);
386 if (error)
387 *error = ssl_error_code_;
388 return SR_ERROR;
389 }
390 // not reached
391}
392
393StreamResult OpenSSLStreamAdapter::Read(void* data, size_t data_len,
394 size_t* read, int* error) {
395 LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::Read(" << data_len << ")";
396 switch (state_) {
397 case SSL_NONE:
398 // pass-through in clear text
399 return StreamAdapterInterface::Read(data, data_len, read, error);
400
401 case SSL_WAIT:
402 case SSL_CONNECTING:
403 return SR_BLOCK;
404
405 case SSL_CONNECTED:
406 break;
407
408 case SSL_CLOSED:
409 return SR_EOS;
410
411 case SSL_ERROR:
412 default:
413 if (error)
414 *error = ssl_error_code_;
415 return SR_ERROR;
416 }
417
418 // Don't trust OpenSSL with zero byte reads
419 if (data_len == 0) {
420 if (read)
421 *read = 0;
422 return SR_SUCCESS;
423 }
424
425 ssl_read_needs_write_ = false;
426
427 int code = SSL_read(ssl_, data, data_len);
428 int ssl_error = SSL_get_error(ssl_, code);
429 switch (ssl_error) {
430 case SSL_ERROR_NONE:
431 LOG(LS_VERBOSE) << " -- success";
432 ASSERT(0 < code && static_cast<unsigned>(code) <= data_len);
433 if (read)
434 *read = code;
435
436 if (ssl_mode_ == SSL_MODE_DTLS) {
437 // Enforce atomic reads -- this is a short read
438 unsigned int pending = SSL_pending(ssl_);
439
440 if (pending) {
441 LOG(LS_INFO) << " -- short DTLS read. flushing";
442 FlushInput(pending);
443 if (error)
444 *error = SSE_MSG_TRUNC;
445 return SR_ERROR;
446 }
447 }
448 return SR_SUCCESS;
449 case SSL_ERROR_WANT_READ:
450 LOG(LS_VERBOSE) << " -- error want read";
451 return SR_BLOCK;
452 case SSL_ERROR_WANT_WRITE:
453 LOG(LS_VERBOSE) << " -- error want write";
454 ssl_read_needs_write_ = true;
455 return SR_BLOCK;
456 case SSL_ERROR_ZERO_RETURN:
457 LOG(LS_VERBOSE) << " -- remote side closed";
458 return SR_EOS;
459 break;
460 default:
461 LOG(LS_VERBOSE) << " -- error " << code;
462 Error("SSL_read", (ssl_error ? ssl_error : -1), false);
463 if (error)
464 *error = ssl_error_code_;
465 return SR_ERROR;
466 }
467 // not reached
468}
469
470void OpenSSLStreamAdapter::FlushInput(unsigned int left) {
471 unsigned char buf[2048];
472
473 while (left) {
474 // This should always succeed
475 int toread = (sizeof(buf) < left) ? sizeof(buf) : left;
476 int code = SSL_read(ssl_, buf, toread);
477
478 int ssl_error = SSL_get_error(ssl_, code);
479 ASSERT(ssl_error == SSL_ERROR_NONE);
480
481 if (ssl_error != SSL_ERROR_NONE) {
482 LOG(LS_VERBOSE) << " -- error " << code;
483 Error("SSL_read", (ssl_error ? ssl_error : -1), false);
484 return;
485 }
486
487 LOG(LS_VERBOSE) << " -- flushed " << code << " bytes";
488 left -= code;
489 }
490}
491
492void OpenSSLStreamAdapter::Close() {
493 Cleanup();
494 ASSERT(state_ == SSL_CLOSED || state_ == SSL_ERROR);
495 StreamAdapterInterface::Close();
496}
497
498StreamState OpenSSLStreamAdapter::GetState() const {
499 switch (state_) {
500 case SSL_WAIT:
501 case SSL_CONNECTING:
502 return SS_OPENING;
503 case SSL_CONNECTED:
504 return SS_OPEN;
505 default:
506 return SS_CLOSED;
507 };
508 // not reached
509}
510
511void OpenSSLStreamAdapter::OnEvent(StreamInterface* stream, int events,
512 int err) {
513 int events_to_signal = 0;
514 int signal_error = 0;
515 ASSERT(stream == this->stream());
516 if ((events & SE_OPEN)) {
517 LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent SE_OPEN";
518 if (state_ != SSL_WAIT) {
519 ASSERT(state_ == SSL_NONE);
520 events_to_signal |= SE_OPEN;
521 } else {
522 state_ = SSL_CONNECTING;
523 if (int err = BeginSSL()) {
524 Error("BeginSSL", err, true);
525 return;
526 }
527 }
528 }
529 if ((events & (SE_READ|SE_WRITE))) {
530 LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent"
531 << ((events & SE_READ) ? " SE_READ" : "")
532 << ((events & SE_WRITE) ? " SE_WRITE" : "");
533 if (state_ == SSL_NONE) {
534 events_to_signal |= events & (SE_READ|SE_WRITE);
535 } else if (state_ == SSL_CONNECTING) {
536 if (int err = ContinueSSL()) {
537 Error("ContinueSSL", err, true);
538 return;
539 }
540 } else if (state_ == SSL_CONNECTED) {
541 if (((events & SE_READ) && ssl_write_needs_read_) ||
542 (events & SE_WRITE)) {
543 LOG(LS_VERBOSE) << " -- onStreamWriteable";
544 events_to_signal |= SE_WRITE;
545 }
546 if (((events & SE_WRITE) && ssl_read_needs_write_) ||
547 (events & SE_READ)) {
548 LOG(LS_VERBOSE) << " -- onStreamReadable";
549 events_to_signal |= SE_READ;
550 }
551 }
552 }
553 if ((events & SE_CLOSE)) {
554 LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent(SE_CLOSE, " << err << ")";
555 Cleanup();
556 events_to_signal |= SE_CLOSE;
557 // SE_CLOSE is the only event that uses the final parameter to OnEvent().
558 ASSERT(signal_error == 0);
559 signal_error = err;
560 }
561 if (events_to_signal)
562 StreamAdapterInterface::OnEvent(stream, events_to_signal, signal_error);
563}
564
565int OpenSSLStreamAdapter::StartSSL() {
566 ASSERT(state_ == SSL_NONE);
567
568 if (StreamAdapterInterface::GetState() != SS_OPEN) {
569 state_ = SSL_WAIT;
570 return 0;
571 }
572
573 state_ = SSL_CONNECTING;
574 if (int err = BeginSSL()) {
575 Error("BeginSSL", err, false);
576 return err;
577 }
578
579 return 0;
580}
581
582int OpenSSLStreamAdapter::BeginSSL() {
583 ASSERT(state_ == SSL_CONNECTING);
584 // The underlying stream has open. If we are in peer-to-peer mode
585 // then a peer certificate must have been specified by now.
586 ASSERT(!ssl_server_name_.empty() ||
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000587 !peer_certificate_digest_algorithm_.empty());
588 LOG(LS_INFO) << "BeginSSL: "
589 << (!ssl_server_name_.empty() ? ssl_server_name_ :
590 "with peer");
591
592 BIO* bio = NULL;
593
594 // First set up the context
595 ASSERT(ssl_ctx_ == NULL);
596 ssl_ctx_ = SetupSSLContext();
597 if (!ssl_ctx_)
598 return -1;
599
600 bio = BIO_new_stream(static_cast<StreamInterface*>(stream()));
601 if (!bio)
602 return -1;
603
604 ssl_ = SSL_new(ssl_ctx_);
605 if (!ssl_) {
606 BIO_free(bio);
607 return -1;
608 }
609
610 SSL_set_app_data(ssl_, this);
611
612 SSL_set_bio(ssl_, bio, bio); // the SSL object owns the bio now.
613
614 SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE |
615 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
616
617 // Do the connect
618 return ContinueSSL();
619}
620
621int OpenSSLStreamAdapter::ContinueSSL() {
622 LOG(LS_VERBOSE) << "ContinueSSL";
623 ASSERT(state_ == SSL_CONNECTING);
624
625 // Clear the DTLS timer
626 Thread::Current()->Clear(this, MSG_TIMEOUT);
627
628 int code = (role_ == SSL_CLIENT) ? SSL_connect(ssl_) : SSL_accept(ssl_);
629 int ssl_error;
630 switch (ssl_error = SSL_get_error(ssl_, code)) {
631 case SSL_ERROR_NONE:
632 LOG(LS_VERBOSE) << " -- success";
633
wu@webrtc.orgf6d6ed02014-01-03 22:08:47 +0000634 if (!SSLPostConnectionCheck(ssl_, ssl_server_name_.c_str(), NULL,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000635 peer_certificate_digest_algorithm_)) {
636 LOG(LS_ERROR) << "TLS post connection check failed";
637 return -1;
638 }
639
640 state_ = SSL_CONNECTED;
641 StreamAdapterInterface::OnEvent(stream(), SE_OPEN|SE_READ|SE_WRITE, 0);
642 break;
643
644 case SSL_ERROR_WANT_READ: {
645 LOG(LS_VERBOSE) << " -- error want read";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000646 struct timeval timeout;
647 if (DTLSv1_get_timeout(ssl_, &timeout)) {
648 int delay = timeout.tv_sec * 1000 + timeout.tv_usec/1000;
649
650 Thread::Current()->PostDelayed(delay, this, MSG_TIMEOUT, 0);
651 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000652 }
653 break;
654
655 case SSL_ERROR_WANT_WRITE:
656 LOG(LS_VERBOSE) << " -- error want write";
657 break;
658
659 case SSL_ERROR_ZERO_RETURN:
660 default:
661 LOG(LS_VERBOSE) << " -- error " << code;
662 return (ssl_error != 0) ? ssl_error : -1;
663 }
664
665 return 0;
666}
667
668void OpenSSLStreamAdapter::Error(const char* context, int err, bool signal) {
669 LOG(LS_WARNING) << "OpenSSLStreamAdapter::Error("
670 << context << ", " << err << ")";
671 state_ = SSL_ERROR;
672 ssl_error_code_ = err;
673 Cleanup();
674 if (signal)
675 StreamAdapterInterface::OnEvent(stream(), SE_CLOSE, err);
676}
677
678void OpenSSLStreamAdapter::Cleanup() {
679 LOG(LS_INFO) << "Cleanup";
680
681 if (state_ != SSL_ERROR) {
682 state_ = SSL_CLOSED;
683 ssl_error_code_ = 0;
684 }
685
686 if (ssl_) {
687 SSL_free(ssl_);
688 ssl_ = NULL;
689 }
690 if (ssl_ctx_) {
691 SSL_CTX_free(ssl_ctx_);
692 ssl_ctx_ = NULL;
693 }
694 identity_.reset();
695 peer_certificate_.reset();
696
697 // Clear the DTLS timer
698 Thread::Current()->Clear(this, MSG_TIMEOUT);
699}
700
701
702void OpenSSLStreamAdapter::OnMessage(Message* msg) {
703 // Process our own messages and then pass others to the superclass
704 if (MSG_TIMEOUT == msg->message_id) {
705 LOG(LS_INFO) << "DTLS timeout expired";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000706 DTLSv1_handle_timeout(ssl_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000707 ContinueSSL();
708 } else {
709 StreamInterface::OnMessage(msg);
710 }
711}
712
713SSL_CTX* OpenSSLStreamAdapter::SetupSSLContext() {
714 SSL_CTX *ctx = NULL;
715
716 if (role_ == SSL_CLIENT) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000717 ctx = SSL_CTX_new(ssl_mode_ == SSL_MODE_DTLS ?
718 DTLSv1_client_method() : TLSv1_client_method());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000719 } else {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000720 ctx = SSL_CTX_new(ssl_mode_ == SSL_MODE_DTLS ?
721 DTLSv1_server_method() : TLSv1_server_method());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000722 }
723 if (ctx == NULL)
724 return NULL;
725
726 if (identity_ && !identity_->ConfigureIdentity(ctx)) {
727 SSL_CTX_free(ctx);
728 return NULL;
729 }
730
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000731#ifdef _DEBUG
732 SSL_CTX_set_info_callback(ctx, OpenSSLAdapter::SSLInfoCallback);
733#endif
734
735 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER |SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
736 SSLVerifyCallback);
737 SSL_CTX_set_verify_depth(ctx, 4);
738 SSL_CTX_set_cipher_list(ctx, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
739
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000740 if (!srtp_ciphers_.empty()) {
741 if (SSL_CTX_set_tlsext_use_srtp(ctx, srtp_ciphers_.c_str())) {
742 SSL_CTX_free(ctx);
743 return NULL;
744 }
745 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000746
747 return ctx;
748}
749
750int OpenSSLStreamAdapter::SSLVerifyCallback(int ok, X509_STORE_CTX* store) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000751 // Get our SSL structure from the store
752 SSL* ssl = reinterpret_cast<SSL*>(X509_STORE_CTX_get_ex_data(
753 store,
754 SSL_get_ex_data_X509_STORE_CTX_idx()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000755 OpenSSLStreamAdapter* stream =
756 reinterpret_cast<OpenSSLStreamAdapter*>(SSL_get_app_data(ssl));
757
wu@webrtc.orgf6d6ed02014-01-03 22:08:47 +0000758 if (stream->peer_certificate_digest_algorithm_.empty()) {
759 return 0;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000760 }
wu@webrtc.orgf6d6ed02014-01-03 22:08:47 +0000761 X509* cert = X509_STORE_CTX_get_current_cert(store);
762 unsigned char digest[EVP_MAX_MD_SIZE];
763 std::size_t digest_length;
764 if (!OpenSSLCertificate::ComputeDigest(
765 cert,
766 stream->peer_certificate_digest_algorithm_,
767 digest, sizeof(digest),
768 &digest_length)) {
769 LOG(LS_WARNING) << "Failed to compute peer cert digest.";
770 return 0;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000771 }
wu@webrtc.orgf6d6ed02014-01-03 22:08:47 +0000772 Buffer computed_digest(digest, digest_length);
773 if (computed_digest != stream->peer_certificate_digest_value_) {
774 LOG(LS_WARNING) << "Rejected peer certificate due to mismatched digest.";
775 return 0;
776 }
777 // Ignore any verification error if the digest matches, since there is no
778 // value in checking the validity of a self-signed cert issued by untrusted
779 // sources.
780 LOG(LS_INFO) << "Accepted peer certificate.";
781 // Record the peer's certificate.
782 stream->peer_certificate_.reset(new OpenSSLCertificate(cert));
783 return 1;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000784}
785
786// This code is taken from the "Network Security with OpenSSL"
787// sample in chapter 5
788bool OpenSSLStreamAdapter::SSLPostConnectionCheck(SSL* ssl,
789 const char* server_name,
790 const X509* peer_cert,
791 const std::string
792 &peer_digest) {
793 ASSERT(server_name != NULL);
794 bool ok;
795 if (server_name[0] != '\0') { // traditional mode
796 ok = OpenSSLAdapter::VerifyServerName(ssl, server_name, ignore_bad_cert());
797
798 if (ok) {
799 ok = (SSL_get_verify_result(ssl) == X509_V_OK ||
800 custom_verification_succeeded_);
801 }
802 } else { // peer-to-peer mode
803 ASSERT((peer_cert != NULL) || (!peer_digest.empty()));
804 // no server name validation
805 ok = true;
806 }
807
808 if (!ok && ignore_bad_cert()) {
809 LOG(LS_ERROR) << "SSL_get_verify_result(ssl) = "
810 << SSL_get_verify_result(ssl);
811 LOG(LS_INFO) << "Other TLS post connection checks failed.";
812 ok = true;
813 }
814
815 return ok;
816}
817
818bool OpenSSLStreamAdapter::HaveDtls() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000819 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000820}
821
822bool OpenSSLStreamAdapter::HaveDtlsSrtp() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000823 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000824}
825
826bool OpenSSLStreamAdapter::HaveExporter() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000827 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000828}
829
830} // namespace talk_base
831
832#endif // HAVE_OPENSSL_SSL_H