Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to use ECDHE-ECDSA-AES128-SHA256 cipher suite with Restbed #86

Open
markelkins opened this issue Apr 12, 2016 · 11 comments · May be fixed by #90
Open

Unable to use ECDHE-ECDSA-AES128-SHA256 cipher suite with Restbed #86

markelkins opened this issue Apr 12, 2016 · 11 comments · May be fixed by #90
Assignees
Projects
Milestone

Comments

@markelkins
Copy link
Contributor

I need to use HTTPS with the ECDHE-ECDSA-AES128-SHA256 cipher suite, but I cannot seem to get Restbed to use this cipher suite. The error I get is "no shared cipher" when I connect using cURL and specify the cipher suite above. I have configured the server to use a ECC secp256p1 keypair. Any thoughts on how to get this working? I'm working on Darwin 10.3.

For reference here is the code I have so far for the server:

#include <memory>
#include <cstdlib>
#include <restbed>

#include "stderr_logger.h"

using namespace std;
using namespace restbed;

/**
 * POST request handler for /ping endpoint. Returns 204 NO CONTENT.
 */
void ping_post_method_handler(const shared_ptr<Session> session)
{
    const auto request = session->get_request();

    size_t content_length = 0;
    request->get_header("Content-Length", content_length);

    session->fetch(
        content_length, [request](const shared_ptr< Session > session, const Bytes & body)
    {
        fprintf(stdout, "%.*s\n", (int) body.size(), body.data());
        session->close(NO_CONTENT, "", {{"Content-Length", "0"}, {"Connection", "close"}});
    } );
}

/**
 * GET request handler for /ping endpoint. Returns 204 NO CONTENT.
 */
void ping_get_method_handler(const shared_ptr< Session > session)
{
    session->close(NO_CONTENT);
}

int main(const int argc, const char** argv)
{
int portNumber = 443;

    if (argc > 1) { // See if port number is specified.
        portNumber = atoi(argv[1]);
    }

    auto pingEndpoint = make_shared<Resource>();
    pingEndpoint->set_path("/ping");
    pingEndpoint->set_method_handler("GET", ping_get_method_handler);
    pingEndpoint->set_method_handler("POST", ping_post_method_handler);

    auto sslSettings = make_shared<SSLSettings>();
    sslSettings->set_http_disabled(true);
    sslSettings->set_port(portNumber);
    sslSettings->set_private_key(Uri("file://ec_privkey.pem"));
    sslSettings->set_certificate(Uri("file://server.crt"));
    sslSettings->set_temporary_diffie_hellman("file://ec_params.pem");

    auto settings = make_shared<Settings>();
    settings->set_ssl_settings(sslSettings);

    Service service;
    service.publish(pingEndpoint);
    service.set_logger(make_shared<StdErrLogger>());
    service.start(settings);

    return EXIT_SUCCESS;
}

