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;
}
#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)
{
@@ -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");
@@ -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)

View File

@@ -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,
@@ -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);

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
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
@@ -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
```
csc wolfSSL_CSharp/wolfSSL.cs wolfSSL_CSharp/X509.cs \
wolfSSL-TLS-Server/wolfSSL-TLS-Server.cs
Run the example:
Compile server:
```
cp wolfSSL-TLS-Server.exe ../../certs
cd ../../certs
mono wolfSSL-TLS-Server.exe
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
mcs wolfSSL_CSharp/wolfSSL.cs wolfSSL_CSharp/X509.cs \
wolfSSL-TLS-Server/wolfSSL-TLS-Server.cs -OUT:server.exe
```
Compile client:
```
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
```
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;
/* 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);
@@ -106,6 +111,12 @@ public class wolfSSL_DTLS_PSK_Server
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)
{

View File

@@ -58,9 +58,14 @@ public class wolfSSL_DTLS_Server
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");
@@ -87,6 +92,12 @@ public class wolfSSL_DTLS_Server
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)
{

View File

@@ -214,12 +214,17 @@ class wolfSSL_Example_IOCallbacks
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");
@@ -242,6 +247,12 @@ class wolfSSL_Example_IOCallbacks
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");

View File

@@ -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;
@@ -60,15 +59,39 @@ public class wolfSSL_TLS_Client
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");
@@ -78,7 +101,6 @@ public class wolfSSL_TLS_Client
wolfssl.Init();
Console.WriteLine("Calling ctx Init from wolfSSL");
ctx = wolfssl.CTX_new(wolfssl.usev23_client());
if (ctx == IntPtr.Zero)
@@ -96,11 +118,34 @@ public class wolfSSL_TLS_Client
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));

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);
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");
@@ -157,6 +161,12 @@ public class wolfSSL_TLS_PSK_Client
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)

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);
/* 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;
}
StringBuilder buff = new StringBuilder(1024);
StringBuilder reply = new StringBuilder("Hello, this is the wolfSSL C# wrapper");
@@ -105,6 +110,12 @@ public class wolfSSL_TLS_PSK_Server
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");

View File

@@ -19,9 +19,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
using System;
using System.Runtime.InteropServices;
using System.Text;
@@ -50,17 +47,55 @@ public class wolfSSL_TLS_CSHarp
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)
{
IntPtr ctx;
IntPtr ssl;
Socket fd;
IntPtr arg_sni;
/* 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");
@@ -70,7 +105,6 @@ public class wolfSSL_TLS_CSHarp
wolfssl.Init();
Console.WriteLine("Calling ctx Init from wolfSSL");
ctx = wolfssl.CTX_new(wolfssl.usev23_server());
if (ctx == IntPtr.Zero)
@@ -87,6 +121,12 @@ public class wolfSSL_TLS_CSHarp
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");
@@ -101,7 +141,6 @@ public class wolfSSL_TLS_CSHarp
return;
}
StringBuilder ciphers = new StringBuilder(new String(' ', 4096));
wolfssl.get_ciphers(ciphers, 4096);
Console.WriteLine("Ciphers : " + ciphers.ToString());
@@ -124,6 +163,23 @@ public class wolfSSL_TLS_CSHarp
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)
{
@@ -134,7 +190,14 @@ public class wolfSSL_TLS_CSHarp
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)
{
@@ -170,6 +233,7 @@ public class wolfSSL_TLS_CSHarp
wolfssl.shutdown(ssl);
fd.Close();
tcp.Stop();
clean(ssl, ctx);
}
}

View File

@@ -116,9 +116,14 @@ public class wolfSSL_TLS_ServerThreaded
IntPtr ctx;
/* 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;
}
/* example of function used for setting logging */
wolfssl.SetLogging(standard_log);
@@ -140,6 +145,12 @@ public class wolfSSL_TLS_ServerThreaded
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");

View File

@@ -59,6 +59,8 @@ namespace wolfSSL.CSharp {
private GCHandle rec_cb;
private GCHandle snd_cb;
private GCHandle psk_cb;
private GCHandle sni_cb;
private GCHandle sni_arg;
private GCHandle vrf_cb;
private IntPtr ctx;
@@ -89,6 +91,22 @@ namespace wolfSSL.CSharp {
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)
{
if (!Object.Equals(this.vrf_cb, default(GCHandle)))
@@ -129,6 +147,10 @@ namespace wolfSSL.CSharp {
{
this.psk_cb.Free();
}
if (!Object.Equals(this.sni_cb, default(GCHandle)))
{
this.sni_cb.Free();
}
if (!Object.Equals(this.vrf_cb, default(GCHandle)))
{
this.vrf_cb.Free();
@@ -144,6 +166,7 @@ namespace wolfSSL.CSharp {
{
private GCHandle fd_pin;
private GCHandle psk_cb;
private GCHandle sni_cb;
private GCHandle vrf_cb;
private IntPtr ssl;
@@ -198,6 +221,10 @@ namespace wolfSSL.CSharp {
{
this.psk_cb.Free();
}
if (!Object.Equals(this.sni_cb, default(GCHandle)))
{
this.sni_cb.Free();
}
if (!Object.Equals(this.vrf_cb, default(GCHandle)))
{
this.vrf_cb.Free();
@@ -290,6 +317,19 @@ namespace wolfSSL.CSharp {
[DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
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
@@ -417,6 +457,7 @@ namespace wolfSSL.CSharp {
public static readonly int SUCCESS = 1;
public static readonly int FAILURE = 0;
public static readonly int WOLFSSL_SNI_HOST_NAME = 0;
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>
/// 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>
/// Set identity hint to use