Skip to content

Commit 11a40a6

Browse files
committed
Ada binding: add support for PSK client callback
Tested with: `wolfSSL/wolfssl-examples/psk/server-psk.c` after changing `DTLSv1_3_Client_Method` to `DTLSv1_2_Client_Method` to comply with the server example.
1 parent 239b85c commit 11a40a6

3 files changed

Lines changed: 154 additions & 43 deletions

File tree

wrapper/Ada/tls_client.adb

Lines changed: 110 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
with Ada.Characters.Handling;
2424
with Ada.Strings.Bounded;
2525
with Ada.Text_IO;
26-
with Interfaces.C;
26+
with Ada.Directories;
27+
with Interfaces.C.Strings;
2728

2829
with SPARK_Terminal;
2930

@@ -40,8 +41,62 @@ package body Tls_Client with SPARK_Mode is
4041

4142
subtype Byte_Type is WolfSSL.Byte_Type;
4243

44+
subtype chars_ptr is WolfSSL.chars_ptr;
45+
subtype unsigned is WolfSSL.unsigned;
46+
4347
package Natural_IO is new Ada.Text_IO.Integer_IO (Natural);
4448

49+
function PSK_Client_Callback
50+
(Unused : WolfSSL.WolfSSL_Type;
51+
Hint : chars_ptr;
52+
Identity : chars_ptr;
53+
Id_Max_Length : unsigned;
54+
Key : chars_ptr;
55+
Key_Max_Length : unsigned) return unsigned
56+
with Convention => C;
57+
58+
function PSK_Client_Callback
59+
(Unused : WolfSSL.WolfSSL_Type;
60+
Hint : chars_ptr;
61+
Identity : chars_ptr;
62+
Id_Max_Length : unsigned;
63+
Key : chars_ptr;
64+
Key_Max_Length : unsigned) return unsigned
65+
with
66+
SPARK_Mode => Off
67+
is
68+
use type Interfaces.C.unsigned;
69+
70+
Hint_String : constant String := Interfaces.C.Strings.Value (Hint);
71+
Identity_String : constant String := "Client_identity";
72+
Key_String : constant String :=
73+
Character'Val (26)
74+
& Character'Val (43)
75+
& Character'Val (60)
76+
& Character'Val (77);
77+
begin
78+
79+
Ada.Text_IO.Put_Line ("Hint: " & Hint_String);
80+
81+
pragma Assert (Id_Max_Length >= Identity_String'Length);
82+
83+
Interfaces.C.Strings.Update
84+
(Item => Identity,
85+
Offset => 0,
86+
Str => Identity_String,
87+
Check => False);
88+
89+
pragma Assert (Key_Max_Length >= Key_String'Length);
90+
91+
Interfaces.C.Strings.Update
92+
(Item => Key,
93+
Offset => 0,
94+
Str => Key_String,
95+
Check => False);
96+
97+
return Key_String'Length;
98+
end PSK_Client_Callback;
99+
45100
procedure Put (Text : String) is
46101
begin
47102
Ada.Text_IO.Put (Text);
@@ -221,49 +276,53 @@ package body Tls_Client with SPARK_Mode is
221276
(Context => Ctx,
222277
Mode => WolfSSL.Verify_Peer or WolfSSL.Verify_Fail_If_No_Peer_Cert);
223278

224-
-- Load client certificate into WOLFSSL_CTX.
225-
Result := WolfSSL.Use_Certificate_File (Context => Ctx,
226-
File => CERT_FILE,
227-
Format => WolfSSL.Format_Pem);
228-
if Result /= Success then
229-
Put ("ERROR: failed to load ");
230-
Put (CERT_FILE);
231-
Put (", please check the file.");
232-
New_Line;
233-
SPARK_Sockets.Close_Socket (C);
234-
WolfSSL.Free (Context => Ctx);
235-
Set (Exit_Status_Failure);
236-
return;
237-
end if;
279+
if Ada.Directories.Exists (CERT_FILE) and then
280+
Ada.Directories.Exists (KEY_FILE) then
238281

239-
-- Load client key into WOLFSSL_CTX.
240-
Result := WolfSSL.Use_Private_Key_File (Context => Ctx,
241-
File => KEY_FILE,
242-
Format => WolfSSL.Format_Pem);
243-
if Result /= Success then
244-
Put ("ERROR: failed to load ");
245-
Put (KEY_FILE);
246-
Put (", please check the file.");
247-
New_Line;
248-
SPARK_Sockets.Close_Socket (C);
249-
WolfSSL.Free (Context => Ctx);
250-
Set (Exit_Status_Failure);
251-
return;
252-
end if;
282+
-- Load client certificate into WOLFSSL_CTX.
283+
Result := WolfSSL.Use_Certificate_File (Context => Ctx,
284+
File => CERT_FILE,
285+
Format => WolfSSL.Format_Pem);
286+
if Result /= Success then
287+
Put ("ERROR: failed to load ");
288+
Put (CERT_FILE);
289+
Put (", please check the file.");
290+
New_Line;
291+
SPARK_Sockets.Close_Socket (C);
292+
WolfSSL.Free (Context => Ctx);
293+
Set (Exit_Status_Failure);
294+
return;
295+
end if;
253296

254-
-- Load CA certificate into WOLFSSL_CTX.
255-
Result := WolfSSL.Load_Verify_Locations (Context => Ctx,
256-
File => CA_FILE,
257-
Path => "");
258-
if Result /= Success then
259-
Put ("ERROR: failed to load ");
260-
Put (CA_FILE);
261-
Put (", please check the file.");
262-
New_Line;
263-
SPARK_Sockets.Close_Socket (C);
264-
WolfSSL.Free (Context => Ctx);
265-
Set (Exit_Status_Failure);
266-
return;
297+
-- Load client key into WOLFSSL_CTX.
298+
Result := WolfSSL.Use_Private_Key_File (Context => Ctx,
299+
File => KEY_FILE,
300+
Format => WolfSSL.Format_Pem);
301+
if Result /= Success then
302+
Put ("ERROR: failed to load ");
303+
Put (KEY_FILE);
304+
Put (", please check the file.");
305+
New_Line;
306+
SPARK_Sockets.Close_Socket (C);
307+
WolfSSL.Free (Context => Ctx);
308+
Set (Exit_Status_Failure);
309+
return;
310+
end if;
311+
312+
-- Load CA certificate into WOLFSSL_CTX.
313+
Result := WolfSSL.Load_Verify_Locations (Context => Ctx,
314+
File => CA_FILE,
315+
Path => "");
316+
if Result /= Success then
317+
Put ("ERROR: failed to load ");
318+
Put (CA_FILE);
319+
Put (", please check the file.");
320+
New_Line;
321+
SPARK_Sockets.Close_Socket (C);
322+
WolfSSL.Free (Context => Ctx);
323+
Set (Exit_Status_Failure);
324+
return;
325+
end if;
267326
end if;
268327

269328
-- Create a WOLFSSL object.
@@ -276,6 +335,15 @@ package body Tls_Client with SPARK_Mode is
276335
return;
277336
end if;
278337

338+
if not (Ada.Directories.Exists (CERT_FILE) and then
339+
Ada.Directories.Exists (KEY_FILE)) then
340+
341+
-- Use PSK for authentication.
342+
WolfSSL.Set_PSK_Client_Callback
343+
(Ssl => Ssl,
344+
Callback => PSK_Client_Callback'Access);
345+
end if;
346+
279347
if DTLS then
280348
Result := WolfSSL.DTLS_Set_Peer(Ssl => Ssl,
281349
Address => A);

wrapper/Ada/wolfssl.adb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,21 @@ package body WolfSSL is
577577

578578
end DTLS_Set_Peer;
579579

580+
procedure WolfSSL_Set_Psk_Client_Callback
581+
(Ssl : WolfSSL_Type;
582+
Cb : PSK_Client_Callback)
583+
with
584+
Convention => C,
585+
External_Name => "wolfSSL_set_psk_client_callback",
586+
Import => True;
587+
588+
procedure Set_PSK_Client_Callback
589+
(Ssl : WolfSSL_Type;
590+
Callback : PSK_Client_Callback) is
591+
begin
592+
WolfSSL_Set_Psk_Client_Callback (Ssl, Callback);
593+
end Set_PSK_Client_Callback;
594+
580595
function WolfSSL_Set_Fd (Ssl : WolfSSL_Type; Fd : int) return int with
581596
Convention => C,
582597
External_Name => "wolfSSL_set_fd",

wrapper/Ada/wolfssl.ads

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
--
2121

2222
with GNAT.Sockets;
23-
with Interfaces.C;
23+
with Interfaces.C.Strings;
2424

2525
-- This package is annotated "with SPARK_Mode" that SPARK can verify
2626
-- the API of this package is used correctly.
@@ -39,7 +39,10 @@ package WolfSSL with SPARK_Mode is
3939
-- Doesn't have to be called, though it will free any resources
4040
-- used by the library.
4141

42+
subtype unsigned is Interfaces.C.unsigned;
43+
4244
subtype char_array is Interfaces.C.char_array; -- Remove?
45+
subtype chars_ptr is Interfaces.C.Strings.chars_ptr;
4346

4447
subtype Byte_Type is Interfaces.C.char;
4548
subtype Byte_Index is Interfaces.C.size_t range 0 .. 16_000;
@@ -297,6 +300,31 @@ package WolfSSL with SPARK_Mode is
297300
-- This function wraps the corresponding WolfSSL C function to allow
298301
-- clients to use Ada socket types when implementing a DTLS client.
299302

303+
type PSK_Client_Callback is access function
304+
(Ssl : WolfSSL_Type;
305+
Hint : chars_ptr;
306+
Identity : chars_ptr;
307+
Id_Max_Length : unsigned;
308+
Key : chars_ptr;
309+
Key_Max_Length : unsigned)
310+
return unsigned with
311+
Convention => C;
312+
-- Return value is the key length on success or zero on error.
313+
-- parameters:
314+
-- Ssl - Pointer to the wolfSSL structure
315+
-- Hint - A stored string that could be displayed to provide a
316+
-- hint to the user.
317+
-- Identity - The ID will be stored here.
318+
-- Id_Max_Length - Size of the ID buffer.
319+
-- Key - The key will be stored here.
320+
-- Key_Max_Length - The max size of the key.
321+
322+
procedure Set_PSK_Client_Callback
323+
(Ssl : WolfSSL_Type;
324+
Callback : PSK_Client_Callback) with
325+
Pre => Is_Valid (Ssl);
326+
-- Sets the PSK client side callback.
327+
300328
function Attach (Ssl : WolfSSL_Type;
301329
Socket : Integer)
302330
return Subprogram_Result with

0 commit comments

Comments
 (0)