/* * hex2data -- Convert hex string to binary data * * Inputs: * * string The string to convert * data_len (output) The length of the resultant binary data * * Returns: * * Pointer to the binary data. * * The returned pointer points to malloc'ed storage which should be * free'ed by the caller when it's no longer needed. If the length of * the input string is not even, the function will return NULL and * set data_len to 0. */ unsigned char * hex2data(const char *string, size_t *data_len) { unsigned char *data; unsigned char *cp; unsigned i; size_t len; if (strlen(string) %2 ) { /* Length is odd */ *data_len = 0; return NULL; } len = strlen(string) / 2; data = Malloc(len); cp = data; for (i=0; i<len; i++) *cp++=hstr_i(&string[i*2]); *data_len = len; return data; }
/* Build sslv2 client hello message struct - pointer to struct int opt - single cipher option or not 1/0 char *c - cipher to use for single cipher option */ unsigned char * build_ssl2_hello_msg ( struct ssl2_client_hello *clientHello, int opt, char *c1, char *c2 ) { unsigned char *p; unsigned char *off; unsigned long num; int i; /* size up ptr */ p=malloc ( sizeof ( struct ssl2_client_hello ) ); clientHello=malloc ( sizeof ( struct ssl2_client_hello ) ); memset ( p, 0, sizeof ( struct ssl2_client_hello ) ); memset ( clientHello, 0, sizeof ( struct ssl2_client_hello ) ); /* Test a single cipher or check all */ //if ( opt ) { num=hstr_i ( c1 ); // clientHello->CipherSuite = htons(num); //} //else // clientHello->CipherSuite = htons(0x0005); clientHello->rl_content_type = SSL2_HANDSHAKE; //clientHello->rl_len = htons(sizeof(struct ssl2_client_hello)-2); clientHello->rl_len = sizeof ( struct ssl2_client_hello )-2; clientHello->client_handshake = CLIENT_HELLO; clientHello->client_version = htons ( SSL2_VERSION ); /* SSLv2 uses 3 bytes per cipher, we'll try use a uint32_t and strip it later or let trim random bytes if needed which follows. */ clientHello->cipher_len = htons ( SSL2_CIPHERLEN ); clientHello->sessionID = htons ( SESSIONID ); clientHello->challenge_len = htons ( SSL2_CHALLENGE_LEN ); /* Do a left bitwise shift to get our uint24_r, leave the extra byte to fall into random. */ num = num << 8; clientHello->CipherSuite = htonl ( num ); /* Cipher to send */ /* todo: cleaner way to generate random() */ for ( i=0; i<sizeof ( clientHello->random ); i++ ) { clientHello->random[i] = random(); } i=0; /* We copy our items off struct one by one to ensure correct alignment at compile time. */ off=p; memcpy ( off, &clientHello->rl_content_type, sizeof ( clientHello->rl_content_type ) ); off += sizeof ( clientHello->rl_content_type ); memcpy ( off, &clientHello->rl_len, sizeof ( clientHello->rl_len ) ); off += sizeof ( clientHello->rl_len ); memcpy ( off, &clientHello->client_handshake, sizeof ( clientHello->client_handshake ) ); off += sizeof ( clientHello->client_handshake ); memcpy ( off, &clientHello->client_version, sizeof ( clientHello->client_version ) ); off += sizeof ( clientHello->client_version ); memcpy ( off, &clientHello->cipher_len, sizeof ( clientHello->cipher_len ) ); off += sizeof ( clientHello->cipher_len ); memcpy ( off, &clientHello->sessionID, sizeof ( clientHello->sessionID ) ); off += sizeof ( clientHello->sessionID ); memcpy ( off, &clientHello->challenge_len, sizeof ( clientHello->challenge_len ) ); off += sizeof ( clientHello->challenge_len ); memcpy ( off, &clientHello->CipherSuite, sizeof ( clientHello->CipherSuite ) ); off += sizeof ( clientHello->CipherSuite ); memcpy ( off, &clientHello->random, sizeof ( clientHello->random ) ); free ( clientHello ); return p; }
/* Build SSLv3/TLSv1 client hello message struct - pointer to struct int opt - single cipher option or not 1/0 char *c - cipher to use for single cipher option */ unsigned char * build_hello_msg ( struct tls1_ssl3_client_hello *clientHello, int opt, char *c1, char *c2 ) { unsigned char *p; unsigned char *off; unsigned long num; int i; /* size up ptr */ p=malloc ( sizeof ( struct tls1_ssl3_client_hello ) ); clientHello=malloc ( sizeof ( struct tls1_ssl3_client_hello ) ); memset ( p, 0, sizeof ( struct tls1_ssl3_client_hello ) ); memset ( clientHello, 0, sizeof ( struct tls1_ssl3_client_hello ) ); /* Test a single cipher or check all */ //if ( opt ) { num=hstr_i ( c1 ); clientHello->CipherSuite = htons ( num ); //} //else // clientHello->CipherSuite = htons(0x0005); clientHello->rl_content_type = SSLHANDSHAKE; /* Decimal value for 1 in TLS1 is 49 (man ascii) We use this for comparison as it saves us having to use string compare functions. */ if ( ( int ) c2[3] == 49 ) clientHello->rl_client_version = htons ( TLS1_VERSION ); else clientHello->rl_client_version = htons ( SSL3_VERSION ); /* todo: add -2 to lens because of extra 2 byte padding. */ clientHello->rl_len = htons ( sizeof ( struct tls1_ssl3_client_hello )-7 ); /* Length for rest of struct */ clientHello->client_handshake = CLIENT_HELLO; clientHello->client_len_pad = 0x00; /* pad */ clientHello->client_len = htons ( sizeof ( struct tls1_ssl3_client_hello )-11 ); /* Length for rest of struct */ if ( ( int ) c2[3] == 49 ) clientHello->client_version = htons ( TLS1_VERSION ); else clientHello->client_version = htons ( SSL3_VERSION ); //clientHello->client_version = htons ( SSL3_VERSION ); /* SSL/TLS version (0x0301) */ //clientHello->random_bytes[] = ''; /* We can leave this blank as we aren't renewing a session */ clientHello->sessionID = SESSIONID; /* opaque SessionID<0..32>, safe to leave as 0 */ clientHello->cipher_len = htons ( CIPHER_LEN ); /* cipher len, 2 bytes per cipher */ //clientHello->CipherSuite = htons(0x0002); /* Cipher to send */ clientHello->compression_len = COMPRESSION_LEN; /* compression length */ clientHello->compression_method = COMPRESSION_TYPE; /* 0-255 safe to leave null or 00 */ /* todo: cleaner way to generate random() */ for ( i=0; i<sizeof ( clientHello->random_bytes ); i++ ) { clientHello->random_bytes[i] = random(); } i=0; /* We copy our items off struct one by one to ensure correct alignment at run time. */ off=p; memcpy ( off, &clientHello->rl_content_type, sizeof ( clientHello->rl_content_type ) ); off += sizeof ( clientHello->rl_content_type ); memcpy ( off, &clientHello->rl_client_version, sizeof ( clientHello->rl_client_version ) ); off += sizeof ( clientHello->rl_client_version ); memcpy ( off, &clientHello->rl_len, sizeof ( clientHello->rl_len ) ); off += sizeof ( clientHello->rl_len ); memcpy ( off, &clientHello->client_handshake, sizeof ( clientHello->client_handshake ) ); off += sizeof ( clientHello->client_handshake ); memcpy ( off, &clientHello->client_len_pad, sizeof ( clientHello->client_len_pad ) ); off += sizeof ( clientHello->client_len_pad ); memcpy ( off, &clientHello->client_len, sizeof ( clientHello->client_len ) ); off += sizeof ( clientHello->client_len ); memcpy ( off, &clientHello->client_version, sizeof ( clientHello->client_version ) ); off += sizeof ( clientHello->client_version ); memcpy ( off, &clientHello->random_bytes, sizeof ( clientHello->random_bytes ) ); off += sizeof ( clientHello->random_bytes ); memcpy ( off, &clientHello->sessionID, sizeof ( clientHello->sessionID ) ); off += sizeof ( clientHello->sessionID ); memcpy ( off, &clientHello->cipher_len, sizeof ( clientHello->cipher_len ) ); off += sizeof ( clientHello->cipher_len ); memcpy ( off, &clientHello->CipherSuite, sizeof ( clientHello->CipherSuite ) ); off += sizeof ( clientHello->CipherSuite ); memcpy ( off, &clientHello->compression_len, sizeof ( clientHello->compression_len ) ); off += sizeof ( clientHello->compression_len ); memcpy ( off, &clientHello->compression_method, sizeof ( clientHello->compression_method ) ); free ( clientHello ); return p; }