OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright 2016 The WebRTC project authors. All Rights Reserved. | |
3 * | |
4 * 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. | |
9 */ | |
10 | |
11 #include "webrtc/base/rtccertificategenerator.h" | |
12 | |
13 #include "webrtc/base/checks.h" | |
14 #include "webrtc/base/sslidentity.h" | |
15 | |
16 namespace rtc { | |
17 | |
18 namespace { | |
19 | |
20 // A certificates' subject and issuer name. | |
21 const char kIdentityName[] = "WebRTC"; | |
22 | |
23 uint64_t kYearInSeconds = 365 * 24 * 60 * 60; | |
24 | |
25 enum { | |
26 MSG_GENERATE, | |
27 MSG_GENERATE_DONE, | |
28 }; | |
29 | |
30 // Using a separate helper class so that a generation request can outlive the | |
hta-webrtc
2016/04/14 11:54:05
Nit: Start the description with a description, not
hbos
2016/04/14 15:31:54
Done.
| |
31 // |RTCCertificateGenerator| that spawned it. | |
32 class RTCCertificateGenerationTask : public RefCountInterface, | |
33 public MessageHandler { | |
34 public: | |
35 RTCCertificateGenerationTask( | |
36 Thread* signaling_thread, | |
37 Thread* worker_thread, | |
38 const KeyParams& key_params, | |
39 const Optional<uint64_t>& expires_ms, | |
40 const scoped_refptr<RTCCertificateGeneratorCallback>& callback) | |
41 : signaling_thread_(signaling_thread), | |
42 worker_thread_(worker_thread), | |
43 key_params_(key_params), | |
44 expires_ms_(expires_ms), | |
45 callback_(callback) { | |
46 RTC_DCHECK(signaling_thread_); | |
47 RTC_DCHECK(worker_thread_); | |
48 RTC_DCHECK(callback_); | |
49 } | |
50 ~RTCCertificateGenerationTask() override {} | |
51 | |
52 // Handles |MSG_GENERATE| and its follow-up |MSG_GENERATE_DONE|. | |
53 void OnMessage(Message* msg) override { | |
54 switch (msg->message_id) { | |
55 case MSG_GENERATE: | |
56 RTC_DCHECK(worker_thread_->IsCurrent()); | |
57 | |
58 // Perform the certificate generation work here on the worker thread. | |
59 certificate_ = RTCCertificateGenerator::GenerateCertificateBlockingly( | |
60 key_params_, expires_ms_); | |
61 | |
62 // Handle callbacks on signaling thread. Pass on the |msg->pdata| | |
63 // (which references |this| with ref counting) to that thread. | |
64 signaling_thread_->Post(this, MSG_GENERATE_DONE, msg->pdata); | |
65 break; | |
66 case MSG_GENERATE_DONE: | |
67 RTC_DCHECK(signaling_thread_->IsCurrent()); | |
68 | |
69 // Perform callback with result here on the signaling thread. | |
70 if (certificate_) { | |
71 callback_->OnSuccess(certificate_); | |
72 } else { | |
73 callback_->OnFailure(); | |
74 } | |
75 | |
76 // Destroy |msg->pdata| which references |this| with ref counting. This | |
77 // may result in |this| being deleted - do not touch member variables | |
78 // after this line. | |
79 delete msg->pdata; | |
80 return; | |
81 default: | |
82 RTC_NOTREACHED(); | |
83 } | |
84 } | |
85 | |
86 private: | |
87 Thread* const signaling_thread_; | |
88 Thread* const worker_thread_; | |
89 const KeyParams key_params_; | |
90 const Optional<uint64_t> expires_ms_; | |
91 const scoped_refptr<RTCCertificateGeneratorCallback> callback_; | |
92 scoped_refptr<RTCCertificate> certificate_; | |
93 }; | |
94 | |
95 } // namespace | |
96 | |
97 // static | |
98 scoped_refptr<RTCCertificate> | |
99 RTCCertificateGenerator::GenerateCertificateBlockingly( | |
100 const KeyParams& key_params, | |
101 const Optional<uint64_t>& expires_ms) { | |
102 if (!key_params.IsValid()) | |
103 return nullptr; | |
104 SSLIdentity* identity; | |
105 if (!expires_ms) { | |
106 identity = SSLIdentity::Generate(kIdentityName, key_params); | |
107 } else { | |
108 uint64_t expires_s = *expires_ms / 1000; | |
hta-webrtc
2016/04/14 11:54:05
If |expires_ms| is less than 1000, we will get an
hbos
2016/04/14 15:31:54
You are right and this is on purpose. Even if you
hbos
2016/04/15 07:59:20
For this CL: https://codereview.chromium.org/16445
| |
109 // Limit the expiration time to something reasonable (a year). This was | |
110 // somewhat arbitrarily chosen. It also ensures that the value is not too | |
111 // large for the unspecified |time_t|. | |
112 if (expires_s > kYearInSeconds) | |
113 expires_s = kYearInSeconds; | |
hta-webrtc
2016/04/14 11:54:05
This seems somewhat arbitrary. Consider returning
hbos
2016/04/14 15:31:54
Based on "a user agent may choose to limit the per
| |
114 // TODO(torbjorng): Stop using |time_t|, its type is unspecified. It it safe | |
115 // to assume it can hold up to a year's worth of seconds (and more), but | |
116 // |SSLIdentity::Generate| should stop relying on |time_t|. | |
117 // See bugs.webrtc.org/5720. | |
118 time_t cert_lifetime_s = static_cast<time_t>(expires_s); | |
119 identity = SSLIdentity::GenerateWithExpiration( | |
120 kIdentityName, key_params, cert_lifetime_s); | |
121 } | |
122 if (!identity) | |
123 return nullptr; | |
124 scoped_ptr<SSLIdentity> identity_sptr(identity); | |
125 return RTCCertificate::Create(std::move(identity_sptr)); | |
126 } | |
127 | |
128 RTCCertificateGenerator::RTCCertificateGenerator( | |
129 Thread* signaling_thread, Thread* worker_thread) | |
130 : signaling_thread_(signaling_thread), | |
131 worker_thread_(worker_thread) { | |
132 RTC_DCHECK(signaling_thread_); | |
133 RTC_DCHECK(worker_thread_); | |
134 } | |
135 | |
136 void RTCCertificateGenerator::GenerateCertificate( | |
137 const KeyParams& key_params, | |
138 const Optional<uint64_t>& expires_ms, | |
139 const scoped_refptr<RTCCertificateGeneratorCallback>& callback) { | |
140 RTC_DCHECK(signaling_thread_->IsCurrent()); | |
141 RTC_DCHECK(callback); | |
142 | |
143 // Create a new |RTCCertificateGenerationTask| for this generation request. It | |
144 // is reference counted and referenced by the message data, ensuring it lives | |
145 // until the task has completed (independent of |RTCCertificateGenerator|). | |
146 ScopedRefMessageData<RTCCertificateGenerationTask>* msg_data = | |
147 new ScopedRefMessageData<RTCCertificateGenerationTask>( | |
148 new RefCountedObject<RTCCertificateGenerationTask>( | |
149 signaling_thread_, worker_thread_, key_params, expires_ms, | |
150 callback)); | |
151 worker_thread_->Post(msg_data->data().get(), MSG_GENERATE, msg_data); | |
152 } | |
153 | |
154 } // namespace rtc | |
OLD | NEW |