Skip to content

Commit 1e7e5b2

Browse files
authored
Merge pull request #514 from tamasan238/windows-pqc
Add C# examples using ML-KEM/ML-DSA
2 parents 9180ab5 + 2050cc2 commit 1e7e5b2

File tree

14 files changed

+1320
-0
lines changed

14 files changed

+1320
-0
lines changed

CSharp/README.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# C# Wrapper Examples
2+
3+
This directory contains examples that demonstrate using the C# wrapper.
4+
5+
These assume the use of `wolfssl\wrapper\CSharp\wolfSSL_CSharp.sln`.
6+
7+
## wolfSSL-TLS-pq
8+
9+
wolfSSL Server and Client using PQC algorithms (ML-KEM / ML-DSA).
10+
11+
### Build Options
12+
13+
The following build options need to be added.
14+
15+
#### for `wolfssl` Project
16+
17+
```
18+
HAVE_MLKEM
19+
WOLFSSL_WC_MLKEM
20+
WOLFSSL_HAVE_MLKEM
21+
WOLFSSL_DTLS_CH_FRAG
22+
HAVE_DILITHIUM
23+
WOLFSSL_WC_DILITHIUM
24+
WOLFSSL_SHAKE128
25+
WOLFSSL_SHAKE256
26+
```
27+
28+
#### for `wolfSSL_CSharp` Project
29+
30+
```
31+
HAVE_MLKEM
32+
HAVE_MLDSA
33+
```
34+
35+
If you want to execute `wolfCrypt-Test` Project as well, add these options to `wolfCrypt-Test` Project.
36+
37+
### wolfSSL-TLS-pq-Server
38+
39+
wolfSSL Server using ML-DSA-87.
40+
41+
### wolfSSL-TLS-pq-ServerThreaded
42+
43+
Threaded version of `wolfSSL-TLS-pq-Server`.
44+
45+
### wolfSSL-TLS-pq-Client
46+
47+
wolfSSL Client using ML-KEM-1024/ML-DSA-87.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<configuration>
3+
<startup>
4+
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/>
5+
</startup>
6+
</configuration>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System.Reflection;
2+
using System.Runtime.CompilerServices;
3+
using System.Runtime.InteropServices;
4+
5+
// General Information about an assembly is controlled through the following
6+
// set of attributes. Change these attribute values to modify the information
7+
// associated with an assembly.
8+
[assembly: AssemblyTitle("wolfSSL-TLS-Client")]
9+
[assembly: AssemblyDescription("")]
10+
[assembly: AssemblyConfiguration("")]
11+
[assembly: AssemblyCompany("wolfSSL")]
12+
[assembly: AssemblyProduct("wolfSSL-TLS-Client")]
13+
[assembly: AssemblyCopyright("Copyright wolfSSL 2020")]
14+
[assembly: AssemblyTrademark("")]
15+
[assembly: AssemblyCulture("")]
16+
17+
// Setting ComVisible to false makes the types in this assembly not visible
18+
// to COM components. If you need to access a type in this assembly from
19+
// COM, set the ComVisible attribute to true on that type.
20+
[assembly: ComVisible(false)]
21+
22+
// The following GUID is for the ID of the typelib if this project is exposed to COM
23+
[assembly: Guid("05aad2b4-445e-4f0e-8e16-8f8512696505")]
24+
25+
// Version information for an assembly consists of the following four values:
26+
//
27+
// Major Version
28+
// Minor Version
29+
// Build Number
30+
// Revision
31+
//
32+
// You can specify all the values or you can default the Build and Revision Numbers
33+
// by using the '*' as shown below:
34+
// [assembly: AssemblyVersion("1.0.*")]
35+
[assembly: AssemblyVersion("1.1.0.0")]
36+
[assembly: AssemblyFileVersion("1.1.0.0")]
Lines changed: 272 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
/* wolfSSL-TLS-Client.cs
2+
*
3+
* Copyright (C) 2006-2025 wolfSSL Inc.
4+
*
5+
* This file is part of wolfSSL.
6+
*
7+
* wolfSSL is free software; you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation; either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* wolfSSL is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program; if not, write to the Free Software
19+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20+
*/
21+
22+
using System;
23+
using System.Runtime.InteropServices;
24+
using System.Text;
25+
using System.IO;
26+
using System.Net;
27+
using System.Net.Sockets;
28+
using wolfSSL.CSharp;
29+
30+
public class wolfSSL_TLS_Client
31+
{
32+
/// <summary>
33+
/// Example of a logging function
34+
/// </summary>
35+
/// <param name="lvl">level of log</param>
36+
/// <param name="msg">message to log</param>
37+
public static void standard_log(int lvl, StringBuilder msg)
38+
{
39+
Console.WriteLine(msg);
40+
}
41+
42+
43+
private static void clean(IntPtr ssl, IntPtr ctx)
44+
{
45+
wolfssl.free(ssl);
46+
wolfssl.CTX_free(ctx);
47+
wolfssl.Cleanup();
48+
}
49+
50+
/// <summary>
51+
/// Verification callback
52+
/// </summary>
53+
/// <param name="preverify">1=Verify Okay, 0=Failure</param>
54+
/// <param name="x509_ctx">Certificate in WOLFSSL_X509_STORE_CTX format</param>
55+
private static int myVerify(int preverify, IntPtr x509_ctx)
56+
{
57+
int verify = preverify;
58+
Console.WriteLine("myVerify is called.");
59+
60+
/* example for overriding an error code */
61+
/* X509_STORE_CTX_get_error API can be enabled with
62+
* OPENSSL_EXTRA_X509_SMALL or WOLFSSL_EXTRA */
63+
int error = wolfssl.X509_STORE_CTX_get_error(x509_ctx);
64+
if (error == wolfcrypt.ASN_BEFORE_DATE_E) {
65+
verify = 1; /* override error */
66+
}
67+
68+
/* Can optionally override failures by returning non-zero value */
69+
return verify;
70+
}
71+
72+
/// <summary>
73+
/// Checks if the SNI option was enabled via command line.
74+
/// Must be enabled with ./configure --enable-sni when configuring
75+
/// wolfSSL.
76+
/// <param name="args">Parameters passed via command line</param>
77+
/// </summary>
78+
private static int haveSNI(string[] args)
79+
{
80+
for (int i = 0; i < args.Length; i++) {
81+
if (args[i] == "-S") {
82+
Console.WriteLine("SNI IS ON");
83+
return i+1;
84+
}
85+
}
86+
Console.WriteLine("SNI IS OFF");
87+
return -1;
88+
}
89+
90+
public static void Main(string[] args)
91+
{
92+
IntPtr ctx;
93+
IntPtr ssl;
94+
Socket tcp;
95+
IntPtr sniHostName;
96+
97+
/* These paths should be changed for use */
98+
string caCert = wolfssl.setPath("mldsa87_root_cert.pem");
99+
StringBuilder dhparam = new StringBuilder(wolfssl.setPath("dh2048.pem"));
100+
101+
if (caCert == "" || dhparam.Length == 0) {
102+
Console.WriteLine("Platform not supported.");
103+
return;
104+
}
105+
106+
StringBuilder buff = new StringBuilder(1024);
107+
StringBuilder reply = new StringBuilder("Hello, this is the wolfSSL C# wrapper");
108+
109+
//example of function used for setting logging
110+
wolfssl.SetLogging(standard_log);
111+
112+
wolfssl.Init();
113+
114+
Console.WriteLine("Calling ctx Init from wolfSSL");
115+
ctx = wolfssl.CTX_new(wolfssl.usev23_client());
116+
if (ctx == IntPtr.Zero)
117+
{
118+
Console.WriteLine("Error in creating ctx structure");
119+
return;
120+
}
121+
Console.WriteLine("Finished init of ctx .... now load in CA");
122+
123+
124+
if (!File.Exists(caCert))
125+
{
126+
Console.WriteLine("Could not find CA cert file");
127+
wolfssl.CTX_free(ctx);
128+
return;
129+
}
130+
131+
if (!File.Exists(dhparam.ToString())) {
132+
Console.WriteLine("Could not find dh file");
133+
wolfssl.CTX_free(ctx);
134+
return;
135+
}
136+
137+
if (wolfssl.CTX_load_verify_locations(ctx, caCert, null)
138+
!= wolfssl.SUCCESS)
139+
{
140+
Console.WriteLine("Error loading CA cert");
141+
wolfssl.CTX_free(ctx);
142+
return;
143+
}
144+
145+
int sniArg = haveSNI(args);
146+
if (sniArg >= 0)
147+
{
148+
string sniHostNameString = args[sniArg].Trim();
149+
sniHostName = Marshal.StringToHGlobalAnsi(sniHostNameString);
150+
151+
ushort size = (ushort)sniHostNameString.Length;
152+
153+
if (wolfssl.CTX_UseSNI(ctx, (byte)wolfssl.WOLFSSL_SNI_HOST_NAME, sniHostName, size) != wolfssl.SUCCESS)
154+
{
155+
Console.WriteLine("UseSNI failed");
156+
wolfssl.CTX_free(ctx);
157+
return;
158+
}
159+
}
160+
161+
StringBuilder ciphers = new StringBuilder(new String(' ', 4096));
162+
wolfssl.get_ciphers(ciphers, 4096);
163+
Console.WriteLine("Ciphers : " + ciphers.ToString());
164+
165+
/* Uncomment Section to enable specific cipher suite */
166+
#if false
167+
ciphers = new StringBuilder("ECDHE-ECDSA-AES128-GCM-SHA256");
168+
if (wolfssl.CTX_set_cipher_list(ctx, ciphers) != wolfssl.SUCCESS)
169+
{
170+
Console.WriteLine("ERROR CTX_set_cipher_list()");
171+
wolfssl.CTX_free(ctx);
172+
return;
173+
}
174+
#endif
175+
176+
short minDhKey = 128;
177+
wolfssl.CTX_SetMinDhKey_Sz(ctx, minDhKey);
178+
179+
/* Setup Verify Callback */
180+
if (wolfssl.CTX_set_verify(ctx, wolfssl.SSL_VERIFY_PEER, myVerify)
181+
!= wolfssl.SUCCESS)
182+
{
183+
Console.WriteLine("Error setting verify callback!");
184+
}
185+
186+
187+
/* set up TCP socket */
188+
tcp = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
189+
ProtocolType.Tcp);
190+
try
191+
{
192+
tcp.Connect("localhost", 11111);
193+
}
194+
catch (Exception e)
195+
{
196+
Console.WriteLine("tcp.Connect() error " + e.ToString());
197+
wolfssl.CTX_free(ctx);
198+
return;
199+
}
200+
if (!tcp.Connected)
201+
{
202+
Console.WriteLine("tcp.Connect() failed!");
203+
tcp.Close();
204+
wolfssl.CTX_free(ctx);
205+
return;
206+
}
207+
208+
Console.WriteLine("Connected TCP");
209+
ssl = wolfssl.new_ssl(ctx);
210+
if (ssl == IntPtr.Zero)
211+
{
212+
Console.WriteLine("Error in creating ssl object");
213+
wolfssl.CTX_free(ctx);
214+
return;
215+
}
216+
217+
if (wolfssl.UseKeyShare(ssl, wolfssl.NamedGroup.WOLFSSL_ML_KEM_1024) != wolfssl.SUCCESS)
218+
{
219+
Console.WriteLine("Error enabling ML-KEM key share");
220+
wolfssl.CTX_free(ctx);
221+
return;
222+
}
223+
224+
Console.WriteLine("Connection made wolfSSL_connect ");
225+
if (wolfssl.set_fd(ssl, tcp) != wolfssl.SUCCESS)
226+
{
227+
/* get and print out the error */
228+
Console.WriteLine(wolfssl.get_error(ssl));
229+
tcp.Close();
230+
clean(ssl, ctx);
231+
return;
232+
}
233+
234+
wolfssl.SetTmpDH_file(ssl, dhparam, wolfssl.SSL_FILETYPE_PEM);
235+
236+
if (wolfssl.connect(ssl) != wolfssl.SUCCESS)
237+
{
238+
/* get and print out the error */
239+
Console.WriteLine(wolfssl.get_error(ssl));
240+
tcp.Close();
241+
clean(ssl, ctx);
242+
return;
243+
}
244+
245+
/* print out results of TLS/SSL accept */
246+
Console.WriteLine("SSL version is " + wolfssl.get_version(ssl));
247+
Console.WriteLine("SSL cipher suite is " + wolfssl.get_current_cipher(ssl));
248+
249+
250+
if (wolfssl.write(ssl, reply, reply.Length) != reply.Length)
251+
{
252+
Console.WriteLine("Error in write");
253+
tcp.Close();
254+
clean(ssl, ctx);
255+
return;
256+
}
257+
258+
/* read and print out the message then reply */
259+
if (wolfssl.read(ssl, buff, 1023) < 0)
260+
{
261+
Console.WriteLine("Error in read");
262+
tcp.Close();
263+
clean(ssl, ctx);
264+
return;
265+
}
266+
Console.WriteLine(buff);
267+
268+
wolfssl.shutdown(ssl);
269+
tcp.Close();
270+
clean(ssl, ctx);
271+
}
272+
}

0 commit comments

Comments
 (0)