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 }