diff --git a/src/ssl.c b/src/ssl.c index d027ef01b0..44b46c1f30 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -20156,16 +20156,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) { @@ -20177,19 +20170,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"); @@ -20224,6 +20206,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) diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index f12d32a23d..59f703d3ce 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -3811,7 +3811,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, @@ -4873,14 +4872,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); diff --git a/wrapper/CSharp/README.md b/wrapper/CSharp/README.md index faba0da7f0..4a2c1455ec 100644 --- a/wrapper/CSharp/README.md +++ b/wrapper/CSharp/README.md @@ -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 +``` + +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 ``` diff --git a/wrapper/CSharp/wolfSSL-DTLS-PSK-Server/wolfSSL-DTLS-PSK-Server.cs b/wrapper/CSharp/wolfSSL-DTLS-PSK-Server/wolfSSL-DTLS-PSK-Server.cs index 6aa9aa542b..f1753282b8 100644 --- a/wrapper/CSharp/wolfSSL-DTLS-PSK-Server/wolfSSL-DTLS-PSK-Server.cs +++ b/wrapper/CSharp/wolfSSL-DTLS-PSK-Server/wolfSSL-DTLS-PSK-Server.cs @@ -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); @@ -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) { diff --git a/wrapper/CSharp/wolfSSL-DTLS-Server/wolfSSL-DTLS-Server.cs b/wrapper/CSharp/wolfSSL-DTLS-Server/wolfSSL-DTLS-Server.cs index fcbfe69229..5e10a9a93b 100644 --- a/wrapper/CSharp/wolfSSL-DTLS-Server/wolfSSL-DTLS-Server.cs +++ b/wrapper/CSharp/wolfSSL-DTLS-Server/wolfSSL-DTLS-Server.cs @@ -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"); @@ -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) { diff --git a/wrapper/CSharp/wolfSSL-Example-IOCallbacks/wolfSSL-Example-IOCallbacks.cs b/wrapper/CSharp/wolfSSL-Example-IOCallbacks/wolfSSL-Example-IOCallbacks.cs index ac91a97954..77218fd0a1 100644 --- a/wrapper/CSharp/wolfSSL-Example-IOCallbacks/wolfSSL-Example-IOCallbacks.cs +++ b/wrapper/CSharp/wolfSSL-Example-IOCallbacks/wolfSSL-Example-IOCallbacks.cs @@ -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"); @@ -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"); diff --git a/wrapper/CSharp/wolfSSL-TLS-Client/wolfSSL-TLS-Client.cs b/wrapper/CSharp/wolfSSL-TLS-Client/wolfSSL-TLS-Client.cs index a12c5f599c..7cf4c71f4c 100644 --- a/wrapper/CSharp/wolfSSL-TLS-Client/wolfSSL-TLS-Client.cs +++ b/wrapper/CSharp/wolfSSL-TLS-Client/wolfSSL-TLS-Client.cs @@ -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 @@ private static int myVerify(int preverify, IntPtr x509_ctx) return preverify; } + /// + /// Checks if the SNI option was enabled via command line. + /// Must be enabled with ./configure --enable-sni when configuring + /// wolfSSL. + /// Parameters passed via command line + /// + 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 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) @@ -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)); diff --git a/wrapper/CSharp/wolfSSL-TLS-PSK-Client/wolfSSL-TLS-PSK-Client.cs b/wrapper/CSharp/wolfSSL-TLS-PSK-Client/wolfSSL-TLS-PSK-Client.cs index cdc3ef7ca9..0f70d72d44 100644 --- a/wrapper/CSharp/wolfSSL-TLS-PSK-Client/wolfSSL-TLS-PSK-Client.cs +++ b/wrapper/CSharp/wolfSSL-TLS-PSK-Client/wolfSSL-TLS-PSK-Client.cs @@ -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"); @@ -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) diff --git a/wrapper/CSharp/wolfSSL-TLS-PSK-Server/wolfSSL-TLS-PSK-Server.cs b/wrapper/CSharp/wolfSSL-TLS-PSK-Server/wolfSSL-TLS-PSK-Server.cs index a46dbd5949..a16bb87325 100644 --- a/wrapper/CSharp/wolfSSL-TLS-PSK-Server/wolfSSL-TLS-PSK-Server.cs +++ b/wrapper/CSharp/wolfSSL-TLS-PSK-Server/wolfSSL-TLS-PSK-Server.cs @@ -80,9 +80,14 @@ public static void Main(string[] args) 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 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"); diff --git a/wrapper/CSharp/wolfSSL-TLS-Server/wolfSSL-TLS-Server.cs b/wrapper/CSharp/wolfSSL-TLS-Server/wolfSSL-TLS-Server.cs index 12217dc071..7552777abb 100644 --- a/wrapper/CSharp/wolfSSL-TLS-Server/wolfSSL-TLS-Server.cs +++ b/wrapper/CSharp/wolfSSL-TLS-Server/wolfSSL-TLS-Server.cs @@ -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 @@ private static void clean(IntPtr ssl, IntPtr ctx) wolfssl.Cleanup(); } + /// + /// Checks if the SNI option was enabled via command line. + /// Must be enabled with ./configure --enable-sni when configuring + /// wolfSSL. + /// Parameters passed via command line + /// + 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; + } + + /// + /// Example of a SNI function call back + /// + /// pointer to ssl structure + /// alert code + /// context arg, can be set with the function wolfssl.CTX_set_servername_arg + /// + 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 static void Main(string[] args) 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 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"); @@ -101,7 +141,6 @@ public static void Main(string[] args) return; } - StringBuilder ciphers = new StringBuilder(new String(' ', 4096)); wolfssl.get_ciphers(ciphers, 4096); Console.WriteLine("Ciphers : " + ciphers.ToString()); @@ -124,6 +163,23 @@ public static void Main(string[] args) 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 static void Main(string[] args) 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 static void Main(string[] args) wolfssl.shutdown(ssl); fd.Close(); tcp.Stop(); + clean(ssl, ctx); } } diff --git a/wrapper/CSharp/wolfSSL-TLS-ServerThreaded/wolfSSL-TLS-ServerThreaded.cs b/wrapper/CSharp/wolfSSL-TLS-ServerThreaded/wolfSSL-TLS-ServerThreaded.cs index e83784e1f7..6cd6982dbe 100644 --- a/wrapper/CSharp/wolfSSL-TLS-ServerThreaded/wolfSSL-TLS-ServerThreaded.cs +++ b/wrapper/CSharp/wolfSSL-TLS-ServerThreaded/wolfSSL-TLS-ServerThreaded.cs @@ -116,9 +116,14 @@ public static void Main(string[] args) 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 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"); diff --git a/wrapper/CSharp/wolfSSL_CSharp/wolfSSL.cs b/wrapper/CSharp/wolfSSL_CSharp/wolfSSL.cs index c59c3e00b5..7b7ec1e236 100644 --- a/wrapper/CSharp/wolfSSL_CSharp/wolfSSL.cs +++ b/wrapper/CSharp/wolfSSL_CSharp/wolfSSL.cs @@ -59,6 +59,8 @@ private class ctx_handle 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 @@ public GCHandle get_psk() 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 @@ public void 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))) { this.vrf_cb.Free(); @@ -144,6 +166,7 @@ private class ssl_handle { private GCHandle fd_pin; private GCHandle psk_cb; + private GCHandle sni_cb; private GCHandle vrf_cb; private IntPtr ssl; @@ -198,6 +221,10 @@ public void 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))) { this.vrf_cb.Free(); @@ -290,6 +317,19 @@ public void free() [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 @@ public void free() 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 @@ private static IntPtr unwrap_ssl(IntPtr ssl) } } + /// + /// Utility function used to access the certificates + /// based on the platform. + /// return the platform specific path to the certificate + /// + 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 ""; + } + } + /// /// Call back to allow receiving TLS information @@ -1084,6 +1145,60 @@ public static void CTX_free(IntPtr ctx) } } + 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; + } + } /// /// Set identity hint to use