flight6handler.go 2.8 KB

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