1 /* wolfSSL.cs
2  *
3  * Copyright (C) 2006-2021 wolfSSL Inc.
4  *
5  * This file is part of wolfSSL.
6  *
7  * wolfSSL is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * wolfSSL is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20  */
21 
22 using System;
23 using System.Runtime.InteropServices;
24 using System.Text;
25 using System.Threading;
26 using System.IO;
27 using System.Net;
28 using System.Net.Sockets;
29 
30 namespace wolfSSL.CSharp {
31     public class wolfssl
32     {
33         private const string wolfssl_dll = "wolfssl.dll";
34 
35         /* wait for 6 seconds default on TCP socket state poll if timeout not set */
36         private const int WC_WAIT = 6000000;
37 
38         /********************************
39          * Class for DTLS connections
40          */
41         /// <summary>
42         /// Contains information regarding a DTLS connection having UdpClient udp and IPEndPoint ep.
43         /// Used to keep memory alive.
44         /// </summary>
45         public class DTLS_con
46         {
47             public UdpClient udp;
48             public IPEndPoint ep;
49         }
50 
51 
52         /********************************
53          * Class for keeping ctx handles alive
54          */
55         [StructLayout(LayoutKind.Sequential)]
56         private class ctx_handle
57         {
58             private GCHandle rec_cb;
59             private GCHandle snd_cb;
60             private GCHandle psk_cb;
61             private GCHandle vrf_cb;
62             private IntPtr ctx;
63 
set_receive(GCHandle input)64             public void set_receive(GCHandle input)
65             {
66                 this.rec_cb = input;
67             }
get_receive()68             public GCHandle get_receive()
69             {
70                 return this.rec_cb;
71             }
72 
set_send(GCHandle input)73             public void set_send(GCHandle input)
74             {
75                 this.snd_cb = input;
76             }
get_send()77             public GCHandle get_send()
78             {
79                 return this.snd_cb;
80             }
81 
set_psk(GCHandle input)82             public void set_psk(GCHandle input)
83             {
84                 this.psk_cb = input;
85             }
get_psk()86             public GCHandle get_psk()
87             {
88                 return this.psk_cb;
89             }
90 
set_vrf(GCHandle input)91             public void set_vrf(GCHandle input)
92             {
93                 if (!Object.Equals(this.vrf_cb, default(GCHandle)))
94                 {
95                     this.vrf_cb.Free();
96                 }
97                 this.vrf_cb = input;
98             }
get_vrf()99             public GCHandle get_vrf()
100             {
101                 return this.vrf_cb;
102             }
103 
set_ctx(IntPtr input)104             public void set_ctx(IntPtr input)
105             {
106                 this.ctx = input;
107             }
get_ctx()108             public IntPtr get_ctx()
109             {
110                 return this.ctx;
111             }
112 
113             /// <summary>
114             /// Called to free the pointers keeping handles alive
115             /// </summary>
free()116             public void free()
117             {
118                 log(INFO_LOG, "freeing ctx handle");
119                 if (!Object.Equals(this.rec_cb, default(GCHandle)))
120                 {
121                     this.rec_cb.Free();
122                 }
123                 if (!Object.Equals(this.snd_cb, default(GCHandle)))
124                 {
125                     this.snd_cb.Free();
126                 }
127                 if (!Object.Equals(this.psk_cb, default(GCHandle)))
128                 {
129                     this.psk_cb.Free();
130                 }
131                 if (!Object.Equals(this.vrf_cb, default(GCHandle)))
132                 {
133                     this.vrf_cb.Free();
134                 }
135             }
136         }
137 
138         /********************************
139          * Class for keeping ssl handle alive
140          */
141         [StructLayout(LayoutKind.Sequential)]
142         private class ssl_handle
143         {
144             private GCHandle fd_pin;
145             private GCHandle psk_cb;
146             private GCHandle vrf_cb;
147             private IntPtr ssl;
148 
set_fd(GCHandle input)149             public void set_fd(GCHandle input)
150             {
151                 this.fd_pin = input;
152             }
get_fd()153             public GCHandle get_fd()
154             {
155                 return this.fd_pin;
156             }
157 
set_psk(GCHandle input)158             public void set_psk(GCHandle input)
159             {
160                 this.psk_cb = input;
161             }
get_psk()162             public GCHandle get_psk()
163             {
164                 return this.psk_cb;
165             }
166 
set_vrf(GCHandle input)167             public void set_vrf(GCHandle input)
168             {
169                 if (!Object.Equals(this.vrf_cb, default(GCHandle)))
170                 {
171                     this.vrf_cb.Free();
172                 }
173                 this.vrf_cb = input;
174             }
get_vrf()175             public GCHandle get_vrf()
176             {
177                 return this.vrf_cb;
178             }
179 
set_ssl(IntPtr input)180             public void set_ssl(IntPtr input)
181             {
182                 this.ssl = input;
183             }
get_ssl()184             public IntPtr get_ssl()
185             {
186                 return this.ssl;
187             }
free()188             public void free()
189             {
190                 log(INFO_LOG, "freeing ssl handle");
191 
192                 if (!Object.Equals(this.fd_pin, default(GCHandle)))
193                 {
194                     this.fd_pin.Free();
195                 }
196                 if (!Object.Equals(this.psk_cb, default(GCHandle)))
197                 {
198                     this.psk_cb.Free();
199                 }
200                 if (!Object.Equals(this.vrf_cb, default(GCHandle)))
201                 {
202                     this.vrf_cb.Free();
203                 }
204             }
205         }
206 
207 
208         /********************************
209          * Init wolfSSL library
210          */
211         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_Init()212         private extern static int wolfSSL_Init();
213         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_Cleanup()214         private extern static int wolfSSL_Cleanup();
215 
216 
217         /********************************
218          * Methods of connection
219          */
220         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfTLSv1_2_server_method()221         private extern static IntPtr wolfTLSv1_2_server_method();
222         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfTLSv1_3_server_method()223         private extern static IntPtr wolfTLSv1_3_server_method();
224         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSLv23_server_method()225         private extern static IntPtr wolfSSLv23_server_method();
226         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfTLSv1_2_client_method()227         private extern static IntPtr wolfTLSv1_2_client_method();
228         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfTLSv1_3_client_method()229         private extern static IntPtr wolfTLSv1_3_client_method();
230         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSLv23_client_method()231         private extern static IntPtr wolfSSLv23_client_method();
232         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfDTLSv1_2_server_method()233         private extern static IntPtr wolfDTLSv1_2_server_method();
234         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfDTLSv1_2_client_method()235         private extern static IntPtr wolfDTLSv1_2_client_method();
236 
237 
238         /********************************
239          * Call backs
240          */
241         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
CallbackIORecv_delegate(IntPtr ssl, IntPtr buf, int sz, IntPtr ctx)242         public delegate int CallbackIORecv_delegate(IntPtr ssl, IntPtr buf, int sz, IntPtr ctx);
243         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_CTX_SetIORecv(IntPtr ctx, CallbackIORecv_delegate recv)244         private extern static int wolfSSL_CTX_SetIORecv(IntPtr ctx, CallbackIORecv_delegate recv);
245         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_SetIOReadCtx(IntPtr ssl, IntPtr rctx)246         private extern static int wolfSSL_SetIOReadCtx(IntPtr ssl, IntPtr rctx);
247         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_GetIOReadCtx(IntPtr ssl)248         private extern static IntPtr wolfSSL_GetIOReadCtx(IntPtr ssl);
249 
250         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
CallbackIOSend_delegate(IntPtr ssl, IntPtr buf, int sz, IntPtr ctx)251         public delegate int CallbackIOSend_delegate(IntPtr ssl, IntPtr buf, int sz, IntPtr ctx);
252         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_CTX_SetIOSend(IntPtr ctx, CallbackIOSend_delegate send)253         private extern static int wolfSSL_CTX_SetIOSend(IntPtr ctx, CallbackIOSend_delegate send);
254         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_SetIOWriteCtx(IntPtr ssl, IntPtr wctx)255         private extern static int wolfSSL_SetIOWriteCtx(IntPtr ssl, IntPtr wctx);
256         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_GetIOWriteCtx(IntPtr ssl)257         private extern static IntPtr wolfSSL_GetIOWriteCtx(IntPtr ssl);
258 
259 
260         /********************************
261          * CTX structure
262          */
263         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_CTX_new(IntPtr method)264         private extern static IntPtr wolfSSL_CTX_new(IntPtr method);
265         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_CTX_use_certificate_file(IntPtr ctx, string file, int type)266         private extern static int wolfSSL_CTX_use_certificate_file(IntPtr ctx, string file, int type);
267         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_CTX_load_verify_locations(IntPtr ctx, string file, string path)268         private extern static int wolfSSL_CTX_load_verify_locations(IntPtr ctx, string file, string path);
269         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_CTX_use_PrivateKey_file(IntPtr ctx, string file, int type)270         private extern static int wolfSSL_CTX_use_PrivateKey_file(IntPtr ctx, string file, int type);
271         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_CTX_free(IntPtr ctx)272         private extern static void wolfSSL_CTX_free(IntPtr ctx);
273 
274 
275 
276         /********************************
277          * PSK
278          */
279         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
psk_delegate(IntPtr ssl, string identity, IntPtr key, uint max_sz)280         public delegate uint psk_delegate(IntPtr ssl, string identity, IntPtr key, uint max_sz);
281         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
psk_client_delegate(IntPtr ssl, string hint, IntPtr identity, uint id_max_len, IntPtr key, uint max_sz)282         public delegate uint psk_client_delegate(IntPtr ssl, string hint, IntPtr identity, uint id_max_len, IntPtr key, uint max_sz);
283         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_set_psk_server_callback(IntPtr ssl, psk_delegate psk_cb)284         private extern static void wolfSSL_set_psk_server_callback(IntPtr ssl, psk_delegate psk_cb);
285         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_CTX_set_psk_server_callback(IntPtr ctx, psk_delegate psk_cb)286         private extern static void wolfSSL_CTX_set_psk_server_callback(IntPtr ctx, psk_delegate psk_cb);
287         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_CTX_set_psk_client_callback(IntPtr ctx, psk_client_delegate psk_cb)288         private extern static void wolfSSL_CTX_set_psk_client_callback(IntPtr ctx, psk_client_delegate psk_cb);
289         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_CTX_use_psk_identity_hint(IntPtr ctx, StringBuilder identity)290         private extern static int wolfSSL_CTX_use_psk_identity_hint(IntPtr ctx, StringBuilder identity);
291 
292 
293         /********************************
294          * SSL Structure
295          */
296         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_new(IntPtr ctx)297         private extern static IntPtr wolfSSL_new(IntPtr ctx);
298         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_accept(IntPtr ssl)299         private extern static int wolfSSL_accept(IntPtr ssl);
300         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_connect(IntPtr ssl)301         private extern static int wolfSSL_connect(IntPtr ssl);
302         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_read(IntPtr ssl, IntPtr buf, int sz)303         private extern static int wolfSSL_read(IntPtr ssl, IntPtr buf, int sz);
304         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_write(IntPtr ssl, IntPtr buf, int sz)305         private extern static int wolfSSL_write(IntPtr ssl, IntPtr buf, int sz);
306         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_shutdown(IntPtr ssl)307         private extern static int wolfSSL_shutdown(IntPtr ssl);
308         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_free(IntPtr ssl)309         private extern static void wolfSSL_free(IntPtr ssl);
310 
311 
312         /********************************
313          * Cipher lists
314          */
315         /* only supports full name from cipher_name[] delimited by : */
316         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_CTX_set_cipher_list(IntPtr ctx, StringBuilder ciphers)317         private extern static int wolfSSL_CTX_set_cipher_list(IntPtr ctx, StringBuilder ciphers);
318         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_set_cipher_list(IntPtr ssl, StringBuilder ciphers)319         private extern static int wolfSSL_set_cipher_list(IntPtr ssl, StringBuilder ciphers);
320         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_get_ciphers(StringBuilder ciphers, int sz)321         private extern static int wolfSSL_get_ciphers(StringBuilder ciphers, int sz);
322         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_get_cipher(IntPtr ssl)323         private extern static IntPtr wolfSSL_get_cipher(IntPtr ssl);
324         [DllImport(wolfssl_dll, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_CIPHER_get_name(IntPtr cipher)325         private extern static IntPtr wolfSSL_CIPHER_get_name(IntPtr cipher);
326         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_get_current_cipher(IntPtr ssl)327         private extern static IntPtr wolfSSL_get_current_cipher(IntPtr ssl);
328         [DllImport(wolfssl_dll, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_get_version(IntPtr ssl)329         private extern static IntPtr wolfSSL_get_version(IntPtr ssl);
330         [DllImport(wolfssl_dll, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_get_cipher_list(IntPtr ssl)331         private extern static IntPtr wolfSSL_get_cipher_list(IntPtr ssl);
332 
333 
334         /********************************
335          * Error logging
336          */
337         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
wolfSSL_ERR_error_string(uint err, StringBuilder errOut)338         private extern static IntPtr wolfSSL_ERR_error_string(uint err, StringBuilder errOut);
339         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_get_error(IntPtr ssl, int err)340         private extern static int wolfSSL_get_error(IntPtr ssl, int err);
341         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
loggingCb(int lvl, StringBuilder msg)342         public delegate void loggingCb(int lvl, StringBuilder msg);
343         private static loggingCb internal_log;
344         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_Debugging_ON()345         private extern static void wolfSSL_Debugging_ON();
346         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_Debugging_OFF()347         private extern static void wolfSSL_Debugging_OFF();
348 
349 
350         /********************************
351          * DH
352          */
353         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_CTX_SetMinDhKey_Sz(IntPtr ctx, short size)354         private extern static int wolfSSL_CTX_SetMinDhKey_Sz(IntPtr ctx, short size);
355         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_SetTmpDH_file(IntPtr ssl, StringBuilder dhParam, int type)356         private extern static int wolfSSL_SetTmpDH_file(IntPtr ssl, StringBuilder dhParam, int type);
357         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_CTX_SetTmpDH_file(IntPtr ctx, StringBuilder dhParam, int type)358         private extern static int wolfSSL_CTX_SetTmpDH_file(IntPtr ctx, StringBuilder dhParam, int type);
359 
360 
361         /********************************
362          * Verify Callback
363          */
364         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
CallbackVerify_delegate(int ret, IntPtr x509_ctx)365         public delegate int CallbackVerify_delegate(int ret, IntPtr x509_ctx);
366         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_CTX_set_verify(IntPtr ctx, int mode, CallbackVerify_delegate vc)367         private extern static void wolfSSL_CTX_set_verify(IntPtr ctx, int mode, CallbackVerify_delegate vc);
368         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_set_verify(IntPtr ssl, int mode, CallbackVerify_delegate vc)369         private extern static void wolfSSL_set_verify(IntPtr ssl, int mode, CallbackVerify_delegate vc);
370 
371 
372         /********************************
373          * X509 Store
374          */
375         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_X509_STORE_CTX_get_current_cert(IntPtr x509Ctx)376         private extern static IntPtr wolfSSL_X509_STORE_CTX_get_current_cert(IntPtr x509Ctx);
377         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_X509_STORE_CTX_get_error(IntPtr sk)378         private extern static int wolfSSL_X509_STORE_CTX_get_error(IntPtr sk);
379         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_X509_STORE_GetCerts(IntPtr x509Ctx)380         private extern static IntPtr wolfSSL_X509_STORE_GetCerts(IntPtr x509Ctx);
381         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_sk_X509_num(IntPtr sk)382         private extern static int wolfSSL_sk_X509_num(IntPtr sk);
383         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_sk_X509_free(IntPtr sk)384         private extern static void wolfSSL_sk_X509_free(IntPtr sk);
385         [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)]
wolfSSL_sk_X509_pop(IntPtr sk)386         private extern static IntPtr wolfSSL_sk_X509_pop(IntPtr sk);
387 
388 
389         /********************************
390          * Enum types from wolfSSL library
391          */
392         public static readonly int SSL_FILETYPE_PEM = 1;
393         public static readonly int SSL_FILETYPE_ASN1 = 2;
394         public static readonly int SSL_FILETYPE_RAW = 3;
395 
396         public static readonly int SSL_VERIFY_NONE = 0;
397         public static readonly int SSL_VERIFY_PEER = 1;
398         public static readonly int SSL_VERIFY_FAIL_IF_NO_PEER_CERT = 2;
399         public static readonly int SSL_VERIFY_CLIENT_ONCE = 4;
400         public static readonly int SSL_VERIFY_POST_HANDSHAKE = 8;
401         public static readonly int SSL_VERIFY_FAIL_EXCEPT_PSK = 16;
402 
403         public static readonly int CBIO_ERR_GENERAL = -1;
404         public static readonly int CBIO_ERR_WANT_READ = -2;
405         public static readonly int CBIO_ERR_WANT_WRITE = -2;
406         public static readonly int CBIO_ERR_CONN_RST = -3;
407         public static readonly int CBIO_ERR_ISR = -4;
408         public static readonly int CBIO_ERR_CONN_CLOSE = -5;
409         public static readonly int CBIO_ERR_TIMEOUT = -6;
410 
411         public static readonly int ERROR_LOG = 0;
412         public static readonly int INFO_LOG = 1;
413         public static readonly int ENTER_LOG = 2;
414         public static readonly int LEAVE_LOG = 3;
415         public static readonly int OTHER_LOG = 4;
416 
417         public static readonly int SUCCESS = 1;
418         public static readonly int FAILURE = 0;
419 
420 
unwrap_ctx(IntPtr ctx)421         private static IntPtr unwrap_ctx(IntPtr ctx)
422         {
423             try {
424                 GCHandle gch = GCHandle.FromIntPtr(ctx);
425                 ctx_handle handles = (ctx_handle)gch.Target;
426                 return handles.get_ctx();
427             } catch (Exception e)
428             {
429                 log(ERROR_LOG, "wolfssl ctx pointer is incorrect " + e);
430                 return IntPtr.Zero;
431             }
432         }
unwrap_ssl(IntPtr ssl)433         private static IntPtr unwrap_ssl(IntPtr ssl)
434         {
435             try {
436                 GCHandle gch = GCHandle.FromIntPtr(ssl);
437                 ssl_handle handles = (ssl_handle)gch.Target;
438                 return handles.get_ssl();
439             } catch (Exception e)
440             {
441                 log(ERROR_LOG, "wolfssl pointer is incorrect " + e);
442                 return IntPtr.Zero;
443             }
444         }
445 
446 
447         /// <summary>
448         /// Call back to allow receiving TLS information
449         /// </summary>
450         /// <param name="ssl">structure of ssl passed in</param>
451         /// <param name="buf">buffer to contain received msg</param>
452         /// <param name="sz">size of buffer</param>
453         /// <param name="ctx">optional information passed in</param>
454         /// <returns>size of message received</returns>
wolfSSLCbIORecv(IntPtr ssl, IntPtr buf, int sz, IntPtr ctx)455         private static int wolfSSLCbIORecv(IntPtr ssl, IntPtr buf, int sz, IntPtr ctx)
456         {
457             if (sz <= 0)
458             {
459                 log(ERROR_LOG, "wolfssl receive error, size less than 0");
460                 return wolfssl.CBIO_ERR_GENERAL;
461             }
462 
463             int amtRecv = 0;
464 
465             try
466             {
467                 System.Runtime.InteropServices.GCHandle gch;
468                 gch = GCHandle.FromIntPtr(ctx);
469                 Socket con = (System.Net.Sockets.Socket)gch.Target;
470                 Byte[] msg = new Byte[sz];
471                 amtRecv = con.Receive(msg, msg.Length, 0);
472                 if (amtRecv == 0)
473                 {
474                     /* No data received so check for a response to see if connection is still open */
475                     if (con.Poll((con.ReceiveTimeout > 0) ? con.ReceiveTimeout : WC_WAIT, SelectMode.SelectRead))
476                     {
477                         log(ERROR_LOG, "socket connection issue, suspected connection termination.");
478                         return wolfssl.CBIO_ERR_CONN_CLOSE;
479                     }
480                 }
481                 Marshal.Copy(msg, 0, buf, sz);
482             }
483             catch (Exception e)
484             {
485                 log(ERROR_LOG, "Error in receive " + e.ToString());
486                 return wolfssl.CBIO_ERR_CONN_CLOSE;
487             }
488 
489             return amtRecv;
490         }
491 
492 
493         /// <summary>
494         /// Call back used for sending TLS information
495         /// </summary>
496         /// <param name="ssl">pointer to ssl struct</param>
497         /// <param name="buf">buffer containing information to send</param>
498         /// <param name="sz">size of buffer to send</param>
499         /// <param name="ctx">optional information</param>
500         /// <returns>amount of information sent</returns>
wolfSSLCbIOSend(IntPtr ssl, IntPtr buf, int sz, IntPtr ctx)501         private static int wolfSSLCbIOSend(IntPtr ssl, IntPtr buf, int sz, IntPtr ctx)
502         {
503             if (sz <= 0)
504             {
505                 log(ERROR_LOG, "wolfssl send error, size less than 0");
506                 return wolfssl.CBIO_ERR_GENERAL;
507             }
508 
509             try
510             {
511                 System.Runtime.InteropServices.GCHandle gch;
512                 gch = GCHandle.FromIntPtr(ctx);
513 
514                 Socket con = (System.Net.Sockets.Socket)gch.Target;
515                 Byte[] msg = new Byte[sz];
516                 Marshal.Copy(buf, msg, 0, sz);
517                 if (con.Send(msg, 0, msg.Length, SocketFlags.None) == 0 && sz != 0)
518                 {
519                     /* no data sent and msg size is larger then 0, check for lost connection */
520                     if (con.Poll((con.SendTimeout > 0) ? con.SendTimeout : WC_WAIT, SelectMode.SelectWrite))
521                     {
522                         log(ERROR_LOG, "socket connection issue, suspect connection termination");
523                         return wolfssl.CBIO_ERR_CONN_CLOSE;
524                     }
525                 }
526                 return sz;
527             }
528             catch (Exception e)
529             {
530                 log(ERROR_LOG, "socket connection issue " + e.ToString());
531                 return wolfssl.CBIO_ERR_CONN_CLOSE;
532             }
533         }
534 
535 
536         /// <summary>
537         /// Call back used for sending DTLS information
538         /// </summary>
539         /// <param name="ssl">pointer to ssl struct</param>
540         /// <param name="buf">buffer containing information to send</param>
541         /// <param name="sz">size of buffer to send</param>
542         /// <param name="ctx">optional information</param>
543         /// <returns>amount of information sent</returns>
wolfSSL_dtlsCbIOSend(IntPtr ssl, IntPtr buf, int sz, IntPtr ctx)544         private static int wolfSSL_dtlsCbIOSend(IntPtr ssl, IntPtr buf, int sz, IntPtr ctx)
545         {
546             if (sz <= 0)
547             {
548                 log(ERROR_LOG, "wolfssl dtls send error, size less than 0");
549                 return wolfssl.CBIO_ERR_GENERAL;
550             }
551 
552             try
553             {
554                 System.Runtime.InteropServices.GCHandle gch;
555                 gch = GCHandle.FromIntPtr(ctx);
556 
557                 DTLS_con con = (DTLS_con)gch.Target;
558 
559                 Byte[] msg = new Byte[sz];
560                 Marshal.Copy(buf, msg, 0, sz);
561                 con.udp.Send(msg, msg.Length, con.ep);
562                 return msg.Length;
563             }
564             catch (Exception e)
565             {
566                 log(ERROR_LOG, "socket connection issue " + e.ToString());
567                 return wolfssl.CBIO_ERR_CONN_CLOSE;
568             }
569         }
570 
571 
572         /// <summary>
573         /// Call back to allow receiving DTLS information
574         /// </summary>
575         /// <param name="ssl">structure of ssl passed in</param>
576         /// <param name="buf">buffer to contain received msg</param>
577         /// <param name="sz">size of buffer</param>
578         /// <param name="ctx">optional information passed in</param>
579         /// <returns>size of message received</returns>
wolfSSL_dtlsCbIORecv(IntPtr ssl, IntPtr buf, int sz, IntPtr ctx)580         private static int wolfSSL_dtlsCbIORecv(IntPtr ssl, IntPtr buf, int sz, IntPtr ctx)
581         {
582             if (sz <= 0)
583             {
584                 log(ERROR_LOG, "wolfssl dtls receive error, size less than 0");
585                 return wolfssl.CBIO_ERR_GENERAL;
586             }
587 
588             try
589             {
590                 System.Runtime.InteropServices.GCHandle gch;
591                 gch = GCHandle.FromIntPtr(ctx);
592                 DTLS_con con = (DTLS_con)gch.Target;
593 
594                 Byte[] msg = con.udp.Receive(ref con.ep);
595                 if (msg.Length > sz)
596                 {
597                     log(ERROR_LOG, "wolfssl DTLS packet received was larger than buffer");
598                     return wolfssl.CBIO_ERR_GENERAL;
599                 }
600 
601                 Marshal.Copy(msg, 0, buf, msg.Length);
602                 return msg.Length;
603             }
604             catch (Exception e)
605             {
606                 /* issue with receive or size of buffer */
607                 log(ERROR_LOG, "socket read issue " + e.ToString());
608                 return wolfssl.CBIO_ERR_CONN_CLOSE;
609             }
610         }
611 
612 
613         /// <summary>
614         /// Create a new ssl structure
615         /// </summary>
616         /// <param name="ctx">structure to create ssl structure from</param>
617         /// <returns>pointer to ssl structure</returns>
new_ssl(IntPtr ctx)618         public static IntPtr new_ssl(IntPtr ctx)
619         {
620             if (ctx == IntPtr.Zero)
621                 return IntPtr.Zero;
622 
623             try
624             {
625                 ssl_handle io;
626                 IntPtr local_ctx = unwrap_ctx(ctx);
627                 if (local_ctx == IntPtr.Zero)
628                 {
629                     log(ERROR_LOG, "new_ssl ctx unwrap error");
630                     return IntPtr.Zero;
631                 }
632 
633                 io = new ssl_handle();
634                 io.set_ssl(wolfSSL_new(local_ctx));
635 
636                 /* check if null */
637                 if (io.get_ssl() == IntPtr.Zero)
638                 {
639                     return IntPtr.Zero;
640                 }
641 
642                 /* keep memory pinned to be able to reference by address */
643                 return GCHandle.ToIntPtr(GCHandle.Alloc(io, GCHandleType.Pinned));
644             }
645             catch (Exception e)
646             {
647                 log(ERROR_LOG, e.ToString());
648                 return IntPtr.Zero;
649             }
650         }
651 
652 
653         /// <summary>
654         /// Used for a server to accept a connection
655         /// </summary>
656         /// <param name="ssl">structure containing info for connection</param>
657         /// <returns>1 on success</returns>
accept(IntPtr ssl)658         public static int accept(IntPtr ssl)
659         {
660             if (ssl == IntPtr.Zero)
661                 return FAILURE;
662             try
663             {
664                 IntPtr sslCtx = unwrap_ssl(ssl);
665                 if (sslCtx == IntPtr.Zero)
666                 {
667                     log(ERROR_LOG, "accept ssl unwrap error");
668                     return FAILURE;
669                 }
670 
671                 return wolfSSL_accept(sslCtx);
672             }
673             catch (Exception e)
674             {
675                 log(ERROR_LOG, "accept error " + e.ToString());
676                 return FAILURE;
677             }
678         }
679 
680 
681         /// <summary>
682         /// Used for a client to connect
683         /// </summary>
684         /// <param name="ssl">structure containing connection info</param>
685         /// <returns>1 on success</returns>
connect(IntPtr ssl)686         public static int connect(IntPtr ssl)
687         {
688             if (ssl == IntPtr.Zero)
689                 return FAILURE;
690             try
691             {
692                 IntPtr sslCtx = unwrap_ssl(ssl);
693                 if (sslCtx == IntPtr.Zero)
694                 {
695                     log(ERROR_LOG, "connect ssl unwrap error");
696                     return FAILURE;
697                 }
698 
699                 return wolfSSL_connect(sslCtx);
700             }
701             catch (Exception e)
702             {
703                 log(ERROR_LOG, "connect error " + e.ToString());
704                 return FAILURE;
705             }
706         }
707 
708 
709         /// <summary>
710         /// Read message from secure connection
711         /// </summary>
712         /// <param name="ssl">structure containing info about connection</param>
713         /// <param name="buf">object to hold incoming message (Unicode format)</param>
714         /// <param name="sz">size of available memory in buf</param>
715         /// <returns>amount of data read on success</returns>
read(IntPtr ssl, StringBuilder buf, int sz)716         public static int read(IntPtr ssl, StringBuilder buf, int sz)
717         {
718             if (ssl == IntPtr.Zero)
719                 return FAILURE;
720             try
721             {
722                 IntPtr sslCtx = unwrap_ssl(ssl);
723                 IntPtr data;
724                 int ret;
725                 byte[] msg;
726 
727                 buf.Clear(); /* Clear incomming buffer */
728 
729                 if (sslCtx == IntPtr.Zero)
730                 {
731                     log(ERROR_LOG, "read ssl unwrap error");
732                     return FAILURE;
733                 }
734                 data = Marshal.AllocHGlobal(sz);
735 
736                 ret = wolfSSL_read(sslCtx, data, sz);
737 
738                 if (ret >= 0)
739                 {
740                     /* Get data that was sent across and store it using a literal read of
741                      * the conversion from bytes to character. Takes care of if
742                      * a null terminator is part of the message read.
743                      */
744                     msg = new byte[ret];
745                     Marshal.Copy(data, msg, 0, ret);
746                     for (int i = 0; i < ret; i++)
747                     {
748                         buf.Append(@Convert.ToChar(msg[i]));
749                     }
750                 }
751                 Marshal.FreeHGlobal(data);
752 
753                 return ret;
754             }
755             catch (Exception e)
756             {
757                 log(ERROR_LOG, "wolfssl read error " + e.ToString());
758                 return FAILURE;
759             }
760         }
761 
762 
763         /// <summary>
764         /// Read message from secure connection using a byte array
765         /// </summary>
766         /// <param name="ssl">structure containing info about connection</param>
767         /// <param name="buf">object to hold incoming message (raw bytes)</param>
768         /// <param name="sz">size of available memory in buf</param>
769         /// <returns>amount of data read on success</returns>
read(IntPtr ssl, byte[] buf, int sz)770         public static int read(IntPtr ssl, byte[] buf, int sz)
771         {
772             if (ssl == IntPtr.Zero)
773                 return FAILURE;
774             try
775             {
776                 IntPtr sslCtx = unwrap_ssl(ssl);
777                 IntPtr data;
778                 int ret;
779 
780                 if (sslCtx == IntPtr.Zero)
781                 {
782                     log(ERROR_LOG, "read ssl unwrap error");
783                     return FAILURE;
784                 }
785                 data = Marshal.AllocHGlobal(sz);
786 
787                 ret = wolfSSL_read(sslCtx, data, sz);
788 
789                 if (ret >= 0)
790                 {
791                     Marshal.Copy(data, buf, 0, ret);
792                 }
793                 Marshal.FreeHGlobal(data);
794 
795                 return ret;
796             }
797             catch (Exception e)
798             {
799                 log(ERROR_LOG, "wolfssl read error " + e.ToString());
800                 return FAILURE;
801             }
802         }
803 
804 
805 
806         /// <summary>
807         /// Write message to secure connection
808         /// </summary>
809         /// <param name="ssl">structure containing connection info</param>
810         /// <param name="buf">message to send</param>
811         /// <param name="sz">size of the message</param>
812         /// <returns>amount sent on success</returns>
write(IntPtr ssl, StringBuilder buf, int sz)813         public static int write(IntPtr ssl, StringBuilder buf, int sz)
814         {
815             if (ssl == IntPtr.Zero)
816                 return FAILURE;
817             try
818             {
819                 IntPtr sslCtx = unwrap_ssl(ssl);
820                 IntPtr data;
821                 int ret;
822 
823                 if (sslCtx == IntPtr.Zero)
824                 {
825                     log(ERROR_LOG, "write ssl unwrap error");
826                     return FAILURE;
827                 }
828 
829                 data = Marshal.AllocHGlobal(sz);
830                 Marshal.Copy(System.Text.Encoding.Default.GetBytes(buf.ToString()), 0,
831                        data, System.Text.Encoding.Default.GetByteCount(buf.ToString()));
832                 ret = wolfSSL_write(sslCtx, data, sz);
833                 Marshal.FreeHGlobal(data);
834                 return ret;
835 
836             }
837             catch (Exception e)
838             {
839                 log(ERROR_LOG, "wolfssl write error " + e.ToString());
840                 return FAILURE;
841             }
842         }
843 
844 
845         /// <summary>
846         /// Write message to secure connection
847         /// </summary>
848         /// <param name="ssl">structure containing connection info</param>
849         /// <param name="buf">message to send</param>
850         /// <param name="sz">size of the message</param>
851         /// <returns>amount sent on success</returns>
write(IntPtr ssl, byte[] buf, int sz)852         public static int write(IntPtr ssl, byte[] buf, int sz)
853         {
854             if (ssl == IntPtr.Zero)
855                 return FAILURE;
856             try
857             {
858                 IntPtr sslCtx = unwrap_ssl(ssl);
859                 IntPtr data;
860                 int ret;
861 
862                 if (sslCtx == IntPtr.Zero)
863                 {
864                     log(ERROR_LOG, "write ssl unwrap error");
865                     return FAILURE;
866                 }
867                 data = Marshal.AllocHGlobal(sz);
868                 Marshal.Copy(buf, 0, data, sz);
869                 ret = wolfSSL_write(sslCtx, data, sz);
870                 Marshal.FreeHGlobal(data);
871                 return ret;
872 
873             }
874             catch (Exception e)
875             {
876                 log(ERROR_LOG, "wolfssl write error " + e.ToString());
877                 return FAILURE;
878             }
879         }
880 
881 
882         /// <summary>
883         /// Free information stored in ssl struct
884         /// </summary>
885         /// <param name="ssl">pointer to ssl struct to free</param>
free(IntPtr ssl)886         public static void free(IntPtr ssl)
887         {
888             try
889             {
890                 IntPtr sslCtx;
891                 GCHandle gch = GCHandle.FromIntPtr(ssl);
892                 ssl_handle handles = (ssl_handle)gch.Target;
893 
894                 sslCtx = handles.get_ssl();
895                 wolfSSL_free(sslCtx);
896                 handles.free();
897                 gch.Free();
898             }
899             catch (Exception e)
900             {
901                 log(ERROR_LOG, "wolfssl free error " + e.ToString());
902             }
903         }
904 
905 
906         /// <summary>
907         /// Shutdown a connection
908         /// </summary>
909         /// <param name="ssl">pointer to ssl struct to close connection of</param>
910         /// <returns>1 on success</returns>
shutdown(IntPtr ssl)911         public static int shutdown(IntPtr ssl)
912         {
913             if (ssl == IntPtr.Zero)
914                 return FAILURE;
915             try
916             {
917                 IntPtr sslCtx = unwrap_ssl(ssl);
918                 if (sslCtx == IntPtr.Zero)
919                 {
920                     log(ERROR_LOG, "shutdown ssl unwrap error");
921                     return FAILURE;
922                 }
923 
924                 return wolfSSL_shutdown(sslCtx);
925             }
926             catch (Exception e)
927             {
928                 log(ERROR_LOG, "wolfssl shutdwon error " + e.ToString());
929                 return FAILURE;
930             }
931         }
932 
933 
934         /// <summary>
935         /// Optional, can be used to set a custom receive function
936         /// </summary>
937         /// <param name="ctx">structure to set receive function in</param>
938         /// <param name="func">function to use when reading socket</param>
SetIORecv(IntPtr ctx, CallbackIORecv_delegate func)939         public static void SetIORecv(IntPtr ctx, CallbackIORecv_delegate func)
940         {
941             try
942             {
943                 GCHandle gch = GCHandle.FromIntPtr(ctx);
944                 ctx_handle handles = (ctx_handle)gch.Target;
945 
946                 /* check if already stored handle needs freed */
947                 gch = handles.get_receive();
948                 if (!Object.Equals(gch, default(GCHandle)))
949                 {
950                     gch.Free();
951                 }
952 
953                 /* keep new function alive */
954                 handles.set_receive(GCHandle.Alloc(func));
955 
956                 wolfSSL_CTX_SetIORecv(handles.get_ctx(), func);
957             }
958             catch (Exception e)
959             {
960                 log(ERROR_LOG, "wolfssl setIORecv error " + e.ToString());
961             }
962         }
963 
964 
965         /// <summary>
966         /// Optional, can be used to set a custom send function
967         /// </summary>
968         /// <param name="ctx">structure to set function in</param>
969         /// <param name="func">function to use when sending data</param>
SetIOSend(IntPtr ctx, CallbackIOSend_delegate func)970         public static void SetIOSend(IntPtr ctx, CallbackIOSend_delegate func)
971         {
972             try
973             {
974                 GCHandle gch = GCHandle.FromIntPtr(ctx);
975                 ctx_handle handles = (ctx_handle)gch.Target;
976 
977                 /* check if already stored handle needs freed */
978                 gch = handles.get_send();
979                 if (!Object.Equals(gch, default(GCHandle)))
980                 {
981                     gch.Free();
982                 }
983 
984                 /* keep new function alive */
985                 handles.set_send(GCHandle.Alloc(func));
986 
987                 wolfSSL_CTX_SetIOSend(handles.get_ctx(), func);
988             }
989             catch (Exception e)
990             {
991                 log(ERROR_LOG, "wolfssl setIOSend error " + e.ToString());
992             }
993         }
994 
995 
996         /// <summary>
997         /// Create a new CTX structure
998         /// </summary>
999         /// <param name="method">method to use such as TLSv1.2</param>
1000         /// <returns>pointer to CTX structure</returns>
CTX_new(IntPtr method)1001         public static IntPtr CTX_new(IntPtr method)
1002         {
1003             try
1004             {
1005                 IntPtr ctx = wolfSSL_CTX_new(method);
1006                 if (ctx == IntPtr.Zero)
1007                     return ctx;
1008 
1009                 ctx_handle io = new ctx_handle();
1010                 io.set_ctx(ctx);
1011 
1012                 CallbackIORecv_delegate recv = new CallbackIORecv_delegate(wolfssl.wolfSSLCbIORecv);
1013                 io.set_receive(GCHandle.Alloc(recv));
1014                 wolfSSL_CTX_SetIORecv(ctx, recv);
1015 
1016                 CallbackIOSend_delegate send = new CallbackIOSend_delegate(wolfssl.wolfSSLCbIOSend);
1017                 io.set_send(GCHandle.Alloc(send));
1018                 wolfSSL_CTX_SetIOSend(ctx, send);
1019 
1020                 /* keep memory pinned */
1021                 return GCHandle.ToIntPtr(GCHandle.Alloc(io, GCHandleType.Pinned));
1022             }
1023             catch (Exception e)
1024             {
1025                 log(ERROR_LOG, "ctx_new error " + e.ToString());
1026                 return IntPtr.Zero;
1027             }
1028         }
1029 
1030 
1031         /// <summary>
1032         /// Create a new CTX structure for a DTLS connection
1033         /// </summary>
1034         /// <param name="method">Method to use in connection ie DTLSv1.2</param>
1035         /// <returns></returns>
CTX_dtls_new(IntPtr method)1036         public static IntPtr CTX_dtls_new(IntPtr method)
1037         {
1038             try
1039             {
1040                 IntPtr ctx = wolfSSL_CTX_new(method);
1041                 if (ctx == IntPtr.Zero)
1042                     return ctx;
1043 
1044                 ctx_handle io = new ctx_handle();
1045                 io.set_ctx(ctx);
1046 
1047                 CallbackIORecv_delegate recv = new CallbackIORecv_delegate(wolfssl.wolfSSL_dtlsCbIORecv);
1048                 io.set_receive(GCHandle.Alloc(recv));
1049                 wolfSSL_CTX_SetIORecv(ctx, recv);
1050 
1051                 CallbackIOSend_delegate send = new CallbackIOSend_delegate(wolfssl.wolfSSL_dtlsCbIOSend);
1052                 io.set_send(GCHandle.Alloc(send));
1053                 wolfSSL_CTX_SetIOSend(ctx, send);
1054 
1055                 /* keep memory pinned */
1056                 return GCHandle.ToIntPtr(GCHandle.Alloc(io, GCHandleType.Pinned));
1057             }
1058             catch (Exception e)
1059             {
1060                 log(ERROR_LOG, "ctx_dtls_new error " + e.ToString());
1061                 return IntPtr.Zero;
1062             }
1063         }
1064 
1065 
1066         /// <summary>
1067         /// Free information used in CTX structure
1068         /// </summary>
1069         /// <param name="ctx">structure to free</param>
CTX_free(IntPtr ctx)1070         public static void CTX_free(IntPtr ctx)
1071         {
1072             try
1073             {
1074                 GCHandle gch = GCHandle.FromIntPtr(ctx);
1075                 ctx_handle handles = (ctx_handle)gch.Target;
1076                 wolfSSL_CTX_free(handles.get_ctx());
1077                 handles.free();
1078                 gch.Free();
1079             }
1080             catch (Exception e)
1081             {
1082                 log(ERROR_LOG, "wolfssl ctx free error " + e.ToString());
1083             }
1084         }
1085 
1086 
1087         /// <summary>
1088         /// Set identity hint to use
1089         /// </summary>
1090         /// <param name="ctx">pointer to structure of ctx to set hint in</param>
1091         /// <param name="hint">hint to use</param>
1092         /// <returns>1 on success</returns>
CTX_use_psk_identity_hint(IntPtr ctx, StringBuilder hint)1093         public static int CTX_use_psk_identity_hint(IntPtr ctx, StringBuilder hint)
1094         {
1095             try
1096             {
1097                 IntPtr local_ctx = unwrap_ctx(ctx);
1098                 if (local_ctx == IntPtr.Zero)
1099                 {
1100                     log(ERROR_LOG, "CTX use psk identity hint unwrap error");
1101                     return FAILURE;
1102                 }
1103 
1104                 return wolfSSL_CTX_use_psk_identity_hint(local_ctx, hint);
1105             }
1106             catch (Exception e)
1107             {
1108                 log(ERROR_LOG, "wolfssl psk identity hint error " + e.ToString());
1109                 return FAILURE;
1110             }
1111         }
1112 
1113 
1114         /// <summary>
1115         /// Set the function to use for PSK connections
1116         /// </summary>
1117         /// <param name="ctx">pointer to CTX that the function is set in</param>
1118         /// <param name="psk_cb">PSK function to use</param>
CTX_set_psk_server_callback(IntPtr ctx, psk_delegate psk_cb)1119         public static void CTX_set_psk_server_callback(IntPtr ctx, psk_delegate psk_cb)
1120         {
1121             try
1122             {
1123                 GCHandle gch = GCHandle.FromIntPtr(ctx);
1124                 ctx_handle handles = (ctx_handle)gch.Target;
1125 
1126                 handles.set_psk(GCHandle.Alloc(psk_cb));
1127                 wolfSSL_CTX_set_psk_server_callback(handles.get_ctx(), psk_cb);
1128             }
1129             catch (Exception e)
1130             {
1131                 log(ERROR_LOG, "wolfssl psk server callback error " + e.ToString());
1132             }
1133         }
1134 
1135 
1136         /// <summary>
1137         /// Set the function to use for PSK connections
1138         /// </summary>
1139         /// <param name="ctx">pointer to CTX that the function is set in</param>
1140         /// <param name="psk_cb">PSK function to use</param>
CTX_set_psk_client_callback(IntPtr ctx, psk_client_delegate psk_cb)1141         public static void CTX_set_psk_client_callback(IntPtr ctx, psk_client_delegate psk_cb)
1142         {
1143             try
1144             {
1145                 GCHandle gch = GCHandle.FromIntPtr(ctx);
1146                 ctx_handle handles = (ctx_handle)gch.Target;
1147 
1148                 handles.set_psk(GCHandle.Alloc(psk_cb));
1149                 wolfSSL_CTX_set_psk_client_callback(handles.get_ctx(), psk_cb);
1150             }
1151             catch (Exception e)
1152             {
1153                 log(ERROR_LOG, "wolfssl psk client callback error " + e.ToString());
1154             }
1155         }
1156 
1157 
1158         /// <summary>
1159         /// Set the function to use for PSK connections on a single TLS/DTLS connection
1160         /// </summary>
1161         /// <param name="ctx">pointer to SSL that the function is set in</param>
1162         /// <param name="psk_cb">PSK function to use</param>
set_psk_server_callback(IntPtr ssl, psk_delegate psk_cb)1163         public static void set_psk_server_callback(IntPtr ssl, psk_delegate psk_cb)
1164         {
1165             try
1166             {
1167                 GCHandle gch = GCHandle.FromIntPtr(ssl);
1168                 ssl_handle handles = (ssl_handle)gch.Target;
1169 
1170                 handles.set_psk(GCHandle.Alloc(psk_cb));
1171                 wolfSSL_set_psk_server_callback(handles.get_ssl(), psk_cb);
1172             }
1173             catch (Exception e)
1174             {
1175                 log(ERROR_LOG, "wolfssl psk server callback error " + e.ToString());
1176             }
1177         }
1178 
1179 
1180         /// <summary>
1181         /// Set Socket for TLS connection
1182         /// </summary>
1183         /// <param name="ssl">structure to set Socket in</param>
1184         /// <param name="fd">Socket to use</param>
1185         /// <returns>1 on success</returns>
set_fd(IntPtr ssl, Socket fd)1186         public static int set_fd(IntPtr ssl, Socket fd)
1187         {
1188             /* sanity check on inputs */
1189             if (ssl == IntPtr.Zero)
1190             {
1191                 return FAILURE;
1192             }
1193 
1194             try
1195             {
1196                 if (!fd.Equals(null))
1197                 {
1198                     GCHandle gch = GCHandle.FromIntPtr(ssl);
1199                     ssl_handle handles = (ssl_handle)gch.Target;
1200                     IntPtr sslCtx = handles.get_ssl();
1201                     IntPtr ptr;
1202                     GCHandle fd_pin = GCHandle.Alloc(fd);
1203 
1204                     if (sslCtx == IntPtr.Zero)
1205                     {
1206                         log(ERROR_LOG, "wolfssl error setting up fd!!");
1207                         return FAILURE;
1208                     }
1209 
1210                     handles.set_fd(fd_pin);
1211                     ptr = GCHandle.ToIntPtr(fd_pin);
1212                     wolfSSL_SetIOWriteCtx(sslCtx, ptr); //pass along the socket for writing to
1213                     wolfSSL_SetIOReadCtx(sslCtx, ptr); //pass along the socket for reading from
1214 
1215                     return SUCCESS;
1216                 }
1217 
1218                 return FAILURE;
1219             }
1220             catch (Exception e)
1221             {
1222                 log(ERROR_LOG, "Error setting up fd!! " + e.ToString());
1223                 return FAILURE;
1224             }
1225         }
1226 
1227 
1228         /// <summary>
1229         /// Get socket of a TLS connection
1230         /// </summary>
1231         /// <param name="ssl">structure to get socket from</param>
1232         /// <returns>Socket object used for connection</returns>
get_fd(IntPtr ssl)1233         public static Socket get_fd(IntPtr ssl)
1234         {
1235             try
1236             {
1237                 IntPtr ptr;
1238                 IntPtr sslCtx = unwrap_ssl(ssl);
1239                 if (sslCtx == IntPtr.Zero)
1240                 {
1241                     log(ERROR_LOG, "wolfssl get_fd error");
1242                     return null;
1243                 }
1244 
1245                 ptr = wolfSSL_GetIOReadCtx(sslCtx);
1246                 if (ptr != IntPtr.Zero)
1247                 {
1248                     GCHandle gch = GCHandle.FromIntPtr(ptr);
1249                     return (System.Net.Sockets.Socket)gch.Target;
1250                 }
1251                 return null;
1252             }
1253             catch (Exception e)
1254             {
1255                 log(ERROR_LOG, "wolfssl get_fd error " + e.ToString());
1256                 return null;
1257             }
1258         }
1259 
1260 
1261 
1262         /// <summary>
1263         /// Set information needed to send and receive a DTLS connection
1264         /// </summary>
1265         /// <param name="ssl">structure to set information in</param>
1266         /// <param name="udp">UDP object to send and receive</param>
1267         /// <param name="ep">End point of connection</param>
1268         /// <returns>1 on success</returns>
set_dtls_fd(IntPtr ssl, UdpClient udp, IPEndPoint ep)1269         public static int set_dtls_fd(IntPtr ssl, UdpClient udp, IPEndPoint ep)
1270         {
1271             /* sanity check on inputs */
1272             if (ssl == IntPtr.Zero)
1273             {
1274                 return FAILURE;
1275             }
1276 
1277             try
1278             {
1279                 if (!udp.Equals(null) && !ep.Equals(null))
1280                 {
1281                     IntPtr ptr;
1282                     DTLS_con con;
1283                     GCHandle gch = GCHandle.FromIntPtr(ssl);
1284                     ssl_handle handles = (ssl_handle)gch.Target;
1285                     GCHandle fd_pin;
1286 
1287                     con = new DTLS_con();
1288                     con.udp = udp;
1289                     con.ep = ep;
1290                     fd_pin = GCHandle.Alloc(con);
1291                     handles.set_fd(fd_pin);
1292                     ptr = GCHandle.ToIntPtr(fd_pin);
1293                     wolfSSL_SetIOWriteCtx(handles.get_ssl(), ptr); //pass along the socket for writing to
1294                     wolfSSL_SetIOReadCtx(handles.get_ssl(), ptr); //pass along the socket for reading from
1295 
1296                     return SUCCESS;
1297                 }
1298                 return FAILURE;
1299             }
1300             catch (Exception e)
1301             {
1302                 log(ERROR_LOG, "Error setting up fd!! " + e.ToString());
1303                 return FAILURE;
1304             }
1305         }
1306 
1307 
1308         /// <summary>
1309         /// Get the pointer to DTLS_con class used for connection
1310         /// </summary>
1311         /// <param name="ssl">structure to get connection from</param>
1312         /// <returns>DTLS_con object</returns>
get_dtls_fd(IntPtr ssl)1313         public static DTLS_con get_dtls_fd(IntPtr ssl)
1314         {
1315             try
1316             {
1317                 IntPtr ptr;
1318                 IntPtr sslCtx = unwrap_ssl(ssl);
1319                 if (sslCtx == IntPtr.Zero)
1320                 {
1321                     log(ERROR_LOG, "wolfssl get_dtls_fd error");
1322                     return null;
1323                 }
1324 
1325                 ptr = wolfSSL_GetIOReadCtx(sslCtx);
1326                 if (ptr != IntPtr.Zero)
1327                 {
1328                     GCHandle gch = GCHandle.FromIntPtr(ptr);
1329                     return (DTLS_con)gch.Target;
1330                 }
1331                 return null;
1332             }
1333             catch (Exception e)
1334             {
1335                 log(ERROR_LOG, "wolfssl get_dtls_fd error " + e.ToString());
1336                 return null;
1337             }
1338         }
1339 
1340 
1341         /// <summary>
1342         /// Get available cipher suites
1343         /// </summary>
1344         /// <param name="list">list to fill with cipher suite names</param>
1345         /// <param name="sz">size of list available to fill</param>
1346         /// <returns>1 on success</returns>
get_ciphers(StringBuilder list, int sz)1347         public static int get_ciphers(StringBuilder list, int sz)
1348         {
1349             try
1350             {
1351                 return wolfSSL_get_ciphers(list, sz);
1352             }
1353             catch (Exception e)
1354             {
1355                 log(ERROR_LOG, "wolfssl get_ciphers error " + e.ToString());
1356                 return FAILURE;
1357             }
1358         }
1359 
1360 
1361         /// <summary>
1362         /// Initialize wolfSSL library
1363         /// </summary>
1364         /// <returns>1 on success</returns>
Init()1365         public static int Init()
1366         {
1367             try
1368             {
1369                 return wolfSSL_Init();
1370             }
1371             catch (Exception e)
1372             {
1373                 log(ERROR_LOG, "wolfssl init error " + e.ToString());
1374                 return FAILURE;
1375             }
1376         }
1377 
1378 
1379         /// <summary>
1380         /// Clean up wolfSSL library memory
1381         /// </summary>
1382         /// <returns>1 on success</returns>
Cleanup()1383         public static int Cleanup()
1384         {
1385             try
1386             {
1387                 return wolfSSL_Cleanup();
1388             }
1389             catch (Exception e)
1390             {
1391                 log(ERROR_LOG, "wolfssl cleanup error " + e.ToString());
1392                 return FAILURE;
1393             }
1394         }
1395 
1396 
1397         /// <summary>
1398         /// Set up TLS version 1.2 method
1399         /// </summary>
1400         /// <returns>pointer to TLSv1.2 method</returns>
useTLSv1_2_server()1401         public static IntPtr useTLSv1_2_server()
1402         {
1403             try
1404             {
1405                 return wolfTLSv1_2_server_method();
1406             }
1407             catch (Exception e)
1408             {
1409                 log(ERROR_LOG, "wolfssl error " + e.ToString());
1410                 return IntPtr.Zero;
1411             }
1412         }
1413 
1414         /// <summary>
1415         /// Set up TLS version 1.3 method
1416         /// </summary>
1417         /// <returns>pointer to TLSv1.3 method</returns>
useTLSv1_3_server()1418         public static IntPtr useTLSv1_3_server()
1419         {
1420             try
1421             {
1422                 return wolfTLSv1_3_server_method();
1423             }
1424             catch (Exception e)
1425             {
1426                 log(ERROR_LOG, "wolfssl error " + e.ToString());
1427                 return IntPtr.Zero;
1428             }
1429         }
1430 
1431 
1432         /// <summary>
1433         /// Use any TLS version
1434         /// </summary>
1435         /// <returns>pointer to method</returns>
usev23_server()1436         public static IntPtr usev23_server()
1437         {
1438             try
1439             {
1440                 return wolfSSLv23_server_method();
1441             }
1442             catch (Exception e)
1443             {
1444                 log(ERROR_LOG, "wolfssl error " + e.ToString());
1445                 return IntPtr.Zero;
1446             }
1447         }
1448 
1449 
1450         /// <summary>
1451         /// Set up TLS version 1.2 method
1452         /// </summary>
1453         /// <returns>pointer to TLSv1.2 method</returns>
useTLSv1_2_client()1454         public static IntPtr useTLSv1_2_client()
1455         {
1456             try
1457             {
1458                 return wolfTLSv1_2_client_method();
1459             }
1460             catch (Exception e)
1461             {
1462                 log(ERROR_LOG, "wolfssl error " + e.ToString());
1463                 return IntPtr.Zero;
1464             }
1465         }
1466 
1467         /// <summary>
1468         /// Set up TLS version 1.3 method
1469         /// </summary>
1470         /// <returns>pointer to TLSv1.3 method</returns>
useTLSv1_3_client()1471         public static IntPtr useTLSv1_3_client()
1472         {
1473             try
1474             {
1475                 return wolfTLSv1_3_client_method();
1476             }
1477             catch (Exception e)
1478             {
1479                 log(ERROR_LOG, "wolfssl error " + e.ToString());
1480                 return IntPtr.Zero;
1481             }
1482         }
1483 
1484         /// <summary>
1485         /// Use any TLS version
1486         /// </summary>
1487         /// <returns>pointer to method</returns>
usev23_client()1488         public static IntPtr usev23_client()
1489         {
1490             try
1491             {
1492                 return wolfSSLv23_client_method();
1493             }
1494             catch (Exception e)
1495             {
1496                 log(ERROR_LOG, "wolfssl error " + e.ToString());
1497                 return IntPtr.Zero;
1498             }
1499         }
1500 
1501 
1502         /// <summary>
1503         /// Set up DTLS version 1.2
1504         /// </summary>
1505         /// <returns>pointer to DTLSv1.2 method</returns>
useDTLSv1_2_server()1506         public static IntPtr useDTLSv1_2_server()
1507         {
1508             try
1509             {
1510                 return wolfDTLSv1_2_server_method();
1511             }
1512             catch (Exception e)
1513             {
1514                 log(ERROR_LOG, "wolfssl error " + e.ToString());
1515                 return IntPtr.Zero;
1516             }
1517         }
1518 
1519 
1520         /// <summary>
1521         /// Set up DTLS version 1.2
1522         /// </summary>
1523         /// <returns>pointer to DTLSv1.2 method</returns>
useDTLSv1_2_client()1524         public static IntPtr useDTLSv1_2_client()
1525         {
1526             try
1527             {
1528                 return wolfDTLSv1_2_client_method();
1529             }
1530             catch (Exception e)
1531             {
1532                 log(ERROR_LOG, "wolfssl error " + e.ToString());
1533                 return IntPtr.Zero;
1534             }
1535         }
1536 
1537 
1538         /// <summary>
1539         /// Gets the current cipher suite being used in connection
1540         /// </summary>
1541         /// <param name="ssl">SSL struct to get cipher suite from</param>
1542         /// <returns>string containing current cipher suite</returns>
get_current_cipher(IntPtr ssl)1543         public static string get_current_cipher(IntPtr ssl)
1544         {
1545             if (ssl == IntPtr.Zero)
1546                 return null;
1547             try
1548             {
1549                 IntPtr ssl_cipher;
1550                 IntPtr ssl_cipher_ptr;
1551                 string ssl_cipher_str;
1552 
1553                 IntPtr sslCtx = unwrap_ssl(ssl);
1554                 if (sslCtx == IntPtr.Zero)
1555                 {
1556                     log(ERROR_LOG, "wolfssl get_current_cipher error");
1557                     return null;
1558                 }
1559 
1560                 ssl_cipher = wolfSSL_get_current_cipher(sslCtx);
1561                 ssl_cipher_ptr = wolfSSL_CIPHER_get_name(ssl_cipher);
1562                 ssl_cipher_str = Marshal.PtrToStringAnsi(ssl_cipher_ptr);
1563 
1564                 return ssl_cipher_str;
1565             }
1566             catch (Exception e)
1567             {
1568                 log(ERROR_LOG, "wolfssl get current cipher error " + e.ToString());
1569                 return null;
1570             }
1571         }
1572 
1573 
1574         /// <summary>
1575         /// Set available cipher suites for all ssl structs created from ctx
1576         /// </summary>
1577         /// <param name="ctx">CTX structure to set</param>
1578         /// <param name="list">List full of ciphers suites</param>
1579         /// <returns>1 on success</returns>
CTX_set_cipher_list(IntPtr ctx, StringBuilder list)1580         public static int CTX_set_cipher_list(IntPtr ctx, StringBuilder list)
1581         {
1582             try
1583             {
1584                 IntPtr local_ctx = unwrap_ctx(ctx);
1585                 if (local_ctx == IntPtr.Zero)
1586                 {
1587                     log(ERROR_LOG, "CTX set cipher list error");
1588                     return FAILURE;
1589                 }
1590 
1591                 return wolfSSL_CTX_set_cipher_list(local_ctx, list);
1592             }
1593             catch (Exception e)
1594             {
1595                 log(ERROR_LOG, "wolfssl ctx set cipher list error " + e.ToString());
1596                 return FAILURE;
1597             }
1598         }
1599 
1600 
1601         /// <summary>
1602         /// Set available cipher suite in local connection
1603         /// </summary>
1604         /// <param name="ssl">Structure to set cipher suite in</param>
1605         /// <param name="list">List of cipher suites</param>
1606         /// <returns>1 on success</returns>
set_cipher_list(IntPtr ssl, StringBuilder list)1607         public static int set_cipher_list(IntPtr ssl, StringBuilder list)
1608         {
1609             try
1610             {
1611                 IntPtr sslCtx = unwrap_ssl(ssl);
1612                 if (sslCtx == IntPtr.Zero)
1613                 {
1614                     log(ERROR_LOG, "wolfssl set_cipher_list error");
1615                     return FAILURE;
1616                 }
1617 
1618                 return wolfSSL_set_cipher_list(sslCtx, list);
1619             }
1620             catch (Exception e)
1621             {
1622                 log(ERROR_LOG, "wolfssl set cipher error " + e.ToString());
1623                 return FAILURE;
1624             }
1625         }
1626 
1627 
1628         /// <summary>
1629         /// Gets the version of the connection made ie TLSv1.2
1630         /// </summary>
1631         /// <param name="ssl">SSL struct to get version of</param>
1632         /// <returns>string containing version</returns>
get_version(IntPtr ssl)1633         public static string get_version(IntPtr ssl)
1634         {
1635             if (ssl == IntPtr.Zero)
1636                 return null;
1637 
1638             try
1639             {
1640                 IntPtr version_ptr;
1641                 string version;
1642 
1643                 IntPtr sslCtx = unwrap_ssl(ssl);
1644                 if (sslCtx == IntPtr.Zero)
1645                 {
1646                     log(ERROR_LOG, "wolfssl get_version error");
1647                     return null;
1648                 }
1649 
1650                 version_ptr = wolfSSL_get_version(sslCtx);
1651                 version = Marshal.PtrToStringAnsi(version_ptr);
1652 
1653                 return version;
1654             }
1655             catch (Exception e)
1656             {
1657                 log(ERROR_LOG, "wolfssl get version error " + e.ToString());
1658                 return null;
1659             }
1660         }
1661 
1662 
1663         /// <summary>
1664         /// Get a string containing error value and reason
1665         /// </summary>
1666         /// <param name="ssl">SSL struct that had error</param>
1667         /// <returns>String containing error value and reason</returns>
get_error(IntPtr ssl)1668         public static string get_error(IntPtr ssl)
1669         {
1670             if (ssl == IntPtr.Zero)
1671                 return null;
1672 
1673             try
1674             {
1675                 int err;
1676                 StringBuilder err_name;
1677                 StringBuilder ret;
1678 
1679                 IntPtr sslCtx = unwrap_ssl(ssl);
1680                 if (sslCtx == IntPtr.Zero)
1681                 {
1682                     log(ERROR_LOG, "wolfssl get_error error");
1683                     return null;
1684                 }
1685 
1686                 /* wolfSSL max error length is 80 */
1687                 ret = new StringBuilder(' ', 100);
1688                 err = wolfSSL_get_error(sslCtx, 0);
1689                 err_name = new StringBuilder(new String(' ', 80));
1690                 wolfSSL_ERR_error_string((uint)err, err_name);
1691                 ret.Append("Error " + err + " " + err_name.ToString());
1692 
1693                 return ret.ToString();
1694             }
1695             catch (Exception e)
1696             {
1697                 log(ERROR_LOG, "wolfssl get error, error " + e.ToString());
1698                 return null;
1699             }
1700         }
1701 
1702 
1703         /// <summary>
1704         /// Used to load in the certificate file
1705         /// </summary>
1706         /// <param name="ctx">CTX structure for TLS/SSL connections</param>
1707         /// <param name="fileCert">Name of the file to load including absolute path</param>
1708         /// <param name="type">Type of file ie PEM or DER</param>
1709         /// <returns>1 on success</returns>
CTX_use_certificate_file(IntPtr ctx, string fileCert, int type)1710         public static int CTX_use_certificate_file(IntPtr ctx, string fileCert, int type)
1711         {
1712             try
1713             {
1714                 IntPtr local_ctx = unwrap_ctx(ctx);
1715                 if (local_ctx == IntPtr.Zero)
1716                 {
1717                     log(ERROR_LOG, "CTX use certificate file error");
1718                     return FAILURE;
1719                 }
1720 
1721                 return wolfSSL_CTX_use_certificate_file(local_ctx, fileCert, type);
1722             }
1723             catch (Exception e)
1724             {
1725                 log(ERROR_LOG, "wolfssl ctx use cert file error " + e.ToString());
1726                 return FAILURE;
1727             }
1728         }
1729 
1730 
1731         /// <summary>
1732         /// Used to load in the peer trusted root file
1733         /// </summary>
1734         /// <param name="ctx">CTX structure for TLS/SSL connections</param>
1735         /// <param name="fileCert">Name of the file to load including absolute path</param>
1736         /// <param name="type">path to multiple certificates (try to load all in path) </param>
1737         /// <returns>1 on success</returns>
CTX_load_verify_locations(IntPtr ctx, string fileCert, string path)1738         public static int CTX_load_verify_locations(IntPtr ctx, string fileCert, string path)
1739         {
1740             try
1741             {
1742                 IntPtr local_ctx = unwrap_ctx(ctx);
1743                 if (local_ctx == IntPtr.Zero)
1744                 {
1745                     log(ERROR_LOG, "CTX load verify locations certificate file error");
1746                     return FAILURE;
1747                 }
1748 
1749                 return wolfSSL_CTX_load_verify_locations(local_ctx, fileCert, path);
1750             }
1751             catch (Exception e)
1752             {
1753                 log(ERROR_LOG, "wolfssl ctx load verify locations file error " + e.ToString());
1754                 return FAILURE;
1755             }
1756         }
1757 
1758         /// <summary>
1759         /// Used to load in the private key from a file
1760         /// </summary>
1761         /// <param name="ctx">CTX structure for TLS/SSL connections </param>
1762         /// <param name="fileKey">Name of the file, includeing absolute directory</param>
1763         /// <param name="type">Type of file ie PEM or DER</param>
1764         /// <returns>1 on success</returns>
CTX_use_PrivateKey_file(IntPtr ctx, string fileKey, int type)1765         public static int CTX_use_PrivateKey_file(IntPtr ctx, string fileKey, int type)
1766         {
1767             try
1768             {
1769                 IntPtr local_ctx = unwrap_ctx(ctx);
1770                 if (local_ctx == IntPtr.Zero)
1771                 {
1772                     log(ERROR_LOG, "CTX use PrivateKey file error");
1773                     return FAILURE;
1774                 }
1775 
1776                 return wolfSSL_CTX_use_PrivateKey_file(local_ctx, fileKey, type);
1777             }
1778             catch (Exception e)
1779             {
1780                 log(ERROR_LOG, "wolfssl ctx use key file error " + e.ToString());
1781                 return FAILURE;
1782             }
1783         }
1784 
1785 
1786         /// <summary>
1787         /// Set temporary DH parameters
1788         /// </summary>
1789         /// <param name="ssl">Structure to set in</param>
1790         /// <param name="dhparam">file name</param>
1791         /// <param name="file_type">type of file ie PEM</param>
1792         /// <returns>1 on success</returns>
SetTmpDH_file(IntPtr ssl, StringBuilder dhparam, int file_type)1793         public static int SetTmpDH_file(IntPtr ssl, StringBuilder dhparam, int file_type)
1794         {
1795             try
1796             {
1797                 IntPtr sslCtx = unwrap_ssl(ssl);
1798                 if (sslCtx == IntPtr.Zero)
1799                 {
1800                     log(ERROR_LOG, "SetTmpDH_file ssl unwrap error");
1801                     return FAILURE;
1802                 }
1803 
1804                 return wolfSSL_SetTmpDH_file(sslCtx, dhparam, file_type);
1805             }
1806             catch (Exception e)
1807             {
1808                 log(ERROR_LOG, "SetTmpDH_file error " + e.ToString());
1809                 return FAILURE;
1810             }
1811         }
1812 
1813         /// <summary>
1814         /// Set temporary DH parameters
1815         /// </summary>
1816         /// <param name="ctx">Structure to set in</param>
1817         /// <param name="dhparam">file name</param>
1818         /// <param name="file_type">type of file ie PEM</param>
1819         /// <returns>1 on success</returns>
CTX_SetTmpDH_file(IntPtr ctx, StringBuilder dhparam, int file_type)1820         public static int CTX_SetTmpDH_file(IntPtr ctx, StringBuilder dhparam, int file_type)
1821         {
1822             try
1823             {
1824                 IntPtr local_ctx = unwrap_ctx(ctx);
1825                 if (local_ctx == IntPtr.Zero)
1826                 {
1827                     log(ERROR_LOG, "CTX_SetTmpDH_file ctx unwrap error");
1828                     return FAILURE;
1829                 }
1830 
1831                 return wolfSSL_CTX_SetTmpDH_file(local_ctx, dhparam, file_type);
1832             }
1833             catch (Exception e)
1834             {
1835                 log(ERROR_LOG, "CTX_SetTmpDH_file error " + e.ToString());
1836                 return FAILURE;
1837             }
1838         }
1839 
1840 
1841         /// <summary>
1842         /// Used to set the minimum size of DH key
1843         /// </summary>
1844         /// <param name="ctx">Structure to store key size</param>
1845         /// <param name="minDhKey">Min key size </param>
1846         /// <returns>1 on success</returns>
CTX_SetMinDhKey_Sz(IntPtr ctx, short minDhKey)1847         public static int CTX_SetMinDhKey_Sz(IntPtr ctx, short minDhKey)
1848         {
1849             try
1850             {
1851                 IntPtr local_ctx = unwrap_ctx(ctx);
1852                 if (local_ctx == IntPtr.Zero)
1853                 {
1854                     log(ERROR_LOG, "CTX SetMinDhKey_Sz error");
1855                     return FAILURE;
1856                 }
1857 
1858                 return wolfSSL_CTX_SetMinDhKey_Sz(local_ctx, minDhKey);
1859             }
1860             catch (Exception e)
1861             {
1862                 log(ERROR_LOG, "wolfssl ctx set min dh key error " + e.ToString());
1863                 return FAILURE;
1864             }
1865         }
1866 
1867         /// <summary>
1868         /// Set the certificate verification mode and optional callback function
1869         /// </summary>
1870         /// <param name="ctx">pointer to CTX that the function is set in</param>
1871         /// <param name="mode">See SSL_VERIFY options</param>
1872         /// <param name="vc">Optional verify callback function to use</param>
CTX_set_verify(IntPtr ctx, int mode, CallbackVerify_delegate vc)1873         public static int CTX_set_verify(IntPtr ctx, int mode, CallbackVerify_delegate vc)
1874         {
1875             try
1876             {
1877                 GCHandle   gch;
1878                 ctx_handle handles;
1879                 IntPtr     local_ctx = unwrap_ctx(ctx);
1880                 if (local_ctx == IntPtr.Zero)
1881                 {
1882                     log(ERROR_LOG, "CTX set_verify error");
1883                     return FAILURE;
1884                 }
1885 
1886                 /* pin the verify callback to protect from garbage collection */
1887                 if (!vc.Equals(null)) {
1888                     gch = GCHandle.FromIntPtr(ctx);
1889                     handles = (ctx_handle)gch.Target;
1890                     handles.set_vrf(GCHandle.Alloc(vc));
1891                 }
1892 
1893                 wolfSSL_CTX_set_verify(local_ctx, mode, vc);
1894                 return SUCCESS;
1895             }
1896             catch (Exception e)
1897             {
1898                 log(ERROR_LOG, "wolfssl ctx set verify error " + e.ToString());
1899                 return FAILURE;
1900             }
1901         }
1902 
1903         /// <summary>
1904         /// Set the certificate verification mode and optional callback function
1905         /// </summary>
1906         /// <param name="ctx">pointer to SSL object that the function is set in</param>
1907         /// <param name="mode">See SSL_VERIFY options</param>
1908         /// <param name="vc">Optional verify callback function to use</param>
set_verify(IntPtr ssl, int mode, CallbackVerify_delegate vc)1909         public static int set_verify(IntPtr ssl, int mode, CallbackVerify_delegate vc)
1910         {
1911             try
1912             {
1913                 GCHandle   gch;
1914                 ssl_handle handles;
1915                 IntPtr     local_ssl = unwrap_ssl(ssl);
1916                 if (local_ssl == IntPtr.Zero)
1917                 {
1918                     log(ERROR_LOG, "set_verify error");
1919                     return FAILURE;
1920                 }
1921 
1922                 /* pin the verify callback to protect from garbage collection */
1923                 if (!vc.Equals(null)) {
1924                     gch = GCHandle.FromIntPtr(ssl);
1925                     handles = (ssl_handle)gch.Target;
1926                     handles.set_vrf(GCHandle.Alloc(vc));
1927                 }
1928 
1929                 wolfSSL_set_verify(local_ssl, mode, vc);
1930                 return SUCCESS;
1931             }
1932             catch (Exception e)
1933             {
1934                 log(ERROR_LOG, "wolfssl set verify error " + e.ToString());
1935                 return FAILURE;
1936             }
1937         }
1938 
1939 
1940         /// <summary>
1941         /// Set the certificate verification mode and optional callback function
1942         /// </summary>
1943         /// <param name="ctx">pointer to SSL object that the function is set in</param>
1944         /// <param name="mode">See SSL_VERIFY options</param>
1945         /// <param name="vc">Optional verify callback function to use</param>
X509_STORE_CTX_get_current_cert(IntPtr x509Ctx)1946         public static X509 X509_STORE_CTX_get_current_cert(IntPtr x509Ctx)
1947         {
1948             X509 ret = null;
1949             try
1950             {
1951                 if (x509Ctx == IntPtr.Zero)
1952                 {
1953                     log(ERROR_LOG, "pointer passed in was not set");
1954                     return ret;
1955                 }
1956                 IntPtr x509 = wolfSSL_X509_STORE_CTX_get_current_cert(x509Ctx);
1957                 if (x509 != IntPtr.Zero) {
1958                     return new X509(x509, false);
1959                 }
1960                 return ret;
1961             }
1962             catch (Exception e)
1963             {
1964                 log(ERROR_LOG, "wolfssl WOLFSSL_X509_STORE_CTX error " + e.ToString());
1965                 return ret;
1966             }
1967         }
1968 
1969 
1970         /// <summary>
1971         /// Gets all of the certificates from store
1972         /// </summary>
1973         /// <param name="x509Ctx">pointer to store to get certificates from</param>
X509_STORE_CTX_get_certs(IntPtr x509Ctx)1974         public static X509[] X509_STORE_CTX_get_certs(IntPtr x509Ctx)
1975         {
1976             X509[] ret = null;
1977             try
1978             {
1979                 if (x509Ctx == IntPtr.Zero)
1980                 {
1981                     log(ERROR_LOG, "pointer passed in was not set");
1982                     return ret;
1983                 }
1984                 IntPtr sk = wolfSSL_X509_STORE_GetCerts(x509Ctx);
1985                 if (sk != IntPtr.Zero) {
1986                     int i;
1987                     int numCerts = wolfSSL_sk_X509_num(sk);
1988                     ret = new X509[numCerts];
1989 
1990                     for (i = 0; i < numCerts; i++) {
1991                         IntPtr current = wolfSSL_sk_X509_pop(sk);
1992                         if (current != IntPtr.Zero)
1993                         {
1994                             ret[i] = new X509(current, true);
1995                         }
1996                     }
1997                     wolfSSL_sk_X509_free(sk);
1998                 }
1999                 return ret;
2000 
2001             }
2002             catch (Exception e)
2003             {
2004                 log(ERROR_LOG, "wolfssl WOLFSSL_X509_STORE_CTX error " + e.ToString());
2005                 return ret;
2006             }
2007         }
2008 
2009 
2010         /// <summary>
2011         /// Get the current WOLFSSL_X509_STORE_CTX error value
2012         /// </summary>
2013         /// <param name="x509Ctx">pointer to store to get error from</param>
X509_STORE_CTX_get_error(IntPtr x509Ctx)2014         public static int X509_STORE_CTX_get_error(IntPtr x509Ctx)
2015         {
2016             try
2017             {
2018                 if (x509Ctx == IntPtr.Zero)
2019                 {
2020                     log(ERROR_LOG, "pointer passed in was not set");
2021                     return -1;
2022                 }
2023                 return wolfSSL_X509_STORE_CTX_get_error(x509Ctx);
2024             }
2025             catch (Exception e)
2026             {
2027                 log(ERROR_LOG, "wolfssl WOLFSSL_X509_STORE_CTX error " + e.ToString());
2028                 return -1;
2029             }
2030         }
2031 
2032         /// <summary>
2033         /// Print low level C library debug messages to stdout when compiled with macro DEBUG_WOLFSSL
2034         /// </summary>
Debugging_ON()2035         public static void Debugging_ON()
2036         {
2037             wolfSSL_Debugging_ON();
2038         }
2039 
2040         /// <summary>
2041         /// Turn off low level C debug messages
2042         /// </summary>
Debugging_OFF()2043         public static void Debugging_OFF()
2044         {
2045             wolfSSL_Debugging_OFF();
2046         }
2047 
2048         /// <summary>
2049         /// Set the function to use for logging
2050         /// </summary>
2051         /// <param name="input">Function that conforms as to loggingCb</param>
2052         /// <returns>1 on success</returns>
SetLogging(loggingCb input)2053         public static int SetLogging(loggingCb input)
2054         {
2055             internal_log = input;
2056             return SUCCESS;
2057         }
2058 
2059 
2060         /// <summary>
2061         /// Log a message to set logging function
2062         /// </summary>
2063         /// <param name="lvl">Level of log message</param>
2064         /// <param name="msg">Message to log</param>
log(int lvl, string msg)2065         public static void log(int lvl, string msg)
2066         {
2067             /* if log is not set then print nothing */
2068             if (internal_log == null)
2069                 return;
2070             StringBuilder ptr = new StringBuilder(msg);
2071             internal_log(lvl, ptr);
2072         }
2073     }
2074 }
2075