1 /* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
2 
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License, version 2.0,
5    as published by the Free Software Foundation.
6 
7    This program is also distributed with certain software (including
8    but not limited to OpenSSL) that is licensed under separate terms,
9    as designated in a particular file or component or in included license
10    documentation.  The authors of MySQL hereby grant you an additional
11    permission to link the program and your derivative works with the
12    separately licensed software that they have included with MySQL.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License, version 2.0, for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
22 
23 #ifndef SSL_ACCEPTOR_CONTEXT_DATA_INCLUDED
24 #define SSL_ACCEPTOR_CONTEXT_DATA_INCLUDED
25 
26 #include <string>
27 
28 #include "my_rcu_lock.h"           /* MyRcuLock */
29 #include "openssl/ossl_typ.h"      /* SSL */
30 #include "sql/ssl_init_callback.h" /* Ssl_init_callback */
31 #include "violite.h"               /* st_VioSSLFd, enum_ssl_init_error */
32 
33 class Ssl_acceptor_context_container;
34 class TLS_channel;
35 class Lock_and_access_ssl_acceptor_context;
36 
37 /**
38   Properties exposed by Ssl Acceptor context
39 
40   Note: Add new value before "last" and update
41         Ssl_acceptor_context_propert_type_names.
42 */
43 enum class Ssl_acceptor_context_property_type {
44   accept_renegotiates = 0,
45   accepts,
46   callback_cache_hits,
47   client_connects,
48   connect_renegotiates,
49   ctx_verify_depth,
50   ctx_verify_mode,
51   current_tls_ca,
52   current_tls_capath,
53   current_tls_cert,
54   current_tls_cipher,
55   current_tls_ciphersuites,
56   current_tls_crl,
57   current_tls_crlpath,
58   current_tls_key,
59   current_tls_version,
60   finished_accepts,
61   finished_connects,
62   server_not_after,
63   server_not_before,
64   session_cache_hits,
65   session_cache_misses,
66   session_cache_mode,
67   session_cache_overflows,
68   session_cache_size,
69   session_cache_timeouts,
70   used_session_cache_entries,
71   last
72 };
73 /**
74   Note: Add new value before "last" and update
75         Ssl_acceptor_context_propert_type_names.
76 */
77 
78 /**
79   Fetch a string representation of SSL acceptor context property
80 
81   @param [in] property_type Property type
82 
83   @returns name of the property
84 */
85 std::string Ssl_ctx_property_name(
86     Ssl_acceptor_context_property_type property_type);
87 
88 /**
89   Increment operator for Ssl_acceptor_context_type
90   Used by iterator
91 
92   @param [in,out] property_type Current position in Ssl_acceptor_context_type
93 
94   @returns incremented value for property_type
95 */
96 Ssl_acceptor_context_property_type &operator++(
97     Ssl_acceptor_context_property_type &property_type);
98 
99 /**
100   Container of SSL Acceptor context data
101 */
102 class Ssl_acceptor_context_data final {
103  public:
104   /**
105    Ctor
106 
107    @param [in]  channel          Name of the channel
108    @param [in]  use_ssl_arg      Don't bother at all to try and construct
109                                  an SSL_CTX and just make an empty
110                                  SslAcceptorContext. Used to pass the
111                                  --ssl/--admin-ssl options at startup.
112    @param [in]  callbacks        TLS context initialization callbacks
113                                  to get values of various options and
114                                  perform validation
115    @param [in]  report_ssl_error Report any SSL errors resulting from trying
116                                  to initialize the SSL_CTX to error log
117    @param [out] out_error        An optional slot to return SSL_CTX
118                                  initialization error information
119   */
120   Ssl_acceptor_context_data(std::string channel, bool use_ssl_arg,
121                             Ssl_init_callback *callbacks,
122                             bool report_ssl_error = true,
123                             enum enum_ssl_init_error *out_error = nullptr);
124 
125   /** Destructor */
126   ~Ssl_acceptor_context_data();
127 
128  protected:
129   /* Disable copy/assignment */
130   Ssl_acceptor_context_data(const Ssl_acceptor_context_data &) = delete;
131   Ssl_acceptor_context_data operator=(const Ssl_acceptor_context_data &) =
132       delete;
133 
134   /* Disable move constructs */
135   Ssl_acceptor_context_data(Ssl_acceptor_context_data &&) = delete;
136   Ssl_acceptor_context_data operator=(Ssl_acceptor_context_data &&) = delete;
137 
138   /**
139     Fetch given property from underlying TLS context
140 
141     @param [in] property_type Property to be fetched
142 
143     @returns Value of property for given context. Empty in case of failure.
144   */
145   std::string show_property(
146       Ssl_acceptor_context_property_type property_type) const;
147 
148   /** TLS context validity */
have_ssl()149   bool have_ssl() const { return ssl_acceptor_fd_ != nullptr; }
150 
151   /** Get channel name */
channel_name()152   const char *channel_name() const { return channel_.c_str(); }
153 
154   /** Get Acceptor context */
155   operator struct st_VioSSLFd *() { return ssl_acceptor_fd_; }
156 
157   /** Get SSL handle */
158   operator SSL *() { return acceptor_; }
159 
160   /** Get current CA */
current_ca()161   const char *current_ca() const { return current_ca_.c_str(); }
162 
163   /** Get current CA Path */
current_capath()164   const char *current_capath() const { return current_capath_.c_str(); }
165 
166   /** Get current Certificate */
current_cert()167   const char *current_cert() const { return current_cert_.c_str(); }
168 
169   /** Get current Key */
current_key()170   const char *current_key() const { return current_key_.c_str(); }
171 
172   /** Get current CRL certificate */
current_crl()173   const char *current_crl() const { return current_crl_.c_str(); }
174 
175   /** Get current CRL Path */
current_crlpath()176   const char *current_crlpath() const { return current_crlpath_.c_str(); }
177 
178   /** Get current TLS version */
current_version()179   const char *current_version() const { return current_version_.c_str(); }
180 
181   /** Get current TLSv1.2 ciphers */
current_cipher()182   const char *current_cipher() const { return current_cipher_.c_str(); }
183 
184   /** Get current TLSv1.3 ciphers */
current_ciphersuites()185   const char *current_ciphersuites() const {
186     return current_ciphersuites_.c_str();
187   }
188 
189  private:
190   /** Channel name */
191   std::string channel_;
192 
193   /** SSL_CTX barerer */
194   struct st_VioSSLFd *ssl_acceptor_fd_;
195 
196   /**
197     An SSL for @ref ssl_acceptor_fd_ to allow access to parameters not in
198     SSL_CTX to be available even if the current connection is not
199     encrypted.
200   */
201   SSL *acceptor_;
202 
203   /**
204     Copies of the current effective values for quick return via the
205     status vars
206   */
207   OptionalString current_ca_, current_capath_, current_version_, current_cert_,
208       current_cipher_, current_ciphersuites_, current_key_, current_crl_,
209       current_crlpath_;
210 
211   /* F.R.I.E.N.D.S. */
212   friend class Ssl_acceptor_context_container;
213   friend class TLS_channel;
214   friend class Lock_and_access_ssl_acceptor_context;
215 };
216 
217 #endif  // SSL_ACCEPTOR_CONTEXT_DATA_INCLUDED
218