Beispiel #1
0
int dssl_decompress( u_char compr_method, void* compr_state, u_char* in_data, uint32_t in_len,
                     u_char* out_data, uint32_t* out_len )
{
    int rc = DSSL_RC_OK;
    z_stream * zs = (z_stream*) compr_state;
    /* right now only DEFLATE method is supported */
    if( compr_method != COMPRESSION_DEFLATE ) return NM_ERROR( DSSL_E_UNSUPPORTED_COMPRESSION );

    _ASSERT( zs );

    zs->next_in = in_data;
    zs->avail_in = in_len;
    zs->next_out = out_data;
    zs->avail_out = *out_len;

    if( in_len > 0 )
    {
        int zlib_rc = inflate( zs, Z_SYNC_FLUSH );
        if( zlib_rc != Z_OK ) {
            rc = NM_ERROR( DSSL_E_DECOMPRESSION_ERROR );
        }
    }

    if( rc == DSSL_RC_OK )
    {
        (*out_len) = (*out_len) - zs->avail_out;
    }

    return rc;

}
Beispiel #2
0
int ssl3_alert_decoder( void* decoder_stack, NM_PacketDir dir,
		u_char* data, uint32_t len, uint32_t* processed )
{
	dssl_decoder_stack* stack = (dssl_decoder_stack*) decoder_stack;

	UNUSED_PARAM(dir);

	if( len != 2 ) return NM_ERROR( NM_ERROR( DSSL_E_SSL_INVALID_RECORD_LENGTH ) );

	if( data[0] == 2 )
	{
		stack->state = SS_FatalAlert;
	}

	/* Close notify? */
	if( data[1] == 0 )
	{
		stack->state = SS_SeenCloseNotify;
	}

#ifdef NM_TRACE_SSL_RECORD
	DEBUG_TRACE2( "\nAlert received: %s (%d)", 
			( (stack->state == SS_FatalAlert) ? "fatal alert" : 
			((stack->state == SS_SeenCloseNotify) ? "close_notify alert" : "unknown alert")), 
			(int) MAKE_UINT16( data[0], data[1] ) );
#endif

		(*processed) = len;
	return DSSL_RC_OK;
}
Beispiel #3
0
int ssl2_PRF( const u_char* secret, uint32_t secret_len,
		const u_char* challenge, uint32_t challenge_len, 
		const u_char* conn_id, uint32_t conn_id_len,
		u_char* out, uint32_t out_len )
{
	u_char c= '0';
	int repeat = 0;
	int i = 0;
	const EVP_MD *md5 = NULL;
	EVP_MD_CTX *ctx;

	md5 = EVP_md5();

	if( !out ) return NM_ERROR( DSSL_E_INVALID_PARAMETER );
	if( out_len % EVP_MD_size(md5) != 0 ) { return NM_ERROR( DSSL_E_INVALID_PARAMETER ); }

	repeat = out_len / EVP_MD_size(md5);
	ctx = EVP_MD_CTX_create();
	EVP_MD_CTX_init( ctx );
	for( i = 0; i < repeat; i++ )
	{
		EVP_DigestInit_ex( ctx, md5, NULL );
		EVP_DigestUpdate( ctx, secret, secret_len );
		EVP_DigestUpdate( ctx, &c, 1);
		c++; /* '0', '1', etc. */
		EVP_DigestUpdate( ctx, challenge, challenge_len );
		EVP_DigestUpdate( ctx, conn_id, conn_id_len );
		EVP_DigestFinal_ex( ctx, out, NULL );
		out += EVP_MD_size( md5 );
	}

	EVP_MD_CTX_destroy( ctx );
	return DSSL_RC_OK;
}
Beispiel #4
0
int ssl_detect_client_hello_version( u_char* data, uint32_t len, uint16_t* ver )
{
	int rc = DSSL_RC_OK;

	_ASSERT( ver != NULL );
	_ASSERT( data != NULL );

	/* SSL v2 header can be sent even by never clients */
	if( data[0] & 0x80 && len >= 3 && data[2] == SSL2_MT_CLIENT_HELLO )
	{
		*ver = MAKE_UINT16( data[3], data[4] );
	}
	else if ( data[0] == SSL3_RT_HANDSHAKE && len > 11 && 
		data[1] == SSL3_VERSION_MAJOR && data[5] == SSL3_MT_CLIENT_HELLO )
	{
		uint16_t client_hello_ver = MAKE_UINT16( data[9], data[10] );
		*ver = MAKE_UINT16( data[1], data[2] );

		if( *ver > client_hello_ver ) rc = NM_ERROR( DSSL_E_SSL_PROTOCOL_ERROR );
	}
	else
	{
		rc = NM_ERROR( DSSL_E_SSL_UNKNOWN_VERSION );
	}

	return rc;
}
Beispiel #5
0
int ssl_detect_server_hello_version( u_char* data, uint32_t len, uint16_t* ver )
{
	int rc = DSSL_RC_OK;

	_ASSERT( ver != NULL );
	_ASSERT( data != NULL );
	
	if( data[0] & 0x80 && len >= SSL20_SERVER_HELLO_MIN_LEN && data[2] == SSL2_MT_SERVER_HELLO )
	{
		*ver = MAKE_UINT16( data[5], data[6] );
	}
	else if( data[0] == SSL3_RT_HANDSHAKE && len > 11 && 
		data[1] == SSL3_VERSION_MAJOR && data[5] == SSL3_MT_SERVER_HELLO )
	{
		uint16_t sever_hello_ver = MAKE_UINT16( data[9], data[10] );
		*ver = MAKE_UINT16( data[1], data[2] );

		if( *ver > sever_hello_ver ) rc = NM_ERROR( DSSL_E_SSL_PROTOCOL_ERROR );
	}
	else if( data[0] == SSL3_RT_ALERT && len == 7 && data[1] == SSL3_VERSION_MAJOR &&
			MAKE_UINT16( data[3], data[4] ) == 2 )
	{
		/* this is an SSL3 Alert message - the server didn't like this session */
		*ver = MAKE_UINT16( data[1], data[2] );
	}
	else
	{
		rc = NM_ERROR( DSSL_E_SSL_UNKNOWN_VERSION );
	}

	return rc;
}
Beispiel #6
0
static int ssl3_decode_new_session_ticket(DSSL_Session* sess, u_char* data, uint32_t len )
{
	uint16_t sz = 0;
	if(len < 6) return NM_ERROR(DSSL_E_SSL_INVALID_RECORD_LENGTH);

	sz = MAKE_UINT16(data[4], data[5]);

	if(len != sz + 6) return NM_ERROR(DSSL_E_SSL_PROTOCOL_ERROR);

	return ssls_store_new_ticket( sess, data + 6, sz );
}
Beispiel #7
0
int tls12_PRF( const EVP_MD *md, const u_char* secret, uint32_t secret_len, const char* label, 
		u_char* random1, uint32_t random1_len, u_char* random2, uint32_t random2_len,
		u_char *out, uint32_t out_len )
{
	uint32_t len;
	uint32_t i;
	const u_char *S1,*S2;
	u_char* out_tmp;
	u_char* seed;
	uint32_t seed_len;
	u_char* p;

	if( !label || !out || out_len == 0 ) { _ASSERT( FALSE); return NM_ERROR( DSSL_E_INVALID_PARAMETER ); }
	
	/* 'sha256' is the default for TLS 1.2.
	 * also, do not allow anything less secure...
	 */
	if ( !md )
		md = EVP_sha256();
	else if ( EVP_MD_size( md ) < EVP_MD_size( EVP_sha256() ) )
		md = EVP_sha256();

	/* allocate a temporary buffer for second output stream */
	out_tmp = (u_char*) malloc( out_len );
	if( !out_tmp ) return NM_ERROR( DSSL_E_OUT_OF_MEMORY );

	/* allocate and initialize the seed */
	seed_len = (uint32_t)strlen( label ) + random1_len + random2_len;
	seed = (u_char*) malloc( seed_len );
	if( !seed ) 
	{
		free( out_tmp );
		return NM_ERROR( DSSL_E_OUT_OF_MEMORY );
	}

	p = seed;
	memcpy( p, label, strlen( label ) ); p+= strlen( label );
	memcpy( p, random1, random1_len ); p+= random1_len;
	memcpy( p, random2, random2_len );

	DEBUG_TRACE_BUF("secret", secret, secret_len);
	DEBUG_TRACE_BUF("seed", seed, seed_len);
	tls1_P_hash( md, secret, secret_len, seed, seed_len, out_tmp, out_len );
	DEBUG_TRACE_BUF("result", out_tmp, out_len);
	
	DEBUG_TRACE3( "\nsecret(%d) + seed(%u)=out(%u)\n", secret_len, seed_len, out_len);

	for( i=0; i < out_len; i++ ) out[i] = out_tmp[i];

	free( seed );
	free( out_tmp );

	return DSSL_RC_OK;
}
Beispiel #8
0
int ssls_get_decrypt_buffer( DSSL_Session* sess, u_char** data, uint32_t len )
{
	if(!data || !len ) return NM_ERROR( DSSL_E_INVALID_PARAMETER );

	if( len > sizeof(sess->env->decrypt_buffer))
	{
		_ASSERT( FALSE ); /*decrypt_buffer is supposed to fit the biggest possible SSL record!*/
		return NM_ERROR( DSSL_E_OUT_OF_MEMORY );
	}

	(*data) = sess->env->decrypt_buffer;
	return DSSL_RC_OK;
}
Beispiel #9
0
int ssls_get_decompress_buffer( DSSL_Session* sess, u_char** data, uint32_t len )
{
	if(!data || !len ) return NM_ERROR( DSSL_E_INVALID_PARAMETER );

	if( len > sizeof(sess->env->decompress_buffer))
	{
		_ASSERT( FALSE ); /*decompressed record can not exceed 2^14 + 1024 bytes !*/
		return NM_ERROR( DSSL_E_OUT_OF_MEMORY );
	}

	(*data) = sess->env->decompress_buffer;
	return DSSL_RC_OK;
}
Beispiel #10
0
int tls1_PRF( const u_char* secret, uint32_t secret_len, const char* label, 
		u_char* random1, uint32_t random1_len, u_char* random2, uint32_t random2_len,
		u_char *out, uint32_t out_len )
{
	uint32_t len;
	uint32_t i;
	const u_char *S1,*S2;
	u_char* out_tmp;
	u_char* seed;
	uint32_t seed_len;
	u_char* p;

	if( !label || !out || out_len == 0 ) { _ASSERT( FALSE); return NM_ERROR( DSSL_E_INVALID_PARAMETER ); }

	/* allocate a temporary buffer for second output stream */
	out_tmp = (u_char*) malloc( out_len );
	if( !out_tmp ) return NM_ERROR( DSSL_E_OUT_OF_MEMORY );

	/* allocate and initialize the seed */
	seed_len = (uint32_t)strlen( label ) + random1_len + random2_len;
	seed = (u_char*) malloc( seed_len );
	if( !seed ) 
	{
		free( out_tmp );
		return NM_ERROR( DSSL_E_OUT_OF_MEMORY );
	}

	p = seed;
	memcpy( p, label, strlen( label ) ); p+= strlen( label );
	memcpy( p, random1, random1_len ); p+= random1_len;
	memcpy( p, random2, random2_len );

	/* split the secret into halves */
	len = (secret_len / 2) + (secret_len % 2);
	S1 = secret;
	S2 = secret + secret_len - len;

	DEBUG_TRACE_BUF("secret", secret, secret_len);
	DEBUG_TRACE_BUF("seed", seed, seed_len);
	tls1_P_hash( EVP_md5(), S1, len, seed, seed_len, out, out_len );
	tls1_P_hash( EVP_sha1(), S2, len, seed, seed_len, out_tmp, out_len );

	for( i=0; i < out_len; i++ ) out[i] ^= out_tmp[i];

	DEBUG_TRACE_BUF("result", out, out_len);

	free( seed );
	free( out_tmp );

	return DSSL_RC_OK;
}
Beispiel #11
0
/* ========== SERVER-VERIFY ========== */
static int ssl2_decode_server_verify(  DSSL_Session* sess, u_char* data, uint32_t len, uint32_t* processed )
{	
	_ASSERT( processed && data && sess );

	if( len != sess->client_challenge_len ) { return NM_ERROR( DSSL_E_SSL_INVALID_RECORD_LENGTH ); }

	if( memcmp( data, sess->client_random, sess->client_challenge_len ) != 0 )
	{
		return NM_ERROR( DSSL_E_SSL2_BAD_SERVER_VERIFY ); 
	}

	*processed = len;

	return DSSL_RC_OK;
}
Beispiel #12
0
/* ========== CLIENT-FINISHED ========== */
static int ssl2_decode_client_finished(  DSSL_Session* sess, u_char* data, uint32_t len, uint32_t* processed )
{
	_ASSERT( processed && data && sess );

	if( len != sess->server_connection_id_len ) { return NM_ERROR( DSSL_E_SSL_INVALID_RECORD_LENGTH ); }

	if( memcmp( data, sess->server_random, sess->server_connection_id_len ) != 0 )
	{
		return NM_ERROR( DSSL_E_SSL2_BAD_CLIENT_FINISHED ); 
	}

	*processed = len;

	return DSSL_RC_OK;
}
/* TCP reassembler callback function for SSL sessions */
static int OnNewSSLPacket( struct _TcpStream* stream, DSSL_Pkt* pkt )
{
	TcpSession* sess = NULL;
	DSSL_Session* ssl_sess = NULL;
	u_char* data = NULL;
	uint32_t len = 0;
	NM_PacketDir dir = ePacketDirInvalid;
	int rc = DSSL_RC_OK;

	_ASSERT( stream );
	_ASSERT( pkt );

	sess = stream->session;
	_ASSERT( sess );

	ssl_sess = sess->ssl_session;
	if( !ssl_sess )
	{
		_ASSERT( FALSE );
		return NM_ERROR( DSSL_E_UNSPECIFIED_ERROR );
	}

	data = PKT_TCP_PAYLOAD( pkt );
	len = pkt->data_len;
	dir = SessionGetPacketDirection( sess, pkt );

	rc = DSSL_SessionProcessData( ssl_sess, dir, data, len );

	if( ssl_sess->flags & ( SSF_CLOSE_NOTIFY_RECEIVED | SSF_FATAL_ALERT_RECEIVED ) )
	{
		sess->closing = 1;
	}

	return rc;
}
int CapEnvSetSSL_ServerInfo( CapEnv* env, struct in_addr* ip_address, uint16_t port, 
			const char* certfile, const char* keyfile, const char* password )
{
	if( env->ssl_env == NULL ) return NM_ERROR( DSSL_E_INVALID_PARAMETER );

	return DSSL_EnvSetServerInfo( env->ssl_env, ip_address, port, certfile, keyfile, password );
}
Beispiel #15
0
int ssl3_change_cipher_spec_decoder( void* decoder_stack, NM_PacketDir dir,
		u_char* data, uint32_t len, uint32_t* processed )
{
	dssl_decoder_stack* stack = (dssl_decoder_stack*) decoder_stack;

	/* unused parameters */
	dir;

	/* check packet data to comply to CSS protocol */
	if( len != 1 ) return NM_ERROR( NM_ERROR( DSSL_E_SSL_INVALID_RECORD_LENGTH ) );
	if(data[0] != 1 ) return NM_ERROR( DSSL_E_SSL_PROTOCOL_ERROR );

	*processed = 1;

	return dssl_decoder_stack_flip_cipher( stack );
}
Beispiel #16
0
int ssls_lookup_session( DSSL_Session* sess )
{
	DSSL_SessionKeyData* sess_data = NULL;

	_ASSERT( sess );
	_ASSERT( sess->env );
	
	if( sess->env->session_cache )
	{
		sess_data = dssl_SessionKT_Find( sess->env->session_cache, sess->session_id );
	}

	if( !sess_data ) return NM_ERROR( DSSL_E_SSL_SESSION_NOT_IN_CACHE );

	dssl_SessionKT_AddRef( sess_data );
	memcpy( sess->master_secret, sess_data->master_secret, SSL3_MASTER_SECRET_SIZE );
	sess->master_key_len = sess_data->master_secret_len;

	if(sess->version == SSL2_VERSION)
	{
		memcpy(sess->ssl2_key_arg, sess_data->ssl2_key_arg, SSL2_KEYARG_MAX_LEN );
		sess->ssl2_key_arg_len = sess_data->ssl2_key_arg_length;
		sess->cipher_suite = sess_data->ssl2_cipher_suite;
	}

	return DSSL_RC_OK;
}
Beispiel #17
0
int dssl_decoder_process( dssl_decoder* d, NM_PacketDir dir, u_char* data, uint32_t len )
{
	uint32_t processed = 0;
	int rc = DSSL_RC_OK;

	if( !d->handler ) return NM_ERROR( DSSL_E_NOT_IMPL );
        fprintf(stderr, "\ntesting testing: %d", rc);

	if( d->buff_used_len > 0 ) 
	{
		rc = dssl_decoder_add_to_buffer( d, data, len );
		fprintf(stderr, "\ndssl dssl_decoder_add_to_buffer: %d", rc);

		if( rc == DSSL_RC_OK )
		{
			data = d->buff;
			len = d->buff_used_len; 
		}
	}

	while( rc == DSSL_RC_OK && processed < len )
	{
		uint32_t p = 0;
        fprintf(stderr, "\ntesting testing: %d", rc);
		rc = d->handler( d->handler_data, dir, data + processed, len - processed, &p );
		processed += p;

        fprintf(stderr, "\ntesting testing: %d", rc);
		/* can't be all ok and no data processed */
		if( p == 0 && rc == DSSL_RC_OK ) { rc = NM_ERROR( DSSL_E_UNSPECIFIED_ERROR ); }
		fprintf(stderr, "\nssl d->handler p==%p rc = %d\n",p, rc);
	}

	if( !NM_IS_FAILED( rc ) )
	{
		if( d->buff_used_len > 0 )
		{
			rc = dssl_decoder_shift_buffer( d, processed );
		}
		else if( processed < len )
		{
			rc = dssl_decoder_add_to_buffer( d, data + processed, len - processed );
		}
	}

	return rc;
}
Beispiel #18
0
int DSSL_SessionProcessData( DSSL_Session* sess, NM_PacketDir dir, u_char* data, uint32_t len )
{
	int rc = DSSL_RC_OK;
	dssl_decoder_stack* dec = NULL;

	if( dir == ePacketDirInvalid ) return NM_ERROR( DSSL_E_INVALID_PARAMETER );

	dec = (dir == ePacketDirFromClient) ? &sess->c_dec : &sess->s_dec;

	if( !sslc_is_decoder_stack_set( dec ) )
	{
		uint16_t ver = 0;
		int is_client = (dir == ePacketDirFromClient);
		if( is_client )
		{
			rc = ssl_detect_client_hello_version( data, len, &ver );
		}
		else
		{
			rc = ssl_detect_server_hello_version( data, len, &ver );
			/* update the client decoder after the server have declared the actual version 
			of the session */
			DEBUG_TRACE2("DSSL_SessionProcessData - sess->version: 0x%02X, ver is: 0x%02X\n", sess->version, ver);
			if( rc == DSSL_RC_OK && sess->version != ver )
			{
				sess->c_dec.version = ver;
				rc = dssl_decoder_stack_set( &sess->c_dec, sess, ver, 1 );
			}
			ssls_set_session_version( sess, ver );
		}

		if( rc == DSSL_RC_OK ) 
		{
			dec->version = ver;
			rc = dssl_decoder_stack_set( dec, sess, ver, is_client );
		}
	}

	if( rc == DSSL_RC_OK ) rc = dssl_decoder_stack_process( dec, dir, data, len );

	/* check if a session with a first-time automapped key failed */
	if( NM_IS_FAILED( rc ) && sess->flags & SSF_TEST_SSL_KEY )
	{
		if(sess->event_callback)
		{
			(*sess->event_callback)( sess->user_data, eSslMappedKeyFailed, sess->ssl_si );
		}
		DSSL_MoveServerToMissingKeyList( sess->env, sess->ssl_si );
		sess->ssl_si = NULL;
	}

	if( NM_IS_FAILED( rc ) && sess->error_callback && rc != DSSL_E_SSL_SERVER_KEY_UNKNOWN )
	{
		sess->error_callback( sess->user_data, rc );
	}

	return rc;
}
Beispiel #19
0
int dssl_compr_init( u_char compr_method, void** compr_state )
{
    int rc = DSSL_RC_OK;

    switch( compr_method )
    {
    case 0:
        break;
    case COMPRESSION_DEFLATE:
    {
        z_stream * zs = (z_stream*) malloc( sizeof(z_stream) );
        int err = Z_OK;

        zs->zalloc = Z_NULL;
        zs->zfree = Z_NULL;
        zs->opaque = Z_NULL;
        zs->next_in = Z_NULL;
        zs->next_out = Z_NULL;
        zs->avail_in = 0;
        zs->avail_out = 0;
        err = inflateInit(zs);

        if( err != Z_OK )
        {
            free( zs );
            rc = NM_ERROR( DSSL_E_DECOMPRESSION_ERROR );
        }
        else
        {
            rc = DSSL_RC_OK;
            (*compr_state) = zs;
        }
    }
    break;

    default:
        rc = NM_ERROR( DSSL_E_UNSUPPORTED_COMPRESSION ); /* unknown compression method */
        break;
    }

    return rc;
}
Beispiel #20
0
int ssls_decode_master_secret( DSSL_Session* sess )
{
	EVP_MD *md;
	DSSL_CipherSuite* suite = NULL;

	switch( sess->version )
	{
	case SSL3_VERSION:
		return ssl3_PRF( sess->PMS, SSL_MAX_MASTER_KEY_LENGTH, 
					sess->client_random, SSL3_RANDOM_SIZE, 
					sess->server_random, SSL3_RANDOM_SIZE,
					sess->master_secret, sizeof( sess->master_secret ) );

	case TLS1_VERSION:
		return tls1_PRF( sess->PMS, SSL_MAX_MASTER_KEY_LENGTH, 
					"master secret", 
					sess->client_random, SSL3_RANDOM_SIZE, 
					sess->server_random, SSL3_RANDOM_SIZE,
					sess->master_secret, sizeof( sess->master_secret ) );

	default:
		DEBUG_TRACE1("ssls_decode_master_secret - version: 0x%02X\n", sess->version);
		if (sess->version == TLS1_1_VERSION) 
		{
			DEBUG_TRACE0("ssls_decode_master_secret - supported for 1.1\n");

			return tls1_PRF( sess->PMS, SSL_MAX_MASTER_KEY_LENGTH, 
					"master secret", 
					sess->client_random, SSL3_RANDOM_SIZE, 
					sess->server_random, SSL3_RANDOM_SIZE,
					sess->master_secret, sizeof( sess->master_secret ) );
		}
		else if (sess->version == TLS1_2_VERSION) 
		{
			DEBUG_TRACE0("ssls_decode_master_secret - supported for 1.2\n");

			/*
			suite = DSSL_GetSSL3CipherSuite( sess->cipher_suite );
			md=EVP_get_digestbyname(suite->digest);
			*/

			return tls12_PRF( "SHA256"/*suite->digest*/, sess->PMS, SSL_MAX_MASTER_KEY_LENGTH, 
					"master secret", 
					sess->client_random, SSL3_RANDOM_SIZE, 
					sess->server_random, SSL3_RANDOM_SIZE,
					sess->master_secret, sizeof( sess->master_secret ) );
		}
		else
		{
			DEBUG_TRACE0("ssls_decode_master_secret - DSSL_E_NOT_IMPL\n");
			return NM_ERROR( DSSL_E_NOT_IMPL );
		}
	}
}
Beispiel #21
0
int ssls_store_new_ticket(DSSL_Session* sess, u_char* ticket, uint32_t len)
{
	_ASSERT(sess && ticket && len);

	if( sess->env->ticket_cache )
	{
		return dssl_SessionTicketTable_Add( sess->env->ticket_cache, sess, ticket, len );
	}
	else
	{
		_ASSERT( FALSE );
		return NM_ERROR( DSSL_E_UNSPECIFIED_ERROR );
	}
}
Beispiel #22
0
/* First client_hello is a special case, because of SSL v2 compatibility */
int ssl_decode_first_client_hello( DSSL_Session* sess, u_char* data, uint32_t len, uint32_t* processed )
{
	int rc = DSSL_RC_OK;
	
	if( data[0] & 0x80 && len >= 3 && data[2] == SSL2_MT_CLIENT_HELLO )
	{
		int hdrLen = SSL20_CLIENT_HELLO_HDR_LEN;
		uint32_t recLen = len - hdrLen;

		rc = ssl2_decode_handshake( sess, ePacketDirFromClient, data + hdrLen, recLen, processed );

		if( rc == DSSL_RC_OK )
		{
			if( sess->version >= SSL3_VERSION && sess->version <= TLS1_2_VERSION )
			{
				ssl3_init_handshake_digests( sess );
				ssl3_update_handshake_digests( sess, data + hdrLen, recLen );
			}

			*processed += hdrLen;
		}
	}
	else if( data[0] == SSL3_RT_HANDSHAKE && len > 6 && 
		data[1] == SSL3_VERSION_MAJOR && data[5] == SSL3_MT_CLIENT_HELLO )
	{
		uint32_t recLen = 0;
		u_char* org_data;

		data += SSL3_HEADER_LEN;
		recLen = (((int32_t)data[1]) << 16) | (((int32_t)data[2]) << 8) | data[3];
		org_data = data;

		data += SSL3_HANDSHAKE_HEADER_LEN;
		len -= SSL3_HANDSHAKE_HEADER_LEN;
		
		rc = ssl3_decode_client_hello( sess, data, recLen );
		if( rc == DSSL_RC_OK )
		{
			*processed = recLen + SSL3_HANDSHAKE_HEADER_LEN + SSL3_HEADER_LEN;
			ssl3_init_handshake_digests( sess );
			ssl3_update_handshake_digests( sess, org_data, recLen + SSL3_HANDSHAKE_HEADER_LEN );
		}
	}
	else
	{
		rc = NM_ERROR( DSSL_E_SSL_UNKNOWN_VERSION );
	}

	return rc;
}
Beispiel #23
0
int ssls_set_session_version( DSSL_Session* sess, uint16_t ver )
{
	int rc = DSSL_RC_OK;

	sess->version = ver;

	switch( ver )
	{
	case SSL3_VERSION:
		DEBUG_TRACE0("ssls_set_session_version - SSL3_VERSION\n");
		sess->decode_finished_proc = ssl3_decode_finished;
		sess->caclulate_mac_proc  = ssl3_calculate_mac;
		/* convert SSL v2 CHALLENGE to SSL v3+ CLIENT_RANDOM */
		if(sess->flags & SSF_SSLV2_CHALLENGE) 
			ssls_convert_v2challenge(sess);
		break;

	case TLS1_VERSION:
		DEBUG_TRACE0("ssls_set_session_version - TLS1_VERSION\n");
		sess->decode_finished_proc = tls1_decode_finished;
		sess->caclulate_mac_proc = tls1_calculate_mac;
		/* convert SSL v2 CHALLENGE to SSL v3+ CLIENT_RANDOM */
		if(sess->flags & SSF_SSLV2_CHALLENGE) 
			ssls_convert_v2challenge(sess);
		break;

	case SSL2_VERSION:
		DEBUG_TRACE0("ssls_set_session_version - SSL2_VERSION\n");
		sess->decode_finished_proc = NULL;
		sess->caclulate_mac_proc = ssl2_calculate_mac;
		break;

	case TLS1_1_VERSION:
	case TLS1_2_VERSION:
		DEBUG_TRACE0("ssls_set_session_version - TLS1_X_VERSION\n");
		sess->decode_finished_proc = tls1_decode_finished;
		sess->caclulate_mac_proc = tls1_calculate_mac;
		if(sess->flags & SSF_SSLV2_CHALLENGE) 
			ssls_convert_v2challenge(sess);
		break;

	default:
		DEBUG_TRACE0("ssls_set_session_version - unsupported.. \n");
		rc = NM_ERROR( DSSL_E_SSL_UNKNOWN_VERSION );
		break;
	}

	return rc;
}
Beispiel #24
0
static int realloc_buffer( dssl_decoder* d, uint32_t new_len )
{
	/* TODO: add CapEnv-scope buffer management */
	u_char* new_buff = NULL;

	_ASSERT( new_len > 0 );
	_ASSERT( d->buff_len == 0 || new_len > d->buff_len );

	if( d->buff != NULL )
		new_buff = (u_char*) realloc( d->buff, new_len );
	else
		new_buff = (u_char*) malloc( new_len );

	if( new_buff == NULL ) return NM_ERROR( DSSL_E_OUT_OF_MEMORY );

	d->buff_len = new_len;
	d->buff = new_buff;

	return DSSL_RC_OK;
}
Beispiel #25
0
/* ========== SERVER-FINISHED ========== */
static int ssl2_decode_server_finished(  DSSL_Session* sess, u_char* data, uint32_t len, uint32_t* processed )
{
	_ASSERT( processed && data && sess );

	if( len > sizeof( sess->session_id ) ) { return NM_ERROR( DSSL_E_SSL_INVALID_RECORD_LENGTH ); }

	/* set new session ID and add the session to the session cache */
	memset( sess->session_id, 0, sizeof(sess->session_id ) );
	memcpy( sess->session_id, data, len );
	ssls_store_session( sess );

	/* handshake is over, time to switch to application data protocol */
	sess->c_dec.state = SS_Established;
	sess->s_dec.state = SS_Established;
	ssls_handshake_done( sess );

	*processed = len;

	return DSSL_RC_OK;
}
int ssl3_PRF( const u_char* secret, uint32_t secret_len, 
		const u_char* random1, uint32_t random1_len,
		const u_char* random2, uint32_t random2_len,
		u_char* out, uint32_t out_len )
{
	MD5_CTX md5;
	SHA_CTX sha;
	u_char buf[20];
	uint32_t off;
	u_char i;

	if( !out ) return NM_ERROR( DSSL_E_INVALID_PARAMETER );

	for( off=0, i = 1; off < out_len; off+=16, ++i )
	{
		u_char md5_buf[16];
		uint32_t cnt;
		uint32_t j;

		MD5_Init(&md5);
		SHA1_Init(&sha);

		/* salt: A, BB, CCC,  ... */
		for( j=0; j < i; j++ ) buf[j]='A' + (i-1);

		SHA1_Update( &sha, buf, i );
		if( secret ) SHA1_Update( &sha, secret, secret_len );
		SHA1_Update( &sha, random1, random1_len );
		SHA1_Update( &sha, random2, random2_len );
		SHA1_Final( buf, &sha );

		MD5_Update( &md5, secret, secret_len );
		MD5_Update( &md5, buf, 20 );
		MD5_Final( md5_buf, &md5 );

		cnt = out_len - off < 16 ? out_len - off : 16;
		memcpy( out + off, md5_buf, cnt );
	}

	return DSSL_RC_OK;
}
Beispiel #27
0
int ssls_decode_master_secret( DSSL_Session* sess )
{
	switch( sess->version )
	{
	case SSL3_VERSION:
		return ssl3_PRF( sess->PMS, SSL_MAX_MASTER_KEY_LENGTH, 
					sess->client_random, SSL3_RANDOM_SIZE, 
					sess->server_random, SSL3_RANDOM_SIZE,
					sess->master_secret, sizeof( sess->master_secret ) );

	case TLS1_VERSION:
		return tls1_PRF( sess->PMS, SSL_MAX_MASTER_KEY_LENGTH, 
					"master secret", 
					sess->client_random, SSL3_RANDOM_SIZE, 
					sess->server_random, SSL3_RANDOM_SIZE,
					sess->master_secret, sizeof( sess->master_secret ) );

	default:
		return NM_ERROR( DSSL_E_NOT_IMPL );
	}
}
/*!
 \fn bool NmHsWidget::loadDocML(HbDocumentLoader &loader)
 
 loads layout data and child items from docml file. Must be called after constructor.
 /return true if loading succeeded, otherwise false. False indicates that object is unusable
 */
