SSL23_GET_SERVER_HELLO:unknown protocol - ssl

I have read all postings on this error, and tried all the answers, but problem is still not resolved.
Running Debian 8 virtual machine created by Google Cloud Platform, created a Self-Signed SSL and configured the default-ssl file as per instructions, and still getting error when connecting to port 443. Here is the command that I ran and the message that I got. Any insightful help would be welcome:
openssl s_client -connect localhost:443
140700056811152:error:140770FC:SSL routines: :s23_clnt.c:782:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 289 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1.2
Cipher : 0000
Session-ID:
Session-ID-ctx:
Master-Key:
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1530501490
Timeout : 300 (sec)
Verify return code: 0 (ok)

Steffen, you're right; I tried to avoid redundant info, but the devil is in the detail and needed to mention. Thank you for your review and insightful comment.
The good news is that the issue is resolved and here is what I did, in detail, so that those like me who get stuck, can benefit from my experience:
In my most recent attempt that turned out to be successful, I followed the instructions for Apache on this page:
https://www.digitalocean.com/community/tutorials/how-to-install-an-ssl-certificate-from-a-commercial-certificate-authority
What made it different this time is the following:
I included reference to the intermediate certificate (the gd_xxxx_bundle.crt file, which I renamed it to ca-buncle.crt) in my default-ssl.conf file which is:
#SSLCACertificatePath /etc/ssl/certs/
#SSLCACertificateFile /etc/apache2/ssl.crt/ca-bundle.crt
In Wordpress Admin, under Settings/General, the WordPress Address (URL) and Site Address (URL) were pointing to the IP address (before I mapped it to the domain in the DNS). I changed it to https://domainname.com (contrary to some articles that mention editing wp-config.php would do, which I did and it threw me out of wp-admin)
Not sure if the following two edits have an impact on the result, but I have no desire to experiment further with it, but sharing it with you nevertheless:
After running openssl command, I specified the domain name for the prompt Common Name, which is supposed to be an optional field
I added ServerName to
/etc/apache2/sites-enabled/wordpress.conf
/etc/apache2/sites-enabled/default-ssl
/etc/apache2/sites-available/000-default.conf
Finally, there is a site that checks for the certificate:
https://decoder.link/sslchecker//443
That may shed some light on the issue if the certificate doesn't work.
Cheers.

Related

openSSL 1.1.1 API Doubts

