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