TLSv1.3: Add support for the key_share extension#1848
TLSv1.3: Add support for the key_share extension#1848mattcaswell wants to merge 14 commits intoopenssl:masterfrom
Conversation
a92298b to
f5fa234
Compare
f5fa234 to
0d9800a
Compare
|
Rebased again, so now this PR is only dependent on the one commit from #1825. So please ignore the first commit, everything else is in scope. |
0d9800a to
16b18bb
Compare
|
Rebased this again. All commits are for review now. There is one test failure which is unrelated to this PR (its in current master) and will be fixed by #1894. |
16b18bb to
07fb0ac
Compare
|
#1894 got merged quickly so rebased again to pick it up! |
ssl/statem/statem_clnt.c
Outdated
There was a problem hiding this comment.
I thought we already resolved this :)
There was a problem hiding this comment.
Oops. This was written before we came to that resolution. Fixed.
ssl/statem/statem_clnt.c
Outdated
There was a problem hiding this comment.
make the test the same as line 419?
There was a problem hiding this comment.
It really should be s->s3->tmp.cert_req != 0. cert_req of 0 means "we are not sending a Certificate message". A cert_req of 1 means "we are sending a Certificate message, and it has a certificate in it", a cert_req of 2 means "we are sending a Certificate message, but it has no Certificate in it" (don't shoot the messenger that's the way the existing code works).
ssl/statem/statem_clnt.c
Outdated
ssl/statem/statem_clnt.c
Outdated
ssl/statem/statem_clnt.c
Outdated
There was a problem hiding this comment.
I prefer "/* FALLTHROUGH */" but probably because I'm an old fogey: http://wiki.c2.com/?LintComments
Not a blocker.
ssl/t1_lib.c
Outdated
There was a problem hiding this comment.
don't need the curly braces. I would do
return i == num_groups ? 0 : 1;
or
return i < num_groups;
ssl/t1_lib.c
Outdated
There was a problem hiding this comment.
should we have a utility function
# define SSLalerterr(a, ap, f, r) (ap=a, SSLerr(f, r), 0)
And then we could do
return SSLalerterr(al, SSL_AD_INTERNAL_ERROR, SSL_F_SCAN_CLIENTHELLO_TLSEXT, SSL_R_LENGTH_MISMATCH)
Obviously a separate MR. But would you be interested in that?
There was a problem hiding this comment.
Maybe...I'm not averse to someone else picking it up, put it that way ;-)
ssl/t1_lib.c
Outdated
There was a problem hiding this comment.
didn't you create a macro for this?
There was a problem hiding this comment.
Yes (after I first created this PR). Fixed now.
ssl/t1_lib.c
Outdated
There was a problem hiding this comment.
move this down to just before line 2865 (with no extra blank line)?
test/recipes/70-test_tlsextms.t
Outdated
There was a problem hiding this comment.
maybe $numtests++ if !disabled("tls1_3"); ? your decision.
ssl/statem/statem_clnt.c
Outdated
There was a problem hiding this comment.
A "TODO(TLS1.3): implement the real 1.3 state machine instead of 1.2-that-calls-itself-1.3" would have saved me a bit of confusion.
ssl/statem/statem_srvr.c
Outdated
There was a problem hiding this comment.
It seems like TODO(TLS1.3) is the convention
ssl/statem/statem_clnt.c
Outdated
There was a problem hiding this comment.
Should we assert that this does not happen (or have an error case for it)?
There was a problem hiding this comment.
Well...we do (see the default case below)
ssl/t1_enc.c
Outdated
There was a problem hiding this comment.
It's also unclear that s->hit is the right thing to be checking here -- I think external (non-resumption) PSK would trigger this conditional as it stasnds.
ssl/t1_lib.c
Outdated
ssl/t1_lib.c
Outdated
There was a problem hiding this comment.
Is it too soon to be worrying about == vs. >=?
There was a problem hiding this comment.
Should be SSL_IS_TLS13(s)
ssl/t1_lib.c
Outdated
There was a problem hiding this comment.
Should the loop body move into a helper function?
ssl/t1_lib.c
Outdated
There was a problem hiding this comment.
Do the 'get_curvelist's need to be inside the loop?
There was a problem hiding this comment.
I'm not sure I follow. We are looping through each of the key_shares sent from the client. For each one we need to check that (1) the group also appears in the supported_groups sent by the client and (2) that it is for a group we can use. If the first fails we abort, and if the second fails then we have to continue the loop on the next key_share...so, yes, it needs to be in the loop?
There was a problem hiding this comment.
I was thinking that the values stored in &curves and &num_curves are not going to change for a given s and given second argument, so we could have separate local variables for the peer's supported_groups and what we support, and then just make two calls to tls1_get_curvelist (outside the loop), instead of two times the number of key_shares calls.
ssl/t1_lib.c
Outdated
There was a problem hiding this comment.
This comment is too imprecise; is it "Check that the group for this key share is in the supported_groups that the client sent"? (That is probably too long, but for clarity here.)
There was a problem hiding this comment.
You wouldn't even add an "if" to make it grammatical?
There was a problem hiding this comment.
sure. who cares. but sure.
There was a problem hiding this comment.
I changed it to "Check if this share is in supported_groups sent from client"
ssl/t1_lib.c
Outdated
There was a problem hiding this comment.
How about "Check if this share is for a group we can use"?
ssl/statem/statem_clnt.c
Outdated
ssl/statem/statem_clnt.c
Outdated
There was a problem hiding this comment.
Oops. This was written before we came to that resolution. Fixed.
ssl/statem/statem_clnt.c
Outdated
There was a problem hiding this comment.
tlsext_ticket_expected is boolean, whilst cert_req is not - hence the difference
ssl/statem/statem_clnt.c
Outdated
There was a problem hiding this comment.
It really should be s->s3->tmp.cert_req != 0. cert_req of 0 means "we are not sending a Certificate message". A cert_req of 1 means "we are sending a Certificate message, and it has a certificate in it", a cert_req of 2 means "we are sending a Certificate message, but it has no Certificate in it" (don't shoot the messenger that's the way the existing code works).
ssl/statem/statem_clnt.c
Outdated
There was a problem hiding this comment.
We still need the == 1 here (it can be 2)
test/recipes/70-test_tlsextms.t
Outdated
ssl/statem/statem_srvr.c
Outdated
There was a problem hiding this comment.
I changed this to SSL_IS_TLS13(s)
ssl/t1_lib.c
Outdated
There was a problem hiding this comment.
Changed this (and the instance below to SSL_IS_TLS13(s)
ssl/t1_lib.c
Outdated
There was a problem hiding this comment.
Changed to SSL_IS_TLS13(s)
ssl/t1_lib.c
Outdated
There was a problem hiding this comment.
Changed to SSL_IS_TLS13(s)
|
New commit pushed addressing feedback comments. |
|
We should never do DH key exchange; only ECDH. I'd prefer we didnt even have that comment, but okay. Just one or two open questions then I can plus-one. |
levitte
left a comment
There was a problem hiding this comment.
make update has complaints:
$ $make update
ssl/t1_lib.c:1531:add_client_key_share_ext:ssl_add_serverhello_tlsext
ssl/t1_lib.c:1538:add_client_key_share_ext:ssl_add_serverhello_tlsext
ssl/t1_lib.c:1547:add_client_key_share_ext:ssl_add_serverhello_tlsext
ssl/t1_lib.c:1554:add_client_key_share_ext:ssl_add_serverhello_tlsext
ssl/t1_lib.c:1565:add_client_key_share_ext:ssl_add_serverhello_tlsext
ssl/t1_lib.c:1980:process_key_share_ext:ssl_scan_clienthello_tlsext
ssl/t1_lib.c:1986:process_key_share_ext:ssl_scan_clienthello_tlsext
ssl/t1_lib.c:1996:process_key_share_ext:ssl_scan_clienthello_tlsext
ssl/t1_lib.c:2011:process_key_share_ext:ssl_scan_clienthello_tlsext
ssl/t1_lib.c:2017:process_key_share_ext:ssl_scan_clienthello_tlsext
ssl/t1_lib.c:2025:process_key_share_ext:ssl_scan_clienthello_tlsext
ssl/t1_lib.c:2038:process_key_share_ext:ssl_scan_clienthello_tlsext
ssl/t1_lib.c:2049:process_key_share_ext:ssl_scan_clienthello_tlsext
ssl/t1_lib.c:2063:process_key_share_ext:ssl_scan_clienthello_tlsext
ssl/t1_lib.c:2076:process_key_share_ext:ssl_scan_clienthello_tlsext
FATAL: error discrepancy
make: *** [errors] Error 1
In this commit we just generate the extension on the client side, but don't yet do anything with it. Subsequent commits, will add the server side capability. At the moment we hard code a single key_share. In the future we should make this configurable.
At the moment the server doesn't yet do anything with this information. We still need to send the server's key_share info back to the client. That will happen in subsequent commits.
This is a temporary fix for while we are still using the old session resumption logic in the TLSv1.3 code. Due to differences in EXTMS support we can't resume a <=TLSv1.2 session in a TLSv1.3 connection (the EXTMS consistency check causes the connection to abort). This causes test failures. Ultimately we will rewrite the session resumption logic for TLSv1.3 so this problem will go away. But until then we need a quick fix to keep the tests happy.
The previous commits put in place the logic to exchange key_share data. We now need to do something with that information. In <= TLSv1.2 the equivalent of the key_share extension is the ServerKeyExchange and ClientKeyExchange messages. With key_share those two messages are no longer necessary. The commit removes the SKE and CKE messages from the TLSv1.3 state machine. TLSv1.3 is completely different to TLSv1.2 in the messages that it sends and the transitions that are allowed. Therefore, rather than extend the existing <=TLS1.2 state transition functions, we create a whole new set for TLSv1.3. Intially these are still based on the TLSv1.2 ones, but over time they will be amended. The new TLSv1.3 transitions remove SKE and CKE completely. There's also some cleanup for some stuff which is not relevant to TLSv1.3 and is easy to remove, e.g. the DTLS support (we're not doing DTLSv1.3 yet) and NPN. I also disable EXTMS for TLSv1.3. Using it was causing some added complexity, so rather than fix it I removed it, since eventually it will not be needed anyway.
Numerous style issues as well as references to TLS1_3_VERSION instead of SSL_IS_TLS13(s)
No need to continually get the list of supported curves for the client and server. Just do it once.
1d8e770 to
1e4b922
Compare
I can't locate this comment anymore in github. Anyway, I moved the two |
|
New commits pushed, addressing all feedback and fixing |
|
+1 |
Gah! Github has totally screwed up the threading on this particular discussion, and its quite difficult to follow....however, I think you are referring to this comment:
Which (I think) is in reference to this code in statem_srvr.c: There is no PSK support yet for TLSv1.3. We'll sort that out when we get to it. |
|
Pushed. Thanks. |
Checklist
Description of change
This adds support for generating and processing the key_share extension on both the client and the server. There are a few restrictions with this current version which will be fixed in later PRs:
The key_share extension does the job of key_exchange which in <=TLSv1.2 is done by the ServerKeyExchange and ClientKeyExchange messages. The TLSv1.3 code in master is still essentially TLSv1.2, so this PR also removes the generation and processing of the SKE and CKE messages. The result is a protocol that is neither TLSv1.2 nor TLSv1.3 but somewhere in the middle. Over time more PRs will move it closer to "real" TLSv1.3.
This PR includes the commits from PRs: #1807, #1808, #1825 and #1847. Therefore please only look at the last 11 commits.