Relationship between ciphers and SSL enabled protocols - ssl

I was told to remove SSL_RSA_WITH_3DES_EDE_CBC_SHA from ciphers list since it is weak. When I looked at sslEnabledProtocols, I didn't see SSLv3. Following is what I have.
ciphers=TLS_RSA_WITH_AES_256_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,SSL_RSA_WITH_3DES_EDE_CBC_SHA
sslEnabledProtocols=TLSv1,TLSv1.1,TLSv1.2
Question 1: Since SSLv3 is no longer listed on the sslEnabledProtocols, Should I assume that SSL_RSA_WITH_3DES_EDE_CBC_SHA is disabled automatically without removing it physically from ciphers? All ciphers starting with SSL_ are related to SSLv3?
Questions 2: Why both SSL_RSA_WITH_3DES_EDE_CBC_SHA and TLS_RSA_WITH_3DES_EDE_CBC_SHA have same OpenSSL name of DES-CBC3-SHA?

No. Confusingly this cipher suite is also available in TLS - sometimes called TLS_RSA_WITH_3DES_EDE_CBC_SHA but often not.
https://mta.openssl.org/pipermail/openssl-users/2015-April/001055.html
Note that if you remove that you will remove access from some older users (including IE8/XP). Always best to run scan through https://www.slllabs.com/ssltest/ to see which clients should be able to connect or not - and similarly this scan looks at SSL and TLS support and not just SSL despite its name :-) I imagine it will show a number of older clients using that cipher suite. So you can only disable if you're prepared to cut them off so you'll need to decide how much traffic that represents and if you want to do that or push back on this plan.

Related

Apache Httpd can't enable TLS1.0/1.1 support with Cipher Suite Honor Order settings

My web server cannot open a TLSv1.0/1.1 connection. Due to the need to support older client versions. Accidentally found that no matter what settings are made, TLSv1.0/1.1 connections cannot be opened, and these two always disappear and appear at the same time.
The Apache2 version I'm using now is
Server version: Apache/2.4.55
Server built: 2023-01-20T06:45:57
The OpenSSL version I'm using now is
OpenSSL 1.1.1n 15 Mar 2022
When I try to remove all configuration about cipher suite, it can support TLS1.0/1.1/1.2/1.3 connection, like this:
SSLEngine on
SSLCertificateFile "something.cer"
SSLCertificateKeyFile "something.key"
When I added the setting about SSL protocol, it also works fine.
SSLProtocol All -SSLv3 -SSLv2
At this point, my web server can provide eight TLS1.0/1.1 cipher suites, which are:
TLS_RSA_WITH_AES_128_CBC_SHA
TLS_DHE_RSA_WITH_AES_128_CBC_SHA
TLS_RSA_WITH_AES_256_CBC_SHA
TLS_DHE_RSA_WITH_AES_256_CBC_SHA
TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
At this time, it can also support three TLS1.3 cipher suites and about forty or fifty TLS1.2 cipher suites. When I check with Qualys SSL Labs it says "This server does not support Forward Secrecy with the reference browsers. Grade capped to B". Although supporting the old TLS protocol will also be downgraded to B, but I still try to fix the previous problem.
So I tried to add the following configuration items, then the problem came, my server no longer supports TLS1.0/1.1.
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA
SSLHonorCipherOrder On
I don't know why this happened, at first I thought it was part of the cipher suite I specified that didn't support TLS1.0. I checked one by one and found that in the TLS1.2 cipher suite list at this time, there are four of the previous eight.
Then I first tried to remove the last configuration, and my server supports TLS1.0/1.1 again. The cipher suites that appear are exactly the ones I found duplicated earlier. Then I tried to add this part again, but set SSLHonorCipherOrder off, it still works as before.
I don't understand why my server cannot support TLS1.0/1.1 when the option of server preference is turned on.
The SSLHonorCipherOrder On setting means "ensure that the server's cipher preferences are followed instead of the client's". So if the client sends a mix of cipher sets, and the server list includes non-TLS1.0/1.1 sets earlier in the list, then it'll use these (and TLS1.2) in preference. Which actually is exactly what you're looking for: if the client supports a stronger protocol, it should use it.
You can use the openssl command line tool to quickly check if the server will accept a connection that supports only TLSv1.0:
openssl s_client -connect example.com:443 -tls1

