flight2handler.go 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
  2. // SPDX-License-Identifier: MIT
  3. package dtls
  4. import (
  5. "bytes"
  6. "context"
  7. "errors"
  8. "github.com/pion/dtls/v2/pkg/protocol"
  9. "github.com/pion/dtls/v2/pkg/protocol/alert"
  10. "github.com/pion/dtls/v2/pkg/protocol/handshake"
  11. "github.com/pion/dtls/v2/pkg/protocol/recordlayer"
  12. )
  13. func flight2Parse(ctx context.Context, c flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert.Alert, error) {
  14. seq, msgs, ok := cache.fullPullMap(state.handshakeRecvSequence, state.cipherSuite,
  15. handshakeCachePullRule{handshake.TypeClientHello, cfg.initialEpoch, true, false},
  16. )
  17. if !ok {
  18. // Client may retransmit the first ClientHello when HelloVerifyRequest is dropped.
  19. // Parse as flight 0 in this case.
  20. return flight0Parse(ctx, c, state, cache, cfg)
  21. }
  22. state.handshakeRecvSequence = seq
  23. var clientHello *handshake.MessageClientHello
  24. // Validate type
  25. if clientHello, ok = msgs[handshake.TypeClientHello].(*handshake.MessageClientHello); !ok {
  26. return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, nil
  27. }
  28. if !clientHello.Version.Equal(protocol.Version1_2) {
  29. return 0, &alert.Alert{Level: alert.Fatal, Description: alert.ProtocolVersion}, errUnsupportedProtocolVersion
  30. }
  31. if len(clientHello.Cookie) == 0 {
  32. return 0, nil, nil
  33. }
  34. if !bytes.Equal(state.cookie, clientHello.Cookie) {
  35. return 0, &alert.Alert{Level: alert.Fatal, Description: alert.AccessDenied}, errCookieMismatch
  36. }
  37. return flight4, nil, nil
  38. }
  39. func flight2Generate(_ context.Context, _ flightConn, state *State, _ *handshakeCache, _ *handshakeConfig) ([]*packet, *alert.Alert, error) {
  40. // [Psiphon]
  41. // With SetDTLSInsecureSkipHelloVerify set, this should never be called,
  42. // so handshake randomization is not implemented here.
  43. return nil, nil, errors.New("unexpected flight2Generate call")
  44. state.handshakeSendSequence = 0
  45. return []*packet{
  46. {
  47. record: &recordlayer.RecordLayer{
  48. Header: recordlayer.Header{
  49. Version: protocol.Version1_2,
  50. },
  51. Content: &handshake.Handshake{
  52. Message: &handshake.MessageHelloVerifyRequest{
  53. Version: protocol.Version1_2,
  54. Cookie: state.cookie,
  55. },
  56. },
  57. },
  58. },
  59. }, nil, nil
  60. }