Beispiel #1
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 #2
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 );
	}
}
Beispiel #3
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;
}