Joachim
Joachim

Reputation: 91

"no shared cipher" at ssl_accept, why?

Have googled a lot, not found any answer to the following problem: Created server code and client code, but get

error:1408A0C1:SSL routines:SSL3_GET_CLIENT_HELLO:no shared cipher

at the server when doing SSL_connect.

The code below is narrowed down to the sequence of the SSL / socket related function calls only. Error handling code has been applied where applicable to make sure calls before SSL_accept / SSL_connect does not return any failure codes. I have also left out initialization methods.

I do not know if it matters, but I run both server and client on localhost.

There might be obvious errors, but I am quite new with OpenSSL.

Client code (inparams: hostname, certificate_chain_file, ca_certificate_file):

SSL_library_init();             // <<< To clarify my initialization
OpenSSL_add_all_algorithms();   // <<< To clarify my initialization
SSL_load_error_strings();       // <<< To clarify my initialization
ERR_load_crypto_strings();      // <<< To clarify my initialization (2)
OpenSSL_add_all_ciphers();      // <<< To clarify my initialization (2)
SSL_METHOD const * method = SSLv23_method();  // <<< Updated method
SSL_CTX * ctx = SSL_CTX_new(method);
SSL_CTX_use_certificate_chain_file(ctx, certificate_chain_file));
const long flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION;    // <<< Added
SSL_CTX_set_options(ctx, flags);   // <<< Added
SSL_CTX_load_verify_locations(ctx, ca_certificate_file, NULL));
struct hostent * host = gethostbyname(hostname);
int client_sd = socket(PF_INET, SOCK_STREAM, 0);
struct sockaddr_in server;
memset(&server, 0, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(6789);
server.sin_addr.s_addr = *(long *) (host->h_addr);
connect(client_sd, (struct sockaddr *) &server, sizeof(server));
SSL * ssl = SSL_new(ctx);
SSL_set_fd(ssl, client_sd);
const char * const preferred_ciphers = "HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4";
SSL_set_cipher_list(ssl, preferred_ciphers);   // <<< Added
SSL_set_tlsext_host_name(ssl, hostname);       // <<< Added
mydata_t mydata;
mydata_index_client = SSL_get_ex_new_index(0, (void *) "mydata index", NULL, NULL, NULL);
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_callback_client);
SSL_CTX_set_verify_depth(ctx, 1);
mydata.verify_depth = 0;
SSL_set_ex_data(ssl, mydata_index_client, &mydata);
int connection_result = SSL_connect(ssl);
if (connection_result < 0)
{
  // Comes in here and ERR_get_error indicates
  // error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure
}
else if (connection_result == 0)
{
}
else if (connection_result == 1)
{
}
else
{
}

Server code (inparams: certificate_chain_file, ca_certificate_file):

SSL_library_init();
OpenSSL_add_all_algorithms();
SSL_load_error_strings();
SSL_METHOD const * method = SSLv23_method();
SSL_CTX * ctx = SSL_CTX_new(method);
SSL_CTX_use_certificate_chain_file(ctx, certificate_chain_file);  //Contains only root CA
SSL_CTX_set_default_passwd_cb_userdata(ctx, (void *) private_key_file_password);
SSL_CTX_set_default_passwd_cb(ctx, pem_passwd_cb);
SSL_CTX_load_verify_locations(ctx, ca_certificate_file, NULL);
struct sockaddr_in addr;
int server_sd = create_socket(addr, 6789);
bind(server_sd, (struct sockaddr *) &addr, sizeof(addr));
listen(server_sd, max_nr_of_simultaneous_connections);
sockaddr_in client;
client.sin_family = AF_INET;
socklen_t c_len = sizeof(client);
int client_sd = accept(server_sd, (sockaddr *) &client, &c_len);
char remote_addr[INET_ADDRSTRLEN];
inet_ntop(client.sin_family, &(client.sin_addr), remote_addr, INET_ADDRSTRLEN);
SSL * ssl = SSL_new(ctx);
SSL_set_fd(ssl, client_sd);
const char * const preferred_ciphers = "HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4";
SSL_set_cipher_list(ssl, preferred_ciphers);   // <<< Added
STACK_OF(X509_NAME) * cert_names = SSL_load_client_CA_file(certificate_chain_file);
if (cert_names != NULL)
{
    SSL_CTX_set_client_CA_list(ctx, cert_names);
}
mydata_t mydata;
mydata_index_server = SSL_get_ex_new_index(0, (void *) "mydata index", NULL, NULL, NULL);
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_callback_server);
SSL_CTX_set_verify_depth(ctx, 1);
mydata.verify_depth = 1;
SSL_set_ex_data(ssl, mydata_index_server, &mydata);
int accept_result = SSL_accept(ssl);
if (accept_result == 0)
{
}
else if (accept_result < 0)
{
  // Comes in here and ERR_get_error indicates
  // error:1408A0C1:SSL routines:SSL3_GET_CLIENT_HELLO:no shared cipher
}

