Skip to content

Commit 1852615

Browse files
Merge pull request #7610 from gasbytes/sni-wrappers
CSharp Wrapper SNI Support
2 parents 8d63fb5 + 453e2fa commit 1852615

12 files changed

Lines changed: 392 additions & 68 deletions

File tree

src/ssl.c

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20181,16 +20181,9 @@ VerifyCallback wolfSSL_CTX_get_verify_callback(WOLFSSL_CTX* ctx)
2018120181
return NULL;
2018220182
}
2018320183

20184-
2018520184
#ifdef HAVE_SNI
20186-
20187-
void wolfSSL_CTX_set_servername_callback(WOLFSSL_CTX* ctx, CallbackSniRecv cb)
20188-
{
20189-
WOLFSSL_ENTER("wolfSSL_CTX_set_servername_callback");
20190-
if (ctx)
20191-
ctx->sniRecvCb = cb;
20192-
}
20193-
20185+
/* this is a compatibily function, consider using
20186+
* wolfSSL_CTX_set_servername_callback */
2019420187
int wolfSSL_CTX_set_tlsext_servername_callback(WOLFSSL_CTX* ctx,
2019520188
CallbackSniRecv cb)
2019620189
{
@@ -20202,19 +20195,8 @@ int wolfSSL_CTX_set_tlsext_servername_callback(WOLFSSL_CTX* ctx,
2020220195
return WOLFSSL_FAILURE;
2020320196
}
2020420197

20205-
int wolfSSL_CTX_set_servername_arg(WOLFSSL_CTX* ctx, void* arg)
20206-
{
20207-
WOLFSSL_ENTER("wolfSSL_CTX_set_servername_arg");
20208-
if (ctx) {
20209-
ctx->sniRecvCbArg = arg;
20210-
return WOLFSSL_SUCCESS;
20211-
}
20212-
return WOLFSSL_FAILURE;
20213-
}
20214-
2021520198
#endif /* HAVE_SNI */
2021620199

20217-
2021820200
#ifndef NO_BIO
2021920201
void wolfSSL_ERR_load_BIO_strings(void) {
2022020202
WOLFSSL_ENTER("wolfSSL_ERR_load_BIO_strings");
@@ -20249,6 +20231,27 @@ void wolfSSL_THREADID_set_numeric(void* id, unsigned long val)
2024920231
* HAVE_LIGHTY || WOLFSSL_HAPROXY || WOLFSSL_OPENSSH ||
2025020232
* HAVE_SBLIM_SFCB)) */
2025120233

20234+
#ifdef HAVE_SNI
20235+
20236+
void wolfSSL_CTX_set_servername_callback(WOLFSSL_CTX* ctx, CallbackSniRecv cb)
20237+
{
20238+
WOLFSSL_ENTER("wolfSSL_CTX_set_servername_callback");
20239+
if (ctx)
20240+
ctx->sniRecvCb = cb;
20241+
}
20242+
20243+
20244+
int wolfSSL_CTX_set_servername_arg(WOLFSSL_CTX* ctx, void* arg)
20245+
{
20246+
WOLFSSL_ENTER("wolfSSL_CTX_set_servername_arg");
20247+
if (ctx) {
20248+
ctx->sniRecvCbArg = arg;
20249+
return WOLFSSL_SUCCESS;
20250+
}
20251+
return WOLFSSL_FAILURE;
20252+
}
20253+
20254+
#endif /* HAVE_SNI */
2025220255

2025320256
#if defined(OPENSSL_EXTRA)
2025420257

wolfssl/ssl.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3813,7 +3813,6 @@ WOLFSSL_API void* wolfSSL_CTX_GetHeap(WOLFSSL_CTX* ctx, WOLFSSL* ssl);
38133813
/* SNI types */
38143814
enum {
38153815
WOLFSSL_SNI_HOST_NAME = 0,
3816-
WOLFSSL_SNI_HOST_NAME_OUTER = 0,
38173816
};
38183817

