Merge pull request #7610 from gasbytes/sni-wrappers

CSharp Wrapper SNI Support
This commit is contained in:
JacobBarthelmeh
2024-06-05 10:27:42 -06:00
committed by GitHub
12 changed files with 395 additions and 71 deletions

View File

@@ -20181,16 +20181,9 @@ VerifyCallback wolfSSL_CTX_get_verify_callback(WOLFSSL_CTX* ctx)
return NULL; return NULL;
} }
#ifdef HAVE_SNI #ifdef HAVE_SNI
/* this is a compatibily function, consider using
void wolfSSL_CTX_set_servername_callback(WOLFSSL_CTX* ctx, CallbackSniRecv cb) * wolfSSL_CTX_set_servername_callback */
{
WOLFSSL_ENTER("wolfSSL_CTX_set_servername_callback");
if (ctx)
ctx->sniRecvCb = cb;
}
int wolfSSL_CTX_set_tlsext_servername_callback(WOLFSSL_CTX* ctx, int wolfSSL_CTX_set_tlsext_servername_callback(WOLFSSL_CTX* ctx,
CallbackSniRecv cb) CallbackSniRecv cb)
{ {
@@ -20202,19 +20195,8 @@ int wolfSSL_CTX_set_tlsext_servername_callback(WOLFSSL_CTX* ctx,
return WOLFSSL_FAILURE; 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 */ #endif /* HAVE_SNI */
#ifndef NO_BIO #ifndef NO_BIO
void wolfSSL_ERR_load_BIO_strings(void) { void wolfSSL_ERR_load_BIO_strings(void) {
WOLFSSL_ENTER("wolfSSL_ERR_load_BIO_strings"); WOLFSSL_ENTER("wolfSSL_ERR_load_BIO_strings");
@@ -20249,6 +20231,27 @@ void wolfSSL_THREADID_set_numeric(void* id, unsigned long val)
* HAVE_LIGHTY || WOLFSSL_HAPROXY || WOLFSSL_OPENSSH || * HAVE_LIGHTY || WOLFSSL_HAPROXY || WOLFSSL_OPENSSH ||
* HAVE_SBLIM_SFCB)) */ * 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) #if defined(OPENSSL_EXTRA)

View File

@@ -3813,7 +3813,6 @@ WOLFSSL_API void* wolfSSL_CTX_GetHeap(WOLFSSL_CTX* ctx, WOLFSSL* ssl);
/* SNI types */ /* SNI types */
enum { enum {
WOLFSSL_SNI_HOST_NAME = 0, WOLFSSL_SNI_HOST_NAME = 0,
WOLFSSL_SNI_HOST_NAME_OUTER = 0,
}; };
WOLFSSL_ABI WOLFSSL_API int wolfSSL_UseSNI(WOLFSSL* ssl, unsigned char type, 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);
WOLFSSL_API void wolfSSL_CTX_set_servername_callback(WOLFSSL_CTX* ctx, WOLFSSL_API void wolfSSL_CTX_set_servername_callback(WOLFSSL_CTX* ctx,
CallbackSniRecv cb); 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); WOLFSSL_API int wolfSSL_CTX_set_servername_arg(WOLFSSL_CTX* ctx, void* arg);
#endif #endif
#if defined(OPENSSL_ALL) || defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) \ #if defined(OPENSSL_ALL) || defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
|| defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) 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); WOLFSSL_API void wolfSSL_ERR_remove_thread_state(void* pid);

View File

@@ -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 to build the wrapper library and examples. It includes the wolfSSL Visual Studio
project directly. project directly.
## Linux (using Mono) ## Linux (Ubuntu) using mono
Prerequisites for linux: 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 ./autogen.sh
@@ -38,24 +40,52 @@ make check
sudo make install sudo make install
``` ```
Build and run the wrapper: ### Build and run the wrapper
From the wolfssl root directory:
``` ```
cd wrapper/CSharp cd wrapper/CSharp
```
csc wolfSSL_CSharp/wolfSSL.cs wolfSSL_CSharp/X509.cs \ Compile server:
wolfSSL-TLS-Server/wolfSSL-TLS-Server.cs
Run the example:
``` ```
cp wolfSSL-TLS-Server.exe ../../certs mcs wolfSSL_CSharp/wolfSSL.cs wolfSSL_CSharp/X509.cs \
cd ../../certs wolfSSL-TLS-Server/wolfSSL-TLS-Server.cs -OUT:server.exe
```
mono wolfSSL-TLS-Server.exe
Compile 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 mcs wolfSSL_CSharp/wolfSSL.cs wolfSSL_CSharp/X509.cs \
Started TCP and waiting for a connection wolfSSL-TLS-Client/wolfSSL-TLS-Client.cs -OUT:client.exe
```
### Run the example
In one terminal instance run the server:
```
mono server.exe
```
And in another terminal instance run the client:
```
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
``` ```