Here are the key files I am using. (Don't worry, they are only temporary keys.)

ec_privkey.pem

-----BEGIN EC PARAMETERS-----
BggqhkjOPQMBBw==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIHp42wxVJLTXAHYCv7SXRjyzabukVYeYeCFtE6P6zV1YoAoGCCqGSM49
AwEHoUQDQgAER/NBX0PrUH3PbsI55tlyQhPZtrnoVWQ7knzPD+rApFmu+3OdDhen
G6m8lp1tQzcP6LgOmxy2KnUYXtchbLjqbA==
-----END EC PRIVATE KEY-----

server.crt

-----BEGIN CERTIFICATE-----
MIIBzTCCAXQCCQChyOJTWfQbiDAKBggqhkjOPQQDAjBvMQswCQYDVQQGEwJDQTEQ
MA4GA1UECAwHT250YXJpbzERMA8GA1UEBwwIV2F0ZXJsb28xHjAcBgNVBAoMFVRy
dXN0UG9pbnQgSW5ub3ZhdGlvbjEbMBkGA1UEAwwSVHJ1c3RQb2ludCBUZXN0IFJB
MB4XDTE2MDQxMTE5MDkzNVoXDTI2MDQwOTE5MDkzNVowbzELMAkGA1UEBhMCQ0Ex
EDAOBgNVBAgMB09udGFyaW8xETAPBgNVBAcMCFdhdGVybG9vMR4wHAYDVQQKDBVU
cnVzdFBvaW50IElubm92YXRpb24xGzAZBgNVBAMMElRydXN0UG9pbnQgVGVzdCBS
QTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABEfzQV9D61B9z27COebZckIT2ba5
6FVkO5J8zw/qwKRZrvtznQ4XpxupvJadbUM3D+i4Dpsctip1GF7XIWy46mwwCgYI
KoZIzj0EAwIDRwAwRAIgDiiPD9FSXOaLF1jMDfwv4ECbQtO0wnEUHpCLWl/kAZAC
ICJN84VDkmtrhNTTV7PCHCAK5en8TuPbvYHHtn8r8T0D
-----END CERTIFICATE-----
@ben-crowhurst
Copy link
Member

Please present the commands used to generate certificates/parameters.

openssl genrsa -out ....

Whats the client command used, whats the output of the client command?

@markelkins
Copy link
Contributor Author

The commands were:

openssl ecparam -name secp256r1 -out ec_privkey.pem -genkey
openssl req -new -key ec_privkey.pem -out server.csr
openssl x509 -req -days 3650 -in server.csr -signkey ec_privkey.pem -out server.crt

@callum-kirby
Copy link
Contributor

What is the outcome from openssl ciphers -s.

@ben-crowhurst
Copy link
Member

ben-crowhurst commented Apr 14, 2016

@markelkins I must mention that your organisation looks very security focused.

Please understand that Restbed is not currently working off the latest version of OpenSSL and 4.0 is on hold until ASIO has merged a pending PR.

If your organisation proceeds with commercial licensing we will reiterate this matter, if it remains unresolved.

@markelkins
Copy link
Contributor Author

@ben-crowhurst I appreciate the warning. For now we are just building a server to test some other products we are working on. If we decide to commercialize our server work, we will definitely need to have more discussion with you.

@conz27
Copy link

conz27 commented Apr 19, 2016

@markelkins

openssl ecparam -name secp256r1 -out ec_privkey.pem -genkey

Did this succeed?

I looked up openssl ecparam -list_curves, and secp256r1 was not in the list. The other name for secp256r1 is prime256v1 based on RFC-5480.

Just to be certain, it might be worth trying with -name prime256v1 in case that's confusing OpenSSL.

@conz27
Copy link

conz27 commented Apr 21, 2016

Okay, so I've finally cracked this beast of a problem but I'm not sure that the fix belongs solely in Restbed's codebase. It's a flaw with Boost's ASIO SSL wrapper as well, because it doesn't contain mechanisms to support ECDHE.

Essentially, it's missing the necessary ASIO API to invoke the equivalent of:
sslSettings->set_temporary_diffie_hellman("file://ec_params.pem");
, but for the ECC (Elliptic Curve Cryptography) implementation. Using set_temporary_diffie_hellman() will not work.

I have a hack fix in place that I've tested as working, but I need to figure out how to integrate it properly.

I think this will impact any & all algorithms that rely on ECDHE, not just the cipher mentioned in this issue.

@ben-crowhurst
Copy link
Member

ben-crowhurst commented Apr 21, 2016

Please share the "hack", and great work 👍

@conz27
Copy link

conz27 commented Apr 24, 2016

So essentially, restbed needs to implement a wrapper around the new ASIO function (from pull request above) in the SSL settings context and use it service_impl.cpp.

I've actually got a working wrapper implemented that I used to test ASIO - just need to clean it up a bit.

@conz27 conz27 linked a pull request Apr 25, 2016 that will close this issue
@ben-crowhurst ben-crowhurst modified the milestone: 5.0 Dec 14, 2016
@ben-crowhurst ben-crowhurst modified the milestones: 5.0, 4.6 Apr 23, 2017
@ben-crowhurst ben-crowhurst modified the milestones: 5.0, 4.6 Jul 9, 2017
@ben-crowhurst
Copy link
Member

This issue will be resolved with the 5.0 release, allowing any socket layer to be inserted into the framework. Public beta branch will be available July 2017.

@ben-crowhurst ben-crowhurst added this to To do in Restbed via automation Feb 8, 2020
@ben-crowhurst ben-crowhurst modified the milestones: 5.0, 4.7 Feb 8, 2020
@ben-crowhurst ben-crowhurst modified the milestones: 4.7, 4.8 Feb 23, 2020
@ben-crowhurst ben-crowhurst removed this from the 4.8 milestone Jun 8, 2021
@ben-crowhurst ben-crowhurst added this to the 5.0 milestone Jun 8, 2021
@ben-crowhurst
Copy link
Member

This will finally be possible July 2021. We will expose a NetworkAdaptor interface that will enable OpenSSL, LibreSSL or any other such functionality.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Restbed
  
To do
Development

Successfully merging a pull request may close this issue.

4 participants