Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(304)

Unified Diff: webrtc/base/rtccertificategenerator.cc

Issue 1883813002: RTCCertificateGenerator added. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Addressed hta's comments Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: webrtc/base/rtccertificategenerator.cc
diff --git a/webrtc/base/rtccertificategenerator.cc b/webrtc/base/rtccertificategenerator.cc
new file mode 100644
index 0000000000000000000000000000000000000000..a2d6870587490fe4e6c170be4ca9c85d6d3b6824
--- /dev/null
+++ b/webrtc/base/rtccertificategenerator.cc
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "webrtc/base/rtccertificategenerator.h"
+
+#include "webrtc/base/checks.h"
+#include "webrtc/base/sslidentity.h"
+
+namespace rtc {
+
+namespace {
+
+// A certificates' subject and issuer name.
+const char kIdentityName[] = "WebRTC";
+
+uint64_t kYearInSeconds = 365 * 24 * 60 * 60;
+
+enum {
+ MSG_GENERATE,
+ MSG_GENERATE_DONE,
+};
+
+// Helper class for generating certificates asynchronously; a single task
+// instance is responsible for a single asynchronous certificate generation
+// request. We are using a separate helper class so that a generation request
+// can outlive the |RTCCertificateGenerator| that spawned it.
+class RTCCertificateGenerationTask : public RefCountInterface,
+ public MessageHandler {
+ public:
+ RTCCertificateGenerationTask(
+ Thread* signaling_thread,
+ Thread* worker_thread,
+ const KeyParams& key_params,
+ const Optional<uint64_t>& expires_ms,
+ const scoped_refptr<RTCCertificateGeneratorCallback>& callback)
+ : signaling_thread_(signaling_thread),
+ worker_thread_(worker_thread),
+ key_params_(key_params),
+ expires_ms_(expires_ms),
+ callback_(callback) {
+ RTC_DCHECK(signaling_thread_);
+ RTC_DCHECK(worker_thread_);
+ RTC_DCHECK(callback_);
+ }
+ ~RTCCertificateGenerationTask() override {}
+
+ // Handles |MSG_GENERATE| and its follow-up |MSG_GENERATE_DONE|.
+ void OnMessage(Message* msg) override {
+ switch (msg->message_id) {
+ case MSG_GENERATE:
+ RTC_DCHECK(worker_thread_->IsCurrent());
+
+ // Perform the certificate generation work here on the worker thread.
+ certificate_ = RTCCertificateGenerator::GenerateCertificate(
+ key_params_, expires_ms_);
+
+ // Handle callbacks on signaling thread. Pass on the |msg->pdata|
+ // (which references |this| with ref counting) to that thread.
+ signaling_thread_->Post(this, MSG_GENERATE_DONE, msg->pdata);
+ break;
+ case MSG_GENERATE_DONE:
+ RTC_DCHECK(signaling_thread_->IsCurrent());
+
+ // Perform callback with result here on the signaling thread.
+ if (certificate_) {
+ callback_->OnSuccess(certificate_);
+ } else {
+ callback_->OnFailure();
+ }
+
+ // Destroy |msg->pdata| which references |this| with ref counting. This
+ // may result in |this| being deleted - do not touch member variables
+ // after this line.
+ delete msg->pdata;
+ return;
+ default:
+ RTC_NOTREACHED();
+ }
+ }
+
+ private:
+ Thread* const signaling_thread_;
+ Thread* const worker_thread_;
+ const KeyParams key_params_;
+ const Optional<uint64_t> expires_ms_;
+ const scoped_refptr<RTCCertificateGeneratorCallback> callback_;
+ scoped_refptr<RTCCertificate> certificate_;
+};
+
+} // namespace
+
+// static
+scoped_refptr<RTCCertificate>
+RTCCertificateGenerator::GenerateCertificate(
+ const KeyParams& key_params,
+ const Optional<uint64_t>& expires_ms) {
+ if (!key_params.IsValid())
+ return nullptr;
+ SSLIdentity* identity;
+ if (!expires_ms) {
+ identity = SSLIdentity::Generate(kIdentityName, key_params);
+ } else {
+ uint64_t expires_s = *expires_ms / 1000;
+ // Limit the expiration time to something reasonable (a year). This was
+ // somewhat arbitrarily chosen. It also ensures that the value is not too
+ // large for the unspecified |time_t|.
+ if (expires_s > kYearInSeconds)
torbjorng (webrtc) 2016/04/15 12:17:48 Consider using std::max.
hbos 2016/04/15 13:24:14 Done. (std::min)
+ expires_s = kYearInSeconds;
+ // TODO(torbjorng): Stop using |time_t|, its type is unspecified. It it safe
+ // to assume it can hold up to a year's worth of seconds (and more), but
+ // |SSLIdentity::Generate| should stop relying on |time_t|.
+ // See bugs.webrtc.org/5720.
+ time_t cert_lifetime_s = static_cast<time_t>(expires_s);
+ identity = SSLIdentity::GenerateWithExpiration(
+ kIdentityName, key_params, cert_lifetime_s);
+ }
+ if (!identity)
+ return nullptr;
+ scoped_ptr<SSLIdentity> identity_sptr(identity);
+ return RTCCertificate::Create(std::move(identity_sptr));
+}
+
+RTCCertificateGenerator::RTCCertificateGenerator(
+ Thread* signaling_thread, Thread* worker_thread)
+ : signaling_thread_(signaling_thread),
+ worker_thread_(worker_thread) {
+ RTC_DCHECK(signaling_thread_);
+ RTC_DCHECK(worker_thread_);
+}
+
+void RTCCertificateGenerator::GenerateCertificateAsync(
+ const KeyParams& key_params,
+ const Optional<uint64_t>& expires_ms,
+ const scoped_refptr<RTCCertificateGeneratorCallback>& callback) {
+ RTC_DCHECK(signaling_thread_->IsCurrent());
+ RTC_DCHECK(callback);
+
+ // Create a new |RTCCertificateGenerationTask| for this generation request. It
+ // is reference counted and referenced by the message data, ensuring it lives
+ // until the task has completed (independent of |RTCCertificateGenerator|).
+ ScopedRefMessageData<RTCCertificateGenerationTask>* msg_data =
+ new ScopedRefMessageData<RTCCertificateGenerationTask>(
+ new RefCountedObject<RTCCertificateGenerationTask>(
+ signaling_thread_, worker_thread_, key_params, expires_ms,
+ callback));
+ worker_thread_->Post(msg_data->data().get(), MSG_GENERATE, msg_data);
+}
+
+} // namespace rtc

Powered by Google App Engine
This is Rietveld 408576698