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