Commit 3b848c64 authored by Matt Caswell's avatar Matt Caswell
Browse files

Add test for SSL_set_session_ticket_ext



The function SSL_set_session_ticket_ext sets the ticket data to be sent in
the ClientHello. This is useful for EAP-FAST. This commit adds a test to
ensure that when this function is called the expected ticket data actually
appears in the ClientHello.

Reviewed-by: default avatarViktor Dukhovni <viktor@openssl.org>
parent 57787ac8
Loading
Loading
Loading
Loading
+31 −4
Original line number Diff line number Diff line
@@ -69,6 +69,7 @@ V3NAMETEST= v3nametest
HEARTBEATTEST=  heartbeat_test
CONSTTIMETEST=  constant_time_test
VERIFYEXTRATEST=	verify_extra_test
CLIENTHELLOTEST=	clienthellotest

TESTS=		alltests

@@ -85,7 +86,8 @@ EXE= $(BNTEST)$(EXE_EXT) $(ECTEST)$(EXE_EXT) $(ECDSATEST)$(EXE_EXT) $(ECDHTEST)
	$(JPAKETEST)$(EXE_EXT) $(SECMEMTEST)$(EXE_EXT) \
	$(SRPTEST)$(EXE_EXT) $(V3NAMETEST)$(EXE_EXT) \
	$(HEARTBEATTEST)$(EXE_EXT) $(P5_CRPT2_TEST)$(EXE_EXT) \
	$(CONSTTIMETEST)$(EXE_EXT) $(VERIFYEXTRATEST)$(EXE_EXT)
	$(CONSTTIMETEST)$(EXE_EXT) $(VERIFYEXTRATEST)$(EXE_EXT) \
	$(CLIENTHELLOTEST)$(EXE_EXT)

# $(METHTEST)$(EXE_EXT)

@@ -99,7 +101,7 @@ OBJ= $(BNTEST).o $(ECTEST).o $(ECDSATEST).o $(ECDHTEST).o $(IDEATEST).o \
	$(BFTEST).o  $(SSLTEST).o  $(DSATEST).o  $(EXPTEST).o $(RSATEST).o \
	$(EVPTEST).o $(EVPEXTRATEST).o $(IGETEST).o $(JPAKETEST).o $(V3NAMETEST).o \
	$(GOST2814789TEST).o $(HEARTBEATTEST).o $(P5_CRPT2_TEST).o \
	$(CONSTTIMETEST).o $(VERIFYEXTRATEST).o testutil.o
	$(CONSTTIMETEST).o $(VERIFYEXTRATEST).o $(CLIENTHELLOTEST).o testutil.o

SRC=	$(BNTEST).c $(ECTEST).c  $(ECDSATEST).c $(ECDHTEST).c $(IDEATEST).c \
	$(MD2TEST).c  $(MD4TEST).c $(MD5TEST).c \
@@ -110,7 +112,7 @@ SRC= $(BNTEST).c $(ECTEST).c $(ECDSATEST).c $(ECDHTEST).c $(IDEATEST).c \
	$(BFTEST).c  $(SSLTEST).c $(DSATEST).c   $(EXPTEST).c $(RSATEST).c \
	$(EVPTEST).c $(EVPEXTRATEST).c $(IGETEST).c $(JPAKETEST).c $(V3NAMETEST).c \
	$(GOST2814789TEST).c $(HEARTBEATTEST).c $(P5_CRPT2_TEST).c \
	$(CONSTTIMETEST).c $(VERIFYEXTRATEST).c testutil.c
	$(CONSTTIMETEST).c $(VERIFYEXTRATEST).c $(CLIENTHELLOTEST).c testutil.c

HEADER=	testutil.h

@@ -151,7 +153,7 @@ alltests: \
	test_ige test_jpake test_secmem \
	test_srp test_cms test_v3name test_ocsp \
	test_gost2814789 test_heartbeat test_p5_crpt2 \
	test_constant_time test_verify_extra
	test_constant_time test_verify_extra test_clienthello

test_evp: $(EVPTEST)$(EXE_EXT) evptests.txt
	@echo $(START) $@
