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 17import "fmt" 18 19func addExportKeyingMaterialTests() { 20 for _, protocol := range []protocol{tls, dtls, quic} { 21 for _, vers := range allVersions(protocol) { 22 suffix := fmt.Sprintf("%s-%s", protocol, vers) 23 testCases = append(testCases, testCase{ 24 protocol: protocol, 25 name: "ExportKeyingMaterial-" + suffix, 26 config: Config{ 27 MaxVersion: vers.version, 28 }, 29 // Test the exporter in both initial and resumption 30 // handshakes. 31 resumeSession: true, 32 exportKeyingMaterial: 1024, 33 exportLabel: "label", 34 exportContext: "context", 35 useExportContext: true, 36 }) 37 testCases = append(testCases, testCase{ 38 protocol: protocol, 39 name: "ExportKeyingMaterial-NoContext-" + suffix, 40 config: Config{ 41 MaxVersion: vers.version, 42 }, 43 exportKeyingMaterial: 1024, 44 }) 45 testCases = append(testCases, testCase{ 46 protocol: protocol, 47 name: "ExportKeyingMaterial-EmptyContext-" + suffix, 48 config: Config{ 49 MaxVersion: vers.version, 50 }, 51 exportKeyingMaterial: 1024, 52 useExportContext: true, 53 }) 54 testCases = append(testCases, testCase{ 55 protocol: protocol, 56 name: "ExportKeyingMaterial-Small-" + suffix, 57 config: Config{ 58 MaxVersion: vers.version, 59 }, 60 exportKeyingMaterial: 1, 61 exportLabel: "label", 62 exportContext: "context", 63 useExportContext: true, 64 }) 65 66 // TODO(crbug.com/381113363): Support 0-RTT in DTLS 1.3. 67 if vers.version >= VersionTLS13 && protocol != dtls { 68 // Test the exporters do not work while the client is 69 // sending 0-RTT data. 70 testCases = append(testCases, testCase{ 71 protocol: protocol, 72 name: "NoEarlyKeyingMaterial-Client-InEarlyData-" + suffix, 73 config: Config{ 74 MaxVersion: vers.version, 75 }, 76 resumeSession: true, 77 earlyData: true, 78 flags: []string{ 79 "-on-resume-export-keying-material", "1024", 80 "-on-resume-export-label", "label", 81 "-on-resume-export-context", "context", 82 }, 83 shouldFail: true, 84 expectedError: ":HANDSHAKE_NOT_COMPLETE:", 85 }) 86 87 // Test the normal exporter on the server in half-RTT. 88 testCases = append(testCases, testCase{ 89 testType: serverTest, 90 protocol: protocol, 91 name: "ExportKeyingMaterial-Server-HalfRTT-" + suffix, 92 config: Config{ 93 MaxVersion: vers.version, 94 Bugs: ProtocolBugs{ 95 // The shim writes exported data immediately after 96 // the handshake returns, so disable the built-in 97 // early data test. 98 SendEarlyData: [][]byte{}, 99 ExpectHalfRTTData: [][]byte{}, 100 }, 101 }, 102 resumeSession: true, 103 earlyData: true, 104 exportKeyingMaterial: 1024, 105 exportLabel: "label", 106 exportContext: "context", 107 useExportContext: true, 108 }) 109 } 110 } 111 } 112 113 // Exporters work during a False Start. 114 testCases = append(testCases, testCase{ 115 name: "ExportKeyingMaterial-FalseStart", 116 config: Config{ 117 MaxVersion: VersionTLS12, 118 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 119 NextProtos: []string{"foo"}, 120 Bugs: ProtocolBugs{ 121 ExpectFalseStart: true, 122 }, 123 }, 124 flags: []string{ 125 "-false-start", 126 "-advertise-alpn", "\x03foo", 127 "-expect-alpn", "foo", 128 }, 129 shimWritesFirst: true, 130 exportKeyingMaterial: 1024, 131 exportLabel: "label", 132 exportContext: "context", 133 useExportContext: true, 134 }) 135 136 // Exporters do not work in the middle of a renegotiation. Test this by 137 // triggering the exporter after every SSL_read call and configuring the 138 // shim to run asynchronously. 139 testCases = append(testCases, testCase{ 140 name: "ExportKeyingMaterial-Renegotiate", 141 config: Config{ 142 MaxVersion: VersionTLS12, 143 }, 144 renegotiate: 1, 145 flags: []string{ 146 "-async", 147 "-use-exporter-between-reads", 148 "-renegotiate-freely", 149 "-expect-total-renegotiations", "1", 150 }, 151 shouldFail: true, 152 expectedError: "failed to export keying material", 153 }) 154} 155 156func addExportTrafficSecretsTests() { 157 for _, cipherSuite := range []testCipherSuite{ 158 // Test a SHA-256 and SHA-384 based cipher suite. 159 {"AEAD-AES128-GCM-SHA256", TLS_AES_128_GCM_SHA256}, 160 {"AEAD-AES256-GCM-SHA384", TLS_AES_256_GCM_SHA384}, 161 } { 162 testCases = append(testCases, testCase{ 163 name: "ExportTrafficSecrets-" + cipherSuite.name, 164 config: Config{ 165 MinVersion: VersionTLS13, 166 CipherSuites: []uint16{cipherSuite.id}, 167 }, 168 exportTrafficSecrets: true, 169 }) 170 } 171} 172 173func addTLSUniqueTests() { 174 for _, isClient := range []bool{false, true} { 175 for _, isResumption := range []bool{false, true} { 176 for _, hasEMS := range []bool{false, true} { 177 var suffix string 178 if isResumption { 179 suffix = "Resume-" 180 } else { 181 suffix = "Full-" 182 } 183 184 if hasEMS { 185 suffix += "EMS-" 186 } else { 187 suffix += "NoEMS-" 188 } 189 190 if isClient { 191 suffix += "Client" 192 } else { 193 suffix += "Server" 194 } 195 196 test := testCase{ 197 name: "TLSUnique-" + suffix, 198 testTLSUnique: true, 199 config: Config{ 200 MaxVersion: VersionTLS12, 201 Bugs: ProtocolBugs{ 202 NoExtendedMasterSecret: !hasEMS, 203 }, 204 }, 205 } 206 207 if isResumption { 208 test.resumeSession = true 209 test.resumeConfig = &Config{ 210 MaxVersion: VersionTLS12, 211 Bugs: ProtocolBugs{ 212 NoExtendedMasterSecret: !hasEMS, 213 }, 214 } 215 } 216 217 if isResumption && !hasEMS { 218 test.shouldFail = true 219 test.expectedError = "failed to get tls-unique" 220 } 221 222 testCases = append(testCases, test) 223 } 224 } 225 } 226} 227