1291709Sjkim/* Written by Matt Caswell for the OpenSSL Project */ 2291709Sjkim/* ==================================================================== 3291709Sjkim * Copyright (c) 1998-2015 The OpenSSL Project. All rights reserved. 4291709Sjkim * 5291709Sjkim * Redistribution and use in source and binary forms, with or without 6291709Sjkim * modification, are permitted provided that the following conditions 7291709Sjkim * are met: 8291709Sjkim * 9291709Sjkim * 1. Redistributions of source code must retain the above copyright 10291709Sjkim * notice, this list of conditions and the following disclaimer. 11291709Sjkim * 12291709Sjkim * 2. Redistributions in binary form must reproduce the above copyright 13291709Sjkim * notice, this list of conditions and the following disclaimer in 14291709Sjkim * the documentation and/or other materials provided with the 15291709Sjkim * distribution. 16291709Sjkim * 17291709Sjkim * 3. All advertising materials mentioning features or use of this 18291709Sjkim * software must display the following acknowledgment: 19291709Sjkim * "This product includes software developed by the OpenSSL Project 20291709Sjkim * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 21291709Sjkim * 22291709Sjkim * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 23291709Sjkim * endorse or promote products derived from this software without 24291709Sjkim * prior written permission. For written permission, please contact 25291709Sjkim * openssl-core@openssl.org. 26291709Sjkim * 27291709Sjkim * 5. Products derived from this software may not be called "OpenSSL" 28291709Sjkim * nor may "OpenSSL" appear in their names without prior written 29291709Sjkim * permission of the OpenSSL Project. 30291709Sjkim * 31291709Sjkim * 6. Redistributions of any form whatsoever must retain the following 32291709Sjkim * acknowledgment: 33291709Sjkim * "This product includes software developed by the OpenSSL Project 34291709Sjkim * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 35291709Sjkim * 36291709Sjkim * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 37291709Sjkim * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 38291709Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 39291709Sjkim * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 40291709Sjkim * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 41291709Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 42291709Sjkim * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 43291709Sjkim * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 44291709Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 45291709Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46291709Sjkim * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 47291709Sjkim * OF THE POSSIBILITY OF SUCH DAMAGE. 48291709Sjkim * ==================================================================== 49291709Sjkim * 50291709Sjkim * This product includes cryptographic software written by Eric Young 51291709Sjkim * (eay@cryptsoft.com). This product includes software written by Tim 52291709Sjkim * Hudson (tjh@cryptsoft.com). 53291709Sjkim * 54291709Sjkim */ 55291709Sjkim 56291709Sjkim#include <string.h> 57291709Sjkim 58291709Sjkim#include <openssl/bio.h> 59291709Sjkim#include <openssl/crypto.h> 60291709Sjkim#include <openssl/evp.h> 61291709Sjkim#include <openssl/ssl.h> 62291709Sjkim#include <openssl/err.h> 63291709Sjkim 64291709Sjkim 65291709Sjkim#define CLIENT_VERSION_LEN 2 66291709Sjkim#define SESSION_ID_LEN_LEN 1 67291709Sjkim#define CIPHERS_LEN_LEN 2 68291709Sjkim#define COMPRESSION_LEN_LEN 1 69291709Sjkim#define EXTENSIONS_LEN_LEN 2 70291709Sjkim#define EXTENSION_TYPE_LEN 2 71291709Sjkim#define EXTENSION_SIZE_LEN 2 72291709Sjkim 73291709Sjkim 74291709Sjkim#define TOTAL_NUM_TESTS 2 75291709Sjkim 76291709Sjkim/* 77291709Sjkim * Test that explicitly setting ticket data results in it appearing in the 78291709Sjkim * ClientHello for TLS1.2 79291709Sjkim */ 80291709Sjkim#define TEST_SET_SESSION_TICK_DATA_TLS_1_2 0 81291709Sjkim 82291709Sjkim/* 83291709Sjkim * Test that explicitly setting ticket data results in it appearing in the 84291709Sjkim * ClientHello for a negotiated SSL/TLS version 85291709Sjkim */ 86291709Sjkim#define TEST_SET_SESSION_TICK_DATA_VER_NEG 1 87291709Sjkim 88291709Sjkimint main(int argc, char *argv[]) 89291709Sjkim{ 90291709Sjkim SSL_CTX *ctx; 91291709Sjkim SSL *con; 92291709Sjkim BIO *rbio; 93291709Sjkim BIO *wbio; 94291709Sjkim BIO *err; 95291709Sjkim long len; 96291709Sjkim unsigned char *data; 97291709Sjkim unsigned char *dataend; 98291709Sjkim char *dummytick = "Hello World!"; 99291709Sjkim unsigned int tmplen; 100291709Sjkim unsigned int type; 101291709Sjkim unsigned int size; 102291709Sjkim int testresult = 0; 103291709Sjkim int currtest = 0; 104291709Sjkim 105291709Sjkim SSL_library_init(); 106291709Sjkim SSL_load_error_strings(); 107291709Sjkim 108291709Sjkim err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT); 109291709Sjkim 110291709Sjkim CRYPTO_malloc_debug_init(); 111291709Sjkim CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); 112291709Sjkim CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); 113291709Sjkim 114291709Sjkim /* 115291709Sjkim * For each test set up an SSL_CTX and SSL and see what ClientHello gets 116291709Sjkim * produced when we try to connect 117291709Sjkim */ 118291709Sjkim for (; currtest < TOTAL_NUM_TESTS; currtest++) { 119291709Sjkim testresult = 0; 120291709Sjkim if (currtest == TEST_SET_SESSION_TICK_DATA_TLS_1_2) { 121291709Sjkim ctx = SSL_CTX_new(TLSv1_2_method()); 122291709Sjkim } else { 123291709Sjkim ctx = SSL_CTX_new(SSLv23_method()); 124291709Sjkim } 125291709Sjkim con = SSL_new(ctx); 126291709Sjkim 127291709Sjkim rbio = BIO_new(BIO_s_mem()); 128291709Sjkim wbio = BIO_new(BIO_s_mem()); 129291709Sjkim SSL_set_bio(con, rbio, wbio); 130291709Sjkim SSL_set_connect_state(con); 131291709Sjkim 132291709Sjkim if (currtest == TEST_SET_SESSION_TICK_DATA_TLS_1_2 133291709Sjkim || currtest == TEST_SET_SESSION_TICK_DATA_VER_NEG) { 134291709Sjkim if (!SSL_set_session_ticket_ext(con, dummytick, strlen(dummytick))) 135291709Sjkim goto end; 136291709Sjkim } 137291709Sjkim 138291709Sjkim if (SSL_connect(con) > 0) { 139291709Sjkim /* This shouldn't succeed because we don't have a server! */ 140291709Sjkim goto end; 141291709Sjkim } 142291709Sjkim 143291709Sjkim len = BIO_get_mem_data(wbio, (char **)&data); 144291709Sjkim dataend = data + len; 145291709Sjkim 146291709Sjkim /* Skip the record header */ 147291709Sjkim data += SSL3_RT_HEADER_LENGTH; 148291709Sjkim /* Skip the handshake message header */ 149291709Sjkim data += SSL3_HM_HEADER_LENGTH; 150291709Sjkim /* Skip client version and random */ 151291709Sjkim data += CLIENT_VERSION_LEN + SSL3_RANDOM_SIZE; 152291709Sjkim if (data + SESSION_ID_LEN_LEN > dataend) 153291709Sjkim goto end; 154291709Sjkim /* Skip session id */ 155291709Sjkim tmplen = *data; 156291709Sjkim data += SESSION_ID_LEN_LEN + tmplen; 157291709Sjkim if (data + CIPHERS_LEN_LEN > dataend) 158291709Sjkim goto end; 159291709Sjkim /* Skip ciphers */ 160291709Sjkim tmplen = ((*data) << 8) | *(data + 1); 161291709Sjkim data += CIPHERS_LEN_LEN + tmplen; 162291709Sjkim if (data + COMPRESSION_LEN_LEN > dataend) 163291709Sjkim goto end; 164291709Sjkim /* Skip compression */ 165291709Sjkim tmplen = *data; 166291709Sjkim data += COMPRESSION_LEN_LEN + tmplen; 167291709Sjkim if (data + EXTENSIONS_LEN_LEN > dataend) 168291709Sjkim goto end; 169291709Sjkim /* Extensions len */ 170291709Sjkim tmplen = ((*data) << 8) | *(data + 1); 171291709Sjkim data += EXTENSIONS_LEN_LEN; 172291709Sjkim if (data + tmplen > dataend) 173291709Sjkim goto end; 174291709Sjkim 175291709Sjkim /* Loop through all extensions */ 176291709Sjkim while (tmplen > EXTENSION_TYPE_LEN + EXTENSION_SIZE_LEN) { 177291709Sjkim type = ((*data) << 8) | *(data + 1); 178291709Sjkim data += EXTENSION_TYPE_LEN; 179291709Sjkim size = ((*data) << 8) | *(data + 1); 180291709Sjkim data += EXTENSION_SIZE_LEN; 181291709Sjkim if (data + size > dataend) 182291709Sjkim goto end; 183291709Sjkim 184291709Sjkim if (type == TLSEXT_TYPE_session_ticket) { 185291709Sjkim if (currtest == TEST_SET_SESSION_TICK_DATA_TLS_1_2 186291709Sjkim || currtest == TEST_SET_SESSION_TICK_DATA_VER_NEG) { 187291709Sjkim if (size == strlen(dummytick) 188291709Sjkim && memcmp(data, dummytick, size) == 0) { 189291709Sjkim /* Ticket data is as we expected */ 190291709Sjkim testresult = 1; 191291709Sjkim } else { 192291709Sjkim printf("Received session ticket is not as expected\n"); 193291709Sjkim } 194291709Sjkim break; 195291709Sjkim } 196291709Sjkim } 197291709Sjkim 198291709Sjkim tmplen -= EXTENSION_TYPE_LEN + EXTENSION_SIZE_LEN + size; 199291709Sjkim data += size; 200291709Sjkim } 201291709Sjkim 202291709Sjkim end: 203291709Sjkim SSL_free(con); 204291709Sjkim SSL_CTX_free(ctx); 205291709Sjkim if (!testresult) { 206291709Sjkim printf("ClientHello test: FAILED (Test %d)\n", currtest); 207291709Sjkim break; 208291709Sjkim } 209291709Sjkim } 210291709Sjkim 211291709Sjkim ERR_free_strings(); 212291709Sjkim ERR_remove_thread_state(NULL); 213291709Sjkim EVP_cleanup(); 214291709Sjkim CRYPTO_cleanup_all_ex_data(); 215291709Sjkim CRYPTO_mem_leaks(err); 216291709Sjkim 217291709Sjkim return testresult?0:1; 218291709Sjkim} 219