wolfSSL.cs 78 KB

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