bool NmHsWidget::loadDocML(HbDocumentLoader &loader)
{
    NM_FUNCTION;
    
    bool ok(false);
    loader.load(KNmHsWidgetDocML, &ok);
    
    if(ok) {
        mMainContainer = static_cast<HbWidget*> (loader.findWidget(KNmHsWidgetMainContainer));  
        mWidgetContainer = static_cast<HbWidget*> (loader.findWidget(KNmHsWidgetContainer));
        mContentContainer = static_cast<HbWidget*> (loader.findWidget(KNmHsWidgetContentContainer));
        mEmptySpaceContainer = static_cast<HbWidget*> (loader.findWidget(KNmHsWidgetEmptySpaceContainer));
        mNoMailsLabel = static_cast<HbLabel*> (loader.findWidget(KNmHsWidgetNoMailsLabel));
        mListView = static_cast<HbListView*> (loader.findWidget(KNmHsWidgetMailListView));
        if (!mMainContainer || !mWidgetContainer || !mContentContainer 
                || !mEmptySpaceContainer || !mNoMailsLabel || !mListView) {
            //something failed in documentloader, no point to continue
            NM_ERROR(1,"NmHsWidget::loadDocML fail @ containers or label");
            ok = false;
        }
    }
    return ok;
}
Beispiel #29
0
int ssls_init_from_tls_ticket( DSSL_Session* sess )
{
	DSSL_SessionTicketData* ticket_data = NULL;

	_ASSERT( sess );
	_ASSERT( sess->env );
	
	if( sess->env->ticket_cache )
	{
		ticket_data = dssl_SessionTicketTable_Find( sess->env->ticket_cache, 
			sess->session_ticket, sess->session_ticket_len );
	}

	if( !ticket_data ) return NM_ERROR( DSSL_E_SSL_SESSION_TICKET_NOT_CACHED );

	memcpy( sess->master_secret, ticket_data->master_secret, SSL3_MASTER_SECRET_SIZE );
	sess->master_key_len = SSL3_MASTER_SECRET_SIZE;

	sess->cipher_suite = ticket_data->cipher_suite;
	sess->version = ticket_data->protocol_version;
	sess->compression_method = ticket_data->compression_method;

	return DSSL_RC_OK;
}
Beispiel #30
0
/* ========== Server Certificate ========== */
static int ssl3_decode_server_certificate( DSSL_Session* sess, u_char* data, uint32_t len )
{
	X509 *x=NULL;
	uint32_t llen = 0;
	int rc = DSSL_RC_OK;

	if( !sess ) return NM_ERROR( DSSL_E_INVALID_PARAMETER );

	/* TBD: skip server certificate check if SSL key has not yet been mapped for this server */
	if( !sess->ssl_si ) return DSSL_RC_OK;

	if( !sess->ssl_si->pkey ) return NM_ERROR( DSSL_E_UNINITIALIZED_ARGUMENT );

	if( len < 3 ) return NM_ERROR( DSSL_E_SSL_INVALID_RECORD_LENGTH );
	
	llen = MAKE_UINT24( data[0], data[1], data[2] );
	data+=3;
	if( llen + 3 != len || llen < 3 ) return NM_ERROR( DSSL_E_SSL_INVALID_CERTIFICATE_RECORD );

	llen = MAKE_UINT24( data[0], data[1], data[2] );
	data+=3;
	if( llen > len ) return NM_ERROR( DSSL_E_SSL_INVALID_CERTIFICATE_LENGTH );

	x = d2i_X509( NULL, &data, llen );
	if( !x ) 
	{
		rc = NM_ERROR( DSSL_E_SSL_BAD_CERTIFICATE );
	}

	if( rc == DSSL_RC_OK && !X509_check_private_key(x, ssls_get_session_private_key( sess )) )
	{
		rc = NM_ERROR( DSSL_E_SSL_CERTIFICATE_KEY_MISMATCH );
	}

	if( x ) X509_free( x );

	return rc;
}