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 17func addExtendedMasterSecretTests() { 18 const expectEMSFlag = "-expect-extended-master-secret" 19 20 for _, with := range []bool{false, true} { 21 prefix := "No" 22 if with { 23 prefix = "" 24 } 25 26 for _, isClient := range []bool{false, true} { 27 suffix := "-Server" 28 testType := serverTest 29 if isClient { 30 suffix = "-Client" 31 testType = clientTest 32 } 33 34 for _, ver := range tlsVersions { 35 // In TLS 1.3, the extension is irrelevant and 36 // always reports as enabled. 37 var flags []string 38 if with || ver.version >= VersionTLS13 { 39 flags = []string{expectEMSFlag} 40 } 41 42 testCases = append(testCases, testCase{ 43 testType: testType, 44 name: prefix + "ExtendedMasterSecret-" + ver.name + suffix, 45 config: Config{ 46 MinVersion: ver.version, 47 MaxVersion: ver.version, 48 Bugs: ProtocolBugs{ 49 NoExtendedMasterSecret: !with, 50 RequireExtendedMasterSecret: with, 51 }, 52 }, 53 flags: flags, 54 }) 55 } 56 } 57 } 58 59 for _, isClient := range []bool{false, true} { 60 for _, supportedInFirstConnection := range []bool{false, true} { 61 for _, supportedInResumeConnection := range []bool{false, true} { 62 boolToWord := func(b bool) string { 63 if b { 64 return "Yes" 65 } 66 return "No" 67 } 68 suffix := boolToWord(supportedInFirstConnection) + "To" + boolToWord(supportedInResumeConnection) + "-" 69 if isClient { 70 suffix += "Client" 71 } else { 72 suffix += "Server" 73 } 74 75 supportedConfig := Config{ 76 MaxVersion: VersionTLS12, 77 Bugs: ProtocolBugs{ 78 RequireExtendedMasterSecret: true, 79 }, 80 } 81 82 noSupportConfig := Config{ 83 MaxVersion: VersionTLS12, 84 Bugs: ProtocolBugs{ 85 NoExtendedMasterSecret: true, 86 }, 87 } 88 89 test := testCase{ 90 name: "ExtendedMasterSecret-" + suffix, 91 resumeSession: true, 92 } 93 94 if !isClient { 95 test.testType = serverTest 96 } 97 98 if supportedInFirstConnection { 99 test.config = supportedConfig 100 } else { 101 test.config = noSupportConfig 102 } 103 104 if supportedInResumeConnection { 105 test.resumeConfig = &supportedConfig 106 } else { 107 test.resumeConfig = &noSupportConfig 108 } 109 110 switch suffix { 111 case "YesToYes-Client", "YesToYes-Server": 112 // When a session is resumed, it should 113 // still be aware that its master 114 // secret was generated via EMS and 115 // thus it's safe to use tls-unique. 116 test.flags = []string{expectEMSFlag} 117 case "NoToYes-Server": 118 // If an original connection did not 119 // contain EMS, but a resumption 120 // handshake does, then a server should 121 // not resume the session. 122 test.expectResumeRejected = true 123 case "YesToNo-Server": 124 // Resuming an EMS session without the 125 // EMS extension should cause the 126 // server to abort the connection. 127 test.shouldFail = true 128 test.expectedError = ":RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION:" 129 case "NoToYes-Client": 130 // A client should abort a connection 131 // where the server resumed a non-EMS 132 // session but echoed the EMS 133 // extension. 134 test.shouldFail = true 135 test.expectedError = ":RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION:" 136 case "YesToNo-Client": 137 // A client should abort a connection 138 // where the server didn't echo EMS 139 // when the session used it. 140 test.shouldFail = true 141 test.expectedError = ":RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION:" 142 } 143 144 testCases = append(testCases, test) 145 } 146 } 147 } 148 149 // Switching EMS on renegotiation is forbidden. 150 testCases = append(testCases, testCase{ 151 name: "ExtendedMasterSecret-Renego-NoEMS", 152 config: Config{ 153 MaxVersion: VersionTLS12, 154 Bugs: ProtocolBugs{ 155 NoExtendedMasterSecret: true, 156 NoExtendedMasterSecretOnRenegotiation: true, 157 }, 158 }, 159 renegotiate: 1, 160 flags: []string{ 161 "-renegotiate-freely", 162 "-expect-total-renegotiations", "1", 163 }, 164 }) 165 166 testCases = append(testCases, testCase{ 167 name: "ExtendedMasterSecret-Renego-Upgrade", 168 config: Config{ 169 MaxVersion: VersionTLS12, 170 Bugs: ProtocolBugs{ 171 NoExtendedMasterSecret: true, 172 }, 173 }, 174 renegotiate: 1, 175 flags: []string{ 176 "-renegotiate-freely", 177 "-expect-total-renegotiations", "1", 178 }, 179 shouldFail: true, 180 expectedError: ":RENEGOTIATION_EMS_MISMATCH:", 181 }) 182 183 testCases = append(testCases, testCase{ 184 name: "ExtendedMasterSecret-Renego-Downgrade", 185 config: Config{ 186 MaxVersion: VersionTLS12, 187 Bugs: ProtocolBugs{ 188 NoExtendedMasterSecretOnRenegotiation: true, 189 }, 190 }, 191 renegotiate: 1, 192 flags: []string{ 193 "-renegotiate-freely", 194 "-expect-total-renegotiations", "1", 195 }, 196 shouldFail: true, 197 expectedError: ":RENEGOTIATION_EMS_MISMATCH:", 198 }) 199} 200