]> git.proxmox.com Git - ceph.git/blob - ceph/src/seastar/include/seastar/net/tls.hh
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / seastar / include / seastar / net / tls.hh
1 /*
2 * This file is open source software, licensed to you under the terms
3 * of the Apache License, Version 2.0 (the "License"). See the NOTICE file
4 * distributed with this work for additional information regarding copyright
5 * ownership. You may not use this file except in compliance with the License.
6 *
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,
12 * software distributed under the License is distributed on an
13 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 * KIND, either express or implied. See the License for the
15 * specific language governing permissions and limitations
16 * under the License.
17 */
18 /*
19 * Copyright 2015 Cloudius Systems
20 */
21 #pragma once
22
23 #include <vector>
24 #include <map>
25
26 #include <boost/any.hpp>
27
28 #include <seastar/core/future.hh>
29 #include <seastar/core/sstring.hh>
30 #include <seastar/core/shared_ptr.hh>
31 #include <seastar/net/socket_defs.hh>
32 #include <seastar/util/std-compat.hh>
33 #include <seastar/net/api.hh>
34
35 namespace seastar {
36
37 class socket;
38 class server_socket;
39 class connected_socket;
40 class socket_address;
41
42 /**
43 * Relatively thin SSL wrapper for socket IO.
44 * (Can be expanded to other IO forms).
45 *
46 * The current underlying mechanism is
47 * gnutls, however, all interfaces are kept
48 * agnostic, so in theory it could be replaced
49 * with OpenSSL or similar.
50 *
51 */
52 namespace tls {
53 enum class x509_crt_format {
54 DER,
55 PEM,
56 };
57
58 typedef compat::basic_string_view<char> blob;
59
60 class session;
61 class server_session;
62 class server_credentials;
63 class certificate_credentials;
64 class credentials_builder;
65
66 /**
67 * Diffie-Hellman parameters for
68 * wire encryption.
69 */
70 class dh_params {
71 public:
72 // Key strength
73 enum class level {
74 LEGACY = 2,
75 MEDIUM = 3,
76 HIGH = 4,
77 ULTRA = 5
78 };
79 dh_params(level = level::LEGACY);
80 // loads a key from data
81 dh_params(const blob&, x509_crt_format);
82 ~dh_params();
83
84 dh_params(dh_params&&) noexcept;
85 dh_params& operator=(dh_params&&) noexcept;
86
87 dh_params(const dh_params&) = delete;
88 dh_params& operator=(const dh_params&) = delete;
89
90 /** loads a key from file */
91 static future<dh_params> from_file(const sstring&, x509_crt_format);
92 private:
93 class impl;
94 friend class server_credentials;
95 friend class certificate_credentials;
96 std::unique_ptr<impl> _impl;
97 };
98
99 class x509_cert {
100 x509_cert(const blob&, x509_crt_format);
101
102 static future<x509_cert> from_file(const sstring&, x509_crt_format);
103 private:
104 class impl;
105 x509_cert(shared_ptr<impl>);
106 shared_ptr<impl> _impl;
107 };
108
109 class abstract_credentials {
110 public:
111 virtual ~abstract_credentials() {};
112
113 virtual void set_x509_trust(const blob&, x509_crt_format) = 0;
114 virtual void set_x509_crl(const blob&, x509_crt_format) = 0;
115 virtual void set_x509_key(const blob& cert, const blob& key, x509_crt_format) = 0;
116
117 virtual void set_simple_pkcs12(const blob&, x509_crt_format, const sstring& password) = 0;
118
119 future<> set_x509_trust_file(const sstring& cafile, x509_crt_format);
120 future<> set_x509_crl_file(const sstring& crlfile, x509_crt_format);
121 future<> set_x509_key_file(const sstring& cf, const sstring& kf, x509_crt_format);
122
123 future<> set_simple_pkcs12_file(const sstring& pkcs12file, x509_crt_format, const sstring& password);
124 };
125
126 /**
127 * Holds certificates and keys.
128 *
129 * Typically, credentials are shared for multiple client/server
130 * sessions. Changes to the credentials object will affect all
131 * sessions instantiated with it.
132 * You should probably set it up once, before starting client/server
133 * connections.
134 */
135 class certificate_credentials : public abstract_credentials {
136 public:
137 certificate_credentials();
138 ~certificate_credentials();
139
140 certificate_credentials(certificate_credentials&&) noexcept;
141 certificate_credentials& operator=(certificate_credentials&&) noexcept;
142
143 certificate_credentials(const certificate_credentials&) = delete;
144 certificate_credentials& operator=(const certificate_credentials&) = delete;
145
146 void set_x509_trust(const blob&, x509_crt_format) override;
147 void set_x509_crl(const blob&, x509_crt_format) override;
148 void set_x509_key(const blob& cert, const blob& key, x509_crt_format) override;
149 void set_simple_pkcs12(const blob&, x509_crt_format, const sstring& password) override;
150
151 /**
152 * Loads default system cert trust file
153 * into this object.
154 */
155 future<> set_system_trust();
156
157 // TODO add methods for certificate verification
158
159 /**
160 * TLS handshake priority string. See gnutls docs and syntax at
161 * https://gnutls.org/manual/html_node/Priority-Strings.html
162 *
163 * Allows specifying order and allowance for handshake alg.
164 */
165 void set_priority_string(const sstring&);
166 private:
167 class impl;
168 friend class session;
169 friend class server_session;
170 friend class server_credentials;
171 friend class credentials_builder;
172 std::unique_ptr<impl> _impl;
173 };
174
175 /** Exception thrown on certificate validation error */
176 class verification_error : public std::runtime_error {
177 public:
178 using runtime_error::runtime_error;
179 };
180
181 enum class client_auth {
182 NONE, REQUEST, REQUIRE
183 };
184
185 /**
186 * Extending certificates and keys for server usage.
187 * More probably goes in here...
188 */
189 class server_credentials : public certificate_credentials {
190 public:
191 server_credentials(shared_ptr<dh_params>);
192 server_credentials(const dh_params&);
193
194 server_credentials(server_credentials&&) noexcept;
195 server_credentials& operator=(server_credentials&&) noexcept;
196
197 server_credentials(const server_credentials&) = delete;
198 server_credentials& operator=(const server_credentials&) = delete;
199
200 void set_client_auth(client_auth);
201 };
202
203 /**
204 * Intentionally "primitive", and more importantly, copyable
205 * container for certificate credentials options.
206 * The intendend use case is to be able to use across shards,
207 * at, say, initialization of tls objects
208 *
209 * Note that loading invalid objects (malformed certs etc) will
210 * _not_ generate exceptions until, earliest, the build functions
211 * are called.
212 */
213 class credentials_builder : public abstract_credentials {
214 public:
215 void set_dh_level(dh_params::level = dh_params::level::LEGACY);
216
217 void set_x509_trust(const blob&, x509_crt_format) override ;
218 void set_x509_crl(const blob&, x509_crt_format) override;
219 void set_x509_key(const blob& cert, const blob& key, x509_crt_format) override;
220 void set_simple_pkcs12(const blob&, x509_crt_format, const sstring& password) override;
221
222 future<> set_system_trust();
223 void set_client_auth(client_auth);
224 void set_priority_string(const sstring&);
225
226 void apply_to(certificate_credentials&) const;
227
228 shared_ptr<certificate_credentials> build_certificate_credentials() const;
229 shared_ptr<server_credentials> build_server_credentials() const;
230
231 private:
232 std::multimap<sstring, boost::any> _blobs;
233 client_auth _client_auth = client_auth::NONE;
234 sstring _priority;
235 };
236
237 /**
238 * Creates a TLS client connection using the default network stack and the
239 * supplied credentials.
240 * Typically these should contain enough information
241 * to validate the remote certificate (i.e. trust info).
242 *
243 * \param name An optional expected server name for the remote end point
244 */
245 /// @{
246 future<connected_socket> connect(shared_ptr<certificate_credentials>, socket_address, sstring name = {});
247 future<connected_socket> connect(shared_ptr<certificate_credentials>, socket_address, socket_address local, sstring name = {});
248 /// @}
249
250 /**
251 * Creates a socket through which a TLS client connection can be created,
252 * using the default network stack and the supplied credentials.
253 * Typically these should contain enough information
254 * to validate the remote certificate (i.e. trust info).
255 *
256 * \param name An optional expected server name for the remote end point
257 */
258 /// @{
259 ::seastar::socket socket(shared_ptr<certificate_credentials>, sstring name = {});
260 /// @}
261
262 /** Wraps an existing connection in SSL/TLS. */
263 /// @{
264 future<connected_socket> wrap_client(shared_ptr<certificate_credentials>, connected_socket&&, sstring name = {});
265 future<connected_socket> wrap_server(shared_ptr<server_credentials>, connected_socket&&);
266 /// @}
267
268 /**
269 * Creates a server socket that accepts SSL/TLS clients using default network stack
270 * and the supplied credentials.
271 * The credentials object should contain certificate info
272 * for the server and optionally trust/crl data.
273 */
274 /// @{
275 server_socket listen(shared_ptr<server_credentials>, socket_address sa, listen_options opts = listen_options());
276 // Wraps an existing server socket in SSL
277 server_socket listen(shared_ptr<server_credentials>, server_socket);
278 /// @}
279 }
280 }
281