Add a test for correct handling of the cryptopro bug extension
authorMatt Caswell <matt@openssl.org>
Fri, 4 Jan 2019 16:55:15 +0000 (16:55 +0000)
committerMatt Caswell <matt@openssl.org>
Mon, 7 Jan 2019 09:39:10 +0000 (09:39 +0000)
This was complicated by the fact that we were using this extension for our
duplicate extension handling tests. In order to add tests for cryptopro
bug the duplicate extension handling tests needed to change first.

Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/7984)

test/recipes/70-test_sslextension.t
util/perl/TLSProxy/Certificate.pm
util/perl/TLSProxy/ClientHello.pm
util/perl/TLSProxy/EncryptedExtensions.pm
util/perl/TLSProxy/Message.pm
util/perl/TLSProxy/ServerHello.pm

index 79466b6109af4ff8d110783cbb9d9a89ddf99253..e725b44f9c62f6459fc8b4089794698dfec5d9e9 100644 (file)
@@ -88,9 +88,11 @@ sub inject_duplicate_extension
     foreach my $message (@{$proxy->message_list}) {
         if ($message->mt == $message_type) {
           my %extensions = %{$message->extension_data};
-            # Add a duplicate (unknown) extension.
-            $message->set_extension(TLSProxy::Message::EXT_DUPLICATE_EXTENSION, "");
-            $message->set_extension(TLSProxy::Message::EXT_DUPLICATE_EXTENSION, "");
+            # Add a duplicate extension. We use cryptopro_bug since we never
+            # normally write that one, and it is allowed as unsolicited in the
+            # ServerHello
+            $message->set_extension(TLSProxy::Message::EXT_CRYPTOPRO_BUG_EXTENSION, "");
+            $message->dupext(TLSProxy::Message::EXT_CRYPTOPRO_BUG_EXTENSION);
             $message->repack();
         }
     }
@@ -173,9 +175,23 @@ sub inject_unsolicited_extension
     $sent_unsolisited_extension = 1;
 }
 
+sub inject_cryptopro_extension
+{
+    my $proxy = shift;
+
+    # We're only interested in the initial ClientHello
+    if ($proxy->flight != 0) {
+        return;
+    }
+
+    my $message = ${$proxy->message_list}[0];
+    $message->set_extension(TLSProxy::Message::EXT_CRYPTOPRO_BUG_EXTENSION, "");
+    $message->repack();
+}
+
 # Test 1-2: Sending a duplicate extension should fail.
 $proxy->start() or plan skip_all => "Unable to start up Proxy for tests";
-plan tests => 7;
+plan tests => 8;
 ok($fatal_alert, "Duplicate ClientHello extension");
 
 $fatal_alert = 0;
@@ -234,3 +250,11 @@ SKIP: {
     $proxy->start();
     ok($fatal_alert, "Unsolicited server name extension (TLSv1.3)");
 }
+
+#Test 8: Send the cryptopro extension in a ClientHello. Normally this is an
+#        unsolicited extension only ever seen in the ServerHello. We should
+#        ignore it in a ClientHello
+$proxy->clear();
+$proxy->filter(\&inject_cryptopro_extension);
+$proxy->start();
+ok(TLSProxy::Message->success(), "Cryptopro extension in ClientHello");
index 70c9faea720e1b1e034d9448bed50a998a7ca0bb..03f661995482ed0a004bacfb1d9939a26b81ac1a 100644 (file)
@@ -138,11 +138,6 @@ sub set_message_contents
             $extensions .= pack("n", $key);
             $extensions .= pack("n", length($extdata));
             $extensions .= $extdata;
-            if ($key == TLSProxy::Message::EXT_DUPLICATE_EXTENSION) {
-              $extensions .= pack("n", $key);
-              $extensions .= pack("n", length($extdata));
-              $extensions .= $extdata;
-            }
         }
         $data = pack('C', length($self->context()));
         $data .= $self->context;
index 7ae3dba9018d3fa976adc342e9c49661d0e1b04d..c49bc23671ffd00fe972f12d433556ee7d86f263 100644 (file)
@@ -124,11 +124,6 @@ sub extension_contents
     $extension .= pack("n", $key);
     $extension .= pack("n", length($extdata));
     $extension .= $extdata;
-    if ($key == TLSProxy::Message::EXT_DUPLICATE_EXTENSION) {
-        $extension .= pack("n", $key);
-        $extension .= pack("n", length($extdata));
-        $extension .= $extdata;
-    }
     return $extension;
 }
 
@@ -151,6 +146,8 @@ sub set_message_contents
     foreach my $key (keys %{$self->extension_data}) {
         next if ($key == TLSProxy::Message::EXT_PSK);
         $extensions .= $self->extension_contents($key);
+        #Add extension twice if we are duplicating that extension
+        $extensions .= $self->extension_contents($key) if ($key == $self->dupext);
     }
     #PSK extension always goes last...
     if (defined ${$self->extension_data}{TLSProxy::Message::EXT_PSK}) {
index f56f3c427092b1b58f2729ff856697b5f1425bc0..4fd445b41e08cc5e00b03be20df5403fa13bd015 100644 (file)
@@ -81,11 +81,6 @@ sub set_message_contents
         $extensions .= pack("n", $key);
         $extensions .= pack("n", length($extdata));
         $extensions .= $extdata;
-        if ($key == TLSProxy::Message::EXT_DUPLICATE_EXTENSION) {
-            $extensions .= pack("n", $key);
-            $extensions .= pack("n", length($extdata));
-            $extensions .= $extdata;
-        }
     }
 
     $data = pack('n', length($extensions));
index 642afb58cbe3a4d7681fe31cca5b9acb1195a37b..71803698c23d1de0e61edc93e30c699e86bb9761 100644 (file)
@@ -86,10 +86,7 @@ use constant {
     EXT_SIG_ALGS_CERT => 50,
     EXT_RENEGOTIATE => 65281,
     EXT_NPN => 13172,
-    # This extension is an unofficial extension only ever written by OpenSSL
-    # (i.e. not read), and even then only when enabled. We use it to test
-    # handling of duplicate extensions.
-    EXT_DUPLICATE_EXTENSION => 0xfde8,
+    EXT_CRYPTOPRO_BUG_EXTENSION => 0xfde8,
     EXT_UNKNOWN => 0xfffe,
     #Unknown extension that should appear last
     EXT_FORCE_LAST => 0xffff
@@ -420,7 +417,8 @@ sub new
         records => $records,
         mt => $mt,
         startoffset => $startoffset,
-        message_frag_lens => $message_frag_lens
+        message_frag_lens => $message_frag_lens,
+        dupext => -1
     };
 
     return bless $self, $class;
@@ -575,6 +573,14 @@ sub encoded_length
     my $self = shift;
     return TLS_MESSAGE_HEADER_LENGTH + length($self->data);
 }
+sub dupext
+{
+    my $self = shift;
+    if (@_) {
+        $self->{dupext} = shift;
+    }
+    return $self->{dupext};
+}
 sub successondata
 {
     my $class = shift;
index 94e7ab5f39743e58389a538a292aa8cd1c9e526c..14eb813d5e6db528f3472c49dbda4c60cd49435c 100644 (file)
@@ -154,7 +154,7 @@ sub set_message_contents
         $extensions .= pack("n", $key);
         $extensions .= pack("n", length($extdata));
         $extensions .= $extdata;
-        if ($key == TLSProxy::Message::EXT_DUPLICATE_EXTENSION) {
+        if ($key == $self->dupext) {
           $extensions .= pack("n", $key);
           $extensions .= pack("n", length($extdata));
           $extensions .= $extdata;