github.com/pion/dtls/v2@v2.2.12/flight5bhandler.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 flight5bParse(_ 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, false, 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 flight5b.
    30  	return flight5b, nil, nil
    31  }
    32  
    33  func flight5bGenerate(_ flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) ([]*packet, *alert.Alert, error) { //nolint:gocognit
    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.TypeFinished, cfg.initialEpoch + 1, false, false},
    51  		)
    52  
    53  		var err error
    54  		state.localVerifyData, err = prf.VerifyDataClient(state.masterSecret, plainText, state.cipherSuite.HashFunc())
    55  		if err != nil {
    56  			return nil, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err
    57  		}
    58  	}
    59  
    60  	pkts = append(pkts,
    61  		&packet{
    62  			record: &recordlayer.RecordLayer{
    63  				Header: recordlayer.Header{
    64  					Version: protocol.Version1_2,
    65  					Epoch:   1,
    66  				},
    67  				Content: &handshake.Handshake{
    68  					Message: &handshake.MessageFinished{
    69  						VerifyData: state.localVerifyData,
    70  					},
    71  				},
    72  			},
    73  			shouldEncrypt:            true,
    74  			resetLocalSequenceNumber: true,
    75  		})
    76  
    77  	return pkts, nil, nil
    78  }