• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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