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