-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix curves findings in TLS1.2 and prior versions #2620
base: 3.2
Are you sure you want to change the base?
Conversation
Hi @Odinmylord, Thanks for reporting this and for providing a PR. I was able to reproduce the issue. I thought that the supported_groups extension was only about key exchange, but RFC 8422 does seem to indicate that it is also about the server's certificate. I think it hadn't been noticed before since server's that have ECC certificates tend to also have RSA certificates, in which case the connection is still successful using the RSA certificate. I haven't had a chance to test your PR, but I have a couple of comments. I believe that the change you made for testing with OpenSSL also needs to be made for testing with I am concerned that this change will not work with all servers. When doing testing of #2617 I noticed that most servers selected signature algorithms based on their own preference order rather than the client's specified preference order. When I tested your proposed fix against an OpenSSL server (i.e., So, while I don't know of a server to test against that ignores the client's preference order for supported_groups, my guess is that a slightly more complicated solution is needed -- run the tests as they are currently done, and then when that is done run the tests as you propose. This would add more lines of code, but would only result in one additional test. In most cases the second set of tests could be skipped. If "RSA" appears in |
Hi, @dcooper16 I fixed the code as you proposed and tested it both with system openssl and sockets. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @Odinmylord,
Sorry it took me so long to look at this code. I haven't had a chance to try running the code, but I read through it and have just a few minor comments. When I get some more time, I'll try testing it out.
# Versions of TLS prior to 1.3 close the connection if the client does not support the curve | ||
# used in the certificate. The easiest solution is to move the curves to the end of the list. | ||
# instead of removing them from the ClientHello. This is only needed if there is no RSA certificate. | ||
if ((! "$HAS_TLS13" || [[ "$proto" == "-no_tls1_3" ]]) && [[ ! "$ecdhe_cipher_list" == *RSA* ]]) || break; then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The "|| break" part of this line is very confusing to me. I would suggest one of two alternatives:
- Enclose the entire "while true" loop in an "if" statement that checks whether the second run is needed.
- Remove the "if" from this line (and the corresponding "fi"). If the condition is not satisfied, then the execution will break out of the loop, so the subsequent code does not need to be within an "if"/"then" clause.
if ((! "$HAS_TLS13" || [[ "$proto" == "-no_tls1_3" ]]) && [[ ! "$ecdhe_cipher_list" == *RSA* ]]) || break; then | ||
curves_to_test="" | ||
for (( i=low; i < high; i++ )); do | ||
if ! "${curves_deprecated[i]}"; then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This "if" statement should be removed. As noted in the comment where curves_deprecated
is defined, a curve is deprecated if it is one that MUST NOT be used with TLS 1.3. Here, you want to try all of the curves, even the deprecated ones.
done | ||
[[ -z "$curves_to_test" ]] && break | ||
for (( i=low; i < high; i++ )); do | ||
if ! "${curves_deprecated[i]}"; then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This "if" statement should be removed for the same reason as the previous check for deprecated curves.
# used in the certificate. The easiest solution is to move the curves to the end of the list. | ||
# instead of removing them from the ClientHello. This is only needed if there is no RSA certificate. | ||
while true; do | ||
if ([[ "$proto" == 03 ]] && [[ ! "$ecdhe_cipher_list" == *RSA* ]]) || break; then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this line should be modified similarly to the one on line 10880, so that there is not an "if" statement with an "|| break" that is part of it.
if ([[ "$proto" == 03 ]] && [[ ! "$ecdhe_cipher_list" == *RSA* ]]) || break; then | ||
curves_to_test="" | ||
for (( i=0; i < nr_curves; i++ )); do | ||
if ! "${curves_deprecated[i]}" || [[ "$proto" == 03 ]]; then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This "if" statement should be deleted. As noted above, deprecated curves should only be excluded from TLS 1.3 ClientHello messages. Also, there is no need to check that "$proto$ == 03
, as that is done earlier.
done | ||
[[ -z "$curves_to_test" ]] && break | ||
for (( i=0; i < nr_curves; i++ )); do | ||
if ! "${curves_deprecated[i]}" || [[ "$proto" == 03 ]]; then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As with the "if" statement on line 10957, this isn't needed.
Describe your changes
If a server uses a certificate with secp256r1 as its private key testssl.sh only finds the "secp256r1" while the server also offers secp384r1 and secp521r1. This is caused by TLS versions prior to 1.3 closing the connection with the error "no shared cipher" if the client does not send the curve used in the certificate in the supported_groups extension.
The easiest solution (which is the one implemented here) is to move the curves found to the end of the supported_groups extension instead of removing them, once testssl.sh finds the same curve a second time it moves forward meaning that only an additional handshake is performed. An alternative would be to first find the private key of the certificate and, if a curve is used, add that curve as the last one instead of removing it from the ClientHello.
What is your pull request about?
If it's a code change please check the boxes which are applicable
help()