flight6handler.go 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
  2. // SPDX-License-Identifier: MIT
  3. package dtls
  4. import (
  5. "context"
  6. "github.com/pion/dtls/v2/pkg/crypto/prf"
  7. "github.com/pion/dtls/v2/pkg/protocol"
  8. "github.com/pion/dtls/v2/pkg/protocol/alert"
  9. "github.com/pion/dtls/v2/pkg/protocol/handshake"
  10. "github.com/pion/dtls/v2/pkg/protocol/recordlayer"
  11. )
  12. func flight6Parse(_ context.Context, _ flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert.Alert, error) {
  13. _, msgs, ok := cache.fullPullMap(state.handshakeRecvSequence-1, state.cipherSuite,
  14. handshakeCachePullRule{handshake.TypeFinished, cfg.initialEpoch + 1, true, false},
  15. )
  16. if !ok {
  17. // No valid message received. Keep reading
  18. return 0, nil, nil
  19. }
  20. if _, ok = msgs[handshake.TypeFinished].(*handshake.MessageFinished); !ok {
  21. return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, nil
  22. }
  23. // Other party may re-transmit the last flight. Keep state to be flight6.
  24. return flight6, nil, nil
  25. }
  26. func flight6Generate(_ context.Context, _ flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) ([]*packet, *alert.Alert, error) {
  27. var pkts []*packet
  28. pkts = append(pkts,
  29. &packet{
  30. record: &recordlayer.RecordLayer{
  31. Header: recordlayer.Header{
  32. Version: protocol.Version1_2,
  33. },
  34. Content: &protocol.ChangeCipherSpec{},
  35. },
  36. })
  37. if len(state.localVerifyData) == 0 {
  38. plainText := cache.pullAndMerge(
  39. handshakeCachePullRule{handshake.TypeClientHello, cfg.initialEpoch, true, false},
  40. handshakeCachePullRule{handshake.TypeServerHello, cfg.initialEpoch, false, false},
  41. handshakeCachePullRule{handshake.TypeCertificate, cfg.initialEpoch, false, false},
  42. handshakeCachePullRule{handshake.TypeServerKeyExchange, cfg.initialEpoch, false, false},
  43. handshakeCachePullRule{handshake.TypeCertificateRequest, cfg.initialEpoch, false, false},
  44. handshakeCachePullRule{handshake.TypeServerHelloDone, cfg.initialEpoch, false, false},
  45. handshakeCachePullRule{handshake.TypeCertificate, cfg.initialEpoch, true, false},
  46. handshakeCachePullRule{handshake.TypeClientKeyExchange, cfg.initialEpoch, true, false},
  47. handshakeCachePullRule{handshake.TypeCertificateVerify, cfg.initialEpoch, true, false},
  48. handshakeCachePullRule{handshake.TypeFinished, cfg.initialEpoch + 1, true, false},
  49. )
  50. var err error
  51. state.localVerifyData, err = prf.VerifyDataServer(state.masterSecret, plainText, state.cipherSuite.HashFunc())
  52. if err != nil {
  53. return nil, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err
  54. }
  55. }
  56. pkts = append(pkts,
  57. &packet{
  58. record: &recordlayer.RecordLayer{
  59. Header: recordlayer.Header{
  60. Version: protocol.Version1_2,
  61. Epoch: 1,
  62. },
  63. Content: &handshake.Handshake{
  64. Message: &handshake.MessageFinished{
  65. VerifyData: state.localVerifyData,
  66. },
  67. },
  68. },
  69. shouldEncrypt: true,
  70. resetLocalSequenceNumber: true,
  71. },
  72. )
  73. return pkts, nil, nil
  74. }