1 //
2 //
3 // Copyright 2022 gRPC authors.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 //
18
19 #include <grpc/credentials.h>
20 #include <grpc/grpc.h>
21 #include <grpc/grpc_security.h>
22 #include <grpc/support/json.h>
23 #include <grpc/support/port_platform.h>
24 #include <grpc/support/time.h>
25
26 #include <map>
27 #include <memory>
28 #include <string>
29 #include <utility>
30
31 #include "absl/strings/string_view.h"
32 #include "src/core/config/core_configuration.h"
33 #include "src/core/lib/security/credentials/channel_creds_registry.h"
34 #include "src/core/lib/security/credentials/credentials.h"
35 #include "src/core/lib/security/credentials/fake/fake_credentials.h"
36 #include "src/core/lib/security/credentials/google_default/google_default_credentials.h" // IWYU pragma: keep
37 #include "src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h"
38 #include "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h"
39 #include "src/core/lib/security/credentials/tls/tls_credentials.h"
40 #include "src/core/util/json/json.h"
41 #include "src/core/util/json/json_args.h"
42 #include "src/core/util/json/json_object_loader.h"
43 #include "src/core/util/ref_counted_ptr.h"
44 #include "src/core/util/time.h"
45 #include "src/core/util/validation_errors.h"
46
47 namespace grpc_core {
48
49 class GoogleDefaultChannelCredsFactory : public ChannelCredsFactory<> {
50 public:
type() const51 absl::string_view type() const override { return Type(); }
ParseConfig(const Json &,const JsonArgs &,ValidationErrors *) const52 RefCountedPtr<ChannelCredsConfig> ParseConfig(
53 const Json& /*config*/, const JsonArgs& /*args*/,
54 ValidationErrors* /*errors*/) const override {
55 return MakeRefCounted<Config>();
56 }
CreateChannelCreds(RefCountedPtr<ChannelCredsConfig>) const57 RefCountedPtr<grpc_channel_credentials> CreateChannelCreds(
58 RefCountedPtr<ChannelCredsConfig> /*config*/) const override {
59 return RefCountedPtr<grpc_channel_credentials>(
60 grpc_google_default_credentials_create(nullptr));
61 }
62
63 private:
64 class Config : public ChannelCredsConfig {
65 public:
type() const66 absl::string_view type() const override { return Type(); }
Equals(const ChannelCredsConfig &) const67 bool Equals(const ChannelCredsConfig&) const override { return true; }
ToJson() const68 Json ToJson() const override { return Json::FromObject({}); }
69 };
70
Type()71 static absl::string_view Type() { return "google_default"; }
72 };
73
74 class TlsChannelCredsFactory : public ChannelCredsFactory<> {
75 public:
type() const76 absl::string_view type() const override { return Type(); }
77
ParseConfig(const Json & config,const JsonArgs & args,ValidationErrors * errors) const78 RefCountedPtr<ChannelCredsConfig> ParseConfig(
79 const Json& config, const JsonArgs& args,
80 ValidationErrors* errors) const override {
81 return LoadFromJson<RefCountedPtr<TlsConfig>>(config, args, errors);
82 }
83
CreateChannelCreds(RefCountedPtr<ChannelCredsConfig> base_config) const84 RefCountedPtr<grpc_channel_credentials> CreateChannelCreds(
85 RefCountedPtr<ChannelCredsConfig> base_config) const override {
86 auto* config = static_cast<const TlsConfig*>(base_config.get());
87 auto options = MakeRefCounted<grpc_tls_credentials_options>();
88 if (!config->certificate_file().empty() ||
89 !config->ca_certificate_file().empty()) {
90 options->set_certificate_provider(
91 MakeRefCounted<FileWatcherCertificateProvider>(
92 config->private_key_file(), config->certificate_file(),
93 config->ca_certificate_file(),
94 config->refresh_interval().millis() / GPR_MS_PER_SEC));
95 }
96 options->set_watch_root_cert(!config->ca_certificate_file().empty());
97 options->set_watch_identity_pair(!config->certificate_file().empty());
98 options->set_certificate_verifier(
99 MakeRefCounted<HostNameCertificateVerifier>());
100 return MakeRefCounted<TlsCredentials>(std::move(options));
101 }
102
103 private:
104 // TODO(roth): It would be nice to share most of this config with the
105 // xDS file watcher cert provider factory, but that would require
106 // adding a dependency from lib to ext.
107 class TlsConfig : public ChannelCredsConfig {
108 public:
type() const109 absl::string_view type() const override { return Type(); }
110
Equals(const ChannelCredsConfig & other) const111 bool Equals(const ChannelCredsConfig& other) const override {
112 auto& o = static_cast<const TlsConfig&>(other);
113 return certificate_file_ == o.certificate_file_ &&
114 private_key_file_ == o.private_key_file_ &&
115 ca_certificate_file_ == o.ca_certificate_file_ &&
116 refresh_interval_ == o.refresh_interval_;
117 }
118
ToJson() const119 Json ToJson() const override {
120 Json::Object obj;
121 if (!certificate_file_.empty()) {
122 obj["certificate_file"] = Json::FromString(certificate_file_);
123 }
124 if (!private_key_file_.empty()) {
125 obj["private_key_file"] = Json::FromString(private_key_file_);
126 }
127 if (!ca_certificate_file_.empty()) {
128 obj["ca_certificate_file"] = Json::FromString(ca_certificate_file_);
129 }
130 if (refresh_interval_ != kDefaultRefreshInterval) {
131 obj["refresh_interval"] =
132 Json::FromString(refresh_interval_.ToJsonString());
133 }
134 return Json::FromObject(std::move(obj));
135 }
136
certificate_file() const137 const std::string& certificate_file() const { return certificate_file_; }
private_key_file() const138 const std::string& private_key_file() const { return private_key_file_; }
ca_certificate_file() const139 const std::string& ca_certificate_file() const {
140 return ca_certificate_file_;
141 }
refresh_interval() const142 Duration refresh_interval() const { return refresh_interval_; }
143
JsonLoader(const JsonArgs &)144 static const JsonLoaderInterface* JsonLoader(const JsonArgs&) {
145 static const auto* loader =
146 JsonObjectLoader<TlsConfig>()
147 .OptionalField("certificate_file", &TlsConfig::certificate_file_)
148 .OptionalField("private_key_file", &TlsConfig::private_key_file_)
149 .OptionalField("ca_certificate_file",
150 &TlsConfig::ca_certificate_file_)
151 .OptionalField("refresh_interval", &TlsConfig::refresh_interval_)
152 .Finish();
153 return loader;
154 }
155
JsonPostLoad(const Json & json,const JsonArgs &,ValidationErrors * errors)156 void JsonPostLoad(const Json& json, const JsonArgs& /*args*/,
157 ValidationErrors* errors) {
158 if ((json.object().find("certificate_file") == json.object().end()) !=
159 (json.object().find("private_key_file") == json.object().end())) {
160 errors->AddError(
161 "fields \"certificate_file\" and \"private_key_file\" must be "
162 "both set or both unset");
163 }
164 }
165
166 private:
167 static constexpr Duration kDefaultRefreshInterval = Duration::Minutes(10);
168
169 std::string certificate_file_;
170 std::string private_key_file_;
171 std::string ca_certificate_file_;
172 Duration refresh_interval_ = kDefaultRefreshInterval;
173 };
174
Type()175 static absl::string_view Type() { return "tls"; }
176 };
177
178 constexpr Duration TlsChannelCredsFactory::TlsConfig::kDefaultRefreshInterval;
179
180 class InsecureChannelCredsFactory : public ChannelCredsFactory<> {
181 public:
type() const182 absl::string_view type() const override { return Type(); }
ParseConfig(const Json &,const JsonArgs &,ValidationErrors *) const183 RefCountedPtr<ChannelCredsConfig> ParseConfig(
184 const Json& /*config*/, const JsonArgs& /*args*/,
185 ValidationErrors* /*errors*/) const override {
186 return MakeRefCounted<Config>();
187 }
CreateChannelCreds(RefCountedPtr<ChannelCredsConfig>) const188 RefCountedPtr<grpc_channel_credentials> CreateChannelCreds(
189 RefCountedPtr<ChannelCredsConfig> /*config*/) const override {
190 return RefCountedPtr<grpc_channel_credentials>(
191 grpc_insecure_credentials_create());
192 }
193
194 private:
195 class Config : public ChannelCredsConfig {
196 public:
type() const197 absl::string_view type() const override { return Type(); }
Equals(const ChannelCredsConfig &) const198 bool Equals(const ChannelCredsConfig&) const override { return true; }
ToJson() const199 Json ToJson() const override { return Json::FromObject({}); }
200 };
201
Type()202 static absl::string_view Type() { return "insecure"; }
203 };
204
205 class FakeChannelCredsFactory : public ChannelCredsFactory<> {
206 public:
type() const207 absl::string_view type() const override { return Type(); }
ParseConfig(const Json &,const JsonArgs &,ValidationErrors *) const208 RefCountedPtr<ChannelCredsConfig> ParseConfig(
209 const Json& /*config*/, const JsonArgs& /*args*/,
210 ValidationErrors* /*errors*/) const override {
211 return MakeRefCounted<Config>();
212 }
CreateChannelCreds(RefCountedPtr<ChannelCredsConfig>) const213 RefCountedPtr<grpc_channel_credentials> CreateChannelCreds(
214 RefCountedPtr<ChannelCredsConfig> /*config*/) const override {
215 return RefCountedPtr<grpc_channel_credentials>(
216 grpc_fake_transport_security_credentials_create());
217 }
218
219 private:
220 class Config : public ChannelCredsConfig {
221 public:
type() const222 absl::string_view type() const override { return Type(); }
Equals(const ChannelCredsConfig &) const223 bool Equals(const ChannelCredsConfig&) const override { return true; }
ToJson() const224 Json ToJson() const override { return Json::FromObject({}); }
225 };
226
Type()227 static absl::string_view Type() { return "fake"; }
228 };
229
RegisterChannelDefaultCreds(CoreConfiguration::Builder * builder)230 void RegisterChannelDefaultCreds(CoreConfiguration::Builder* builder) {
231 builder->channel_creds_registry()->RegisterChannelCredsFactory(
232 std::make_unique<GoogleDefaultChannelCredsFactory>());
233 builder->channel_creds_registry()->RegisterChannelCredsFactory(
234 std::make_unique<TlsChannelCredsFactory>());
235 builder->channel_creds_registry()->RegisterChannelCredsFactory(
236 std::make_unique<InsecureChannelCredsFactory>());
237 builder->channel_creds_registry()->RegisterChannelCredsFactory(
238 std::make_unique<FakeChannelCredsFactory>());
239 }
240
241 } // namespace grpc_core
242