Add tests for version negotiation failure alerts.

Ensure that both the client and the server emit a protocol_version alert
(except in SSLv3 where it doesn't exist) with a record-layer version which the
peer will recognize.

Change-Id: I31650a64fe9b027ff3d51e303711910a00b43d6f
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index 7de5159..81a502d 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -777,6 +777,9 @@
 			{
 			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_UNSUPPORTED_PROTOCOL);
 			s->version = server_version;
+			/* Mark the version as fixed so the record-layer version
+			 * is not clamped to TLS 1.0. */
+			s->s3->have_version = 1;
 			al = SSL_AD_PROTOCOL_VERSION;
 			goto f_err;
 			}
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index 3cfc92d..8d6dabc 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -1722,18 +1722,20 @@
 				}
 				shimVersFlag := strconv.Itoa(int(versionToWire(shimVers.version, protocol == dtls)))
 
-				// TODO(davidben): This should also assert on
-				// expectedLocalError to check we send an alert
-				// rather than close the connection, but the TLS
-				// code currently fails this.
 				var expectedVersion uint16
 				var shouldFail bool
 				var expectedError string
+				var expectedLocalError string
 				if runnerVers.version >= shimVers.version {
 					expectedVersion = runnerVers.version
 				} else {
 					shouldFail = true
 					expectedError = ":UNSUPPORTED_PROTOCOL:"
+					if runnerVers.version > VersionSSL30 {
+						expectedLocalError = "remote error: protocol version not supported"
+					} else {
+						expectedLocalError = "remote error: handshake failure"
+					}
 				}
 
 				testCases = append(testCases, testCase{
@@ -1743,10 +1745,11 @@
 					config: Config{
 						MaxVersion: runnerVers.version,
 					},
-					flags:           flags,
-					expectedVersion: expectedVersion,
-					shouldFail:      shouldFail,
-					expectedError:   expectedError,
+					flags:              flags,
+					expectedVersion:    expectedVersion,
+					shouldFail:         shouldFail,
+					expectedError:      expectedError,
+					expectedLocalError: expectedLocalError,
 				})
 				testCases = append(testCases, testCase{
 					protocol: protocol,
@@ -1755,10 +1758,11 @@
 					config: Config{
 						MaxVersion: runnerVers.version,
 					},
-					flags:           []string{"-min-version", shimVersFlag},
-					expectedVersion: expectedVersion,
-					shouldFail:      shouldFail,
-					expectedError:   expectedError,
+					flags:              []string{"-min-version", shimVersFlag},
+					expectedVersion:    expectedVersion,
+					shouldFail:         shouldFail,
+					expectedError:      expectedError,
+					expectedLocalError: expectedLocalError,
 				})
 
 				testCases = append(testCases, testCase{
@@ -1768,10 +1772,11 @@
 					config: Config{
 						MaxVersion: runnerVers.version,
 					},
-					flags:           flags,
-					expectedVersion: expectedVersion,
-					shouldFail:      shouldFail,
-					expectedError:   expectedError,
+					flags:              flags,
+					expectedVersion:    expectedVersion,
+					shouldFail:         shouldFail,
+					expectedError:      expectedError,
+					expectedLocalError: expectedLocalError,
 				})
 				testCases = append(testCases, testCase{
 					protocol: protocol,
@@ -1780,10 +1785,11 @@
 					config: Config{
 						MaxVersion: runnerVers.version,
 					},
-					flags:           []string{"-min-version", shimVersFlag},
-					expectedVersion: expectedVersion,
-					shouldFail:      shouldFail,
-					expectedError:   expectedError,
+					flags:              []string{"-min-version", shimVersFlag},
+					expectedVersion:    expectedVersion,
+					shouldFail:         shouldFail,
+					expectedError:      expectedError,
+					expectedLocalError: expectedLocalError,
 				})
 			}
 		}