EDITED: jww, I have tried the things you suggested below. However, without any progress; I still get the same error output. This is how I have created my certificates:

openssl-ca.cnf

HOME            = .
RANDFILE        = $ENV::HOME/.rnd

####################################################################
[ ca ]
default_ca  = CA_default        # The default ca section

####################################################################
[ CA_default ]
default_days     = 1000          # how long to certify for
default_crl_days = 30            # how long before next CRL
default_md       = sha256        # use public key default MD
preserve         = no            # keep passed DN ordering

x509_extensions  = ca_extensions     # The extensions to add to the cert

email_in_dn      = no            # Don't concat the email in the DN
copy_extensions  = copy          # Required to copy SANs from CSR to cert

base_dir        = .
certificate     = $base_dir/certs/ca_fromweb.cert.pem  # The CA certifcate
private_key     = $base_dir/private/ca.key.pem   # The CA private key
new_certs_dir   = $base_dir     # Location for new certs after signing
database        = $base_dir/index2.txt   # Database index file
serial          = $base_dir/serial2.txt  # The current serial number

unique_subject  = no            # Set to 'no' to allow creation of
                                # several certificates with same subject.

####################################################################
[ req ]
default_bits        = 4096
default_keyfile     = ./private/ca.key.pem
distinguished_name  = ca_distinguished_name
x509_extensions     = ca_extensions
string_mask         = utf8only

####################################################################
[ ca_distinguished_name ]
countryName         = Country Name (2 letter code)
countryName_default = SE

stateOrProvinceName         = State or Province Name (full name)
stateOrProvinceName_default = Östergötland

localityName            = Locality Name (eg, city)
localityName_default    = 

organizationName          = Organization Name (eg, company)
organizationName_default  = 

organizationalUnitName          = Organizational Unit (eg, division)
organizationalUnitName_default  = 

commonName          = Common Name (e.g. server FQDN or YOUR name)
commonName_default  = 

emailAddress            = Email Address
emailAddress_default    = 

####################################################################
[ ca_extensions ]
subjectKeyIdentifier    = hash
authorityKeyIdentifier  = keyid:always, issuer
basicConstraints        = critical, CA:true
keyUsage                = keyCertSign, cRLSign

####################################################################
[ signing_policy ]
countryName             = optional
stateOrProvinceName     = optional
localityName            = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

####################################################################
[ signing_req ]
subjectKeyIdentifier   = hash
authorityKeyIdentifier = keyid,issuer

basicConstraints       = CA:FALSE
keyUsage               = digitalSignature, keyEncipherment

openssl-server.cnf

HOME            = .
RANDFILE        = $ENV::HOME/.rnd

####################################################################
[ req ]
default_bits        = 2048
default_keyfile     = ./intermediate/private/my.example.com.key.pem
distinguished_name  = server_distinguished_name
req_extensions      = server_req_extensions
string_mask         = utf8only

####################################################################
[ server_distinguished_name ]
countryName             = Country Name (2 letter code)
countryName_default     = SE

stateOrProvinceName         = State or Province Name (full name)
stateOrProvinceName_default = Östergötland

localityName            = Locality Name (eg, city)
localityName_default    = Linköping

organizationName            = Organization Name (eg, company)
organizationName_default    = 

commonName          = Common Name (e.g. server FQDN or YOUR name)
commonName_default  = 

emailAddress            = Email Address
emailAddress_default    = 

####################################################################
[ server_req_extensions ]
subjectKeyIdentifier    = hash
basicConstraints        = CA:FALSE
keyUsage                = digitalSignature, keyEncipherment
subjectAltName          = @alternate_names
nsComment               = "OpenSSL Generated Certificate"

####################################################################
[ alternate_names ]
DNS.1       = my.example.com

Commands

 touch index.txt
 echo 1000 > serial
 openssl genrsa -aes256 -out ca.key.pem 4096
 chmod 400 private/ca.key.pem
 openssl req -config openssl-ca.cnf -key ca.key.pem -new -x509 -days 7300 -sha256 -extensions ca_extensions -out ca.cert.pem
 chmod 444 ca.cert.pem

 openssl genrsa -aes256 -out server.key.pem 4096
 openssl req -config openssl-server.cnf -new -sha256 -key server.key.pem -out my.example.com.csr.pem
 openssl ca -config openssl-ca.cnf -policy signing_policy -extensions signing_req -out my.example.com.cert.pem -infiles my.example.com.csr.pem
 chmod 444 my.example.com.cert.pem
 cat ca.cert.pem > ca_chain.cert.pem