I want to set up and run SSL client and server with TLS 1.2 using openSSL 1.1.1 for my project.
I have a few doubts and/or requirements with openSSL:
what is the right way to select TLS 1.2 as version? Currently I am using TLS_client_method(). the other methods seem to be deprecated. Is there a specific API for choosing particular version?
I need to run an SSL clinet with following handshake extensions.
ec_point_formats with "uncompressed" as value
supported_groups with list of "secp521r","secp384r1","secp256r1","secp224r1","secp192r1","secp160r1","ffdhe2048"
encrypt_then_mac with value 0
server_name
extended_master_secret without any value and length set to 0
I need to run an SSL server with following handshake extensions
encrypt_then_mac with value 0
extended_master_secret without any value and length set to 0
Apart from above header extension fields I want to disable everything else. How to accomplish that?
From client I want to provide only "TLS_PSK_WITH_AES_128_CBC_SHA256" cipher suite as option.
Is client certificate and key files (pem) necessary for successful connection establishment and communication when PSK cipher is used?
Is there any example or open source client-server implementation with PSK authentication?
what is the right way to select TLS 1.2 as version? Currently I am using TLS_client_method(). the other methods seem to be deprecated. Is there a specific API for choosing particular version?
TLS_client_method() is the correct method to use. To specify that no version below TLSv1.2 is used you should do this:
SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
Where ctx is your SSL_CTX object.
If you also want to prevent anything higher than TLSv1.2 from being used then do this:
SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION);
See this page for information on these calls:
https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_min_proto_version.html
I need to run an SSL clinet with following handshake extensions.
ec_point_formats with "uncompressed" as value
supported_groups with list of "secp521r","secp384r1","secp256r1","secp224r1","secp192r1","secp160r1","ffdhe2048"
These extensions aren't used if you specify the PSK ciphersuite that you've selected so OpenSSL won't send them (assuming you've restricted the max TLS protocol version as described above, and have configured only that ciphersuite). Doing so would be pointless. Even if it did, OpenSSL 1.1.1 does not support "ffdhe2048". It does support all the others.
encrypt_then_mac with value 0
Not sure what you mean by "with value 0" since this extension is always empty and has no value. I assume you mean with length 0. This extension is sent by default so you don't need to do anything.
server_name
You should call:
SSL_set_tlsext_host_name(ssl, "hostname of the server");
Where ssl is your SSL object, and replacing "hostname of the server" with the server's real hostname.
See this page for information on this call:
https://www.openssl.org/docs/man1.1.1/man3/SSL_set_tlsext_host_name.html
extended_master_secret without any value and length set to 0
This extension is sent by default so you don't need to do anything.
I need to run an SSL server with following handshake extensions
encrypt_then_mac with value 0
extended_master_secret without any value and length set to 0
If the client sent them, then the server will echo them back by default. You don't need to do anything.
Apart from above header extension fields I want to disable everything else. How to accomplish that?
An OpenSSL client will additionally send the session_ticket extension. Its harmless, but if you really want to disable it you can do this:
SSL_CTX_set_options(ctx, SSL_OP_NO_TICKET);
See this page for further information:
https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_options.html
An OpenSSL server will additionally send the "renegotiate" extension. You must not disable this (in fact you cannot). Ignore it. Its harmless.
From client I want to provide only "TLS_PSK_WITH_AES_128_CBC_SHA256" cipher suite as option.
That is the official IANA name for the ciphersuite. OpenSSL knows it as "PSK-AES128-CBC-SHA256".
Configure it on both the client and the server like this:
SSL_CTX_set_cipher_list(ctx, "PSK-AES128-CBC-SHA256");
See this page for further information:
https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_cipher_list.html
In addition you will need to provide PSK callbacks to tell OpenSSL what the PSK is that you want to use.
On the client you need to call SSL_CTX_set_psk_client_callback(). On the server you must call SSL_CTX_set_psk_server_callback().
See these pages for further information:
https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_psk_client_callback.html
https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_psk_server_callback.html
TLSv1.3 ciphersuites will still automatically be sent unless you have additionally restricted the max TLS protocol version to TLSv1.2 as described above. Finally you will also see a ciphersuite called "TLS_EMPTY_RENEGOTIATION_INFO_SCSV" being sent. This isn't actually a real ciphersuite at all. It is always sent and cannot be suppressed. It will never be negotiated and is harmless. Ignore it.
Is client certificate and key files (pem) necessary for successful connection establishment and communication when PSK cipher is used?
No.
Is there any example or open source client-server implementation with PSK authentication?
You can look at how s_client and s_server do it:
https://github.com/openssl/openssl/blob/OpenSSL_1_1_1-stable/apps/s_client.c
https://github.com/openssl/openssl/blob/OpenSSL_1_1_1-stable/apps/s_server.c

SSL in Bluemix and nginx configuration

I have added a certificate in Bluemix, following this post : https://www.ibm.com/blogs/bluemix/2014/09/ssl-certificates-bluemix-custom-domains/
I can see the certificate in the domain tab, and it's the one I have uploaded.
Now I have a container running nginx, because we use it as a reverse proxy. Previously it was handling the SSL configuration, but now that it's done in Bluemix directly, we just want to accept https request, without configuring certificate.
What we did was forwarding the http requests to https, like advised in the post (explaining how to do it for node.js though). We get something like this:
server {
listen 80;
server_name *hostname.domain*;
return 301 https://$http_host$request_uri;
}
And in the 443 part, we only listen, without the ssl part:
server {
listen 443;
server_name *host.domain*;
*other stuff for reverse proxy*
}
However, when trying to access it, I get a generic error in chrome: ERR_SSL_PROTOCOL_ERROR
Firefox gives a bit more information:
An error occurred during a connection to *host.domain*. SSL received a record that exceeded the maximum permissible length. Error code: SSL_ERROR_RX_RECORD_TOO_LONG
And when I try to check the certificate from command line, I don't get any.
openssl s_client -connect *host.domain*:443
CONNECTED(00000003)
140250419918480:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:s23_clnt.c:782:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 289 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1.2
Cipher : 0000
Session-ID:
Session-ID-ctx:
Master-Key:
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1484673167
Timeout : 300 (sec)
Verify return code: 0 (ok)
---
There's no error in nginx logs, and I can't manage to tell if the issue in on Bluemix side, or in the configuration of nginx, or if nginx allows this kind of configuration where it has to handle https requests, without the certificate configuration...
Does someone have any idea?
Many thanks.
Regards.
If you want NGINX to pass-thru SSL, you have to use the stream module.
Thanks for your answers. I was not able to check your solutions, but I talked with a technical expert from IBM meanwhile, and here is what I learned.
About the SSL pass-thru, we would need to configure each component (behind the nginx) to handle the SSL, so it seems to be harder to manage. I'm not an expert though, so I'm just reporting what I had as an answer on that point.
First, what we want should be doable by removing the public IP adress of our nginx container.
Then, by creating a route from BM load balancer to our nginx container, we should solve the issue. Then the route would be configured to forward the port 443 to the nginx on port 80 (since the container is not publicly available, there no need to handle 80 AND 443).
However, Bluemix allows route only for container groups (for now?). Unfortunately, we use docker-compose that does not allow (for now?) to create container groups on BlueMix.
So the best solution was to put back the ssl configuration in nginx. The certificate being both on BlueMix domain and nginx container. And it's working fine, so we'll just improve the procedure to update the certificate, and wait until there's a need, or a new way to do it...
K.

