Skip to content
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

Add separate stateless processing for client_hello of epoch 0. #89

Merged
merged 1 commit into from
Oct 1, 2021

Conversation

boaks
Copy link
Contributor

@boaks boaks commented Jun 9, 2021

The PR is on the top of some other pending ones.
If at all merged, it is intended to be merged after these PRs.

Use the record and message sequence numbers of that client_hellos for
either sending a hello verify request or starting the handshake on the
server side with sending a server_hello.

The function of a HELLO_REQUEST is unclear and therefore not considered.
In some scopes a HELLO_REQUEST is only used for associated peers to
trigger a rehandshake (handshake executed within an previous encrypted
association, epoch > 0), and some scopes seems to handle also
situations, where either no previous association is required or the new
handshake is executed in epoch 0. That may be clarified either before or
after this change.

Signed-off-by: Achim Kraus [email protected]

@boaks boaks force-pushed the stateless_client_hello branch 3 times, most recently from 51d7e10 to f8859c1 Compare June 23, 2021 14:20
@boaks boaks force-pushed the stateless_client_hello branch 2 times, most recently from 24bdd6e to 24d02cb Compare June 28, 2021 09:33
@boaks
Copy link
Contributor Author

boaks commented Jun 28, 2021

Together with the other PRs #91, #92, #94, this PR provides now a redesign and cleanup for processing CLIENT_HELLO in epoch 0 and removes some stuff, which seems for me to be work-arounds.

I removed the rudiments of the HELLO_REQUEST in epoch 0.
If really someone complains, it may be introduced again, then with details on how that should be processed.

@boaks boaks force-pushed the stateless_client_hello branch 2 times, most recently from 5edace2 to ed09aef Compare June 29, 2021 10:39
@obgm
Copy link
Contributor

obgm commented Jun 29, 2021

Thanks. May I ask you to change the spelling of DTLS messages in the commit message and in code comments in alignment with RFC 6347 (i.e., camel case: ClientHello, HelloRequest, Finished, etc.)?

@boaks
Copy link
Contributor Author

boaks commented Jun 29, 2021

Sure. I'm on it.

@boaks
Copy link
Contributor Author

boaks commented Jun 29, 2021

Done.

Do you prefer that CaMel also in the c-documentation?

@obgm
Copy link
Contributor

obgm commented Jun 29, 2021

Yes, please.

@boaks boaks force-pushed the stateless_client_hello branch 2 times, most recently from aecd264 to 0185aec Compare June 29, 2021 11:17
@boaks
Copy link
Contributor Author

boaks commented Jun 29, 2021

The comments should be fixed.

Let me know, if there is more editorial work to do. I will be back in the later afternoon :-).

@mrdeep1
Copy link
Contributor

mrdeep1 commented Jun 29, 2021

If I try using a bad PSK, the server fails to decrypt the Finished, which is fine. As there is no response to the 'bad' Finish the client retries sending the stuff from epoch 0 and then the Finished again in epoch 1.

The previous code reports

WARN Wrong epoch, expected 1, got: 0
WARN Wrong epoch, expected 1, got: 0
WARN Wrong epoch, expected 1, got: 0

and the new code

WARN The message sequence number is too small, expected 4, got: 1
WARN The message sequence number is too small, expected 4, got: 2
WARN The message sequence number is too small, expected 4, got: 3

As the server has done a ChangeCipherSpec and moved into epoch 1, should the server be continuing with the stateless processing for epoch 0?

As the Finished cannot be decrypted, there is no way of determining what the actual handshake is, but we know that it is in the new epoch as a handshake with a small record sequence number. Should we just drop this 'bad' record (as does OpenSSL) or send back an alert (as does GnuTLS - Bad Record MAC)?

@boaks
Copy link
Contributor Author

boaks commented Jun 29, 2021

I'm not sure, if I understand the scenario.

The "stateless" end with a ClientHello with a verified cookie.
After that, there is a peer.
Is it possible to see the wireshark capture?

@mrdeep1
Copy link
Contributor

mrdeep1 commented Jun 29, 2021

Sure - abstracted an example out of my test suite which gives slightly different results to what I reported above.
pr_89-1.pcap.zip

Server key was 12345678 , client key 87654321

Coap-Server log

Jun 29 18:35:21 WARN decryption failed
Jun 29 18:35:23 WARN The message sequence number is too small, expected 3, got: 2
Jun 29 18:35:23 WARN expected ChangeCipherSpec during handshake
Jun 29 18:35:23 WARN decryption failed
Jun 29 18:35:27 WARN The message sequence number is too small, expected 3, got: 2
Jun 29 18:35:27 WARN expected ChangeCipherSpec during handshake
Jun 29 18:35:27 WARN decryption failed
Jun 29 18:35:35 WARN The message sequence number is too small, expected 3, got: 2
Jun 29 18:35:35 WARN expected ChangeCipherSpec during handshake
Jun 29 18:35:35 WARN decryption failed
Jun 29 18:35:46 WARN decryption failed
Jun 29 18:35:59 WARN decryption failed
Jun 29 18:36:01 WARN The message sequence number is too small, expected 3, got: 2
Jun 29 18:36:01 WARN expected ChangeCipherSpec during handshake
Jun 29 18:36:01 WARN decryption failed
Jun 29 18:36:05 WARN The message sequence number is too small, expected 3, got: 2
Jun 29 18:36:05 WARN expected ChangeCipherSpec during handshake
Jun 29 18:36:05 WARN decryption failed
Jun 29 18:36:13 WARN The message sequence number is too small, expected 3, got: 2
Jun 29 18:36:13 WARN expected ChangeCipherSpec during handshake
Jun 29 18:36:13 WARN decryption failed
Jun 29 18:36:19 WARN decryption failed

