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