1
#include "source/common/secret/secret_manager_impl.h"
2

            
3
#include "envoy/admin/v3/config_dump.pb.h"
4
#include "envoy/common/exception.h"
5
#include "envoy/config/core/v3/base.pb.h"
6
#include "envoy/config/core/v3/config_source.pb.h"
7
#include "envoy/extensions/transport_sockets/tls/v3/cert.pb.h"
8

            
9
#include "source/common/common/assert.h"
10
#include "source/common/common/logger.h"
11
#include "source/common/protobuf/utility.h"
12
#include "source/common/secret/sds_api.h"
13
#include "source/common/secret/secret_provider_impl.h"
14
#include "source/common/ssl/certificate_validation_context_config_impl.h"
15
#include "source/common/ssl/tls_certificate_config_impl.h"
16

            
17
namespace Envoy {
18
namespace Secret {
19

            
20
50709
SecretManagerImpl::SecretManagerImpl(OptRef<Server::ConfigTracker> config_tracker) {
21
50709
  if (config_tracker.has_value()) {
22
50709
    config_tracker_entry_ =
23
50709
        config_tracker->add("secrets", [this](const Matchers::StringMatcher& name_matcher) {
24
63
          return dumpSecretConfigs(name_matcher);
25
63
        });
26
50709
  }
27
50709
}
28

            
29
absl::Status SecretManagerImpl::addStaticSecret(
30
8802
    const envoy::extensions::transport_sockets::tls::v3::Secret& secret) {
31
8802
  switch (secret.type_case()) {
32
8759
  case envoy::extensions::transport_sockets::tls::v3::Secret::TypeCase::kTlsCertificate: {
33
8759
    auto secret_provider =
34
8759
        std::make_shared<TlsCertificateConfigProviderImpl>(secret.tls_certificate());
35
8759
    if (!static_tls_certificate_providers_.insert(std::make_pair(secret.name(), secret_provider))
36
8759
             .second) {
37
1
      return absl::InvalidArgumentError(
38
1
          absl::StrCat("Duplicate static TlsCertificate secret name ", secret.name()));
39
1
    }
40
8758
    break;
41
8759
  }
42
8759
  case envoy::extensions::transport_sockets::tls::v3::Secret::TypeCase::kValidationContext: {
43
10
    auto secret_provider = std::make_shared<CertificateValidationContextConfigProviderImpl>(
44
10
        secret.validation_context());
45
10
    if (!static_certificate_validation_context_providers_
46
10
             .insert(std::make_pair(secret.name(), secret_provider))
47
10
             .second) {
48
1
      return absl::InvalidArgumentError(absl::StrCat(
49
1
          "Duplicate static CertificateValidationContext secret name ", secret.name()));
50
1
    }
51
9
    break;
52
10
  }
53
9
  case envoy::extensions::transport_sockets::tls::v3::Secret::TypeCase::kSessionTicketKeys: {
54
5
    auto secret_provider =
55
5
        std::make_shared<TlsSessionTicketKeysConfigProviderImpl>(secret.session_ticket_keys());
56
5
    if (!static_session_ticket_keys_providers_
57
5
             .insert(std::make_pair(secret.name(), secret_provider))
58
5
             .second) {
59
1
      return absl::InvalidArgumentError(
60
1
          absl::StrCat("Duplicate static TlsSessionTicketKeys secret name ", secret.name()));
61
1
    }
62
4
    break;
63
5
  }
64
29
  case envoy::extensions::transport_sockets::tls::v3::Secret::TypeCase::kGenericSecret: {
65
28
    auto secret_provider =
66
28
        std::make_shared<GenericSecretConfigProviderImpl>(secret.generic_secret());
67
28
    if (!static_generic_secret_providers_.insert(std::make_pair(secret.name(), secret_provider))
68
28
             .second) {
69
1
      return absl::InvalidArgumentError(
70
1
          absl::StrCat("Duplicate static GenericSecret secret name ", secret.name()));
71
1
    }
72
27
    break;
73
28
  }
74
27
  default:
75
    return absl::InvalidArgumentError("Secret type not implemented");
76
8802
  }
77
8798
  return absl::OkStatus();
78
8802
}
79

            
80
TlsCertificateConfigProviderSharedPtr
81
16
SecretManagerImpl::findStaticTlsCertificateProvider(const std::string& name) const {
82
16
  auto secret = static_tls_certificate_providers_.find(name);
83
16
  return (secret != static_tls_certificate_providers_.end()) ? secret->second : nullptr;
84
16
}
85

            
86
CertificateValidationContextConfigProviderSharedPtr
87
12
SecretManagerImpl::findStaticCertificateValidationContextProvider(const std::string& name) const {
88
12
  auto secret = static_certificate_validation_context_providers_.find(name);
89
12
  return (secret != static_certificate_validation_context_providers_.end()) ? secret->second
90
12
                                                                            : nullptr;
91
12
}
92

            
93
TlsSessionTicketKeysConfigProviderSharedPtr
94
5
SecretManagerImpl::findStaticTlsSessionTicketKeysContextProvider(const std::string& name) const {
95
5
  auto secret = static_session_ticket_keys_providers_.find(name);
96
5
  return (secret != static_session_ticket_keys_providers_.end()) ? secret->second : nullptr;
97
5
}
98

            
99
GenericSecretConfigProviderSharedPtr
100
31
SecretManagerImpl::findStaticGenericSecretProvider(const std::string& name) const {
101
31
  auto secret = static_generic_secret_providers_.find(name);
102
31
  return (secret != static_generic_secret_providers_.end()) ? secret->second : nullptr;
103
31
}
104

            
105
TlsCertificateConfigProviderSharedPtr SecretManagerImpl::createInlineTlsCertificateProvider(
106
5154
    const envoy::extensions::transport_sockets::tls::v3::TlsCertificate& tls_certificate) {
107
5154
  return std::make_shared<TlsCertificateConfigProviderImpl>(tls_certificate);
108
5154
}
109

            
110
CertificateValidationContextConfigProviderSharedPtr
111
SecretManagerImpl::createInlineCertificateValidationContextProvider(
112
    const envoy::extensions::transport_sockets::tls::v3::CertificateValidationContext&
113
5923
        certificate_validation_context) {
114
5923
  return std::make_shared<CertificateValidationContextConfigProviderImpl>(
115
5923
      certificate_validation_context);
116
5923
}
117

            
118
TlsSessionTicketKeysConfigProviderSharedPtr
119
SecretManagerImpl::createInlineTlsSessionTicketKeysProvider(
120
    const envoy::extensions::transport_sockets::tls::v3::TlsSessionTicketKeys&
121
50
        tls_session_ticket_keys) {
122
50
  return std::make_shared<TlsSessionTicketKeysConfigProviderImpl>(tls_session_ticket_keys);
123
50
}
124

            
125
GenericSecretConfigProviderSharedPtr SecretManagerImpl::createInlineGenericSecretProvider(
126
    const envoy::extensions::transport_sockets::tls::v3::GenericSecret& generic_secret) {
127
  return std::make_shared<GenericSecretConfigProviderImpl>(generic_secret);
128
}
129

            
130
TlsCertificateConfigProviderSharedPtr SecretManagerImpl::findOrCreateTlsCertificateProvider(
131
    const envoy::config::core::v3::ConfigSource& sds_config_source, const std::string& config_name,
132
    Server::Configuration::ServerFactoryContext& server_context, OptRef<Init::Manager> init_manager,
133
111
    bool warm) {
134
111
  return certificate_providers_.findOrCreate(sds_config_source, config_name, server_context,
135
111
                                             init_manager, warm);
136
111
}
137

            
138
CertificateValidationContextConfigProviderSharedPtr
139
SecretManagerImpl::findOrCreateCertificateValidationContextProvider(
140
    const envoy::config::core::v3::ConfigSource& sds_config_source, const std::string& config_name,
141
49
    Server::Configuration::ServerFactoryContext& server_context, Init::Manager& init_manager) {
142
49
  return validation_context_providers_.findOrCreate(sds_config_source, config_name, server_context,
143
49
                                                    init_manager, true);
144
49
}
145

            
146
TlsSessionTicketKeysConfigProviderSharedPtr
147
SecretManagerImpl::findOrCreateTlsSessionTicketKeysContextProvider(
148
    const envoy::config::core::v3::ConfigSource& sds_config_source, const std::string& config_name,
149
3
    Server::Configuration::ServerFactoryContext& server_context, Init::Manager& init_manager) {
150
3
  return session_ticket_keys_providers_.findOrCreate(sds_config_source, config_name, server_context,
151
3
                                                     init_manager, true);
152
3
}
153

            
154
GenericSecretConfigProviderSharedPtr SecretManagerImpl::findOrCreateGenericSecretProvider(
155
    const envoy::config::core::v3::ConfigSource& sds_config_source, const std::string& config_name,
156
98
    Server::Configuration::ServerFactoryContext& server_context, Init::Manager& init_manager) {
157
98
  return generic_secret_providers_.findOrCreate(sds_config_source, config_name, server_context,
158
98
                                                init_manager, true);
159
98
}
160

            
161
ProtobufTypes::MessagePtr
162
63
SecretManagerImpl::dumpSecretConfigs(const Matchers::StringMatcher& name_matcher) {
163
63
  auto config_dump = std::make_unique<envoy::admin::v3::SecretsConfigDump>();
164
  // Handle static tls key/cert providers.
165
63
  for (const auto& cert_iter : static_tls_certificate_providers_) {
166
34
    const auto& tls_cert = cert_iter.second;
167
34
    ASSERT(tls_cert != nullptr);
168
34
    envoy::extensions::transport_sockets::tls::v3::Secret dump_secret;
169
34
    dump_secret.set_name(cert_iter.first);
170
34
    dump_secret.mutable_tls_certificate()->MergeFrom(*tls_cert->secret());
171
34
    if (!name_matcher.match(dump_secret.name())) {
172
5
      continue;
173
5
    }
174
29
    MessageUtil::redact(dump_secret);
175
29
    auto static_secret = config_dump->mutable_static_secrets()->Add();
176
29
    static_secret->set_name(cert_iter.first);
177
29
    static_secret->mutable_secret()->PackFrom(dump_secret);
178
29
  }
179

            
180
  // Handle static certificate validation context providers.
181
63
  for (const auto& context_iter : static_certificate_validation_context_providers_) {
182
2
    const auto& validation_context = context_iter.second;
183
2
    ASSERT(validation_context != nullptr);
184
2
    envoy::extensions::transport_sockets::tls::v3::Secret dump_secret;
185
2
    dump_secret.set_name(context_iter.first);
186
2
    dump_secret.mutable_validation_context()->MergeFrom(*validation_context->secret());
187
2
    if (!name_matcher.match(dump_secret.name())) {
188
1
      continue;
189
1
    }
190
1
    auto static_secret = config_dump->mutable_static_secrets()->Add();
191
1
    static_secret->set_name(context_iter.first);
192
1
    static_secret->mutable_secret()->PackFrom(dump_secret);
193
1
  }
194

            
195
  // Handle static session keys providers.
196
63
  for (const auto& context_iter : static_session_ticket_keys_providers_) {
197
2
    const auto& session_ticket_keys = context_iter.second;
198
2
    ASSERT(session_ticket_keys != nullptr);
199
2
    envoy::extensions::transport_sockets::tls::v3::Secret dump_secret;
200
2
    dump_secret.set_name(context_iter.first);
201
6
    for (const auto& key : session_ticket_keys->secret()->keys()) {
202
6
      dump_secret.mutable_session_ticket_keys()->add_keys()->MergeFrom(key);
203
6
    }
204
2
    if (!name_matcher.match(dump_secret.name())) {
205
1
      continue;
206
1
    }
207
1
    MessageUtil::redact(dump_secret);
208
1
    auto static_secret = config_dump->mutable_static_secrets()->Add();
209
1
    static_secret->set_name(context_iter.first);
210
1
    static_secret->mutable_secret()->PackFrom(dump_secret);
211
1
  }
212

            
213
  // Handle static generic secret providers.
214
63
  for (const auto& secret_iter : static_generic_secret_providers_) {
215
2
    const auto& generic_secret = secret_iter.second;
216
2
    ASSERT(generic_secret != nullptr);
217
2
    envoy::extensions::transport_sockets::tls::v3::Secret dump_secret;
218
2
    dump_secret.set_name(secret_iter.first);
219
2
    dump_secret.mutable_generic_secret()->MergeFrom(*generic_secret->secret());
220
2
    if (!name_matcher.match(dump_secret.name())) {
221
1
      continue;
222
1
    }
223
1
    auto static_secret = config_dump->mutable_static_secrets()->Add();
224
1
    static_secret->set_name(secret_iter.first);
225
1
    MessageUtil::redact(dump_secret);
226
1
    static_secret->mutable_secret()->PackFrom(dump_secret);
227
1
  }
228

            
229
  // Handle dynamic tls_certificate providers.
230
63
  const auto providers = certificate_providers_.allSecretProviders();
231
63
  for (const auto& cert_secrets : providers) {
232
20
    const auto& secret_data = cert_secrets->secretData();
233
20
    const auto& tls_cert = cert_secrets->secret();
234
20
    const bool secret_ready = tls_cert != nullptr;
235
20
    envoy::extensions::transport_sockets::tls::v3::Secret secret;
236
20
    secret.set_name(secret_data.resource_name_);
237
20
    Protobuf::Timestamp last_updated_ts;
238
20
    TimestampUtil::systemClockToTimestamp(secret_data.last_updated_, last_updated_ts);
239
20
    secret.set_name(secret_data.resource_name_);
240
20
    if (secret_ready) {
241
12
      secret.mutable_tls_certificate()->MergeFrom(*tls_cert);
242
12
    }
243
20
    if (!name_matcher.match(secret.name())) {
244
8
      continue;
245
8
    }
246
12
    MessageUtil::redact(secret);
247
12
    envoy::admin::v3::SecretsConfigDump::DynamicSecret* dump_secret;
248
12
    if (secret_ready) {
249
8
      dump_secret = config_dump->mutable_dynamic_active_secrets()->Add();
250
8
    } else {
251
4
      dump_secret = config_dump->mutable_dynamic_warming_secrets()->Add();
252
4
    }
253
12
    dump_secret->set_name(secret_data.resource_name_);
254
12
    dump_secret->set_version_info(secret_data.version_info_);
255
12
    *dump_secret->mutable_last_updated() = last_updated_ts;
256
12
    dump_secret->mutable_secret()->PackFrom(secret);
257
12
  }
258

            
259
  // Handling dynamic cert validation context providers.
260
63
  const auto context_secret_provider = validation_context_providers_.allSecretProviders();
261
63
  for (const auto& validation_context_secret : context_secret_provider) {
262
12
    const auto& secret_data = validation_context_secret->secretData();
263
12
    const auto& validation_context = validation_context_secret->secret();
264
12
    const bool secret_ready = validation_context != nullptr;
265

            
266
12
    envoy::extensions::transport_sockets::tls::v3::Secret secret;
267

            
268
12
    if (secret_ready) {
269
6
      secret.mutable_validation_context()->MergeFrom(*validation_context);
270
6
    }
271
12
    secret.set_name(secret_data.resource_name_);
272
12
    if (!name_matcher.match(secret.name())) {
273
6
      continue;
274
6
    }
275
6
    Protobuf::Timestamp last_updated_ts;
276
6
    envoy::admin::v3::SecretsConfigDump::DynamicSecret* dump_secret;
277
6
    TimestampUtil::systemClockToTimestamp(secret_data.last_updated_, last_updated_ts);
278
6
    if (secret_ready) {
279
3
      dump_secret = config_dump->mutable_dynamic_active_secrets()->Add();
280
3
    } else {
281
3
      dump_secret = config_dump->mutable_dynamic_warming_secrets()->Add();
282
3
    }
283
6
    dump_secret->set_version_info(secret_data.version_info_);
284
6
    *dump_secret->mutable_last_updated() = last_updated_ts;
285
6
    dump_secret->set_name(secret_data.resource_name_);
286
6
    dump_secret->mutable_secret()->PackFrom(secret);
287
6
  }
288

            
289
  // Handle dynamic session keys providers providers.
290
63
  const auto stek_providers = session_ticket_keys_providers_.allSecretProviders();
291
63
  for (const auto& stek_secrets : stek_providers) {
292
8
    const auto& secret_data = stek_secrets->secretData();
293
8
    const auto& tls_stek = stek_secrets->secret();
294
8
    const bool secret_ready = tls_stek != nullptr;
295
8
    envoy::extensions::transport_sockets::tls::v3::Secret secret;
296
8
    secret.set_name(secret_data.resource_name_);
297
8
    if (secret_ready) {
298
4
      secret.mutable_session_ticket_keys()->MergeFrom(*tls_stek);
299
4
    }
300
8
    if (!name_matcher.match(secret.name())) {
301
4
      continue;
302
4
    }
303
4
    Protobuf::Timestamp last_updated_ts;
304
4
    TimestampUtil::systemClockToTimestamp(secret_data.last_updated_, last_updated_ts);
305
4
    envoy::admin::v3::SecretsConfigDump::DynamicSecret* dump_secret;
306
4
    if (secret_ready) {
307
2
      dump_secret = config_dump->mutable_dynamic_active_secrets()->Add();
308
2
    } else {
309
2
      dump_secret = config_dump->mutable_dynamic_warming_secrets()->Add();
310
2
    }
311
4
    dump_secret->set_name(secret_data.resource_name_);
312
4
    dump_secret->set_version_info(secret_data.version_info_);
313
4
    *dump_secret->mutable_last_updated() = last_updated_ts;
314
4
    MessageUtil::redact(secret);
315
4
    dump_secret->mutable_secret()->PackFrom(secret);
316
4
  }
317

            
318
  // Handle dynamic generic secret providers.
319
63
  const auto generic_secret_providers = generic_secret_providers_.allSecretProviders();
320
63
  for (const auto& provider : generic_secret_providers) {
321
4
    const auto& secret_data = provider->secretData();
322
4
    const auto& generic_secret = provider->secret();
323
4
    const bool secret_ready = generic_secret != nullptr;
324
4
    envoy::extensions::transport_sockets::tls::v3::Secret secret;
325
4
    secret.set_name(secret_data.resource_name_);
326
4
    if (secret_ready) {
327
2
      secret.mutable_generic_secret()->MergeFrom(*generic_secret);
328
2
    }
329
4
    if (!name_matcher.match(secret.name())) {
330
2
      continue;
331
2
    }
332
2
    Protobuf::Timestamp last_updated_ts;
333
2
    TimestampUtil::systemClockToTimestamp(secret_data.last_updated_, last_updated_ts);
334
2
    envoy::admin::v3::SecretsConfigDump::DynamicSecret* dump_secret;
335
2
    if (secret_ready) {
336
1
      dump_secret = config_dump->mutable_dynamic_active_secrets()->Add();
337
1
    } else {
338
1
      dump_secret = config_dump->mutable_dynamic_warming_secrets()->Add();
339
1
    }
340
2
    dump_secret->set_name(secret_data.resource_name_);
341
2
    dump_secret->set_version_info(secret_data.version_info_);
342
2
    *dump_secret->mutable_last_updated() = last_updated_ts;
343
2
    MessageUtil::redact(secret);
344
2
    dump_secret->mutable_secret()->PackFrom(secret);
345
2
  }
346

            
347
63
  return config_dump;
348
63
}
349

            
350
} // namespace Secret
351
} // namespace Envoy