Gabe
Gabe

Reputation: 135

Can't use openssl server because the ciphers are outdated...or something...ERR_SSL_VERSION_OR_CIPHER_MISMATCH

This question is a bit easier than my last one so hopefully I'll get literally any response like at least a comment (please.)

I am trying to create a simple tls socket server using OpenSSL, but can't complete a handshake because my server doesn't have any ciphers that any browser will use (that's what I deduce.) Chrome says "ERR_SSL_VERSION_OR_CIPHER_MISMATCH" and Firefox says "SSL_ERROR_NO_CYPHER_OVERLAP." The program itself keeps running.

It's a pretty simple program, so I am not sure why it fails this way. The version of openssl installed on my machine is 1.1.0l-1~deb9u1, but I'm not sure if that's what the compiler actually links when I use -lcrypto or how I would determine that.

int main() {
    SSL_library_init();

    OpenSSL_add_all_algorithms();
    OpenSSL_add_all_ciphers();
    SSL_load_error_strings();
    SSL_CTX* ctx = SSL_CTX_new(TLSv1_2_server_method());

    SSL_CTX_use_certificate_file(ctx, "example-com.cert.pem", SSL_FILETYPE_PEM);
    SSL_CTX_use_PrivateKey_file(ctx, "example-com.key.pem", SSL_FILETYPE_PEM);

    int sd = socket(PF_INET, SOCK_STREAM, 0);
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(8080);
    addr.sin_addr.s_addr = INADDR_ANY;
    bind(sd, (struct sockaddr*) & addr, sizeof(addr));
    listen(sd, 100);
    while (1) {
        struct sockaddr_in clientAddr;
        socklen_t len = sizeof(clientAddr);

        SSL* ssl = SSL_new(ctx);
        int clientFD = accept(sd, NULL, NULL);
        SSL_set_fd(ssl, clientFD);
        SSL_accept(ssl);
        char buf[1024];
        int bytes = SSL_read(ssl, buf, sizeof(buf));
        std::string reply = "HTTP/1.1 301 Moved Permanently\r\nCache-Control: no-store\r\nLocation: https://google.com/ ";
        SSL_write(ssl, reply.c_str(), reply.length());
        SSL_free(ssl);
        close(clientFD);
    }
    close(sd);
    SSL_CTX_free(ctx);
    return 0;
}

edit: According to the man page, TLS_server_method() should be used, but that yielded the same result. I also tried using SSL_CTX_set_options() and SSL_CTX_set_cipher_list() but with same results.

Upvotes: 0

Views: 527

Answers (1)

rekmus
rekmus

Reputation: 71

First, to clean a bit up, instead of:

SSL_CTX* ctx = SSL_CTX_new(TLSv1_2_server_method());

you may try:

const SSL_METHOD *method;
method = SSLv23_server_method();    /* negotiate the highest protocol version supported by both the server and the client */

M_ssl_ctx = SSL_CTX_new(method);    /* create new context from method */

if ( M_ssl_ctx == NULL )
{
    // error message
    return -1;
}

SSLv23_server_method() ensures compatibility with older OpenSSL versions and now is simply a macro replacing it with TLS_server_method().

Then (before certificates) you may need to add:

if ( SSL_CTX_set_ecdh_auto(M_ssl_ctx, 1) <= 0 )
{
    // error message
    return -1;
}

Older SSL versions required this to support elliptic curves algorithms.

Upvotes: 2

Related Questions