The "stateless" end with a ClientHello with a verified cookie.
After that, there is a peer.

Agreed, however the code for case DTLS_CT_HANDSHAKE: in dtls_handle_message() no longer checks that the handshake is in the right epoch and so goes on the report the The message sequence number is too small, expected .

@boaks
Copy link
Contributor Author

boaks commented Jun 29, 2021

As the Finished cannot be decrypted, there is no way of determining what the actual handshake is, but we know that it is in the new epoch as a handshake with a small record sequence number. Should we just drop this 'bad' record (as does OpenSSL) or send back an alert (as does GnuTLS - Bad Record MAC)?

I'm not sure, if "GnuTLS - Bad Record MAC" is intended. At least for Californium there was a discussion about that PSK-failures and in that context TLS-IETF. There we decide " just drop this 'bad' record (as does OpenSSL)".

@boaks
Copy link
Contributor Author

boaks commented Jun 29, 2021

my test suite

That's not in the tinydtls repo, or?
(I was already asking me, if there are more tests ...).

@mrdeep1
Copy link
Contributor

mrdeep1 commented Jun 29, 2021

No, it is not in the tinydtls repo.

I have built up a regression test suite for libcoap over time for testing out different functionality and using different (D)TLS libraries with good/bad keys/certs etc. Diffs are then done for actual against expected. When using valgrind, things grind on for hours.....

Unfortunately, it is very dependent on the host OS, versions of underlying (D)TLS libraries that were would be too many false positives if it was to became part of the libcoap repo.

@boaks
Copy link
Contributor Author

boaks commented Jun 29, 2021

Unfortunately, it is very dependent on the host OS, versions of underlying (D)TLS libraries that were would be too many false positives if it was to became part of the libcoap repo.

OK. Good to know, that there are more tests.

@boaks
Copy link
Contributor Author

boaks commented Jun 29, 2021

I checked the GnuTLS behavior, it closes on the retransmission of flight 5. So the first flight 5 seems to be ignored.

Even in the Californium discussion on 2018, I wasn't totally convinced , what the best behavior will be. Anyway, usually to systems are used with the "right credentials", so I don't care too much about the wrong ;-).

@boaks
Copy link
Contributor Author

boaks commented Jun 29, 2021

My feeling is, "alert or not", is not really changed by this PR (hope I'm right.)
But by other PRs before, I guess #91 .

@mrdeep1
Copy link
Contributor

mrdeep1 commented Jun 29, 2021

Prior to #91, Decrypt Error is returned when processing the Finished. This PR (which includes #91) changes the message that is reported.

RFC5246 says

   decrypt_error
      A handshake cryptographic operation failed, including being unable
      to correctly verify a signature or validate a Finished message.
      This message is always fatal.

But agree that RFC6347 effectively states that Alerts should not be sent.

I am not sure that check_finished() will ever get called if the wrong keys are used as it is not possible to decrypt the Finished and so there is no way of working out the handshake type (other than the clue of epoch change and small sequence no).

@boaks
Copy link
Contributor Author

boaks commented Jun 29, 2021

I am not sure that check_finished() will ever get called

That protects against "manipulated handshake messages", e.g. on-path-attacker.
If extended master secret is use, this will happen really rarely.

@boaks
Copy link
Contributor Author

boaks commented Jun 29, 2021

And using RPK changes the possible failure as well. There the encrytion may work more often, but manipulated handshake message may get detected.

@boaks
Copy link
Contributor Author

boaks commented Jun 30, 2021

Yes, please.

The c-documentation is updated to use CaMeL. I added some more information about the "stateless phase" (which ends with receiving a ClientHello with a valid cookie). I adapted the function names of the affected funtions to a pattern xxx_0_yyy, in order to easier detect them (the other difference is the ephemeral_peer instead of a peer).

@obgm
Copy link
Contributor

obgm commented Sep 28, 2021

@boaks Thank you, this looks good to me. I am not sure if the two commits should be squashed before merge. Do you have an opinion on that?

@boaks
Copy link
Contributor Author

boaks commented Sep 29, 2021

I am not sure if the two commits should be squashed before merge.

I would do so.

Though this PR together with #91 obsoletes #85, @mrdeep1 is that also OK for you?

@mrdeep1
Copy link
Contributor

mrdeep1 commented Sep 29, 2021

Fine by me.

@boaks
Copy link
Contributor Author

boaks commented Sep 29, 2021

OK, I squash and push.

Copy link
Contributor

@obgm obgm left a comment

Choose a reason for hiding this comment

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

A few minor nits, otherwise I think it is ready for merge.

dtls.c Outdated Show resolved Hide resolved
dtls.c Outdated Show resolved Hide resolved
dtls.c Outdated Show resolved Hide resolved
dtls.c Outdated Show resolved Hide resolved
dtls.c Outdated Show resolved Hide resolved
dtls.c Outdated Show resolved Hide resolved
dtls.c Outdated Show resolved Hide resolved
Use the record and message sequence numbers of that ClientHellos for
either sending a HelloVerifyRequest or starting the handshake on the
server side with sending a ServerHello.
To reduce the complexity, this stateless processing is separated in a
set of special functions, which use the new ephemeral_peer instead of
the old peer. The names of those function follow the pattern xxx_0_yyy
to indicate their usage in epoch 0.

Using a HelloRequest in epoch 0 is removed. If required, a
clarification about the processing details is required ahead.

Remove checks for peers and code/parameter, which have been used to
handle that missing peer.

(Fix some minor typos in comments and log messages.)

Signed-off-by: Achim Kraus <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants