github.com/pion/dtls/v2@v2.2.12/handshake_cache_test.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  	"bytes"
     8  	"testing"
     9  
    10  	"github.com/pion/dtls/v2/internal/ciphersuite"
    11  	"github.com/pion/dtls/v2/pkg/protocol/handshake"
    12  )
    13  
    14  func TestHandshakeCacheSinglePush(t *testing.T) {
    15  	for _, test := range []struct {
    16  		Name     string
    17  		Rule     []handshakeCachePullRule
    18  		Input    []handshakeCacheItem
    19  		Expected []byte
    20  	}{
    21  		{
    22  			Name: "Single Push",
    23  			Input: []handshakeCacheItem{
    24  				{0, true, 0, 0, []byte{0x00}},
    25  			},
    26  			Rule: []handshakeCachePullRule{
    27  				{0, 0, true, false},
    28  			},
    29  			Expected: []byte{0x00},
    30  		},
    31  		{
    32  			Name: "Multi Push",
    33  			Input: []handshakeCacheItem{
    34  				{0, true, 0, 0, []byte{0x00}},
    35  				{1, true, 0, 1, []byte{0x01}},
    36  				{2, true, 0, 2, []byte{0x02}},
    37  			},
    38  			Rule: []handshakeCachePullRule{
    39  				{0, 0, true, false},
    40  				{1, 0, true, false},
    41  				{2, 0, true, false},
    42  			},
    43  			Expected: []byte{0x00, 0x01, 0x02},
    44  		},
    45  		{
    46  			Name: "Multi Push, Rules set order",
    47  			Input: []handshakeCacheItem{
    48  				{2, true, 0, 2, []byte{0x02}},
    49  				{0, true, 0, 0, []byte{0x00}},
    50  				{1, true, 0, 1, []byte{0x01}},
    51  			},
    52  			Rule: []handshakeCachePullRule{
    53  				{0, 0, true, false},
    54  				{1, 0, true, false},
    55  				{2, 0, true, false},
    56  			},
    57  			Expected: []byte{0x00, 0x01, 0x02},
    58  		},
    59  
    60  		{
    61  			Name: "Multi Push, Dupe Seqnum",
    62  			Input: []handshakeCacheItem{
    63  				{0, true, 0, 0, []byte{0x00}},
    64  				{1, true, 0, 1, []byte{0x01}},
    65  				{1, true, 0, 1, []byte{0x01}},
    66  			},
    67  			Rule: []handshakeCachePullRule{
    68  				{0, 0, true, false},
    69  				{1, 0, true, false},
    70  			},
    71  			Expected: []byte{0x00, 0x01},
    72  		},
    73  		{
    74  			Name: "Multi Push, Dupe Seqnum Client/Server",
    75  			Input: []handshakeCacheItem{
    76  				{0, true, 0, 0, []byte{0x00}},
    77  				{1, true, 0, 1, []byte{0x01}},
    78  				{1, false, 0, 1, []byte{0x02}},
    79  			},
    80  			Rule: []handshakeCachePullRule{
    81  				{0, 0, true, false},
    82  				{1, 0, true, false},
    83  				{1, 0, false, false},
    84  			},
    85  			Expected: []byte{0x00, 0x01, 0x02},
    86  		},
    87  		{
    88  			Name: "Multi Push, Dupe Seqnum with Unique HandshakeType",
    89  			Input: []handshakeCacheItem{
    90  				{1, true, 0, 0, []byte{0x00}},
    91  				{2, true, 0, 1, []byte{0x01}},
    92  				{3, false, 0, 0, []byte{0x02}},
    93  			},
    94  			Rule: []handshakeCachePullRule{
    95  				{1, 0, true, false},
    96  				{2, 0, true, false},
    97  				{3, 0, false, false},
    98  			},
    99  			Expected: []byte{0x00, 0x01, 0x02},
   100  		},
   101  		{
   102  			Name: "Multi Push, Wrong epoch",
   103  			Input: []handshakeCacheItem{
   104  				{1, true, 0, 0, []byte{0x00}},
   105  				{2, true, 1, 1, []byte{0x01}},
   106  				{2, true, 0, 2, []byte{0x11}},
   107  				{3, false, 0, 0, []byte{0x02}},
   108  				{3, false, 1, 0, []byte{0x12}},
   109  				{3, false, 2, 0, []byte{0x12}},
   110  			},
   111  			Rule: []handshakeCachePullRule{
   112  				{1, 0, true, false},
   113  				{2, 1, true, false},
   114  				{3, 0, false, false},
   115  			},
   116  			Expected: []byte{0x00, 0x01, 0x02},
   117  		},
   118  	} {
   119  		h := newHandshakeCache()
   120  		for _, i := range test.Input {
   121  			h.push(i.data, i.epoch, i.messageSequence, i.typ, i.isClient)
   122  		}
   123  		verifyData := h.pullAndMerge(test.Rule...)
   124  		if !bytes.Equal(verifyData, test.Expected) {
   125  			t.Errorf("handshakeCache '%s' exp: % 02x actual % 02x", test.Name, test.Expected, verifyData)
   126  		}
   127  	}
   128  }
   129  
   130  func TestHandshakeCacheSessionHash(t *testing.T) {
   131  	for _, test := range []struct {
   132  		Name     string
   133  		Rule     []handshakeCachePullRule
   134  		Input    []handshakeCacheItem
   135  		Expected []byte
   136  	}{
   137  		{
   138  			Name: "Standard Handshake",
   139  			Input: []handshakeCacheItem{
   140  				{handshake.TypeClientHello, true, 0, 0, []byte{0x00}},
   141  				{handshake.TypeServerHello, false, 0, 1, []byte{0x01}},
   142  				{handshake.TypeCertificate, false, 0, 2, []byte{0x02}},
   143  				{handshake.TypeServerKeyExchange, false, 0, 3, []byte{0x03}},
   144  				{handshake.TypeServerHelloDone, false, 0, 4, []byte{0x04}},
   145  				{handshake.TypeClientKeyExchange, true, 0, 5, []byte{0x05}},
   146  			},
   147  			Expected: []byte{0x17, 0xe8, 0x8d, 0xb1, 0x87, 0xaf, 0xd6, 0x2c, 0x16, 0xe5, 0xde, 0xbf, 0x3e, 0x65, 0x27, 0xcd, 0x00, 0x6b, 0xc0, 0x12, 0xbc, 0x90, 0xb5, 0x1a, 0x81, 0x0c, 0xd8, 0x0c, 0x2d, 0x51, 0x1f, 0x43},
   148  		},
   149  		{
   150  			Name: "Handshake With Client Cert Request",
   151  			Input: []handshakeCacheItem{
   152  				{handshake.TypeClientHello, true, 0, 0, []byte{0x00}},
   153  				{handshake.TypeServerHello, false, 0, 1, []byte{0x01}},
   154  				{handshake.TypeCertificate, false, 0, 2, []byte{0x02}},
   155  				{handshake.TypeServerKeyExchange, false, 0, 3, []byte{0x03}},
   156  				{handshake.TypeCertificateRequest, false, 0, 4, []byte{0x04}},
   157  				{handshake.TypeServerHelloDone, false, 0, 5, []byte{0x05}},
   158  				{handshake.TypeClientKeyExchange, true, 0, 6, []byte{0x06}},
   159  			},
   160  			Expected: []byte{0x57, 0x35, 0x5a, 0xc3, 0x30, 0x3c, 0x14, 0x8f, 0x11, 0xae, 0xf7, 0xcb, 0x17, 0x94, 0x56, 0xb9, 0x23, 0x2c, 0xde, 0x33, 0xa8, 0x18, 0xdf, 0xda, 0x2c, 0x2f, 0xcb, 0x93, 0x25, 0x74, 0x9a, 0x6b},
   161  		},
   162  		{
   163  			Name: "Handshake Ignores after ClientKeyExchange",
   164  			Input: []handshakeCacheItem{
   165  				{handshake.TypeClientHello, true, 0, 0, []byte{0x00}},
   166  				{handshake.TypeServerHello, false, 0, 1, []byte{0x01}},
   167  				{handshake.TypeCertificate, false, 0, 2, []byte{0x02}},
   168  				{handshake.TypeServerKeyExchange, false, 0, 3, []byte{0x03}},
   169  				{handshake.TypeCertificateRequest, false, 0, 4, []byte{0x04}},
   170  				{handshake.TypeServerHelloDone, false, 0, 5, []byte{0x05}},
   171  				{handshake.TypeClientKeyExchange, true, 0, 6, []byte{0x06}},
   172  				{handshake.TypeCertificateVerify, true, 0, 7, []byte{0x07}},
   173  				{handshake.TypeFinished, true, 1, 7, []byte{0x08}},
   174  				{handshake.TypeFinished, false, 1, 7, []byte{0x09}},
   175  			},
   176  			Expected: []byte{0x57, 0x35, 0x5a, 0xc3, 0x30, 0x3c, 0x14, 0x8f, 0x11, 0xae, 0xf7, 0xcb, 0x17, 0x94, 0x56, 0xb9, 0x23, 0x2c, 0xde, 0x33, 0xa8, 0x18, 0xdf, 0xda, 0x2c, 0x2f, 0xcb, 0x93, 0x25, 0x74, 0x9a, 0x6b},
   177  		},
   178  		{
   179  			Name: "Handshake Ignores wrong epoch",
   180  			Input: []handshakeCacheItem{
   181  				{handshake.TypeClientHello, true, 0, 0, []byte{0x00}},
   182  				{handshake.TypeServerHello, false, 0, 1, []byte{0x01}},
   183  				{handshake.TypeCertificate, false, 0, 2, []byte{0x02}},
   184  				{handshake.TypeServerKeyExchange, false, 0, 3, []byte{0x03}},
   185  				{handshake.TypeCertificateRequest, false, 0, 4, []byte{0x04}},
   186  				{handshake.TypeServerHelloDone, false, 0, 5, []byte{0x05}},
   187  				{handshake.TypeClientKeyExchange, true, 0, 6, []byte{0x06}},
   188  				{handshake.TypeCertificateVerify, true, 0, 7, []byte{0x07}},
   189  				{handshake.TypeFinished, true, 0, 7, []byte{0xf0}},
   190  				{handshake.TypeFinished, false, 0, 7, []byte{0xf1}},
   191  				{handshake.TypeFinished, true, 1, 7, []byte{0x08}},
   192  				{handshake.TypeFinished, false, 1, 7, []byte{0x09}},
   193  				{handshake.TypeFinished, true, 0, 7, []byte{0xf0}},
   194  				{handshake.TypeFinished, false, 0, 7, []byte{0xf1}},
   195  			},
   196  			Expected: []byte{0x57, 0x35, 0x5a, 0xc3, 0x30, 0x3c, 0x14, 0x8f, 0x11, 0xae, 0xf7, 0xcb, 0x17, 0x94, 0x56, 0xb9, 0x23, 0x2c, 0xde, 0x33, 0xa8, 0x18, 0xdf, 0xda, 0x2c, 0x2f, 0xcb, 0x93, 0x25, 0x74, 0x9a, 0x6b},
   197  		},
   198  	} {
   199  		h := newHandshakeCache()
   200  		for _, i := range test.Input {
   201  			h.push(i.data, i.epoch, i.messageSequence, i.typ, i.isClient)
   202  		}
   203  
   204  		cipherSuite := ciphersuite.TLSEcdheEcdsaWithAes128GcmSha256{}
   205  		verifyData, err := h.sessionHash(cipherSuite.HashFunc(), 0)
   206  		if err != nil {
   207  			t.Error(err)
   208  		}
   209  		if !bytes.Equal(verifyData, test.Expected) {
   210  			t.Errorf("handshakeCacheSesssionHassh '%s' exp: % 02x actual % 02x", test.Name, test.Expected, verifyData)
   211  		}
   212  	}
   213  }