@@ -28,7 +28,7 @@ type recordProtection13TestCase struct {
2828}
2929
3030type tls13RecordProtectionSuite interface {
31- CipherSuite
31+ CipherSuiteTLS13
3232 newRecordProtection (localTrafficSecret , remoteTrafficSecret []byte ) (* recordProtection13 , error )
3333}
3434
@@ -89,6 +89,46 @@ func trafficSecret13(suite tls13RecordProtectionSuite, fill byte) []byte {
8989 return bytes .Repeat ([]byte {fill }, hashFunc ().Size ())
9090}
9191
92+ func newRecordProtection13TestSuite (t * testing.T , name string ) tls13RecordProtectionSuite {
93+ t .Helper ()
94+
95+ for _ , testCase := range recordProtection13TestCases () {
96+ if testCase .name == name {
97+ return testCase .suite
98+ }
99+ }
100+
101+ assert .FailNowf (t , "unknown TLS 1.3 test suite" , "name: %s" , name )
102+
103+ return nil
104+ }
105+
106+ func requireRecordProtection13 (t * testing.T , suite tls13RecordProtectionSuite ) * recordProtection13 {
107+ t .Helper ()
108+
109+ switch s := suite .(type ) {
110+ case * TLSAes128GcmSha256 :
111+ protection , ok := s .getRecordProtection13 ()
112+ require .True (t , ok )
113+
114+ return protection
115+ case * TLSAes256GcmSha384 :
116+ protection , ok := s .getRecordProtection13 ()
117+ require .True (t , ok )
118+
119+ return protection
120+ case * TLSChacha20Poly1305Sha256 :
121+ protection , ok := s .getRecordProtection13 ()
122+ require .True (t , ok )
123+
124+ return protection
125+ default :
126+ assert .FailNowf (t , "unknown TLS 1.3 test suite" , "suite: %T" , suite )
127+
128+ return nil
129+ }
130+ }
131+
92132func TestDeriveRecordTrafficKeys13Suites (t * testing.T ) {
93133 for _ , testCase := range recordProtection13TestCases () {
94134 t .Run (testCase .name , func (t * testing.T ) {
@@ -171,6 +211,44 @@ func TestTLS13CipherSuiteNewRecordProtectionSuites(t *testing.T) {
171211 }
172212}
173213
214+ func TestTLS13CipherSuiteInitFromTrafficSecrets13 (t * testing.T ) {
215+ for _ , testCase := range recordProtection13TestCases () {
216+ t .Run (testCase .name , func (t * testing.T ) {
217+ clientSuite := testCase .suite
218+ serverSuite := newRecordProtection13TestSuite (t , testCase .name )
219+
220+ clientSecret := trafficSecret13 (testCase .suite , 0xa6 )
221+ serverSecret := trafficSecret13 (testCase .suite , 0xb6 )
222+
223+ require .False (t , clientSuite .IsInitialized ())
224+ require .False (t , serverSuite .IsInitialized ())
225+
226+ require .NoError (t , clientSuite .InitFromTrafficSecrets13 (clientSecret , serverSecret , true ))
227+ require .NoError (t , serverSuite .InitFromTrafficSecrets13 (clientSecret , serverSecret , false ))
228+
229+ require .True (t , clientSuite .IsInitialized ())
230+ require .True (t , serverSuite .IsInitialized ())
231+
232+ clientProtection := requireRecordProtection13 (t , clientSuite )
233+ serverProtection := requireRecordProtection13 (t , serverSuite )
234+ header := recordlayer.UnifiedHeader {
235+ SequenceNumber : 0x1234 ,
236+ EpochLow : 2 ,
237+ }
238+ sequenceNumber := uint64 (0x0102030405060708 )
239+ plaintext := []byte ("traffic-secret initialized payload" )
240+
241+ record , err := clientProtection .seal (header , sequenceNumber , protocol .ContentTypeApplicationData , plaintext )
242+ require .NoError (t , err )
243+
244+ innerPlaintext , err := serverProtection .open (record .Header , sequenceNumber , record .EncryptedRecord )
245+ require .NoError (t , err )
246+ assert .Equal (t , plaintext , innerPlaintext .Content )
247+ assert .Equal (t , protocol .ContentTypeApplicationData , innerPlaintext .RealType )
248+ })
249+ }
250+ }
251+
174252func TestRecordProtection13SealOpenSyntheticTrafficSecret (t * testing.T ) {
175253 for _ , testCase := range recordProtection13TestCases () {
176254 t .Run (testCase .name , func (t * testing.T ) {
0 commit comments