38193818
WOLFSSL_ABI WOLFSSL_API int wolfSSL_UseSNI(WOLFSSL* ssl, unsigned char type,
@@ -4875,14 +4874,17 @@ typedef int (*CallbackSniRecv)(WOLFSSL *ssl, int *ret, void* exArg);
48754874

48764875
WOLFSSL_API void wolfSSL_CTX_set_servername_callback(WOLFSSL_CTX* ctx,
48774876
CallbackSniRecv cb);
4878-
WOLFSSL_API int wolfSSL_CTX_set_tlsext_servername_callback(WOLFSSL_CTX* ctx,
4879-
CallbackSniRecv cb);
48804877

48814878
WOLFSSL_API int wolfSSL_CTX_set_servername_arg(WOLFSSL_CTX* ctx, void* arg);
48824879
#endif
48834880

4884-
#if defined(OPENSSL_ALL) || defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) \
4885-
|| defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY)
4881+
#if defined(OPENSSL_ALL) || defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
4882+
defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY)
4883+
4884+
#ifdef HAVE_SNI
4885+
WOLFSSL_API int wolfSSL_CTX_set_tlsext_servername_callback(WOLFSSL_CTX* ctx,
4886+
CallbackSniRecv cb);
4887+
#endif
48864888

48874889
WOLFSSL_API void wolfSSL_ERR_remove_thread_state(void* pid);
48884890

wrapper/CSharp/README.md

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,17 @@ A Visual Studio solution `wolfSSL_CSharp.sln` is provided. This will allow you
2020
to build the wrapper library and examples. It includes the wolfSSL Visual Studio
2121
project directly.
2222

23-
## Linux (using Mono)
23+
## Linux (Ubuntu) using mono
2424

2525
Prerequisites for linux:
2626

2727
```
28-
apt install mono-tools-devel
28+
apt-get update
29+
apt-get upgrade
30+
apt-get install mono-complete
2931
```
3032

31-
Build wolfSSL and install:
33+
### Build wolfSSL and install
3234

3335
```
3436
./autogen.sh
@@ -38,24 +40,52 @@ make check
3840
sudo make install
3941
```
4042

41-
Build and run the wrapper:
43+
### Build and run the wrapper
44+
45+
From the wolfssl root directory:
4246

4347
```
4448
cd wrapper/CSharp
49+
```
50+
51+
Compile server:
4552

46-
csc wolfSSL_CSharp/wolfSSL.cs wolfSSL_CSharp/X509.cs \
47-
wolfSSL-TLS-Server/wolfSSL-TLS-Server.cs
53+
```
54+
mcs wolfSSL_CSharp/wolfSSL.cs wolfSSL_CSharp/X509.cs \
55+
wolfSSL-TLS-Server/wolfSSL-TLS-Server.cs -OUT:server.exe
56+
```
4857

49-
Run the example:
58+
Compile client:
5059

5160
```
52-
cp wolfSSL-TLS-Server.exe ../../certs
53-
cd ../../certs
61+
mcs wolfSSL_CSharp/wolfSSL.cs wolfSSL_CSharp/X509.cs \
62+
wolfSSL-TLS-Client/wolfSSL-TLS-Client.cs -OUT:client.exe
63+
```
64+
65+
### Run the example
66+
67+
In one terminal instance run the server:
68+
69+
```
70+
mono server.exe
71+
```
5472

55-
mono wolfSSL-TLS-Server.exe
73+
And in another terminal instance run the client:
5674

57-
Calling ctx Init from wolfSSL
58-
Finished init of ctx .... now load in cert and key
59-
Ciphers : TLS13-AES128-GCM-SHA256:TLS13-AES256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-CHACHA20-POLY1305:DHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305-OLD:ECDHE-ECDSA-CHACHA20-POLY1305-OLD:DHE-RSA-CHACHA20-POLY1305-OLD
60-
Started TCP and waiting for a connection
75+
```
76+
mono client.exe
77+
```
78+
79+
### Enabling SNI
80+
81+
To enable SNI, just pass the `-S` argument with the specified hostname to the client:
82+
83+
```
84+
mono client.exe -S hostname
85+
```
86+
87+
And run the server with the `-S` flag:
88+
89+
```
90+
mono server.exe -S
6191
```

wrapper/CSharp/wolfSSL-DTLS-PSK-Server/wolfSSL-DTLS-PSK-Server.cs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,14 @@ public static void Main(string[] args)
7878
IntPtr ssl;
7979

8080
/* These paths should be changed according to use */
81-
string fileCert = @"server-cert.pem";
82-
string fileKey = @"server-key.pem";
83-
StringBuilder dhparam = new StringBuilder("dh2048.pem");
81+
string fileCert = wolfssl.setPath("server-cert.pem");
82+
string fileKey = wolfssl.setPath("server-key.pem");
83+
StringBuilder dhparam = new StringBuilder(wolfssl.setPath("dh2048.pem"));
84+
85+
if (fileCert == "" || fileKey == "" || dhparam.Length == 0) {
86+
Console.WriteLine("Platform not supported");
87+
return;
88+
}
8489

