Actually check that the message has the expected type in DTLS.
That might be a reasonable check to make, maybe.
DTLS handshake message reading has a ton of other bugs and needs a complete
rewrite. But let's fix this and get a test in now.
Change-Id: I4981fc302feb9125908bb6161ed1a18288c39e2b
Reviewed-on: https://boringssl-review.googlesource.com/3600
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/d1_both.c b/ssl/d1_both.c
index 1390863..16c3e08 100644
--- a/ssl/d1_both.c
+++ b/ssl/d1_both.c
@@ -359,10 +359,10 @@
}
-/* Obtain handshake message of message type 'mt' (any if mt == -1), maximum
- * acceptable body length 'max'. Read an entire handshake message. Handshake
- * messages arrive in fragments. */
-long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max,
+/* dtls1_get_message reads a handshake message of message type |msg_type| (any
+ * if |msg_type| == -1), maximum acceptable body length |max|. Read an entire
+ * handshake message. Handshake messages arrive in fragments. */
+long dtls1_get_message(SSL *s, int st1, int stn, int msg_type, long max,
int hash_message, int *ok) {
int i, al;
struct hm_header_st *msg_hdr;
@@ -377,7 +377,7 @@
* would have to have been applied to the previous call. */
assert(hash_message != SSL_GET_MESSAGE_DONT_HASH_MESSAGE);
s->s3->tmp.reuse_message = 0;
- if (mt >= 0 && s->s3->tmp.message_type != mt) {
+ if (msg_type >= 0 && s->s3->tmp.message_type != msg_type) {
al = SSL_AD_UNEXPECTED_MESSAGE;
OPENSSL_PUT_ERROR(SSL, dtls1_get_message, SSL_R_UNEXPECTED_MESSAGE);
goto f_err;
@@ -401,6 +401,12 @@
return i;
}
+ if (msg_type >= 0 && msg_hdr->type != msg_type) {
+ al = SSL_AD_UNEXPECTED_MESSAGE;
+ OPENSSL_PUT_ERROR(SSL, dtls1_get_message, SSL_R_UNEXPECTED_MESSAGE);
+ goto f_err;
+ }
+
p = (uint8_t *)s->init_buf->data;
msg_len = msg_hdr->msg_len;
diff --git a/ssl/test/runner/common.go b/ssl/test/runner/common.go
index e8df1aa..b505c8f 100644
--- a/ssl/test/runner/common.go
+++ b/ssl/test/runner/common.go
@@ -625,6 +625,10 @@
// SendInvalidRecordType, if true, causes a record with an invalid
// content type to be sent immediately following the handshake.
SendInvalidRecordType bool
+
+ // WrongCertificateMessageType, if true, causes Certificate message to
+ // be sent with the wrong message type.
+ WrongCertificateMessageType bool
}
func (c *Config) serverInit() {
diff --git a/ssl/test/runner/handshake_server.go b/ssl/test/runner/handshake_server.go
index 9c920d6..50cc20b 100644
--- a/ssl/test/runner/handshake_server.go
+++ b/ssl/test/runner/handshake_server.go
@@ -490,8 +490,12 @@
certMsg := new(certificateMsg)
certMsg.certificates = hs.cert.Certificate
if !config.Bugs.UnauthenticatedECDH {
- hs.writeServerHash(certMsg.marshal())
- c.writeRecord(recordTypeHandshake, certMsg.marshal())
+ certMsgBytes := certMsg.marshal()
+ if config.Bugs.WrongCertificateMessageType {
+ certMsgBytes[0] += 42
+ }
+ hs.writeServerHash(certMsgBytes)
+ c.writeRecord(recordTypeHandshake, certMsgBytes)
}
}
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index 4079863..6857358 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -788,6 +788,29 @@
expectedError: ":CONNECTION_REJECTED:",
expectedLocalError: "remote error: access denied",
},
+ {
+ name: "WrongMessageType",
+ config: Config{
+ Bugs: ProtocolBugs{
+ WrongCertificateMessageType: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_MESSAGE:",
+ expectedLocalError: "remote error: unexpected message",
+ },
+ {
+ protocol: dtls,
+ name: "WrongMessageType-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ WrongCertificateMessageType: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_MESSAGE:",
+ expectedLocalError: "remote error: unexpected message",
+ },
}
func doExchange(test *testCase, config *Config, conn net.Conn, messageLen int, isResume bool) error {