View File

@@ -78,9 +78,14 @@ public class wolfSSL_DTLS_PSK_Server
IntPtr ssl; IntPtr ssl;
/* These paths should be changed according to use */ /* These paths should be changed according to use */
string fileCert = @"server-cert.pem"; string fileCert = wolfssl.setPath("server-cert.pem");
string fileKey = @"server-key.pem"; string fileKey = wolfssl.setPath("server-key.pem");
StringBuilder dhparam = new StringBuilder("dh2048.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); wolfssl.psk_delegate psk_cb = new wolfssl.psk_delegate(my_psk_server_cb);
@@ -106,6 +111,12 @@ public class wolfSSL_DTLS_PSK_Server
return; 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) if (wolfssl.CTX_use_certificate_file(ctx, fileCert, wolfssl.SSL_FILETYPE_PEM) != wolfssl.SUCCESS)
{ {

View File

@@ -58,9 +58,14 @@ public class wolfSSL_DTLS_Server
IntPtr ssl; IntPtr ssl;
/* These paths should be changed for use */ /* These paths should be changed for use */
string fileCert = @"server-cert.pem"; string fileCert = wolfssl.setPath("server-cert.pem");
string fileKey = @"server-key.pem"; string fileKey = wolfssl.setPath(@"server-key.pem");
StringBuilder dhparam = new StringBuilder("dh2048.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 buff = new StringBuilder(1024);
StringBuilder reply = new StringBuilder("Hello, this is the wolfSSL C# wrapper"); StringBuilder reply = new StringBuilder("Hello, this is the wolfSSL C# wrapper");
@@ -87,6 +92,12 @@ public class wolfSSL_DTLS_Server
return; 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) if (wolfssl.CTX_use_certificate_file(ctx, fileCert, wolfssl.SSL_FILETYPE_PEM) != wolfssl.SUCCESS)
{ {

View File

@@ -214,12 +214,17 @@ class wolfSSL_Example_IOCallbacks
IntPtr ssl; IntPtr ssl;
Socket fd; 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); wolfssl.CallbackVerify_delegate verify_cb = new wolfssl.CallbackVerify_delegate(my_verify_cb);
/* These paths should be changed according to use */ /* These paths should be changed according to use */
string fileCert = @"server-cert.pem"; string fileCert = wolfssl.setPath("server-cert.pem");
string fileKey = @"server-key.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 buff = new StringBuilder(1024);
StringBuilder reply = new StringBuilder("Hello, this is the wolfSSL C# wrapper"); StringBuilder reply = new StringBuilder("Hello, this is the wolfSSL C# wrapper");
@@ -242,6 +247,12 @@ class wolfSSL_Example_IOCallbacks
return; 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) if (wolfssl.CTX_use_certificate_file(ctx, fileCert, wolfssl.SSL_FILETYPE_PEM) != wolfssl.SUCCESS)
{ {
Console.WriteLine("Error in setting cert file"); Console.WriteLine("Error in setting cert file");

View File

@@ -19,7 +19,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/ */
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
@@ -60,15 +59,39 @@ public class wolfSSL_TLS_Client
return preverify; 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) public static void Main(string[] args)
{ {
IntPtr ctx; IntPtr ctx;
IntPtr ssl; IntPtr ssl;
Socket tcp; Socket tcp;
IntPtr sniHostName;
/* These paths should be changed for use */ /* These paths should be changed for use */
string caCert = @"ca-cert.pem"; string caCert = wolfssl.setPath("ca-cert.pem");
StringBuilder dhparam = new StringBuilder("dh2048.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 buff = new StringBuilder(1024);
StringBuilder reply = new StringBuilder("Hello, this is the wolfSSL C# wrapper"); StringBuilder reply = new StringBuilder("Hello, this is the wolfSSL C# wrapper");
@@ -78,7 +101,6 @@ public class wolfSSL_TLS_Client
wolfssl.Init(); wolfssl.Init();
Console.WriteLine("Calling ctx Init from wolfSSL"); Console.WriteLine("Calling ctx Init from wolfSSL");
ctx = wolfssl.CTX_new(wolfssl.usev23_client()); ctx = wolfssl.CTX_new(wolfssl.usev23_client());
if (ctx == IntPtr.Zero) if (ctx == IntPtr.Zero)
@@ -96,11 +118,34 @@ public class wolfSSL_TLS_Client
return; 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) if (wolfssl.CTX_load_verify_locations(ctx, caCert, null)
!= wolfssl.SUCCESS) != wolfssl.SUCCESS)
{ {
Console.WriteLine("Error loading CA cert"); 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)); StringBuilder ciphers = new StringBuilder(new String(' ', 4096));

View File

@@ -82,7 +82,11 @@ public class wolfSSL_TLS_PSK_Client
wolfssl.psk_client_delegate psk_cb = new wolfssl.psk_client_delegate(my_psk_client_cb); 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 buff = new StringBuilder(1024);
StringBuilder reply = new StringBuilder("Hello, this is the wolfSSL C# client psk wrapper"); StringBuilder reply = new StringBuilder("Hello, this is the wolfSSL C# client psk wrapper");
@@ -157,6 +161,12 @@ public class wolfSSL_TLS_PSK_Client
return; 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); wolfssl.SetTmpDH_file(ssl, dhparam, wolfssl.SSL_FILETYPE_PEM);
if (wolfssl.connect(ssl) != wolfssl.SUCCESS) if (wolfssl.connect(ssl) != wolfssl.SUCCESS)

View File

@@ -80,9 +80,14 @@ public class wolfSSL_TLS_PSK_Server
wolfssl.psk_delegate psk_cb = new wolfssl.psk_delegate(my_psk_server_cb); wolfssl.psk_delegate psk_cb = new wolfssl.psk_delegate(my_psk_server_cb);
/* These paths should be changed according to use */ /* These paths should be changed according to use */
string fileCert = @"server-cert.pem"; string fileCert = wolfssl.setPath("server-cert.pem");
string fileKey = @"server-key.pem"; string fileKey = wolfssl.setPath("server-key.pem");
StringBuilder dhparam = new StringBuilder("dh2048.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 buff = new StringBuilder(1024);
StringBuilder reply = new StringBuilder("Hello, this is the wolfSSL C# wrapper"); StringBuilder reply = new StringBuilder("Hello, this is the wolfSSL C# wrapper");
@@ -105,6 +110,12 @@ public class wolfSSL_TLS_PSK_Server
return; 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) if (wolfssl.CTX_use_certificate_file(ctx, fileCert, wolfssl.SSL_FILETYPE_PEM) != wolfssl.SUCCESS)
{ {
Console.WriteLine("Error in setting cert file"); Console.WriteLine("Error in setting cert file");

View File

@@ -19,9 +19,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/ */
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
@@ -50,17 +47,55 @@ public class wolfSSL_TLS_CSHarp
wolfssl.Cleanup(); wolfssl.Cleanup();
} }
/// <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 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;
}
/// <summary>
/// Example of a SNI function call back
/// </summary>
/// <param name="ssl">pointer to ssl structure</param>
/// <param name="ret">alert code</param>
/// <param name="exArg">context arg, can be set with the function wolfssl.CTX_set_servername_arg</param>
/// <returns></returns>
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) public static void Main(string[] args)
{ {
IntPtr ctx; IntPtr ctx;
IntPtr ssl; IntPtr ssl;
Socket fd; Socket fd;
IntPtr arg_sni;
/* These paths should be changed for use */ /* These paths should be changed for use */
string fileCert = @"server-cert.pem"; string fileCert = wolfssl.setPath("server-cert.pem");
string fileKey = @"server-key.pem"; string fileKey = wolfssl.setPath("server-key.pem");
StringBuilder dhparam = new StringBuilder("dh2048.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 buff = new StringBuilder(1024);
StringBuilder reply = new StringBuilder("Hello, this is the wolfSSL C# wrapper"); StringBuilder reply = new StringBuilder("Hello, this is the wolfSSL C# wrapper");
@@ -70,7 +105,6 @@ public class wolfSSL_TLS_CSHarp
wolfssl.Init(); wolfssl.Init();
Console.WriteLine("Calling ctx Init from wolfSSL"); Console.WriteLine("Calling ctx Init from wolfSSL");
ctx = wolfssl.CTX_new(wolfssl.usev23_server()); ctx = wolfssl.CTX_new(wolfssl.usev23_server());
if (ctx == IntPtr.Zero) if (ctx == IntPtr.Zero)
@@ -87,6 +121,12 @@ public class wolfSSL_TLS_CSHarp
return; 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) if (wolfssl.CTX_use_certificate_file(ctx, fileCert, wolfssl.SSL_FILETYPE_PEM) != wolfssl.SUCCESS)
{ {
Console.WriteLine("Error in setting cert file"); Console.WriteLine("Error in setting cert file");
@@ -101,7 +141,6 @@ public class wolfSSL_TLS_CSHarp
return; return;
} }
StringBuilder ciphers = new StringBuilder(new String(' ', 4096)); StringBuilder ciphers = new StringBuilder(new String(' ', 4096));
wolfssl.get_ciphers(ciphers, 4096); wolfssl.get_ciphers(ciphers, 4096);
Console.WriteLine("Ciphers : " + ciphers.ToString()); Console.WriteLine("Ciphers : " + ciphers.ToString());
@@ -124,6 +163,23 @@ public class wolfSSL_TLS_CSHarp
return; 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 "); Console.WriteLine("Connection made wolfSSL_accept ");
if (wolfssl.set_fd(ssl, fd) != wolfssl.SUCCESS) if (wolfssl.set_fd(ssl, fd) != wolfssl.SUCCESS)
{ {
@@ -134,7 +190,14 @@ public class wolfSSL_TLS_CSHarp
return; return;
} }
wolfssl.SetTmpDH_file(ssl, dhparam, wolfssl.SSL_FILETYPE_PEM); 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) if (wolfssl.accept(ssl) != wolfssl.SUCCESS)
{ {
@@ -170,6 +233,7 @@ public class wolfSSL_TLS_CSHarp
wolfssl.shutdown(ssl); wolfssl.shutdown(ssl);
fd.Close(); fd.Close();
tcp.Stop(); tcp.Stop();
clean(ssl, ctx); clean(ssl, ctx);
} }
} }

View File

@@ -116,9 +116,14 @@ public class wolfSSL_TLS_ServerThreaded
IntPtr ctx; IntPtr ctx;
/* These paths should be changed for use */ /* These paths should be changed for use */
string fileCert = @"server-cert.pem"; string fileCert = wolfssl.setPath("server-cert.pem");
string fileKey = @"server-key.pem"; string fileKey = wolfssl.setPath("server-key.pem");
StringBuilder dhparam = new StringBuilder("dh2048.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 */ /* example of function used for setting logging */
wolfssl.SetLogging(standard_log); wolfssl.SetLogging(standard_log);
@@ -140,6 +145,12 @@ public class wolfSSL_TLS_ServerThreaded
return; 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) if (wolfssl.CTX_use_certificate_file(ctx, fileCert, wolfssl.SSL_FILETYPE_PEM) != wolfssl.SUCCESS)
{ {
Console.WriteLine("Error in setting cert file"); Console.WriteLine("Error in setting cert file");

View File

@@ -59,6 +59,8 @@ namespace wolfSSL.CSharp {
private GCHandle rec_cb; private GCHandle rec_cb;
private GCHandle snd_cb; private GCHandle snd_cb;
private GCHandle psk_cb; private GCHandle psk_cb;
private GCHandle sni_cb;
private GCHandle sni_arg;
private GCHandle vrf_cb; private GCHandle vrf_cb;
private IntPtr ctx; private IntPtr ctx;
@@ -89,6 +91,22 @@ namespace wolfSSL.CSharp {
return this.psk_cb; return this.psk_cb;
} }
public void set_sni(GCHandle input) {
this.sni_cb = input;
}
public GCHandle get_sni(GCHandle input) {
return this.sni_cb;
}
public void set_arg(GCHandle input) {
this.sni_arg= input;
}
public GCHandle get_arg(GCHandle input) {
return this.sni_arg;
}
public void set_vrf(GCHandle input) public void set_vrf(GCHandle input)
{ {
if (!Object.Equals(this.vrf_cb, default(GCHandle))) if (!Object.Equals(this.vrf_cb, default(GCHandle)))
@@ -129,6 +147,10 @@ namespace wolfSSL.CSharp {
{ {
this.psk_cb.Free(); this.psk_cb.Free();
} }
if (!Object.Equals(this.sni_cb, default(GCHandle)))
{
this.sni_cb.Free();
}
if (!Object.Equals(this.vrf_cb, default(GCHandle))) if (!Object.Equals(this.vrf_cb, default(GCHandle)))
{ {
this.vrf_cb.Free(); this.vrf_cb.Free();
@@ -144,6 +166,7 @@ namespace wolfSSL.CSharp {
{ {
private GCHandle fd_pin; private GCHandle fd_pin;
private GCHandle psk_cb; private GCHandle psk_cb;
private GCHandle sni_cb;
private GCHandle vrf_cb; private GCHandle vrf_cb;
private IntPtr ssl; private IntPtr ssl;
@@ -198,6 +221,10 @@ namespace wolfSSL.CSharp {
{ {
this.psk_cb.Free(); this.psk_cb.Free();
} }
if (!Object.Equals(this.sni_cb, default(GCHandle)))
{
this.sni_cb.Free();
}
if (!Object.Equals(this.vrf_cb, default(GCHandle))) if (!Object.Equals(this.vrf_cb, default(GCHandle)))
{ {
this.vrf_cb.Free(); this.vrf_cb.Free();
@@ -290,6 +317,19 @@ namespace wolfSSL.CSharp {
[DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
private extern static int wolfSSL_CTX_use_psk_identity_hint(IntPtr ctx, StringBuilder identity); private extern static int wolfSSL_CTX_use_psk_identity_hint(IntPtr ctx, StringBuilder identity);
/********************************
* SNI
*/
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int sni_delegate(IntPtr ssl, IntPtr ret, IntPtr exArg);
[DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
private extern static void wolfSSL_CTX_set_servername_callback(IntPtr ctx, sni_delegate sni_cb);
[DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
private extern static int wolfSSL_CTX_set_servername_arg(IntPtr ctx, IntPtr arg);
[DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
private extern static int wolfSSL_CTX_UseSNI(IntPtr ctx, byte type, IntPtr data, ushort size);
[DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
private extern static int wolfSSL_UseSNI(IntPtr ssl, byte type, IntPtr data, ushort size);
/******************************** /********************************
* SSL Structure * SSL Structure
@@ -417,6 +457,7 @@ namespace wolfSSL.CSharp {
public static readonly int SUCCESS = 1; public static readonly int SUCCESS = 1;
public static readonly int FAILURE = 0; public static readonly int FAILURE = 0;
public static readonly int WOLFSSL_SNI_HOST_NAME = 0;
private static IntPtr unwrap_ctx(IntPtr ctx) private static IntPtr unwrap_ctx(IntPtr ctx)
@@ -444,6 +485,26 @@ namespace wolfSSL.CSharp {
} }
} }
/// <summary>
/// Utility function used to access the certificates
/// based on the platform.
/// <returns>return the platform specific path to the certificate</returns>
/// </summary>
public static string setPath(string file) {
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
Console.WriteLine("Linux - " + file);
return @"../../certs/" + file;
} else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
Console.WriteLine("Windows - " + file);
return @"../../../../certs/" + file;
} else
{
return "";
}
}
/// <summary> /// <summary>
/// Call back to allow receiving TLS information /// Call back to allow receiving TLS information
@@ -1084,6 +1145,60 @@ namespace wolfSSL.CSharp {
} }
} }
public static void CTX_set_servername_callback(IntPtr ctx, sni_delegate sni_cb)
{
try {
GCHandle gch = GCHandle.FromIntPtr(ctx);
ctx_handle handles = (ctx_handle)gch.Target;
handles.set_sni(GCHandle.Alloc(sni_cb));
wolfSSL_CTX_set_servername_callback(handles.get_ctx(), sni_cb);
} catch (Exception e) {
log(ERROR_LOG, "wolfssl servername callback error: " + e.ToString());
}
}
public static int CTX_set_servername_arg(IntPtr ctx, IntPtr arg)
{
try {
GCHandle gch = GCHandle.FromIntPtr(ctx);
ctx_handle handles = (ctx_handle)gch.Target;
handles.set_arg(GCHandle.Alloc(arg));
return wolfSSL_CTX_set_servername_arg(handles.get_ctx(), arg);
} catch (Exception e) {
log(ERROR_LOG, "wolfssl arg servername callback error: " + e.ToString());
return FAILURE;
}
}
public static int CTX_UseSNI(IntPtr ctx, byte type, IntPtr data, ushort size)
{
try {
GCHandle gch = GCHandle.FromIntPtr(ctx);
ctx_handle handles = (ctx_handle)gch.Target;
return wolfSSL_CTX_UseSNI(handles.get_ctx(), type, data, size);
} catch (Exception e) {
log(ERROR_LOG, "wolfssl ctx use sni error: " + e.ToString());
return FAILURE;
}
}
public static int UseSNI(IntPtr ssl, byte type, IntPtr data, ushort size)
{
try {
GCHandle gch = GCHandle.FromIntPtr(ssl);
ssl_handle handles = (ssl_handle)gch.Target;
return wolfSSL_UseSNI(handles.get_ssl(), type, data, size);
} catch (Exception e) {
log(ERROR_LOG, "wolfssl use sni error: " + e.ToString());
return FAILURE;
}
}
/// <summary> /// <summary>
/// Set identity hint to use /// Set identity hint to use