8590
wolfssl.psk_delegate psk_cb = new wolfssl.psk_delegate(my_psk_server_cb);
8691

@@ -106,6 +111,12 @@ public static void Main(string[] args)
106111
return;
107112
}
108113

114+
if (!File.Exists(dhparam.ToString())) {
115+
Console.WriteLine("Could not find dh file");
116+
wolfssl.CTX_free(ctx);
117+
return;
118+
}
119+
109120

110121
if (wolfssl.CTX_use_certificate_file(ctx, fileCert, wolfssl.SSL_FILETYPE_PEM) != wolfssl.SUCCESS)
111122
{

wrapper/CSharp/wolfSSL-DTLS-Server/wolfSSL-DTLS-Server.cs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,14 @@ public static void Main(string[] args)
5858
IntPtr ssl;
5959

6060
/* These paths should be changed for use */
61-
string fileCert = @"server-cert.pem";
62-
string fileKey = @"server-key.pem";
63-
StringBuilder dhparam = new StringBuilder("dh2048.pem");
61+
string fileCert = wolfssl.setPath("server-cert.pem");
62+
string fileKey = wolfssl.setPath(@"server-key.pem");
63+
StringBuilder dhparam = new StringBuilder(wolfssl.setPath("dh2048.pem"));
64+
65+
if (fileCert == "" || fileKey == "" || dhparam.Length == 0) {
66+
Console.WriteLine("Platform not supported");
67+
return;
68+
}
6469

6570
StringBuilder buff = new StringBuilder(1024);
6671
StringBuilder reply = new StringBuilder("Hello, this is the wolfSSL C# wrapper");
@@ -87,6 +92,12 @@ public static void Main(string[] args)
8792
return;
8893
}
8994

95+
if (!File.Exists(dhparam.ToString())) {
96+
Console.WriteLine("Could not find dh file");
97+
wolfssl.CTX_free(ctx);
98+
return;
99+
}
100+
90101

91102
if (wolfssl.CTX_use_certificate_file(ctx, fileCert, wolfssl.SSL_FILETYPE_PEM) != wolfssl.SUCCESS)
92103
{

wrapper/CSharp/wolfSSL-Example-IOCallbacks/wolfSSL-Example-IOCallbacks.cs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -214,12 +214,17 @@ static void Main(string[] args)
214214
IntPtr ssl;
215215
Socket fd;
216216

217-
wolfssl.psk_delegate psk_cb = new wolfssl.psk_delegate(my_psk_server_cb);
218217
wolfssl.CallbackVerify_delegate verify_cb = new wolfssl.CallbackVerify_delegate(my_verify_cb);
219218

220219
/* These paths should be changed according to use */
221-
string fileCert = @"server-cert.pem";
222-
string fileKey = @"server-key.pem";
220+
string fileCert = wolfssl.setPath("server-cert.pem");
221+
string fileKey = wolfssl.setPath("server-key.pem");
222+
StringBuilder dhparam = new StringBuilder(wolfssl.setPath("dh2048.pem"));
223+
224+
if (fileCert == "" || fileKey == "" || dhparam.Length == 0) {
225+
Console.WriteLine("Platform not supported");
226+
return;
227+
}
223228

224229
StringBuilder buff = new StringBuilder(1024);
225230
StringBuilder reply = new StringBuilder("Hello, this is the wolfSSL C# wrapper");
@@ -242,6 +247,12 @@ static void Main(string[] args)
242247
return;
243248
}
244249

250+
if (!File.Exists(dhparam.ToString())) {
251+
Console.WriteLine("Could not find dh file");
252+
wolfssl.CTX_free(ctx);
253+
return;
254+
}
255+
245256
if (wolfssl.CTX_use_certificate_file(ctx, fileCert, wolfssl.SSL_FILETYPE_PEM) != wolfssl.SUCCESS)
246257
{
247258
Console.WriteLine("Error in setting cert file");

wrapper/CSharp/wolfSSL-TLS-Client/wolfSSL-TLS-Client.cs

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
2020
*/
2121

22-
2322
using System;
2423
using System.Runtime.InteropServices;
2524
using System.Text;
@@ -60,15 +59,39 @@ private static int myVerify(int preverify, IntPtr x509_ctx)
6059
return preverify;
6160
}
6261

