Skip to content
Chrono edited this page Sep 10, 2021 · 11 revisions

This section will be describing on all the possible ephemeral TLS(Transport Layer Security) operations with the server.

API Root URL: https://mrchewitsoftware.com.my:5001/api/ECDH_ECDSA_TempSession

Prerequisites:

  1. You must know how to convert data into/from Base64 encoding
  2. You must know how to convert data into URL encoded format
  3. You must know how to generate a random password without special characters as an ASCII ID (will be useful later)
  4. You must know how to use query string in HttpGet
https://mrchewitsoftware.com.my:5001/api/ECDH_ECDSA_TempSession/byID?
https://mrchewitsoftware.com.my:5001/api/ECDH_ECDSA_TempSession/DeleteByClientCryptographicID?
https://mrchewitsoftware.com.my:5001/api/ECDH_ECDSA_TempSession/ByHandshake?
https://mrchewitsoftware.com.my:5001/api/ECDH_ECDSA_TempSession/BySharedSecret?

These 4 different endpoint acts differently and have different purposes.

1st Endpoint: Initiating ETLS session

https://mrchewitsoftware.com.my:5001/api/ECDH_ECDSA_TempSession/byID?

This endpoint was responsible for initiating an ETLS session with the server.

Here's an example on how to do it.

        public void InitializeNewSession()
        {
            //refers to the SecureIDGenerator in Helper
            String MySession_ID = MySecureIDGenerator.GenerateUniqueString();
            ECDH_ECDSA_Models MyECDH_ECDSA_Models = new ECDH_ECDSA_Models();
            Boolean CheckServerOnline = true;
            Boolean CreateShareSecretStatus = true;
            Boolean CheckSharedSecretStatus = true;
            Byte[] ServerECDSAPKByte = new Byte[] { };
            Byte[] ServerECDHSPKByte = new Byte[] { };
            Byte[] ServerECDHPKByte = new Byte[] { };
            Boolean VerifyBoolean = true;
            String SessionStatus = "";
            String ExceptionString = "";
            using (var InitializeHandShakeHttpclient = new HttpClient())
            {
                InitializeHandShakeHttpclient.BaseAddress = new Uri("https://mrchewitsoftware.com.my:5001/api/");
                InitializeHandShakeHttpclient.DefaultRequestHeaders.Accept.Clear();
                InitializeHandShakeHttpclient.DefaultRequestHeaders.Accept.Add(
                    new MediaTypeWithQualityHeaderValue("application/json"));
                var response = InitializeHandShakeHttpclient.GetAsync("ECDH_ECDSA_TempSession/byID?ClientPathID=" + MySession_ID);
                try
                {
                    response.Wait();
                }
                catch
                {
                    CheckServerOnline = false;
                }
                if (CheckServerOnline == true)
                {
                    var result = response.Result;
                    if (result.IsSuccessStatusCode)
                    {
                        var readTask = result.Content.ReadAsStringAsync();
                        readTask.Wait();

                        var ECDH_ECDSA_Models_Result = readTask.Result;
                        MyECDH_ECDSA_Models = JsonConvert.DeserializeObject<ECDH_ECDSA_Models>(ECDH_ECDSA_Models_Result);
                        if (MyECDH_ECDSA_Models.ID_Checker_Message.CompareTo("You still can use the exact same client ID...") == 0 || MyECDH_ECDSA_Models.ID_Checker_Message.CompareTo("You have an exact client ID great~") == 0)
                        {
                            ServerECDSAPKByte = Convert.FromBase64String(MyECDH_ECDSA_Models.ECDSA_PK_Base64String);
                            ServerECDHSPKByte = Convert.FromBase64String(MyECDH_ECDSA_Models.ECDH_SPK_Base64String);
                            try
                            {
                                ServerECDHPKByte = SodiumPublicKeyAuth.Verify(ServerECDHSPKByte, ServerECDSAPKByte);
                            }
                            catch (Exception exception)
                            {
                                VerifyBoolean = false;
                                ExceptionString = exception.ToString();
                                SessionStatus += ExceptionString + Environment.NewLine;
                            }
                            if (VerifyBoolean == true)
                            {
                                //Do something here... as the system able to verify the server signed ECDHPK or X25519PK
                                //Please store the verified server ECDHPK or X25519 PK as it will be useful later
                            }
                            else
                            {
                                //Do something here as the system unable to verify the server signed ECDHPK or X25519PK
                            }
                            //These might not be necessary but I leave it there for clearing the server public key material on the client
                            //side through cryptography secure way
                            SodiumSecureMemory.SecureClearBytes(ServerECDSAPKByte);
                            SodiumSecureMemory.SecureClearBytes(ServerECDHSPKByte);
                            SodiumSecureMemory.SecureClearBytes(ServerECDHPKByte);
                            SodiumSecureMemory.SecureClearString(MyECDH_ECDSA_Models.ECDSA_PK_Base64String);
                            SodiumSecureMemory.SecureClearString(MyECDH_ECDSA_Models.ECDH_SPK_Base64String);
                        }
                        else
                        {
                            MessageBox.Show(MyECDH_ECDSA_Models.ID_Checker_Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                    }
                    else
                    {
                        File.WriteAllText(Application.StartupPath + "\\Error_Data\\Greetings\\FetchHandShakeSessionParameterStatus.txt", "Failed to get handshake parameters from server");
                    }
                }
                else
                {
                    MessageBox.Show("The server is offline now please wait for awhile ..", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

There's a reason why there's a need to use cryptography random number generator to generate random ASCII ID. This was done with a reason that it can avoid possible ID duplication in the server side.

2nd Endpoint: Delete ETLS session

https://mrchewitsoftware.com.my:5001/api/ECDH_ECDSA_TempSession/DeleteByClientCryptographicID?

This endpoint is responsible for deleting ETLS session

Here's an example on how to do it

Boolean ServerOnlineChecker = true;
StreamReader MyStreamReader = new StreamReader(Application.StartupPath + "\\Temp_Session\\" + "SessionID.txt");
String Temp_Session_ID = MyStreamReader.ReadLine();
MyStreamReader.Close();
Byte[] ClientECDSASKByte = new Byte[] { };
Byte[] RandomData = new Byte[240];
RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider();
rngCsp.GetBytes(RandomData);
Byte[] SignedRandomData = new Byte[] { };
String Status = "";
if (Temp_Session_ID != null && Temp_Session_ID.CompareTo("") != 0)
{
    using (var client = new HttpClient())
    {
        ClientECDSASKByte = File.ReadAllBytes(Application.StartupPath + "\\Temp_Session\\" + Temp_Session_ID + "\\ECDSASK.txt");
        SignedRandomData = SodiumPublicKeyAuth.Sign(RandomData, ClientECDSASKByte,true);
        client.BaseAddress = new Uri("https://mrchewitsoftware.com.my:5001/api/");
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(
            new MediaTypeWithQualityHeaderValue("application/json"));
        var response = client.GetAsync("ECDH_ECDSA_TempSession/DeleteByClientCryptographicID?ClientPathID=" + Temp_Session_ID + "&ValidationData=" + HttpUtility.UrlEncode(Convert.ToBase64String(SignedRandomData)));
        SodiumSecureMemory.SecureClearBytes(RandomData);
        SodiumSecureMemory.SecureClearBytes(SignedRandomData);
        try
        {
            response.Wait();
        }
        catch
        {
            ServerOnlineChecker = false;
        }
        if (ServerOnlineChecker == true)
        {
            var result = response.Result;
            if (result.IsSuccessStatusCode)
            {
                var readTask = result.Content.ReadAsStringAsync();
                readTask.Wait();

                Status = readTask.Result;

                if (Status.Contains("Error"))
                {
                    //Do something
                }
                else
                {
                    //Do something..
                }
            }
            else
            {
                //Do something..
            }
        }
    }
}
else
{
    //Do something..
}

Warning: This function can only be call if you had established a working ephemeral TLS session with the server.

Clone this wiki locally