wolfSSL.cs 79 KB

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