[openssl-commits] [openssl] master update

Matt Caswell matt at openssl.org
Sat Mar 4 23:39:19 UTC 2017


The branch master has been updated
       via  ee7002266cbdcfcfe002c94396795c9fb3d5a337 (commit)
       via  cfef5027bf27a74098588e48829f0d058b4b0aea (commit)
      from  6356716ac09d94a0c85fd6e5ad12f088c54d75c0 (commit)


- Log -----------------------------------------------------------------
commit ee7002266cbdcfcfe002c94396795c9fb3d5a337
Author: Matt Caswell <matt at openssl.org>
Date:   Fri Mar 3 10:28:02 2017 +0000

    Add a test for TLSv1.3 cookies
    
    We just check that if we insert a cookie into an HRR it gets echoed back
    in the subsequent ClientHello.
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2839)

commit cfef5027bf27a74098588e48829f0d058b4b0aea
Author: Matt Caswell <matt at openssl.org>
Date:   Thu Mar 2 17:37:03 2017 +0000

    Add basic TLSv1.3 cookie support
    
    We do not allow the generation of TLSv1.3 cookies. But if we receive one
    in an HRR we will echo it back in the ClientHello.
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2839)

-----------------------------------------------------------------------

Summary of changes:
 include/openssl/ssl.h              |  2 +
 include/openssl/tls1.h             |  1 +
 ssl/ssl_err.c                      |  2 +
 ssl/ssl_lib.c                      |  1 +
 ssl/ssl_locl.h                     |  5 +++
 ssl/statem/extensions.c            |  7 ++++
 ssl/statem/extensions_clnt.c       | 43 ++++++++++++++++++++
 ssl/statem/statem_locl.h           |  4 ++
 test/recipes/70-test_tls13cookie.t | 81 ++++++++++++++++++++++++++++++++++++++
 util/TLSProxy/Message.pm           |  1 +
 10 files changed, 147 insertions(+)
 create mode 100644 test/recipes/70-test_tls13cookie.t

diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index 64a312c..c569407 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -2348,6 +2348,7 @@ int ERR_load_SSL_strings(void);
 # define SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY                489
 # define SSL_F_TLS_CONSTRUCT_CTOS_ALPN                    466
 # define SSL_F_TLS_CONSTRUCT_CTOS_CERTIFICATE             355
+# define SSL_F_TLS_CONSTRUCT_CTOS_COOKIE                  535
 # define SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA              530
 # define SSL_F_TLS_CONSTRUCT_CTOS_EC_PT_FORMATS           467
 # define SSL_F_TLS_CONSTRUCT_CTOS_EMS                     468
@@ -2408,6 +2409,7 @@ int ERR_load_SSL_strings(void);
 # define SSL_F_TLS_PARSE_CTOS_PSK                         505
 # define SSL_F_TLS_PARSE_CTOS_RENEGOTIATE                 464
 # define SSL_F_TLS_PARSE_CTOS_USE_SRTP                    465
+# define SSL_F_TLS_PARSE_STOC_COOKIE                      534
 # define SSL_F_TLS_PARSE_STOC_EARLY_DATA_INFO             528
 # define SSL_F_TLS_PARSE_STOC_KEY_SHARE                   445
 # define SSL_F_TLS_PARSE_STOC_PSK                         502
diff --git a/include/openssl/tls1.h b/include/openssl/tls1.h
index 1054487..280d131 100644
--- a/include/openssl/tls1.h
+++ b/include/openssl/tls1.h
@@ -181,6 +181,7 @@ extern "C" {
 # define TLSEXT_TYPE_psk                         41
 # define TLSEXT_TYPE_early_data                  42
 # define TLSEXT_TYPE_supported_versions          43
+# define TLSEXT_TYPE_cookie                      44
 # define TLSEXT_TYPE_psk_kex_modes               45
 # define TLSEXT_TYPE_early_data_info             46
 
diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c
index 0ace985..ee1ca62 100644
--- a/ssl/ssl_err.c
+++ b/ssl/ssl_err.c
@@ -304,6 +304,7 @@ static ERR_STRING_DATA SSL_str_functs[] = {
     {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CTOS_ALPN), "tls_construct_ctos_alpn"},
     {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CTOS_CERTIFICATE),
      "TLS_CONSTRUCT_CTOS_CERTIFICATE"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CTOS_COOKIE), "tls_construct_ctos_cookie"},
     {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA),
      "tls_construct_ctos_early_data"},
     {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CTOS_EC_PT_FORMATS),
