1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "cast/receiver/channel/static_credentials.h"
6 
7 #include <openssl/mem.h>
8 #include <openssl/pem.h>
9 
10 #include <cstdio>
11 #include <memory>
12 #include <string>
13 #include <utility>
14 #include <vector>
15 
16 #include "platform/base/tls_credentials.h"
17 #include "util/crypto/certificate_utils.h"
18 #include "util/osp_logging.h"
19 
20 namespace openscreen {
21 namespace cast {
22 namespace {
23 using FileUniquePtr = std::unique_ptr<FILE, decltype(&fclose)>;
24 
25 constexpr char kGeneratedRootCertificateName[] =
26     "generated_root_cast_receiver.crt";
27 constexpr char kGeneratedPrivateKey[] = "generated_root_cast_receiver.key";
28 constexpr int kThreeDaysInSeconds = 3 * 24 * 60 * 60;
29 constexpr auto kCertificateDuration = std::chrono::seconds(kThreeDaysInSeconds);
30 
GenerateCredentials(std::string device_certificate_id,EVP_PKEY * root_key,X509 * root_cert)31 ErrorOr<GeneratedCredentials> GenerateCredentials(
32     std::string device_certificate_id,
33     EVP_PKEY* root_key,
34     X509* root_cert) {
35   OSP_CHECK(root_key);
36   OSP_CHECK(root_cert);
37   bssl::UniquePtr<EVP_PKEY> intermediate_key = GenerateRsaKeyPair();
38   bssl::UniquePtr<EVP_PKEY> device_key = GenerateRsaKeyPair();
39   OSP_CHECK(intermediate_key);
40   OSP_CHECK(device_key);
41 
42   ErrorOr<bssl::UniquePtr<X509>> intermediate_cert_or_error =
43       CreateSelfSignedX509Certificate(
44           "Cast Intermediate", kCertificateDuration, *intermediate_key,
45           GetWallTimeSinceUnixEpoch(), true, root_cert, root_key);
46   OSP_CHECK(intermediate_cert_or_error);
47   bssl::UniquePtr<X509> intermediate_cert =
48       std::move(intermediate_cert_or_error.value());
49 
50   ErrorOr<bssl::UniquePtr<X509>> device_cert_or_error =
51       CreateSelfSignedX509Certificate(
52           device_certificate_id, kCertificateDuration, *device_key,
53           GetWallTimeSinceUnixEpoch(), false, intermediate_cert.get(),
54           intermediate_key.get());
55   OSP_CHECK(device_cert_or_error);
56   bssl::UniquePtr<X509> device_cert = std::move(device_cert_or_error.value());
57 
58   // Device cert chain plumbing + serialization.
59   DeviceCredentials device_creds;
60   device_creds.private_key = std::move(device_key);
61 
62   int cert_length = i2d_X509(device_cert.get(), nullptr);
63   std::string cert_serial(cert_length, 0);
64   uint8_t* out = reinterpret_cast<uint8_t*>(&cert_serial[0]);
65   i2d_X509(device_cert.get(), &out);
66   device_creds.certs.emplace_back(std::move(cert_serial));
67 
68   cert_length = i2d_X509(intermediate_cert.get(), nullptr);
69   cert_serial.resize(cert_length);
70   out = reinterpret_cast<uint8_t*>(&cert_serial[0]);
71   i2d_X509(intermediate_cert.get(), &out);
72   device_creds.certs.emplace_back(std::move(cert_serial));
73 
74   cert_length = i2d_X509(root_cert, nullptr);
75   std::vector<uint8_t> trust_anchor_der(cert_length);
76   out = &trust_anchor_der[0];
77   i2d_X509(root_cert, &out);
78 
79   // TLS key pair + certificate generation.
80   bssl::UniquePtr<EVP_PKEY> tls_key = GenerateRsaKeyPair();
81   OSP_CHECK_EQ(EVP_PKEY_id(tls_key.get()), EVP_PKEY_RSA);
82   ErrorOr<bssl::UniquePtr<X509>> tls_cert_or_error =
83       CreateSelfSignedX509Certificate("Test Device TLS", kCertificateDuration,
84                                       *tls_key, GetWallTimeSinceUnixEpoch());
85   OSP_CHECK(tls_cert_or_error);
86   bssl::UniquePtr<X509> tls_cert = std::move(tls_cert_or_error.value());
87 
88   // TLS private key serialization.
89   RSA* rsa_key = EVP_PKEY_get0_RSA(tls_key.get());
90   size_t pkey_len = 0;
91   uint8_t* pkey_bytes = nullptr;
92   OSP_CHECK(RSA_private_key_to_bytes(&pkey_bytes, &pkey_len, rsa_key));
93   OSP_CHECK_GT(pkey_len, 0u);
94   std::vector<uint8_t> tls_key_serial(pkey_bytes, pkey_bytes + pkey_len);
95   OPENSSL_free(pkey_bytes);
96 
97   // TLS public key serialization.
98   pkey_len = 0;
99   pkey_bytes = nullptr;
100   OSP_CHECK(RSA_public_key_to_bytes(&pkey_bytes, &pkey_len, rsa_key));
101   OSP_CHECK_GT(pkey_len, 0u);
102   std::vector<uint8_t> tls_pub_serial(pkey_bytes, pkey_bytes + pkey_len);
103   OPENSSL_free(pkey_bytes);
104 
105   // TLS cert serialization.
106   cert_length = 0;
107   cert_length = i2d_X509(tls_cert.get(), nullptr);
108   OSP_CHECK_GT(cert_length, 0);
109   std::vector<uint8_t> tls_cert_serial(cert_length);
110   out = &tls_cert_serial[0];
111   i2d_X509(tls_cert.get(), &out);
112 
113   auto provider = std::make_unique<StaticCredentialsProvider>(
114       std::move(device_creds), tls_cert_serial);
115   return GeneratedCredentials{
116       std::move(provider),
117       TlsCredentials{std::move(tls_key_serial), std::move(tls_pub_serial),
118                      std::move(tls_cert_serial)},
119       std::move(trust_anchor_der)};
120 }
121 
GeneratePrivateKey()122 bssl::UniquePtr<EVP_PKEY> GeneratePrivateKey() {
123   bssl::UniquePtr<EVP_PKEY> root_key = GenerateRsaKeyPair();
124   OSP_CHECK(root_key);
125   return root_key;
126 }
127 
GenerateRootCert(const EVP_PKEY & root_key)128 bssl::UniquePtr<X509> GenerateRootCert(const EVP_PKEY& root_key) {
129   ErrorOr<bssl::UniquePtr<X509>> root_cert_or_error =
130       CreateSelfSignedX509Certificate("Cast Root CA", kCertificateDuration,
131                                       root_key, GetWallTimeSinceUnixEpoch(),
132                                       true);
133   OSP_CHECK(root_cert_or_error);
134   return std::move(root_cert_or_error.value());
135 }
136 }  // namespace
137 
138 StaticCredentialsProvider::StaticCredentialsProvider() = default;
StaticCredentialsProvider(DeviceCredentials device_creds,std::vector<uint8_t> tls_cert_der)139 StaticCredentialsProvider::StaticCredentialsProvider(
140     DeviceCredentials device_creds,
141     std::vector<uint8_t> tls_cert_der)
142     : device_creds(std::move(device_creds)),
143       tls_cert_der(std::move(tls_cert_der)) {}
144 
145 StaticCredentialsProvider::StaticCredentialsProvider(
146     StaticCredentialsProvider&&) noexcept = default;
147 StaticCredentialsProvider& StaticCredentialsProvider::operator=(
148     StaticCredentialsProvider&&) = default;
149 StaticCredentialsProvider::~StaticCredentialsProvider() = default;
150 
GenerateDeveloperCredentialsToFile()151 void GenerateDeveloperCredentialsToFile() {
152   bssl::UniquePtr<EVP_PKEY> root_key = GeneratePrivateKey();
153   bssl::UniquePtr<X509> root_cert = GenerateRootCert(*root_key);
154 
155   FileUniquePtr f(fopen(kGeneratedPrivateKey, "w"), &fclose);
156   if (PEM_write_PrivateKey(f.get(), root_key.get(), nullptr, nullptr, 0, 0,
157                            nullptr) != 1) {
158     OSP_LOG_ERROR << "Failed to write private key, check permissions?";
159     return;
160   }
161   OSP_LOG_INFO << "Generated new private key for session: ./"
162                << kGeneratedPrivateKey;
163 
164   FileUniquePtr cert_file(fopen(kGeneratedRootCertificateName, "w"), &fclose);
165   if (PEM_write_X509(cert_file.get(), root_cert.get()) != 1) {
166     OSP_LOG_ERROR << "Failed to write root certificate, check permissions?";
167     return;
168   }
169   OSP_LOG_INFO << "Generated new root certificate for session: ./"
170                << kGeneratedRootCertificateName;
171 }
172 
GenerateCredentialsForTesting(const std::string & device_certificate_id)173 ErrorOr<GeneratedCredentials> GenerateCredentialsForTesting(
174     const std::string& device_certificate_id) {
175   bssl::UniquePtr<EVP_PKEY> root_key = GeneratePrivateKey();
176   bssl::UniquePtr<X509> root_cert = GenerateRootCert(*root_key);
177   return GenerateCredentials(device_certificate_id, root_key.get(),
178                              root_cert.get());
179 }
180 
GenerateCredentials(const std::string & device_certificate_id,const std::string & private_key_path,const std::string & server_certificate_path)181 ErrorOr<GeneratedCredentials> GenerateCredentials(
182     const std::string& device_certificate_id,
183     const std::string& private_key_path,
184     const std::string& server_certificate_path) {
185   if (private_key_path.empty() || server_certificate_path.empty()) {
186     return Error(Error::Code::kParameterInvalid,
187                  "Missing either private key or server certificate");
188   }
189 
190   FileUniquePtr key_file(fopen(private_key_path.c_str(), "r"), &fclose);
191   if (!key_file) {
192     return Error(Error::Code::kParameterInvalid,
193                  "Missing private key file path");
194   }
195   bssl::UniquePtr<EVP_PKEY> root_key =
196       bssl::UniquePtr<EVP_PKEY>(PEM_read_PrivateKey(
197           key_file.get(), nullptr /* x */, nullptr /* cb */, nullptr /* u */));
198 
199   FileUniquePtr cert_file(fopen(server_certificate_path.c_str(), "r"), &fclose);
200   if (!cert_file) {
201     return Error(Error::Code::kParameterInvalid,
202                  "Missing server certificate file path");
203   }
204   bssl::UniquePtr<X509> root_cert = bssl::UniquePtr<X509>(PEM_read_X509(
205       cert_file.get(), nullptr /* x */, nullptr /* cb */, nullptr /* u */));
206 
207   return GenerateCredentials(device_certificate_id, root_key.get(),
208                              root_cert.get());
209 }
210 
211 }  // namespace cast
212 }  // namespace openscreen
213