Exemple #1
0
/* ========== Finished, handshake digest routines ========== */
void ssl3_init_handshake_digests( DSSL_Session* sess )
{
	EVP_DigestInit_ex( &sess->handshake_digest_md5, EVP_md5(), NULL );
	EVP_DigestInit_ex( &sess->handshake_digest_sha, EVP_sha1(), NULL );

	if ( sess->version >= TLS1_2_VERSION )
	{
		EVP_MD* digest = NULL;
		DSSL_CipherSuite* suite = sess->dssl_cipher_suite;
		if ( !suite )
			suite = DSSL_GetSSL3CipherSuite( sess->cipher_suite );
		digest = EVP_get_digestbyname( suite->digest );
		/* 'sha256' is the default for TLS 1.2 */
		if ( !digest )
			digest = EVP_sha256();

		if ( digest )
			EVP_DigestInit_ex( &sess->handshake_digest, digest, NULL );
	}
}
Exemple #2
0
int ssls_generate_keys( DSSL_Session* sess )
{
	DSSL_CipherSuite* suite = NULL;
	const EVP_CIPHER* c = NULL;
	const EVP_MD* digest = NULL;
	u_char* c_mac = NULL;
	u_char* c_wk = NULL;
	u_char* c_iv = NULL;
	u_char* s_mac = NULL;
	u_char* s_wk = NULL;
	u_char* s_iv = NULL;
	u_char export_iv_block[EVP_MAX_IV_LENGTH*2];

	u_char export_c_wk[EVP_MAX_KEY_LENGTH];
	u_char export_s_wk[EVP_MAX_KEY_LENGTH];
	
	u_char keyblock[ TLS_MAX_KEYBLOCK_LEN ];
	uint32_t keyblock_len = 0;

	uint32_t iv_len = 0;
	uint32_t wk_len = 0;
	uint32_t digest_len = 0;

	EVP_CIPHER_CTX* c_cipher = NULL;
	EVP_CIPHER_CTX* s_cipher = NULL;

	int rc = DSSL_RC_OK;

	_ASSERT( sess->c_dec.compression_data_new == NULL );
	_ASSERT( sess->s_dec.compression_data_new == NULL );
	_ASSERT( sess->c_dec.compression_method_new == 0 );
	_ASSERT( sess->s_dec.compression_method_new == 0 );

	/* set new compression algorithm */
	if( sess->compression_method != 0 )
	{
		sess->s_dec.compression_method_new = sess->compression_method;
		sess->c_dec.compression_method_new = sess->compression_method;

		dssl_compr_init( sess->s_dec.compression_method_new, &sess->s_dec.compression_data_new );
		dssl_compr_init( sess->c_dec.compression_method_new, &sess->c_dec.compression_data_new );
	}

	if( sess->c_dec.cipher_new != NULL )
	{
//		_ASSERT( FALSE );
		EVP_CIPHER_CTX_cleanup( sess->c_dec.cipher_new );
		free( sess->c_dec.cipher_new );
		sess->c_dec.cipher_new = NULL;
	}

	if( sess->s_dec.cipher_new != NULL )
	{
//		_ASSERT( FALSE );
		EVP_CIPHER_CTX_cleanup( sess->s_dec.cipher_new );
		free( sess->s_dec.cipher_new );
		sess->s_dec.cipher_new = NULL;
	}

	suite = DSSL_GetSSL3CipherSuite( sess->cipher_suite );

	if( !suite ) {
		DEBUG_TRACE0("ssls_generate_keys - failed to find cipher suite\n");
		return NM_ERROR( DSSL_E_SSL_CANNOT_DECRYPT );
	}

	if (suite->enc != NULL && strlen(suite->enc) < 32)
		strcpy(sess->cipher_encoding, suite->enc);

	if (suite->digest != NULL && strlen(suite->digest) < 32)
		strcpy(sess->cipher_digest, suite->digest);

	c = EVP_get_cipherbyname( suite->enc );
	digest = EVP_get_digestbyname( suite->digest );

	/* calculate key length and IV length */
	if( c != NULL ) 
	{
		if( DSSL_CipherSuiteExportable( suite ) )
		{ wk_len = suite->export_key_bits / 8; }
		else 
		{ wk_len = EVP_CIPHER_key_length( c ); }

		iv_len = EVP_CIPHER_iv_length( c );
	}
	if( digest != NULL ) digest_len = EVP_MD_size( digest );

	/* calculate total keyblock length */
	keyblock_len = (wk_len + digest_len + iv_len)*2;
	if( !keyblock_len ) return DSSL_RC_OK;

	if( sess->version == TLS1_VERSION || sess->version == TLS1_1_VERSION)
	{
		DEBUG_TRACE0("ssls_generate_keys - calling tls1_PRF\n");
		rc = tls1_PRF( sess->master_secret, sizeof( sess->master_secret ), 
					"key expansion", 
					sess->server_random, SSL3_RANDOM_SIZE,
					sess->client_random, SSL3_RANDOM_SIZE,
					keyblock, keyblock_len );
	}
	else if( sess->version == TLS1_2_VERSION)
	{
		DEBUG_TRACE0("ssls_generate_keys - calling tls12_PRF\n");
		rc = tls12_PRF( "SHA256"/*sess->cipher_digest*/, sess->master_secret, sizeof( sess->master_secret ), 
					"key expansion", 
					sess->server_random, SSL3_RANDOM_SIZE,
					sess->client_random, SSL3_RANDOM_SIZE,
					keyblock, keyblock_len );
	}
	else
	{
		DEBUG_TRACE0("ssls_generate_keys - calling ssl3_PRF\n");
		rc = ssl3_PRF( sess->master_secret, sizeof( sess->master_secret ),
					sess->server_random, SSL3_RANDOM_SIZE,
					sess->client_random, SSL3_RANDOM_SIZE,
					keyblock, keyblock_len );
	}

	/* init keying material pointers */
	if( rc == DSSL_RC_OK )
	{
		u_char* p = keyblock;

		if( digest_len )
		{
			c_mac = p; p+= digest_len;
			s_mac = p; p+= digest_len;
		}

		if( c != NULL )
		{
			c_wk = p; p+= wk_len;
			s_wk = p; p+= wk_len;

			/* generate final server and client write keys for exportable ciphers */
			if( DSSL_CipherSuiteExportable( suite ) )
			{
				int final_wk_len =  EVP_CIPHER_key_length( c );

				if( sess->version == TLS1_VERSION || sess->version == TLS1_1_VERSION )
				{
					DEBUG_TRACE0("ssls_generate_keys - calling tls1_PRF (2)\n");

					tls1_PRF( c_wk, wk_len, "client write key", 
							sess->client_random, SSL3_RANDOM_SIZE,
							sess->server_random, SSL3_RANDOM_SIZE,
							export_c_wk, final_wk_len );
					
					tls1_PRF( s_wk, wk_len, "server write key", 
							sess->client_random, SSL3_RANDOM_SIZE,
							sess->server_random, SSL3_RANDOM_SIZE,
							export_s_wk, final_wk_len );
				}
				else if( sess->version == TLS1_2_VERSION)
				{
					DEBUG_TRACE1("ssls_generate_keys - calling tls12_PRF (2) - sess->cipher_digest: %s\n", sess->cipher_digest);

					tls12_PRF( "SHA256"/*sess->cipher_digest*/,c_wk, wk_len, "client write key", 
							sess->client_random, SSL3_RANDOM_SIZE,
							sess->server_random, SSL3_RANDOM_SIZE,
							export_c_wk, final_wk_len );
					
					tls12_PRF( "SHA256"/*sess->cipher_digest*/,s_wk, wk_len, "server write key", 
							sess->client_random, SSL3_RANDOM_SIZE,
							sess->server_random, SSL3_RANDOM_SIZE,
							export_s_wk, final_wk_len );
				}
				else
				{
					MD5_CTX md5;
					DEBUG_TRACE0("ssls_generate_keys - MD5_CTX handling\n");

					_ASSERT( sess->version == SSL3_VERSION );
					MD5_Init( &md5 );
					MD5_Update( &md5, c_wk, wk_len );
					MD5_Update( &md5, sess->client_random, SSL3_RANDOM_SIZE );
					MD5_Update( &md5, sess->server_random, SSL3_RANDOM_SIZE );
					MD5_Final( export_c_wk, &md5 );

					MD5_Init( &md5 );
					MD5_Update( &md5, s_wk, wk_len );
					MD5_Update( &md5, sess->server_random, SSL3_RANDOM_SIZE );
					MD5_Update( &md5, sess->client_random, SSL3_RANDOM_SIZE );
					MD5_Final( export_s_wk, &md5 );

				}
				c_wk = export_c_wk;
				s_wk = export_s_wk;
				wk_len = final_wk_len;
			}
		}
		
		if( iv_len )
		{
			if( DSSL_CipherSuiteExportable( suite ) )
			{
				if( sess->version == TLS1_VERSION || sess->version == TLS1_1_VERSION )
				{
					DEBUG_TRACE0("ssls_generate_keys - calling tls1_PRF (3)\n");

					tls1_PRF( NULL, 0, "IV block",
							sess->client_random, SSL3_RANDOM_SIZE, 
							sess->server_random, SSL3_RANDOM_SIZE,
							export_iv_block, iv_len*2 );
				}
				else if( sess->version == TLS1_2_VERSION)
				{
					DEBUG_TRACE1("ssls_generate_keys - calling tls12_PRF (3) - sess->cipher_digest: %s\n", sess->cipher_digest);

					tls12_PRF( "SHA256"/*sess->cipher_digest*/, NULL, 0, "IV block",
							sess->client_random, SSL3_RANDOM_SIZE, 
							sess->server_random, SSL3_RANDOM_SIZE,
							export_iv_block, iv_len*2 );
				}
				else
				{
					MD5_CTX md5;
					DEBUG_TRACE0("ssls_generate_keys - MD5_CTX handling (2)\n");

					_ASSERT( sess->version == SSL3_VERSION );

					MD5_Init( &md5 );
					MD5_Update( &md5, sess->client_random, SSL3_RANDOM_SIZE );
					MD5_Update( &md5, sess->server_random, SSL3_RANDOM_SIZE );
					MD5_Final( export_iv_block, &md5 );

					MD5_Init( &md5 );
					MD5_Update( &md5, sess->server_random, SSL3_RANDOM_SIZE );
					MD5_Update( &md5, sess->client_random, SSL3_RANDOM_SIZE );
					MD5_Final( export_iv_block + iv_len, &md5 );
				}
				c_iv = export_iv_block;
				s_iv = export_iv_block + iv_len;
			}
			else
			{
				c_iv = p; p+= iv_len;
				s_iv = p; p+= iv_len;
			}
		}
		else
		{
			c_iv = s_iv = NULL;
		}
	}

	/* create ciphers */
	if(  c != NULL && rc == DSSL_RC_OK )
	{
		c_cipher = (EVP_CIPHER_CTX*) malloc( sizeof(EVP_CIPHER_CTX) );
		s_cipher = (EVP_CIPHER_CTX*) malloc( sizeof(EVP_CIPHER_CTX) );

		if( !c_cipher || !s_cipher ) 
		{
			rc = NM_ERROR( DSSL_E_OUT_OF_MEMORY );
		}
	}

	/* init ciphers */
	if( c != NULL && rc == DSSL_RC_OK )
	{
		DEBUG_TRACE0("ssls_generate_keys - EVP_CIPHER_CTX_init\n");

		EVP_CIPHER_CTX_init( c_cipher );
		EVP_CipherInit( c_cipher, c, c_wk, c_iv, 0 );

		EVP_CIPHER_CTX_init( s_cipher );
		EVP_CipherInit( s_cipher, c, s_wk, s_iv, 0 );
	}
	else
	{
		DEBUG_TRACE0("ssls_generate_keys - not calling EVP_CIPHER_CTX_init\n");
	}

	/* set session data */
	if( rc == DSSL_RC_OK )
	{
		_ASSERT( sess->c_dec.cipher_new == NULL );
		_ASSERT( sess->s_dec.cipher_new == NULL );

		sess->c_dec.cipher_new = c_cipher; c_cipher = NULL;
		sess->s_dec.cipher_new = s_cipher; s_cipher = NULL;

		if( digest )
		{
			DEBUG_TRACE1("ssls_generate_keys - identified digest. len: %d\n", digest_len);
			_ASSERT( EVP_MD_size( digest ) == (int)digest_len );
			sess->c_dec.md_new = digest;
			sess->s_dec.md_new = digest;
			memcpy( sess->c_dec.mac_key_new, c_mac, digest_len );
			memcpy( sess->s_dec.mac_key_new, s_mac, digest_len );
		}
	}

	/* cleanup */
	OPENSSL_cleanse( keyblock, keyblock_len );

	if( c_cipher )
	{
		free( c_cipher );
		c_cipher = NULL;
	}

	if( s_cipher )
	{
		free( c_cipher );
		c_cipher = NULL;
	}

	return rc;
}
Exemple #3
0
void ssl3_update_handshake_digests( DSSL_Session* sess, u_char* data, uint32_t len )
{
	DSSL_handshake_buffer *q = NULL, *next;

	/* sanity check in case client hello is not received */
	if( sess->handshake_digest_md5.digest == NULL
		|| sess->handshake_digest_sha.digest == NULL)
	{
		ssl3_init_handshake_digests( sess );
	}
	EVP_DigestUpdate( &sess->handshake_digest_md5, data, len );
	EVP_DigestUpdate( &sess->handshake_digest_sha, data, len );
	
	if ( sess->version >= TLS1_2_VERSION )
	{
		/* if digest is still unknown, then queue the packets.
		 * we'll calculate the handshake hash once we determine which digest we should use.
		 */
		EVP_MD* digest = NULL;
		DSSL_CipherSuite* suite = sess->dssl_cipher_suite;
		if ( !suite )
			suite = DSSL_GetSSL3CipherSuite( sess->cipher_suite );
		digest = EVP_get_digestbyname( suite->digest );
		/* 'sha256' is the default for TLS 1.2, and can be replaced with a different (but stronger) hash */
		if ( !digest ) 
		{
			q = (DSSL_handshake_buffer*) malloc( sizeof(DSSL_handshake_buffer) );
			q->next = NULL;
			q->data = (u_char*) malloc( len );
			memcpy(q->data, data, len);
			q->len = len;
			
			if (NULL == sess->handshake_queue)
				sess->handshake_queue = q;
			else
				sess->handshake_queue->next = q;
			
			DEBUG_TRACE3( "Queue handshake packet %p (%u @ %p)", q, q->len, q->data );
		}
		else if ( digest != sess->handshake_digest.digest && EVP_MD_size( digest ) >= EVP_MD_size( sess->handshake_digest.digest ) ) 
		{
			/* specified digest is different than the default.
			 * re-init and re-hash all queued packets.
			 */
			EVP_MD_CTX_cleanup( &sess->handshake_digest );
			EVP_DigestInit_ex( &sess->handshake_digest, digest, NULL );
			for (q = sess->handshake_queue; q != NULL; q = next)
			{
				DEBUG_TRACE3( "Re-hash handshake packet %p (%u @ %p)", q, q->len, q->data );
				EVP_DigestUpdate( &sess->handshake_digest, q->data, q->len );
				next = q->next;
				free ( q->data );
				free ( q );
			}
			sess->handshake_queue = NULL;
		}
		else 
		{
			/* specified digest is identical to the default.
			 * throw away all the queued packets.
			 */
			for (q = sess->handshake_queue; q != NULL; q = next)
			{
				DEBUG_TRACE3( "discard handshake packet %p (%u @ %p)", q, q->len, q->data );
				next = q->next;
				free ( q->data );
				free ( q );
			}
			sess->handshake_queue = NULL;
		}
		
		if ( sess->handshake_digest.digest )
			EVP_DigestUpdate( &sess->handshake_digest, data, len );
	}
}