@@ -401,6 +402,7 @@ static ERR_STRING_DATA SSL_str_functs[] = {
     {ERR_FUNC(SSL_F_TLS_PARSE_CTOS_RENEGOTIATE),
      "tls_parse_ctos_renegotiate"},
     {ERR_FUNC(SSL_F_TLS_PARSE_CTOS_USE_SRTP), "tls_parse_ctos_use_srtp"},
+    {ERR_FUNC(SSL_F_TLS_PARSE_STOC_COOKIE), "tls_parse_stoc_cookie"},
     {ERR_FUNC(SSL_F_TLS_PARSE_STOC_EARLY_DATA_INFO),
      "tls_parse_stoc_early_data_info"},
     {ERR_FUNC(SSL_F_TLS_PARSE_STOC_KEY_SHARE), "tls_parse_stoc_key_share"},
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index fcf4f4d..f0e8639 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -1017,6 +1017,7 @@ void SSL_free(SSL *s)
 #endif
     OPENSSL_free(s->ext.ocsp.resp);
     OPENSSL_free(s->ext.alpn);
+    OPENSSL_free(s->ext.tls13_cookie);
     OPENSSL_free(s->clienthello);
 
     sk_X509_NAME_pop_free(s->client_CA, X509_NAME_free);
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index 6811b4f..f4860ea 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -1211,6 +1211,10 @@ struct ssl_st {
         int early_data;
         /* Is the session suitable for early data? */
         int early_data_ok;
+
+        /* May be sent by a server in HRR. Must be echoed back in ClientHello */
+        unsigned char *tls13_cookie;
+        size_t tls13_cookie_len;
     } ext;
 
     /* Parsed form of the ClientHello, kept around across early_cb calls. */
@@ -1801,6 +1805,7 @@ typedef enum tlsext_index_en {
     TLSEXT_IDX_supported_versions,
     TLSEXT_IDX_psk_kex_modes,
     TLSEXT_IDX_key_share,
+    TLSEXT_IDX_cookie,
     TLSEXT_IDX_cryptopro_bug,
     TLSEXT_IDX_early_data,
     TLSEXT_IDX_padding,
diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c
index edcfe71..8c4013e 100644
--- a/ssl/statem/extensions.c
+++ b/ssl/statem/extensions.c
@@ -270,6 +270,13 @@ static const EXTENSION_DEFINITION ext_defs[] = {
     },
 #endif
     {
+        TLSEXT_TYPE_cookie,
+        EXT_CLIENT_HELLO | EXT_TLS1_3_HELLO_RETRY_REQUEST
+        | EXT_TLS_IMPLEMENTATION_ONLY | EXT_TLS1_3_ONLY,
+        NULL, NULL, tls_parse_stoc_cookie, NULL, tls_construct_ctos_cookie,
+        NULL
+    },
+    {
         /*
          * Special unsolicited ServerHello extension only used when
          * SSL_OP_CRYPTOPRO_TLSEXT_BUG is set
diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c
index 0af4d1b..23dc8d3 100644
--- a/ssl/statem/extensions_clnt.c
+++ b/ssl/statem/extensions_clnt.c
@@ -636,6 +636,33 @@ int tls_construct_ctos_key_share(SSL *s, WPACKET *pkt, unsigned int context,
     return 1;
 }
 
+int tls_construct_ctos_cookie(SSL *s, WPACKET *pkt, unsigned int context,
+                              X509 *x, size_t chainidx, int *al)
+{
+    int ret = 0;
+
+    /* Should only be set if we've had an HRR */
+    if (s->ext.tls13_cookie_len == 0)
+        return 1;
+
+    if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_cookie)
+               /* Extension data sub-packet */
+            || !WPACKET_start_sub_packet_u16(pkt)
+            || !WPACKET_sub_memcpy_u16(pkt, s->ext.tls13_cookie,
+                                       s->ext.tls13_cookie_len)
+            || !WPACKET_close(pkt)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_COOKIE, ERR_R_INTERNAL_ERROR);
+        goto end;
+    }
+
+    ret = 1;
+ end:
+    OPENSSL_free(s->ext.tls13_cookie);
+    s->ext.tls13_cookie_len = 0;
+
+    return ret;
+}
+
 int tls_construct_ctos_early_data(SSL *s, WPACKET *pkt, unsigned int context,
                                   X509 *x, size_t chainidx, int *al)
 {
@@ -1338,6 +1365,22 @@ int tls_parse_stoc_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
     return 1;
 }
 
