Skip to content

Commit

Permalink
Merge pull request #7610 from gasbytes/sni-wrappers
Browse files Browse the repository at this point in the history
CSharp Wrapper SNI Support
  • Loading branch information
JacobBarthelmeh authored Jun 5, 2024
2 parents 8d63fb5 + 453e2fa commit 1852615
Show file tree
Hide file tree
Showing 12 changed files with 392 additions and 68 deletions.
43 changes: 23 additions & 20 deletions src/ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -20181,16 +20181,9 @@ VerifyCallback wolfSSL_CTX_get_verify_callback(WOLFSSL_CTX* ctx)
return NULL;
}


#ifdef HAVE_SNI

void wolfSSL_CTX_set_servername_callback(WOLFSSL_CTX* ctx, CallbackSniRecv cb)
{
WOLFSSL_ENTER("wolfSSL_CTX_set_servername_callback");
if (ctx)
ctx->sniRecvCb = cb;
}

/* this is a compatibily function, consider using
* wolfSSL_CTX_set_servername_callback */
int wolfSSL_CTX_set_tlsext_servername_callback(WOLFSSL_CTX* ctx,
CallbackSniRecv cb)
{
Expand All @@ -20202,19 +20195,8 @@ int wolfSSL_CTX_set_tlsext_servername_callback(WOLFSSL_CTX* ctx,
return WOLFSSL_FAILURE;
}

int wolfSSL_CTX_set_servername_arg(WOLFSSL_CTX* ctx, void* arg)
{
WOLFSSL_ENTER("wolfSSL_CTX_set_servername_arg");
if (ctx) {
ctx->sniRecvCbArg = arg;
return WOLFSSL_SUCCESS;
}
return WOLFSSL_FAILURE;
}

#endif /* HAVE_SNI */


#ifndef NO_BIO
void wolfSSL_ERR_load_BIO_strings(void) {
WOLFSSL_ENTER("wolfSSL_ERR_load_BIO_strings");
Expand Down Expand Up @@ -20249,6 +20231,27 @@ void wolfSSL_THREADID_set_numeric(void* id, unsigned long val)
* HAVE_LIGHTY || WOLFSSL_HAPROXY || WOLFSSL_OPENSSH ||
* HAVE_SBLIM_SFCB)) */

#ifdef HAVE_SNI

void wolfSSL_CTX_set_servername_callback(WOLFSSL_CTX* ctx, CallbackSniRecv cb)
{
WOLFSSL_ENTER("wolfSSL_CTX_set_servername_callback");
if (ctx)
ctx->sniRecvCb = cb;
}


int wolfSSL_CTX_set_servername_arg(WOLFSSL_CTX* ctx, void* arg)
{
WOLFSSL_ENTER("wolfSSL_CTX_set_servername_arg");
if (ctx) {
ctx->sniRecvCbArg = arg;
return WOLFSSL_SUCCESS;
}
return WOLFSSL_FAILURE;
}

#endif /* HAVE_SNI */

#if defined(OPENSSL_EXTRA)

Expand Down
12 changes: 7 additions & 5 deletions wolfssl/ssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -3813,7 +3813,6 @@ WOLFSSL_API void* wolfSSL_CTX_GetHeap(WOLFSSL_CTX* ctx, WOLFSSL* ssl);
/* SNI types */
enum {
WOLFSSL_SNI_HOST_NAME = 0,
WOLFSSL_SNI_HOST_NAME_OUTER = 0,
};

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

WOLFSSL_API void wolfSSL_CTX_set_servername_callback(WOLFSSL_CTX* ctx,
CallbackSniRecv cb);
WOLFSSL_API int wolfSSL_CTX_set_tlsext_servername_callback(WOLFSSL_CTX* ctx,
CallbackSniRecv cb);

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

#if defined(OPENSSL_ALL) || defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) \
|| defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY)
#if defined(OPENSSL_ALL) || defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY)

#ifdef HAVE_SNI
WOLFSSL_API int wolfSSL_CTX_set_tlsext_servername_callback(WOLFSSL_CTX* ctx,
CallbackSniRecv cb);
#endif

WOLFSSL_API void wolfSSL_ERR_remove_thread_state(void* pid);

Expand Down
58 changes: 44 additions & 14 deletions wrapper/CSharp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,17 @@ A Visual Studio solution `wolfSSL_CSharp.sln` is provided. This will allow you
to build the wrapper library and examples. It includes the wolfSSL Visual Studio
project directly.

## Linux (using Mono)
## Linux (Ubuntu) using mono

Prerequisites for linux:

```
apt install mono-tools-devel
apt-get update
apt-get upgrade
apt-get install mono-complete
```

Build wolfSSL and install:
### Build wolfSSL and install

```
./autogen.sh
Expand All @@ -38,24 +40,52 @@ make check
sudo make install
```

Build and run the wrapper:
### Build and run the wrapper

From the wolfssl root directory:

```
cd wrapper/CSharp
```

Compile server:

csc wolfSSL_CSharp/wolfSSL.cs wolfSSL_CSharp/X509.cs \
wolfSSL-TLS-Server/wolfSSL-TLS-Server.cs
```
mcs wolfSSL_CSharp/wolfSSL.cs wolfSSL_CSharp/X509.cs \
wolfSSL-TLS-Server/wolfSSL-TLS-Server.cs -OUT:server.exe
```

