/* * libjingle * Copyright 2015 Google Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef TALK_APP_WEBRTC_DTLSIDENTITYSTORE_H_ #define TALK_APP_WEBRTC_DTLSIDENTITYSTORE_H_ #include #include #include #include "webrtc/base/messagehandler.h" #include "webrtc/base/messagequeue.h" #include "webrtc/base/refcount.h" #include "webrtc/base/scoped_ptr.h" #include "webrtc/base/scoped_ref_ptr.h" #include "webrtc/base/sslidentity.h" #include "webrtc/base/thread.h" namespace webrtc { // Passed to SSLIdentity::Generate. extern const char kIdentityName[]; class SSLIdentity; class Thread; // Used to receive callbacks of DTLS identity requests. class DtlsIdentityRequestObserver : public rtc::RefCountInterface { public: virtual void OnFailure(int error) = 0; // TODO(hbos): Unify the OnSuccess method once Chrome code is updated. virtual void OnSuccess(const std::string& der_cert, const std::string& der_private_key) = 0; // |identity| is a scoped_ptr because rtc::SSLIdentity is not copyable and the // client has to get the ownership of the object to make use of it. virtual void OnSuccess(rtc::scoped_ptr identity) = 0; protected: virtual ~DtlsIdentityRequestObserver() {} }; // This interface defines an in-memory DTLS identity store, which generates DTLS // identities. // APIs calls must be made on the signaling thread and the callbacks are also // called on the signaling thread. class DtlsIdentityStoreInterface { public: virtual ~DtlsIdentityStoreInterface() { } // The |observer| will be called when the requested identity is ready, or when // identity generation fails. // TODO(torbjorng,hbos): The following RequestIdentity is about to be removed, // see below todo. virtual void RequestIdentity( rtc::KeyType key_type, const rtc::scoped_refptr& observer) { // Add default parameterization. RequestIdentity(rtc::KeyParams(key_type), observer); } // TODO(torbjorng,hbos): Parameterized key types! The following // RequestIdentity should replace the old one that takes rtc::KeyType. When // the new one is implemented by Chromium and WebRTC the old one should be // removed. crbug.com/544902, webrtc:5092. virtual void RequestIdentity( rtc::KeyParams key_params, const rtc::scoped_refptr& observer) { // Drop parameterization. RequestIdentity(key_params.type(), observer); } }; // The WebRTC default implementation of DtlsIdentityStoreInterface. // Identity generation is performed on the worker thread. class DtlsIdentityStoreImpl : public DtlsIdentityStoreInterface, public rtc::MessageHandler { public: // This will start to preemptively generating an RSA identity in the // background if the worker thread is not the same as the signaling thread. DtlsIdentityStoreImpl(rtc::Thread* signaling_thread, rtc::Thread* worker_thread); ~DtlsIdentityStoreImpl() override; // DtlsIdentityStoreInterface override; void RequestIdentity( rtc::KeyType key_type, const rtc::scoped_refptr& observer) override; // rtc::MessageHandler override; void OnMessage(rtc::Message* msg) override; // Returns true if there is a free RSA identity, used for unit tests. bool HasFreeIdentityForTesting(rtc::KeyType key_type) const; private: void GenerateIdentity( rtc::KeyType key_type, const rtc::scoped_refptr& observer); void OnIdentityGenerated(rtc::KeyType key_type, rtc::scoped_ptr identity); class WorkerTask; typedef rtc::ScopedMessageData WorkerTaskMessageData; // A key type-identity pair. struct IdentityResult { IdentityResult(rtc::KeyType key_type, rtc::scoped_ptr identity) : key_type_(key_type), identity_(std::move(identity)) {} rtc::KeyType key_type_; rtc::scoped_ptr identity_; }; typedef rtc::ScopedMessageData IdentityResultMessageData; sigslot::signal0<> SignalDestroyed; rtc::Thread* const signaling_thread_; // TODO(hbos): RSA generation is slow and would be VERY slow if we switch over // to 2048, DtlsIdentityStore should use a new thread and not the "general // purpose" worker thread. rtc::Thread* const worker_thread_; struct RequestInfo { RequestInfo() : request_observers_(), gen_in_progress_counts_(0), free_identity_() {} std::queue> request_observers_; size_t gen_in_progress_counts_; rtc::scoped_ptr free_identity_; }; // One RequestInfo per KeyType. Only touch on the |signaling_thread_|. RequestInfo request_info_[rtc::KT_LAST]; }; } // namespace webrtc #endif // TALK_APP_WEBRTC_DTLSIDENTITYSTORE_H_