Skip to main content

pairing_handshake

/// <summary>
/// Handshakes the with server.
/// </summary>
/// <param name="clientId">The client identifier.</param>
/// <param name="clients">The client dictionary</param>
/// <param name="currentConversation">The current conversation GUID.</param>
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
private static bool HandshakeWithServer(int clientId,
Dictionary<int, string> clients,
string currentConversation = null)
{
try
{
Console.WriteLine($"Performing Handshake for Client {clientId}");

//--------------------------------
// create clientId for this client
//--------------------------------
HandshakeModel handshake = new HandshakeModel {
ConversationIdentifier = Guid.NewGuid().ToString() };

//-------------------------------------------------------------
// If current conversation guid is passed in, update identifier
//-------------------------------------------------------------
if (!string.IsNullOrWhiteSpace(currentConversation))
{
handshake.ConversationIdentifier = currentConversation;
}

//-------------------------------------------------------------
// Add client to dictionary list if this is a new conversation
//-------------------------------------------------------------
if (!clients.ContainsKey(clientId))
{
clients.Add(clientId, handshake.ConversationIdentifier);
}

//-------------------------------------------
// Create eclypses DH containers for handshake
//-------------------------------------------
EclypsesECDH encoderEcdh = new EclypsesECDH();
EclypsesECDH decoderEcdh = new EclypsesECDH();

//-------------------------------------------
// Get the public key to send to other side
//-------------------------------------------
handshake.ClientEncoderPublicKey =
encoderEcdh.GetPublicKey(encoderEcdh.GetTheContainer());
handshake.ClientDecoderPublicKey =
decoderEcdh.GetPublicKey(decoderEcdh.GetTheContainer());

//-------------------
// Perform handshake
//-------------------
string handshakeResponse =
MakeHttpCall($"{_restAPIName}/api/handshake",
HttpMethod.Post, handshake.ConversationIdentifier,
_jsonContentType,
JsonSerializer.Serialize(handshake, _jsonOptions)).Result;

//---------------------------------------
// Deserialize the result from handshake
//---------------------------------------
ResponseModel<HandshakeModel> response =
JsonSerializer.Deserialize<ResponseModel<HandshakeModel>>(handshakeResponse, _jsonOptions);

//---------------------------------------
// If handshake was not successful break
//---------------------------------------
if (!response.Success)
{
Console.WriteLine($"Error making DH handshake for Client " +
"{clientId}: {response.Message}");
return false;
}

//----------------------
// Create shared secret
//----------------------
var encoderSharedSecretModel =
encoderEcdh.ProcessPartnerPublicKey(response.Data.ClientEncoderPublicKey);
var decoderSharedSecretModel =
decoderEcdh.ProcessPartnerPublicKey(response.Data.ClientDecoderPublicKey);

//----------------------------------------------------------
// Create and store MTE Encoder and Decoder for this Client
//----------------------------------------------------------
ResponseModel mteResponse = CreateMteStates(response.Data.ConversationIdentifier,
encoderSharedSecretModel.SharedSecret,
decoderSharedSecretModel.SharedSecret,
Convert.ToUInt64(response.Data.Timestamp));

//----------------------------------------------------------
// Clear container to ensure key is different for each client
//----------------------------------------------------------
encoderEcdh.ClearContainer();
decoderEcdh.ClearContainer();

//-----------------------------------------
// If there was an error break out of loop
//-----------------------------------------
if (!mteResponse.Success)
{
Console.WriteLine($"Error creating mte states for Client {clientId}: {response.Message}");
return false;
}

return true;
}
catch (Exception ex)
{
Console.WriteLine(ex);
throw;
}
}