Coverage Report

Created: 2024-09-19 09:45

/proc/self/cwd/source/common/tls/ssl_socket.h
Line
Count
Source (jump to first uncovered line)
1
#pragma once
2
3
#include <cstdint>
4
#include <string>
5
6
#include "envoy/network/connection.h"
7
#include "envoy/network/transport_socket.h"
8
#include "envoy/secret/secret_callbacks.h"
9
#include "envoy/ssl/handshaker.h"
10
#include "envoy/ssl/private_key/private_key_callbacks.h"
11
#include "envoy/ssl/ssl_socket_extended_info.h"
12
#include "envoy/ssl/ssl_socket_state.h"
13
#include "envoy/stats/scope.h"
14
#include "envoy/stats/stats_macros.h"
15
16
#include "source/common/common/logger.h"
17
#include "source/common/network/transport_socket_options_impl.h"
18
#include "source/common/tls/context_impl.h"
19
#include "source/common/tls/ssl_handshaker.h"
20
#include "source/common/tls/utility.h"
21
22
#include "absl/container/node_hash_map.h"
23
#include "absl/synchronization/mutex.h"
24
#include "absl/types/optional.h"
25
#include "openssl/ssl.h"
26
27
namespace Envoy {
28
namespace Extensions {
29
namespace TransportSockets {
30
namespace Tls {
31
32
#define ALL_SSL_SOCKET_FACTORY_STATS(COUNTER)                                                      \
33
0
  COUNTER(ssl_context_update_by_sds)                                                               \
34
0
  COUNTER(upstream_context_secrets_not_ready)                                                      \
35
0
  COUNTER(downstream_context_secrets_not_ready)
36
37
/**
38
 * Wrapper struct for SSL socket factory stats. @see stats_macros.h
39
 */
40
struct SslSocketFactoryStats {
41
  ALL_SSL_SOCKET_FACTORY_STATS(GENERATE_COUNTER_STRUCT)
42
};
43
44
enum class InitialState { Client, Server };
45
46
class SslSocket : public Network::TransportSocket,
47
                  public Envoy::Ssl::PrivateKeyConnectionCallbacks,
48
                  public Ssl::HandshakeCallbacks,
49
                  protected Logger::Loggable<Logger::Id::connection> {
50
public:
51
  static absl::StatusOr<std::unique_ptr<SslSocket>>
52
  create(Envoy::Ssl::ContextSharedPtr ctx, InitialState state,
53
         const Network::TransportSocketOptionsConstSharedPtr& transport_socket_options,
54
         Ssl::HandshakerFactoryCb handshaker_factory_cb);
55
56
  // Network::TransportSocket
57
  void setTransportSocketCallbacks(Network::TransportSocketCallbacks& callbacks) override;
58
  std::string protocol() const override;
59
  absl::string_view failureReason() const override;
60
0
  bool canFlushClose() override { return info_->state() == Ssl::SocketState::HandshakeComplete; }
61
  void closeSocket(Network::ConnectionEvent close_type) override;
62
  Network::IoResult doRead(Buffer::Instance& read_buffer) override;
63
  Network::IoResult doWrite(Buffer::Instance& write_buffer, bool end_stream) override;
64
  void onConnected() override;
65
  Ssl::ConnectionInfoConstSharedPtr ssl() const override;
66
0
  bool startSecureTransport() override { return false; }
67
0
  void configureInitialCongestionWindow(uint64_t, std::chrono::microseconds) override {}
68
  // Ssl::PrivateKeyConnectionCallbacks
69
  void onPrivateKeyMethodComplete() override;
70
  // Ssl::HandshakeCallbacks
71
  Network::Connection& connection() const override;
72
  void onSuccess(SSL* ssl) override;
73
  void onFailure() override;
74
0
  Network::TransportSocketCallbacks* transportSocketCallbacks() override { return callbacks_; }
75
  void onAsynchronousCertValidationComplete() override;
76
  void onAsynchronousCertificateSelectionComplete() override;
77
78
0
  SSL* rawSslForTest() const { return rawSsl(); }
79
80
protected:
81
0
  SSL* rawSsl() const { return info_->ssl(); }
82
83
private:
84
  SslSocket(Envoy::Ssl::ContextSharedPtr ctx,
85
            const Network::TransportSocketOptionsConstSharedPtr& transport_socket_options);
86
  absl::Status initialize(InitialState state, Ssl::HandshakerFactoryCb handshaker_factory_cb);
87
88
  struct ReadResult {
89
    uint64_t bytes_read_{0};
90
    absl::optional<int> error_;
91
  };
92
  ReadResult sslReadIntoSlice(Buffer::RawSlice& slice);
93
94
  Network::PostIoAction doHandshake();
95
  void drainErrorQueue();
96
  void shutdownSsl();
97
  void shutdownBasic();
98
  void resumeHandshake();
99
100
  const Network::TransportSocketOptionsConstSharedPtr transport_socket_options_;
101
  Network::TransportSocketCallbacks* callbacks_{};
102
  ContextImplSharedPtr ctx_;
103
  uint64_t bytes_to_retry_{};
104
  std::string failure_reason_;
105
106
  SslHandshakerImplSharedPtr info_;
107
};
108
109
class InvalidSslSocket : public Network::TransportSocket {
110
public:
111
  // Network::TransportSocket
112
0
  void setTransportSocketCallbacks(Network::TransportSocketCallbacks&) override {}
113
0
  std::string protocol() const override { return EMPTY_STRING; }
114
0
  bool canFlushClose() override { return true; }
115
0
  void closeSocket(Network::ConnectionEvent) override {}
116
0
  Network::IoResult doRead(Buffer::Instance&) override {
117
0
    return {Network::PostIoAction::Close, 0, false};
118
0
  }
119
0
  Network::IoResult doWrite(Buffer::Instance&, bool) override {
120
0
    return {Network::PostIoAction::Close, 0, false};
121
0
  }
122
0
  void onConnected() override {}
123
0
  Ssl::ConnectionInfoConstSharedPtr ssl() const override { return nullptr; }
124
0
  bool startSecureTransport() override { return false; }
125
0
  void configureInitialCongestionWindow(uint64_t, std::chrono::microseconds) override {}
126
};
127
128
// This SslSocket will be used when SSL secret is not fetched from SDS server.
129
class NotReadySslSocket : public InvalidSslSocket {
130
public:
131
  // Network::TransportSocket
132
  absl::string_view failureReason() const override;
133
};
134
135
class ErrorSslSocket : public InvalidSslSocket {
136
public:
137
0
  ErrorSslSocket(absl::string_view error) : error_(error) {}
138
139
  // Network::TransportSocket
140
0
  absl::string_view failureReason() const override { return error_; }
141
142
private:
143
  std::string error_;
144
};
145
146
} // namespace Tls
147
} // namespace TransportSockets
148
} // namespace Extensions
149
} // namespace Envoy