difference between !3des and -3des

I have a HTTP process running on solaris, recently we were asked to remove 3DES from the cipher suite. We need to apply something like this is the cipher suite config,
SSLCipherSuite HIGH:!aNULL:!eNULL:!PSK:!RC4:!MD5:!3DES
But there is an Oracle documentation here - https://docs.oracle.com/middleware/12213/webtier/administer-ohs/GUID-C76BCA2A-9C28-4D16-9758-9346FBCF7512.htm#HSADM1016
which says
Blockquote- : Removes the cipher from the list (can be added later)
! : Removes the cipher from the list permanently
So my question is if we apply !3DES and the change doesnot work will we be able to use it again on the same cipher suite config by just removing !3DES? The reason for the confusion is that oracle says that applying !3DES removes the cipher from the list permanently. In other words, is applying a !3DES an irreversible change? NOTE - We only have access to the HTTP and SLL conf files where the cipher suite changes can be made by us
The relevant documentation is the documentation of ciphers in OpenSSL. To cite:
If ! is used then the ciphers are permanently deleted from the list. The ciphers deleted can never reappear in the list even if they are explicitly stated.
If - is used then the ciphers are deleted from the list, but some or all of the ciphers can be added again by later options.
Thus, both options delete the given cipher from the list. But only ! is permant.
To understand take HIGH !3DES kRSA vs HIGH -3DES !kRSA. In the first case no 3DES ciphers are enabled. In the second case 3DES ciphers which use RSA key exchange are enabled, since these were added by a later kRSA.
In other words: to be sure that these ciphers are not used in any case better use !.

OpenSSL connection: alert internal error

I have 100 HTTPS services running on a single server using SNI. (Actually, I don't have access to them. It's an assignment. All I know are their domain names N.xxx.yy where N is in range from 00 to 99.) The goal of the assignment is to evaluate security of every single connection to each of these servers. So some of the servers contain expired certificates, certificates with wrong CN, etc.
My problem is that I cannot get past the handshake on some of the servers. I have written my own application in C++ using OpenSSL, but I've also tried it with openssl s_client. This is how I connect to the server:
openssl s_client -host N.xxx.yy -port 443 -verify 1 -servername N.xxx.yy -CAfile assignment-ca.pem
And this is what I get:
139625941858168:error:14094438:SSL routines:ssl3_read_bytes:tlsv1 alert internal error:s3_pkt.c:1493:SSL alert number 80
139625941858168:error:140790E5:SSL routines:ssl23_write:ssl handshake failure:s23_lib.c:177:
In Wireshark, I see that client sent ClientHello, server responded with ServerHello (choosing TLSv1.2 and ECDHE-RSA-AES256-GCM-SHA384) followed by Certificate and then it sent me Alert message containing Internal Error (80).
After trying different thing I have found out that if I run s_client with -tls1 or -tls1_1 I can successfully get past the handshake. -tls1_2 does not work. What is even stranger is that connection through Chrome/Firefox/any other browser succeeds even if TLSv1.2 is negotiated. From what I see, Chrome is sending a different cipher list than me or s_client but even after modifying the cipher list to match the one in Chrome (and making sure that server chooses ECDHE-RSA-AES128-GCM-SHA256), it does not work either. Chrome is sending these TLS extensions, which I don't but most of them seem empty:
Unknown 47802
renegotiation_info
Extended Master Secret
signed_certificate_timestamp
status_request
Application Layer Protocol Negotiation
channel_id
Unknown 6682
Can anybody explain me what is happening here? Unfortunately, I have no way to debug it on the server side so this is all I know.
UPDATE:
After playing around with forged ClientHello messages I managed to track it down to signature_algorithms extension. My app and s_client provide SHA384 + {RSA,DSA,ECDSA} but if I remove these and keep just SHA256 + {RSA,DSA,ECDSA}, as Chrome does, it works and I receive Server Key Exchange message successfully. Could it be that server somehow does not support it, but instead of providing meaningful error message, it just ends unexpectedly and gives me this internal error?
UPDATE 2:
I found answer to why it works with TLS versions prior to 1.2 in RFC5246. Question from the previous UPDATE still holds.
Note: this extension is not meaningful for TLS versions prior to 1.2.
Clients MUST NOT offer it if they are offering prior versions.
However, even if clients do offer it, the rules specified in [TLSEXT]
require servers to ignore extensions they do not understand.
Since you wrote that -tls1_2 does not work I assume either you and/or the server uses an older openssl library. The current version while writing this is 1.1.0e
There were quite some fixes since 0.9.8, which could often be seen on older systems.
For Version 1.0.1 there was this fix, which sounds like your problem:
`Some servers which support TLS 1.0 can choke if we initially indicate
support for TLS 1.2 and later renegotiate using TLS 1.0 in the RSA
encrypted premaster secret. As a workaround use the maximum permitted
client version in client hello, this should keep such servers happy
and still work with previous versions of OpenSSL.`
Maybe also notable:
Don't allow TLS 1.2 SHA-256 ciphersuites in TLS 1.0, 1.1 connections.
So I would suggest to update your openssl-Version and in case of the servers out of your control I would stick to the settings you already found.

