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
  5. You must know how to convert data into/from JSON string
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.

In future, this endpoint will work differently as it's still a work in the progress at the moment.. For the time being, this is how you can call it

3rd Endpoint: Establish ETLS session

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

This endpoint is responsible for establishing ETLS session

Here's an example on how to do it

//The MySession_ID is the ASCII ID that was sent to the server during ETLS initialization
//SignedClientSessionECDHPKByte is the client's signed X25519 PK or ECDHPK
//ClientSessionECDSAPKByte is the client's ED25519 PK or ECDSA PK
public void CreateSharedSecret(ref Boolean CheckBoolean, String MySession_ID, Byte[] SignedClientSessionECDHPKByte, Byte[] ClientSessionECDSAPKByte)
{
    CheckBoolean = false;
    String SessionStatus = "";
    var CreateSharedSecretHttpClient = new HttpClient();
    CreateSharedSecretHttpClient.BaseAddress = new Uri("https://mrchewitsoftware.com.my:5001/api/");
    CreateSharedSecretHttpClient.DefaultRequestHeaders.Accept.Clear();
    CreateSharedSecretHttpClient.DefaultRequestHeaders.Accept.Add(
        new MediaTypeWithQualityHeaderValue("application/json"));
    var newresponse = CreateSharedSecretHttpClient.GetAsync("ECDH_ECDSA_TempSession/ByHandshake?ClientPathID=" + MySession_ID + "&SECDHPK=" + 
        HttpUtility.UrlEncode(Convert.ToBase64String(SignedClientSessionECDHPKByte)) + "&ECDSAPK=" + 
        HttpUtility.UrlEncode(Convert.ToBase64String(ClientSessionECDSAPKByte)));
    try
    {
        newresponse.Wait();
        var newresult = newresponse.Result;

        if (newresult.IsSuccessStatusCode)
        {
            var newreadTask = newresult.Content.ReadAsStringAsync();
            newreadTask.Wait();

            SessionStatus += newreadTask.Result;

            if (SessionStatus.Contains("Error")==true)
            {
                CheckBoolean = false;
            }
            else
            {
                CheckBoolean = true;
            }
        }
        else
        {
            MessageBox.Show("Failed to fetch values from server", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }
    catch
    {
        MessageBox.Show("The server is offline now please wait for awhile ..", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}
Clone this wiki locally