Run the example:
Compile client:

```
cp wolfSSL-TLS-Server.exe ../../certs
cd ../../certs
mcs wolfSSL_CSharp/wolfSSL.cs wolfSSL_CSharp/X509.cs \
wolfSSL-TLS-Client/wolfSSL-TLS-Client.cs -OUT:client.exe
```

### Run the example

In one terminal instance run the server:

```
mono server.exe
```

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

Calling ctx Init from wolfSSL
Finished init of ctx .... now load in cert and key
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
Started TCP and waiting for a connection
```
mono client.exe
```

### Enabling SNI

To enable SNI, just pass the `-S` argument with the specified hostname to the client:

```
mono client.exe -S hostname
```

And run the server with the `-S` flag:

```
mono server.exe -S
```
17 changes: 14 additions & 3 deletions wrapper/CSharp/wolfSSL-DTLS-PSK-Server/wolfSSL-DTLS-PSK-Server.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,14 @@ public static void Main(string[] args)
IntPtr ssl;

/* These paths should be changed according to use */
string fileCert = @"server-cert.pem";
string fileKey = @"server-key.pem";
StringBuilder dhparam = new StringBuilder("dh2048.pem");
string fileCert = wolfssl.setPath("server-cert.pem");
string fileKey = wolfssl.setPath("server-key.pem");
StringBuilder dhparam = new StringBuilder(wolfssl.setPath("dh2048.pem"));

if (fileCert == "" || fileKey == "" || dhparam.Length == 0) {
Console.WriteLine("Platform not supported");
return;
}

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

Expand All @@ -106,6 +111,12 @@ public static void Main(string[] args)
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)
{
Expand Down
17 changes: 14 additions & 3 deletions wrapper/CSharp/wolfSSL-DTLS-Server/wolfSSL-DTLS-Server.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,14 @@ public static void Main(string[] args)
IntPtr ssl;

/* These paths should be changed for use */
string fileCert = @"server-cert.pem";
string fileKey = @"server-key.pem";
StringBuilder dhparam = new StringBuilder("dh2048.pem");
string fileCert = wolfssl.setPath("server-cert.pem");
string fileKey = wolfssl.setPath(@"server-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");
Expand All @@ -87,6 +92,12 @@ public static void Main(string[] args)
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)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,12 +214,17 @@ static void Main(string[] args)
IntPtr ssl;
Socket fd;

wolfssl.psk_delegate psk_cb = new wolfssl.psk_delegate(my_psk_server_cb);
wolfssl.CallbackVerify_delegate verify_cb = new wolfssl.CallbackVerify_delegate(my_verify_cb);

/* These paths should be changed according to use */
string fileCert = @"server-cert.pem";
string fileKey = @"server-key.pem";
string fileCert = wolfssl.setPath("server-cert.pem");
string fileKey = wolfssl.setPath("server-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");
Expand All @@ -242,6 +247,12 @@ static void Main(string[] args)
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");
Expand Down
53 changes: 49 additions & 4 deletions wrapper/CSharp/wolfSSL-TLS-Client/wolfSSL-TLS-Client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/


using System;
using System.Runtime.InteropServices;
using System.Text;
Expand Down Expand Up @@ -60,15 +59,39 @@ private static int myVerify(int preverify, IntPtr x509_ctx)
return preverify;
}

/// <summary>
/// Checks if the SNI option was enabled via command line.
/// Must be enabled with ./configure --enable-sni when configuring
/// wolfSSL.
/// <param name="args">Parameters passed via command line</param>
/// </summary>
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 = @"ca-cert.pem";
StringBuilder dhparam = new StringBuilder("dh2048.pem");
string caCert = wolfssl.setPath("ca-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");
Expand All @@ -78,7 +101,6 @@ public static void Main(string[] args)

wolfssl.Init();


Console.WriteLine("Calling ctx Init from wolfSSL");
ctx = wolfssl.CTX_new(wolfssl.usev23_client());
if (ctx == IntPtr.Zero)
Expand All @@ -96,11 +118,34 @@ public static void Main(string[] args)
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));
Expand Down
12 changes: 11 additions & 1 deletion wrapper/CSharp/wolfSSL-TLS-PSK-Client/wolfSSL-TLS-PSK-Client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,11 @@ public static void Main(string[] args)

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

StringBuilder dhparam = new StringBuilder("dh2048.pem");
StringBuilder dhparam = new StringBuilder(wolfssl.setPath("dh2048.pem"));
if (dhparam.Length == 0) {
Console.WriteLine("Platform not supported");
return;
}

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

if (!File.Exists(dhparam.ToString())) {
Console.WriteLine("Could not find dh file");
wolfssl.CTX_free(ctx);
return;
}

wolfssl.SetTmpDH_file(ssl, dhparam, wolfssl.SSL_FILETYPE_PEM);

if (wolfssl.connect(ssl) != wolfssl.SUCCESS)
Expand Down
Loading

0 comments on commit 1852615

Please sign in to comment.