Add slightly better RSA key exchange tests.
Cover not just the wrong version, but also other mistakes.
Change-Id: I46f05a9a37b7e325adc19084d315a415777d3a46
Reviewed-on: https://boringssl-review.googlesource.com/6610
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/test/runner/common.go b/ssl/test/runner/common.go
index 143b0e0..2addea6 100644
--- a/ssl/test/runner/common.go
+++ b/ssl/test/runner/common.go
@@ -399,6 +399,17 @@
NumBadValues
)
+type RSABadValue int
+
+const (
+ RSABadValueNone RSABadValue = iota
+ RSABadValueCorrupt
+ RSABadValueTooLong
+ RSABadValueTooShort
+ RSABadValueWrongVersion
+ NumRSABadValues
+)
+
type ProtocolBugs struct {
// InvalidSKXSignature specifies that the signature in a
// ServerKeyExchange message should be invalid.
@@ -509,10 +520,9 @@
// alert to be sent.
SendSpuriousAlert alert
- // RsaClientKeyExchangeVersion, if non-zero, causes the client to send a
- // ClientKeyExchange with the specified version rather than the
- // client_version when performing the RSA key exchange.
- RsaClientKeyExchangeVersion uint16
+ // BadRSAClientKeyExchange causes the client to send a corrupted RSA
+ // ClientKeyExchange which would not pass padding checks.
+ BadRSAClientKeyExchange RSABadValue
// RenewTicketOnResume causes the server to renew the session ticket and
// send a NewSessionTicket message during an abbreviated handshake.
diff --git a/ssl/test/runner/key_agreement.go b/ssl/test/runner/key_agreement.go
index f65ff6e..d1ec91f 100644
--- a/ssl/test/runner/key_agreement.go
+++ b/ssl/test/runner/key_agreement.go
@@ -138,10 +138,11 @@
}
func (ka *rsaKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
+ bad := config.Bugs.BadRSAClientKeyExchange
preMasterSecret := make([]byte, 48)
vers := clientHello.vers
- if config.Bugs.RsaClientKeyExchangeVersion != 0 {
- vers = config.Bugs.RsaClientKeyExchangeVersion
+ if bad == RSABadValueWrongVersion {
+ vers ^= 1
}
vers = versionToWire(vers, clientHello.isDTLS)
preMasterSecret[0] = byte(vers >> 8)
@@ -151,10 +152,21 @@
return nil, nil, err
}
- encrypted, err := rsa.EncryptPKCS1v15(config.rand(), cert.PublicKey.(*rsa.PublicKey), preMasterSecret)
+ sentPreMasterSecret := preMasterSecret
+ if bad == RSABadValueTooLong {
+ sentPreMasterSecret = make([]byte, len(sentPreMasterSecret)+1)
+ copy(sentPreMasterSecret, preMasterSecret)
+ } else if bad == RSABadValueTooShort {
+ sentPreMasterSecret = sentPreMasterSecret[:len(sentPreMasterSecret)-1]
+ }
+
+ encrypted, err := rsa.EncryptPKCS1v15(config.rand(), cert.PublicKey.(*rsa.PublicKey), sentPreMasterSecret)
if err != nil {
return nil, nil, err
}
+ if bad == RSABadValueCorrupt {
+ encrypted[0] ^= 1
+ }
ckx := new(clientKeyExchangeMsg)
if clientHello.vers != VersionSSL30 {
ckx.ciphertext = make([]byte, len(encrypted)+2)
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index ba0eeeb..19a9dac 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -907,18 +907,6 @@
expectedError: ":WRONG_CURVE:",
},
{
- testType: serverTest,
- name: "BadRSAVersion",
- config: Config{
- CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
- Bugs: ProtocolBugs{
- RsaClientKeyExchangeVersion: VersionTLS11,
- },
- },
- shouldFail: true,
- expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
- },
- {
name: "NoFallbackSCSV",
config: Config{
Bugs: ProtocolBugs{
@@ -4523,6 +4511,27 @@
})
}
+func addRSAClientKeyExchangeTests() {
+ for bad := RSABadValue(1); bad < NumRSABadValues; bad++ {
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: fmt.Sprintf("BadRSAClientKeyExchange-%d", bad),
+ config: Config{
+ // Ensure the ClientHello version and final
+ // version are different, to detect if the
+ // server uses the wrong one.
+ MaxVersion: VersionTLS11,
+ CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
+ Bugs: ProtocolBugs{
+ BadRSAClientKeyExchange: bad,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
+ })
+ }
+}
+
func worker(statusChan chan statusMsg, c chan *testCase, shimPath string, wg *sync.WaitGroup) {
defer wg.Done()
@@ -4619,6 +4628,7 @@
addExportKeyingMaterialTests()
addTLSUniqueTests()
addCustomExtensionTests()
+ addRSAClientKeyExchangeTests()
for _, async := range []bool{false, true} {
for _, splitHandshake := range []bool{false, true} {
for _, protocol := range []protocol{tls, dtls} {