xref: /aosp_15_r20/external/webrtc/rtc_base/rtc_certificate_generator.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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