Skip to content

Additional TLS min/max version sanity checks#3422

Closed
kaduk wants to merge 2 commits intoopenssl:masterfrom
kaduk:version
Closed

Additional TLS min/max version sanity checks#3422
kaduk wants to merge 2 commits intoopenssl:masterfrom
kaduk:version

Conversation

@kaduk
Copy link
Contributor

@kaduk kaduk commented May 10, 2017

If the application sets an identical minimum and maximum supported protocol version on an SSL/SSL_CTX, but support for that version was disabled at configure-time, there is no chance of a handshake succeeding; we should error out immediately.

(A previous version of this patchset that errored out when only one of the min/max was an unsupported version failed make test, in one of the configurations that does an exhaustive cross product of the version matrix.)

@kroeckx
Copy link
Member

kroeckx commented May 10, 2017

Is there a reason not to move this in ssl_set_version_bound() itself? It would also cover the ssl_conf case.

@kroeckx
Copy link
Member

kroeckx commented May 10, 2017

Oh, I guess you need to know the max version.

@kaduk
Copy link
Contributor Author

kaduk commented May 10, 2017

Well, we could change the prototype of ssl_set_version_bound(), since it's just an internal helper.

ssl/ssl_lib.c Outdated
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add some minimal comment at least documenting the return value.

ssl/ssl_lib.c Outdated
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer that nothing is modified in the error case, and so that you first call ssl_check_allowed_versions().

@kroeckx
Copy link
Member

kroeckx commented May 10, 2017

Should we check that a version between min and max is enabled?

@kaduk
Copy link
Contributor Author

kaduk commented May 10, 2017

Should we check that a version between min and max is enabled?

I thought (briefly) about it, and my first reaction was that it would be a lot of complexity, especially since we have to handle the case where one or the other is 0/any. But I could put something together if you think it's worthwhile.

@kroeckx
Copy link
Member

kroeckx commented May 10, 2017

I don't think there is much point in making it more complex.

@kaduk
Copy link
Contributor Author

kaduk commented May 10, 2017

Modified version force-pushed, to comment ssl_check_allowed_versions() and put the calls to it before anything is written to, per @kroeckx review

@kroeckx kroeckx added branch: master Applies to master branch 1.1.0 labels May 10, 2017
ssl/ssl_lib.c Outdated
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to pass larg here instead of the old value.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops, worrying too hard about efficient editor use and not enough about reading the logic. Thanks for spotting it.

@kaduk
Copy link
Contributor Author

kaduk commented May 17, 2017

Anyone want to be a second reviewer here?

ssl/ssl_lib.c Outdated
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this good enough? What if min_version != max_version but both are disabled (and all versions in between)?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually asked the same question. It would get a complex function, and I don't see an easy way to reuse the existing functions.

This is just a case of giving an error earlier, they'd get an error later anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a tradeoff between comprehensiveness of check and complexity of code. Handling the case where one or the other is zero gets kind of awkward. (Kurt had asked a similar question.) But let me know if you want me to put something together.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not really convinced it needs to be that complicated. Check if max_version is 0 at the beginning and if so set it to TLS1_3_VERSION. Check if min_version is 0 at the beginning and if so set it to SSL3_VERSION. Then a series of checks like this:

#ifdef OPENSSL_NO_TLS1_3
    if (max_version == TLS1_3_VERSION)
        max_version = TLS1_2_VERSION;
#endif
#ifdef OPENSSL_NO_TLS1_2
    if (max_version == TLS1_2_VERSION)
        max_version = TLS1_1_VERSION;
#endif
...and so on...
#ifdef OPENSSL_NO_SSL3
    if (max_version == SSL3_VERSION)
        max_version = 0;
#endif
    if (max_version < min_version)
        return 0;
    return 1;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although, thinking about it you need to cope with DTLS too which this PR doesn't at the moment.

@kroeckx
Copy link
Member

kroeckx commented Jun 11, 2017

@kaduk: Care to address Matt's comment? At least the part about DTLS.

@kaduk
Copy link
Contributor Author

kaduk commented Jun 12, 2017

Yes, I'll work on an update.

@richsalz
Copy link
Contributor

ping @kaduk for update (and no second reviewer needed now:)

@kaduk
Copy link
Contributor Author

kaduk commented Jun 17, 2017

I got distracted fixing some issues I noticed while reviewing the "allow ciphersuites to change on resumption" change, sorry.

kaduk added 2 commits June 19, 2017 16:10
If the result of a SSL_{CTX_,}set_{min,max}_proto_version() call
leaves the min and max version identical, and support for that version
is compiled out of the library, return an error.  Such an object has
no hope of successfully completing a handshake, and this error may
be easier to decipher than the resulting handshake failure.
@kaduk
Copy link
Contributor Author

kaduk commented Jun 19, 2017

I think I have to detect whether we're doing DTLS or TLS and have separate checking logic for the two cases.
Also, @dwmw2 can you confirm that I should translate a default min_proto_ver to DTLS1_VERSION and not DTLS1_BAD_VER? I seem to have been confused about how it worked, since I thought it only got used as a minimum version (but test_bad_dtls uses it as a max version as well).

@dwmw2
Copy link
Contributor

dwmw2 commented Jun 19, 2017

Yes, default to DTLS1_VERSION not DTLS1_BAD_VER.

DTLS1_BAD_VER will only ever be used where it is known in advance that that's exactly what we're going to use — hence being used for max and min simultaneously. We never do in-band negotiation and settle on DTLS1_BAD_VER.

As long as bad_dtls_test is working, I think we're fine there. It's basically the only use case.

@kaduk
Copy link
Contributor Author

kaduk commented Jun 28, 2017

@kroeckx this is more like a re-review than a reconfirm at this point, if you're interested.

@richsalz richsalz added the approval: done This pull request has the required number of approvals label Jul 3, 2017
@richsalz
Copy link
Contributor

richsalz commented Jul 3, 2017

+1 from me.

levitte pushed a commit that referenced this pull request Jul 5, 2017
If the result of a SSL_{CTX_,}set_{min,max}_proto_version() call
leaves the min and max version identical, and support for that version
is compiled out of the library, return an error.  Such an object has
no hope of successfully completing a handshake, and this error may
be easier to decipher than the resulting handshake failure.

Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from #3422)
@kaduk
Copy link
Contributor Author

kaduk commented Jul 5, 2017

c8feba7 on master.
1.1.0 and 1.0.2 lack TLS1_3_VERSION, so probably ought to get separate pull requests. (The commit cherry-picks cleanly but fails to compile.)

@kaduk kaduk closed this Jul 5, 2017
@kaduk kaduk removed the 1.1.0 label Jul 5, 2017
@kaduk kaduk mentioned this pull request Jul 27, 2017
kaduk added a commit to kaduk/openssl that referenced this pull request Sep 15, 2017
If the result of a SSL_{CTX_,}set_{min,max}_proto_version() call
leaves the min and max version identical, and support for that version
is compiled out of the library, return an error.  Such an object has
no hope of successfully completing a handshake, and this error may
be easier to decipher than the resulting handshake failure.

Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from openssl#3422)

(cherry picked from commit c8feba7)

Updated the cherry-pick to not reference TLS1_3_VERSION, which does
not exist on this branch.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approval: done This pull request has the required number of approvals branch: master Applies to master branch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants