~ne02ptzero/pistache

27c0c9ed740de6fe084df25ec713993e826e20ce — Louis Solofrizzo 3 months ago 6b217cc work/louis/password_openssl
[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: Louis Solofrizzo <lsolofrizzo@scaleway.com>
M include/pistache/endpoint.h => include/pistache/endpoint.h +4 -2
@@ 109,7 109,8 @@ namespace Pistache::Http
   *
   * \param[in] cert Server certificate 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
   * function will init OpenSSL constants and load *all* algorithms. It will


@@ 125,7 126,8 @@ namespace Pistache::Http
   * [1] https://en.wikipedia.org/wiki/BREACH
   * [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

M include/pistache/listener.h => include/pistache/listener.h +1 -1
@@ 87,7 87,7 @@ namespace Pistache::Tcp
        void pinWorker(size_t worker, const CpuSet& set);

        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,
                          int (*cb)(int, void*));


M src/server/endpoint.cc => src/server/endpoint.cc +2 -2
@@ 248,12 248,12 @@ namespace Pistache::Http

    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
        throw std::runtime_error("Pistache is not compiled with SSL support.");
#else
        listener.setupSSL(cert, key, use_compression);
        listener.setupSSL(cert, key, use_compression, pass_cb);
#endif /* PISTACHE_USE_SSL */
    }


M src/server/listener.cc => src/server/listener.cc +12 -3
@@ 84,7 84,8 @@ namespace Pistache::Tcp

        ssl::SSLCtxPtr ssl_create_context(const std::string& cert,
                                          const std::string& key,
                                          bool use_compression)
                                          bool use_compression,
                                          int (*cb)(char *, int, int, void *))
        {
            const SSL_METHOD* method = SSLv23_server_method();



@@ 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 */
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
            SSL_CTX_set_ecdh_auto(GetSSLContext(ctx), 1);


@@ 576,14 583,16 @@ namespace Pistache::Tcp
    }

    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();
        OpenSSL_add_ssl_algorithms();

        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)
        {