blob: 9313b9962c27b367e38761931cfd0b8087ca3482 [file] [log] [blame]
jiayl@webrtc.org25484062015-02-18 23:58:16 +00001/*
2 * libjingle
3 * Copyright 2015 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 */
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +000027
Henrik Kjellander15583c12016-02-10 10:53:12 +010028#ifndef WEBRTC_API_DTLSIDENTITYSTORE_H_
29#define WEBRTC_API_DTLSIDENTITYSTORE_H_
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +000030
31#include <queue>
32#include <string>
kwiberg0eb15ed2015-12-17 03:04:15 -080033#include <utility>
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +000034
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +000035#include "webrtc/base/messagehandler.h"
jiayl@webrtc.orgd83f4ef2015-03-13 21:26:12 +000036#include "webrtc/base/messagequeue.h"
Henrik Boström5b4ce332015-08-05 16:55:22 +020037#include "webrtc/base/refcount.h"
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +000038#include "webrtc/base/scoped_ptr.h"
39#include "webrtc/base/scoped_ref_ptr.h"
Henrik Boström5b4ce332015-08-05 16:55:22 +020040#include "webrtc/base/sslidentity.h"
41#include "webrtc/base/thread.h"
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +000042
43namespace webrtc {
glaznev97579a42015-09-01 11:31:27 -070044
45// Passed to SSLIdentity::Generate.
46extern const char kIdentityName[];
47
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +000048class SSLIdentity;
49class Thread;
50
Henrik Boström5b4ce332015-08-05 16:55:22 +020051// Used to receive callbacks of DTLS identity requests.
Henrik Boström5b4ce332015-08-05 16:55:22 +020052class DtlsIdentityRequestObserver : public rtc::RefCountInterface {
53 public:
54 virtual void OnFailure(int error) = 0;
55 // TODO(hbos): Unify the OnSuccess method once Chrome code is updated.
56 virtual void OnSuccess(const std::string& der_cert,
57 const std::string& der_private_key) = 0;
58 // |identity| is a scoped_ptr because rtc::SSLIdentity is not copyable and the
59 // client has to get the ownership of the object to make use of it.
60 virtual void OnSuccess(rtc::scoped_ptr<rtc::SSLIdentity> identity) = 0;
61
62 protected:
63 virtual ~DtlsIdentityRequestObserver() {}
64};
65
Henrik Boström5b4ce332015-08-05 16:55:22 +020066// This interface defines an in-memory DTLS identity store, which generates DTLS
67// identities.
68// APIs calls must be made on the signaling thread and the callbacks are also
69// called on the signaling thread.
70class DtlsIdentityStoreInterface {
71 public:
72 virtual ~DtlsIdentityStoreInterface() { }
73
Henrik Boström5e56c592015-08-11 10:33:13 +020074 // The |observer| will be called when the requested identity is ready, or when
75 // identity generation fails.
hbos3b7c7932015-10-21 01:44:21 -070076 // TODO(torbjorng,hbos): The following RequestIdentity is about to be removed,
77 // see below todo.
Henrik Boström5b4ce332015-08-05 16:55:22 +020078 virtual void RequestIdentity(
79 rtc::KeyType key_type,
hbos3b7c7932015-10-21 01:44:21 -070080 const rtc::scoped_refptr<DtlsIdentityRequestObserver>& observer) {
81 // Add default parameterization.
82 RequestIdentity(rtc::KeyParams(key_type), observer);
83 }
84 // TODO(torbjorng,hbos): Parameterized key types! The following
85 // RequestIdentity should replace the old one that takes rtc::KeyType. When
86 // the new one is implemented by Chromium and WebRTC the old one should be
87 // removed. crbug.com/544902, webrtc:5092.
88 virtual void RequestIdentity(
89 rtc::KeyParams key_params,
90 const rtc::scoped_refptr<DtlsIdentityRequestObserver>& observer) {
91 // Drop parameterization.
92 RequestIdentity(key_params.type(), observer);
93 }
Henrik Boström5b4ce332015-08-05 16:55:22 +020094};
95
Henrik Boström5e56c592015-08-11 10:33:13 +020096// The WebRTC default implementation of DtlsIdentityStoreInterface.
97// Identity generation is performed on the worker thread.
98class DtlsIdentityStoreImpl : public DtlsIdentityStoreInterface,
99 public rtc::MessageHandler {
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +0000100 public:
Henrik Boström5e56c592015-08-11 10:33:13 +0200101 // This will start to preemptively generating an RSA identity in the
102 // background if the worker thread is not the same as the signaling thread.
103 DtlsIdentityStoreImpl(rtc::Thread* signaling_thread,
104 rtc::Thread* worker_thread);
105 ~DtlsIdentityStoreImpl() override;
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +0000106
Henrik Boström5e56c592015-08-11 10:33:13 +0200107 // DtlsIdentityStoreInterface override;
108 void RequestIdentity(
109 rtc::KeyType key_type,
110 const rtc::scoped_refptr<DtlsIdentityRequestObserver>& observer) override;
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +0000111
112 // rtc::MessageHandler override;
113 void OnMessage(rtc::Message* msg) override;
114
Henrik Boström5e56c592015-08-11 10:33:13 +0200115 // Returns true if there is a free RSA identity, used for unit tests.
116 bool HasFreeIdentityForTesting(rtc::KeyType key_type) const;
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +0000117
118 private:
Henrik Boström5e56c592015-08-11 10:33:13 +0200119 void GenerateIdentity(
120 rtc::KeyType key_type,
121 const rtc::scoped_refptr<DtlsIdentityRequestObserver>& observer);
122 void OnIdentityGenerated(rtc::KeyType key_type,
123 rtc::scoped_ptr<rtc::SSLIdentity> identity);
124
jiayl@webrtc.orgd83f4ef2015-03-13 21:26:12 +0000125 class WorkerTask;
Henrik Boström5e56c592015-08-11 10:33:13 +0200126 typedef rtc::ScopedMessageData<DtlsIdentityStoreImpl::WorkerTask>
127 WorkerTaskMessageData;
jiayl@webrtc.orgd83f4ef2015-03-13 21:26:12 +0000128
Henrik Boström5e56c592015-08-11 10:33:13 +0200129 // A key type-identity pair.
130 struct IdentityResult {
131 IdentityResult(rtc::KeyType key_type,
132 rtc::scoped_ptr<rtc::SSLIdentity> identity)
kwiberg0eb15ed2015-12-17 03:04:15 -0800133 : key_type_(key_type), identity_(std::move(identity)) {}
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +0000134
Henrik Boström5e56c592015-08-11 10:33:13 +0200135 rtc::KeyType key_type_;
136 rtc::scoped_ptr<rtc::SSLIdentity> identity_;
137 };
138
139 typedef rtc::ScopedMessageData<IdentityResult> IdentityResultMessageData;
140
141 sigslot::signal0<> SignalDestroyed;
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +0000142
Tommi532caea2015-06-09 17:33:06 +0200143 rtc::Thread* const signaling_thread_;
Henrik Boström5e56c592015-08-11 10:33:13 +0200144 // TODO(hbos): RSA generation is slow and would be VERY slow if we switch over
145 // to 2048, DtlsIdentityStore should use a new thread and not the "general
146 // purpose" worker thread.
Tommi532caea2015-06-09 17:33:06 +0200147 rtc::Thread* const worker_thread_;
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +0000148
Henrik Boström5e56c592015-08-11 10:33:13 +0200149 struct RequestInfo {
150 RequestInfo()
151 : request_observers_(), gen_in_progress_counts_(0), free_identity_() {}
152
153 std::queue<rtc::scoped_refptr<DtlsIdentityRequestObserver>>
154 request_observers_;
155 size_t gen_in_progress_counts_;
156 rtc::scoped_ptr<rtc::SSLIdentity> free_identity_;
157 };
158
159 // One RequestInfo per KeyType. Only touch on the |signaling_thread_|.
160 RequestInfo request_info_[rtc::KT_LAST];
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +0000161};
162
163} // namespace webrtc
164
Henrik Kjellander15583c12016-02-10 10:53:12 +0100165#endif // WEBRTC_API_DTLSIDENTITYSTORE_H_