62+
/// <summary>
63+
/// Checks if the SNI option was enabled via command line.
64+
/// Must be enabled with ./configure --enable-sni when configuring
65+
/// wolfSSL.
66+
/// <param name="args">Parameters passed via command line</param>
67+
/// </summary>
68+
private static int haveSNI(string[] args)
69+
{
70+
for (int i = 0; i < args.Length; i++) {
71+
if (args[i] == "-S") {
72+
Console.WriteLine("SNI IS ON");
73+
return i+1;
74+
}
75+
}
76+
Console.WriteLine("SNI IS OFF");
77+
return -1;
78+
}
79+
6380
public static void Main(string[] args)
6481
{
6582
IntPtr ctx;
6683
IntPtr ssl;
6784
Socket tcp;
85+
IntPtr sniHostName;
6886

6987
/* These paths should be changed for use */
70-
string caCert = @"ca-cert.pem";
71-
StringBuilder dhparam = new StringBuilder("dh2048.pem");
88+
string caCert = wolfssl.setPath("ca-cert.pem");
89+
StringBuilder dhparam = new StringBuilder(wolfssl.setPath("dh2048.pem"));
90+
91+
if (caCert == "" || dhparam.Length == 0) {
92+
Console.WriteLine("Platform not supported.");
93+
return;
94+
}
7295

7396
StringBuilder buff = new StringBuilder(1024);
7497
StringBuilder reply = new StringBuilder("Hello, this is the wolfSSL C# wrapper");
@@ -78,7 +101,6 @@ public static void Main(string[] args)
78101

79102
wolfssl.Init();
80103

81-
82104
Console.WriteLine("Calling ctx Init from wolfSSL");
83105
ctx = wolfssl.CTX_new(wolfssl.usev23_client());
84106
if (ctx == IntPtr.Zero)
@@ -96,11 +118,34 @@ public static void Main(string[] args)
96118
return;
97119
}
98120

121+
if (!File.Exists(dhparam.ToString())) {
122+
Console.WriteLine("Could not find dh file");
123+
wolfssl.CTX_free(ctx);
124+
return;
125+
}
99126

100127
if (wolfssl.CTX_load_verify_locations(ctx, caCert, null)
101128
!= wolfssl.SUCCESS)
102129
{
103130
Console.WriteLine("Error loading CA cert");
131+
wolfssl.CTX_free(ctx);
132+
return;
133+
}
134+
135+
int sniArg = haveSNI(args);
136+
if (sniArg >= 0)
137+
{
138+
string sniHostNameString = args[sniArg].Trim();
139+
sniHostName = Marshal.StringToHGlobalAnsi(sniHostNameString);
140+
141+
ushort size = (ushort)sniHostNameString.Length;
142+
143+
if (wolfssl.CTX_UseSNI(ctx, (byte)wolfssl.WOLFSSL_SNI_HOST_NAME, sniHostName, size) != wolfssl.SUCCESS)
144+
{
145+
Console.WriteLine("UseSNI failed");
146+
wolfssl.CTX_free(ctx);
147+
return;
148+
}
104149
}
105150

106151
StringBuilder ciphers = new StringBuilder(new String(' ', 4096));

wrapper/CSharp/wolfSSL-TLS-PSK-Client/wolfSSL-TLS-PSK-Client.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,11 @@ public static void Main(string[] args)
8282

8383
wolfssl.psk_client_delegate psk_cb = new wolfssl.psk_client_delegate(my_psk_client_cb);
8484

85-
StringBuilder dhparam = new StringBuilder("dh2048.pem");
85+
StringBuilder dhparam = new StringBuilder(wolfssl.setPath("dh2048.pem"));
86+
if (dhparam.Length == 0) {
87+
Console.WriteLine("Platform not supported");
88+
return;
89+
}
8690

8791
StringBuilder buff = new StringBuilder(1024);
8892
StringBuilder reply = new StringBuilder("Hello, this is the wolfSSL C# client psk wrapper");
@@ -157,6 +161,12 @@ public static void Main(string[] args)
157161
return;
158162
}
159163

164+
if (!File.Exists(dhparam.ToString())) {
165+
Console.WriteLine("Could not find dh file");
166+
wolfssl.CTX_free(ctx);
167+
return;
168+
}
169+
160170
wolfssl.SetTmpDH_file(ssl, dhparam, wolfssl.SSL_FILETYPE_PEM);
161171

162172
if (wolfssl.connect(ssl) != wolfssl.SUCCESS)

0 commit comments

Comments
 (0)