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.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
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
19 * Copyright 2015 Cloudius Systems
26 #include <boost/any.hpp>
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>
39 class connected_socket;
43 * Relatively thin SSL wrapper for socket IO.
44 * (Can be expanded to other IO forms).
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.
53 enum class x509_crt_format {
58 typedef compat::basic_string_view<char> blob;
62 class server_credentials;
63 class certificate_credentials;
64 class credentials_builder;
67 * Diffie-Hellman parameters for
79 dh_params(level = level::LEGACY);
80 // loads a key from data
81 dh_params(const blob&, x509_crt_format);
84 dh_params(dh_params&&) noexcept;
85 dh_params& operator=(dh_params&&) noexcept;
87 dh_params(const dh_params&) = delete;
88 dh_params& operator=(const dh_params&) = delete;
90 /** loads a key from file */
91 static future<dh_params> from_file(const sstring&, x509_crt_format);
94 friend class server_credentials;
95 friend class certificate_credentials;
96 std::unique_ptr<impl> _impl;
100 x509_cert(const blob&, x509_crt_format);
102 static future<x509_cert> from_file(const sstring&, x509_crt_format);
105 x509_cert(shared_ptr<impl>);
106 shared_ptr<impl> _impl;
109 class abstract_credentials {
111 virtual ~abstract_credentials() {};
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;
117 virtual void set_simple_pkcs12(const blob&, x509_crt_format, const sstring& password) = 0;
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);
123 future<> set_simple_pkcs12_file(const sstring& pkcs12file, x509_crt_format, const sstring& password);
127 * Holds certificates and keys.
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
135 class certificate_credentials : public abstract_credentials {
137 certificate_credentials();
138 ~certificate_credentials();
140 certificate_credentials(certificate_credentials&&) noexcept;
141 certificate_credentials& operator=(certificate_credentials&&) noexcept;
143 certificate_credentials(const certificate_credentials&) = delete;
144 certificate_credentials& operator=(const certificate_credentials&) = delete;
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;
152 * Loads default system cert trust file
155 future<> set_system_trust();
157 // TODO add methods for certificate verification
160 * TLS handshake priority string. See gnutls docs and syntax at
161 * https://gnutls.org/manual/html_node/Priority-Strings.html
163 * Allows specifying order and allowance for handshake alg.
165 void set_priority_string(const sstring&);
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;
175 /** Exception thrown on certificate validation error */
176 class verification_error : public std::runtime_error {
178 using runtime_error::runtime_error;
181 enum class client_auth {
182 NONE, REQUEST, REQUIRE
186 * Extending certificates and keys for server usage.
187 * More probably goes in here...
189 class server_credentials : public certificate_credentials {
191 server_credentials(shared_ptr<dh_params>);
192 server_credentials(const dh_params&);
194 server_credentials(server_credentials&&) noexcept;
195 server_credentials& operator=(server_credentials&&) noexcept;
197 server_credentials(const server_credentials&) = delete;
198 server_credentials& operator=(const server_credentials&) = delete;
200 void set_client_auth(client_auth);
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
209 * Note that loading invalid objects (malformed certs etc) will
210 * _not_ generate exceptions until, earliest, the build functions
213 class credentials_builder : public abstract_credentials {
215 void set_dh_level(dh_params::level = dh_params::level::LEGACY);
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;
222 future<> set_system_trust();
223 void set_client_auth(client_auth);
224 void set_priority_string(const sstring&);
226 void apply_to(certificate_credentials&) const;
228 shared_ptr<certificate_credentials> build_certificate_credentials() const;
229 shared_ptr<server_credentials> build_server_credentials() const;
232 std::multimap<sstring, boost::any> _blobs;
233 client_auth _client_auth = client_auth::NONE;
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).
243 * \param name An optional expected server name for the remote end point
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 = {});
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).
256 * \param name An optional expected server name for the remote end point
259 ::seastar::socket socket(shared_ptr<certificate_credentials>, sstring name = {});
262 /** Wraps an existing connection in SSL/TLS. */
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&&);
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.
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);