1291707Sjkim/* Written by Matt Caswell for the OpenSSL Project */ 2291707Sjkim/* ==================================================================== 3291707Sjkim * Copyright (c) 1998-2015 The OpenSSL Project. All rights reserved. 4291707Sjkim * 5291707Sjkim * Redistribution and use in source and binary forms, with or without 6291707Sjkim * modification, are permitted provided that the following conditions 7291707Sjkim * are met: 8291707Sjkim * 9291707Sjkim * 1. Redistributions of source code must retain the above copyright 10291707Sjkim * notice, this list of conditions and the following disclaimer. 11291707Sjkim * 12291707Sjkim * 2. Redistributions in binary form must reproduce the above copyright 13291707Sjkim * notice, this list of conditions and the following disclaimer in 14291707Sjkim * the documentation and/or other materials provided with the 15291707Sjkim * distribution. 16291707Sjkim * 17291707Sjkim * 3. All advertising materials mentioning features or use of this 18291707Sjkim * software must display the following acknowledgment: 19291707Sjkim * "This product includes software developed by the OpenSSL Project 20291707Sjkim * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 21291707Sjkim * 22291707Sjkim * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 23291707Sjkim * endorse or promote products derived from this software without 24291707Sjkim * prior written permission. For written permission, please contact 25291707Sjkim * openssl-core@openssl.org. 26291707Sjkim * 27291707Sjkim * 5. Products derived from this software may not be called "OpenSSL" 28291707Sjkim * nor may "OpenSSL" appear in their names without prior written 29291707Sjkim * permission of the OpenSSL Project. 30291707Sjkim * 31291707Sjkim * 6. Redistributions of any form whatsoever must retain the following 32291707Sjkim * acknowledgment: 33291707Sjkim * "This product includes software developed by the OpenSSL Project 34291707Sjkim * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 35291707Sjkim * 36291707Sjkim * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 37291707Sjkim * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 38291707Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 39291707Sjkim * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 40291707Sjkim * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 41291707Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 42291707Sjkim * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 43291707Sjkim * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 44291707Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 45291707Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46291707Sjkim * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 47291707Sjkim * OF THE POSSIBILITY OF SUCH DAMAGE. 48291707Sjkim * ==================================================================== 49291707Sjkim * 50291707Sjkim * This product includes cryptographic software written by Eric Young 51291707Sjkim * (eay@cryptsoft.com). This product includes software written by Tim 52291707Sjkim * Hudson (tjh@cryptsoft.com). 53291707Sjkim * 54291707Sjkim */ 55291707Sjkim 56291707Sjkim#include <string.h> 57291707Sjkim 58291707Sjkim#include <openssl/bio.h> 59291707Sjkim#include <openssl/crypto.h> 60291707Sjkim#include <openssl/evp.h> 61291707Sjkim#include <openssl/ssl.h> 62291707Sjkim#include <openssl/err.h> 63291707Sjkim 64291707Sjkim 65291707Sjkim#define CLIENT_VERSION_LEN 2 66291707Sjkim#define SESSION_ID_LEN_LEN 1 67291707Sjkim#define CIPHERS_LEN_LEN 2 68291707Sjkim#define COMPRESSION_LEN_LEN 1 69291707Sjkim#define EXTENSIONS_LEN_LEN 2 70291707Sjkim#define EXTENSION_TYPE_LEN 2 71291707Sjkim#define EXTENSION_SIZE_LEN 2 72291707Sjkim 73291707Sjkim 74291707Sjkim#define TOTAL_NUM_TESTS 2 75291707Sjkim 76291707Sjkim/* 77291707Sjkim * Test that explicitly setting ticket data results in it appearing in the 78291707Sjkim * ClientHello for TLS1.2 79291707Sjkim */ 80291707Sjkim#define TEST_SET_SESSION_TICK_DATA_TLS_1_2 0 81291707Sjkim 82291707Sjkim/* 83291707Sjkim * Test that explicitly setting ticket data results in it appearing in the 84291707Sjkim * ClientHello for a negotiated SSL/TLS version 85291707Sjkim */ 86291707Sjkim#define TEST_SET_SESSION_TICK_DATA_VER_NEG 1 87291707Sjkim 88291707Sjkimint main(int argc, char *argv[]) 89291707Sjkim{ 90291707Sjkim SSL_CTX *ctx; 91291707Sjkim SSL *con; 92291707Sjkim BIO *rbio; 93291707Sjkim BIO *wbio; 94291707Sjkim BIO *err; 95291707Sjkim long len; 96291707Sjkim unsigned char *data; 97291707Sjkim unsigned char *dataend; 98291707Sjkim char *dummytick = "Hello World!"; 99291707Sjkim unsigned int tmplen; 100291707Sjkim unsigned int type; 101291707Sjkim unsigned int size; 102291707Sjkim int testresult = 0; 103291707Sjkim int currtest = 0; 104291707Sjkim 105291707Sjkim SSL_library_init(); 106291707Sjkim SSL_load_error_strings(); 107291707Sjkim 108291707Sjkim err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT); 109291707Sjkim 110291707Sjkim CRYPTO_malloc_debug_init(); 111291707Sjkim CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); 112291707Sjkim CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); 113291707Sjkim 114291707Sjkim /* 115291707Sjkim * For each test set up an SSL_CTX and SSL and see what ClientHello gets 116291707Sjkim * produced when we try to connect 117291707Sjkim */ 118291707Sjkim for (; currtest < TOTAL_NUM_TESTS; currtest++) { 119291707Sjkim testresult = 0; 120291707Sjkim if (currtest == TEST_SET_SESSION_TICK_DATA_TLS_1_2) { 121291707Sjkim ctx = SSL_CTX_new(TLSv1_2_method()); 122291707Sjkim } else { 123291707Sjkim ctx = SSL_CTX_new(SSLv23_method()); 124291707Sjkim } 125291707Sjkim con = SSL_new(ctx); 126291707Sjkim 127291707Sjkim rbio = BIO_new(BIO_s_mem()); 128291707Sjkim wbio = BIO_new(BIO_s_mem()); 129291707Sjkim SSL_set_bio(con, rbio, wbio); 130291707Sjkim SSL_set_connect_state(con); 131291707Sjkim 132291707Sjkim if (currtest == TEST_SET_SESSION_TICK_DATA_TLS_1_2 133291707Sjkim || currtest == TEST_SET_SESSION_TICK_DATA_VER_NEG) { 134291707Sjkim if (!SSL_set_session_ticket_ext(con, dummytick, strlen(dummytick))) 135291707Sjkim goto end; 136291707Sjkim } 137291707Sjkim 138291707Sjkim if (SSL_connect(con) > 0) { 139291707Sjkim /* This shouldn't succeed because we don't have a server! */ 140291707Sjkim goto end; 141291707Sjkim } 142291707Sjkim 143291707Sjkim len = BIO_get_mem_data(wbio, (char **)&data); 144291707Sjkim dataend = data + len; 145291707Sjkim 146291707Sjkim /* Skip the record header */ 147291707Sjkim data += SSL3_RT_HEADER_LENGTH; 148291707Sjkim /* Skip the handshake message header */ 149291707Sjkim data += SSL3_HM_HEADER_LENGTH; 150291707Sjkim /* Skip client version and random */ 151291707Sjkim data += CLIENT_VERSION_LEN + SSL3_RANDOM_SIZE; 152291707Sjkim if (data + SESSION_ID_LEN_LEN > dataend) 153291707Sjkim goto end; 154291707Sjkim /* Skip session id */ 155291707Sjkim tmplen = *data; 156291707Sjkim data += SESSION_ID_LEN_LEN + tmplen; 157291707Sjkim if (data + CIPHERS_LEN_LEN > dataend) 158291707Sjkim goto end; 159291707Sjkim /* Skip ciphers */ 160291707Sjkim tmplen = ((*data) << 8) | *(data + 1); 161291707Sjkim data += CIPHERS_LEN_LEN + tmplen; 162291707Sjkim if (data + COMPRESSION_LEN_LEN > dataend) 163291707Sjkim goto end; 164291707Sjkim /* Skip compression */ 165291707Sjkim tmplen = *data; 166291707Sjkim data += COMPRESSION_LEN_LEN + tmplen; 167291707Sjkim if (data + EXTENSIONS_LEN_LEN > dataend) 168291707Sjkim goto end; 169291707Sjkim /* Extensions len */ 170291707Sjkim tmplen = ((*data) << 8) | *(data + 1); 171291707Sjkim data += EXTENSIONS_LEN_LEN; 172291707Sjkim if (data + tmplen > dataend) 173291707Sjkim goto end; 174291707Sjkim 175291707Sjkim /* Loop through all extensions */ 176291707Sjkim while (tmplen > EXTENSION_TYPE_LEN + EXTENSION_SIZE_LEN) { 177291707Sjkim type = ((*data) << 8) | *(data + 1); 178291707Sjkim data += EXTENSION_TYPE_LEN; 179291707Sjkim size = ((*data) << 8) | *(data + 1); 180291707Sjkim data += EXTENSION_SIZE_LEN; 181291707Sjkim if (data + size > dataend) 182291707Sjkim goto end; 183291707Sjkim 184291707Sjkim if (type == TLSEXT_TYPE_session_ticket) { 185291707Sjkim if (currtest == TEST_SET_SESSION_TICK_DATA_TLS_1_2 186291707Sjkim || currtest == TEST_SET_SESSION_TICK_DATA_VER_NEG) { 187291707Sjkim if (size == strlen(dummytick) 188291707Sjkim && memcmp(data, dummytick, size) == 0) { 189291707Sjkim /* Ticket data is as we expected */ 190291707Sjkim testresult = 1; 191291707Sjkim } else { 192291707Sjkim printf("Received session ticket is not as expected\n"); 193291707Sjkim } 194291707Sjkim break; 195291707Sjkim } 196291707Sjkim } 197291707Sjkim 198291707Sjkim tmplen -= EXTENSION_TYPE_LEN + EXTENSION_SIZE_LEN + size; 199291707Sjkim data += size; 200291707Sjkim } 201291707Sjkim 202291707Sjkim end: 203291707Sjkim SSL_free(con); 204291707Sjkim SSL_CTX_free(ctx); 205291707Sjkim if (!testresult) { 206291707Sjkim printf("ClientHello test: FAILED (Test %d)\n", currtest); 207291707Sjkim break; 208291707Sjkim } 209291707Sjkim } 210291707Sjkim 211291707Sjkim ERR_free_strings(); 212291707Sjkim ERR_remove_thread_state(NULL); 213291707Sjkim EVP_cleanup(); 214291707Sjkim CRYPTO_cleanup_all_ex_data(); 215291707Sjkim CRYPTO_mem_leaks(err); 216291707Sjkim BIO_free(err); 217291707Sjkim 218291707Sjkim return testresult?0:1; 219291707Sjkim} 220