Can a TLS 1.2 server/client get by with just TLS_RSA_WITH_AES_128_CBC_SHA?

I'm updating an embedded TLS 1.0 implementation to TLS 1.2 (devices with 1MB of code space or less, and no OS). At this point, I have AES-128 and AES-256 CBC ciphers working with SHA-1 and SHA-256 digests for a minimal implementation. The library cannot negotiate an SSLv2, SSLv3, TLS 1.0 or TLS 1.1 connection.
I felt this would be sufficient, given that RFC 5246 states, "TLS_RSA_WITH_AES_128_CBC_SHA is now the mandatory to implement cipher suite."
Yet as I read various postings on security blogs, I'm seeing recommendations that would have users disable that suite, and (for example) only allow the ECDHE_RSA or DHE_RSA variants.
So my question is whether devices using our library will interoperate with modern web browsers (as a server) and modern https/smtps/pop servers (as a client). Are there TLS 1.2 clients/servers that fail to negotiate a TLS_RSA_WITH_AES_128_CBC_SHA connection?
I am not sure there are currently many servers supporting TLS that would fail negotiating TLS_RSA_WITH_AES_128_CBC_SHA with TLSv1.2 as it is THE mandatory cipher suite for TLSv1.2.
However there are things to keep in mind:
TLS_RSA_WITH_3DES_EDE_CBC_SHA is mandatory for TLSv1.0 and TLSv1.1 but due to security reasons it is no longer supported by every server,
Mozilla recommends (and it is not the only one) to favor AES128 instead of AES256,
Perfect Forward Secrecy (PFS), allowed by DHE or ECDHE is now a must-have feature.
So if I can provide you with 4 cipher suites (the same number than you have), I would say these ones from the strongest to the weakest:
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
TLS_RSA_WITH_AES_128_GCM_SHA256
TLS_RSA_WITH_AES_128_CBC_SHA
I would say that these 4 cipher suites bring enough security and compatibility with TLSv1.2 servers.
Now the question of supporting only TLSv1.2 is another question, but if you have enough space, I recommend you to add TLSv1.0 too (TLSv1.1 does not provide extra compatibility).
PS: The reason why AES128 is favored instead of AES256 is that some people think the extra security added by AES256 is (for now) worthless and that AES128 seems to be more resistant to timing attacks.
"So my question is whether devices using our library will interoperate with modern web browsers (as a server) and modern https/smtps/pop servers (as a client). Are there TLS 1.2 clients/servers that fail to negotiate a TLS_RSA_WITH_AES_128_CBC_SHA connection?"
Yes there are plenty implementations that fail.
Most common:
Clients that still send a SSL2.0 Client Hello
Clients/Servers that only support PFS cipher suite
Servers that still not support TLS 1.2
Servers that no longer support TLS 1.2 - since those only support TLS 1.3
My recommendation is:
also support TLS 1.3 (not that hard to implement, I did it)
also support DHE
Or use a tool/site like https://www.ssllabs.com/ssltest/index.html and test the compatibility/security of your server until it's sufficient for you.