+int tls_parse_stoc_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
+                       size_t chainidx, int *al)
+{
+    PACKET cookie;
+
+    if (!PACKET_as_length_prefixed_2(pkt, &cookie)
+            || !PACKET_memdup(&cookie, &s->ext.tls13_cookie,
+                              &s->ext.tls13_cookie_len)) {
+        *al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_TLS_PARSE_STOC_COOKIE, SSL_R_LENGTH_MISMATCH);
+        return 0;
+    }
+
+    return 1;
+}
+
 int tls_parse_stoc_early_data(SSL *s, PACKET *pkt, unsigned int context,
                               X509 *x, size_t chainidx, int *al)
 {
diff --git a/ssl/statem/statem_locl.h b/ssl/statem/statem_locl.h
index c52ce2b..68160c9 100644
--- a/ssl/statem/statem_locl.h
+++ b/ssl/statem/statem_locl.h
@@ -332,6 +332,8 @@ int tls_construct_ctos_key_share(SSL *s, WPACKET *pkt, unsigned int context,
                                  X509 *x, size_t chainidx, int *al);
 int tls_construct_ctos_psk_kex_modes(SSL *s, WPACKET *pkt, unsigned int context,
                                      X509 *x, size_t chainidx, int *al);
+int tls_construct_ctos_cookie(SSL *s, WPACKET *pkt, unsigned int context,
+                              X509 *x, size_t chainidx, int *al);
 int tls_construct_ctos_padding(SSL *s, WPACKET *pkt, unsigned int context,
                                X509 *x, size_t chainidx, int *al);
 int tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context, X509 *x,
@@ -374,5 +376,7 @@ int tls_parse_stoc_ems(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
                        size_t chainidx, int *al);
 int tls_parse_stoc_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
                              size_t chainidx, int *al);
+int tls_parse_stoc_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
+                       size_t chainidx, int *al);
 int tls_parse_stoc_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
                        size_t chainidx, int *al);
diff --git a/test/recipes/70-test_tls13cookie.t b/test/recipes/70-test_tls13cookie.t
new file mode 100644
index 0000000..c263e0e
--- /dev/null
+++ b/test/recipes/70-test_tls13cookie.t
@@ -0,0 +1,81 @@
+#! /usr/bin/env perl
+# Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the OpenSSL license (the "License").  You may not use
+# this file except in compliance with the License.  You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
+use strict;
+use OpenSSL::Test qw/:DEFAULT cmdstr srctop_file bldtop_dir/;
+use OpenSSL::Test::Utils;
+use TLSProxy::Proxy;
+
+my $test_name = "test_tls13cookie";
+setup($test_name);
+
+plan skip_all => "TLSProxy isn't usable on $^O"
+    if $^O =~ /^(VMS|MSWin32)$/;
+
+plan skip_all => "$test_name needs the dynamic engine feature enabled"
+    if disabled("engine") || disabled("dynamic-engine");
+
+plan skip_all => "$test_name needs the sock feature enabled"
+    if disabled("sock");
+
+plan skip_all => "$test_name needs TLS1.3 enabled"
+    if disabled("tls1_3");
+
+$ENV{OPENSSL_ia32cap} = '~0x200000200000000';
+
+my $proxy = TLSProxy::Proxy->new(
+    undef,
+    cmdstr(app(["openssl"]), display => 1),
+    srctop_file("apps", "server.pem"),
+    (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
+);
+
+my $cookieseen = 0;
+
+#Test 1: Inserting a cookie into an HRR should see it echoed in the ClientHello
+$proxy->filter(\&cookie_filter);
+$proxy->serverflags("-curves P-256");
+$proxy->start() or plan skip_all => "Unable to start up Proxy for tests";
+plan tests => 1;
+ok(TLSProxy::Message->success() && $cookieseen == 1, "Cookie seen");
+
+sub cookie_filter
+{
+    my $proxy = shift;
+
+    # We're only interested in the HRR and subsequent ClientHello
+    if ($proxy->flight != 1 && $proxy->flight != 2) {
+        return;
+    }
+
+    my $ext = pack "C8",
+        0x00, 0x06, #Cookie Length
+        0x00, 0x01, #Dummy cookie data (6 bytes)
+        0x02, 0x03,
+        0x04, 0x05;
+
+    foreach my $message (@{$proxy->message_list}) {
+        if ($message->mt == TLSProxy::Message::MT_HELLO_RETRY_REQUEST) {
+
+            $message->set_extension(TLSProxy::Message::EXT_COOKIE, $ext);
+            $message->repack();
+        } elsif ($message->mt == TLSProxy::Message::MT_CLIENT_HELLO
+                    && ${$message->records}[0]->flight == 2) {
+            #cmp can behave differently dependent on locale
+            no locale;
+            my $cookie =
+                $message->extension_data->{TLSProxy::Message::EXT_COOKIE};
+
+            return if !defined($cookie);
+
+            return if ($cookie cmp $ext) != 0;
+
+            $cookieseen = 1;
+        }
+    }
+}
diff --git a/util/TLSProxy/Message.pm b/util/TLSProxy/Message.pm
index ce469c4..88de558 100644
--- a/util/TLSProxy/Message.pm
+++ b/util/TLSProxy/Message.pm
@@ -78,6 +78,7 @@ use constant {
     EXT_KEY_SHARE => 40,
     EXT_PSK => 41,
     EXT_SUPPORTED_VERSIONS => 43,
+    EXT_COOKIE => 44,
     EXT_PSK_KEX_MODES => 45,
     EXT_RENEGOTIATE => 65281,
     EXT_NPN => 13172,


More information about the openssl-commits mailing list