void DSSL_SessionDeInit( DSSL_Session* s ) { #ifdef NM_TRACE_SSL_SESSIONS DEBUG_TRACE0( "DSSL_SessionDeInit\n" ); #endif if( s->env ) DSSL_EnvOnSessionClosing( s->env, s ); dssl_decoder_stack_deinit( &s->c_dec ); dssl_decoder_stack_deinit( &s->s_dec ); ssls_free_extension_data(s); EVP_MD_CTX_cleanup( &s->handshake_digest_md5 ); EVP_MD_CTX_cleanup( &s->handshake_digest_sha ); }
static int ssl3_decode_client_hello( DSSL_Session* sess, u_char* data, uint32_t len ) { u_char* org_data = data; int t_len = 0; /* record the handshake start time */ sess->handshake_start = sess->last_packet->pcap_header.ts; if( data[0] != 3 || data[1] > 3) return NM_ERROR( DSSL_E_SSL_UNKNOWN_VERSION ); /* 2 bytes client version */ sess->client_version = MAKE_UINT16( data[0], data[1] ); ssls_set_session_version( sess, MAKE_UINT16( data[0], data[1] ) ); data+= 2; /* make sure */ if( data + 32 > org_data + len ) return NM_ERROR( DSSL_E_SSL_INVALID_RECORD_LENGTH ); /* 32 bytes ClientRandom */ memcpy( sess->client_random, data, 32 ); data+= 32; DEBUG_TRACE_BUF("client_random", sess->client_random, 32); /* check session ID length */ if( data[0] > 32 ) return NM_ERROR( DSSL_E_SSL_PROTOCOL_ERROR ); if( data[0] > 0 ) { /* Session ID set */ if( data + data[0] > org_data + len ) return NM_ERROR( DSSL_E_SSL_INVALID_RECORD_LENGTH ); memcpy( sess->session_id, data+1, data[0] ); sess->flags |= SSF_CLIENT_SESSION_ID_SET; data += data[0] + 1; } else { /* no Session ID */ sess->flags &= ~SSF_CLIENT_SESSION_ID_SET; ++data; } /* Cypher Suites */ if(data + 1 >= org_data + len) return NM_ERROR( DSSL_E_SSL_INVALID_RECORD_LENGTH ); t_len = MAKE_UINT16(data[0], data[1]) + 2; /* cypher suites + cypher sute length size */ data += t_len; /* skip cypher suites */ /* Compression Method */ if(data >= org_data + len) return NM_ERROR( DSSL_E_SSL_INVALID_RECORD_LENGTH ); if(data + data[0] + 1 > org_data + len) return NM_ERROR( DSSL_E_SSL_INVALID_RECORD_LENGTH ); t_len = data[0] + 1; data += t_len; /* skip compression methods */ /* Extensions */ /* clear all previous extension fields */ ssls_free_extension_data(sess); if(data >= org_data + len) return DSSL_RC_OK; if(data + 2 > org_data + len) return NM_ERROR( DSSL_E_SSL_INVALID_RECORD_LENGTH ); t_len = MAKE_UINT16(data[0], data[1]); data += 2; /* positon at the beginning of the first extension record, if any*/ while(t_len >= 4) { int ext_type = MAKE_UINT16(data[0], data[1]); /* extension type */ int ext_len = MAKE_UINT16(data[2], data[3]); #ifdef NM_TRACE_SSL_HANDSHAKE DEBUG_TRACE2( "\nSSL extension: %s len: %d", SSL3_ExtensionTypeToString( ext_type ), ext_len ); #endif /* TLS Session Ticket */ if( ext_type == 0x0023) { /* non empty ticket passed, store it */ if(ext_len > 0) { sess->flags |= SSF_TLS_SESSION_TICKET_SET; sess->session_ticket = (u_char*) malloc(ext_len); if(sess->session_ticket == NULL) return NM_ERROR(DSSL_E_OUT_OF_MEMORY); memcpy(sess->session_ticket, data+4, ext_len); sess->session_ticket_len = ext_len; } } data += ext_len + 4; if(data > org_data + len) return NM_ERROR(DSSL_E_SSL_INVALID_RECORD_LENGTH); t_len -= ext_len + 4; } return DSSL_RC_OK; }