[SERVER] ssl: Add the possibility for the user to set a password callback

In order to use passphrase-protected keys.
This patch does not change the default behavior:

    server.useSSL("./cert/server.crt", "./cert/server.key");
    $> ./a.out
    Enter PEM pass phrase:
    [...]

    static int password_callback(char *buf, int size, int rwflag, void *u)
    {
        static const char *password = "foobar"; // _Please_ don't do that, that's an example
        strncpy(buf, password, size);
        return strlen(password);
    }

    server.useSSL("./cert/server.crt", "./cert/server.key", false, &password_callback);
    $> ./a.out
    Listening on 0.0.0.0:9080

Key has been generated with:

    $> openssl genrsa -aes128 -passout pass:foobar -out server.key 3072

If you intend to use this feature, please look at the recent
developments on memfd_secret[1] in order to actually store a passphrase
with relative security in memory.

[1] https://lwn.net/Articles/865256/Signed-off-by: default avatarLouis Solofrizzo <lsolofrizzo@scaleway.com>
parent 6b217cc0
...@@ -109,7 +109,8 @@ namespace Pistache::Http ...@@ -109,7 +109,8 @@ namespace Pistache::Http
* *
* \param[in] cert Server certificate path * \param[in] cert Server certificate path
* \param[in] key Server key path * \param[in] key Server key path
* \param[in] use_compression Wether or not use compression on the encryption * \param[in] use_compression Whether or not use compression on the encryption
* \param[in] cb_password OpenSSL callback for a potential key password. See SSL_CTX_set_default_passwd_cb
* *
* Setup the SSL configuration for an endpoint. In order to do that, this * Setup the SSL configuration for an endpoint. In order to do that, this
* function will init OpenSSL constants and load *all* algorithms. It will * function will init OpenSSL constants and load *all* algorithms. It will
...@@ -125,7 +126,8 @@ namespace Pistache::Http ...@@ -125,7 +126,8 @@ namespace Pistache::Http
* [1] https://en.wikipedia.org/wiki/BREACH * [1] https://en.wikipedia.org/wiki/BREACH
* [2] https://en.wikipedia.org/wiki/CRIME * [2] https://en.wikipedia.org/wiki/CRIME
*/ */
void useSSL(const std::string& cert, const std::string& key, bool use_compression = false); void useSSL(const std::string& cert, const std::string& key,
bool use_compression = false, int (*cb_password)(char *, int, int, void *) = NULL);
/*! /*!
* \brief Use SSL certificate authentication on this endpoint * \brief Use SSL certificate authentication on this endpoint
......
...@@ -87,7 +87,7 @@ namespace Pistache::Tcp ...@@ -87,7 +87,7 @@ namespace Pistache::Tcp
void pinWorker(size_t worker, const CpuSet& set); void pinWorker(size_t worker, const CpuSet& set);
void setupSSL(const std::string& cert_path, const std::string& key_path, void setupSSL(const std::string& cert_path, const std::string& key_path,
bool use_compression); bool use_compression, int (*cb_password)(char *, int, int, void *));
void setupSSLAuth(const std::string& ca_file, const std::string& ca_path, void setupSSLAuth(const std::string& ca_file, const std::string& ca_path,
int (*cb)(int, void*)); int (*cb)(int, void*));
......
...@@ -248,12 +248,12 @@ namespace Pistache::Http ...@@ -248,12 +248,12 @@ namespace Pistache::Http
void Endpoint::shutdown() { listener.shutdown(); } void Endpoint::shutdown() { listener.shutdown(); }
void Endpoint::useSSL([[maybe_unused]] const std::string& cert, [[maybe_unused]] const std::string& key, [[maybe_unused]] bool use_compression) void Endpoint::useSSL([[maybe_unused]] const std::string& cert, [[maybe_unused]] const std::string& key, [[maybe_unused]] bool use_compression, [[maybe_unused]] int (*pass_cb)(char *, int, int, void *))
{ {
#ifndef PISTACHE_USE_SSL #ifndef PISTACHE_USE_SSL
throw std::runtime_error("Pistache is not compiled with SSL support."); throw std::runtime_error("Pistache is not compiled with SSL support.");
#else #else
listener.setupSSL(cert, key, use_compression); listener.setupSSL(cert, key, use_compression, pass_cb);
#endif /* PISTACHE_USE_SSL */ #endif /* PISTACHE_USE_SSL */
} }
......
...@@ -84,7 +84,8 @@ namespace Pistache::Tcp ...@@ -84,7 +84,8 @@ namespace Pistache::Tcp
ssl::SSLCtxPtr ssl_create_context(const std::string& cert, ssl::SSLCtxPtr ssl_create_context(const std::string& cert,
const std::string& key, const std::string& key,
bool use_compression) bool use_compression,
int (*cb)(char *, int, int, void *))
{ {
const SSL_METHOD* method = SSLv23_server_method(); const SSL_METHOD* method = SSLv23_server_method();
...@@ -105,6 +106,12 @@ namespace Pistache::Tcp ...@@ -105,6 +106,12 @@ namespace Pistache::Tcp
} }
} }
if (cb != NULL)
{
/* Use the user-defined callback for password if provided */
SSL_CTX_set_default_passwd_cb(GetSSLContext(ctx), cb);
}
/* Function introduced in 1.0.2 */ /* Function introduced in 1.0.2 */
#if OPENSSL_VERSION_NUMBER >= 0x10002000L #if OPENSSL_VERSION_NUMBER >= 0x10002000L
SSL_CTX_set_ecdh_auto(GetSSLContext(ctx), 1); SSL_CTX_set_ecdh_auto(GetSSLContext(ctx), 1);
...@@ -576,14 +583,16 @@ namespace Pistache::Tcp ...@@ -576,14 +583,16 @@ namespace Pistache::Tcp
} }
void Listener::setupSSL(const std::string& cert_path, void Listener::setupSSL(const std::string& cert_path,
const std::string& key_path, bool use_compression) const std::string& key_path,
bool use_compression,
int (*cb_password)(char *, int, int, void *))
{ {
SSL_load_error_strings(); SSL_load_error_strings();
OpenSSL_add_ssl_algorithms(); OpenSSL_add_ssl_algorithms();
try try
{ {
ssl_ctx_ = ssl_create_context(cert_path, key_path, use_compression); ssl_ctx_ = ssl_create_context(cert_path, key_path, use_compression, cb_password);
} }
catch (std::exception& e) catch (std::exception& e)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment