wolfssl C# wrapper client gives System.EntryPointNotFoundException for CTX_set_psk_client_callback

237 Views Asked by At

WolfSSL documentation provides different PSK example for C# and C++ client examples are different.

Following URL provides PSK client C++ example. https://github.com/wolfSSL/wolfssl-examples/blob/master/psk/client-psk.c

In C++ PSK client example, "wolfSSL_CTX_set_psk_client_callback" function is used.

Where as C# example does not use this function but tries to read shared key from a certificate file.

https://github.com/wolfSSL/wolfssl/tree/master/wrapper/CSharp/wolfSSL-TLS-Client

In our prototype, we need to modify C# client code to use a 4 bytes key like C++ example.

When the function “CTX_set_psk_client_callback” is used in C# example , it gives System.EntryPointNotFoundException for function.

I am not sure what is the problem with this code. I am using wolfssl C# wrapper solution to compile wolfSSL code.

The code for client is as described

public class WolfTLSClient
{

public static void standard_log(int lvl, StringBuilder msg)
    {
        Console.WriteLine(msg);
    }

private static void clean(IntPtr ssl, IntPtr ctx)
{
    wolfssl.free(ssl);
    wolfssl.CTX_free(ctx);
    wolfssl.Cleanup();
}




public static uint psk_client_callback_function(IntPtr ssl, string hint, IntPtr identity, uint id_max_len, IntPtr key, uint max_sz)
{
wolfssl.log(wolfssl.INFO_LOG, "PSK Client Identity = " + identity);

if (max_sz < 4)
    return 0;
byte[] tmp = { 26, 43, 60, 77 };
Marshal.Copy(tmp, 0, key, 4);

   return (uint)4;
}

public static void Main(string[] args)
{
    int _hostPort = 11111;
    string IPAddress = "198.162.0.10";

    IntPtr ctx;
    IntPtr ssl;
    Socket tcp;

    StringBuilder buff = new StringBuilder(1024);
    StringBuilder reply = new StringBuilder("Hello, this is the wolfSSL C# wrapper");

    //example of function used for setting logging
    wolfssl.SetLogging(standard_log);

    wolfssl.Init();

    Console.WriteLine("Calling ctx Init from wolfSSL");
    ctx = wolfssl.CTX_new(wolfssl.usev23_client());
    if (ctx == IntPtr.Zero)
    {
        Console.WriteLine("Error in creating ctx structure");
        return;
    }
    Console.WriteLine("Finished init of ctx .... now load in CA");

    short minDhKey = 128;
    wolfssl.CTX_SetMinDhKey_Sz(ctx, minDhKey);
    Console.Write("Setting cipher suite to ");

    ///* In order to use static PSK build wolfSSL with the preprocessor flag WOLFSSL_STATIC_PSK */
    StringBuilder set_cipher = new StringBuilder("ECDHE-ECDSA-AES128-GCM-SHA256");

    Console.WriteLine(set_cipher);
    if (wolfssl.CTX_set_cipher_list(ctx, set_cipher) != wolfssl.SUCCESS)
    {
        Console.WriteLine("Failed to set cipher suite");
        return;
    }

    wolfssl.psk_client_delegate psk_cb = new wolfssl.psk_client_delegate(psk_client_callback_function);
    wolfssl.CTX_set_psk_client_callback(ctx, psk_cb);
    
    
    /* set up TCP socket */
    tcp = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
                          ProtocolType.Tcp);
    try
    {
        tcp.Connect(IPAddress, _hostPort);
    }
    catch (Exception e)
    {
        Console.WriteLine("tcp.Connect() error " + e.ToString());
        wolfssl.CTX_free(ctx);
        return;
    }
    if (!tcp.Connected)
    {
        Console.WriteLine("tcp.Connect() failed!");
        tcp.Close();
        wolfssl.CTX_free(ctx);
        return;
    }

    Console.WriteLine("Connected TCP");
    ssl = wolfssl.new_ssl(ctx);
    if (ssl == IntPtr.Zero)
    {
        Console.WriteLine("Error in creating ssl object");
        wolfssl.CTX_free(ctx);
        return;
    }

    Console.WriteLine("Connection made wolfSSL_connect ");
    if (wolfssl.set_fd(ssl, tcp) != wolfssl.SUCCESS)
    {
        /* get and print out the error */
        Console.WriteLine(wolfssl.get_error(ssl));
        tcp.Close();
        clean(ssl, ctx);
        return;
    }

    if (wolfssl.connect(ssl) != wolfssl.SUCCESS)
    {
        /* get and print out the error */
        Console.WriteLine(wolfssl.get_error(ssl));
        tcp.Close();
        clean(ssl, ctx);
        return;
    }

    /* print out results of TLS/SSL accept */
    Console.WriteLine("SSL version is " + wolfssl.get_version(ssl));
    Console.WriteLine("SSL cipher suite is " + wolfssl.get_current_cipher(ssl));


    if (wolfssl.write(ssl, reply, reply.Length) != reply.Length)
    {
        Console.WriteLine("Error in write");
        tcp.Close();
        clean(ssl, ctx);
        return;
    }

    /* read and print out the message then reply */
    if (wolfssl.read(ssl, buff, 1023) < 0)
    {
        Console.WriteLine("Error in read");
        tcp.Close();
        clean(ssl, ctx);
        return;
    }
    Console.WriteLine(buff);

    wolfssl.shutdown(ssl);
    tcp.Close();
    clean(ssl, ctx);
}
}
1

There are 1 best solutions below

2
On

Couple of things.

  1. Eventually you will want to set a PSK cipher suite "StringBuilder set_cipher = new StringBuilder("ECDHE-ECDSA-AES128-GCM-SHA256");". Use something like DHE-PSK-AES128-CBC-SHA256 or any other you would like that has the -PSK- in it. (Note that PSK in the C# wrapper is not yet supported with TLS 1.3 so would need to be TLS 1.2 and lower cipher suites).

  2. The entry not found could be due to configuration mismatches happening with the wolfSSL library and application. Check to make sure that the bundled example PSK server is able to run. Lots of times by default PSK is off when wolfSSL is built in which case it could run into issues when trying to call down to the C implementations of PSK functions.

I added an example of using the TLS PSK client just now to wolfSSL while double checking this, here is the PR (https://github.com/wolfSSL/wolfssl/pull/4973). When testing it I was using mono....just easier that way on a non windows system, but it could be tied into the VS solution and built.

./configure --enable-all --enable-psk && make && sudo make install
cd wrapper/CSharp
csc -lib:/usr/local/lib wolfSSL_CSharp/wolfSSL.cs wolfSSL_CSharp/X509.cs wolfSSL-TLS-PSK-Client/wolfSSL-TLS-PSK-Client.cs
cp wolfSSL-TLS-PSK-Client.exe ../../certs
cd ../../certs
mono wolfSSL-TLS-PSK-Client.exe

Note the example identity in the PSK client call back code, if the server is checking the identity when connecting it would need changed to be an expected identity.

Regards, Jacob (wolfSSL)