1// Copyright 2025 The BoringSSL Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package runner
16
17type perMessageTest struct {
18	messageType uint8
19	test        testCase
20}
21
22// makePerMessageTests returns a series of test templates which cover each
23// message in the TLS handshake. These may be used with bugs like
24// WrongMessageType to fully test a per-message bug.
25func makePerMessageTests() []perMessageTest {
26	var ret []perMessageTest
27	// The following tests are limited to TLS 1.2, so QUIC is not tested.
28	for _, protocol := range []protocol{tls, dtls} {
29		suffix := "-" + protocol.String()
30
31		ret = append(ret, perMessageTest{
32			messageType: typeClientHello,
33			test: testCase{
34				protocol: protocol,
35				testType: serverTest,
36				name:     "ClientHello" + suffix,
37				config: Config{
38					MaxVersion: VersionTLS12,
39				},
40			},
41		})
42
43		if protocol == dtls {
44			ret = append(ret, perMessageTest{
45				messageType: typeHelloVerifyRequest,
46				test: testCase{
47					protocol: protocol,
48					name:     "HelloVerifyRequest" + suffix,
49					config: Config{
50						MaxVersion: VersionTLS12,
51					},
52				},
53			})
54		}
55
56		ret = append(ret, perMessageTest{
57			messageType: typeServerHello,
58			test: testCase{
59				protocol: protocol,
60				name:     "ServerHello" + suffix,
61				config: Config{
62					MaxVersion: VersionTLS12,
63				},
64			},
65		})
66
67		ret = append(ret, perMessageTest{
68			messageType: typeCertificate,
69			test: testCase{
70				protocol: protocol,
71				name:     "ServerCertificate" + suffix,
72				config: Config{
73					MaxVersion: VersionTLS12,
74				},
75			},
76		})
77
78		ret = append(ret, perMessageTest{
79			messageType: typeCertificateStatus,
80			test: testCase{
81				protocol: protocol,
82				name:     "CertificateStatus" + suffix,
83				config: Config{
84					MaxVersion: VersionTLS12,
85					Credential: rsaCertificate.WithOCSP(testOCSPResponse),
86				},
87				flags: []string{"-enable-ocsp-stapling"},
88			},
89		})
90
91		ret = append(ret, perMessageTest{
92			messageType: typeServerKeyExchange,
93			test: testCase{
94				protocol: protocol,
95				name:     "ServerKeyExchange" + suffix,
96				config: Config{
97					MaxVersion:   VersionTLS12,
98					CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
99				},
100			},
101		})
102
103		ret = append(ret, perMessageTest{
104			messageType: typeCertificateRequest,
105			test: testCase{
106				protocol: protocol,
107				name:     "CertificateRequest" + suffix,
108				config: Config{
109					MaxVersion: VersionTLS12,
110					ClientAuth: RequireAnyClientCert,
111				},
112			},
113		})
114
115		ret = append(ret, perMessageTest{
116			messageType: typeServerHelloDone,
117			test: testCase{
118				protocol: protocol,
119				name:     "ServerHelloDone" + suffix,
120				config: Config{
121					MaxVersion: VersionTLS12,
122				},
123			},
124		})
125
126		ret = append(ret, perMessageTest{
127			messageType: typeCertificate,
128			test: testCase{
129				testType: serverTest,
130				protocol: protocol,
131				name:     "ClientCertificate" + suffix,
132				config: Config{
133					Credential: &rsaCertificate,
134					MaxVersion: VersionTLS12,
135				},
136				flags: []string{"-require-any-client-certificate"},
137			},
138		})
139
140		ret = append(ret, perMessageTest{
141			messageType: typeCertificateVerify,
142			test: testCase{
143				testType: serverTest,
144				protocol: protocol,
145				name:     "CertificateVerify" + suffix,
146				config: Config{
147					Credential: &rsaCertificate,
148					MaxVersion: VersionTLS12,
149				},
150				flags: []string{"-require-any-client-certificate"},
151			},
152		})
153
154		ret = append(ret, perMessageTest{
155			messageType: typeClientKeyExchange,
156			test: testCase{
157				testType: serverTest,
158				protocol: protocol,
159				name:     "ClientKeyExchange" + suffix,
160				config: Config{
161					MaxVersion: VersionTLS12,
162				},
163			},
164		})
165
166		if protocol != dtls {
167			ret = append(ret, perMessageTest{
168				messageType: typeNextProtocol,
169				test: testCase{
170					testType: serverTest,
171					protocol: protocol,
172					name:     "NextProtocol" + suffix,
173					config: Config{
174						MaxVersion: VersionTLS12,
175						NextProtos: []string{"bar"},
176					},
177					flags: []string{"-advertise-npn", "\x03foo\x03bar\x03baz"},
178				},
179			})
180
181			ret = append(ret, perMessageTest{
182				messageType: typeChannelID,
183				test: testCase{
184					testType: serverTest,
185					protocol: protocol,
186					name:     "ChannelID" + suffix,
187					config: Config{
188						MaxVersion: VersionTLS12,
189						ChannelID:  &channelIDKey,
190					},
191					flags: []string{
192						"-expect-channel-id",
193						base64FlagValue(channelIDBytes),
194					},
195				},
196			})
197		}
198
199		ret = append(ret, perMessageTest{
200			messageType: typeFinished,
201			test: testCase{
202				testType: serverTest,
203				protocol: protocol,
204				name:     "ClientFinished" + suffix,
205				config: Config{
206					MaxVersion: VersionTLS12,
207				},
208			},
209		})
210
211		ret = append(ret, perMessageTest{
212			messageType: typeNewSessionTicket,
213			test: testCase{
214				protocol: protocol,
215				name:     "NewSessionTicket" + suffix,
216				config: Config{
217					MaxVersion: VersionTLS12,
218				},
219			},
220		})
221
222		ret = append(ret, perMessageTest{
223			messageType: typeFinished,
224			test: testCase{
225				protocol: protocol,
226				name:     "ServerFinished" + suffix,
227				config: Config{
228					MaxVersion: VersionTLS12,
229				},
230			},
231		})
232
233	}
234
235	for _, protocol := range []protocol{tls, quic, dtls} {
236		suffix := "-" + protocol.String()
237		ret = append(ret, perMessageTest{
238			messageType: typeClientHello,
239			test: testCase{
240				testType: serverTest,
241				protocol: protocol,
242				name:     "TLS13-ClientHello" + suffix,
243				config: Config{
244					MaxVersion: VersionTLS13,
245				},
246			},
247		})
248
249		ret = append(ret, perMessageTest{
250			messageType: typeServerHello,
251			test: testCase{
252				name:     "TLS13-ServerHello" + suffix,
253				protocol: protocol,
254				config: Config{
255					MaxVersion: VersionTLS13,
256				},
257			},
258		})
259
260		ret = append(ret, perMessageTest{
261			messageType: typeEncryptedExtensions,
262			test: testCase{
263				name:     "TLS13-EncryptedExtensions" + suffix,
264				protocol: protocol,
265				config: Config{
266					MaxVersion: VersionTLS13,
267				},
268			},
269		})
270
271		ret = append(ret, perMessageTest{
272			messageType: typeCertificateRequest,
273			test: testCase{
274				name:     "TLS13-CertificateRequest" + suffix,
275				protocol: protocol,
276				config: Config{
277					MaxVersion: VersionTLS13,
278					ClientAuth: RequireAnyClientCert,
279				},
280			},
281		})
282
283		ret = append(ret, perMessageTest{
284			messageType: typeCertificate,
285			test: testCase{
286				name:     "TLS13-ServerCertificate" + suffix,
287				protocol: protocol,
288				config: Config{
289					MaxVersion: VersionTLS13,
290				},
291			},
292		})
293
294		ret = append(ret, perMessageTest{
295			messageType: typeCertificateVerify,
296			test: testCase{
297				name:     "TLS13-ServerCertificateVerify" + suffix,
298				protocol: protocol,
299				config: Config{
300					MaxVersion: VersionTLS13,
301				},
302			},
303		})
304
305		ret = append(ret, perMessageTest{
306			messageType: typeFinished,
307			test: testCase{
308				name:     "TLS13-ServerFinished" + suffix,
309				protocol: protocol,
310				config: Config{
311					MaxVersion: VersionTLS13,
312				},
313			},
314		})
315
316		ret = append(ret, perMessageTest{
317			messageType: typeCertificate,
318			test: testCase{
319				testType: serverTest,
320				protocol: protocol,
321				name:     "TLS13-ClientCertificate" + suffix,
322				config: Config{
323					Credential: &rsaCertificate,
324					MaxVersion: VersionTLS13,
325				},
326				flags: []string{"-require-any-client-certificate"},
327			},
328		})
329
330		ret = append(ret, perMessageTest{
331			messageType: typeCertificateVerify,
332			test: testCase{
333				testType: serverTest,
334				protocol: protocol,
335				name:     "TLS13-ClientCertificateVerify" + suffix,
336				config: Config{
337					Credential: &rsaCertificate,
338					MaxVersion: VersionTLS13,
339				},
340				flags: []string{"-require-any-client-certificate"},
341			},
342		})
343
344		ret = append(ret, perMessageTest{
345			messageType: typeFinished,
346			test: testCase{
347				testType: serverTest,
348				protocol: protocol,
349				name:     "TLS13-ClientFinished" + suffix,
350				config: Config{
351					MaxVersion: VersionTLS13,
352				},
353			},
354		})
355
356		// Only TLS uses EndOfEarlyData.
357		if protocol == tls {
358			ret = append(ret, perMessageTest{
359				messageType: typeEndOfEarlyData,
360				test: testCase{
361					testType: serverTest,
362					protocol: protocol,
363					name:     "TLS13-EndOfEarlyData" + suffix,
364					config: Config{
365						MaxVersion: VersionTLS13,
366					},
367					resumeSession: true,
368					earlyData:     true,
369				},
370			})
371		}
372	}
373
374	return ret
375}
376
377func addWrongMessageTypeTests() {
378	for _, t := range makePerMessageTests() {
379		t.test.name = "WrongMessageType-" + t.test.name
380		if t.test.resumeConfig != nil {
381			t.test.resumeConfig.Bugs.SendWrongMessageType = t.messageType
382		} else {
383			t.test.config.Bugs.SendWrongMessageType = t.messageType
384		}
385		t.test.shouldFail = true
386		t.test.expectedError = ":UNEXPECTED_MESSAGE:"
387		t.test.expectedLocalError = "remote error: unexpected message"
388
389		if t.test.config.MaxVersion >= VersionTLS13 && t.messageType == typeServerHello {
390			// In TLS 1.3, if the server believes it has sent ServerHello,
391			// but the client cannot process it, the client will send an
392			// unencrypted alert while the server expects encryption. This
393			// decryption failure is reported differently for each protocol, so
394			// leave it unchecked.
395			t.test.expectedLocalError = ""
396		}
397
398		testCases = append(testCases, t.test)
399	}
400}
401
402func addTrailingMessageDataTests() {
403	for _, t := range makePerMessageTests() {
404		t.test.name = "TrailingMessageData-" + t.test.name
405		if t.test.resumeConfig != nil {
406			t.test.resumeConfig.Bugs.SendTrailingMessageData = t.messageType
407		} else {
408			t.test.config.Bugs.SendTrailingMessageData = t.messageType
409		}
410		t.test.shouldFail = true
411		t.test.expectedError = ":DECODE_ERROR:"
412		t.test.expectedLocalError = "remote error: error decoding message"
413
414		if t.test.config.MaxVersion >= VersionTLS13 && t.messageType == typeServerHello {
415			// In TLS 1.3, if the server believes it has sent ServerHello,
416			// but the client cannot process it, the client will send an
417			// unencrypted alert while the server expects encryption. This
418			// decryption failure is reported differently for each protocol, so
419			// leave it unchecked.
420			t.test.expectedLocalError = ""
421		}
422
423		if t.messageType == typeClientHello {
424			// We have a different error for ClientHello parsing.
425			t.test.expectedError = ":CLIENTHELLO_PARSE_FAILED:"
426		}
427
428		if t.messageType == typeFinished {
429			// Bad Finished messages read as the verify data having
430			// the wrong length.
431			t.test.expectedError = ":DIGEST_CHECK_FAILED:"
432			t.test.expectedLocalError = "remote error: error decrypting message"
433		}
434
435		testCases = append(testCases, t.test)
436	}
437}
438