@@ -404,6 +406,10 @@ test_verify_extra: $(VERIFYEXTRATEST)$(EXE_EXT)
	@echo $(START) $@
	../util/shlib_wrap.sh ./$(VERIFYEXTRATEST)

test_clienthello: $(CLIENTHELLOTEST)$(EXE_EXT)
	@echo $(START) $@
	../util/shlib_wrap.sh ./$(CLIENTHELLOTEST)

update: local_depend
	@if [ -z "$(THIS)" ]; then $(MAKE) -f $(TOP)/Makefile reflect THIS=$@; fi

@@ -594,6 +600,9 @@ $(CONSTTIMETEST)$(EXE_EXT): $(CONSTTIMETEST).o
$(VERIFYEXTRATEST)$(EXE_EXT): $(VERIFYEXTRATEST).o
	@target=$(VERIFYEXTRATEST) $(BUILD_CMD)

$(CLIENTHELLOTEST)$(EXE_EXT): $(CLIENTHELLOTEST).o
	@target=$(CLIENTHELLOTEST) $(BUILD_CMD)

#$(AESTEST).o: $(AESTEST).c
#	$(CC) -c $(CFLAGS) -DINTERMEDIATE_VALUE_KAT -DTRACE_KAT_MCT $(AESTEST).c

@@ -627,6 +636,24 @@ bntest.o: ../include/openssl/symhacks.h ../include/openssl/x509.h
bntest.o: ../include/openssl/x509_vfy.h bntest.c
casttest.o: ../e_os.h ../include/openssl/cast.h ../include/openssl/e_os2.h
casttest.o: ../include/openssl/opensslconf.h casttest.c
clienthellotest.o: ../include/openssl/asn1.h ../include/openssl/bio.h
clienthellotest.o: ../include/openssl/buffer.h ../include/openssl/comp.h
clienthellotest.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
clienthellotest.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
clienthellotest.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
clienthellotest.o: ../include/openssl/err.h ../include/openssl/evp.h
clienthellotest.o: ../include/openssl/hmac.h ../include/openssl/lhash.h
clienthellotest.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
clienthellotest.o: ../include/openssl/opensslconf.h
clienthellotest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
clienthellotest.o: ../include/openssl/pem.h ../include/openssl/pem2.h
clienthellotest.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
clienthellotest.o: ../include/openssl/sha.h ../include/openssl/srtp.h
clienthellotest.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
clienthellotest.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
clienthellotest.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
clienthellotest.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
clienthellotest.o: clienthellotest.c
constant_time_test.o: ../e_os.h ../include/internal/constant_time_locl.h
constant_time_test.o: ../include/openssl/e_os2.h
constant_time_test.o: ../include/openssl/opensslconf.h constant_time_test.c

test/clienthellotest.c

0 → 100644
+218 −0
Original line number Diff line number Diff line
/* Written by Matt Caswell for the OpenSSL Project */
/* ====================================================================
 * Copyright (c) 1998-2015 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#include <string.h>

#include <openssl/bio.h>
#include <openssl/crypto.h>
#include <openssl/evp.h>
#include <openssl/ssl.h>
#include <openssl/err.h>


#define CLIENT_VERSION_LEN      2
#define SESSION_ID_LEN_LEN      1
#define CIPHERS_LEN_LEN         2
#define COMPRESSION_LEN_LEN     1
#define EXTENSIONS_LEN_LEN      2
#define EXTENSION_TYPE_LEN      2
#define EXTENSION_SIZE_LEN      2


#define TOTAL_NUM_TESTS                         2

/*
 * Test that explicitly setting ticket data results in it appearing in the
 * ClientHello for TLS1.2
 */
#define TEST_SET_SESSION_TICK_DATA_TLS_1_2      0

/*
 * Test that explicitly setting ticket data results in it appearing in the
 * ClientHello for a negotiated SSL/TLS version
 */
#define TEST_SET_SESSION_TICK_DATA_VER_NEG      1