EDIT 2: Also tried with

 ERR_load_crypto_strings();      // <<< To clarify my initialization (2)
 OpenSSL_add_all_ciphers();      // <<< To clarify my initialization (2)

See top. Same result.

"Unfortunately, all the initialization function return a useless values (for example, always 1) or are void functions. There is no way to determine if a failure occurred. " - (https://wiki.openssl.org/index.php/Library_Initialization) that sucks!

Upvotes: 7

Views: 55071

Answers (4)

chaitanya kumar
chaitanya kumar

Reputation: 1

I hit this problem very recently. I had tried all the suggestions that are outlined above. None of these resolved the issue.

When i checked the dependencies of my server (radsecproxy is the server that i was running in Ubuntu distro), the server is linked with libssl1.0.

List of ciphers that I was using are below.

DHE-RSA-AES128-GCM-SHA256 DHE-RSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES256-GCM-SHA384

These ciphers are not supported in libssl 1.0. Hence the error "no shared cipher". When libssl 1.1 is linked then the error is not seen and handshake is successful.

ldd can be used to check the dependencies of the software.

Upvotes: 0

asveikau
asveikau

Reputation: 40254

I'm a few years late to this question, but I hit it too and like you, none of the suggestions I found worked.

Frustrated, I built LibreSSL with debug symbols and stepped through ssl3_choose_cipher in a debuger. I noticed that it was inspecting s->cert to disqualify every cipher. s->cert seemed to mostly contain a bunch of null pointers. OTOH I found that s->ctx->internal->cert had the values I had populated (cert, CA chain certs, private key, all of which were NULL in s->cert).

So what fixed it for me was to change a bunch of SSL_CTX_foo to SSL_foo in order to populate the SSL* instead of the SSL_CTX*.

So I would recommend replacing:

SSL_CTX_use_certificate_chain_file(ctx, certificate_chain_file);

With:

SSL_use_certificate_chain_file(ssl, certificate_chain_file);

And for me I replaced:

SSL_CTX_use_PrivateKey(ctx, key);

with:

SSL_use_PrivateKey(ssl, key);

This seems like an absurd distinction but it works for me now.

Upvotes: 2

ayurchen
ayurchen

Reputation: 416

Some older OpenSSL versions, like one in RHEL 7.x require an explicit call to SSL_CTX_set_ecdh_auto() at initialization stage to enable negotiation of advanced algorithms. See e.g. https://wiki.openssl.org/index.php/Simple_TLS_Server

Upvotes: 8

jww
jww

Reputation: 102326

“no shared cipher” at ssl_accept, why?

There could be several reasons for it. Below are some suggestions depending on the problem you are having. I suspect one or more is the answer to your problems.


Client:

SSL_METHOD const * method = SSLv3_client_method();

And:

Server:

SSL_METHOD const * method = SSLv23_method();

You should start by setting "TLS 1.0 and above". You would do that on the client and server with the following. Its from the OpenSSL wiki and SLL/TLS Client example.

const SSL_METHOD* method = SSLv23_method();
if(method == NULL) handleFailure();

ctx = SSL_CTX_new(method);
if(ctx == NULL) handleFailure();

...

/* Cannot fail ??? */
const long flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION;
SSL_CTX_set_options(ctx, flags);

Your client should also use Server Name Indication (SNI). The client utilizes it with SSL_set_tlsext_host_name. SNI is a TLS extension, and its part of the reason you want "TLS 1.0 and above".

Both the client and the server want to use a cipher suite list like "HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4". Set them with either SSL_CTX_set_cipher_list or SSL_set_cipher_list. It avoids the “Your connection to website is encrypted with obsolete cryptography” warnings from the browser.

If you are using Elliptic Curve based certificates, then you need to use a named curve. Also see boost asio with ECDSA certificate issue on Stack Overflow and Elliptic Curve Cryptography | Named Curves on the OpenSSL wiki.

Be sure you initialize the OpenSSL library. If the library is not initialized properly, then there will be no ciphers available, and it can result in "no shared ciphers". Also see Openssl SSL_CTX_new(SSLv3_method()) returns NULL on Stack Overflow and Library Initialization on the OpenSSL wiki.

If you are creating your own certificate, then be sure you put hostnames in the in the Subject Alternate Name (SAN). Hostnames always go in the SAN. If its present in the CN, then it must be present in the SAN too (you have to list it twice in this case). For more rules and reasons, see How do you sign Certificate Signing Request with your Certification Authority and How to create a self-signed certificate with openssl?

Upvotes: 6

Related Questions