1
#include "source/common/tls/server_ssl_socket.h"
2

            
3
#include "envoy/stats/scope.h"
4

            
5
#include "source/common/common/assert.h"
6
#include "source/common/common/empty_string.h"
7
#include "source/common/common/hex.h"
8
#include "source/common/http/headers.h"
9
#include "source/common/runtime/runtime_features.h"
10
#include "source/common/tls/io_handle_bio.h"
11
#include "source/common/tls/ssl_handshaker.h"
12
#include "source/common/tls/utility.h"
13

            
14
#include "absl/strings/str_replace.h"
15
#include "openssl/err.h"
16
#include "openssl/x509v3.h"
17

            
18
namespace Envoy {
19
namespace Extensions {
20
namespace TransportSockets {
21
namespace Tls {
22

            
23
namespace {
24
1329
SslSocketFactoryStats generateStats(Stats::Scope& store) {
25
1329
  return {ALL_SSL_SOCKET_FACTORY_STATS(POOL_COUNTER_PREFIX(store, "server_ssl_socket_factory."))};
26
1329
}
27
} // namespace
28

            
29
absl::StatusOr<std::unique_ptr<ServerSslSocketFactory>>
30
ServerSslSocketFactory::create(Envoy::Ssl::ServerContextConfigPtr config,
31
1329
                               Envoy::Ssl::ContextManager& manager, Stats::Scope& stats_scope) {
32
1329
  absl::Status creation_status = absl::OkStatus();
33
1329
  auto ret = std::unique_ptr<ServerSslSocketFactory>(
34
1329
      new ServerSslSocketFactory(std::move(config), manager, stats_scope, creation_status));
35
1329
  RETURN_IF_NOT_OK(creation_status);
36
1316
  return ret;
37
1329
}
38

            
39
ServerSslSocketFactory::ServerSslSocketFactory(Envoy::Ssl::ServerContextConfigPtr config,
40
                                               Envoy::Ssl::ContextManager& manager,
41
                                               Stats::Scope& stats_scope,
42
                                               absl::Status& creation_status)
43
1329
    : manager_(manager), stats_scope_(stats_scope), stats_(generateStats(stats_scope)),
44
1329
      config_(std::move(config)) {
45
1329
  auto ctx_or_error = manager_.createSslServerContext(stats_scope_, *config_, nullptr);
46
1329
  SET_AND_RETURN_IF_NOT_OK(ctx_or_error.status(), creation_status);
47

            
48
1316
  ssl_ctx_ = *ctx_or_error;
49
1316
  config_->setSecretUpdateCallback([this]() { return onAddOrUpdateSecret(); });
50
1316
}
51

            
52
1329
ServerSslSocketFactory::~ServerSslSocketFactory() { manager_.removeContext(ssl_ctx_); }
53

            
54
1392
Network::TransportSocketPtr ServerSslSocketFactory::createDownstreamTransportSocket() const {
55
  // onAddOrUpdateSecret() could be invoked in the middle of checking the existence of ssl_ctx and
56
  // creating SslSocket using ssl_ctx. Capture ssl_ctx_ into a local variable so that we check and
57
  // use the same ssl_ctx to create SslSocket.
58
1392
  Envoy::Ssl::ServerContextSharedPtr ssl_ctx;
59
1392
  {
60
1392
    absl::ReaderMutexLock l(ssl_ctx_mu_);
61
1392
    ssl_ctx = ssl_ctx_;
62
1392
  }
63
1392
  if (ssl_ctx) {
64
1389
    auto status_or_socket = SslSocket::create(std::move(ssl_ctx), InitialState::Server, nullptr,
65
1389
                                              config_->createHandshaker());
66
1389
    if (status_or_socket.ok()) {
67
1389
      return std::move(*status_or_socket);
68
1389
    }
69
    return std::make_unique<ErrorSslSocket>(status_or_socket.status().message());
70
1389
  } else {
71
3
    ENVOY_LOG(debug, "Create NotReadySslSocket");
72
3
    stats_.downstream_context_secrets_not_ready_.inc();
73
3
    return std::make_unique<NotReadySslSocket>();
74
3
  }
75
1392
}
76

            
77
65
bool ServerSslSocketFactory::implementsSecureTransport() const { return true; }
78

            
79
34
absl::Status ServerSslSocketFactory::onAddOrUpdateSecret() {
80
34
  ENVOY_LOG(debug, "Secret is updated.");
81
34
  auto ctx_or_error = manager_.createSslServerContext(stats_scope_, *config_, nullptr);
82
34
  RETURN_IF_NOT_OK(ctx_or_error.status());
83
34
  {
84
34
    absl::WriterMutexLock l(ssl_ctx_mu_);
85
34
    std::swap(*ctx_or_error, ssl_ctx_);
86
34
  }
87
34
  manager_.removeContext(*ctx_or_error);
88

            
89
34
  stats_.ssl_context_update_by_sds_.inc();
90
34
  return absl::OkStatus();
91
34
}
92

            
93
} // namespace Tls
94
} // namespace TransportSockets
95
} // namespace Extensions
96
} // namespace Envoy