int main(int argc, char *argv[])
{
    SSL_CTX *ctx;
    SSL *con;
    BIO *rbio;
    BIO *wbio;
    BIO *err;
    long len;
    unsigned char *data;
    unsigned char *dataend;
    char *dummytick = "Hello World!";
    unsigned int tmplen;
    unsigned int type;
    unsigned int size;
    int testresult = 0;
    int currtest = 0;

    SSL_library_init();
    SSL_load_error_strings();

    err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT);

    CRYPTO_malloc_debug_init();
    CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);

    /*
     * For each test set up an SSL_CTX and SSL and see what ClientHello gets
     * produced when we try to connect
     */
    for (; currtest < TOTAL_NUM_TESTS; currtest++) {
        testresult = 0;
        if (currtest == TEST_SET_SESSION_TICK_DATA_TLS_1_2) {
            ctx = SSL_CTX_new(TLSv1_2_method());
        } else {
            ctx = SSL_CTX_new(TLS_method());
        }
        con = SSL_new(ctx);

        rbio = BIO_new(BIO_s_mem());
        wbio = BIO_new(BIO_s_mem());
        SSL_set_bio(con, rbio, wbio);
        SSL_set_connect_state(con);

        if (currtest == TEST_SET_SESSION_TICK_DATA_TLS_1_2
                || currtest == TEST_SET_SESSION_TICK_DATA_VER_NEG) {
            if (!SSL_set_session_ticket_ext(con, dummytick, strlen(dummytick)))
                goto end;
        }

        if (SSL_connect(con) > 0) {
            /* This shouldn't succeed because we don't have a server! */
            goto end;
        }

        len = BIO_get_mem_data(wbio, (char **)&data);
        dataend = data + len;

        /* Skip the record header */
        data += SSL3_RT_HEADER_LENGTH;
        /* Skip the handshake message header */
        data += SSL3_HM_HEADER_LENGTH;
        /* Skip client version and random */
        data += CLIENT_VERSION_LEN + SSL3_RANDOM_SIZE;
        if (data + SESSION_ID_LEN_LEN > dataend)
            goto end;
        /* Skip session id */
        tmplen = *data;
        data += SESSION_ID_LEN_LEN + tmplen;
        if (data + CIPHERS_LEN_LEN > dataend)
            goto end;
        /* Skip ciphers */
        tmplen = ((*data) << 8) | *(data + 1);
        data += CIPHERS_LEN_LEN + tmplen;
        if (data + COMPRESSION_LEN_LEN > dataend)
            goto end;
        /* Skip compression */
        tmplen = *data;
        data += COMPRESSION_LEN_LEN + tmplen;
        if (data + EXTENSIONS_LEN_LEN > dataend)
            goto end;
        /* Extensions len */
        tmplen = ((*data) << 8) | *(data + 1);
        data += EXTENSIONS_LEN_LEN;
        if (data + tmplen > dataend)
            goto end;

        /* Loop through all extensions */
        while (tmplen > EXTENSION_TYPE_LEN + EXTENSION_SIZE_LEN) {
            type = ((*data) << 8) | *(data + 1);
            data += EXTENSION_TYPE_LEN;
            size = ((*data) << 8) | *(data + 1);
            data += EXTENSION_SIZE_LEN;
            if (data + size > dataend)
                goto end;

            if (type == TLSEXT_TYPE_session_ticket) {
                if (currtest == TEST_SET_SESSION_TICK_DATA_TLS_1_2
                        || currtest == TEST_SET_SESSION_TICK_DATA_VER_NEG) {
                    if (size == strlen(dummytick)
                            && memcmp(data, dummytick, size) == 0) {
                        /* Ticket data is as we expected */
                        testresult = 1;
                    } else {
                        printf("Received session ticket is not as expected\n");
                    }
                    break;
                }
            }

            tmplen -= EXTENSION_TYPE_LEN + EXTENSION_SIZE_LEN + size;
            data += size;
        }

 end:
        SSL_free(con);
        SSL_CTX_free(ctx);
        if (!testresult) {
            printf("ClientHello test: FAILED (Test %d)\n", currtest);
            break;
        }
    }

    ERR_free_strings();
    ERR_remove_thread_state(NULL);
    EVP_cleanup();
    CRYPTO_cleanup_all_ex_data();
    CRYPTO_mem_leaks(err);

    return testresult?0:1;
}