wolfssl.adb 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768
  1. -- wolfssl.adb
  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. pragma Warnings (Off, "* is an internal GNAT unit");
  22. with GNAT.Sockets.Thin_Common;
  23. pragma Warnings (On, "* is an internal GNAT unit");
  24. with Interfaces.C.Extensions;
  25. with Interfaces.C.Strings;
  26. with System;
  27. package body WolfSSL is
  28. subtype size_t is Interfaces.C.size_t; use type size_t;
  29. subtype long is Interfaces.C.long;
  30. subtype unsigned_long is Interfaces.C.unsigned_long;
  31. WOLFSSL_SUCCESS : constant int := Get_WolfSSL_Success;
  32. function Initialize_WolfSSL return int with
  33. Convention => C,
  34. External_Name => "wolfSSL_Init",
  35. Import => True;
  36. function Finalize_WolfSSL return int with
  37. Convention => C,
  38. External_Name => "wolfSSL_Cleanup",
  39. Import => True;
  40. function Initialize return Subprogram_Result is
  41. Result : constant int := Initialize_WolfSSL;
  42. begin
  43. return Subprogram_Result (Result);
  44. end Initialize;
  45. function Finalize return Subprogram_Result is
  46. Result : constant int := Finalize_WolfSSL;
  47. begin
  48. return Subprogram_Result (Result);
  49. end Finalize;
  50. function Is_Valid (Context : Context_Type) return Boolean is
  51. begin
  52. return Context /= null;
  53. end Is_Valid;
  54. function WolfTLSv1_2_Server_Method return Method_Type with
  55. Convention => C,
  56. External_Name => "wolfTLSv1_2_server_method",
  57. Import => True;
  58. function TLSv1_2_Server_Method return Method_Type is
  59. begin
  60. return WolfTLSv1_2_Server_Method;
  61. end TLSv1_2_Server_Method;
  62. function WolfTLSv1_2_Client_Method return Method_Type with
  63. Convention => C,
  64. External_Name => "wolfTLSv1_2_client_method",
  65. Import => True;
  66. function TLSv1_2_Client_Method return Method_Type is
  67. begin
  68. return WolfTLSv1_2_Client_Method;
  69. end TLSv1_2_Client_Method;
  70. function WolfTLSv1_3_Server_Method return Method_Type with
  71. Convention => C,
  72. External_Name => "wolfTLSv1_3_server_method",
  73. Import => True;
  74. function TLSv1_3_Server_Method return Method_Type is
  75. begin
  76. return WolfTLSv1_3_Server_Method;
  77. end TLSv1_3_Server_Method;
  78. function WolfTLSv1_3_Client_Method return Method_Type with
  79. Convention => C,
  80. External_Name => "wolfTLSv1_3_client_method",
  81. Import => True;
  82. function TLSv1_3_Client_Method return Method_Type is
  83. begin
  84. return WolfTLSv1_3_Client_Method;
  85. end TLSv1_3_Client_Method;
  86. function WolfDTLSv1_2_Server_Method return Method_Type with
  87. Convention => C,
  88. External_Name => "wolfDTLSv1_2_server_method",
  89. Import => True;
  90. function DTLSv1_2_Server_Method return Method_Type is
  91. begin
  92. return WolfDTLSv1_2_Server_Method;
  93. end DTLSv1_2_Server_Method;
  94. function WolfDTLSv1_2_Client_Method return Method_Type with
  95. Convention => C,
  96. External_Name => "wolfDTLSv1_2_client_method",
  97. Import => True;
  98. function DTLSv1_2_Client_Method return Method_Type is
  99. begin
  100. return WolfDTLSv1_2_Client_Method;
  101. end DTLSv1_2_Client_Method;
  102. function WolfDTLSv1_3_Server_Method return Method_Type with
  103. Convention => C,
  104. External_Name => "wolfDTLSv1_3_server_method",
  105. Import => True;
  106. function DTLSv1_3_Server_Method return Method_Type is
  107. begin
  108. return WolfDTLSv1_3_Server_Method;
  109. end DTLSv1_3_Server_Method;
  110. function WolfDTLSv1_3_Client_Method return Method_Type with
  111. Convention => C,
  112. External_Name => "wolfDTLSv1_3_client_method",
  113. Import => True;
  114. function DTLSv1_3_Client_Method return Method_Type is
  115. begin
  116. return WolfDTLSv1_3_Client_Method;
  117. end DTLSv1_3_Client_Method;
  118. function WolfSSL_CTX_new (Method : Method_Type)
  119. return Context_Type with
  120. Convention => C, External_Name => "wolfSSL_CTX_new", Import => True;
  121. procedure Create_Context (Method : Method_Type;
  122. Context : out Context_Type) is
  123. begin
  124. Context := WolfSSL_CTX_new (Method);
  125. end Create_Context;
  126. procedure WolfSSL_CTX_free (Context : Context_Type) with
  127. Convention => C, External_Name => "wolfSSL_CTX_free", Import => True;
  128. procedure Free (Context : in out Context_Type) is
  129. begin
  130. WolfSSL_CTX_free (Context);
  131. Context := null;
  132. end Free;
  133. type Opaque_X509_Store_Context is limited null record;
  134. type X509_Store_Context is access Opaque_X509_Store_Context with
  135. Convention => C;
  136. type Verify_Callback is access function
  137. (A : int;
  138. Context : X509_Store_Context)
  139. return int
  140. with Convention => C;
  141. procedure WolfSSL_CTX_Set_Verify (Context : Context_Type;
  142. Mode : int;
  143. Callback : Verify_Callback) with
  144. Convention => C,
  145. External_Name => "wolfSSL_CTX_set_verify",
  146. Import => True;
  147. -- This function sets the verification method for remote peers and
  148. -- also allows a verify callback to be registered with the SSL
  149. -- context. The verify callback will be called only when a
  150. -- verification failure has occurred. If no verify callback is
  151. -- desired, the NULL pointer can be used for verify_callback.
  152. -- The verification mode of peer certificates is a logically OR'd
  153. -- list of flags. The possible flag values include:
  154. -- SSL_VERIFY_NONE Client mode: the client will not verify the
  155. -- certificate received from the server and the handshake will
  156. -- continue as normal. Server mode: the server will not send a
  157. -- certificate request to the client. As such, client verification
  158. -- will not be enabled. SSL_VERIFY_PEER Client mode: the client will
  159. -- verify the certificate received from the server during the
  160. -- handshake. This is turned on by default in wolfSSL, therefore,
  161. -- using this option has no effect. Server mode: the server will send
  162. -- a certificate request to the client and verify the client
  163. -- certificate received. SSL_VERIFY_FAIL_IF_NO_PEER_CERT Client mode:
  164. -- no effect when used on the client side. Server mode:
  165. -- the verification will fail on the server side if the client fails
  166. -- to send a certificate when requested to do so (when using
  167. -- SSL_VERIFY_PEER on the SSL server).
  168. -- SSL_VERIFY_FAIL_EXCEPT_PSK Client mode: no effect when used on
  169. -- the client side. Server mode: the verification is the same as
  170. -- SSL_VERIFY_FAIL_IF_NO_PEER_CERT except in the case of a
  171. -- PSK connection. If a PSK connection is being made then the
  172. -- connection will go through without a peer cert.
  173. function "&" (Left, Right : Mode_Type) return Mode_Type is
  174. L : constant Unsigned_32 := Unsigned_32 (Left);
  175. R : constant Unsigned_32 := Unsigned_32 (Right);
  176. begin
  177. return Mode_Type (L and R);
  178. end "&";
  179. procedure Set_Verify (Context : Context_Type;
  180. Mode : Mode_Type) is
  181. begin
  182. WolfSSL_CTX_Set_Verify (Context => Context,
  183. Mode => int (Mode),
  184. Callback => null);
  185. end Set_Verify;
  186. function Use_Certificate_File (Context : Context_Type;
  187. File : char_array;
  188. Format : int)
  189. return int with
  190. Convention => C,
  191. External_Name => "wolfSSL_CTX_use_certificate_file",
  192. Import => True;
  193. function Use_Certificate_File (Context : Context_Type;
  194. File : String;
  195. Format : File_Format)
  196. return Subprogram_Result is
  197. Ctx : constant Context_Type := Context;
  198. C : size_t;
  199. F : char_array (1 .. File'Length + 1);
  200. Result : int;
  201. begin
  202. Interfaces.C.To_C (Item => File,
  203. Target => F,
  204. Count => C,
  205. Append_Nul => True);
  206. Result := Use_Certificate_File (Ctx, F (1 .. C), int (Format));
  207. return Subprogram_Result (Result);
  208. end Use_Certificate_File;
  209. function Use_Certificate_Buffer (Context : Context_Type;
  210. Input : char_array;
  211. Size : long;
  212. Format : int)
  213. return int with
  214. Convention => C,
  215. External_Name => "wolfSSL_CTX_use_certificate_buffer",
  216. Import => True;
  217. function Use_Certificate_Buffer (Context : Context_Type;
  218. Input : char_array;
  219. Format : File_Format)
  220. return Subprogram_Result is
  221. Result : int;
  222. begin
  223. Result := Use_Certificate_Buffer (Context, Input,
  224. Input'Length, int (Format));
  225. return Subprogram_Result (Result);
  226. end Use_Certificate_Buffer;
  227. function Use_Private_Key_File (Context : Context_Type;
  228. File : char_array;
  229. Format : int)
  230. return int with
  231. Convention => C,
  232. External_Name => "wolfSSL_CTX_use_PrivateKey_file",
  233. Import => True;
  234. function Use_Private_Key_File (Context : Context_Type;
  235. File : String;
  236. Format : File_Format)
  237. return Subprogram_Result is
  238. Ctx : constant Context_Type := Context;
  239. C : size_t;
  240. F : char_array (1 .. File'Length + 1);
  241. Result : int;
  242. begin
  243. Interfaces.C.To_C (Item => File,
  244. Target => F,
  245. Count => C,
  246. Append_Nul => True);
  247. Result := Use_Private_Key_File (Ctx, F (1 .. C), int (Format));
  248. return Subprogram_Result (Result);
  249. end Use_Private_Key_File;
  250. function Use_Private_Key_Buffer (Context : Context_Type;
  251. Input : char_array;
  252. Size : long;
  253. Format : int)
  254. return int with
  255. Convention => C,
  256. External_Name => "wolfSSL_CTX_use_PrivateKey_buffer",
  257. Import => True;
  258. function Use_Private_Key_Buffer (Context : Context_Type;
  259. Input : Byte_Array;
  260. Format : File_Format)
  261. return Subprogram_Result is
  262. Result : int;
  263. begin
  264. Result := Use_Private_Key_Buffer (Context, Input,
  265. Input'Length, int (Format));
  266. return Subprogram_Result (Result);
  267. end Use_Private_Key_Buffer;
  268. function Load_Verify_Locations1
  269. (Context : Context_Type;
  270. File : char_array;
  271. Path : char_array) return int with
  272. Convention => C,
  273. External_Name => "wolfSSL_CTX_load_verify_locations",
  274. Import => True;
  275. -- This function loads PEM-formatted CA certificate files into
  276. -- the SSL context (WOLFSSL_CTX). These certificates will be treated
  277. -- as trusted root certificates and used to verify certs received
  278. -- from peers during the SSL handshake. The root certificate file,
  279. -- provided by the file argument, may be a single certificate or a
  280. -- file containing multiple certificates. If multiple CA certs are
  281. -- included in the same file, wolfSSL will load them in the same order
  282. -- they are presented in the file. The path argument is a pointer to
  283. -- the name of a directory that contains certificates of trusted
  284. -- root CAs. If the value of file is not NULL, path may be specified
  285. -- as NULL if not needed. If path is specified and NO_WOLFSSL_DIR was
  286. -- not defined when building the library, wolfSSL will load all
  287. -- CA certificates located in the given directory. This function will
  288. -- attempt to load all files in the directory. This function expects
  289. -- PEM formatted CERT_TYPE file with header "--BEGIN CERTIFICATE--".
  290. subtype char_array_ptr is Interfaces.C.Strings.char_array_access;
  291. function Load_Verify_Locations2
  292. (Context : Context_Type;
  293. File : char_array;
  294. Path : char_array_ptr) return int with
  295. Convention => C,
  296. External_Name => "wolfSSL_CTX_load_verify_locations",
  297. Import => True;
  298. function Load_Verify_Locations3
  299. (Context : Context_Type;
  300. File : char_array_ptr;
  301. Path : char_array) return int with
  302. Convention => C,
  303. External_Name => "wolfSSL_CTX_load_verify_locations",
  304. Import => True;
  305. function Load_Verify_Locations4
  306. (Context : Context_Type;
  307. File : char_array_ptr;
  308. Path : char_array_ptr) return int with
  309. Convention => C,
  310. External_Name => "wolfSSL_CTX_load_verify_locations",
  311. Import => True;
  312. function Load_Verify_Locations (Context : Context_Type;
  313. File : String;
  314. Path : String)
  315. return Subprogram_Result is
  316. Ctx : constant Context_Type := Context;
  317. FC : size_t; -- File Count, specifies the characters used in F.
  318. F : aliased char_array := (1 .. File'Length + 1 => '#');
  319. PC : size_t; -- Path Count, specifies the characters used in P.
  320. P : aliased char_array := (1 .. Path'Length + 1 => '#');
  321. Result : int;
  322. begin
  323. if File = "" then
  324. if Path = "" then
  325. Result := Load_Verify_Locations4 (Ctx, null, null);
  326. else
  327. Interfaces.C.To_C (Item => Path,
  328. Target => P,
  329. Count => PC,
  330. Append_Nul => True);
  331. Result := Load_Verify_Locations3 (Ctx, null, P);
  332. end if;
  333. else
  334. Interfaces.C.To_C (Item => File,
  335. Target => F,
  336. Count => FC,
  337. Append_Nul => True);
  338. if Path = "" then
  339. Result := Load_Verify_Locations2 (Ctx, F, null);
  340. else
  341. Interfaces.C.To_C (Item => Path,
  342. Target => P,
  343. Count => PC,
  344. Append_Nul => True);
  345. Interfaces.C.To_C (Item => Path,
  346. Target => P,
  347. Count => PC,
  348. Append_Nul => True);
  349. Result := Load_Verify_Locations1 (Context => Ctx,
  350. File => F,
  351. Path => P);
  352. end if;
  353. end if;
  354. return Subprogram_Result (Result);
  355. end Load_Verify_Locations;
  356. function Load_Verify_Buffer
  357. (Context : Context_Type;
  358. Input : char_array;
  359. Size : int;
  360. Format : int) return int with
  361. Convention => C,
  362. External_Name => "wolfSSL_CTX_load_verify_buffer",
  363. Import => True;
  364. function Load_Verify_Buffer (Context : Context_Type;
  365. Input : Byte_Array;
  366. Format : File_Format)
  367. return Subprogram_Result is
  368. Result : int;
  369. begin
  370. Result := Load_Verify_Buffer (Context => Context,
  371. Input => Input,
  372. Size => Input'Length,
  373. Format => int(Format));
  374. return Subprogram_Result (Result);
  375. end Load_Verify_Buffer;
  376. function Is_Valid (Ssl : WolfSSL_Type) return Boolean is
  377. begin
  378. return Ssl /= null;
  379. end Is_Valid;
  380. function WolfSSL_New (Context : Context_Type)
  381. return WolfSSL_Type with
  382. Convention => C,
  383. External_Name => "wolfSSL_new",
  384. Import => True;
  385. procedure Create_WolfSSL (Context : Context_Type;
  386. Ssl : out WolfSSL_Type) is
  387. begin
  388. Ssl := WolfSSL_New (Context);
  389. end Create_WolfSSL;
  390. function Use_Certificate_File (Ssl : WolfSSL_Type;
  391. File : char_array;
  392. Format : int)
  393. return int with
  394. Convention => C,
  395. External_Name => "wolfSSL_use_certificate_file",
  396. Import => True;
  397. function Use_Certificate_File (Ssl : WolfSSL_Type;
  398. File : String;
  399. Format : File_Format)
  400. return Subprogram_Result is
  401. C : size_t;
  402. F : char_array (1 .. File'Length + 1);
  403. Result : int;
  404. begin
  405. Interfaces.C.To_C (Item => File,
  406. Target => F,
  407. Count => C,
  408. Append_Nul => True);
  409. Result := Use_Certificate_File (Ssl, F (1 .. C), int (Format));
  410. return Subprogram_Result (Result);
  411. end Use_Certificate_File;
  412. function Use_Certificate_Buffer (Ssl : WolfSSL_Type;
  413. Input : char_array;
  414. Size : long;
  415. Format : int)
  416. return int with
  417. Convention => C,
  418. External_Name => "wolfSSL_use_certificate_buffer",
  419. Import => True;
  420. function Use_Certificate_Buffer (Ssl : WolfSSL_Type;
  421. Input : char_array;
  422. Format : File_Format)
  423. return Subprogram_Result is
  424. Result : int;
  425. begin
  426. Result := Use_Certificate_Buffer (Ssl, Input,
  427. Input'Length, int (Format));
  428. return Subprogram_Result (Result);
  429. end Use_Certificate_Buffer;
  430. function Use_Private_Key_File (Ssl : WolfSSL_Type;
  431. File : char_array;
  432. Format : int)
  433. return int with
  434. Convention => C,
  435. External_Name => "wolfSSL_use_PrivateKey_file",
  436. Import => True;
  437. function Use_Private_Key_File (Ssl : WolfSSL_Type;
  438. File : String;
  439. Format : File_Format)
  440. return Subprogram_Result is
  441. C : size_t;
  442. F : char_array (1 .. File'Length + 1);
  443. Result : int;
  444. begin
  445. Interfaces.C.To_C (Item => File,
  446. Target => F,
  447. Count => C,
  448. Append_Nul => True);
  449. Result := Use_Private_Key_File (Ssl, F (1 .. C), int (Format));
  450. return Subprogram_Result (Result);
  451. end Use_Private_Key_File;
  452. function Use_Private_Key_Buffer (Ssl : WolfSSL_Type;
  453. Input : char_array;
  454. Size : long;
  455. Format : int)
  456. return int with
  457. Convention => C,
  458. External_Name => "wolfSSL_use_PrivateKey_buffer",
  459. Import => True;
  460. function Use_Private_Key_Buffer (Ssl : WolfSSL_Type;
  461. Input : Byte_Array;
  462. Format : File_Format)
  463. return Subprogram_Result is
  464. Result : int;
  465. begin
  466. Result := Use_Private_Key_Buffer (Ssl, Input,
  467. Input'Length, int (Format));
  468. return Subprogram_Result (Result);
  469. end Use_Private_Key_Buffer;
  470. function WolfSSL_DTLS_Set_Peer
  471. (ssl : WolfSSL_Type;
  472. peer : GNAT.Sockets.Thin_Common.Sockaddr_Access;
  473. peerSz : Interfaces.C.unsigned)
  474. return int with
  475. Convention => C,
  476. External_Name => "wolfSSL_dtls_set_peer",
  477. Import => True;
  478. function DTLS_Set_Peer
  479. (Ssl : WolfSSL_Type;
  480. Address : GNAT.Sockets.Sock_Addr_Type)
  481. return Subprogram_Result is
  482. Sin : aliased GNAT.Sockets.Thin_Common.Sockaddr;
  483. Length : Interfaces.C.int;
  484. begin
  485. GNAT.Sockets.Thin_Common.Set_Address
  486. (Sin => Sin'Unchecked_Access,
  487. Address => Address,
  488. Length => Length);
  489. pragma Assert (Length >= 0);
  490. return
  491. Subprogram_Result
  492. (WolfSSL_DTLS_Set_Peer
  493. (ssl => Ssl,
  494. peer => Sin'Unchecked_Access,
  495. peerSz => Interfaces.C.unsigned (Length)));
  496. end DTLS_Set_Peer;
  497. function WolfSSL_Set_Fd (Ssl : WolfSSL_Type; Fd : int) return int with
  498. Convention => C,
  499. External_Name => "wolfSSL_set_fd",
  500. Import => True;
  501. function Attach (Ssl : WolfSSL_Type;
  502. Socket : Integer)
  503. return Subprogram_Result is
  504. Result : int := WolfSSL_Set_Fd (Ssl, int (Socket));
  505. begin
  506. return Subprogram_Result (Result);
  507. end Attach;
  508. procedure WolfSSL_Keep_Arrays (Ssl : WolfSSL_Type) with
  509. Convention => C,
  510. External_Name => "wolfSSL_KeepArrays",
  511. Import => True;
  512. procedure Keep_Arrays (Ssl : WolfSSL_Type) is
  513. begin
  514. WolfSSL_Keep_Arrays (Ssl);
  515. end Keep_Arrays;
  516. function WolfSSL_Accept (Ssl : WolfSSL_Type) return int with
  517. Convention => C,
  518. External_Name => "wolfSSL_accept",
  519. Import => True;
  520. function Accept_Connection (Ssl : WolfSSL_Type)
  521. return Subprogram_Result is
  522. Result : int := WolfSSL_Accept (Ssl);
  523. begin
  524. return Subprogram_Result (Result);
  525. end Accept_Connection;
  526. procedure WolfSSL_Free_Arrays (Ssl : WolfSSL_Type) with
  527. Convention => C,
  528. External_Name => "wolfSSL_FreeArrays",
  529. Import => True;
  530. procedure Free_Arrays (Ssl : WolfSSL_Type) is
  531. begin
  532. WolfSSL_Free_Arrays (Ssl);
  533. end Free_Arrays;
  534. function WolfSSL_Read (Ssl : WolfSSL_Type;
  535. Data : out char_array;
  536. Sz : int) return int with
  537. Convention => C,
  538. External_Name => "wolfSSL_read",
  539. Import => True;
  540. -- This function reads sz bytes from the SSL session (ssl) internal
  541. -- read buffer into the buffer data. The bytes read are removed from
  542. -- the internal receive buffer. If necessary wolfSSL_read() will
  543. -- negotiate an SSL/TLS session if the handshake has not already
  544. -- been performed yet by wolfSSL_connect() or wolfSSL_accept().
  545. -- The SSL/TLS protocol uses SSL records which have a maximum size
  546. -- of 16kB (the max record size can be controlled by the
  547. -- MAX_RECORD_SIZE define in /wolfssl/internal.h). As such, wolfSSL
  548. -- needs to read an entire SSL record internally before it is able
  549. -- to process and decrypt the record. Because of this, a call to
  550. -- wolfSSL_read() will only be able to return the maximum buffer
  551. -- size which has been decrypted at the time of calling. There may
  552. -- be additional not-yet-decrypted data waiting in the internal
  553. -- wolfSSL receive buffer which will be retrieved and decrypted with
  554. -- the next call to wolfSSL_read(). If sz is larger than the number
  555. -- of bytes in the internal read buffer, SSL_read() will return
  556. -- the bytes available in the internal read buffer. If no bytes are
  557. -- buffered in the internal read buffer yet, a call to wolfSSL_read()
  558. -- will trigger processing of the next record.
  559. --
  560. -- The integer returned is the number of bytes read upon success.
  561. -- 0 will be returned upon failure. This may be caused by a either
  562. -- a clean (close notify alert) shutdown or just that the peer closed
  563. -- the connection. Call wolfSSL_get_error() for the specific
  564. -- error code. SSL_FATAL_ERROR will be returned upon failure when
  565. -- either an error occurred or, when using non-blocking sockets,
  566. -- the SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE error was received
  567. -- and and the application needs to call wolfSSL_read() again.
  568. -- Use wolfSSL_get_error() to get a specific error code.
  569. function Read (Ssl : WolfSSL_Type) return Read_Result is
  570. Data : char_array (1 .. Byte_Index'Last);
  571. Size : int;
  572. begin
  573. Size := WolfSSL_Read (Ssl, Data, int (Byte_Index'Last));
  574. if Size <= 0 then
  575. return (Success => False,
  576. Last => 0,
  577. Code => Subprogram_Result (Size));
  578. else
  579. return (Success => True,
  580. Last => Byte_Index (Size),
  581. Buffer => Data (1 .. Byte_Index (Size)));
  582. end if;
  583. end Read;
  584. function WolfSSL_Write (Ssl : WolfSSL_Type;
  585. Data : char_array;
  586. Sz : int) return int with
  587. Convention => C,
  588. External_Name => "wolfSSL_write",
  589. Import => True;
  590. function Write (Ssl : WolfSSL_Type;
  591. Data : Byte_Array) return Write_Result is
  592. Size : constant int := Data'Length;
  593. Result : int;
  594. begin
  595. Result := WolfSSL_Write (Ssl, Data, Size);
  596. if Result > 0 then
  597. return (Success => True,
  598. Bytes_Written => Byte_Index (Result));
  599. else
  600. return (Success => False, Code => Subprogram_Result (Result));
  601. end if;
  602. end Write;
  603. function WolfSSL_Shutdown (Ssl : WolfSSL_Type) return int with
  604. Convention => C,
  605. External_Name => "wolfSSL_shutdown",
  606. Import => True;
  607. function Shutdown (Ssl : WolfSSL_Type) return Subprogram_Result is
  608. Result : constant int := WolfSSL_Shutdown (Ssl);
  609. begin
  610. return Subprogram_Result (Result);
  611. end Shutdown;
  612. function WolfSSL_Connect (Ssl : WolfSSL_Type) return int with
  613. Convention => C,
  614. External_Name => "wolfSSL_connect",
  615. Import => True;
  616. function Connect (Ssl : WolfSSL_Type) return Subprogram_Result is
  617. Result : constant int := WolfSSL_Connect (Ssl);
  618. begin
  619. return Subprogram_Result (Result);
  620. end Connect;
  621. procedure WolfSSL_Free (Ssl : WolfSSL_Type) with
  622. Convention => C,
  623. External_Name => "wolfSSL_free",
  624. Import => True;
  625. procedure Free (Ssl : in out WolfSSL_Type) is
  626. begin
  627. if Ssl /= null then
  628. WolfSSL_Free (Ssl);
  629. end if;
  630. Ssl := null;
  631. end Free;
  632. function WolfSSL_Get_Error (Ssl : WolfSSL_Type;
  633. Ret : int) return int with
  634. Convention => C,
  635. External_Name => "wolfSSL_get_error",
  636. Import => True;
  637. function Get_Error (Ssl : WolfSSL_Type;
  638. Result : Subprogram_Result) return Error_Code is
  639. begin
  640. return Error_Code (WolfSSL_Get_Error (Ssl, int (Result)));
  641. end Get_Error;
  642. procedure WolfSSL_Error_String (Error : unsigned_long;
  643. Data : out Byte_Array;
  644. Size : unsigned_long) with
  645. Convention => C,
  646. External_Name => "wolfSSL_ERR_error_string_n",
  647. Import => True;
  648. function Error (Code : Error_Code) return Error_Message is
  649. S : String (1 .. Error_Message_Index'Last);
  650. B : Byte_Array (1 .. size_t (Error_Message_Index'Last));
  651. C : Natural;
  652. begin
  653. WolfSSL_Error_String (Error => unsigned_long (Code),
  654. Data => B,
  655. Size => unsigned_long (B'Last));
  656. Interfaces.C.To_Ada (Item => B,
  657. Target => S,
  658. Count => C,
  659. Trim_Nul => True);
  660. return (Last => C,
  661. Text => S (1 .. C));
  662. end Error;
  663. function Get_WolfSSL_Max_Error_Size return int with
  664. Convention => C,
  665. External_Name => "get_wolfssl_max_error_size",
  666. Import => True;
  667. function Max_Error_Size return Natural is
  668. begin
  669. return Natural (Get_WolfSSL_Max_Error_Size);
  670. end Max_Error_Size;
  671. end WolfSSL;