Don't set SNI by default if hostname is not dNS name; fixes #8083#8175
Don't set SNI by default if hostname is not dNS name; fixes #8083#8175iamihalcea wants to merge 4 commits intoopenssl:masterfrom
Conversation
vdukhovni
left a comment
There was a problem hiding this comment.
The code looks fine. Please address the requested changes in the comments and documentation. Finally, I might note that "all-numeric" does not take "-" into account. Thus "12-34.56-78" will be considered "all-numeric", which it is not, but I don't expect we need to handle these by adding all_numeric = 0 when a hyphen is found.
There was a problem hiding this comment.
The second sentence of the second comment paragraph is about X.509 and does not apply here. Delete it.
There was a problem hiding this comment.
This text is surely wrong. When -servername <name> is given, then that name and not the name from -connect will I expect be sent. Also the above sentence is poorly phrased. Could use some grammar editing.
There was a problem hiding this comment.
Updated - please have a look and let me know if it makes more sense now. Had to rearrange some bits.
vdukhovni
left a comment
There was a problem hiding this comment.
Provisional approval, modulo others not viewing the style nits as "must fix".
There was a problem hiding this comment.
Cosmetic: (@mattcaswell do we care?) We don't normally camel case internal functions in OpenSSL. To comport with the style of the existing code, perhaps this should be just is_dns_name()? Secondly, perhaps this function should be in apps.c just in case some other app will find use for it? I'm approving the PR, but if Matt or someone else wants the style issued addressed, please speak up...
There was a problem hiding this comment.
There are other names like this already in this file (e.g. ldap_ExtendedResponse_parse) so I don't find it so jarring in this case. I think the function is fine in this file for now. We can always move it to apps.c later if appropriate.
|
Close/reopen to kick CLA bot |
There was a problem hiding this comment.
MAX_LABEL_LENGTH, i, length and label_length all seem to be more appropriately declared as size_t.
There was a problem hiding this comment.
In cn2dnsid the original input is ASN.1 string, and the API for converting those to UTF8 uses integer lengths, so size_t was not an option there. Here, the hostname comes from the command-line, so size_t is possible, but does not add any measure of security, I am not aware of any OS where one can execute a program with a 2GB command-line argument... Still this code could size_t just to "unask" the question.
There was a problem hiding this comment.
I'll change just to make it consistent with the "contents" of the variables
There was a problem hiding this comment.
Right - my point wasn't really about security. More about using an appropriate and consistent type.
|
Oh...one other point. Please rebase this to remove the "merge" commit. We don't allow merge commits. |
Fixed |
vdukhovni
left a comment
There was a problem hiding this comment.
One minor style issue. I'm leaving it to Matt to decide how much EBCDIC support is appropriate to require here.
There was a problem hiding this comment.
Delete the blank line here, keeping all the declarations together.
mattcaswell
left a comment
There was a problem hiding this comment.
Approved subject to the minor styling nit that @vdukhovni noted being fixed.
kaduk
left a comment
There was a problem hiding this comment.
Most of this could have been fixed by the committer, but I think we need to check the length of all labels and not just the last one.
| servername = (host == NULL) ? "localhost" : host; | ||
| if (!SSL_set_tlsext_host_name(con, servername)) { | ||
| if (servername == NULL) { | ||
| if(host == NULL || is_dNS_name(host)) |
|
|
||
| /* | ||
| * Host dNS Name verifier: used for checking that the hostname is in dNS format | ||
| * before setting it as SNI |
There was a problem hiding this comment.
nit: end the sentence with a period.
| && host[i + 1] != '.' | ||
| && host[i - 1] != '-' | ||
| && host[i + 1] != '-') { | ||
| label_length = 0; |
There was a problem hiding this comment.
Don't we need to check label_length against MAX_LABEL_LENGTH here? At present I can only see us making that check for the final label (which is probably a TLD anyway).
There was a problem hiding this comment.
The check is done for all labels - see end condition on the for.
There was a problem hiding this comment.
So it is, my apologies. (It seems that I got interrupted mid-review and lost some state.)
That said, the RFC allows a label of length exactly 63, but my first read of the for loop (and this check) would be that it would reject such a label.
There was a problem hiding this comment.
This does, though, suggest that we may want some test cases with 63- and 64-byte labels.
There was a problem hiding this comment.
I think attempting to test this would need the test itself to make calls across the network so I'll avoid doing that, but if there's a way to mock said calls I could give it a go - @mattcaswell ?
There was a problem hiding this comment.
We don't really have a good way to do that at the moment.
There was a problem hiding this comment.
Looking at the comment by @kaduk I also agree that the code seems to reject 63-octet labels, which are rare, but legal.
| } | ||
|
|
||
| /* dNS name must not be all numeric and labels must be shorter than 64 characters. */ | ||
| isdnsname &= !all_numeric && !(label_length == MAX_LABEL_LENGTH); |
There was a problem hiding this comment.
I've been thinking of these variables as booleans, but &= is a bitwise operator.
And we don't do anything with isdnsname afterward anyway; can't we just return this expression?
There was a problem hiding this comment.
It is indeed a bitwise operator, but the effect is very much the same.
And I didn't return isdnsname && something_else because for a function named is_dNS_name, I find that confusing. I could change the name of the isdnsname variable, but efficiency-wise, the compiler should take care of it.
kaduk
left a comment
There was a problem hiding this comment.
Having thought about this overnight, in the broader context of where this fits in, I don't think we necessarily need to hold it up on the precise details; even as-is it's a bit improvement over the previous status quo.
|
The command-line is also used for testing. Using the hostname automatically as the SNI if it looks like a hostname is the requirement. Enforcing all DNS requirements is not. |
|
Pushed to master and 1.1.1. Thanks! |
Reviewed-by: Ben Kaduk <kaduk@mit.edu> Reviewed-by: Viktor Dukhovni <viktor@openssl.org> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from #8175)
Don't set SNI by default (i.e. when -servername is not set) in clientHello if hostname is not dNS name
CLA not yet completed, will do asap
Fixes #8083
Checklist