Fix the tests following the state machine changes for TLSv1.3
authorMatt Caswell <matt@openssl.org>
Fri, 11 Nov 2016 16:22:19 +0000 (16:22 +0000)
committerMatt Caswell <matt@openssl.org>
Wed, 23 Nov 2016 15:31:21 +0000 (15:31 +0000)
Reviewed-by: Rich Salz <rsalz@openssl.org>
test/asynciotest.c
test/recipes/70-test_sslrecords.t
test/ssltestlib.c
util/TLSProxy/Message.pm
util/TLSProxy/Record.pm
util/TLSProxy/ServerHello.pm

index a4f43f8..d7b1dd3 100644 (file)
@@ -142,8 +142,9 @@ static int async_write(BIO *bio, const char *in, int inl)
                 abort();
 
             while (PACKET_remaining(&pkt) > 0) {
-                PACKET payload;
+                PACKET payload, wholebody;
                 unsigned int contenttype, versionhi, versionlo, data;
+                unsigned int msgtype = 0, negversion;
 
                 if (   !PACKET_get_1(&pkt, &contenttype)
                     || !PACKET_get_1(&pkt, &versionhi)
@@ -154,6 +155,17 @@ static int async_write(BIO *bio, const char *in, int inl)
                 /* Pretend we wrote out the record header */
                 written += SSL3_RT_HEADER_LENGTH;
 
+                wholebody = payload;
+                if (contenttype == SSL3_RT_HANDSHAKE
+                        && !PACKET_get_1(&wholebody, &msgtype))
+                    abort();
+
+                if (msgtype == SSL3_MT_SERVER_HELLO
+                        && (!PACKET_forward(&wholebody,
+                                            SSL3_HM_HEADER_LENGTH - 1)
+                            || !PACKET_get_net_2(&wholebody, &negversion)))
+                    abort();
+
                 while (PACKET_get_1(&payload, &data)) {
                     /* Create a new one byte long record for each byte in the
                      * record in the input buffer
@@ -177,10 +189,14 @@ static int async_write(BIO *bio, const char *in, int inl)
                     written++;
                 }
                 /*
-                 * We can't fragment anything after the CCS, otherwise we
-                 * get a bad record MAC
+                 * We can't fragment anything after the ServerHello (or CCS <=
+                 * TLS1.2), otherwise we get a bad record MAC
+                 * TODO(TLS1.3): Change TLS1_3_VERSION_DRAFT to TLS1_3_VERSION
+                 * before release
                  */
-                if (contenttype == SSL3_RT_CHANGE_CIPHER_SPEC) {
+                if (contenttype == SSL3_RT_CHANGE_CIPHER_SPEC
+                        || (negversion == TLS1_3_VERSION_DRAFT
+                            && msgtype == SSL3_MT_SERVER_HELLO)) {
                     fragment = 0;
                     break;
                 }
index cafa30c..e6f7a36 100644 (file)
@@ -128,6 +128,7 @@ ok(TLSProxy::Message->fail(), "Alert before SSLv2 ClientHello test");
 
 #Test 10: Sending an unrecognised record type in TLS1.2 should fail
 $proxy->clear();
+$proxy->serverflags("-tls1_2");
 $proxy->filter(\&add_unknown_record_type);
 $proxy->start();
 ok(TLSProxy::Message->fail(), "Unrecognised record type in TLS1.2");
index 4e20763..42ba98c 100644 (file)
@@ -564,7 +564,7 @@ int create_ssl_ctx_pair(const SSL_METHOD *sm, const SSL_METHOD *cm,
     return 0;
 }
 
-#define MAXLOOPS    100000
+#define MAXLOOPS    1000000
 
 /*
  * NOTE: Transfers control of the BIOs - this function will free them on error
index 6bf5a72..3259edc 100644 (file)
@@ -115,9 +115,9 @@ sub get_messages
             die "CCS received before message data complete\n";
         }
         if ($server) {
-            TLSProxy::Record->server_ccs_seen(1);
+            TLSProxy::Record->server_encrypting(1);
         } else {
-            TLSProxy::Record->client_ccs_seen(1);
+            TLSProxy::Record->client_encrypting(1);
         }
     } elsif ($record->content_type == TLSProxy::Record::RT_HANDSHAKE) {
         if ($record->len == 0 || $record->len_real == 0) {
index bf6de43..6d35f08 100644 (file)
@@ -11,8 +11,8 @@ use TLSProxy::Proxy;
 
 package TLSProxy::Record;
 
-my $server_ccs_seen = 0;
-my $client_ccs_seen = 0;
+my $server_encrypting = 0;
+my $client_encrypting = 0;
 my $etm = 0;
 
 use constant TLS_RECORD_HEADER_LENGTH => 5;
@@ -36,6 +36,7 @@ my %record_type = (
 
 use constant {
     VERS_TLS_1_4 => 773,
+    VERS_TLS_1_3_DRAFT => 32530,
     VERS_TLS_1_3 => 772,
     VERS_TLS_1_2 => 771,
     VERS_TLS_1_1 => 770,
@@ -108,8 +109,8 @@ sub get_records
                 substr($packet, TLS_RECORD_HEADER_LENGTH, $len_real)
             );
 
-            if (($server && $server_ccs_seen)
-                     || (!$server && $client_ccs_seen)) {
+            if (($server && $server_encrypting)
+                     || (!$server && $client_encrypting)) {
                 if ($version != VERS_TLS_1_3() && $etm) {
                     $record->decryptETM();
                 } else {
@@ -133,26 +134,26 @@ sub get_records
 
 sub clear
 {
-    $server_ccs_seen = 0;
-    $client_ccs_seen = 0;
+    $server_encrypting = 0;
+    $client_encrypting = 0;
 }
 
 #Class level accessors
-sub server_ccs_seen
+sub server_encrypting
 {
     my $class = shift;
     if (@_) {
-      $server_ccs_seen = shift;
+      $server_encrypting = shift;
     }
-    return $server_ccs_seen;
+    return $server_encrypting;
 }
-sub client_ccs_seen
+sub client_encrypting
 {
     my $class = shift;
     if (@_) {
-      $client_ccs_seen = shift;
+      $client_encrypting= shift;
     }
-    return $client_ccs_seen;
+    return $client_encrypting;
 }
 #Enable/Disable Encrypt-then-MAC
 sub etm
index 79a8be9..9d6ad38 100644 (file)
@@ -94,6 +94,12 @@ sub parse
 
     $self->process_data();
 
+    # TODO(TLS1.3): Replace this reference to draft version before release
+    if ($server_version == TLSProxy::Record::VERS_TLS_1_3_DRAFT) {
+        TLSProxy::Record->server_encrypting(1);
+        TLSProxy::Record->client_encrypting(1);
+    }
+
     print "    Server Version:".$server_version."\n";
     print "    Session ID Len:".$session_id_len."\n";
     print "    Ciphersuite:".$ciphersuite."\n";