blob: 5ded1f112b367308d84e26e7273405fec98ada2f [file] [log] [blame]
jiayl@webrtc.org25484062015-02-18 23:58:16 +00001/*
kjellanderb24317b2016-02-10 07:54:43 -08002 * Copyright 2015 The WebRTC project authors. All Rights Reserved.
jiayl@webrtc.org25484062015-02-18 23:58:16 +00003 *
kjellanderb24317b2016-02-10 07:54:43 -08004 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
jiayl@webrtc.org25484062015-02-18 23:58:16 +00009 */
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +000010
Henrik Kjellander15583c12016-02-10 10:53:12 +010011#ifndef WEBRTC_API_DTLSIDENTITYSTORE_H_
12#define WEBRTC_API_DTLSIDENTITYSTORE_H_
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +000013
jbauch555604a2016-04-26 03:13:22 -070014#include <memory>
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +000015#include <queue>
16#include <string>
kwiberg0eb15ed2015-12-17 03:04:15 -080017#include <utility>
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +000018
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +000019#include "webrtc/base/messagehandler.h"
jiayl@webrtc.orgd83f4ef2015-03-13 21:26:12 +000020#include "webrtc/base/messagequeue.h"
hbos25359e02016-03-02 07:55:53 -080021#include "webrtc/base/optional.h"
Henrik Boström5b4ce332015-08-05 16:55:22 +020022#include "webrtc/base/refcount.h"
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +000023#include "webrtc/base/scoped_ref_ptr.h"
Henrik Boström5b4ce332015-08-05 16:55:22 +020024#include "webrtc/base/sslidentity.h"
25#include "webrtc/base/thread.h"
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +000026
27namespace webrtc {
glaznev97579a42015-09-01 11:31:27 -070028
29// Passed to SSLIdentity::Generate.
30extern const char kIdentityName[];
31
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +000032class SSLIdentity;
33class Thread;
34
Henrik Boström5b4ce332015-08-05 16:55:22 +020035// Used to receive callbacks of DTLS identity requests.
Henrik Boström5b4ce332015-08-05 16:55:22 +020036class DtlsIdentityRequestObserver : public rtc::RefCountInterface {
37 public:
38 virtual void OnFailure(int error) = 0;
39 // TODO(hbos): Unify the OnSuccess method once Chrome code is updated.
40 virtual void OnSuccess(const std::string& der_cert,
41 const std::string& der_private_key) = 0;
jbauch555604a2016-04-26 03:13:22 -070042 // |identity| is a unique_ptr because rtc::SSLIdentity is not copyable and the
Henrik Boström5b4ce332015-08-05 16:55:22 +020043 // client has to get the ownership of the object to make use of it.
jbauch555604a2016-04-26 03:13:22 -070044 virtual void OnSuccess(std::unique_ptr<rtc::SSLIdentity> identity) = 0;
Henrik Boström5b4ce332015-08-05 16:55:22 +020045
46 protected:
47 virtual ~DtlsIdentityRequestObserver() {}
48};
49
Henrik Boström5b4ce332015-08-05 16:55:22 +020050// This interface defines an in-memory DTLS identity store, which generates DTLS
51// identities.
52// APIs calls must be made on the signaling thread and the callbacks are also
53// called on the signaling thread.
54class DtlsIdentityStoreInterface {
55 public:
56 virtual ~DtlsIdentityStoreInterface() { }
57
Henrik Boström5e56c592015-08-11 10:33:13 +020058 // The |observer| will be called when the requested identity is ready, or when
59 // identity generation fails.
hbos25359e02016-03-02 07:55:53 -080060 // TODO(torbjorng,hbos): There are currently two versions of RequestIdentity,
61 // with default implementation to call the other version of itself (so that a
62 // call can be made regardless of which version has been overridden). The 1st
63 // version exists because it is currently implemented in chromium. The 2nd
64 // version will become the one and only RequestIdentity as soon as chromium
65 // implements the correct version. crbug.com/544902, webrtc:5092.
hbos3b7c7932015-10-21 01:44:21 -070066 virtual void RequestIdentity(
67 rtc::KeyParams key_params,
68 const rtc::scoped_refptr<DtlsIdentityRequestObserver>& observer) {
hbos25359e02016-03-02 07:55:53 -080069 // Add default ("null") expiration.
70 RequestIdentity(key_params, rtc::Optional<uint64_t>(), observer);
71 }
72 virtual void RequestIdentity(
hbos52913932016-03-07 15:14:40 -080073 const rtc::KeyParams& key_params,
74 const rtc::Optional<uint64_t>& expires_ms,
hbos25359e02016-03-02 07:55:53 -080075 const rtc::scoped_refptr<DtlsIdentityRequestObserver>& observer) {
76 // Drop |expires|.
77 RequestIdentity(key_params, observer);
hbos3b7c7932015-10-21 01:44:21 -070078 }
Henrik Boström5b4ce332015-08-05 16:55:22 +020079};
80
Henrik Boström5e56c592015-08-11 10:33:13 +020081// The WebRTC default implementation of DtlsIdentityStoreInterface.
82// Identity generation is performed on the worker thread.
83class DtlsIdentityStoreImpl : public DtlsIdentityStoreInterface,
84 public rtc::MessageHandler {
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +000085 public:
Henrik Boström5e56c592015-08-11 10:33:13 +020086 // This will start to preemptively generating an RSA identity in the
87 // background if the worker thread is not the same as the signaling thread.
88 DtlsIdentityStoreImpl(rtc::Thread* signaling_thread,
89 rtc::Thread* worker_thread);
90 ~DtlsIdentityStoreImpl() override;
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +000091
Henrik Boström5e56c592015-08-11 10:33:13 +020092 // DtlsIdentityStoreInterface override;
93 void RequestIdentity(
hbos52913932016-03-07 15:14:40 -080094 const rtc::KeyParams& key_params,
95 const rtc::Optional<uint64_t>& expires_ms,
Henrik Boström5e56c592015-08-11 10:33:13 +020096 const rtc::scoped_refptr<DtlsIdentityRequestObserver>& observer) override;
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +000097
98 // rtc::MessageHandler override;
99 void OnMessage(rtc::Message* msg) override;
100
Henrik Boström5e56c592015-08-11 10:33:13 +0200101 // Returns true if there is a free RSA identity, used for unit tests.
102 bool HasFreeIdentityForTesting(rtc::KeyType key_type) const;
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +0000103
104 private:
Henrik Boström5e56c592015-08-11 10:33:13 +0200105 void GenerateIdentity(
106 rtc::KeyType key_type,
107 const rtc::scoped_refptr<DtlsIdentityRequestObserver>& observer);
108 void OnIdentityGenerated(rtc::KeyType key_type,
jbauch555604a2016-04-26 03:13:22 -0700109 std::unique_ptr<rtc::SSLIdentity> identity);
Henrik Boström5e56c592015-08-11 10:33:13 +0200110
jiayl@webrtc.orgd83f4ef2015-03-13 21:26:12 +0000111 class WorkerTask;
Henrik Boström5e56c592015-08-11 10:33:13 +0200112 typedef rtc::ScopedMessageData<DtlsIdentityStoreImpl::WorkerTask>
113 WorkerTaskMessageData;
jiayl@webrtc.orgd83f4ef2015-03-13 21:26:12 +0000114
Henrik Boström5e56c592015-08-11 10:33:13 +0200115 // A key type-identity pair.
116 struct IdentityResult {
117 IdentityResult(rtc::KeyType key_type,
jbauch555604a2016-04-26 03:13:22 -0700118 std::unique_ptr<rtc::SSLIdentity> identity)
kwiberg0eb15ed2015-12-17 03:04:15 -0800119 : key_type_(key_type), identity_(std::move(identity)) {}
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +0000120
Henrik Boström5e56c592015-08-11 10:33:13 +0200121 rtc::KeyType key_type_;
jbauch555604a2016-04-26 03:13:22 -0700122 std::unique_ptr<rtc::SSLIdentity> identity_;
Henrik Boström5e56c592015-08-11 10:33:13 +0200123 };
124
125 typedef rtc::ScopedMessageData<IdentityResult> IdentityResultMessageData;
126
127 sigslot::signal0<> SignalDestroyed;
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +0000128
Tommi532caea2015-06-09 17:33:06 +0200129 rtc::Thread* const signaling_thread_;
Henrik Boström5e56c592015-08-11 10:33:13 +0200130 // TODO(hbos): RSA generation is slow and would be VERY slow if we switch over
131 // to 2048, DtlsIdentityStore should use a new thread and not the "general
132 // purpose" worker thread.
Tommi532caea2015-06-09 17:33:06 +0200133 rtc::Thread* const worker_thread_;
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +0000134
Henrik Boström5e56c592015-08-11 10:33:13 +0200135 struct RequestInfo {
136 RequestInfo()
137 : request_observers_(), gen_in_progress_counts_(0), free_identity_() {}
138
139 std::queue<rtc::scoped_refptr<DtlsIdentityRequestObserver>>
140 request_observers_;
141 size_t gen_in_progress_counts_;
jbauch555604a2016-04-26 03:13:22 -0700142 std::unique_ptr<rtc::SSLIdentity> free_identity_;
Henrik Boström5e56c592015-08-11 10:33:13 +0200143 };
144
145 // One RequestInfo per KeyType. Only touch on the |signaling_thread_|.
146 RequestInfo request_info_[rtc::KT_LAST];
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +0000147};
148
149} // namespace webrtc
150
Henrik Kjellander15583c12016-02-10 10:53:12 +0100151#endif // WEBRTC_API_DTLSIDENTITYSTORE_H_