diff --git a/CSharp/README.md b/CSharp/README.md
new file mode 100644
index 00000000..829c4b7d
--- /dev/null
+++ b/CSharp/README.md
@@ -0,0 +1,47 @@
+# C# Wrapper Examples
+
+This directory contains examples that demonstrate using the C# wrapper.
+
+These assume the use of `wolfssl\wrapper\CSharp\wolfSSL_CSharp.sln`.
+
+## wolfSSL-TLS-pq
+
+wolfSSL Server and Client using PQC algorithms (ML-KEM / ML-DSA).
+
+### Build Options
+
+The following build options need to be added.
+
+#### for `wolfssl` Project
+
+```
+HAVE_MLKEM
+WOLFSSL_WC_MLKEM
+WOLFSSL_HAVE_MLKEM
+WOLFSSL_DTLS_CH_FRAG
+HAVE_DILITHIUM
+WOLFSSL_WC_DILITHIUM
+WOLFSSL_SHAKE128
+WOLFSSL_SHAKE256
+```
+
+#### for `wolfSSL_CSharp` Project
+
+```
+HAVE_MLKEM
+HAVE_MLDSA
+```
+
+If you want to execute `wolfCrypt-Test` Project as well, add these options to `wolfCrypt-Test` Project.
+
+### wolfSSL-TLS-pq-Server
+
+wolfSSL Server using ML-DSA-87.
+
+### wolfSSL-TLS-pq-ServerThreaded
+
+Threaded version of `wolfSSL-TLS-pq-Server`.
+
+### wolfSSL-TLS-pq-Client
+
+wolfSSL Client using ML-KEM-1024/ML-DSA-87.
\ No newline at end of file
diff --git a/CSharp/wolfSSL-TLS-pq-Client/App.config b/CSharp/wolfSSL-TLS-pq-Client/App.config
new file mode 100644
index 00000000..a86c6465
--- /dev/null
+++ b/CSharp/wolfSSL-TLS-pq-Client/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/CSharp/wolfSSL-TLS-pq-Client/Properties/AssemblyInfo.cs b/CSharp/wolfSSL-TLS-pq-Client/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000..203c30b0
--- /dev/null
+++ b/CSharp/wolfSSL-TLS-pq-Client/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("wolfSSL-TLS-Client")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("wolfSSL")]
+[assembly: AssemblyProduct("wolfSSL-TLS-Client")]
+[assembly: AssemblyCopyright("Copyright wolfSSL 2020")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("05aad2b4-445e-4f0e-8e16-8f8512696505")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.1.0.0")]
+[assembly: AssemblyFileVersion("1.1.0.0")]
diff --git a/CSharp/wolfSSL-TLS-pq-Client/wolfSSL-TLS-Client.cs b/CSharp/wolfSSL-TLS-pq-Client/wolfSSL-TLS-Client.cs
new file mode 100644
index 00000000..788c43e3
--- /dev/null
+++ b/CSharp/wolfSSL-TLS-pq-Client/wolfSSL-TLS-Client.cs
@@ -0,0 +1,272 @@
+/* wolfSSL-TLS-Client.cs
+ *
+ * Copyright (C) 2006-2025 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.IO;
+using System.Net;
+using System.Net.Sockets;
+using wolfSSL.CSharp;
+
+public class wolfSSL_TLS_Client
+{
+ ///
+ /// Example of a logging function
+ ///
+ /// level of log
+ /// message to log
+ 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();
+ }
+
+ ///
+ /// Verification callback
+ ///
+ /// 1=Verify Okay, 0=Failure
+ /// Certificate in WOLFSSL_X509_STORE_CTX format
+ private static int myVerify(int preverify, IntPtr x509_ctx)
+ {
+ int verify = preverify;
+ Console.WriteLine("myVerify is called.");
+
+ /* example for overriding an error code */
+ /* X509_STORE_CTX_get_error API can be enabled with
+ * OPENSSL_EXTRA_X509_SMALL or WOLFSSL_EXTRA */
+ int error = wolfssl.X509_STORE_CTX_get_error(x509_ctx);
+ if (error == wolfcrypt.ASN_BEFORE_DATE_E) {
+ verify = 1; /* override error */
+ }
+
+ /* Can optionally override failures by returning non-zero value */
+ return verify;
+ }
+
+ ///
+ /// Checks if the SNI option was enabled via command line.
+ /// Must be enabled with ./configure --enable-sni when configuring
+ /// wolfSSL.
+ /// Parameters passed via command line
+ ///
+ private static int haveSNI(string[] args)
+ {
+ for (int i = 0; i < args.Length; i++) {
+ if (args[i] == "-S") {
+ Console.WriteLine("SNI IS ON");
+ return i+1;
+ }
+ }
+ Console.WriteLine("SNI IS OFF");
+ return -1;
+ }
+
+ public static void Main(string[] args)
+ {
+ IntPtr ctx;
+ IntPtr ssl;
+ Socket tcp;
+ IntPtr sniHostName;
+
+ /* These paths should be changed for use */
+ string caCert = wolfssl.setPath("mldsa87_root_cert.pem");
+ StringBuilder dhparam = new StringBuilder(wolfssl.setPath("dh2048.pem"));
+
+ if (caCert == "" || dhparam.Length == 0) {
+ Console.WriteLine("Platform not supported.");
+ return;
+ }
+
+ 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");
+
+
+ if (!File.Exists(caCert))
+ {
+ Console.WriteLine("Could not find CA cert file");
+ wolfssl.CTX_free(ctx);
+ return;
+ }
+
+ if (!File.Exists(dhparam.ToString())) {
+ Console.WriteLine("Could not find dh file");
+ wolfssl.CTX_free(ctx);
+ return;
+ }
+
+ if (wolfssl.CTX_load_verify_locations(ctx, caCert, null)
+ != wolfssl.SUCCESS)
+ {
+ Console.WriteLine("Error loading CA cert");
+ wolfssl.CTX_free(ctx);
+ return;
+ }
+
+ int sniArg = haveSNI(args);
+ if (sniArg >= 0)
+ {
+ string sniHostNameString = args[sniArg].Trim();
+ sniHostName = Marshal.StringToHGlobalAnsi(sniHostNameString);
+
+ ushort size = (ushort)sniHostNameString.Length;
+
+ if (wolfssl.CTX_UseSNI(ctx, (byte)wolfssl.WOLFSSL_SNI_HOST_NAME, sniHostName, size) != wolfssl.SUCCESS)
+ {
+ Console.WriteLine("UseSNI failed");
+ wolfssl.CTX_free(ctx);
+ return;
+ }
+ }
+
+ StringBuilder ciphers = new StringBuilder(new String(' ', 4096));
+ wolfssl.get_ciphers(ciphers, 4096);
+ Console.WriteLine("Ciphers : " + ciphers.ToString());
+
+ /* Uncomment Section to enable specific cipher suite */
+#if false
+ ciphers = new StringBuilder("ECDHE-ECDSA-AES128-GCM-SHA256");
+ if (wolfssl.CTX_set_cipher_list(ctx, ciphers) != wolfssl.SUCCESS)
+ {
+ Console.WriteLine("ERROR CTX_set_cipher_list()");
+ wolfssl.CTX_free(ctx);
+ return;
+ }
+#endif
+
+ short minDhKey = 128;
+ wolfssl.CTX_SetMinDhKey_Sz(ctx, minDhKey);
+
+ /* Setup Verify Callback */
+ if (wolfssl.CTX_set_verify(ctx, wolfssl.SSL_VERIFY_PEER, myVerify)
+ != wolfssl.SUCCESS)
+ {
+ Console.WriteLine("Error setting verify callback!");
+ }
+
+
+ /* set up TCP socket */
+ tcp = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
+ ProtocolType.Tcp);
+ try
+ {
+ tcp.Connect("localhost", 11111);
+ }
+ 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;
+ }
+
+ if (wolfssl.UseKeyShare(ssl, wolfssl.NamedGroup.WOLFSSL_ML_KEM_1024) != wolfssl.SUCCESS)
+ {
+ Console.WriteLine("Error enabling ML-KEM key share");
+ 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;
+ }
+
+ wolfssl.SetTmpDH_file(ssl, dhparam, wolfssl.SSL_FILETYPE_PEM);
+
+ 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);
+ }
+}
diff --git a/CSharp/wolfSSL-TLS-pq-Client/wolfSSL-TLS-Client.csproj b/CSharp/wolfSSL-TLS-pq-Client/wolfSSL-TLS-Client.csproj
new file mode 100644
index 00000000..a7c8e0a4
--- /dev/null
+++ b/CSharp/wolfSSL-TLS-pq-Client/wolfSSL-TLS-Client.csproj
@@ -0,0 +1,124 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}
+ Exe
+ Properties
+ wolfSSL_TLS_Client
+ wolfSSL-TLS-Client
+ v4.8
+ 512
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ false
+ true
+
+
+
+ AnyCPU
+ true
+ full
+ false
+ $(SolutionDir)$(Configuration)\$(Platform)\
+ DEBUG;TRACE
+ prompt
+ 3
+
+
+ AnyCPU
+ pdbonly
+ true
+ $(SolutionDir)$(Configuration)\$(Platform)\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+ true
+ $(SolutionDir)$(Configuration)\$(Platform)\
+ DEBUG;TRACE
+ 4
+ full
+ x64
+ prompt
+ MinimumRecommendedRules.ruleset
+ true
+
+
+ $(SolutionDir)$(Configuration)\$(Platform)\x64
+ TRACE
+ true
+ pdbonly
+ x64
+ prompt
+ MinimumRecommendedRules.ruleset
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {52609808-0418-46d3-8e17-141927a1a39a}
+ wolfSSL_CSharp
+
+
+
+
+ False
+ Microsoft .NET Framework 4.5 %28x86 and x64%29
+ true
+
+
+ False
+ .NET Framework 3.5 SP1 Client Profile
+ false
+
+
+ False
+ .NET Framework 3.5 SP1
+ false
+
+
+
+
+
+
+
+
+
diff --git a/CSharp/wolfSSL-TLS-pq-Server/App.config b/CSharp/wolfSSL-TLS-pq-Server/App.config
new file mode 100644
index 00000000..a86c6465
--- /dev/null
+++ b/CSharp/wolfSSL-TLS-pq-Server/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/CSharp/wolfSSL-TLS-pq-Server/Properties/AssemblyInfo.cs b/CSharp/wolfSSL-TLS-pq-Server/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000..079a1267
--- /dev/null
+++ b/CSharp/wolfSSL-TLS-pq-Server/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("wolfSSL-TLS-Server")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("wolfSSL")]
+[assembly: AssemblyProduct("wolfSSL-TLS-Server")]
+[assembly: AssemblyCopyright("Copyright wolfSSL 2020")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("716e8f30-1318-4e3b-b788-d0380b397a4c")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.1.0.0")]
+[assembly: AssemblyFileVersion("1.1.0.0")]
diff --git a/CSharp/wolfSSL-TLS-pq-Server/wolfSSL-TLS-Server.cs b/CSharp/wolfSSL-TLS-pq-Server/wolfSSL-TLS-Server.cs
new file mode 100644
index 00000000..08d19d4b
--- /dev/null
+++ b/CSharp/wolfSSL-TLS-pq-Server/wolfSSL-TLS-Server.cs
@@ -0,0 +1,289 @@
+/* wolfSSL-TLS-Server.cs
+ *
+ * Copyright (C) 2006-2025 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.IO;
+using System.Net;
+using System.Net.Sockets;
+using wolfSSL.CSharp;
+
+public class wolfSSL_TLS_CSHarp
+{
+ ///
+ /// Example of a logging function
+ ///
+ /// level of log
+ /// message to log
+ 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();
+ }
+
+ ///
+ /// Checks if the SNI option was enabled via command line.
+ /// Must be enabled with ./configure --enable-sni when configuring
+ /// wolfSSL.
+ /// Parameters passed via command line
+ ///
+ private static bool haveSNI(string[] args)
+ {
+ bool sniON = false;
+ for (int i = 0; i < args.Length; i++) {
+ if (args[i] == "-S") {
+ sniON = true;
+ break;
+ }
+ }
+ Console.WriteLine("SNI IS: " + sniON);
+ return sniON;
+ }
+
+ ///
+ /// Example of a SNI function call back
+ ///
+ /// pointer to ssl structure
+ /// alert code
+ /// context arg, can be set with the function wolfssl.CTX_set_servername_arg
+ ///
+ public static int my_sni_server_cb(IntPtr ssl, IntPtr ret, IntPtr exArg) {
+ /* Trivial callback just for testing */
+ Console.WriteLine("my sni server callback");
+
+ return 0;
+ }
+
+ public static void Main(string[] args)
+ {
+ IntPtr ctx;
+ IntPtr ssl;
+ Socket fd;
+ IntPtr arg_sni;
+
+ /* These paths should be changed for use */
+ string fileCert = wolfssl.setPath("mldsa87_entity_cert.pem");
+ string fileKey = wolfssl.setPath("mldsa87_entity_key.pem");
+ StringBuilder dhparam = new StringBuilder(wolfssl.setPath("dh2048.pem"));
+
+ if (fileCert == "" || fileKey == "" || dhparam.Length == 0) {
+ Console.WriteLine("Platform not supported.");
+ return;
+ }
+
+ 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_server());
+ if (ctx == IntPtr.Zero)
+ {
+ Console.WriteLine("Error in creating ctx structure");
+ return;
+ }
+ Console.WriteLine("Finished init of ctx .... now load in cert and key");
+
+ if (!File.Exists(fileCert) || !File.Exists(fileKey))
+ {
+ Console.WriteLine("Could not find cert or key file");
+ wolfssl.CTX_free(ctx);
+ return;
+ }
+
+ if (!File.Exists(dhparam.ToString())) {
+ Console.WriteLine("Could not find dh file");
+ wolfssl.CTX_free(ctx);
+ return;
+ }
+
+ if (wolfssl.CTX_use_certificate_file(ctx, fileCert, wolfssl.SSL_FILETYPE_PEM) != wolfssl.SUCCESS)
+ {
+ Console.WriteLine("Error in setting cert file");
+ wolfssl.CTX_free(ctx);
+ return;
+ }
+
+ if (wolfssl.CTX_use_PrivateKey_file(ctx, fileKey, wolfssl.SSL_FILETYPE_PEM) != wolfssl.SUCCESS)
+ {
+ Console.WriteLine("Error in setting key file");
+ wolfssl.CTX_free(ctx);
+ return;
+ }
+
+ StringBuilder ciphers = new StringBuilder(new String(' ', 4096));
+ wolfssl.get_ciphers(ciphers, 4096);
+ Console.WriteLine("Ciphers : " + ciphers.ToString());
+
+ short minDhKey = 128;
+ wolfssl.CTX_SetMinDhKey_Sz(ctx, minDhKey);
+
+ /* set up TCP socket */
+ IPAddress ip = IPAddress.Parse("0.0.0.0"); /* bind to any */
+ TcpListener tcp = new TcpListener(ip, 11111);
+ tcp.Start();
+
+ Console.WriteLine("Started TCP and waiting for a connection");
+ fd = tcp.AcceptSocket();
+
+ ssl = wolfssl.new_ssl(ctx);
+ if (ssl == IntPtr.Zero)
+ {
+ Console.WriteLine("Error in creating ssl object");
+ wolfssl.CTX_free(ctx);
+ return;
+ }
+
+ if (haveSNI(args))
+ {
+ // Allocating memory and setting SNI arg
+ int test_value = 32;
+ arg_sni = Marshal.AllocHGlobal(sizeof(int));
+ Marshal.WriteInt32(arg_sni, test_value);
+ if (wolfssl.CTX_set_servername_arg(ctx, arg_sni) == wolfssl.FAILURE) {
+ Console.WriteLine("wolfssl.CTX_set_servername_arg failed");
+ wolfssl.CTX_free(ctx);
+ return;
+ }
+
+ // Setting SNI delegate
+ wolfssl.sni_delegate sni_cb = new wolfssl.sni_delegate(my_sni_server_cb);
+ wolfssl.CTX_set_servername_callback(ctx, sni_cb);
+ }
+
+ Console.WriteLine("Connection made wolfSSL_accept ");
+ if (wolfssl.set_fd(ssl, fd) != wolfssl.SUCCESS)
+ {
+ /* get and print out the error */
+ Console.WriteLine(wolfssl.get_error(ssl));
+ tcp.Stop();
+ clean(ssl, ctx);
+ return;
+ }
+
+ if (wolfssl.SetTmpDH_file(ssl, dhparam, wolfssl.SSL_FILETYPE_PEM) != wolfssl.SUCCESS)
+ {
+ Console.WriteLine("Error in setting dh2048Pem");
+ Console.WriteLine(wolfssl.get_error(ssl));
+ tcp.Stop();
+ clean(ssl, ctx);
+ return;
+ }
+
+ if (wolfssl.accept(ssl) != wolfssl.SUCCESS)
+ {
+ /* get and print out the error */
+ Console.WriteLine(wolfssl.get_error(ssl));
+ tcp.Stop();
+ clean(ssl, ctx);
+ return;
+ }
+
+ /* get and print sni used by the client */
+ if (haveSNI(args)) {
+ IntPtr data = IntPtr.Zero;
+
+ ushort size = wolfssl.SNI_GetRequest(ssl, 0, ref data);
+ string dataStr = Marshal.PtrToStringAnsi(data);
+ Console.WriteLine("(SNI_GetRequest) Size of SNI used by client: " + size);
+ Console.WriteLine("(SNI_GetRequest) SNI used by client: " + dataStr);
+ }
+
+ /* 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));
+
+ /* read and print out the message then reply */
+ if (wolfssl.read(ssl, buff, 1023) < 0)
+ {
+ Console.WriteLine("Error in read");
+ tcp.Stop();
+ clean(ssl, ctx);
+ return;
+ }
+ Console.WriteLine(buff);
+
+ /* get and print sni from a sample buffer, can be used by using the raw client hello */
+ if (haveSNI(args)) {
+ IntPtr result = Marshal.AllocHGlobal(32);
+ IntPtr inOutSz = Marshal.AllocHGlobal(sizeof(int));
+ Marshal.WriteInt32(inOutSz, 32);
+ byte []buffer = { /* from TextMate website client hello example */
+ 0x16, 0x03, 0x01, 0x00, 0xc6, 0x01, 0x00, 0x00, 0xc2, 0x03, 0x03, 0x52,
+ 0x8b, 0x7b, 0xca, 0x69, 0xec, 0x97, 0xd5, 0x08, 0x03, 0x50, 0xfe, 0x3b,
+ 0x99, 0xc3, 0x20, 0xce, 0xa5, 0xf6, 0x99, 0xa5, 0x71, 0xf9, 0x57, 0x7f,
+ 0x04, 0x38, 0xf6, 0x11, 0x0b, 0xb8, 0xd3, 0x00, 0x00, 0x5e, 0x00, 0xff,
+ 0xc0, 0x24, 0xc0, 0x23, 0xc0, 0x0a, 0xc0, 0x09, 0xc0, 0x07, 0xc0, 0x08,
+ 0xc0, 0x28, 0xc0, 0x27, 0xc0, 0x14, 0xc0, 0x13, 0xc0, 0x11, 0xc0, 0x12,
+ 0xc0, 0x26, 0xc0, 0x25, 0xc0, 0x2a, 0xc0, 0x29, 0xc0, 0x05, 0xc0, 0x04,
+ 0xc0, 0x02, 0xc0, 0x03, 0xc0, 0x0f, 0xc0, 0x0e, 0xc0, 0x0c, 0xc0, 0x0d,
+ 0x00, 0x3d, 0x00, 0x3c, 0x00, 0x2f, 0x00, 0x05, 0x00, 0x04, 0x00, 0x35,
+ 0x00, 0x0a, 0x00, 0x67, 0x00, 0x6b, 0x00, 0x33, 0x00, 0x39, 0x00, 0x16,
+ 0x00, 0xaf, 0x00, 0xae, 0x00, 0x8d, 0x00, 0x8c, 0x00, 0x8a, 0x00, 0x8b,
+ 0x00, 0xb1, 0x00, 0xb0, 0x00, 0x2c, 0x00, 0x3b, 0x01, 0x00, 0x00, 0x3b,
+ 0x00, 0x00, 0x00, 0x15, 0x00, 0x13, 0x00, 0x00, 0x10, 0x61, 0x70, 0x69,
+ 0x2e, 0x74, 0x65, 0x78, 0x74, 0x6d, 0x61, 0x74, 0x65, 0x2e, 0x6f, 0x72,
+ 0x67, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x17, 0x00, 0x18, 0x00,
+ 0x19, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x0d, 0x00, 0x0c, 0x00,
+ 0x0a, 0x05, 0x01, 0x04, 0x01, 0x02, 0x01, 0x04, 0x03, 0x02, 0x03
+ };
+
+ int ret = wolfssl.SNI_GetFromBuffer(buffer, 1024, 0, result, inOutSz);
+
+ if (ret != wolfssl.SUCCESS) {
+ Console.WriteLine("Error on reading SNI from buffer, ret value = " + ret);
+ tcp.Stop();
+ clean(ssl, ctx);
+ return;
+ }
+
+ string resultStr = Marshal.PtrToStringAnsi(result);
+ Console.WriteLine("(SNI_GetFromBuffer) SNI used by client: " + resultStr);
+
+ }
+
+ if (wolfssl.write(ssl, reply, reply.Length) != reply.Length)
+ {
+ Console.WriteLine("Error in write");
+ tcp.Stop();
+ clean(ssl, ctx);
+ return;
+ }
+
+ wolfssl.shutdown(ssl);
+ fd.Close();
+ tcp.Stop();
+
+ clean(ssl, ctx);
+ }
+}
diff --git a/CSharp/wolfSSL-TLS-pq-Server/wolfSSL-TLS-Server.csproj b/CSharp/wolfSSL-TLS-pq-Server/wolfSSL-TLS-Server.csproj
new file mode 100644
index 00000000..9acd0511
--- /dev/null
+++ b/CSharp/wolfSSL-TLS-pq-Server/wolfSSL-TLS-Server.csproj
@@ -0,0 +1,124 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}
+ Exe
+ Properties
+ wolfSSL_TLS_Server
+ wolfSSL-TLS-Server
+ v4.8
+ 512
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ false
+ true
+
+
+
+ AnyCPU
+ true
+ full
+ false
+ $(SolutionDir)$(Configuration)\$(Platform)\
+ DEBUG;TRACE
+ prompt
+ 3
+
+
+ AnyCPU
+ pdbonly
+ true
+ $(SolutionDir)$(Configuration)\$(Platform)\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+ true
+ $(SolutionDir)$(Configuration)\$(Platform)\
+ DEBUG;TRACE
+ 4
+ full
+ x64
+ prompt
+ MinimumRecommendedRules.ruleset
+ true
+
+
+ $(SolutionDir)$(Configuration)\$(Platform)\
+ TRACE
+ true
+ pdbonly
+ x64
+ prompt
+ MinimumRecommendedRules.ruleset
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {52609808-0418-46d3-8e17-141927a1a39a}
+ wolfSSL_CSharp
+
+
+
+
+ False
+ Microsoft .NET Framework 4.5 %28x86 and x64%29
+ true
+
+
+ False
+ .NET Framework 3.5 SP1 Client Profile
+ false
+
+
+ False
+ .NET Framework 3.5 SP1
+ false
+
+
+
+
+
+
+
+
+
diff --git a/CSharp/wolfSSL-TLS-pq-ServerThreaded/App.config b/CSharp/wolfSSL-TLS-pq-ServerThreaded/App.config
new file mode 100644
index 00000000..a86c6465
--- /dev/null
+++ b/CSharp/wolfSSL-TLS-pq-ServerThreaded/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/CSharp/wolfSSL-TLS-pq-ServerThreaded/Properties/AssemblyInfo.cs b/CSharp/wolfSSL-TLS-pq-ServerThreaded/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000..9391e05e
--- /dev/null
+++ b/CSharp/wolfSSL-TLS-pq-ServerThreaded/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("wolfSSL-TLS-ServerThreaded")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("wolfSSL")]
+[assembly: AssemblyProduct("wolfSSL-TLS-ServerThreaded")]
+[assembly: AssemblyCopyright("Copyright wolfSSL 2020")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("716e8f30-1318-4e3b-b788-d0380b397a4c")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.1.0.0")]
+[assembly: AssemblyFileVersion("1.1.0.0")]
diff --git a/CSharp/wolfSSL-TLS-pq-ServerThreaded/wolfSSL-TLS-ServerThreaded.cs b/CSharp/wolfSSL-TLS-pq-ServerThreaded/wolfSSL-TLS-ServerThreaded.cs
new file mode 100644
index 00000000..59484ce5
--- /dev/null
+++ b/CSharp/wolfSSL-TLS-pq-ServerThreaded/wolfSSL-TLS-ServerThreaded.cs
@@ -0,0 +1,205 @@
+/* wolfSSL-TLS-ServerThreaded.cs
+ *
+ * Copyright (C) 2006-2025 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.IO;
+using System.Net;
+using System.Net.Sockets;
+using System.Threading;
+
+using wolfSSL.CSharp;
+
+public class wolfSSL_TLS_ServerThread
+{
+ private IntPtr _ctx;
+ private Socket _fd;
+
+ public wolfSSL_TLS_ServerThread(IntPtr ctx, Socket fd)
+ {
+ _ctx = ctx;
+ _fd = fd;
+ }
+
+ private const int kEchoBufSz = 1024;
+ public void start_client()
+ {
+ StringBuilder buff = new StringBuilder(kEchoBufSz);
+ IntPtr ssl = wolfssl.new_ssl(_ctx);
+ if (ssl == IntPtr.Zero)
+ {
+ Console.WriteLine("Error in creating ssl object");
+ return;
+ }
+
+ if (wolfssl.set_fd(ssl, _fd) != wolfssl.SUCCESS)
+ {
+ /* get and print out the error */
+ Console.WriteLine(wolfssl.get_error(ssl));
+ _fd.Close();
+ wolfssl.free(ssl);
+ return;
+ }
+
+ Console.WriteLine("Starting TLS handshake");
+ if (wolfssl.accept(ssl) != wolfssl.SUCCESS)
+ {
+ /* get and print out the error */
+ Console.WriteLine("Failed " + wolfssl.get_error(ssl));
+ _fd.Close();
+ wolfssl.free(ssl);
+ 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));
+
+ /* echo data until error */
+ while (true)
+ {
+ /* read and print out the message then reply */
+ if (wolfssl.read(ssl, buff, kEchoBufSz-1) < 0)
+ {
+ Console.WriteLine("Error in read");
+ break;
+ }
+ Console.WriteLine(buff);
+
+ if (wolfssl.write(ssl, buff, buff.Length) != buff.Length)
+ {
+ Console.WriteLine("Error in write");
+ break;
+ }
+ }
+
+ Console.WriteLine("Closing " + wolfssl.get_error(ssl));
+ _fd.Close();
+ wolfssl.free(ssl);
+ }
+}
+
+public class wolfSSL_TLS_ServerThreaded
+{
+ ///
+ /// Example of a logging function
+ ///
+ /// level of log
+ /// message to log
+ public static void standard_log(int lvl, StringBuilder msg)
+ {
+ Console.WriteLine(msg);
+ }
+
+ public static void Main(string[] args)
+ {
+ IntPtr ctx;
+
+ /* These paths should be changed for use */
+ string fileCert = wolfssl.setPath("mldsa87_entity_cert.pem");
+ string fileKey = wolfssl.setPath("mldsa87_entity_key.pem");
+ StringBuilder dhparam = new StringBuilder(wolfssl.setPath("dh2048.pem"));
+
+ if (fileCert == "" || fileKey == "" || dhparam.Length == 0) {
+ Console.WriteLine("Platform not supported");
+ return;
+ }
+
+ /* 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_server());
+ if (ctx == IntPtr.Zero)
+ {
+ Console.WriteLine("Error in creating ctx structure");
+ return;
+ }
+ Console.WriteLine("Finished init of ctx .... now load in cert and key");
+
+ if (!File.Exists(fileCert) || !File.Exists(fileKey))
+ {
+ Console.WriteLine("Could not find cert or key file");
+ wolfssl.CTX_free(ctx);
+ return;
+ }
+
+ if (!File.Exists(dhparam.ToString())) {
+ Console.WriteLine("Could not find dh file");
+ wolfssl.CTX_free(ctx);
+ return;
+ }
+
+ if (wolfssl.CTX_use_certificate_file(ctx, fileCert, wolfssl.SSL_FILETYPE_PEM) != wolfssl.SUCCESS)
+ {
+ Console.WriteLine("Error in setting cert file");
+ wolfssl.CTX_free(ctx);
+ return;
+ }
+
+ if (wolfssl.CTX_use_PrivateKey_file(ctx, fileKey, wolfssl.SSL_FILETYPE_PEM) != wolfssl.SUCCESS)
+ {
+ Console.WriteLine("Error in setting key file");
+ wolfssl.CTX_free(ctx);
+ return;
+ }
+
+ StringBuilder ciphers = new StringBuilder(new String(' ', 4096));
+ wolfssl.get_ciphers(ciphers, 4096);
+ Console.WriteLine("Ciphers : " + ciphers.ToString());
+
+ short minDhKey = 128;
+ wolfssl.CTX_SetMinDhKey_Sz(ctx, minDhKey);
+ wolfssl.CTX_SetTmpDH_file(ctx, dhparam, wolfssl.SSL_FILETYPE_PEM);
+
+ /* set up TCP socket */
+ IPAddress ip = IPAddress.Parse("0.0.0.0"); /* bind to any */
+ TcpListener tcp = new TcpListener(ip, 11111);
+ tcp.Start();
+
+ Console.WriteLine("Started TCP and waiting for a connection");
+
+ while (true) {
+ try
+ {
+ Socket fd = tcp.AcceptSocket();
+ Console.WriteLine("Got client connection");
+
+ /* Spin up thread for client */
+ wolfSSL_TLS_ServerThread thread = new wolfSSL_TLS_ServerThread(ctx, fd);
+ Thread thr = new Thread(new ThreadStart(thread.start_client));
+ thr.Start();
+ }
+ catch(Exception ex)
+ {
+ Console.WriteLine("Server Exception " + ex.ToString());
+ break;
+ }
+ }
+
+ tcp.Stop();
+ wolfssl.CTX_free(ctx);
+ wolfssl.Cleanup();
+ }
+}
diff --git a/CSharp/wolfSSL-TLS-pq-ServerThreaded/wolfSSL-TLS-ServerThreaded.csproj b/CSharp/wolfSSL-TLS-pq-ServerThreaded/wolfSSL-TLS-ServerThreaded.csproj
new file mode 100644
index 00000000..5f49a915
--- /dev/null
+++ b/CSharp/wolfSSL-TLS-pq-ServerThreaded/wolfSSL-TLS-ServerThreaded.csproj
@@ -0,0 +1,124 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}
+ Exe
+ Properties
+ wolfSSL_TLS_ServerThreaded
+ wolfSSL-TLS-ServerThreaded
+ v4.8
+ 512
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ false
+ true
+
+
+
+ AnyCPU
+ true
+ full
+ false
+ $(SolutionDir)$(Configuration)\$(Platform)\
+ DEBUG;TRACE
+ prompt
+ 3
+
+
+ AnyCPU
+ pdbonly
+ true
+ $(SolutionDir)$(Configuration)\$(Platform)\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+ true
+ $(SolutionDir)$(Configuration)\$(Platform)\
+ DEBUG;TRACE
+ 4
+ full
+ x64
+ prompt
+ MinimumRecommendedRules.ruleset
+ true
+
+
+ $(SolutionDir)$(Configuration)\$(Platform)\
+ TRACE
+ true
+ pdbonly
+ x64
+ prompt
+ MinimumRecommendedRules.ruleset
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {52609808-0418-46d3-8e17-141927a1a39a}
+ wolfSSL_CSharp
+
+
+
+
+ False
+ Microsoft .NET Framework 4.5 %28x86 and x64%29
+ true
+
+
+ False
+ .NET Framework 3.5 SP1 Client Profile
+ false
+
+
+ False
+ .NET Framework 3.5 SP1
+ false
+
+
+
+
+
+
+
+
+
diff --git a/README.md b/README.md
index 433785d3..09ecc3fa 100644
--- a/README.md
+++ b/README.md
@@ -84,6 +84,15 @@ to encrypt files with different algorithms (aes, 3des, etc.)
Please see the [crypto/README.md](crypto/README.md) for further usage and details.
+
+
+#### CSharp (C# Wrapper Examples)
+
+This directory contains examples that demonstrate using the C# wrapper.
+
+Please see the [CSharp/README.md](CSharp/README.md) for further usage and details.
+
+
#### custom-io-callbacks (wolfSSL Custom IO Callbacks)