0

I am writing a server which accepts SSL connections. I have generated a self signed certificate:

openssl req -new -x509 -days 365 -nodes -out self.pem -keyout self.pem -subj "/CN=myhostname"

SSL_accept fails with this message:

140121764049248:error:1408A0C1:SSL routines:ssl3_get_client_hello:no shared cipher:s3_srvr.c:1417:

Here is a part of the server code:

  sslCtx = (SSL_CTX_new(SSLv23_server_method());
  if (!sslCtx){
      ERR_print_errors_fp(stderr);
    throw runtime_error("SSL_CTX_new failed");
  }
  ssl = SSL_new(sslCtx);
  if (!ssl)
    throw runtime_error("SSL_new failed");

  if (SSL_CTX_use_PrivateKey_file(sslCtx, keyFile.c_str(),
                                  SSL_FILETYPE_PEM) != 1)
    throw runtime_error("Unable to load private key file" + keyFile);

  if (SSL_CTX_use_certificate_file(sslCtx, certFile.c_str(),
                                   SSL_FILETYPE_PEM) != 1)
    throw runtime_error("Unable to load certificate file" + certFile);


  if (SSL_set_fd(ssl, socket) != 1)
    throw runtime_error("SSL_set_fd failed");

  if (SSL_accept(ssl) != 1){
     ERR_print_errors_fp(stderr);
    throw runtime_error("SSL_accept failed");
  }

I tried to test the server:

openssl s_client -cipher RSA -connect myhostname:33221 -tls1 -CApath . -servername myhostname

and got

CONNECTED(00000003)
139898773520408:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:s3_pkt.c:1487:SSL alert number 40
139898773520408:error:1409E0E5:SSL routines:ssl3_write_bytes:ssl handshake failure:s3_pkt.c:656:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 0 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1
    Cipher    : 0000
    Session-ID: 
    Session-ID-ctx: 
    Master-Key: 
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1496232544
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
---

I am using OpenSSL 1.0.2g.

robert
  • 3,539
  • 3
  • 35
  • 56
  • ***`CN=myhostname`*** is probably wrong. 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](http://stackoverflow.com/a/21340898/608639) and [How to create a self-signed certificate with openssl?](http://stackoverflow.com/q/10175812/608639) You will also need to place the self-signed certificate in the appropriate trust store. – jww May 31 '17 at 19:56
  • Please provide the URL you are using to connect to the server, and post the output of `openssl s_client -connect : -tls1 -servername | openssl x509 -text -noout`. Also see [TLS Client](https://wiki.openssl.org/index.php/SSL/TLS_Client) on the OpenSSL wiki. It shows you how to well configure a `SSL_CTX` in the context of a client. Most of it applies to a server, too. Also, this may cause you trouble: `if (SSL_accept(ssl) != 1)`, especially on non-blocking sockets. I seem to recall non-blocking sockets often return `-1` and its not an error. – jww May 31 '17 at 19:59

1 Answers1

0

Try SSL_new, only after fully setting up the context and make sure you have OpenSSL_add_ssl_algorithms at the start of your program. The 1.0.2 docs says it "inherits", but not sure if that effectively means it copies the settings at that time and further changes are not applied.

https://www.openssl.org/docs/man1.0.2/ssl/SSL_new.html

The new structure inherits the settings of the underlying context ctx: connection method (SSLv2/v3/TLSv1), options, verification settings, timeout settings.

There is also an example on the OpenSSL wiki

Which without error handling goes along the lines of:

// General initialisation
SSL_load_error_strings();
OpenSSL_add_ssl_algorithms();
// Context for a server socket
ctx = SSL_CTX_new(SSLv23_server_method ()); //Note SSLv23_server_method in example is deprecated in favour of TLS_server_method for new versions. TLSv1_2_server_method will force TLS 1.2.
SSL_CTX_set_ecdh_auto(ctx, 1);
SSL_CTX_use_certificate_file(ctx, "cert.pem", SSL_FILETYPE_PEM);
SSL_CTX_use_PrivateKey_file(ctx, "key.pem", SSL_FILETYPE_PEM);
// Only after all certificates, and other config is set
ssl = SSL_new(ctx);
SSL_set_fd(ssl, client_socket);
SSL_accept(ssl);
// Use SSL_write and SSL_read
SSL_free(ssl);
close(client_socket);
// OpenSSL cleanup
EVP_cleanup();
Fire Lancer
  • 29,364
  • 31
  • 116
  • 182
  • Still getting the same error. Maybe I should copy the certificaion to a specific location? – robert May 31 '17 at 12:43
  • You try the sample code? `SSL_CTX_use_certificate_file` etc. should result in an error if not given a valid file (its a normal file path, so '/absolute' or otherwise relative the current directory). So if you are not getting an error in the server code, would seem you did something different from the example. The sample code, and `openssl s_client` on the same system gives me "Verify return code: 18 (self signed certificate)" using the self signed command line you showed. – Fire Lancer May 31 '17 at 15:09
  • Did you maybe skip some of the OpenSSL setup steps outside the code you posted? `OpenSSL_add_ssl_algorithms` for example? – Fire Lancer May 31 '17 at 15:14
  • I think the problem is that I am using nonblocking sockets with BIO-s, therefore I have to handle the handshake differently. – robert May 31 '17 at 16:11
  • 1
    Yes, if you have a non-blocking socket, you need to handle `SSL_ERROR_WANT_READ/WRITE` since it is multiple round trips to establish a TLS connection. Similar applies client side. But in that case you should be seeing `SSL_accept` fail with such an error and then in the message you print (note that `SSL_accept` and `SSL_connect` are both just thin wrappers around `SSL_do_handshake`). – Fire Lancer May 31 '17 at 16:33