clienthellotest.c revision 291721
1/* Written by Matt Caswell for the OpenSSL Project */ 2/* ==================================================================== 3 * Copyright (c) 1998-2015 The OpenSSL Project. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in 14 * the documentation and/or other materials provided with the 15 * distribution. 16 * 17 * 3. All advertising materials mentioning features or use of this 18 * software must display the following acknowledgment: 19 * "This product includes software developed by the OpenSSL Project 20 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 21 * 22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 23 * endorse or promote products derived from this software without 24 * prior written permission. For written permission, please contact 25 * openssl-core@openssl.org. 26 * 27 * 5. Products derived from this software may not be called "OpenSSL" 28 * nor may "OpenSSL" appear in their names without prior written 29 * permission of the OpenSSL Project. 30 * 31 * 6. Redistributions of any form whatsoever must retain the following 32 * acknowledgment: 33 * "This product includes software developed by the OpenSSL Project 34 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 35 * 36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 47 * OF THE POSSIBILITY OF SUCH DAMAGE. 48 * ==================================================================== 49 * 50 * This product includes cryptographic software written by Eric Young 51 * (eay@cryptsoft.com). This product includes software written by Tim 52 * Hudson (tjh@cryptsoft.com). 53 * 54 */ 55 56#include <string.h> 57 58#include <openssl/bio.h> 59#include <openssl/crypto.h> 60#include <openssl/evp.h> 61#include <openssl/ssl.h> 62#include <openssl/err.h> 63 64 65#define CLIENT_VERSION_LEN 2 66#define SESSION_ID_LEN_LEN 1 67#define CIPHERS_LEN_LEN 2 68#define COMPRESSION_LEN_LEN 1 69#define EXTENSIONS_LEN_LEN 2 70#define EXTENSION_TYPE_LEN 2 71#define EXTENSION_SIZE_LEN 2 72 73 74#define TOTAL_NUM_TESTS 2 75 76/* 77 * Test that explicitly setting ticket data results in it appearing in the 78 * ClientHello for TLS1.2 79 */ 80#define TEST_SET_SESSION_TICK_DATA_TLS_1_2 0 81 82/* 83 * Test that explicitly setting ticket data results in it appearing in the 84 * ClientHello for a negotiated SSL/TLS version 85 */ 86#define TEST_SET_SESSION_TICK_DATA_VER_NEG 1 87 88int main(int argc, char *argv[]) 89{ 90 SSL_CTX *ctx; 91 SSL *con; 92 BIO *rbio; 93 BIO *wbio; 94 BIO *err; 95 long len; 96 unsigned char *data; 97 unsigned char *dataend; 98 char *dummytick = "Hello World!"; 99 unsigned int tmplen; 100 unsigned int type; 101 unsigned int size; 102 int testresult = 0; 103 int currtest = 0; 104 105 SSL_library_init(); 106 SSL_load_error_strings(); 107 108 err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT); 109 110 CRYPTO_malloc_debug_init(); 111 CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); 112 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); 113 114 /* 115 * For each test set up an SSL_CTX and SSL and see what ClientHello gets 116 * produced when we try to connect 117 */ 118 for (; currtest < TOTAL_NUM_TESTS; currtest++) { 119 testresult = 0; 120 if (currtest == TEST_SET_SESSION_TICK_DATA_TLS_1_2) { 121 ctx = SSL_CTX_new(TLSv1_2_method()); 122 } else { 123 ctx = SSL_CTX_new(SSLv23_method()); 124 } 125 con = SSL_new(ctx); 126 127 rbio = BIO_new(BIO_s_mem()); 128 wbio = BIO_new(BIO_s_mem()); 129 SSL_set_bio(con, rbio, wbio); 130 SSL_set_connect_state(con); 131 132 if (currtest == TEST_SET_SESSION_TICK_DATA_TLS_1_2 133 || currtest == TEST_SET_SESSION_TICK_DATA_VER_NEG) { 134 if (!SSL_set_session_ticket_ext(con, dummytick, strlen(dummytick))) 135 goto end; 136 } 137 138 if (SSL_connect(con) > 0) { 139 /* This shouldn't succeed because we don't have a server! */ 140 goto end; 141 } 142 143 len = BIO_get_mem_data(wbio, (char **)&data); 144 dataend = data + len; 145 146 /* Skip the record header */ 147 data += SSL3_RT_HEADER_LENGTH; 148 /* Skip the handshake message header */ 149 data += SSL3_HM_HEADER_LENGTH; 150 /* Skip client version and random */ 151 data += CLIENT_VERSION_LEN + SSL3_RANDOM_SIZE; 152 if (data + SESSION_ID_LEN_LEN > dataend) 153 goto end; 154 /* Skip session id */ 155 tmplen = *data; 156 data += SESSION_ID_LEN_LEN + tmplen; 157 if (data + CIPHERS_LEN_LEN > dataend) 158 goto end; 159 /* Skip ciphers */ 160 tmplen = ((*data) << 8) | *(data + 1); 161 data += CIPHERS_LEN_LEN + tmplen; 162 if (data + COMPRESSION_LEN_LEN > dataend) 163 goto end; 164 /* Skip compression */ 165 tmplen = *data; 166 data += COMPRESSION_LEN_LEN + tmplen; 167 if (data + EXTENSIONS_LEN_LEN > dataend) 168 goto end; 169 /* Extensions len */ 170 tmplen = ((*data) << 8) | *(data + 1); 171 data += EXTENSIONS_LEN_LEN; 172 if (data + tmplen > dataend) 173 goto end; 174 175 /* Loop through all extensions */ 176 while (tmplen > EXTENSION_TYPE_LEN + EXTENSION_SIZE_LEN) { 177 type = ((*data) << 8) | *(data + 1); 178 data += EXTENSION_TYPE_LEN; 179 size = ((*data) << 8) | *(data + 1); 180 data += EXTENSION_SIZE_LEN; 181 if (data + size > dataend) 182 goto end; 183 184 if (type == TLSEXT_TYPE_session_ticket) { 185 if (currtest == TEST_SET_SESSION_TICK_DATA_TLS_1_2 186 || currtest == TEST_SET_SESSION_TICK_DATA_VER_NEG) { 187 if (size == strlen(dummytick) 188 && memcmp(data, dummytick, size) == 0) { 189 /* Ticket data is as we expected */ 190 testresult = 1; 191 } else { 192 printf("Received session ticket is not as expected\n"); 193 } 194 break; 195 } 196 } 197 198 tmplen -= EXTENSION_TYPE_LEN + EXTENSION_SIZE_LEN + size; 199 data += size; 200 } 201 202 end: 203 SSL_free(con); 204 SSL_CTX_free(ctx); 205 if (!testresult) { 206 printf("ClientHello test: FAILED (Test %d)\n", currtest); 207 break; 208 } 209 } 210 211 ERR_free_strings(); 212 ERR_remove_thread_state(NULL); 213 EVP_cleanup(); 214 CRYPTO_cleanup_all_ex_data(); 215 CRYPTO_mem_leaks(err); 216 217 return testresult?0:1; 218} 219