OpenSSL command line tool version and cipher

I have 2 computers - lets name it A and B. Both have the same OpenSSL version installed. Both Debian 8.3.
OpenSSL 1.0.1k 8 Jan 2015
I try to connect to a mailserver via SSL from both.
openssl s_client -host pop.amailserver.net -port 995
From A I need to specify the ssl-version (parameter -tls1 or -tls1_1) to make it work.
If not I get an error.
SSL routines:SSL3_GET_SERVER_HELLO:wrong ssl version:s3_clnt.c:851
...
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1.1
Cipher : 0000
But from B it works out of the box without any parameter.
Protocol : TLSv1
Cipher : AES128-SHA
The problem is that some library seems to use this setting and is not able to connect from A (works from B). So I think its the same reason - I am not able to pass some SSL-parameters to the library.
Does anyone knows if this behavior is configured or set somewhere?
There is no global setting for ciphers or protocols which affect all OpenSSL based applications on the system. My guess is that the difference is in the network, like
there is a SSL intercepting middlebox (firewall or similar) somewhere
the target is different, i.e. A and B use different IP addresses for connecting to the server. This might be because the server is reachable by IPv4 and IPv6 but one system has IPv6 connectivity while the other does not. But there are also other reasons why different IP addresses might be used.

openssl connect fails for some websites

I'm having some problems getting openssl to consistently connect to some websites. pnc.com seems to have the problem almost every time. When I run the following command:
openssl s_client -bugs -msg -debug -connect www.pnc.com:443
The first time I will always get the following response:
CONNECTED(00000003)
write to 0x1095fa0 [0x11362d0] (112 bytes => -1 (0xFFFFFFFFFFFFFFFF))
write:errno=104
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 0 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
---
If I run it a couple more times it will successfully connect and I can run a GET for the specific web site I'm looking for, but the connect never works on the first try. I've seen several posts with similar issues that have been solved by specifying SSLv3, or using the no_tls1_2 option, but neither of those have worked in this case. I have tried this from both a centOS box as well as my macbook, and using both openssl 1.0.0 and 1.0.1e.
I chased the problem to openSSL after initially suspecting it was the ssl_bump from my squid install. All I really need is for the webpage to open properly through the squid ssl_bump, so if I could get openSSL to connect properly the first time, or keep retrying until it was successful, or get squid to keep trying until the connection is established, I'd consider it working.
Has anyone else had this problem and found a solution for it?

SSL Cannot Make A Handshake

After strictly following the SSL certificate authority documentation, I'm stumped to solve the reason for this error. When accessing my website via HTTPS Firefox spits out the following error:
SSL peer was unable to negotiate an acceptable set of security parameters.
(Error code: ssl_error_handshake_failure_alert)
I went back and found this in the SSL error log (domain was modified on purpose):
[Mon May 09 02:11:05 2011] [warn] RSA server certificate wildcard CommonName (CN) `*.domain.com' does NOT match server name!?
Where is the server name defined? I can't find a reasonable explanation in my httpd-ssl.conf file to solve this error. Thanks for your help!
Update Finally solved the problem, detailed below:
Unfortunately it was created by a default value in my Apache distribution. The option:
SSLVerifyClient require
Actually needed to be set as:
SSLVerifyClient optional
I'm not issuing client certs just yet. However credit is due to the answers for narrowing the problem. I appreciate the help!
That line in your logfile might matter later, but it's only a [warn] and it's not what handshake_failure means. Handshake_failure means that a cipher suite could not be negotiated -- no cipher suite is supported by both client and server. Look at what ciphers are supported by your server.
Edit: I always forget that if a client fails to provide a required certificate, that also results in handshake_failure (section 7.4.6).
SSL compares the CommonName with the name of the server you actually try to connect to.
Possibly you are using an alternative name like 'localhost' or an IP Adress.
Solved the problem, and unfortunately it was created by a default value in my Apache distribution. The option:
SSLVerifyClient require
Actually needed to be set as:
SSLVerifyClient optional
I'm not issuing client certs just yet. However credit is due to the answers for narrowing the problem. I appreciate the help!