Esempio n. 1
0
/**
 * Negotiate TLS parameters on an already-established socket.
 */
int tls_connect( int connection,
                 TLSParameters *parameters )
{
  init_parameters( parameters );
  new_md5_digest( &parameters->md5_handshake_digest );
  new_sha1_digest( &parameters->sha1_handshake_digest );

  // Step 1. Send the TLS handshake "client hello" message
  if ( send_client_hello( connection, parameters ) < 0 )
  {
    perror( "Unable to send client hello" );
    return 1;
  }

  // Step 2. Receive the server hello response
  parameters->server_hello_done = 0;
  while ( !parameters->server_hello_done )
  {
    if ( receive_tls_msg( connection, NULL, 0, parameters ) < 0 )
    {
      perror( "Unable to receive server hello" );
      return 2;
    }
  }
  // Step 3. Send client key exchange, change cipher spec (7.1) and encrypted 
  // handshake message
  if ( !( send_client_key_exchange( connection, parameters ) ) )
  {
    perror( "Unable to send client key exchange" );
    return 3;
  }

  if ( !( send_change_cipher_spec( connection, parameters ) ) )
  {
    perror( "Unable to send client change cipher spec" );
    return 4;
  }

  // This message will be encrypted using the newly negotiated keys
  if ( !( send_finished( connection, parameters ) ) )
  {
    perror( "Unable to send client finished" );
    return 5;
  }

  parameters->server_finished = 0;
  while ( !parameters->server_finished )
  {
    if ( receive_tls_msg( connection, NULL, 0, parameters ) < 0 )
    {
      perror( "Unable to receive server finished" );
      return 6;
    }
  }

  return 0;
}
Esempio n. 2
0
	void TLSClient_Impl::progress_conversation()
	{
		try
		{
			bool should_continue;
			do
			{
				should_continue = false;
				switch (conversation_state)
				{
				case cl_tls_state_send_client_hello:
					should_continue = send_client_hello();
					break;
				case cl_tls_state_receive_server_hello:
					break;
				case cl_tls_state_receive_certificate:
					break;
				//FIXME: Implement "7.4.3. Server key exchange message"
				case cl_tls_state_receive_server_hello_done:
					break;
				// FIXME: Should be send a "client certificate message" ?
				case cl_tls_state_send_client_key_exchange:
					should_continue = send_client_key_exchange();
					break;
				case cl_tls_state_send_change_cipher_spec:
					should_continue = send_change_cipher_spec();
					break;
				case cl_tls_state_send_finished:
					should_continue = send_finished();
					break;
				case cl_tls_state_receive_change_cipher_spec:
					break;
				case cl_tls_state_receive_finished:
					break;
				case cl_tls_state_connected:
					should_continue = send_application_data();
					break;

				case cl_tls_state_error:
					return; // TBD: Should we rather throw an exception when the conversation is in error state?

				default:
					throw Exception("Unknown TLSClient conversation state");
				}

				if (receive_record())
					should_continue = true;

			} while (should_continue);
		}
		catch (...)
		{
			conversation_state = cl_tls_state_error;
			throw;
		}
	}