-
Notifications
You must be signed in to change notification settings - Fork 373
/
openssl_server.cpp
114 lines (100 loc) · 3.47 KB
/
openssl_server.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include <net/https/openssl_server.hpp>
#include <net/openssl/init.hpp>
#include <net/openssl/tls_stream.hpp>
#include <memdisk>
#define LOAD_FROM_MEMDISK
namespace http
{
// https://gist.github.com/darrenjs/4645f115d10aa4b5cebf57483ec82eca
inline void handle_error(const char* file, int lineno, const char* msg) {
fprintf(stderr, "** %s:%i %s\n", file, lineno, msg);
ERR_print_errors_fp(stderr);
exit(1);
}
#define int_error(msg) handle_error(__FILE__, __LINE__, msg)
static void
tls_load_from_memory(SSL_CTX* ctx,
fs::Buffer cert_buffer,
fs::Buffer key_buffer)
{
auto* cbio = BIO_new_mem_buf(cert_buffer.data(), cert_buffer.size());
auto* cert = PEM_read_bio_X509(cbio, NULL, 0, NULL);
assert(cert != NULL);
SSL_CTX_use_certificate(ctx, cert);
BIO_free(cbio);
auto* kbio = BIO_new_mem_buf(key_buffer.data(), key_buffer.size());
auto* key = PEM_read_bio_RSAPrivateKey(kbio, NULL, 0, NULL);
assert(key != NULL);
SSL_CTX_use_RSAPrivateKey(ctx, key);
BIO_free(kbio);
}
SSL_CTX* tls_init_server(const char* cert_file, const char* key_file)
{
/* create the SSL server context */
auto* ctx = SSL_CTX_new(TLSv1_2_method());
if (!ctx) throw std::runtime_error("SSL_CTX_new()");
int res = SSL_CTX_set_cipher_list(ctx, "AES256-SHA");
assert(res == 1);
#ifdef LOAD_FROM_MEMDISK
auto& filesys = fs::memdisk().fs();
// load CA certificate
auto ca_cert_buffer = filesys.read_file(cert_file);
// load CA private key
auto ca_key_buffer = filesys.read_file(key_file);
// use in SSL CTX
tls_load_from_memory(ctx, ca_cert_buffer, ca_key_buffer);
#else
/* Load certificate and private key files, and check consistency */
int err;
err = SSL_CTX_use_certificate_file(ctx, cert_file, SSL_FILETYPE_PEM);
if (err != 1)
int_error("SSL_CTX_use_certificate_file failed");
/* Indicate the key file to be used */
err = SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM);
if (err != 1)
int_error("SSL_CTX_use_PrivateKey_file failed");
#endif
/* Make sure the key and certificate file match. */
if (SSL_CTX_check_private_key(ctx) != 1)
int_error("SSL_CTX_check_private_key failed");
/* Recommended to avoid SSLv2 & SSLv3 */
SSL_CTX_set_options(ctx, SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3);
int error = ERR_get_error();
if (error) {
printf("Status: %s\n", ERR_error_string(error, nullptr));
}
assert(error == SSL_ERROR_NONE);
return ctx;
}
void OpenSSL_server::openssl_initialize(const std::string& certif,
const std::string& key)
{
fs::memdisk().init_fs(
[] (auto err, auto&) {
assert(!err);
});
/** INIT OPENSSL **/
openssl::init();
/** SETUP CUSTOM RNG **/
//openssl::setup_rng();
/** VERIFY RNG **/
openssl::verify_rng();
this->m_ctx = tls_init_server(certif.c_str(), key.c_str());
assert(ERR_get_error() == 0);
}
OpenSSL_server::~OpenSSL_server()
{
SSL_CTX_free((SSL_CTX*) this->m_ctx);
}
void OpenSSL_server::bind(const uint16_t port)
{
tcp_.listen(port, {this, &OpenSSL_server::on_connect});
INFO("HTTPS Server", "Listening on port %u", port);
}
void OpenSSL_server::on_connect(TCP_conn conn)
{
connect(
std::make_unique<openssl::TLS_stream> ((SSL_CTX*) m_ctx, std::make_unique<net::tcp::Connection::Stream>(std::move(conn)))
);
}
} // http