1
0

wolfssl.adb 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778
  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 "or" (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 or R);
  178. end "or";
  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 WolfSSL_Get_Verify(Context : Context_Type) return int with
  187. Convention => C,
  188. External_Name => "wolfSSL_CTX_get_verify_mode",
  189. Import => True;
  190. function Get_Verify (Context : Context_Type) return Mode_Type is
  191. begin
  192. return Mode_Type (WolfSSL_Get_Verify(Context));
  193. end Get_Verify;
  194. function Use_Certificate_File (Context : Context_Type;
  195. File : char_array;
  196. Format : int)
  197. return int with
  198. Convention => C,
  199. External_Name => "wolfSSL_CTX_use_certificate_file",
  200. Import => True;
  201. function Use_Certificate_File (Context : Context_Type;
  202. File : String;
  203. Format : File_Format)
  204. return Subprogram_Result is
  205. Ctx : constant Context_Type := Context;
  206. C : size_t;
  207. F : char_array (1 .. File'Length + 1);
  208. Result : int;
  209. begin
  210. Interfaces.C.To_C (Item => File,
  211. Target => F,
  212. Count => C,
  213. Append_Nul => True);
  214. Result := Use_Certificate_File (Ctx, F (1 .. C), int (Format));
  215. return Subprogram_Result (Result);
  216. end Use_Certificate_File;
  217. function Use_Certificate_Buffer (Context : Context_Type;
  218. Input : char_array;
  219. Size : long;
  220. Format : int)
  221. return int with
  222. Convention => C,
  223. External_Name => "wolfSSL_CTX_use_certificate_buffer",
  224. Import => True;
  225. function Use_Certificate_Buffer (Context : Context_Type;
  226. Input : char_array;
  227. Format : File_Format)
  228. return Subprogram_Result is
  229. Result : int;
  230. begin
  231. Result := Use_Certificate_Buffer (Context, Input,
  232. Input'Length, int (Format));
  233. return Subprogram_Result (Result);
  234. end Use_Certificate_Buffer;
  235. function Use_Private_Key_File (Context : Context_Type;
  236. File : char_array;
  237. Format : int)
  238. return int with
  239. Convention => C,
  240. External_Name => "wolfSSL_CTX_use_PrivateKey_file",
  241. Import => True;
  242. function Use_Private_Key_File (Context : Context_Type;
  243. File : String;
  244. Format : File_Format)
  245. return Subprogram_Result is
  246. Ctx : constant Context_Type := Context;
  247. C : size_t;
  248. F : char_array (1 .. File'Length + 1);
  249. Result : int;
  250. begin
  251. Interfaces.C.To_C (Item => File,
  252. Target => F,
  253. Count => C,
  254. Append_Nul => True);
  255. Result := Use_Private_Key_File (Ctx, F (1 .. C), int (Format));
  256. return Subprogram_Result (Result);
  257. end Use_Private_Key_File;
  258. function Use_Private_Key_Buffer (Context : Context_Type;
  259. Input : char_array;
  260. Size : long;
  261. Format : int)
  262. return int with
  263. Convention => C,
  264. External_Name => "wolfSSL_CTX_use_PrivateKey_buffer",
  265. Import => True;
  266. function Use_Private_Key_Buffer (Context : Context_Type;
  267. Input : Byte_Array;
  268. Format : File_Format)
  269. return Subprogram_Result is
  270. Result : int;
  271. begin
  272. Result := Use_Private_Key_Buffer (Context, Input,
  273. Input'Length, int (Format));
  274. return Subprogram_Result (Result);
  275. end Use_Private_Key_Buffer;
  276. function Load_Verify_Locations1
  277. (Context : Context_Type;
  278. File : char_array;
  279. Path : char_array) return int with
  280. Convention => C,
  281. External_Name => "wolfSSL_CTX_load_verify_locations",
  282. Import => True;
  283. -- This function loads PEM-formatted CA certificate files into
  284. -- the SSL context (WOLFSSL_CTX). These certificates will be treated
  285. -- as trusted root certificates and used to verify certs received
  286. -- from peers during the SSL handshake. The root certificate file,
  287. -- provided by the file argument, may be a single certificate or a
  288. -- file containing multiple certificates. If multiple CA certs are
  289. -- included in the same file, wolfSSL will load them in the same order
  290. -- they are presented in the file. The path argument is a pointer to
  291. -- the name of a directory that contains certificates of trusted
  292. -- root CAs. If the value of file is not NULL, path may be specified
  293. -- as NULL if not needed. If path is specified and NO_WOLFSSL_DIR was
  294. -- not defined when building the library, wolfSSL will load all
  295. -- CA certificates located in the given directory. This function will
  296. -- attempt to load all files in the directory. This function expects
  297. -- PEM formatted CERT_TYPE file with header "--BEGIN CERTIFICATE--".
  298. subtype char_array_ptr is Interfaces.C.Strings.char_array_access;
  299. function Load_Verify_Locations2
  300. (Context : Context_Type;
  301. File : char_array;
  302. Path : char_array_ptr) return int with
  303. Convention => C,
  304. External_Name => "wolfSSL_CTX_load_verify_locations",
  305. Import => True;
  306. function Load_Verify_Locations3
  307. (Context : Context_Type;
  308. File : char_array_ptr;
  309. Path : char_array) return int with
  310. Convention => C,
  311. External_Name => "wolfSSL_CTX_load_verify_locations",
  312. Import => True;
  313. function Load_Verify_Locations4
  314. (Context : Context_Type;
  315. File : char_array_ptr;
  316. Path : char_array_ptr) return int with
  317. Convention => C,
  318. External_Name => "wolfSSL_CTX_load_verify_locations",
  319. Import => True;
  320. function Load_Verify_Locations (Context : Context_Type;
  321. File : String;
  322. Path : String)
  323. return Subprogram_Result is
  324. Ctx : constant Context_Type := Context;
  325. FC : size_t; -- File Count, specifies the characters used in F.
  326. F : aliased char_array := (1 .. File'Length + 1 => '#');
  327. PC : size_t; -- Path Count, specifies the characters used in P.
  328. P : aliased char_array := (1 .. Path'Length + 1 => '#');
  329. Result : int;
  330. begin
  331. if File = "" then
  332. if Path = "" then
  333. Result := Load_Verify_Locations4 (Ctx, null, null);
  334. else
  335. Interfaces.C.To_C (Item => Path,
  336. Target => P,
  337. Count => PC,
  338. Append_Nul => True);
  339. Result := Load_Verify_Locations3 (Ctx, null, P);
  340. end if;
  341. else
  342. Interfaces.C.To_C (Item => File,
  343. Target => F,
  344. Count => FC,
  345. Append_Nul => True);
  346. if Path = "" then
  347. Result := Load_Verify_Locations2 (Ctx, F, null);
  348. else
  349. Interfaces.C.To_C (Item => Path,
  350. Target => P,
  351. Count => PC,
  352. Append_Nul => True);
  353. Interfaces.C.To_C (Item => Path,
  354. Target => P,
  355. Count => PC,
  356. Append_Nul => True);
  357. Result := Load_Verify_Locations1 (Context => Ctx,
  358. File => F,
  359. Path => P);
  360. end if;
  361. end if;
  362. return Subprogram_Result (Result);
  363. end Load_Verify_Locations;
  364. function Load_Verify_Buffer
  365. (Context : Context_Type;
  366. Input : char_array;
  367. Size : int;
  368. Format : int) return int with
  369. Convention => C,
  370. External_Name => "wolfSSL_CTX_load_verify_buffer",
  371. Import => True;
  372. function Load_Verify_Buffer (Context : Context_Type;
  373. Input : Byte_Array;
  374. Format : File_Format)
  375. return Subprogram_Result is
  376. Result : int;
  377. begin
  378. Result := Load_Verify_Buffer (Context => Context,
  379. Input => Input,
  380. Size => Input'Length,
  381. Format => int(Format));
  382. return Subprogram_Result (Result);
  383. end Load_Verify_Buffer;
  384. function Is_Valid (Ssl : WolfSSL_Type) return Boolean is
  385. begin
  386. return Ssl /= null;
  387. end Is_Valid;
  388. function WolfSSL_New (Context : Context_Type)
  389. return WolfSSL_Type with
  390. Convention => C,
  391. External_Name => "wolfSSL_new",
  392. Import => True;
  393. procedure Create_WolfSSL (Context : Context_Type;
  394. Ssl : out WolfSSL_Type) is
  395. begin
  396. Ssl := WolfSSL_New (Context);
  397. end Create_WolfSSL;
  398. function Use_Certificate_File (Ssl : WolfSSL_Type;
  399. File : char_array;
  400. Format : int)
  401. return int with
  402. Convention => C,
  403. External_Name => "wolfSSL_use_certificate_file",
  404. Import => True;
  405. function Use_Certificate_File (Ssl : WolfSSL_Type;
  406. File : String;
  407. Format : File_Format)
  408. return Subprogram_Result is
  409. C : size_t;
  410. F : char_array (1 .. File'Length + 1);
  411. Result : int;
  412. begin
  413. Interfaces.C.To_C (Item => File,
  414. Target => F,
  415. Count => C,
  416. Append_Nul => True);
  417. Result := Use_Certificate_File (Ssl, F (1 .. C), int (Format));
  418. return Subprogram_Result (Result);
  419. end Use_Certificate_File;
  420. function Use_Certificate_Buffer (Ssl : WolfSSL_Type;
  421. Input : char_array;
  422. Size : long;
  423. Format : int)
  424. return int with
  425. Convention => C,
  426. External_Name => "wolfSSL_use_certificate_buffer",
  427. Import => True;
  428. function Use_Certificate_Buffer (Ssl : WolfSSL_Type;
  429. Input : char_array;
  430. Format : File_Format)
  431. return Subprogram_Result is
  432. Result : int;
  433. begin
  434. Result := Use_Certificate_Buffer (Ssl, Input,
  435. Input'Length, int (Format));
  436. return Subprogram_Result (Result);
  437. end Use_Certificate_Buffer;
  438. function Use_Private_Key_File (Ssl : WolfSSL_Type;
  439. File : char_array;
  440. Format : int)
  441. return int with
  442. Convention => C,
  443. External_Name => "wolfSSL_use_PrivateKey_file",
  444. Import => True;
  445. function Use_Private_Key_File (Ssl : WolfSSL_Type;
  446. File : String;
  447. Format : File_Format)
  448. return Subprogram_Result is
  449. C : size_t;
  450. F : char_array (1 .. File'Length + 1);
  451. Result : int;
  452. begin
  453. Interfaces.C.To_C (Item => File,
  454. Target => F,
  455. Count => C,
  456. Append_Nul => True);
  457. Result := Use_Private_Key_File (Ssl, F (1 .. C), int (Format));
  458. return Subprogram_Result (Result);
  459. end Use_Private_Key_File;
  460. function Use_Private_Key_Buffer (Ssl : WolfSSL_Type;
  461. Input : char_array;
  462. Size : long;
  463. Format : int)
  464. return int with
  465. Convention => C,
  466. External_Name => "wolfSSL_use_PrivateKey_buffer",
  467. Import => True;
  468. function Use_Private_Key_Buffer (Ssl : WolfSSL_Type;
  469. Input : Byte_Array;
  470. Format : File_Format)
  471. return Subprogram_Result is
  472. Result : int;
  473. begin
  474. Result := Use_Private_Key_Buffer (Ssl, Input,
  475. Input'Length, int (Format));
  476. return Subprogram_Result (Result);
  477. end Use_Private_Key_Buffer;
  478. function WolfSSL_DTLS_Set_Peer
  479. (ssl : WolfSSL_Type;
  480. peer : GNAT.Sockets.Thin_Common.Sockaddr_Access;
  481. peerSz : Interfaces.C.unsigned)
  482. return int with
  483. Convention => C,
  484. External_Name => "wolfSSL_dtls_set_peer",
  485. Import => True;
  486. function DTLS_Set_Peer
  487. (Ssl : WolfSSL_Type;
  488. Address : GNAT.Sockets.Sock_Addr_Type)
  489. return Subprogram_Result is
  490. Sin : aliased GNAT.Sockets.Thin_Common.Sockaddr;
  491. Length : Interfaces.C.int;
  492. begin
  493. GNAT.Sockets.Thin_Common.Set_Address
  494. (Sin => Sin'Unchecked_Access,
  495. Address => Address,
  496. Length => Length);
  497. pragma Assert (Length >= 0);
  498. return
  499. Subprogram_Result
  500. (WolfSSL_DTLS_Set_Peer
  501. (ssl => Ssl,
  502. peer => Sin'Unchecked_Access,
  503. peerSz => Interfaces.C.unsigned (Length)));
  504. end DTLS_Set_Peer;
  505. function WolfSSL_Set_Fd (Ssl : WolfSSL_Type; Fd : int) return int with
  506. Convention => C,
  507. External_Name => "wolfSSL_set_fd",
  508. Import => True;
  509. function Attach (Ssl : WolfSSL_Type;
  510. Socket : Integer)
  511. return Subprogram_Result is
  512. Result : int := WolfSSL_Set_Fd (Ssl, int (Socket));
  513. begin
  514. return Subprogram_Result (Result);
  515. end Attach;
  516. procedure WolfSSL_Keep_Arrays (Ssl : WolfSSL_Type) with
  517. Convention => C,
  518. External_Name => "wolfSSL_KeepArrays",
  519. Import => True;
  520. procedure Keep_Arrays (Ssl : WolfSSL_Type) is
  521. begin
  522. WolfSSL_Keep_Arrays (Ssl);
  523. end Keep_Arrays;
  524. function WolfSSL_Accept (Ssl : WolfSSL_Type) return int with
  525. Convention => C,
  526. External_Name => "wolfSSL_accept",
  527. Import => True;
  528. function Accept_Connection (Ssl : WolfSSL_Type)
  529. return Subprogram_Result is
  530. Result : int := WolfSSL_Accept (Ssl);
  531. begin
  532. return Subprogram_Result (Result);
  533. end Accept_Connection;
  534. procedure WolfSSL_Free_Arrays (Ssl : WolfSSL_Type) with
  535. Convention => C,
  536. External_Name => "wolfSSL_FreeArrays",
  537. Import => True;
  538. procedure Free_Arrays (Ssl : WolfSSL_Type) is
  539. begin
  540. WolfSSL_Free_Arrays (Ssl);
  541. end Free_Arrays;
  542. function WolfSSL_Read (Ssl : WolfSSL_Type;
  543. Data : out char_array;
  544. Sz : int) return int with
  545. Convention => C,
  546. External_Name => "wolfSSL_read",
  547. Import => True;
  548. -- This function reads sz bytes from the SSL session (ssl) internal
  549. -- read buffer into the buffer data. The bytes read are removed from
  550. -- the internal receive buffer. If necessary wolfSSL_read() will
  551. -- negotiate an SSL/TLS session if the handshake has not already
  552. -- been performed yet by wolfSSL_connect() or wolfSSL_accept().
  553. -- The SSL/TLS protocol uses SSL records which have a maximum size
  554. -- of 16kB (the max record size can be controlled by the
  555. -- MAX_RECORD_SIZE define in /wolfssl/internal.h). As such, wolfSSL
  556. -- needs to read an entire SSL record internally before it is able
  557. -- to process and decrypt the record. Because of this, a call to
  558. -- wolfSSL_read() will only be able to return the maximum buffer
  559. -- size which has been decrypted at the time of calling. There may
  560. -- be additional not-yet-decrypted data waiting in the internal
  561. -- wolfSSL receive buffer which will be retrieved and decrypted with
  562. -- the next call to wolfSSL_read(). If sz is larger than the number
  563. -- of bytes in the internal read buffer, SSL_read() will return
  564. -- the bytes available in the internal read buffer. If no bytes are
  565. -- buffered in the internal read buffer yet, a call to wolfSSL_read()
  566. -- will trigger processing of the next record.
  567. --
  568. -- The integer returned is the number of bytes read upon success.
  569. -- 0 will be returned upon failure. This may be caused by a either
  570. -- a clean (close notify alert) shutdown or just that the peer closed
  571. -- the connection. Call wolfSSL_get_error() for the specific
  572. -- error code. SSL_FATAL_ERROR will be returned upon failure when
  573. -- either an error occurred or, when using non-blocking sockets,
  574. -- the SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE error was received
  575. -- and and the application needs to call wolfSSL_read() again.
  576. -- Use wolfSSL_get_error() to get a specific error code.
  577. function Read (Ssl : WolfSSL_Type) return Read_Result is
  578. Data : char_array (1 .. Byte_Index'Last);
  579. Size : int;
  580. begin
  581. Size := WolfSSL_Read (Ssl, Data, int (Byte_Index'Last));
  582. if Size <= 0 then
  583. return (Success => False,
  584. Last => 0,
  585. Code => Subprogram_Result (Size));
  586. else
  587. return (Success => True,
  588. Last => Byte_Index (Size),
  589. Buffer => Data (1 .. Byte_Index (Size)));
  590. end if;
  591. end Read;
  592. function WolfSSL_Write (Ssl : WolfSSL_Type;
  593. Data : char_array;
  594. Sz : int) return int with
  595. Convention => C,
  596. External_Name => "wolfSSL_write",
  597. Import => True;
  598. function Write (Ssl : WolfSSL_Type;
  599. Data : Byte_Array) return Write_Result is
  600. Size : constant int := Data'Length;
  601. Result : int;
  602. begin
  603. Result := WolfSSL_Write (Ssl, Data, Size);
  604. if Result > 0 then
  605. return (Success => True,
  606. Bytes_Written => Byte_Index (Result));
  607. else
  608. return (Success => False, Code => Subprogram_Result (Result));
  609. end if;
  610. end Write;
  611. function WolfSSL_Shutdown (Ssl : WolfSSL_Type) return int with
  612. Convention => C,
  613. External_Name => "wolfSSL_shutdown",
  614. Import => True;
  615. function Shutdown (Ssl : WolfSSL_Type) return Subprogram_Result is
  616. Result : constant int := WolfSSL_Shutdown (Ssl);
  617. begin
  618. return Subprogram_Result (Result);
  619. end Shutdown;
  620. function WolfSSL_Connect (Ssl : WolfSSL_Type) return int with
  621. Convention => C,
  622. External_Name => "wolfSSL_connect",
  623. Import => True;
  624. function Connect (Ssl : WolfSSL_Type) return Subprogram_Result is
  625. Result : constant int := WolfSSL_Connect (Ssl);
  626. begin
  627. return Subprogram_Result (Result);
  628. end Connect;
  629. procedure WolfSSL_Free (Ssl : WolfSSL_Type) with
  630. Convention => C,
  631. External_Name => "wolfSSL_free",
  632. Import => True;
  633. procedure Free (Ssl : in out WolfSSL_Type) is
  634. begin
  635. if Ssl /= null then
  636. WolfSSL_Free (Ssl);
  637. end if;
  638. Ssl := null;
  639. end Free;
  640. function WolfSSL_Get_Error (Ssl : WolfSSL_Type;
  641. Ret : int) return int with
  642. Convention => C,
  643. External_Name => "wolfSSL_get_error",
  644. Import => True;
  645. function Get_Error (Ssl : WolfSSL_Type;
  646. Result : Subprogram_Result) return Error_Code is
  647. begin
  648. return Error_Code (WolfSSL_Get_Error (Ssl, int (Result)));
  649. end Get_Error;
  650. procedure WolfSSL_Error_String (Error : unsigned_long;
  651. Data : out Byte_Array;
  652. Size : unsigned_long) with
  653. Convention => C,
  654. External_Name => "wolfSSL_ERR_error_string_n",
  655. Import => True;
  656. function Error (Code : Error_Code) return Error_Message is
  657. S : String (1 .. Error_Message_Index'Last);
  658. B : Byte_Array (1 .. size_t (Error_Message_Index'Last));
  659. C : Natural;
  660. begin
  661. WolfSSL_Error_String (Error => unsigned_long (Code),
  662. Data => B,
  663. Size => unsigned_long (B'Last));
  664. Interfaces.C.To_Ada (Item => B,
  665. Target => S,
  666. Count => C,
  667. Trim_Nul => True);
  668. return (Last => C,
  669. Text => S (1 .. C));
  670. end Error;
  671. function Get_WolfSSL_Max_Error_Size return int with
  672. Convention => C,
  673. External_Name => "get_wolfssl_max_error_size",
  674. Import => True;
  675. function Max_Error_Size return Natural is
  676. begin
  677. return Natural (Get_WolfSSL_Max_Error_Size);
  678. end Max_Error_Size;
  679. end WolfSSL;