OpenSSL let the server and client negotiate the method

Following a really outdated tutorial I managed to create an HTTPS server using OpenSSL with TLS1.2, and I'm very proud of it ;)
However TLS 1.2 is only supported in latest browsers and I would like to have some kind of negotiation of the protocol between the client and server, which I'm sure it can be done, but I'm not able to find how! So that if the client only supports TLS1.0, well use that. And if it only supports SSLv3, use that. Not sure about SSLv2, maybe better leave that...
The code I use right now is:
SSL_library_init();
OpenSSL_add_all_algorithms();
SSL_load_error_strings();
ssl_method = TLSv1_2_server_method();
ssl_ctx = SSL_CTX_new(ssl_method);
Then the server certificates are loaded and the ssl_ctx is shared among all connections. When a client is accepted by the server socket it is encapsulated in an SSL object (whatever it represents):
ssl = SSL_new(ssl_ctx);
SSL_set_fd(ssl, client_socket);
SSL_accept(ssl);
So I guess that something has to be changed in the ssl_ctx creation to allow more methods... Any idea?
<rant> No decent, extensive documentation can be found for OpenSSL, the best available is a 10 years old tutorial! </rant>
Thanks in advance.
You do this by using SSLv23_method() (and friends) instead of a specific method (e.g. TLSv1_2_server_method() in your example). This sends the SSLv2 ClientHello but also specifies the highest protocol supported. The somewhat outdated man page says:
SSLv23_method(void), SSLv23_server_method(void), SSLv23_client_method(void)
A TLS/SSL connection established with these methods will understand
the SSLv2, SSLv3, and TLSv1 protocol. A client will send out SSLv2
client hello messages and will indicate that it also understands SSLv3
and TLSv1. A server will understand SSLv2, SSLv3, and TLSv1 client
hello messages. This is the best choice when compatibility is a
concern.
This online man page doesn't discuss the newer TLSv1_1 and TLSv1_2 protocols, but I verified in the 1.0.1g source of s23_clnt.c that SSLv23_method() includes them.
You then limit the protocols you actually accept with SSL_CTX_set_options():
The list of protocols available can later be limited using the
SSL_OP_NO_SSLv2, SSL_OP_NO_SSLv3, SSL_OP_NO_TLSv1 options of the
SSL_CTX_set_options() or SSL_set_options() functions. Using these
options it is possible to choose e.g. SSLv23_server_method() and be
able to negotiate with all possible clients, but to only allow newer
protocols like SSLv3 or TLSv1.
Note, however, that you can't enable arbitrary sets of protocols, only contiguous protocols in SSLv2, SSLv3, TLSv1, TLSv1_1, TLSv1_2. For example, you can't choose only SSLv3 and TLSv1_1, omitting TLSv1. This comment in the source explains why:
SSL_OP_NO_X disables all protocols above X if there are some protocols below X enabled. This is required in order to maintain "version capability" vector contiguous. So that if application wants to disable TLS1.0 in favour of TLS1>=1, it would be insufficient to pass SSL_NO_TLSv1, the answer is SSL_OP_NO_TLSv1|SSL_OP_NO_SSLv3|SSL_OP_NO_SSLv2.