still must match obs first
[ghsmtp.git] / TLS-OpenSSL.hpp
blob49f6421105ff40ec715d07b3ac108db34b8e8167
1 #ifndef TLS_OPENSSL_DOT_HPP
2 #define TLS_OPENSSL_DOT_HPP
4 #include "DNS-rrs.hpp"
5 #include "Domain.hpp"
6 #include "fs.hpp"
8 #include <chrono>
9 #include <functional>
11 #include <openssl/ssl.h>
13 namespace Config {
14 auto constexpr cert_verify_depth{10};
16 auto constexpr cert_fn_re = ".+\\.pem$";
17 auto constexpr key_ext = ".key";
19 } // namespace Config
21 class TLS {
22 public:
23 TLS(TLS const&) = delete;
24 TLS& operator=(const TLS&) = delete;
26 explicit TLS(std::function<void(void)> read_hook);
27 ~TLS();
29 bool starttls_client(fs::path config_path,
30 int fd_in,
31 int fd_out,
32 char const* client_name,
33 char const* server_name,
34 DNS::RR_collection const& tlsa_rrs,
35 bool enforce_dane,
36 std::chrono::milliseconds timeout);
37 bool starttls_server(fs::path config_path,
38 int fd_in,
39 int fd_out,
40 std::chrono::milliseconds timeout);
42 bool pending() const { return SSL_pending(ssl_) > 0; }
44 std::streamsize
45 read(char* s, std::streamsize n, std::chrono::milliseconds wait, bool& t_o)
47 return io_tls_("SSL_read", SSL_read, s, n, wait, t_o);
49 std::streamsize write(const char* c_s,
50 std::streamsize n,
51 std::chrono::milliseconds wait,
52 bool& t_o)
54 auto s = const_cast<char*>(c_s);
55 return io_tls_("SSL_write", SSL_write, s, n, wait, t_o);
58 std::string info() const;
60 std::string const& verified_peername() const { return verified_peername_; }
61 bool verified() const { return verified_; }
63 struct per_cert_ctx {
64 explicit per_cert_ctx(SSL_CTX* ctx_, std::vector<Domain> cn_)
65 : ctx(ctx_)
66 , cn(cn_)
70 SSL_CTX* ctx;
71 std::vector<Domain> cn;
74 private:
75 std::streamsize io_tls_(char const* fn,
76 std::function<int(SSL*, void*, int)> io_fnc,
77 char* s,
78 std::streamsize n,
79 std::chrono::milliseconds wait,
80 bool& t_o);
82 static void ssl_error(int n_err) __attribute__((noreturn));
84 private:
85 SSL* ssl_{nullptr};
87 std::vector<per_cert_ctx> cert_ctx_;
89 std::function<void(void)> read_hook_;
91 std::string verified_peername_;
92 bool verified_{false};
95 #endif // TLS_OPENSSL_DOT_HPP