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 "rtc_base/rtc_certificate_generator.h"
12
13 #include <time.h>
14
15 #include <algorithm>
16 #include <memory>
17 #include <utility>
18
19 #include "rtc_base/checks.h"
20 #include "rtc_base/ssl_identity.h"
21
22 namespace rtc {
23
24 namespace {
25
26 // A certificates' subject and issuer name.
27 const char kIdentityName[] = "WebRTC";
28 const uint64_t kYearInSeconds = 365 * 24 * 60 * 60;
29
30 } // namespace
31
32 // static
GenerateCertificate(const KeyParams & key_params,const absl::optional<uint64_t> & expires_ms)33 scoped_refptr<RTCCertificate> RTCCertificateGenerator::GenerateCertificate(
34 const KeyParams& key_params,
35 const absl::optional<uint64_t>& expires_ms) {
36 if (!key_params.IsValid()) {
37 return nullptr;
38 }
39
40 std::unique_ptr<SSLIdentity> identity;
41 if (!expires_ms) {
42 identity = SSLIdentity::Create(kIdentityName, key_params);
43 } else {
44 uint64_t expires_s = *expires_ms / 1000;
45 // Limit the expiration time to something reasonable (a year). This was
46 // somewhat arbitrarily chosen. It also ensures that the value is not too
47 // large for the unspecified `time_t`.
48 expires_s = std::min(expires_s, kYearInSeconds);
49 // TODO(torbjorng): Stop using `time_t`, its type is unspecified. It it safe
50 // to assume it can hold up to a year's worth of seconds (and more), but
51 // `SSLIdentity::Create` should stop relying on `time_t`.
52 // See bugs.webrtc.org/5720.
53 time_t cert_lifetime_s = static_cast<time_t>(expires_s);
54 identity = SSLIdentity::Create(kIdentityName, key_params, cert_lifetime_s);
55 }
56 if (!identity) {
57 return nullptr;
58 }
59 return RTCCertificate::Create(std::move(identity));
60 }
61
RTCCertificateGenerator(Thread * signaling_thread,Thread * worker_thread)62 RTCCertificateGenerator::RTCCertificateGenerator(Thread* signaling_thread,
63 Thread* worker_thread)
64 : signaling_thread_(signaling_thread), worker_thread_(worker_thread) {
65 RTC_DCHECK(signaling_thread_);
66 RTC_DCHECK(worker_thread_);
67 }
68
GenerateCertificateAsync(const KeyParams & key_params,const absl::optional<uint64_t> & expires_ms,RTCCertificateGenerator::Callback callback)69 void RTCCertificateGenerator::GenerateCertificateAsync(
70 const KeyParams& key_params,
71 const absl::optional<uint64_t>& expires_ms,
72 RTCCertificateGenerator::Callback callback) {
73 RTC_DCHECK(signaling_thread_->IsCurrent());
74 RTC_DCHECK(callback);
75
76 worker_thread_->PostTask([key_params, expires_ms,
77 signaling_thread = signaling_thread_,
78 cb = std::move(callback)]() mutable {
79 scoped_refptr<RTCCertificate> certificate =
80 RTCCertificateGenerator::GenerateCertificate(key_params, expires_ms);
81 signaling_thread->PostTask(
82 [cert = std::move(certificate), cb = std::move(cb)]() mutable {
83 std::move(cb)(std::move(cert));
84 });
85 });
86 }
87
88 } // namespace rtc
89