| // Copyright 2025 The BoringSSL Authors | 
 | // | 
 | // Licensed under the Apache License, Version 2.0 (the "License"); | 
 | // you may not use this file except in compliance with the License. | 
 | // You may obtain a copy of the License at | 
 | // | 
 | //	https://www.apache.org/licenses/LICENSE-2.0 | 
 | // | 
 | // Unless required by applicable law or agreed to in writing, software | 
 | // distributed under the License is distributed on an "AS IS" BASIS, | 
 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 | // See the License for the specific language governing permissions and | 
 | // limitations under the License. | 
 |  | 
 | package runner | 
 |  | 
 | func addExtendedMasterSecretTests() { | 
 | 	const expectEMSFlag = "-expect-extended-master-secret" | 
 |  | 
 | 	for _, with := range []bool{false, true} { | 
 | 		prefix := "No" | 
 | 		if with { | 
 | 			prefix = "" | 
 | 		} | 
 |  | 
 | 		for _, isClient := range []bool{false, true} { | 
 | 			suffix := "-Server" | 
 | 			testType := serverTest | 
 | 			if isClient { | 
 | 				suffix = "-Client" | 
 | 				testType = clientTest | 
 | 			} | 
 |  | 
 | 			for _, ver := range tlsVersions { | 
 | 				// In TLS 1.3, the extension is irrelevant and | 
 | 				// always reports as enabled. | 
 | 				var flags []string | 
 | 				if with || ver.version >= VersionTLS13 { | 
 | 					flags = []string{expectEMSFlag} | 
 | 				} | 
 |  | 
 | 				testCases = append(testCases, testCase{ | 
 | 					testType: testType, | 
 | 					name:     prefix + "ExtendedMasterSecret-" + ver.name + suffix, | 
 | 					config: Config{ | 
 | 						MinVersion: ver.version, | 
 | 						MaxVersion: ver.version, | 
 | 						Bugs: ProtocolBugs{ | 
 | 							NoExtendedMasterSecret:      !with, | 
 | 							RequireExtendedMasterSecret: with, | 
 | 						}, | 
 | 					}, | 
 | 					flags: flags, | 
 | 				}) | 
 | 			} | 
 | 		} | 
 | 	} | 
 |  | 
 | 	for _, isClient := range []bool{false, true} { | 
 | 		for _, supportedInFirstConnection := range []bool{false, true} { | 
 | 			for _, supportedInResumeConnection := range []bool{false, true} { | 
 | 				boolToWord := func(b bool) string { | 
 | 					if b { | 
 | 						return "Yes" | 
 | 					} | 
 | 					return "No" | 
 | 				} | 
 | 				suffix := boolToWord(supportedInFirstConnection) + "To" + boolToWord(supportedInResumeConnection) + "-" | 
 | 				if isClient { | 
 | 					suffix += "Client" | 
 | 				} else { | 
 | 					suffix += "Server" | 
 | 				} | 
 |  | 
 | 				supportedConfig := Config{ | 
 | 					MaxVersion: VersionTLS12, | 
 | 					Bugs: ProtocolBugs{ | 
 | 						RequireExtendedMasterSecret: true, | 
 | 					}, | 
 | 				} | 
 |  | 
 | 				noSupportConfig := Config{ | 
 | 					MaxVersion: VersionTLS12, | 
 | 					Bugs: ProtocolBugs{ | 
 | 						NoExtendedMasterSecret: true, | 
 | 					}, | 
 | 				} | 
 |  | 
 | 				test := testCase{ | 
 | 					name:          "ExtendedMasterSecret-" + suffix, | 
 | 					resumeSession: true, | 
 | 				} | 
 |  | 
 | 				if !isClient { | 
 | 					test.testType = serverTest | 
 | 				} | 
 |  | 
 | 				if supportedInFirstConnection { | 
 | 					test.config = supportedConfig | 
 | 				} else { | 
 | 					test.config = noSupportConfig | 
 | 				} | 
 |  | 
 | 				if supportedInResumeConnection { | 
 | 					test.resumeConfig = &supportedConfig | 
 | 				} else { | 
 | 					test.resumeConfig = &noSupportConfig | 
 | 				} | 
 |  | 
 | 				switch suffix { | 
 | 				case "YesToYes-Client", "YesToYes-Server": | 
 | 					// When a session is resumed, it should | 
 | 					// still be aware that its master | 
 | 					// secret was generated via EMS and | 
 | 					// thus it's safe to use tls-unique. | 
 | 					test.flags = []string{expectEMSFlag} | 
 | 				case "NoToYes-Server": | 
 | 					// If an original connection did not | 
 | 					// contain EMS, but a resumption | 
 | 					// handshake does, then a server should | 
 | 					// not resume the session. | 
 | 					test.expectResumeRejected = true | 
 | 				case "YesToNo-Server": | 
 | 					// Resuming an EMS session without the | 
 | 					// EMS extension should cause the | 
 | 					// server to abort the connection. | 
 | 					test.shouldFail = true | 
 | 					test.expectedError = ":RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION:" | 
 | 				case "NoToYes-Client": | 
 | 					// A client should abort a connection | 
 | 					// where the server resumed a non-EMS | 
 | 					// session but echoed the EMS | 
 | 					// extension. | 
 | 					test.shouldFail = true | 
 | 					test.expectedError = ":RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION:" | 
 | 				case "YesToNo-Client": | 
 | 					// A client should abort a connection | 
 | 					// where the server didn't echo EMS | 
 | 					// when the session used it. | 
 | 					test.shouldFail = true | 
 | 					test.expectedError = ":RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION:" | 
 | 				} | 
 |  | 
 | 				testCases = append(testCases, test) | 
 | 			} | 
 | 		} | 
 | 	} | 
 |  | 
 | 	// Switching EMS on renegotiation is forbidden. | 
 | 	testCases = append(testCases, testCase{ | 
 | 		name: "ExtendedMasterSecret-Renego-NoEMS", | 
 | 		config: Config{ | 
 | 			MaxVersion: VersionTLS12, | 
 | 			Bugs: ProtocolBugs{ | 
 | 				NoExtendedMasterSecret:                true, | 
 | 				NoExtendedMasterSecretOnRenegotiation: true, | 
 | 			}, | 
 | 		}, | 
 | 		renegotiate: 1, | 
 | 		flags: []string{ | 
 | 			"-renegotiate-freely", | 
 | 			"-expect-total-renegotiations", "1", | 
 | 		}, | 
 | 	}) | 
 |  | 
 | 	testCases = append(testCases, testCase{ | 
 | 		name: "ExtendedMasterSecret-Renego-Upgrade", | 
 | 		config: Config{ | 
 | 			MaxVersion: VersionTLS12, | 
 | 			Bugs: ProtocolBugs{ | 
 | 				NoExtendedMasterSecret: true, | 
 | 			}, | 
 | 		}, | 
 | 		renegotiate: 1, | 
 | 		flags: []string{ | 
 | 			"-renegotiate-freely", | 
 | 			"-expect-total-renegotiations", "1", | 
 | 		}, | 
 | 		shouldFail:    true, | 
 | 		expectedError: ":RENEGOTIATION_EMS_MISMATCH:", | 
 | 	}) | 
 |  | 
 | 	testCases = append(testCases, testCase{ | 
 | 		name: "ExtendedMasterSecret-Renego-Downgrade", | 
 | 		config: Config{ | 
 | 			MaxVersion: VersionTLS12, | 
 | 			Bugs: ProtocolBugs{ | 
 | 				NoExtendedMasterSecretOnRenegotiation: true, | 
 | 			}, | 
 | 		}, | 
 | 		renegotiate: 1, | 
 | 		flags: []string{ | 
 | 			"-renegotiate-freely", | 
 | 			"-expect-total-renegotiations", "1", | 
 | 		}, | 
 | 		shouldFail:    true, | 
 | 		expectedError: ":RENEGOTIATION_EMS_MISMATCH:", | 
 | 	}) | 
 | } |