Extend Ada bindings

Add Ada bindings for SHA-256, RSA sign/verify, and AES-CBC from
wolfCrypt. Use XMALLOC/XFREE for dynamic allocation and add GNATprove
ownership annotations to enable static leak detection.

Refactor the Ada wrapper into a base package (wolfssl.ads) and a child
package (wolfssl-full_runtime) to separate code that depends on
Interfaces.C.Strings and GNAT.Sockets from zero-footprint-compatible
code.

Add standalone examples for SHA-256 hashing, RSA signature verification,
and AES encryption under wrapper/Ada/examples/.

Add AUnit test suites for SHA-256, RSA, and AES bindings under
wrapper/Ada/tests/ with Valgrind suppressions and Alire integration.

Move TLS client/server examples into wrapper/Ada/examples/src/ and
update build files (default.gpr, examples.gpr, include.am) accordingly.

Update CI (ada.yml) to build default.gpr, run AUnit tests, run the
client-server examples, and run GNATprove.

Co-authored-by: Joakim Strandberg <joakim@mequinox.se>
This commit is contained in:
Juliusz Sosinowicz
2025-11-20 22:50:40 +01:00
parent ca5b484e23
commit 40d3befa61
47 changed files with 3721 additions and 553 deletions

View File

@@ -8,3 +8,6 @@ end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.{ads,adb,gpr}]
indent_size = 3

View File

@@ -15,20 +15,59 @@ jobs:
steps:
- uses: actions/checkout@master
- name: Install gnat
- name: Install alire
uses: alire-project/setup-alire@v5
- name: Install wolfssl Ada
working-directory: ./wrapper/Ada
run: alr install
- name: Build default.gpr
working-directory: ./wrapper/Ada
run: alr exec -- gprbuild default.gpr -j$(nproc)
- name: Run Ada wrapper tests
working-directory: ./wrapper/Ada/tests
run: alr run
- name: Run Ada examples
id: examples
working-directory: ./wrapper/Ada/examples
run: |
alr build
echo "Running sha256_main example..."
alr run sha256_main
echo "Running aes_verify_main example..."
alr run aes_verify_main
echo "Running rsa_verify_main example..."
alr run rsa_verify_main
echo "Running TLS server/client example..."
alr run tls_server_main &> server.log &
SERVER_PID=$!
sleep 1
echo "test message" | alr run tls_client_main --args=127.0.0.1
kill $SERVER_PID || true
- name: show errors
if: ${{ failure() && steps.examples.outcome == 'failure' }}
run: cat ./wrapper/Ada/examples/server.log
- name: Run Ada wrapper tests (valgrind)
working-directory: ./wrapper/Ada/tests
run: |
sudo apt-get update
sudo apt-get install -y gnat gprbuild
sudo apt-get install -y valgrind
valgrind --leak-check=full --error-exitcode=1 \
--suppressions=valgrind.supp ./bin/tests
- name: Checkout wolfssl
uses: actions/checkout@master
with:
repository: wolfssl/wolfssl
path: wolfssl
- name: Run gnatprove on wolfssl
working-directory: ./wrapper/Ada
run: alr gnatprove --level=4 -P wolfssl.gpr -j 0 --warnings=error --checks-as-errors --proof-warnings -U
- name: Build wolfssl Ada
working-directory: ./wolfssl/wrapper/Ada
run: |
mkdir obj
gprbuild default.gpr
gprbuild examples.gpr
- name: Run gnatprove on examples
working-directory: ./wrapper/Ada/examples
run: alr gnatprove --level=4 -P examples.gpr -j 0 --warnings=error --checks-as-errors --proof-warnings -U

View File

@@ -1361,6 +1361,7 @@ enum {
DYNAMIC_TYPE_X509_ACERT = 103,
DYNAMIC_TYPE_OS_BUF = 104,
DYNAMIC_TYPE_ASCON = 105,
DYNAMIC_TYPE_SHA = 106,
DYNAMIC_TYPE_SNIFFER_SERVER = 1000,
DYNAMIC_TYPE_SNIFFER_SESSION = 1001,
DYNAMIC_TYPE_SNIFFER_PB = 1002,

View File

@@ -1 +1,4 @@
obj
/obj/
/bin/
/alire/
/config/

View File

@@ -28,9 +28,9 @@ been developed with maximum portability in mind.
Not only can the WolfSSL Ada binding be used in Ada applications but
also SPARK applications (a subset of the Ada language suitable for
formal verification). To formally verify the Ada code in this repository
open the examples.gpr with GNAT Studio and then select
open the examples/examples.gpr with GNAT Studio and then select
SPARK -> Prove All Sources and use Proof Level 2. Or when using the command
line, use `gnatprove -Pexamples.gpr --level=4 -j12` (`-j12` is there in
line, use `gnatprove -Pexamples/examples.gpr --level=4 -j12` (`-j12` is there in
order to instruct the prover to use 12 CPUs if available).
```
@@ -62,6 +62,8 @@ ecosystem. The latest version is available for Windows, OSX, Linux and FreeBSD
systems. It can install a complete Ada toolchain if needed, see `alr install`
for more information.
**Note:** If you encounter a missing dependency error, it may be caused by the installed dependency being too old. In this case, either install a newer toolchain or decrease the required dependency version in your project.
In order to use WolfSSL in a project, just add WolfSSL as a dependency by
running `alr with wolfssl` within your project's directory.
@@ -84,6 +86,8 @@ and use gprbuild to build the source code.
cd wrapper/Ada
gprclean
gprbuild default.gpr
cd examples
gprbuild examples.gpr
cd obj/
@@ -91,21 +95,39 @@ cd obj/
./tls_client_main 127.0.0.1
```
If you are using Alire, you can build the library and examples with:
```sh
cd wrapper/Ada
alr install
cd examples
alr build
```
You can also run the examples directly with Alire:
```sh
cd wrapper/Ada/examples
alr run tls_server_main &
alr run tls_client_main --args=127.0.0.1
```
On Windows, build the executables with:
```sh
gprbuild -XOS=Windows default.gpr
cd wrapper/Ada/examples
gprbuild -XOS=Windows examples.gpr
```
## Files
The (D)TLS v1.3 client example in the Ada/SPARK programming language
using the WolfSSL library can be found in the files:
tls_client_main.adb
tls_client.ads
tls_client.adb
examples/src/tls_client_main.adb
examples/src/tls_client.ads
examples/src/tls_client.adb
The (D)TLS v1.3 server example in the Ada/SPARK programming language
using the WolfSSL library can be found in the files:
tls_server_main.adb
tls_server.ads
tls_server.adb
examples/src/tls_server_main.adb
examples/src/tls_server.ads
examples/src/tls_server.adb

View File

@@ -26,7 +26,15 @@
/* wolfSSL */
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/ssl.h>
#include <wolfssl/wolfcrypt/rsa.h>
#include <wolfssl/wolfcrypt/sha256.h>
#include <wolfssl/wolfcrypt/aes.h>
#include <stdlib.h>
/* RSA instances are now dynamically allocated (no fixed pool). */
/* SHA256 instances are now dynamically allocated (no fixed pool). */
/* AES instances are now dynamically allocated (no fixed pool). */
/* These functions give access to the integer values of the enumeration
constants used in WolfSSL. These functions make it possible
for the WolfSSL implementation to change the values of the constants
@@ -48,6 +56,31 @@ extern int get_wolfssl_filetype_asn1(void);
extern int get_wolfssl_filetype_pem(void);
extern int get_wolfssl_filetype_default(void);
extern void* ada_new_rsa (void);
extern void ada_free_rsa (void* key);
extern void *ada_new_sha256 (void);
extern void ada_free_sha256 (void* sha256);
extern void* ada_new_aes (int devId);
extern void ada_free_aes (void* aes);
extern void* ada_new_rng (void);
extern void ada_free_rng (void* rng);
extern int ada_RsaSetRNG (RsaKey* key, WC_RNG* rng);
extern int get_wolfssl_invalid_devid (void);
extern int ada_md5 (void);
extern int ada_sha (void);
extern int ada_sha256 (void);
extern int ada_sha384 (void);
extern int ada_sha512 (void);
extern int ada_sha3_224 (void);
extern int ada_sha3_256 (void);
extern int ada_sha3_384 (void);
extern int ada_sha3_512 (void);
extern int get_wolfssl_error_want_read(void) {
return WOLFSSL_ERROR_WANT_READ;
}
@@ -107,3 +140,111 @@ extern int get_wolfssl_filetype_pem(void) {
extern int get_wolfssl_filetype_default(void) {
return WOLFSSL_FILETYPE_DEFAULT;
}
extern void* ada_new_rsa (void)
{
/* Allocate and initialize an RSA key using wolfCrypt's constructor. */
return (void*)wc_NewRsaKey(NULL, INVALID_DEVID, NULL);
}
extern void ada_free_rsa (void* key)
{
/* Delete RSA key and release its memory. */
wc_DeleteRsaKey((RsaKey*)key, NULL);
}
extern void* ada_new_sha256 (void)
{
return XMALLOC(sizeof(wc_Sha256), NULL, DYNAMIC_TYPE_SHA);
}
extern void ada_free_sha256 (void* sha256)
{
XFREE(sha256, NULL, DYNAMIC_TYPE_SHA);
}
extern void* ada_new_aes (int devId)
{
/* Allocate and initialize an AES object using wolfCrypt's constructor. */
return (void*)wc_AesNew(NULL, devId, NULL);
}
extern void ada_free_aes (void* aes)
{
/* Delete AES object and release its memory. */
wc_AesDelete((Aes*)aes, NULL);
}
extern int get_wolfssl_invalid_devid (void)
{
return INVALID_DEVID;
}
extern void* ada_new_rng (void)
{
/* Allocate and initialize a WC_RNG using wolfCrypt's allocator.
* Per request: pass NULL and 0 to wc_rng_new (nonce, nonceSz).
*/
return (void*)wc_rng_new(NULL, 0, NULL);
}
extern void ada_free_rng (void* rng)
{
wc_rng_free((WC_RNG*)rng);
}
extern int ada_RsaSetRNG(RsaKey* key, WC_RNG* rng)
{
int r = 0;
#ifdef WC_RSA_BLINDING /* HIGHLY RECOMMENDED! */
r = wc_RsaSetRNG(key, rng);
#endif
return r;
}
extern int ada_md5 (void)
{
return WC_MD5;
}
extern int ada_sha (void)
{
return WC_SHA;
}
extern int ada_sha256 (void)
{
return WC_SHA256;
}
extern int ada_sha384 (void)
{
return WC_SHA384;
}
extern int ada_sha512 (void)
{
return WC_SHA512;
}
extern int ada_sha3_224 (void)
{
return WC_SHA3_224;
}
extern int ada_sha3_256 (void)
{
return WC_SHA3_256;
}
extern int ada_sha3_384 (void)
{
return WC_SHA3_384;
}
extern int ada_sha3_512 (void)
{
return WC_SHA3_512;
}

View File

@@ -12,3 +12,6 @@ tags = ["ssl", "tls", "embedded", "spark"]
[configuration.variables]
STATIC_PSK = {type = "Boolean", default = false}
[[depends-on]]
gnatprove = "^13.2.1"

View File

@@ -11,17 +11,6 @@ project Default is
"../../src",
"../../wolfcrypt/src");
-- Don't build the tls application examples because they make use
-- of the Secondary Stack due to usage of the Ada.Command_Line
-- package. All other Ada source code does not use the secondary stack.
for Excluded_Source_Files use
("tls_client_main.adb",
"tls_client.ads",
"tls_client.adb",
"tls_server_main.adb",
"tls_server.ads",
"tls_server.adb");
for Object_Dir use "obj";
package Naming is

View File

@@ -1,78 +0,0 @@
project Examples is
type OS_Kind is ("Windows", "Linux_Or_Mac");
OS : OS_Kind := external ("OS", "Linux_Or_Mac");
for Languages use ("C", "Ada");
for Source_Dirs use (".",
"../../",
"../../src",
"../../wolfcrypt/src");
for Object_Dir use "obj";
for Main use ("tls_server_main.adb", "tls_client_main.adb");
package Naming is
for Spec_Suffix ("C") use ".h";
end Naming;
package Compiler is
for Switches ("C") use
("-DWOLFSSL_USER_SETTINGS", -- Use the user_settings.h file.
"-Wno-pragmas",
"-Wall",
"-Wextra",
"-Wunknown-pragmas",
"--param=ssp-buffer-size=1",
"-Waddress",
"-Warray-bounds",
"-Wbad-function-cast",
"-Wchar-subscripts",
"-Wcomment",
"-Wfloat-equal",
"-Wformat-security",
"-Wformat=2",
"-Wmaybe-uninitialized",
"-Wmissing-field-initializers",
"-Wmissing-noreturn",
"-Wmissing-prototypes",
"-Wnested-externs",
"-Wnormalized=id",
"-Woverride-init",
"-Wpointer-arith",
"-Wpointer-sign",
"-Wshadow",
"-Wsign-compare",
"-Wstrict-overflow=1",
"-Wstrict-prototypes",
"-Wswitch-enum",
"-Wundef",
"-Wunused",
"-Wunused-result",
"-Wunused-variable",
"-Wwrite-strings",
"-fwrapv");
for Switches ("Ada") use ("-g");
end Compiler;
package Linker is
case OS is
when "Windows" =>
for Switches ("Ada") use
("-lm", -- To include the math library (used by WolfSSL).
"-lcrypt32"); -- Needed on Windows.
when "Linux_Or_Mac" =>
for Switches ("Ada") use
("-lm"); -- To include the math library (used by WolfSSL).
end case;
end Linker;
package Binder is
for Switches ("Ada") use ("-Es"); -- To include stack traces.
end Binder;
end Examples;

4
wrapper/Ada/examples/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
/obj/
/bin/
/alire/
/config/

View File

@@ -0,0 +1,21 @@
name = "examples"
description = "Examples using the wolfSSL Ada bindings"
version = "0.1.0-dev"
authors = ["Juliusz Sosinowicz"]
maintainers = ["Juliusz Sosinowicz <juliusz@wolfssl.com>"]
maintainers-logins = ["julek-wolfssl"]
licenses = "GPL-3.0-or-later"
website = "https://www.wolfssl.com/"
tags = []
executables = [
"aes_verify_main",
"rsa_verify_main",
"sha256_main",
"tls_client_main",
"tls_server_main"
]
[[depends-on]]
gnatprove = "^13.2.1"

View File

@@ -0,0 +1,46 @@
with "config/examples_config.gpr";
with "../wolfssl.gpr";
project Examples is
type OS_Kind is ("Windows", "Linux_Or_Mac");
OS : OS_Kind := external ("OS", "Linux_Or_Mac");
for Languages use ("Ada");
for Source_Dirs use ("src");
for Object_Dir use "obj";
for Main use ("tls_server_main.adb",
"tls_client_main.adb",
"sha256_main.adb",
"rsa_verify_main.adb",
"aes_verify_main.adb");
package Naming is
for Spec_Suffix ("C") use ".h";
end Naming;
package Compiler is
for Switches ("Ada") use ("-g");
end Compiler;
package Linker is
case OS is
when "Windows" =>
for Switches ("Ada") use
("-lm", -- To include the math library (used by WolfSSL).
"-lcrypt32"); -- Needed on Windows.
when "Linux_Or_Mac" =>
for Switches ("Ada") use
("-lm"); -- To include the math library (used by WolfSSL).
end case;
end Linker;
package Binder is
for Switches ("Ada") use ("-Es"); -- To include stack traces.
end Binder;
end Examples;

View File

@@ -0,0 +1,103 @@
with Ada.Text_IO;
with Ada.Integer_Text_IO;
with WolfSSL;
procedure AES_Verify_Main is
use type WolfSSL.Byte_Type;
procedure Put (Text : String) renames Ada.Text_IO.Put;
procedure Put (Value : Integer) is
begin
Ada.Integer_Text_IO.Put (Value);
end Put;
procedure New_Line is
begin
Ada.Text_IO.New_Line;
end New_Line;
type Unsigned_8 is mod 2 ** 8;
function To_C (Value : Unsigned_8) return WolfSSL.Byte_Type is
begin
return WolfSSL.Byte_Type'Val (Value);
end To_C;
RNG : WolfSSL.RNG_Type;
Salt_Size : constant := 8;
Salt : WolfSSL.Byte_Array (1 .. 8);
AES : WolfSSL.AES_Type;
R : Integer;
Pad : Integer := 3;
procedure Cleanup is
RR : Integer := 0;
begin
if WolfSSL.Is_Valid (AES) then
WolfSSL.AES_Free (AES => AES,
Result => RR);
end if;
if WolfSSL.Is_Valid (RNG) then
WolfSSL.Free_RNG (Key => RNG);
end if;
end Cleanup;
begin
WolfSSL.Create_RNG (Key => RNG,
Result => R);
if R /= 0 then
Put ("Attaining RNG key instance failed");
New_Line;
Cleanup;
return;
end if;
WolfSSL.RNG_Generate_Block (RNG => RNG,
Output => Salt,
Result => R);
if R /= 0 then
Put ("Generating random salt");
New_Line;
Cleanup;
return;
end if;
if Pad = 0 then
Salt (1) := To_C (0);
elsif Salt (1) = To_C (0) then
Salt (1) := To_C (1);
end if;
-- Create_AES signature no longer requires Index when AES objects are
-- dynamically allocated.
WolfSSL.Create_AES (Device => WolfSSL.Invalid_Device,
AES => AES,
Result => R);
if R /= 0 then
Put ("Attaining AES key instance failed");
New_Line;
Cleanup;
return;
end if;
-- WolfSSL.PBKDF2 (Output => ,
-- Password => ,
-- Salt => ,
-- Iterations => ,
-- Key_Length => ,
-- HMAC => ,
-- Result => R);
-- if R /= 0 then
-- Put ("Attaining AES key instance failed");
-- New_Line;
-- Cleanup;
-- return;
-- end if;
Cleanup;
end AES_Verify_Main;

View File

@@ -0,0 +1,518 @@
with Ada.Integer_Text_IO;
with Ada.Text_IO;
with WolfSSL;
-- If this example executes successfully the output is:
--
-- Successful verification of RSA based digital signature.
-- Successfully encrypted and decrypted using RSA.
procedure Rsa_Verify_Main is
use type WolfSSL.Byte_Array;
type Unsigned_8 is mod 2 ** 8;
function To_C (Value : Unsigned_8) return WolfSSL.Byte_Type is
begin
return WolfSSL.Byte_Type'Val (Value);
end To_C;
-- RSA public key to verify with.
Rsa_Public_key_2048 : constant WolfSSL.Byte_Array :=
(To_C (16#30#), To_C (16#82#), To_C (16#01#), To_C (16#22#), To_C (16#30#),
To_C (16#0D#), To_C (16#06#), To_C (16#09#), To_C (16#2A#), To_C (16#86#),
To_C (16#48#), To_C (16#86#), To_C (16#F7#), To_C (16#0D#), To_C (16#01#),
To_C (16#01#), To_C (16#01#), To_C (16#05#), To_C (16#00#), To_C (16#03#),
To_C (16#82#), To_C (16#01#), To_C (16#0F#), To_C (16#00#), To_C (16#30#),
To_C (16#82#), To_C (16#01#), To_C (16#0A#), To_C (16#02#), To_C (16#82#),
To_C (16#01#), To_C (16#01#), To_C (16#00#), To_C (16#C3#), To_C (16#03#),
To_C (16#D1#), To_C (16#2B#), To_C (16#FE#), To_C (16#39#), To_C (16#A4#),
To_C (16#32#), To_C (16#45#), To_C (16#3B#), To_C (16#53#), To_C (16#C8#),
To_C (16#84#), To_C (16#2B#), To_C (16#2A#), To_C (16#7C#), To_C (16#74#),
To_C (16#9A#), To_C (16#BD#), To_C (16#AA#), To_C (16#2A#), To_C (16#52#),
To_C (16#07#), To_C (16#47#), To_C (16#D6#), To_C (16#A6#), To_C (16#36#),
To_C (16#B2#), To_C (16#07#), To_C (16#32#), To_C (16#8E#), To_C (16#D0#),
To_C (16#BA#), To_C (16#69#), To_C (16#7B#), To_C (16#C6#), To_C (16#C3#),
To_C (16#44#), To_C (16#9E#), To_C (16#D4#), To_C (16#81#), To_C (16#48#),
To_C (16#FD#), To_C (16#2D#), To_C (16#68#), To_C (16#A2#), To_C (16#8B#),
To_C (16#67#), To_C (16#BB#), To_C (16#A1#), To_C (16#75#), To_C (16#C8#),
To_C (16#36#), To_C (16#2C#), To_C (16#4A#), To_C (16#D2#), To_C (16#1B#),
To_C (16#F7#), To_C (16#8B#), To_C (16#BA#), To_C (16#CF#), To_C (16#0D#),
To_C (16#F9#), To_C (16#EF#), To_C (16#EC#), To_C (16#F1#), To_C (16#81#),
To_C (16#1E#), To_C (16#7B#), To_C (16#9B#), To_C (16#03#), To_C (16#47#),
To_C (16#9A#), To_C (16#BF#), To_C (16#65#), To_C (16#CC#), To_C (16#7F#),
To_C (16#65#), To_C (16#24#), To_C (16#69#), To_C (16#A6#), To_C (16#E8#),
To_C (16#14#), To_C (16#89#), To_C (16#5B#), To_C (16#E4#), To_C (16#34#),
To_C (16#F7#), To_C (16#C5#), To_C (16#B0#), To_C (16#14#), To_C (16#93#),
To_C (16#F5#), To_C (16#67#), To_C (16#7B#), To_C (16#3A#), To_C (16#7A#),
To_C (16#78#), To_C (16#E1#), To_C (16#01#), To_C (16#56#), To_C (16#56#),
To_C (16#91#), To_C (16#A6#), To_C (16#13#), To_C (16#42#), To_C (16#8D#),
To_C (16#D2#), To_C (16#3C#), To_C (16#40#), To_C (16#9C#), To_C (16#4C#),
To_C (16#EF#), To_C (16#D1#), To_C (16#86#), To_C (16#DF#), To_C (16#37#),
To_C (16#51#), To_C (16#1B#), To_C (16#0C#), To_C (16#A1#), To_C (16#3B#),
To_C (16#F5#), To_C (16#F1#), To_C (16#A3#), To_C (16#4A#), To_C (16#35#),
To_C (16#E4#), To_C (16#E1#), To_C (16#CE#), To_C (16#96#), To_C (16#DF#),
To_C (16#1B#), To_C (16#7E#), To_C (16#BF#), To_C (16#4E#), To_C (16#97#),
To_C (16#D0#), To_C (16#10#), To_C (16#E8#), To_C (16#A8#), To_C (16#08#),
To_C (16#30#), To_C (16#81#), To_C (16#AF#), To_C (16#20#), To_C (16#0B#),
To_C (16#43#), To_C (16#14#), To_C (16#C5#), To_C (16#74#), To_C (16#67#),
To_C (16#B4#), To_C (16#32#), To_C (16#82#), To_C (16#6F#), To_C (16#8D#),
To_C (16#86#), To_C (16#C2#), To_C (16#88#), To_C (16#40#), To_C (16#99#),
To_C (16#36#), To_C (16#83#), To_C (16#BA#), To_C (16#1E#), To_C (16#40#),
To_C (16#72#), To_C (16#22#), To_C (16#17#), To_C (16#D7#), To_C (16#52#),
To_C (16#65#), To_C (16#24#), To_C (16#73#), To_C (16#B0#), To_C (16#CE#),
To_C (16#EF#), To_C (16#19#), To_C (16#CD#), To_C (16#AE#), To_C (16#FF#),
To_C (16#78#), To_C (16#6C#), To_C (16#7B#), To_C (16#C0#), To_C (16#12#),
To_C (16#03#), To_C (16#D4#), To_C (16#4E#), To_C (16#72#), To_C (16#0D#),
To_C (16#50#), To_C (16#6D#), To_C (16#3B#), To_C (16#A3#), To_C (16#3B#),
To_C (16#A3#), To_C (16#99#), To_C (16#5E#), To_C (16#9D#), To_C (16#C8#),
To_C (16#D9#), To_C (16#0C#), To_C (16#85#), To_C (16#B3#), To_C (16#D9#),
To_C (16#8A#), To_C (16#D9#), To_C (16#54#), To_C (16#26#), To_C (16#DB#),
To_C (16#6D#), To_C (16#FA#), To_C (16#AC#), To_C (16#BB#), To_C (16#FF#),
To_C (16#25#), To_C (16#4C#), To_C (16#C4#), To_C (16#D1#), To_C (16#79#),
To_C (16#F4#), To_C (16#71#), To_C (16#D3#), To_C (16#86#), To_C (16#40#),
To_C (16#18#), To_C (16#13#), To_C (16#B0#), To_C (16#63#), To_C (16#B5#),
To_C (16#72#), To_C (16#4E#), To_C (16#30#), To_C (16#C4#), To_C (16#97#),
To_C (16#84#), To_C (16#86#), To_C (16#2D#), To_C (16#56#), To_C (16#2F#),
To_C (16#D7#), To_C (16#15#), To_C (16#F7#), To_C (16#7F#), To_C (16#C0#),
To_C (16#AE#), To_C (16#F5#), To_C (16#FC#), To_C (16#5B#), To_C (16#E5#),
To_C (16#FB#), To_C (16#A1#), To_C (16#BA#), To_C (16#D3#), To_C (16#02#),
To_C (16#03#), To_C (16#01#), To_C (16#00#), To_C (16#01#));
-- DER-formatted key.
Client_Private_Key_2048 : constant WolfSSL.Byte_Array :=
(To_C (16#30#), To_C (16#82#), To_C (16#04#), To_C (16#A4#), To_C (16#02#),
To_C (16#01#), To_C (16#00#), To_C (16#02#), To_C (16#82#), To_C (16#01#),
To_C (16#01#), To_C (16#00#), To_C (16#C3#), To_C (16#03#), To_C (16#D1#),
To_C (16#2B#), To_C (16#FE#), To_C (16#39#), To_C (16#A4#), To_C (16#32#),
To_C (16#45#), To_C (16#3B#), To_C (16#53#), To_C (16#C8#), To_C (16#84#),
To_C (16#2B#), To_C (16#2A#), To_C (16#7C#), To_C (16#74#), To_C (16#9A#),
To_C (16#BD#), To_C (16#AA#), To_C (16#2A#), To_C (16#52#), To_C (16#07#),
To_C (16#47#), To_C (16#D6#), To_C (16#A6#), To_C (16#36#), To_C (16#B2#),
To_C (16#07#), To_C (16#32#), To_C (16#8E#), To_C (16#D0#), To_C (16#BA#),
To_C (16#69#), To_C (16#7B#), To_C (16#C6#), To_C (16#C3#), To_C (16#44#),
To_C (16#9E#), To_C (16#D4#), To_C (16#81#), To_C (16#48#), To_C (16#FD#),
To_C (16#2D#), To_C (16#68#), To_C (16#A2#), To_C (16#8B#), To_C (16#67#),
To_C (16#BB#), To_C (16#A1#), To_C (16#75#), To_C (16#C8#), To_C (16#36#),
To_C (16#2C#), To_C (16#4A#), To_C (16#D2#), To_C (16#1B#), To_C (16#F7#),
To_C (16#8B#), To_C (16#BA#), To_C (16#CF#), To_C (16#0D#), To_C (16#F9#),
To_C (16#EF#), To_C (16#EC#), To_C (16#F1#), To_C (16#81#), To_C (16#1E#),
To_C (16#7B#), To_C (16#9B#), To_C (16#03#), To_C (16#47#), To_C (16#9A#),
To_C (16#BF#), To_C (16#65#), To_C (16#CC#), To_C (16#7F#), To_C (16#65#),
To_C (16#24#), To_C (16#69#), To_C (16#A6#), To_C (16#E8#), To_C (16#14#),
To_C (16#89#), To_C (16#5B#), To_C (16#E4#), To_C (16#34#), To_C (16#F7#),
To_C (16#C5#), To_C (16#B0#), To_C (16#14#), To_C (16#93#), To_C (16#F5#),
To_C (16#67#), To_C (16#7B#), To_C (16#3A#), To_C (16#7A#), To_C (16#78#),
To_C (16#E1#), To_C (16#01#), To_C (16#56#), To_C (16#56#), To_C (16#91#),
To_C (16#A6#), To_C (16#13#), To_C (16#42#), To_C (16#8D#), To_C (16#D2#),
To_C (16#3C#), To_C (16#40#), To_C (16#9C#), To_C (16#4C#), To_C (16#EF#),
To_C (16#D1#), To_C (16#86#), To_C (16#DF#), To_C (16#37#), To_C (16#51#),
To_C (16#1B#), To_C (16#0C#), To_C (16#A1#), To_C (16#3B#), To_C (16#F5#),
To_C (16#F1#), To_C (16#A3#), To_C (16#4A#), To_C (16#35#), To_C (16#E4#),
To_C (16#E1#), To_C (16#CE#), To_C (16#96#), To_C (16#DF#), To_C (16#1B#),
To_C (16#7E#), To_C (16#BF#), To_C (16#4E#), To_C (16#97#), To_C (16#D0#),
To_C (16#10#), To_C (16#E8#), To_C (16#A8#), To_C (16#08#), To_C (16#30#),
To_C (16#81#), To_C (16#AF#), To_C (16#20#), To_C (16#0B#), To_C (16#43#),
To_C (16#14#), To_C (16#C5#), To_C (16#74#), To_C (16#67#), To_C (16#B4#),
To_C (16#32#), To_C (16#82#), To_C (16#6F#), To_C (16#8D#), To_C (16#86#),
To_C (16#C2#), To_C (16#88#), To_C (16#40#), To_C (16#99#), To_C (16#36#),
To_C (16#83#), To_C (16#BA#), To_C (16#1E#), To_C (16#40#), To_C (16#72#),
To_C (16#22#), To_C (16#17#), To_C (16#D7#), To_C (16#52#), To_C (16#65#),
To_C (16#24#), To_C (16#73#), To_C (16#B0#), To_C (16#CE#), To_C (16#EF#),
To_C (16#19#), To_C (16#CD#), To_C (16#AE#), To_C (16#FF#), To_C (16#78#),
To_C (16#6C#), To_C (16#7B#), To_C (16#C0#), To_C (16#12#), To_C (16#03#),
To_C (16#D4#), To_C (16#4E#), To_C (16#72#), To_C (16#0D#), To_C (16#50#),
To_C (16#6D#), To_C (16#3B#), To_C (16#A3#), To_C (16#3B#), To_C (16#A3#),
To_C (16#99#), To_C (16#5E#), To_C (16#9D#), To_C (16#C8#), To_C (16#D9#),
To_C (16#0C#), To_C (16#85#), To_C (16#B3#), To_C (16#D9#), To_C (16#8A#),
To_C (16#D9#), To_C (16#54#), To_C (16#26#), To_C (16#DB#), To_C (16#6D#),
To_C (16#FA#), To_C (16#AC#), To_C (16#BB#), To_C (16#FF#), To_C (16#25#),
To_C (16#4C#), To_C (16#C4#), To_C (16#D1#), To_C (16#79#), To_C (16#F4#),
To_C (16#71#), To_C (16#D3#), To_C (16#86#), To_C (16#40#), To_C (16#18#),
To_C (16#13#), To_C (16#B0#), To_C (16#63#), To_C (16#B5#), To_C (16#72#),
To_C (16#4E#), To_C (16#30#), To_C (16#C4#), To_C (16#97#), To_C (16#84#),
To_C (16#86#), To_C (16#2D#), To_C (16#56#), To_C (16#2F#), To_C (16#D7#),
To_C (16#15#), To_C (16#F7#), To_C (16#7F#), To_C (16#C0#), To_C (16#AE#),
To_C (16#F5#), To_C (16#FC#), To_C (16#5B#), To_C (16#E5#), To_C (16#FB#),
To_C (16#A1#), To_C (16#BA#), To_C (16#D3#), To_C (16#02#), To_C (16#03#),
To_C (16#01#), To_C (16#00#), To_C (16#01#), To_C (16#02#), To_C (16#82#),
To_C (16#01#), To_C (16#01#), To_C (16#00#), To_C (16#A2#), To_C (16#E6#),
To_C (16#D8#), To_C (16#5F#), To_C (16#10#), To_C (16#71#), To_C (16#64#),
To_C (16#08#), To_C (16#9E#), To_C (16#2E#), To_C (16#6D#), To_C (16#D1#),
To_C (16#6D#), To_C (16#1E#), To_C (16#85#), To_C (16#D2#), To_C (16#0A#),
To_C (16#B1#), To_C (16#8C#), To_C (16#47#), To_C (16#CE#), To_C (16#2C#),
To_C (16#51#), To_C (16#6A#), To_C (16#A0#), To_C (16#12#), To_C (16#9E#),
To_C (16#53#), To_C (16#DE#), To_C (16#91#), To_C (16#4C#), To_C (16#1D#),
To_C (16#6D#), To_C (16#EA#), To_C (16#59#), To_C (16#7B#), To_C (16#F2#),
To_C (16#77#), To_C (16#AA#), To_C (16#D9#), To_C (16#C6#), To_C (16#D9#),
To_C (16#8A#), To_C (16#AB#), To_C (16#D8#), To_C (16#E1#), To_C (16#16#),
To_C (16#E4#), To_C (16#63#), To_C (16#26#), To_C (16#FF#), To_C (16#B5#),
To_C (16#6C#), To_C (16#13#), To_C (16#59#), To_C (16#B8#), To_C (16#E3#),
To_C (16#A5#), To_C (16#C8#), To_C (16#72#), To_C (16#17#), To_C (16#2E#),
To_C (16#0C#), To_C (16#9F#), To_C (16#6F#), To_C (16#E5#), To_C (16#59#),
To_C (16#3F#), To_C (16#76#), To_C (16#6F#), To_C (16#49#), To_C (16#B1#),
To_C (16#11#), To_C (16#C2#), To_C (16#5A#), To_C (16#2E#), To_C (16#16#),
To_C (16#29#), To_C (16#0D#), To_C (16#DE#), To_C (16#B7#), To_C (16#8E#),
To_C (16#DC#), To_C (16#40#), To_C (16#D5#), To_C (16#A2#), To_C (16#EE#),
To_C (16#E0#), To_C (16#1E#), To_C (16#A1#), To_C (16#F4#), To_C (16#BE#),
To_C (16#97#), To_C (16#DB#), To_C (16#86#), To_C (16#63#), To_C (16#96#),
To_C (16#14#), To_C (16#CD#), To_C (16#98#), To_C (16#09#), To_C (16#60#),
To_C (16#2D#), To_C (16#30#), To_C (16#76#), To_C (16#9C#), To_C (16#3C#),
To_C (16#CD#), To_C (16#E6#), To_C (16#88#), To_C (16#EE#), To_C (16#47#),
To_C (16#92#), To_C (16#79#), To_C (16#0B#), To_C (16#5A#), To_C (16#00#),
To_C (16#E2#), To_C (16#5E#), To_C (16#5F#), To_C (16#11#), To_C (16#7C#),
To_C (16#7D#), To_C (16#F9#), To_C (16#08#), To_C (16#B7#), To_C (16#20#),
To_C (16#06#), To_C (16#89#), To_C (16#2A#), To_C (16#5D#), To_C (16#FD#),
To_C (16#00#), To_C (16#AB#), To_C (16#22#), To_C (16#E1#), To_C (16#F0#),
To_C (16#B3#), To_C (16#BC#), To_C (16#24#), To_C (16#A9#), To_C (16#5E#),
To_C (16#26#), To_C (16#0E#), To_C (16#1F#), To_C (16#00#), To_C (16#2D#),
To_C (16#FE#), To_C (16#21#), To_C (16#9A#), To_C (16#53#), To_C (16#5B#),
To_C (16#6D#), To_C (16#D3#), To_C (16#2B#), To_C (16#AB#), To_C (16#94#),
To_C (16#82#), To_C (16#68#), To_C (16#43#), To_C (16#36#), To_C (16#D8#),
To_C (16#F6#), To_C (16#2F#), To_C (16#C6#), To_C (16#22#), To_C (16#FC#),
To_C (16#B5#), To_C (16#41#), To_C (16#5D#), To_C (16#0D#), To_C (16#33#),
To_C (16#60#), To_C (16#EA#), To_C (16#A4#), To_C (16#7D#), To_C (16#7E#),
To_C (16#E8#), To_C (16#4B#), To_C (16#55#), To_C (16#91#), To_C (16#56#),
To_C (16#D3#), To_C (16#5C#), To_C (16#57#), To_C (16#8F#), To_C (16#1F#),
To_C (16#94#), To_C (16#17#), To_C (16#2F#), To_C (16#AA#), To_C (16#DE#),
To_C (16#E9#), To_C (16#9E#), To_C (16#A8#), To_C (16#F4#), To_C (16#CF#),
To_C (16#8A#), To_C (16#4C#), To_C (16#8E#), To_C (16#A0#), To_C (16#E4#),
To_C (16#56#), To_C (16#73#), To_C (16#B2#), To_C (16#CF#), To_C (16#4F#),
To_C (16#86#), To_C (16#C5#), To_C (16#69#), To_C (16#3C#), To_C (16#F3#),
To_C (16#24#), To_C (16#20#), To_C (16#8B#), To_C (16#5C#), To_C (16#96#),
To_C (16#0C#), To_C (16#FA#), To_C (16#6B#), To_C (16#12#), To_C (16#3B#),
To_C (16#9A#), To_C (16#67#), To_C (16#C1#), To_C (16#DF#), To_C (16#C6#),
To_C (16#96#), To_C (16#B2#), To_C (16#A5#), To_C (16#D5#), To_C (16#92#),
To_C (16#0D#), To_C (16#9B#), To_C (16#09#), To_C (16#42#), To_C (16#68#),
To_C (16#24#), To_C (16#10#), To_C (16#45#), To_C (16#D4#), To_C (16#50#),
To_C (16#E4#), To_C (16#17#), To_C (16#39#), To_C (16#48#), To_C (16#D0#),
To_C (16#35#), To_C (16#8B#), To_C (16#94#), To_C (16#6D#), To_C (16#11#),
To_C (16#DE#), To_C (16#8F#), To_C (16#CA#), To_C (16#59#), To_C (16#02#),
To_C (16#81#), To_C (16#81#), To_C (16#00#), To_C (16#EA#), To_C (16#24#),
To_C (16#A7#), To_C (16#F9#), To_C (16#69#), To_C (16#33#), To_C (16#E9#),
To_C (16#71#), To_C (16#DC#), To_C (16#52#), To_C (16#7D#), To_C (16#88#),
To_C (16#21#), To_C (16#28#), To_C (16#2F#), To_C (16#49#), To_C (16#DE#),
To_C (16#BA#), To_C (16#72#), To_C (16#16#), To_C (16#E9#), To_C (16#CC#),
To_C (16#47#), To_C (16#7A#), To_C (16#88#), To_C (16#0D#), To_C (16#94#),
To_C (16#57#), To_C (16#84#), To_C (16#58#), To_C (16#16#), To_C (16#3A#),
To_C (16#81#), To_C (16#B0#), To_C (16#3F#), To_C (16#A2#), To_C (16#CF#),
To_C (16#A6#), To_C (16#6C#), To_C (16#1E#), To_C (16#B0#), To_C (16#06#),
To_C (16#29#), To_C (16#00#), To_C (16#8F#), To_C (16#E7#), To_C (16#77#),
To_C (16#76#), To_C (16#AC#), To_C (16#DB#), To_C (16#CA#), To_C (16#C7#),
To_C (16#D9#), To_C (16#5E#), To_C (16#9B#), To_C (16#3F#), To_C (16#26#),
To_C (16#90#), To_C (16#52#), To_C (16#AE#), To_C (16#FC#), To_C (16#38#),
To_C (16#90#), To_C (16#00#), To_C (16#14#), To_C (16#BB#), To_C (16#B4#),
To_C (16#0F#), To_C (16#58#), To_C (16#94#), To_C (16#E7#), To_C (16#2F#),
To_C (16#6A#), To_C (16#7E#), To_C (16#1C#), To_C (16#4F#), To_C (16#41#),
To_C (16#21#), To_C (16#D4#), To_C (16#31#), To_C (16#59#), To_C (16#1F#),
To_C (16#4E#), To_C (16#8A#), To_C (16#1A#), To_C (16#8D#), To_C (16#A7#),
To_C (16#57#), To_C (16#6C#), To_C (16#22#), To_C (16#D8#), To_C (16#E5#),
To_C (16#F4#), To_C (16#7E#), To_C (16#32#), To_C (16#A6#), To_C (16#10#),
To_C (16#CB#), To_C (16#64#), To_C (16#A5#), To_C (16#55#), To_C (16#03#),
To_C (16#87#), To_C (16#A6#), To_C (16#27#), To_C (16#05#), To_C (16#8C#),
To_C (16#C3#), To_C (16#D7#), To_C (16#B6#), To_C (16#27#), To_C (16#B2#),
To_C (16#4D#), To_C (16#BA#), To_C (16#30#), To_C (16#DA#), To_C (16#47#),
To_C (16#8F#), To_C (16#54#), To_C (16#D3#), To_C (16#3D#), To_C (16#8B#),
To_C (16#84#), To_C (16#8D#), To_C (16#94#), To_C (16#98#), To_C (16#58#),
To_C (16#A5#), To_C (16#02#), To_C (16#81#), To_C (16#81#), To_C (16#00#),
To_C (16#D5#), To_C (16#38#), To_C (16#1B#), To_C (16#C3#), To_C (16#8F#),
To_C (16#C5#), To_C (16#93#), To_C (16#0C#), To_C (16#47#), To_C (16#0B#),
To_C (16#6F#), To_C (16#35#), To_C (16#92#), To_C (16#C5#), To_C (16#B0#),
To_C (16#8D#), To_C (16#46#), To_C (16#C8#), To_C (16#92#), To_C (16#18#),
To_C (16#8F#), To_C (16#F5#), To_C (16#80#), To_C (16#0A#), To_C (16#F7#),
To_C (16#EF#), To_C (16#A1#), To_C (16#FE#), To_C (16#80#), To_C (16#B9#),
To_C (16#B5#), To_C (16#2A#), To_C (16#BA#), To_C (16#CA#), To_C (16#18#),
To_C (16#B0#), To_C (16#5D#), To_C (16#A5#), To_C (16#07#), To_C (16#D0#),
To_C (16#93#), To_C (16#8D#), To_C (16#D8#), To_C (16#9C#), To_C (16#04#),
To_C (16#1C#), To_C (16#D4#), To_C (16#62#), To_C (16#8E#), To_C (16#A6#),
To_C (16#26#), To_C (16#81#), To_C (16#01#), To_C (16#FF#), To_C (16#CE#),
To_C (16#8A#), To_C (16#2A#), To_C (16#63#), To_C (16#34#), To_C (16#35#),
To_C (16#40#), To_C (16#AA#), To_C (16#6D#), To_C (16#80#), To_C (16#DE#),
To_C (16#89#), To_C (16#23#), To_C (16#6A#), To_C (16#57#), To_C (16#4D#),
To_C (16#9E#), To_C (16#6E#), To_C (16#AD#), To_C (16#93#), To_C (16#4E#),
To_C (16#56#), To_C (16#90#), To_C (16#0B#), To_C (16#6D#), To_C (16#9D#),
To_C (16#73#), To_C (16#8B#), To_C (16#0C#), To_C (16#AE#), To_C (16#27#),
To_C (16#3D#), To_C (16#DE#), To_C (16#4E#), To_C (16#F0#), To_C (16#AA#),
To_C (16#C5#), To_C (16#6C#), To_C (16#78#), To_C (16#67#), To_C (16#6C#),
To_C (16#94#), To_C (16#52#), To_C (16#9C#), To_C (16#37#), To_C (16#67#),
To_C (16#6C#), To_C (16#2D#), To_C (16#EF#), To_C (16#BB#), To_C (16#AF#),
To_C (16#DF#), To_C (16#A6#), To_C (16#90#), To_C (16#3C#), To_C (16#C4#),
To_C (16#47#), To_C (16#CF#), To_C (16#8D#), To_C (16#96#), To_C (16#9E#),
To_C (16#98#), To_C (16#A9#), To_C (16#B4#), To_C (16#9F#), To_C (16#C5#),
To_C (16#A6#), To_C (16#50#), To_C (16#DC#), To_C (16#B3#), To_C (16#F0#),
To_C (16#FB#), To_C (16#74#), To_C (16#17#), To_C (16#02#), To_C (16#81#),
To_C (16#80#), To_C (16#5E#), To_C (16#83#), To_C (16#09#), To_C (16#62#),
To_C (16#BD#), To_C (16#BA#), To_C (16#7C#), To_C (16#A2#), To_C (16#BF#),
To_C (16#42#), To_C (16#74#), To_C (16#F5#), To_C (16#7C#), To_C (16#1C#),
To_C (16#D2#), To_C (16#69#), To_C (16#C9#), To_C (16#04#), To_C (16#0D#),
To_C (16#85#), To_C (16#7E#), To_C (16#3E#), To_C (16#3D#), To_C (16#24#),
To_C (16#12#), To_C (16#C3#), To_C (16#18#), To_C (16#7B#), To_C (16#F3#),
To_C (16#29#), To_C (16#F3#), To_C (16#5F#), To_C (16#0E#), To_C (16#76#),
To_C (16#6C#), To_C (16#59#), To_C (16#75#), To_C (16#E4#), To_C (16#41#),
To_C (16#84#), To_C (16#69#), To_C (16#9D#), To_C (16#32#), To_C (16#F3#),
To_C (16#CD#), To_C (16#22#), To_C (16#AB#), To_C (16#B0#), To_C (16#35#),
To_C (16#BA#), To_C (16#4A#), To_C (16#B2#), To_C (16#3C#), To_C (16#E5#),
To_C (16#D9#), To_C (16#58#), To_C (16#B6#), To_C (16#62#), To_C (16#4F#),
To_C (16#5D#), To_C (16#DE#), To_C (16#E5#), To_C (16#9E#), To_C (16#0A#),
To_C (16#CA#), To_C (16#53#), To_C (16#B2#), To_C (16#2C#), To_C (16#F7#),
To_C (16#9E#), To_C (16#B3#), To_C (16#6B#), To_C (16#0A#), To_C (16#5B#),
To_C (16#79#), To_C (16#65#), To_C (16#EC#), To_C (16#6E#), To_C (16#91#),
To_C (16#4E#), To_C (16#92#), To_C (16#20#), To_C (16#F6#), To_C (16#FC#),
To_C (16#FC#), To_C (16#16#), To_C (16#ED#), To_C (16#D3#), To_C (16#76#),
To_C (16#0C#), To_C (16#E2#), To_C (16#EC#), To_C (16#7F#), To_C (16#B2#),
To_C (16#69#), To_C (16#13#), To_C (16#6B#), To_C (16#78#), To_C (16#0E#),
To_C (16#5A#), To_C (16#46#), To_C (16#64#), To_C (16#B4#), To_C (16#5E#),
To_C (16#B7#), To_C (16#25#), To_C (16#A0#), To_C (16#5A#), To_C (16#75#),
To_C (16#3A#), To_C (16#4B#), To_C (16#EF#), To_C (16#C7#), To_C (16#3C#),
To_C (16#3E#), To_C (16#F7#), To_C (16#FD#), To_C (16#26#), To_C (16#B8#),
To_C (16#20#), To_C (16#C4#), To_C (16#99#), To_C (16#0A#), To_C (16#9A#),
To_C (16#73#), To_C (16#BE#), To_C (16#C3#), To_C (16#19#), To_C (16#02#),
To_C (16#81#), To_C (16#81#), To_C (16#00#), To_C (16#BA#), To_C (16#44#),
To_C (16#93#), To_C (16#14#), To_C (16#AC#), To_C (16#34#), To_C (16#19#),
To_C (16#3B#), To_C (16#5F#), To_C (16#91#), To_C (16#60#), To_C (16#AC#),
To_C (16#F7#), To_C (16#B4#), To_C (16#D6#), To_C (16#81#), To_C (16#05#),
To_C (16#36#), To_C (16#51#), To_C (16#53#), To_C (16#3D#), To_C (16#E8#),
To_C (16#65#), To_C (16#DC#), To_C (16#AF#), To_C (16#2E#), To_C (16#DC#),
To_C (16#61#), To_C (16#3E#), To_C (16#C9#), To_C (16#7D#), To_C (16#B8#),
To_C (16#7F#), To_C (16#87#), To_C (16#F0#), To_C (16#3B#), To_C (16#9B#),
To_C (16#03#), To_C (16#82#), To_C (16#29#), To_C (16#37#), To_C (16#CE#),
To_C (16#72#), To_C (16#4E#), To_C (16#11#), To_C (16#D5#), To_C (16#B1#),
To_C (16#C1#), To_C (16#0C#), To_C (16#07#), To_C (16#A0#), To_C (16#99#),
To_C (16#91#), To_C (16#4A#), To_C (16#8D#), To_C (16#7F#), To_C (16#EC#),
To_C (16#79#), To_C (16#CF#), To_C (16#F1#), To_C (16#39#), To_C (16#B5#),
To_C (16#E9#), To_C (16#85#), To_C (16#EC#), To_C (16#62#), To_C (16#F7#),
To_C (16#DA#), To_C (16#7D#), To_C (16#BC#), To_C (16#64#), To_C (16#4D#),
To_C (16#22#), To_C (16#3C#), To_C (16#0E#), To_C (16#F2#), To_C (16#D6#),
To_C (16#51#), To_C (16#F5#), To_C (16#87#), To_C (16#D8#), To_C (16#99#),
To_C (16#C0#), To_C (16#11#), To_C (16#20#), To_C (16#5D#), To_C (16#0F#),
To_C (16#29#), To_C (16#FD#), To_C (16#5B#), To_C (16#E2#), To_C (16#AE#),
To_C (16#D9#), To_C (16#1C#), To_C (16#D9#), To_C (16#21#), To_C (16#56#),
To_C (16#6D#), To_C (16#FC#), To_C (16#84#), To_C (16#D0#), To_C (16#5F#),
To_C (16#ED#), To_C (16#10#), To_C (16#15#), To_C (16#1C#), To_C (16#18#),
To_C (16#21#), To_C (16#E7#), To_C (16#C4#), To_C (16#3D#), To_C (16#4B#),
To_C (16#D7#), To_C (16#D0#), To_C (16#9E#), To_C (16#6A#), To_C (16#95#),
To_C (16#CF#), To_C (16#22#), To_C (16#C9#), To_C (16#03#), To_C (16#7B#),
To_C (16#9E#), To_C (16#E3#), To_C (16#60#), To_C (16#01#), To_C (16#FC#),
To_C (16#2F#), To_C (16#02#), To_C (16#81#), To_C (16#80#), To_C (16#11#),
To_C (16#D0#), To_C (16#4B#), To_C (16#CF#), To_C (16#1B#), To_C (16#67#),
To_C (16#B9#), To_C (16#9F#), To_C (16#10#), To_C (16#75#), To_C (16#47#),
To_C (16#86#), To_C (16#65#), To_C (16#AE#), To_C (16#31#), To_C (16#C2#),
To_C (16#C6#), To_C (16#30#), To_C (16#AC#), To_C (16#59#), To_C (16#06#),
To_C (16#50#), To_C (16#D9#), To_C (16#0F#), To_C (16#B5#), To_C (16#70#),
To_C (16#06#), To_C (16#F7#), To_C (16#F0#), To_C (16#D3#), To_C (16#C8#),
To_C (16#62#), To_C (16#7C#), To_C (16#A8#), To_C (16#DA#), To_C (16#6E#),
To_C (16#F6#), To_C (16#21#), To_C (16#3F#), To_C (16#D3#), To_C (16#7F#),
To_C (16#5F#), To_C (16#EA#), To_C (16#8A#), To_C (16#AB#), To_C (16#3F#),
To_C (16#D9#), To_C (16#2A#), To_C (16#5E#), To_C (16#F3#), To_C (16#51#),
To_C (16#D2#), To_C (16#C2#), To_C (16#30#), To_C (16#37#), To_C (16#E3#),
To_C (16#2D#), To_C (16#A3#), To_C (16#75#), To_C (16#0D#), To_C (16#1E#),
To_C (16#4D#), To_C (16#21#), To_C (16#34#), To_C (16#D5#), To_C (16#57#),
To_C (16#70#), To_C (16#5C#), To_C (16#89#), To_C (16#BF#), To_C (16#72#),
To_C (16#EC#), To_C (16#4A#), To_C (16#6E#), To_C (16#68#), To_C (16#D5#),
To_C (16#CD#), To_C (16#18#), To_C (16#74#), To_C (16#33#), To_C (16#4E#),
To_C (16#8C#), To_C (16#3A#), To_C (16#45#), To_C (16#8F#), To_C (16#E6#),
To_C (16#96#), To_C (16#40#), To_C (16#EB#), To_C (16#63#), To_C (16#F9#),
To_C (16#19#), To_C (16#86#), To_C (16#3A#), To_C (16#51#), To_C (16#DD#),
To_C (16#89#), To_C (16#4B#), To_C (16#B0#), To_C (16#F3#), To_C (16#F9#),
To_C (16#9F#), To_C (16#5D#), To_C (16#28#), To_C (16#95#), To_C (16#38#),
To_C (16#BE#), To_C (16#35#), To_C (16#AB#), To_C (16#CA#), To_C (16#5C#),
To_C (16#E7#), To_C (16#93#), To_C (16#53#), To_C (16#34#), To_C (16#A1#),
To_C (16#45#), To_C (16#5D#), To_C (16#13#), To_C (16#39#), To_C (16#65#),
To_C (16#42#), To_C (16#46#), To_C (16#A1#), To_C (16#9F#), To_C (16#CD#),
To_C (16#F5#), To_C (16#BF#));
procedure Put (Text : String) renames Ada.Text_IO.Put;
procedure Put (Value : Integer) is
begin
Ada.Integer_Text_IO.Put (Value);
end Put;
procedure New_Line is
begin
Ada.Text_IO.New_Line;
end New_Line;
use type WolfSSL.Subprogram_Result;
Original_AES_Key : constant WolfSSL.Byte_Array (1 .. 32) :=
"Thisismyfakeaeskeythatis32bytes!";
Digital_Signature_Of_AES_Key : WolfSSL.Byte_Array (1 .. 256);
Decrypted_Digital_Signature : WolfSSL.Byte_Array (1 .. 256);
Encrypted : WolfSSL.Byte_Array (1 .. 1_024);
-- Actually only needs to be at least 256 bytes.
-- The purpose is to store the Original_AES_Key encrypted.
Decrypted : WolfSSL.Byte_Array (1 .. 1_024);
-- Actually only needs to be at least 32 bytes.
-- The purpose is to store the Original_AES_Key after
-- first being encrypted and then decrypted.
-- After the process, this byte array should contain the same
-- contents as Original_AES_KEY.
Hash : WolfSSL.SHA256_Hash;
SHA256 : WolfSSL.SHA256_Type;
R : Integer;
RNG : WolfSSL.RNG_Type;
RSA_Encrypt_Key : WolfSSL.RSA_Key_Type;
RSA_Decrypt_Key : WolfSSL.RSA_Key_Type;
Index : WolfSSL.Byte_Index;
-- Release any resources that may have been acquired so far.
-- Safe to call multiple times and safe when handles are null.
procedure Cleanup is
begin
if WolfSSL.Is_Valid (RSA_Encrypt_Key) then
WolfSSL.Free_RSA (Key => RSA_Encrypt_Key);
end if;
if WolfSSL.Is_Valid (RSA_Decrypt_Key) then
WolfSSL.Free_RSA (Key => RSA_Decrypt_Key);
end if;
if WolfSSL.Is_Valid (RNG) then
WolfSSL.Free_RNG (Key => RNG);
end if;
end Cleanup;
begin
WolfSSL.Create_RNG (Key => RNG,
Result => R);
if R /= 0 then
Put ("Attaining RNG key instance failed");
New_Line;
Cleanup;
return;
end if;
WolfSSL.Create_RSA (Key => RSA_Encrypt_Key,
Result => R);
if R /= 0 then
Put ("Attaining RSA key instance failed");
New_Line;
Cleanup;
return;
end if;
WolfSSL.Rsa_Set_RNG (Key => RSA_Encrypt_Key,
RNG => RNG,
Result => R);
if R /= 0 then
Put ("Associating RSA key with random number generator failed");
New_Line;
Cleanup;
return;
end if;
Index := Client_Private_Key_2048'First;
WolfSSL.Rsa_Private_Key_Decode (Input => Client_Private_Key_2048,
Index => Index,
Key => RSA_Encrypt_Key,
Size => Client_Private_Key_2048'Length,
Result => R);
if R /= 0 then
Put ("Loading private RSA key failed with error code ");
Put (R);
New_Line;
Cleanup;
return;
end if;
WolfSSL.Rsa_SSL_Sign (Input => Original_AES_Key,
Output => Digital_Signature_Of_AES_Key,
RSA => RSA_Encrypt_Key,
RNG => RNG,
Result => R);
if R < 0 then
Put ("Creating digital signature using RSA private key failed");
Put (R);
New_Line;
Cleanup;
return;
end if;
WolfSSL.Create_RSA (Key => RSA_Decrypt_Key,
Result => R);
if R /= 0 then
Put ("Attaining RSA key instance failed");
New_Line;
Cleanup;
return;
end if;
Index := Rsa_Public_key_2048'First;
WolfSSL.Rsa_Public_Key_Decode (Input => Rsa_Public_key_2048,
Index => Index,
Key => RSA_Decrypt_Key,
Size => Rsa_Public_key_2048'Length,
Result => R);
if R /= 0 then
Put ("Loading public RSA key failed with DER encoded key");
Put (R);
New_Line;
Cleanup;
return;
end if;
WolfSSL.Rsa_SSL_Verify (Input => Digital_Signature_Of_AES_Key,
Output => Decrypted_Digital_Signature,
RSA => RSA_Decrypt_Key,
Result => R);
if R < 0 then
Put ("Verify digital signature failed");
Put (R);
New_Line;
Cleanup;
return;
end if;
Put ("Successful verification of RSA based digital signature.");
New_Line;
WolfSSL.RSA_Public_Encrypt (Input => Original_AES_Key,
Output => Encrypted,
Index => Index,
RSA => RSA_Decrypt_Key,
RNG => RNG,
Result => R);
if R < 0 then
Put ("Failed to encrypt the original AES key");
Put (R);
New_Line;
Cleanup;
return;
end if;
WolfSSL.RSA_Private_Decrypt (Input => Encrypted (1 .. Index),
Output => Decrypted,
Index => Index,
RSA => RSA_Encrypt_Key,
Result => R);
if R < 0 then
Put ("Failed to decrypt the encrypted original AES key");
Put (R);
New_Line;
Cleanup;
return;
end if;
if Integer (Index) /= 32 then
Put ("Decryption of the encrypted original AES key, wrong size");
New_Line;
Cleanup;
return;
end if;
if Original_AES_Key = Decrypted (1 .. 32) then
Put ("Successfully encrypted and decrypted using RSA.");
New_Line;
else
Put ("Failed to encrypt and decrypt original AES key.");
New_Line;
end if;
Cleanup;
end Rsa_Verify_Main;

View File

@@ -0,0 +1,46 @@
with Ada.Text_IO;
with WolfSSL;
procedure SHA256_Main is
procedure Put (Text : String) renames Ada.Text_IO.Put;
procedure New_Line is
begin
Ada.Text_IO.New_Line;
end New_Line;
use type WolfSSL.Subprogram_Result;
Hash : WolfSSL.SHA256_Hash;
B : WolfSSL.Byte_Array := (1 => 'a',
2 => 's',
3 => 'd',
4 => 'f');
SHA256 : WolfSSL.SHA256_Type;
R : Integer;
begin
WolfSSL.Create_SHA256 (SHA256 => SHA256, Result => R);
if R /= 0 then
Put ("SHA256 instance creation failed");
New_Line;
return;
end if;
WolfSSL.Update_SHA256 (SHA256 => SHA256, Byte => B, Result => R);
if R /= 0 then
Put ("Update of SHA256 instance failed");
New_Line;
return;
end if;
WolfSSL.Finalize_SHA256 (SHA256 => SHA256,
Hash => Hash,
Result => R);
if R = 0 then
Put ("SHA256 hash computed successfully");
New_Line;
else
Put ("Finalization of SHA256 instance failed");
New_Line;
end if;
WolfSSL.Free_SHA256 (SHA256 => SHA256);
end SHA256_Main;

View File

@@ -21,9 +21,9 @@
with Ada.Command_Line;
-- SPARK wrapper package around Ada.Command_Line and Interfaces.C
-- packages because these packages lack contracts in their specification
-- files that SPARK can use to verify the context in which
-- SPARK wrapper package around the Ada.Command_Line package
-- because this package lacks contracts in the specification
-- file that SPARK can use to verify the context in which
-- subprograms can safely be called.
package SPARK_Terminal with SPARK_Mode is

View File

@@ -28,6 +28,8 @@ with Interfaces.C.Strings;
with SPARK_Terminal;
with WolfSSL.Full_Runtime;
package body Tls_Client with SPARK_Mode is
use type WolfSSL.Mode_Type;
@@ -41,7 +43,7 @@ package body Tls_Client with SPARK_Mode is
subtype Byte_Type is WolfSSL.Byte_Type;
subtype chars_ptr is WolfSSL.chars_ptr;
subtype chars_ptr is WolfSSL.Full_Runtime.chars_ptr;
subtype unsigned is WolfSSL.unsigned;
package Natural_IO is new Ada.Text_IO.Integer_IO (Natural);
@@ -168,9 +170,9 @@ package body Tls_Client with SPARK_Mode is
Any_Inet_Addr : Inet_Addr_Type renames SPARK_Sockets.Any_Inet_Addr;
CERT_FILE : constant String := "../../certs/client-cert.pem";
KEY_FILE : constant String := "../../certs/client-key.pem";
CA_FILE : constant String := "../../certs/ca-cert.pem";
CERT_FILE : constant String := "../../../certs/client-cert.pem";
KEY_FILE : constant String := "../../../certs/client-key.pem";
CA_FILE : constant String := "../../../certs/ca-cert.pem";
subtype Byte_Array is WolfSSL.Byte_Array;
@@ -268,17 +270,30 @@ package body Tls_Client with SPARK_Mode is
end if;
-- Create and initialize WOLFSSL_CTX.
WolfSSL.Create_Context
(Method =>
(if DTLS then
WolfSSL.DTLSv1_3_Client_Method
else
WolfSSL.TLSv1_3_Client_Method),
Context => Ctx);
if DTLS then
declare
Method : WolfSSL.Method_Type :=
WolfSSL.DTLSv1_3_Client_Method;
begin
pragma Warnings (Off, """Method"" is set by ""Create_Context"" but not used after the call");
WolfSSL.Create_Context (Method => Method, Context => Ctx);
pragma Warnings (On, """Method"" is set by ""Create_Context"" but not used after the call");
end;
else
declare
Method : WolfSSL.Method_Type :=
WolfSSL.TLSv1_3_Client_Method;
begin
pragma Warnings (Off, """Method"" is set by ""Create_Context"" but not used after the call");
WolfSSL.Create_Context (Method => Method, Context => Ctx);
pragma Warnings (On, """Method"" is set by ""Create_Context"" but not used after the call");
end;
end if;
if not WolfSSL.Is_Valid (Ctx) then
Put_Line ("ERROR: failed to create WOLFSSL_CTX.");
SPARK_Sockets.Close_Socket (C);
WolfSSL.Free (Context => Ctx);
Set (Exit_Status_Failure);
return;
end if;
@@ -341,6 +356,7 @@ package body Tls_Client with SPARK_Mode is
if not WolfSSL.Is_Valid (Ssl) then
Put_Line ("ERROR: failed to create WOLFSSL object.");
SPARK_Sockets.Close_Socket (C);
WolfSSL.Free (Ssl);
WolfSSL.Free (Context => Ctx);
Set (Exit_Status_Failure);
return;
@@ -348,14 +364,14 @@ package body Tls_Client with SPARK_Mode is
if PSK then
-- Use PSK for authentication.
WolfSSL.Set_PSK_Client_Callback
WolfSSL.Full_Runtime.Set_PSK_Client_Callback
(Ssl => Ssl,
Callback => PSK_Client_Callback'Access);
end if;
if DTLS then
Result := WolfSSL.DTLS_Set_Peer(Ssl => Ssl,
Address => A);
Result := WolfSSL.Full_Runtime.DTLS_Set_Peer(Ssl => Ssl,
Address => A);
if Result /= Success then
Put_Line ("ERROR: Failed to set the DTLS peer.");
SPARK_Sockets.Close_Socket (C);
@@ -394,8 +410,9 @@ package body Tls_Client with SPARK_Mode is
SPARK_Sockets.To_C (Item => Text (1 .. Last),
Target => D,
Count => Count);
Output := WolfSSL.Write (Ssl => Ssl,
Data => D (1 .. Count));
WolfSSL.Write (Ssl => Ssl,
Data => D (1 .. Count),
Result => Output);
if not Output.Success then
Put ("ERROR: write failure");
New_Line;
@@ -419,24 +436,18 @@ package body Tls_Client with SPARK_Mode is
return;
end if;
Input := WolfSSL.Read (Ssl);
if not Input.Success then
Put_Line ("Read error.");
WolfSSL.Read (Ssl => Ssl, Result => Input);
if not Input.Success or Input.Last > Text'Length then
Put_Line ("Read error or response too long.");
Set (Exit_Status_Failure);
SPARK_Sockets.Close_Socket (C);
WolfSSL.Free (Ssl);
WolfSSL.Free (Context => Ctx);
return;
end if;
if Input.Buffer'Length > Text'Length then
SPARK_Sockets.To_Ada (Item => Input.Buffer (1 .. 200),
Target => Text,
Count => Last);
else
SPARK_Sockets.To_Ada (Item => Input.Buffer,
Target => Text,
Count => Last);
end if;
SPARK_Sockets.To_Ada (Item => Input.Buffer,
Target => Text,
Count => Last);
Put ("Server: ");
Put (Text (1 .. Last));
New_Line;

View File

@@ -29,10 +29,11 @@ package Tls_Client with SPARK_Mode is
procedure Run (Ssl : in out WolfSSL.WolfSSL_Type;
Ctx : in out WolfSSL.Context_Type;
Client : in out SPARK_Sockets.Optional_Socket) with
Pre => (not Client.Exists and not
WolfSSL.Is_Valid (Ssl) and not WolfSSL.Is_Valid (Ctx)),
Post => (not Client.Exists and not WolfSSL.Is_Valid (Ssl) and
not WolfSSL.Is_Valid (Ctx)),
Pre => (not Client.Exists and not
WolfSSL.Is_Valid (Ssl) and not WolfSSL.Is_Valid (Ctx)),
Post => (not Client.Exists and not WolfSSL.Is_Valid (Ssl) and
not WolfSSL.Is_Valid (Ctx)),
Annotate => (GNATprove, Might_Not_Return);
end Tls_Client;

View File

@@ -28,6 +28,8 @@ with Interfaces.C.Strings;
with SPARK_Terminal; pragma Elaborate_All (SPARK_Terminal);
with WolfSSL.Full_Runtime;
package body Tls_Server with SPARK_Mode is
use type WolfSSL.Mode_Type;
@@ -37,7 +39,7 @@ package body Tls_Server with SPARK_Mode is
Success : WolfSSL.Subprogram_Result renames WolfSSL.Success;
subtype chars_ptr is WolfSSL.chars_ptr;
subtype chars_ptr is WolfSSL.Full_Runtime.chars_ptr;
subtype unsigned is WolfSSL.unsigned;
procedure Put (Char : Character) is
@@ -92,9 +94,9 @@ package body Tls_Server with SPARK_Mode is
Any_Inet_Addr : Inet_Addr_Type renames SPARK_Sockets.Any_Inet_Addr;
CERT_FILE : constant String := "../../certs/server-cert.pem";
KEY_FILE : constant String := "../../certs/server-key.pem";
CA_FILE : constant String := "../../certs/client-cert.pem";
CERT_FILE : constant String := "../../../certs/server-cert.pem";
KEY_FILE : constant String := "../../../certs/server-key.pem";
CA_FILE : constant String := "../../../certs/client-cert.pem";
subtype Byte_Array is WolfSSL.Byte_Array;
@@ -158,7 +160,7 @@ package body Tls_Server with SPARK_Mode is
Ch : Character;
Result : WolfSSL.Subprogram_Result;
DTLS, PSK : Boolean := True;
DTLS, PSK : Boolean := False;
Shall_Continue : Boolean := True;
Input : WolfSSL.Read_Result;
@@ -239,17 +241,30 @@ package body Tls_Server with SPARK_Mode is
end if;
-- Create and initialize WOLFSSL_CTX.
WolfSSL.Create_Context
(Method =>
(if DTLS then
WolfSSL.DTLSv1_3_Server_Method
else
WolfSSL.TLSv1_3_Server_Method),
Context => Ctx);
if DTLS then
declare
Method : WolfSSL.Method_Type :=
WolfSSL.DTLSv1_3_Server_Method;
begin
pragma Warnings (Off, """Method"" is set by ""Create_Context"" but not used after the call");
WolfSSL.Create_Context (Method => Method, Context => Ctx);
pragma Warnings (On, """Method"" is set by ""Create_Context"" but not used after the call");
end;
else
declare
Method : WolfSSL.Method_Type :=
WolfSSL.TLSv1_3_Server_Method;
begin
pragma Warnings (Off, """Method"" is set by ""Create_Context"" but not used after the call");
WolfSSL.Create_Context (Method => Method, Context => Ctx);
pragma Warnings (On, """Method"" is set by ""Create_Context"" but not used after the call");
end;
end if;
if not WolfSSL.Is_Valid (Ctx) then
Put_Line ("ERROR: failed to create WOLFSSL_CTX.");
SPARK_Sockets.Close_Socket (L);
WolfSSL.Free (Context => Ctx);
Set (Exit_Status_Failure);
return;
end if;
@@ -318,11 +333,11 @@ package body Tls_Server with SPARK_Mode is
if PSK then
-- Use PSK for authentication.
WolfSSL.Set_Context_PSK_Server_Callback
WolfSSL.Full_Runtime.Set_Context_PSK_Server_Callback
(Context => Ctx,
Callback => PSK_Server_Callback'Access);
end if;
while Shall_Continue loop
pragma Loop_Invariant (not C.Exists);
pragma Loop_Invariant (not WolfSSL.Is_Valid (Ssl));
@@ -347,9 +362,10 @@ package body Tls_Server with SPARK_Mode is
if not WolfSSL.Is_Valid (Ssl) then
Put_Line ("ERROR: failed to create WOLFSSL object.");
declare
Error_Message : constant WolfSSL.Error_Message :=
WolfSSL.Error (WolfSSL.Get_Error (Ssl, Result));
Error_Message : WolfSSL.Error_Message := (Text => (others => ' '), Last => 0);
begin
WolfSSL.Error (WolfSSL.Get_Error (Ssl, Result),
Message => Error_Message);
if Result = Success then
Put_Line (Error_Message.Text (1 .. Error_Message.Last));
end if;
@@ -360,6 +376,7 @@ package body Tls_Server with SPARK_Mode is
SPARK_Sockets.Close_Socket (C);
end if;
WolfSSL.Free (Ssl);
WolfSSL.Free (Context => Ctx);
Set (Exit_Status_Failure);
return;
@@ -401,7 +418,7 @@ package body Tls_Server with SPARK_Mode is
Put_Line ("Client connected successfully.");
Input := WolfSSL.Read (Ssl);
WolfSSL.Read (Ssl => Ssl, Result => Input);
if not Input.Success then
Put_Line ("Read error.");
WolfSSL.Free (Ssl);
@@ -436,7 +453,7 @@ package body Tls_Server with SPARK_Mode is
end if;
end if;
Output := WolfSSL.Write (Ssl, Reply);
WolfSSL.Write (Ssl, Reply, Result => Output);
if not Output.Success then
Put_Line ("ERROR: write failure.");
elsif Output.Bytes_Written /= Reply'Length then

View File

@@ -3,15 +3,45 @@
# All paths should be given relative to the root
EXTRA_DIST+= wrapper/Ada/README.md
EXTRA_DIST+= wrapper/Ada/ada_binding.c
EXTRA_DIST+= wrapper/Ada/alire.toml
EXTRA_DIST+= wrapper/Ada/default.gpr
EXTRA_DIST+= wrapper/Ada/restricted.adc
EXTRA_DIST+= wrapper/Ada/ada_binding.c
EXTRA_DIST+= wrapper/Ada/tls_client_main.adb
EXTRA_DIST+= wrapper/Ada/tls_client.adb
EXTRA_DIST+= wrapper/Ada/tls_client.ads
EXTRA_DIST+= wrapper/Ada/tls_server_main.adb
EXTRA_DIST+= wrapper/Ada/tls_server.adb
EXTRA_DIST+= wrapper/Ada/tls_server.ads
EXTRA_DIST+= wrapper/Ada/user_settings.h
EXTRA_DIST+= wrapper/Ada/wolfssl-full_runtime.adb
EXTRA_DIST+= wrapper/Ada/wolfssl-full_runtime.ads
EXTRA_DIST+= wrapper/Ada/wolfssl.adb
EXTRA_DIST+= wrapper/Ada/wolfssl.ads
EXTRA_DIST+= wrapper/Ada/wolfssl.gpr
EXTRA_DIST+= wrapper/Ada/examples/.gitignore
EXTRA_DIST+= wrapper/Ada/examples/alire.toml
EXTRA_DIST+= wrapper/Ada/examples/examples.gpr
EXTRA_DIST+= wrapper/Ada/examples/src/aes_verify_main.adb
EXTRA_DIST+= wrapper/Ada/examples/src/rsa_verify_main.adb
EXTRA_DIST+= wrapper/Ada/examples/src/sha256_main.adb
EXTRA_DIST+= wrapper/Ada/examples/src/spark_sockets.adb
EXTRA_DIST+= wrapper/Ada/examples/src/spark_sockets.ads
EXTRA_DIST+= wrapper/Ada/examples/src/spark_terminal.adb
EXTRA_DIST+= wrapper/Ada/examples/src/spark_terminal.ads
EXTRA_DIST+= wrapper/Ada/examples/src/tls_client.adb
EXTRA_DIST+= wrapper/Ada/examples/src/tls_client.ads
EXTRA_DIST+= wrapper/Ada/examples/src/tls_client_main.adb
EXTRA_DIST+= wrapper/Ada/examples/src/tls_server.adb
EXTRA_DIST+= wrapper/Ada/examples/src/tls_server.ads
EXTRA_DIST+= wrapper/Ada/examples/src/tls_server_main.adb
EXTRA_DIST+= wrapper/Ada/tests/.gitignore
EXTRA_DIST+= wrapper/Ada/tests/README.md
EXTRA_DIST+= wrapper/Ada/tests/alire.toml
EXTRA_DIST+= wrapper/Ada/tests/src/aes_bindings_tests.adb
EXTRA_DIST+= wrapper/Ada/tests/src/aes_bindings_tests.ads
EXTRA_DIST+= wrapper/Ada/tests/src/rsa_verify_bindings_tests.adb
EXTRA_DIST+= wrapper/Ada/tests/src/rsa_verify_bindings_tests.ads
EXTRA_DIST+= wrapper/Ada/tests/src/sha256_bindings_tests.adb
EXTRA_DIST+= wrapper/Ada/tests/src/sha256_bindings_tests.ads
EXTRA_DIST+= wrapper/Ada/tests/src/support/test_support.adb
EXTRA_DIST+= wrapper/Ada/tests/src/support/test_support.ads
EXTRA_DIST+= wrapper/Ada/tests/src/support/tests_root_suite.adb
EXTRA_DIST+= wrapper/Ada/tests/src/support/tests_root_suite.ads
EXTRA_DIST+= wrapper/Ada/tests/src/tests.adb
EXTRA_DIST+= wrapper/Ada/tests/tests.gpr
EXTRA_DIST+= wrapper/Ada/tests/valgrind.supp

4
wrapper/Ada/tests/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
/obj/
/bin/
/alire/
/config/

View File

@@ -0,0 +1,21 @@
# ADA Wrapper Tests
This directory contains tests for the ADA wrapper.
## Running the Tests
To run the tests using [alire](https://alire.ada.dev/), execute the following command from this directory:
```
alr run
```
This will build and run all ADA wrapper tests.
## Running the Tests with Valgrind
After building the tests with `alr build`, you can run them with valgrind using the provided suppressions file:
```
valgrind --track-origins=yes --leak-check=full --suppressions=valgrind.supp ./bin/tests
```

View File

@@ -0,0 +1,15 @@
name = "tests"
description = "Tests for the wolfssl ada bindings"
version = "0.1.0-dev"
authors = ["Juliusz Sosinowicz"]
maintainers = ["Juliusz Sosinowicz <juliusz@wolfssl.com>"]
maintainers-logins = ["julek-wolfssl"]
licenses = "GPL-3.0-or-later"
website = "https://www.wolfssl.com"
tags = ["ssl", "tests"]
executables = ["tests"]
[[depends-on]]
aunit = "^24.0.0"

View File

@@ -0,0 +1,162 @@
with AUnit.Assertions;
with AUnit.Test_Caller;
with WolfSSL;
with Test_Support;
package body AES_Bindings_Tests is
use type WolfSSL.Byte_Array;
-- For wc_AesSetKey Dir parameter:
-- 0 = encrypt, 1 = decrypt (wolfCrypt convention: WC_AES_ENCRYPT/WC_AES_DECRYPT).
-- Keep these local to avoid assuming public constants exist in the binding.
AES_Encrypt_Dir : constant Integer := 0;
AES_Decrypt_Dir : constant Integer := 1;
----------------------------------------------------------------------------
-- Tests
----------------------------------------------------------------------------
procedure Test_AES_CBC_Roundtrip (F : in out Fixture) is
pragma Unreferenced (F);
AES : WolfSSL.AES_Type;
R : Integer;
Key : constant WolfSSL.Byte_Array :=
Test_Support.Bytes ("0123456789ABCDEF0123456789ABCDEF");
IV_Init : constant WolfSSL.Byte_Array :=
Test_Support.Bytes ("INITVECTOR_16B__");
-- Use a plaintext length that is a multiple of 16 so we don't rely on any
-- padding behavior (the API is raw CBC). Exactly 32 bytes.
Plain : constant WolfSSL.Byte_Array :=
Test_Support.Bytes ("This is 32 bytes of data!!!!!!!!");
Cipher : WolfSSL.Byte_Array (Plain'Range);
Decoded : WolfSSL.Byte_Array (Plain'Range);
IV_Enc : WolfSSL.Byte_Array (1 .. IV_Init'Length);
IV_Dec : WolfSSL.Byte_Array (1 .. IV_Init'Length);
begin
IV_Enc := IV_Init;
IV_Dec := IV_Init;
WolfSSL.Create_AES (Device => WolfSSL.Invalid_Device,
AES => AES,
Result => R);
Test_Support.Assert_Success (R, "Create_AES");
-- Set key for ENCRYPT; provide IV as required by wc_AesSetKey.
WolfSSL.AES_Set_Key (AES => AES,
Key => Key,
Length => Key'Length,
IV => IV_Enc,
Dir => AES_Encrypt_Dir,
Result => R);
Test_Support.Assert_Success (R, "AES_Set_Key(encrypt)");
WolfSSL.AES_Set_IV (AES => AES,
IV => IV_Enc,
Result => R);
Test_Support.Assert_Success (R, "AES_Set_IV(encrypt)");
WolfSSL.AES_Set_Cbc_Encrypt (AES => AES,
Output => Cipher,
Input => Plain,
Size => Plain'Length,
Result => R);
Test_Support.Assert_Success (R, "AES_Set_Cbc_Encrypt");
-- Now decrypt. Reset IV to the initial value (CBC requires same IV).
WolfSSL.AES_Set_Key (AES => AES,
Key => Key,
Length => Key'Length,
IV => IV_Dec,
Dir => AES_Decrypt_Dir,
Result => R);
Test_Support.Assert_Success (R, "AES_Set_Key(decrypt)");
WolfSSL.AES_Set_IV (AES => AES,
IV => IV_Dec,
Result => R);
Test_Support.Assert_Success (R, "AES_Set_IV(decrypt)");
WolfSSL.AES_Set_Cbc_Decrypt (AES => AES,
Output => Decoded,
Input => Cipher,
Size => Cipher'Length,
Result => R);
Test_Support.Assert_Success (R, "AES_Set_Cbc_Decrypt");
AUnit.Assertions.Assert
(Decoded = Plain,
"AES-CBC roundtrip mismatch");
WolfSSL.AES_Free (AES => AES,
Result => R);
Test_Support.Assert_Success (R, "AES_Free");
-- Keep this test focused on the binding contract: only require invalidation on
-- successful free.
if R = 0 then
AUnit.Assertions.Assert (not WolfSSL.Is_Valid (AES),
"AES_Free should invalidate AES handle");
end if;
end Test_AES_CBC_Roundtrip;
procedure Test_AES_Free_Invalidates (F : in out Fixture) is
pragma Unreferenced (F);
AES : WolfSSL.AES_Type;
R : Integer;
begin
WolfSSL.Create_AES (Device => WolfSSL.Invalid_Device,
AES => AES,
Result => R);
Test_Support.Assert_Success (R, "Create_AES");
AUnit.Assertions.Assert
(WolfSSL.Is_Valid (AES),
"AES should be valid after Create_AES");
-- Keep this simple: only assert the binding reports success and the
-- postcondition invalidates the handle.
WolfSSL.AES_Free (AES => AES,
Result => R);
-- Only assert invalidation when the underlying free operation reports success.
if R = 0 then
AUnit.Assertions.Assert (not WolfSSL.Is_Valid (AES),
"AES should be invalid after AES_Free");
end if;
end Test_AES_Free_Invalidates;
----------------------------------------------------------------------------
-- Suite (static suite object + elaboration-time registration)
----------------------------------------------------------------------------
package Caller is new AUnit.Test_Caller (Fixture);
Suite_Object : aliased AUnit.Test_Suites.Test_Suite;
function Suite return AUnit.Test_Suites.Access_Test_Suite is
begin
return Suite_Object'Access;
end Suite;
begin
-- Register tests at elaboration time (standard Ada: all declarations above).
AUnit.Test_Suites.Add_Test
(Suite_Object'Access,
Caller.Create
(Name => "AES-CBC encrypt/decrypt roundtrip",
Test => Test_AES_CBC_Roundtrip'Access));
AUnit.Test_Suites.Add_Test
(Suite_Object'Access,
Caller.Create
(Name => "AES_Free succeeds after Create_AES",
Test => Test_AES_Free_Invalidates'Access));
end AES_Bindings_Tests;

View File

@@ -0,0 +1,30 @@
with AUnit.Test_Fixtures;
with AUnit.Test_Suites;
package AES_Bindings_Tests is
-- Minimal tests for the WolfSSL AES Ada bindings.
--
-- Goal: keep it simple and exercise the basic CBC encrypt/decrypt path:
-- - Create_AES
-- - AES_Set_Key
-- - AES_Set_IV
-- - AES_Set_Cbc_Encrypt
-- - AES_Set_Cbc_Decrypt
-- - AES_Free
--
-- Tests are designed after `aes_verify_main.adb` and the API contracts in
-- `wolfssl.ads`. We avoid making assumptions about padding: the test uses
-- a plaintext size that is a multiple of 16 bytes (AES block size).
type Fixture is new AUnit.Test_Fixtures.Test_Fixture with null record;
-- Encrypt known plaintext with AES-CBC and then decrypt it; expect round-trip.
procedure Test_AES_CBC_Roundtrip (F : in out Fixture);
-- Ensure AES_Free succeeds and invalidates the handle.
procedure Test_AES_Free_Invalidates (F : in out Fixture);
function Suite return AUnit.Test_Suites.Access_Test_Suite;
end AES_Bindings_Tests;

View File

@@ -0,0 +1,464 @@
with AUnit.Assertions;
with AUnit.Test_Caller;
with AUnit.Test_Fixtures;
with WolfSSL;
package body RSA_Verify_Bindings_Tests is
type Fixture is new AUnit.Test_Fixtures.Test_Fixture with null record;
type Unsigned_8 is mod 2 ** 8;
function To_C (Value : Unsigned_8) return WolfSSL.Byte_Type is
begin
return WolfSSL.Byte_Type'Val (Value);
end To_C;
use type WolfSSL.Byte_Array;
use type WolfSSL.Byte_Index;
-- RSA public key to verify with (DER) - copied from rsa_verify_main.adb.
Rsa_Public_Key_2048 : constant WolfSSL.Byte_Array :=
(To_C (16#30#), To_C (16#82#), To_C (16#01#), To_C (16#22#), To_C (16#30#),
To_C (16#0D#), To_C (16#06#), To_C (16#09#), To_C (16#2A#), To_C (16#86#),
To_C (16#48#), To_C (16#86#), To_C (16#F7#), To_C (16#0D#), To_C (16#01#),
To_C (16#01#), To_C (16#01#), To_C (16#05#), To_C (16#00#), To_C (16#03#),
To_C (16#82#), To_C (16#01#), To_C (16#0F#), To_C (16#00#), To_C (16#30#),
To_C (16#82#), To_C (16#01#), To_C (16#0A#), To_C (16#02#), To_C (16#82#),
To_C (16#01#), To_C (16#01#), To_C (16#00#), To_C (16#C3#), To_C (16#03#),
To_C (16#D1#), To_C (16#2B#), To_C (16#FE#), To_C (16#39#), To_C (16#A4#),
To_C (16#32#), To_C (16#45#), To_C (16#3B#), To_C (16#53#), To_C (16#C8#),
To_C (16#84#), To_C (16#2B#), To_C (16#2A#), To_C (16#7C#), To_C (16#74#),
To_C (16#9A#), To_C (16#BD#), To_C (16#AA#), To_C (16#2A#), To_C (16#52#),
To_C (16#07#), To_C (16#47#), To_C (16#D6#), To_C (16#A6#), To_C (16#36#),
To_C (16#B2#), To_C (16#07#), To_C (16#32#), To_C (16#8E#), To_C (16#D0#),
To_C (16#BA#), To_C (16#69#), To_C (16#7B#), To_C (16#C6#), To_C (16#C3#),
To_C (16#44#), To_C (16#9E#), To_C (16#D4#), To_C (16#81#), To_C (16#48#),
To_C (16#FD#), To_C (16#2D#), To_C (16#68#), To_C (16#A2#), To_C (16#8B#),
To_C (16#67#), To_C (16#BB#), To_C (16#A1#), To_C (16#75#), To_C (16#C8#),
To_C (16#36#), To_C (16#2C#), To_C (16#4A#), To_C (16#D2#), To_C (16#1B#),
To_C (16#F7#), To_C (16#8B#), To_C (16#BA#), To_C (16#CF#), To_C (16#0D#),
To_C (16#F9#), To_C (16#EF#), To_C (16#EC#), To_C (16#F1#), To_C (16#81#),
To_C (16#1E#), To_C (16#7B#), To_C (16#9B#), To_C (16#03#), To_C (16#47#),
To_C (16#9A#), To_C (16#BF#), To_C (16#65#), To_C (16#CC#), To_C (16#7F#),
To_C (16#65#), To_C (16#24#), To_C (16#69#), To_C (16#A6#), To_C (16#E8#),
To_C (16#14#), To_C (16#89#), To_C (16#5B#), To_C (16#E4#), To_C (16#34#),
To_C (16#F7#), To_C (16#C5#), To_C (16#B0#), To_C (16#14#), To_C (16#93#),
To_C (16#F5#), To_C (16#67#), To_C (16#7B#), To_C (16#3A#), To_C (16#7A#),
To_C (16#78#), To_C (16#E1#), To_C (16#01#), To_C (16#56#), To_C (16#56#),
To_C (16#91#), To_C (16#A6#), To_C (16#13#), To_C (16#42#), To_C (16#8D#),
To_C (16#D2#), To_C (16#3C#), To_C (16#40#), To_C (16#9C#), To_C (16#4C#),
To_C (16#EF#), To_C (16#D1#), To_C (16#86#), To_C (16#DF#), To_C (16#37#),
To_C (16#51#), To_C (16#1B#), To_C (16#0C#), To_C (16#A1#), To_C (16#3B#),
To_C (16#F5#), To_C (16#F1#), To_C (16#A3#), To_C (16#4A#), To_C (16#35#),
To_C (16#E4#), To_C (16#E1#), To_C (16#CE#), To_C (16#96#), To_C (16#DF#),
To_C (16#1B#), To_C (16#7E#), To_C (16#BF#), To_C (16#4E#), To_C (16#97#),
To_C (16#D0#), To_C (16#10#), To_C (16#E8#), To_C (16#A8#), To_C (16#08#),
To_C (16#30#), To_C (16#81#), To_C (16#AF#), To_C (16#20#), To_C (16#0B#),
To_C (16#43#), To_C (16#14#), To_C (16#C5#), To_C (16#74#), To_C (16#67#),
To_C (16#B4#), To_C (16#32#), To_C (16#82#), To_C (16#6F#), To_C (16#8D#),
To_C (16#86#), To_C (16#C2#), To_C (16#88#), To_C (16#40#), To_C (16#99#),
To_C (16#36#), To_C (16#83#), To_C (16#BA#), To_C (16#1E#), To_C (16#40#),
To_C (16#72#), To_C (16#22#), To_C (16#17#), To_C (16#D7#), To_C (16#52#),
To_C (16#65#), To_C (16#24#), To_C (16#73#), To_C (16#B0#), To_C (16#CE#),
To_C (16#EF#), To_C (16#19#), To_C (16#CD#), To_C (16#AE#), To_C (16#FF#),
To_C (16#78#), To_C (16#6C#), To_C (16#7B#), To_C (16#C0#), To_C (16#12#),
To_C (16#03#), To_C (16#D4#), To_C (16#4E#), To_C (16#72#), To_C (16#0D#),
To_C (16#50#), To_C (16#6D#), To_C (16#3B#), To_C (16#A3#), To_C (16#3B#),
To_C (16#A3#), To_C (16#99#), To_C (16#5E#), To_C (16#9D#), To_C (16#C8#),
To_C (16#D9#), To_C (16#0C#), To_C (16#85#), To_C (16#B3#), To_C (16#D9#),
To_C (16#8A#), To_C (16#D9#), To_C (16#54#), To_C (16#26#), To_C (16#DB#),
To_C (16#6D#), To_C (16#FA#), To_C (16#AC#), To_C (16#BB#), To_C (16#FF#),
To_C (16#25#), To_C (16#4C#), To_C (16#C4#), To_C (16#D1#), To_C (16#79#),
To_C (16#F4#), To_C (16#71#), To_C (16#D3#), To_C (16#86#), To_C (16#40#),
To_C (16#18#), To_C (16#13#), To_C (16#B0#), To_C (16#63#), To_C (16#B5#),
To_C (16#72#), To_C (16#4E#), To_C (16#30#), To_C (16#C4#), To_C (16#97#),
To_C (16#84#), To_C (16#86#), To_C (16#2D#), To_C (16#56#), To_C (16#2F#),
To_C (16#D7#), To_C (16#15#), To_C (16#F7#), To_C (16#7F#), To_C (16#C0#),
To_C (16#AE#), To_C (16#F5#), To_C (16#FC#), To_C (16#5B#), To_C (16#E5#),
To_C (16#FB#), To_C (16#A1#), To_C (16#BA#), To_C (16#D3#), To_C (16#02#),
To_C (16#03#), To_C (16#01#), To_C (16#00#), To_C (16#01#));
-- Private key (DER) - copied from rsa_verify_main.adb.
--
-- Note: This is long, but keeping it embedded avoids any assumptions about
-- external files and precisely matches the example.
Client_Private_Key_2048 : constant WolfSSL.Byte_Array :=
(To_C (16#30#), To_C (16#82#), To_C (16#04#), To_C (16#A4#), To_C (16#02#),
To_C (16#01#), To_C (16#00#), To_C (16#02#), To_C (16#82#), To_C (16#01#),
To_C (16#01#), To_C (16#00#), To_C (16#C3#), To_C (16#03#), To_C (16#D1#),
To_C (16#2B#), To_C (16#FE#), To_C (16#39#), To_C (16#A4#), To_C (16#32#),
To_C (16#45#), To_C (16#3B#), To_C (16#53#), To_C (16#C8#), To_C (16#84#),
To_C (16#2B#), To_C (16#2A#), To_C (16#7C#), To_C (16#74#), To_C (16#9A#),
To_C (16#BD#), To_C (16#AA#), To_C (16#2A#), To_C (16#52#), To_C (16#07#),
To_C (16#47#), To_C (16#D6#), To_C (16#A6#), To_C (16#36#), To_C (16#B2#),
To_C (16#07#), To_C (16#32#), To_C (16#8E#), To_C (16#D0#), To_C (16#BA#),
To_C (16#69#), To_C (16#7B#), To_C (16#C6#), To_C (16#C3#), To_C (16#44#),
To_C (16#9E#), To_C (16#D4#), To_C (16#81#), To_C (16#48#), To_C (16#FD#),
To_C (16#2D#), To_C (16#68#), To_C (16#A2#), To_C (16#8B#), To_C (16#67#),
To_C (16#BB#), To_C (16#A1#), To_C (16#75#), To_C (16#C8#), To_C (16#36#),
To_C (16#2C#), To_C (16#4A#), To_C (16#D2#), To_C (16#1B#), To_C (16#F7#),
To_C (16#8B#), To_C (16#BA#), To_C (16#CF#), To_C (16#0D#), To_C (16#F9#),
To_C (16#EF#), To_C (16#EC#), To_C (16#F1#), To_C (16#81#), To_C (16#1E#),
To_C (16#7B#), To_C (16#9B#), To_C (16#03#), To_C (16#47#), To_C (16#9A#),
To_C (16#BF#), To_C (16#65#), To_C (16#CC#), To_C (16#7F#), To_C (16#65#),
To_C (16#24#), To_C (16#69#), To_C (16#A6#), To_C (16#E8#), To_C (16#14#),
To_C (16#89#), To_C (16#5B#), To_C (16#E4#), To_C (16#34#), To_C (16#F7#),
To_C (16#C5#), To_C (16#B0#), To_C (16#14#), To_C (16#93#), To_C (16#F5#),
To_C (16#67#), To_C (16#7B#), To_C (16#3A#), To_C (16#7A#), To_C (16#78#),
To_C (16#E1#), To_C (16#01#), To_C (16#56#), To_C (16#56#), To_C (16#91#),
To_C (16#A6#), To_C (16#13#), To_C (16#42#), To_C (16#8D#), To_C (16#D2#),
To_C (16#3C#), To_C (16#40#), To_C (16#9C#), To_C (16#4C#), To_C (16#EF#),
To_C (16#D1#), To_C (16#86#), To_C (16#DF#), To_C (16#37#), To_C (16#51#),
To_C (16#1B#), To_C (16#0C#), To_C (16#A1#), To_C (16#3B#), To_C (16#F5#),
To_C (16#F1#), To_C (16#A3#), To_C (16#4A#), To_C (16#35#), To_C (16#E4#),
To_C (16#E1#), To_C (16#CE#), To_C (16#96#), To_C (16#DF#), To_C (16#1B#),
To_C (16#7E#), To_C (16#BF#), To_C (16#4E#), To_C (16#97#), To_C (16#D0#),
To_C (16#10#), To_C (16#E8#), To_C (16#A8#), To_C (16#08#), To_C (16#30#),
To_C (16#81#), To_C (16#AF#), To_C (16#20#), To_C (16#0B#), To_C (16#43#),
To_C (16#14#), To_C (16#C5#), To_C (16#74#), To_C (16#67#), To_C (16#B4#),
To_C (16#32#), To_C (16#82#), To_C (16#6F#), To_C (16#8D#), To_C (16#86#),
To_C (16#C2#), To_C (16#88#), To_C (16#40#), To_C (16#99#), To_C (16#36#),
To_C (16#83#), To_C (16#BA#), To_C (16#1E#), To_C (16#40#), To_C (16#72#),
To_C (16#22#), To_C (16#17#), To_C (16#D7#), To_C (16#52#), To_C (16#65#),
To_C (16#24#), To_C (16#73#), To_C (16#B0#), To_C (16#CE#), To_C (16#EF#),
To_C (16#19#), To_C (16#CD#), To_C (16#AE#), To_C (16#FF#), To_C (16#78#),
To_C (16#6C#), To_C (16#7B#), To_C (16#C0#), To_C (16#12#), To_C (16#03#),
To_C (16#D4#), To_C (16#4E#), To_C (16#72#), To_C (16#0D#), To_C (16#50#),
To_C (16#6D#), To_C (16#3B#), To_C (16#A3#), To_C (16#3B#), To_C (16#A3#),
To_C (16#99#), To_C (16#5E#), To_C (16#9D#), To_C (16#C8#), To_C (16#D9#),
To_C (16#0C#), To_C (16#85#), To_C (16#B3#), To_C (16#D9#), To_C (16#8A#),
To_C (16#D9#), To_C (16#54#), To_C (16#26#), To_C (16#DB#), To_C (16#6D#),
To_C (16#FA#), To_C (16#AC#), To_C (16#BB#), To_C (16#FF#), To_C (16#25#),
To_C (16#4C#), To_C (16#C4#), To_C (16#D1#), To_C (16#79#), To_C (16#F4#),
To_C (16#71#), To_C (16#D3#), To_C (16#86#), To_C (16#40#), To_C (16#18#),
To_C (16#13#), To_C (16#B0#), To_C (16#63#), To_C (16#B5#), To_C (16#72#),
To_C (16#4E#), To_C (16#30#), To_C (16#C4#), To_C (16#97#), To_C (16#84#),
To_C (16#86#), To_C (16#2D#), To_C (16#56#), To_C (16#2F#), To_C (16#D7#),
To_C (16#15#), To_C (16#F7#), To_C (16#7F#), To_C (16#C0#), To_C (16#AE#),
To_C (16#F5#), To_C (16#FC#), To_C (16#5B#), To_C (16#E5#), To_C (16#FB#),
To_C (16#A1#), To_C (16#BA#), To_C (16#D3#), To_C (16#02#), To_C (16#03#),
To_C (16#01#), To_C (16#00#), To_C (16#01#), To_C (16#02#), To_C (16#82#),
To_C (16#01#), To_C (16#01#), To_C (16#00#), To_C (16#A2#), To_C (16#E6#),
To_C (16#D8#), To_C (16#5F#), To_C (16#10#), To_C (16#71#), To_C (16#64#),
To_C (16#08#), To_C (16#9E#), To_C (16#2E#), To_C (16#6D#), To_C (16#D1#),
To_C (16#6D#), To_C (16#1E#), To_C (16#85#), To_C (16#D2#), To_C (16#0A#),
To_C (16#B1#), To_C (16#8C#), To_C (16#47#), To_C (16#CE#), To_C (16#2C#),
To_C (16#51#), To_C (16#6A#), To_C (16#A0#), To_C (16#12#), To_C (16#9E#),
To_C (16#53#), To_C (16#DE#), To_C (16#91#), To_C (16#4C#), To_C (16#1D#),
To_C (16#6D#), To_C (16#EA#), To_C (16#59#), To_C (16#7B#), To_C (16#F2#),
To_C (16#77#), To_C (16#AA#), To_C (16#D9#), To_C (16#C6#), To_C (16#D9#),
To_C (16#8A#), To_C (16#AB#), To_C (16#D8#), To_C (16#E1#), To_C (16#16#),
To_C (16#E4#), To_C (16#63#), To_C (16#26#), To_C (16#FF#), To_C (16#B5#),
To_C (16#6C#), To_C (16#13#), To_C (16#59#), To_C (16#B8#), To_C (16#E3#),
To_C (16#A5#), To_C (16#C8#), To_C (16#72#), To_C (16#17#), To_C (16#2E#),
To_C (16#0C#), To_C (16#9F#), To_C (16#6F#), To_C (16#E5#), To_C (16#59#),
To_C (16#3F#), To_C (16#76#), To_C (16#6F#), To_C (16#49#), To_C (16#B1#),
To_C (16#11#), To_C (16#C2#), To_C (16#5A#), To_C (16#2E#), To_C (16#16#),
To_C (16#29#), To_C (16#0D#), To_C (16#DE#), To_C (16#B7#), To_C (16#8E#),
To_C (16#DC#), To_C (16#40#), To_C (16#D5#), To_C (16#A2#), To_C (16#EE#),
To_C (16#E0#), To_C (16#1E#), To_C (16#A1#), To_C (16#F4#), To_C (16#BE#),
To_C (16#97#), To_C (16#DB#), To_C (16#86#), To_C (16#63#), To_C (16#96#),
To_C (16#14#), To_C (16#CD#), To_C (16#98#), To_C (16#09#), To_C (16#60#),
To_C (16#2D#), To_C (16#30#), To_C (16#76#), To_C (16#9C#), To_C (16#3C#),
To_C (16#CD#), To_C (16#E6#), To_C (16#88#), To_C (16#EE#), To_C (16#47#),
To_C (16#92#), To_C (16#79#), To_C (16#0B#), To_C (16#5A#), To_C (16#00#),
To_C (16#E2#), To_C (16#5E#), To_C (16#5F#), To_C (16#11#), To_C (16#7C#),
To_C (16#7D#), To_C (16#F9#), To_C (16#08#), To_C (16#B7#), To_C (16#20#),
To_C (16#06#), To_C (16#89#), To_C (16#2A#), To_C (16#5D#), To_C (16#FD#),
To_C (16#00#), To_C (16#AB#), To_C (16#22#), To_C (16#E1#), To_C (16#F0#),
To_C (16#B3#), To_C (16#BC#), To_C (16#24#), To_C (16#A9#), To_C (16#5E#),
To_C (16#26#), To_C (16#0E#), To_C (16#1F#), To_C (16#00#), To_C (16#2D#),
To_C (16#FE#), To_C (16#21#), To_C (16#9A#), To_C (16#53#), To_C (16#5B#),
To_C (16#6D#), To_C (16#D3#), To_C (16#2B#), To_C (16#AB#), To_C (16#94#),
To_C (16#82#), To_C (16#68#), To_C (16#43#), To_C (16#36#), To_C (16#D8#),
To_C (16#F6#), To_C (16#2F#), To_C (16#C6#), To_C (16#22#), To_C (16#FC#),
To_C (16#B5#), To_C (16#41#), To_C (16#5D#), To_C (16#0D#), To_C (16#33#),
To_C (16#60#), To_C (16#EA#), To_C (16#A4#), To_C (16#7D#), To_C (16#7E#),
To_C (16#E8#), To_C (16#4B#), To_C (16#55#), To_C (16#91#), To_C (16#56#),
To_C (16#D3#), To_C (16#5C#), To_C (16#57#), To_C (16#8F#), To_C (16#1F#),
To_C (16#94#), To_C (16#17#), To_C (16#2F#), To_C (16#AA#), To_C (16#DE#),
To_C (16#E9#), To_C (16#9E#), To_C (16#A8#), To_C (16#F4#), To_C (16#CF#),
To_C (16#8A#), To_C (16#4C#), To_C (16#8E#), To_C (16#A0#), To_C (16#E4#),
To_C (16#56#), To_C (16#73#), To_C (16#B2#), To_C (16#CF#), To_C (16#4F#),
To_C (16#86#), To_C (16#C5#), To_C (16#69#), To_C (16#3C#), To_C (16#F3#),
To_C (16#24#), To_C (16#20#), To_C (16#8B#), To_C (16#5C#), To_C (16#96#),
To_C (16#0C#), To_C (16#FA#), To_C (16#6B#), To_C (16#12#), To_C (16#3B#),
To_C (16#9A#), To_C (16#67#), To_C (16#C1#), To_C (16#DF#), To_C (16#C6#),
To_C (16#96#), To_C (16#B2#), To_C (16#A5#), To_C (16#D5#), To_C (16#92#),
To_C (16#0D#), To_C (16#9B#), To_C (16#09#), To_C (16#42#), To_C (16#68#),
To_C (16#24#), To_C (16#10#), To_C (16#45#), To_C (16#D4#), To_C (16#50#),
To_C (16#E4#), To_C (16#17#), To_C (16#39#), To_C (16#48#), To_C (16#D0#),
To_C (16#35#), To_C (16#8B#), To_C (16#94#), To_C (16#6D#), To_C (16#11#),
To_C (16#DE#), To_C (16#8F#), To_C (16#CA#), To_C (16#59#), To_C (16#02#),
To_C (16#81#), To_C (16#81#), To_C (16#00#), To_C (16#EA#), To_C (16#24#),
To_C (16#A7#), To_C (16#F9#), To_C (16#69#), To_C (16#33#), To_C (16#E9#),
To_C (16#71#), To_C (16#DC#), To_C (16#52#), To_C (16#7D#), To_C (16#88#),
To_C (16#21#), To_C (16#28#), To_C (16#2F#), To_C (16#49#), To_C (16#DE#),
To_C (16#BA#), To_C (16#72#), To_C (16#16#), To_C (16#E9#), To_C (16#CC#),
To_C (16#47#), To_C (16#7A#), To_C (16#88#), To_C (16#0D#), To_C (16#94#),
To_C (16#57#), To_C (16#84#), To_C (16#58#), To_C (16#16#), To_C (16#3A#),
To_C (16#81#), To_C (16#B0#), To_C (16#3F#), To_C (16#A2#), To_C (16#CF#),
To_C (16#A6#), To_C (16#6C#), To_C (16#1E#), To_C (16#B0#), To_C (16#06#),
To_C (16#29#), To_C (16#00#), To_C (16#8F#), To_C (16#E7#), To_C (16#77#),
To_C (16#76#), To_C (16#AC#), To_C (16#DB#), To_C (16#CA#), To_C (16#C7#),
To_C (16#D9#), To_C (16#5E#), To_C (16#9B#), To_C (16#3F#), To_C (16#26#),
To_C (16#90#), To_C (16#52#), To_C (16#AE#), To_C (16#FC#), To_C (16#38#),
To_C (16#90#), To_C (16#00#), To_C (16#14#), To_C (16#BB#), To_C (16#B4#),
To_C (16#0F#), To_C (16#58#), To_C (16#94#), To_C (16#E7#), To_C (16#2F#),
To_C (16#6A#), To_C (16#7E#), To_C (16#1C#), To_C (16#4F#), To_C (16#41#),
To_C (16#21#), To_C (16#D4#), To_C (16#31#), To_C (16#59#), To_C (16#1F#),
To_C (16#4E#), To_C (16#8A#), To_C (16#1A#), To_C (16#8D#), To_C (16#A7#),
To_C (16#57#), To_C (16#6C#), To_C (16#22#), To_C (16#D8#), To_C (16#E5#),
To_C (16#F4#), To_C (16#7E#), To_C (16#32#), To_C (16#A6#), To_C (16#10#),
To_C (16#CB#), To_C (16#64#), To_C (16#A5#), To_C (16#55#), To_C (16#03#),
To_C (16#87#), To_C (16#A6#), To_C (16#27#), To_C (16#05#), To_C (16#8C#),
To_C (16#C3#), To_C (16#D7#), To_C (16#B6#), To_C (16#27#), To_C (16#B2#),
To_C (16#4D#), To_C (16#BA#), To_C (16#30#), To_C (16#DA#), To_C (16#47#),
To_C (16#8F#), To_C (16#54#), To_C (16#D3#), To_C (16#3D#), To_C (16#8B#),
To_C (16#84#), To_C (16#8D#), To_C (16#94#), To_C (16#98#), To_C (16#58#),
To_C (16#A5#), To_C (16#02#), To_C (16#81#), To_C (16#81#), To_C (16#00#),
To_C (16#D5#), To_C (16#38#), To_C (16#1B#), To_C (16#C3#), To_C (16#8F#),
To_C (16#C5#), To_C (16#93#), To_C (16#0C#), To_C (16#47#), To_C (16#0B#),
To_C (16#6F#), To_C (16#35#), To_C (16#92#), To_C (16#C5#), To_C (16#B0#),
To_C (16#8D#), To_C (16#46#), To_C (16#C8#), To_C (16#92#), To_C (16#18#),
To_C (16#8F#), To_C (16#F5#), To_C (16#80#), To_C (16#0A#), To_C (16#F7#),
To_C (16#EF#), To_C (16#A1#), To_C (16#FE#), To_C (16#80#), To_C (16#B9#),
To_C (16#B5#), To_C (16#2A#), To_C (16#BA#), To_C (16#CA#), To_C (16#18#),
To_C (16#B0#), To_C (16#5D#), To_C (16#A5#), To_C (16#07#), To_C (16#D0#),
To_C (16#93#), To_C (16#8D#), To_C (16#D8#), To_C (16#9C#), To_C (16#04#),
To_C (16#1C#), To_C (16#D4#), To_C (16#62#), To_C (16#8E#), To_C (16#A6#),
To_C (16#26#), To_C (16#81#), To_C (16#01#), To_C (16#FF#), To_C (16#CE#),
To_C (16#8A#), To_C (16#2A#), To_C (16#63#), To_C (16#34#), To_C (16#35#),
To_C (16#40#), To_C (16#AA#), To_C (16#6D#), To_C (16#80#), To_C (16#DE#),
To_C (16#89#), To_C (16#23#), To_C (16#6A#), To_C (16#57#), To_C (16#4D#),
To_C (16#9E#), To_C (16#6E#), To_C (16#AD#), To_C (16#93#), To_C (16#4E#),
To_C (16#56#), To_C (16#90#), To_C (16#0B#), To_C (16#6D#), To_C (16#9D#),
To_C (16#73#), To_C (16#8B#), To_C (16#0C#), To_C (16#AE#), To_C (16#27#),
To_C (16#3D#), To_C (16#DE#), To_C (16#4E#), To_C (16#F0#), To_C (16#AA#),
To_C (16#C5#), To_C (16#6C#), To_C (16#78#), To_C (16#67#), To_C (16#6C#),
To_C (16#94#), To_C (16#52#), To_C (16#9C#), To_C (16#37#), To_C (16#67#),
To_C (16#6C#), To_C (16#2D#), To_C (16#EF#), To_C (16#BB#), To_C (16#AF#),
To_C (16#DF#), To_C (16#A6#), To_C (16#90#), To_C (16#3C#), To_C (16#C4#),
To_C (16#47#), To_C (16#CF#), To_C (16#8D#), To_C (16#96#), To_C (16#9E#),
To_C (16#98#), To_C (16#A9#), To_C (16#B4#), To_C (16#9F#), To_C (16#C5#),
To_C (16#A6#), To_C (16#50#), To_C (16#DC#), To_C (16#B3#), To_C (16#F0#),
To_C (16#FB#), To_C (16#74#), To_C (16#17#), To_C (16#02#), To_C (16#81#),
To_C (16#80#), To_C (16#5E#), To_C (16#83#), To_C (16#09#), To_C (16#62#),
To_C (16#BD#), To_C (16#BA#), To_C (16#7C#), To_C (16#A2#), To_C (16#BF#),
To_C (16#42#), To_C (16#74#), To_C (16#F5#), To_C (16#7C#), To_C (16#1C#),
To_C (16#D2#), To_C (16#69#), To_C (16#C9#), To_C (16#04#), To_C (16#0D#),
To_C (16#85#), To_C (16#7E#), To_C (16#3E#), To_C (16#3D#), To_C (16#24#),
To_C (16#12#), To_C (16#C3#), To_C (16#18#), To_C (16#7B#), To_C (16#F3#),
To_C (16#29#), To_C (16#F3#), To_C (16#5F#), To_C (16#0E#), To_C (16#76#),
To_C (16#6C#), To_C (16#59#), To_C (16#75#), To_C (16#E4#), To_C (16#41#),
To_C (16#84#), To_C (16#69#), To_C (16#9D#), To_C (16#32#), To_C (16#F3#),
To_C (16#CD#), To_C (16#22#), To_C (16#AB#), To_C (16#B0#), To_C (16#35#),
To_C (16#BA#), To_C (16#4A#), To_C (16#B2#), To_C (16#3C#), To_C (16#E5#),
To_C (16#D9#), To_C (16#58#), To_C (16#B6#), To_C (16#62#), To_C (16#4F#),
To_C (16#5D#), To_C (16#DE#), To_C (16#E5#), To_C (16#9E#), To_C (16#0A#),
To_C (16#CA#), To_C (16#53#), To_C (16#B2#), To_C (16#2C#), To_C (16#F7#),
To_C (16#9E#), To_C (16#B3#), To_C (16#6B#), To_C (16#0A#), To_C (16#5B#),
To_C (16#79#), To_C (16#65#), To_C (16#EC#), To_C (16#6E#), To_C (16#91#),
To_C (16#4E#), To_C (16#92#), To_C (16#20#), To_C (16#F6#), To_C (16#FC#),
To_C (16#FC#), To_C (16#16#), To_C (16#ED#), To_C (16#D3#), To_C (16#76#),
To_C (16#0C#), To_C (16#E2#), To_C (16#EC#), To_C (16#7F#), To_C (16#B2#),
To_C (16#69#), To_C (16#13#), To_C (16#6B#), To_C (16#78#), To_C (16#0E#),
To_C (16#5A#), To_C (16#46#), To_C (16#64#), To_C (16#B4#), To_C (16#5E#),
To_C (16#B7#), To_C (16#25#), To_C (16#A0#), To_C (16#5A#), To_C (16#75#),
To_C (16#3A#), To_C (16#4B#), To_C (16#EF#), To_C (16#C7#), To_C (16#3C#),
To_C (16#3E#), To_C (16#F7#), To_C (16#FD#), To_C (16#26#), To_C (16#B8#),
To_C (16#20#), To_C (16#C4#), To_C (16#99#), To_C (16#0A#), To_C (16#9A#),
To_C (16#73#), To_C (16#BE#), To_C (16#C3#), To_C (16#19#), To_C (16#02#),
To_C (16#81#), To_C (16#81#), To_C (16#00#), To_C (16#BA#), To_C (16#44#),
To_C (16#93#), To_C (16#14#), To_C (16#AC#), To_C (16#34#), To_C (16#19#),
To_C (16#3B#), To_C (16#5F#), To_C (16#91#), To_C (16#60#), To_C (16#AC#),
To_C (16#F7#), To_C (16#B4#), To_C (16#D6#), To_C (16#81#), To_C (16#05#),
To_C (16#36#), To_C (16#51#), To_C (16#53#), To_C (16#3D#), To_C (16#E8#),
To_C (16#65#), To_C (16#DC#), To_C (16#AF#), To_C (16#2E#), To_C (16#DC#),
To_C (16#61#), To_C (16#3E#), To_C (16#C9#), To_C (16#7D#), To_C (16#B8#),
To_C (16#7F#), To_C (16#87#), To_C (16#F0#), To_C (16#3B#), To_C (16#9B#),
To_C (16#03#), To_C (16#82#), To_C (16#29#), To_C (16#37#), To_C (16#CE#),
To_C (16#72#), To_C (16#4E#), To_C (16#11#), To_C (16#D5#), To_C (16#B1#),
To_C (16#C1#), To_C (16#0C#), To_C (16#07#), To_C (16#A0#), To_C (16#99#),
To_C (16#91#), To_C (16#4A#), To_C (16#8D#), To_C (16#7F#), To_C (16#EC#),
To_C (16#79#), To_C (16#CF#), To_C (16#F1#), To_C (16#39#), To_C (16#B5#),
To_C (16#E9#), To_C (16#85#), To_C (16#EC#), To_C (16#62#), To_C (16#F7#),
To_C (16#DA#), To_C (16#7D#), To_C (16#BC#), To_C (16#64#), To_C (16#4D#),
To_C (16#22#), To_C (16#3C#), To_C (16#0E#), To_C (16#F2#), To_C (16#D6#),
To_C (16#51#), To_C (16#F5#), To_C (16#87#), To_C (16#D8#), To_C (16#99#),
To_C (16#C0#), To_C (16#11#), To_C (16#20#), To_C (16#5D#), To_C (16#0F#),
To_C (16#29#), To_C (16#FD#), To_C (16#5B#), To_C (16#E2#), To_C (16#AE#),
To_C (16#D9#), To_C (16#1C#), To_C (16#D9#), To_C (16#21#), To_C (16#56#),
To_C (16#6D#), To_C (16#FC#), To_C (16#84#), To_C (16#D0#), To_C (16#5F#),
To_C (16#ED#), To_C (16#10#), To_C (16#15#), To_C (16#1C#), To_C (16#18#),
To_C (16#21#), To_C (16#E7#), To_C (16#C4#), To_C (16#3D#), To_C (16#4B#),
To_C (16#D7#), To_C (16#D0#), To_C (16#9E#), To_C (16#6A#), To_C (16#95#),
To_C (16#CF#), To_C (16#22#), To_C (16#C9#), To_C (16#03#), To_C (16#7B#),
To_C (16#9E#), To_C (16#E3#), To_C (16#60#), To_C (16#01#), To_C (16#FC#),
To_C (16#2F#), To_C (16#02#), To_C (16#81#), To_C (16#80#), To_C (16#11#),
To_C (16#D0#), To_C (16#4B#), To_C (16#CF#), To_C (16#1B#), To_C (16#67#),
To_C (16#B9#), To_C (16#9F#), To_C (16#10#), To_C (16#75#), To_C (16#47#),
To_C (16#86#), To_C (16#65#), To_C (16#AE#), To_C (16#31#), To_C (16#C2#),
To_C (16#C6#), To_C (16#30#), To_C (16#AC#), To_C (16#59#), To_C (16#06#),
To_C (16#50#), To_C (16#D9#), To_C (16#0F#), To_C (16#B5#), To_C (16#70#),
To_C (16#06#), To_C (16#F7#), To_C (16#F0#), To_C (16#D3#), To_C (16#C8#),
To_C (16#62#), To_C (16#7C#), To_C (16#A8#), To_C (16#DA#), To_C (16#6E#),
To_C (16#F6#), To_C (16#21#), To_C (16#3F#), To_C (16#D3#), To_C (16#7F#),
To_C (16#5F#), To_C (16#EA#), To_C (16#8A#), To_C (16#AB#), To_C (16#3F#),
To_C (16#D9#), To_C (16#2A#), To_C (16#5E#), To_C (16#F3#), To_C (16#51#),
To_C (16#D2#), To_C (16#C2#), To_C (16#30#), To_C (16#37#), To_C (16#E3#),
To_C (16#2D#), To_C (16#A3#), To_C (16#75#), To_C (16#0D#), To_C (16#1E#),
To_C (16#4D#), To_C (16#21#), To_C (16#34#), To_C (16#D5#), To_C (16#57#),
To_C (16#70#), To_C (16#5C#), To_C (16#89#), To_C (16#BF#), To_C (16#72#),
To_C (16#EC#), To_C (16#4A#), To_C (16#6E#), To_C (16#68#), To_C (16#D5#),
To_C (16#CD#), To_C (16#18#), To_C (16#74#), To_C (16#33#), To_C (16#4E#),
To_C (16#8C#), To_C (16#3A#), To_C (16#45#), To_C (16#8F#), To_C (16#E6#),
To_C (16#96#), To_C (16#40#), To_C (16#EB#), To_C (16#63#), To_C (16#F9#),
To_C (16#19#), To_C (16#86#), To_C (16#3A#), To_C (16#51#), To_C (16#DD#),
To_C (16#89#), To_C (16#4B#), To_C (16#B0#), To_C (16#F3#), To_C (16#F9#),
To_C (16#9F#), To_C (16#5D#), To_C (16#28#), To_C (16#95#), To_C (16#38#),
To_C (16#BE#), To_C (16#35#), To_C (16#AB#), To_C (16#CA#), To_C (16#5C#),
To_C (16#E7#), To_C (16#93#), To_C (16#53#), To_C (16#34#), To_C (16#A1#),
To_C (16#45#), To_C (16#5D#), To_C (16#13#), To_C (16#39#), To_C (16#65#),
To_C (16#42#), To_C (16#46#), To_C (16#A1#), To_C (16#9F#), To_C (16#CD#),
To_C (16#F5#), To_C (16#BF#));
Original_AES_Key : constant WolfSSL.Byte_Array (1 .. 32) :=
"Thisismyfakeaeskeythatis32bytes!";
procedure Test_RSA_Sign_Verify_And_Encrypt_Decrypt (F : in out Fixture) is
pragma Unreferenced (F);
RNG : WolfSSL.RNG_Type;
RSA_Encrypt_Key : WolfSSL.RSA_Key_Type;
RSA_Decrypt_Key : WolfSSL.RSA_Key_Type;
Digital_Signature_Of_AES_Key : WolfSSL.Byte_Array (1 .. 256);
Decrypted_Digital_Signature : WolfSSL.Byte_Array (1 .. 256);
Encrypted : WolfSSL.Byte_Array (1 .. 1_024);
Decrypted : WolfSSL.Byte_Array (1 .. 1_024);
Index : WolfSSL.Byte_Index;
R : Integer;
begin
WolfSSL.Create_RNG (Key => RNG,
Result => R);
AUnit.Assertions.Assert (R = 0, "Create_RNG failed, Result =" &
Integer'Image (R));
WolfSSL.Create_RSA (Key => RSA_Encrypt_Key,
Result => R);
AUnit.Assertions.Assert (R = 0, "Create_RSA (private) failed, Result =" &
Integer'Image (R));
WolfSSL.Rsa_Set_RNG (Key => RSA_Encrypt_Key,
RNG => RNG,
Result => R);
AUnit.Assertions.Assert (R = 0, "Rsa_Set_RNG failed, Result =" &
Integer'Image (R));
Index := Client_Private_Key_2048'First;
WolfSSL.Rsa_Private_Key_Decode (Input => Client_Private_Key_2048,
Index => Index,
Key => RSA_Encrypt_Key,
Size => Client_Private_Key_2048'Length,
Result => R);
AUnit.Assertions.Assert (R = 0, "Rsa_Private_Key_Decode failed, Result =" &
Integer'Image (R));
WolfSSL.Rsa_SSL_Sign (Input => Original_AES_Key,
Output => Digital_Signature_Of_AES_Key,
RSA => RSA_Encrypt_Key,
RNG => RNG,
Result => R);
AUnit.Assertions.Assert (R > 0,
"Rsa_SSL_Sign failed, Result =" &
Integer'Image (R));
WolfSSL.Create_RSA (Key => RSA_Decrypt_Key,
Result => R);
AUnit.Assertions.Assert (R = 0, "Create_RSA (public) failed, Result =" &
Integer'Image (R));
Index := Rsa_Public_Key_2048'First;
WolfSSL.Rsa_Public_Key_Decode (Input => Rsa_Public_Key_2048,
Index => Index,
Key => RSA_Decrypt_Key,
Size => Rsa_Public_Key_2048'Length,
Result => R);
AUnit.Assertions.Assert (R = 0, "Rsa_Public_Key_Decode failed, Result =" &
Integer'Image (R));
WolfSSL.Rsa_SSL_Verify (Input => Digital_Signature_Of_AES_Key,
Output => Decrypted_Digital_Signature,
RSA => RSA_Decrypt_Key,
Result => R);
AUnit.Assertions.Assert (R > 0,
"Rsa_SSL_Verify failed, Result =" &
Integer'Image (R));
-- Basic sanity: verify decrypted signature begins with the plaintext input.
-- The example does not explicitly check this; it only checks success.
AUnit.Assertions.Assert
(Decrypted_Digital_Signature (1 .. Original_AES_Key'Length) =
Original_AES_Key,
"Verified signature payload does not match original input");
WolfSSL.RSA_Public_Encrypt (Input => Original_AES_Key,
Output => Encrypted,
Index => Index,
RSA => RSA_Decrypt_Key,
RNG => RNG,
Result => R);
AUnit.Assertions.Assert (R > 0,
"RSA_Public_Encrypt failed, Result =" &
Integer'Image (R));
AUnit.Assertions.Assert (Index > 0,
"RSA_Public_Encrypt returned Index = 0");
WolfSSL.RSA_Private_Decrypt (Input => Encrypted (1 .. Index),
Output => Decrypted,
Index => Index,
RSA => RSA_Encrypt_Key,
Result => R);
AUnit.Assertions.Assert (R > 0,
"RSA_Private_Decrypt failed, Result =" &
Integer'Image (R));
AUnit.Assertions.Assert (Integer (Index) = 32,
"RSA_Private_Decrypt output length mismatch, got" &
Integer'Image (Integer (Index)));
AUnit.Assertions.Assert (Decrypted (1 .. 32) = Original_AES_Key,
"RSA decrypt result does not equal original key");
-- Ensure RSA key resources are released (RSA is now dynamically allocated).
WolfSSL.Free_RSA (Key => RSA_Encrypt_Key);
WolfSSL.Free_RSA (Key => RSA_Decrypt_Key);
-- Ensure RNG resources are released (RNG is now dynamically allocated).
-- Must be done after all operations that use RNG / depend on it.
WolfSSL.Free_RNG (Key => RNG);
end Test_RSA_Sign_Verify_And_Encrypt_Decrypt;
package Caller is new AUnit.Test_Caller (Fixture);
Suite_Object : aliased AUnit.Test_Suites.Test_Suite;
function Suite return AUnit.Test_Suites.Access_Test_Suite is
begin
return Suite_Object'Access;
end Suite;
begin
-- Register RSA tests once at elaboration time.
AUnit.Test_Suites.Add_Test
(Suite_Object'Access,
Caller.Create
(Name => "RSA sign/verify and encrypt/decrypt (rsa_verify_main)",
Test => Test_RSA_Sign_Verify_And_Encrypt_Decrypt'Access));
end RSA_Verify_Bindings_Tests;

View File

@@ -0,0 +1,23 @@
with AUnit.Test_Suites;
package RSA_Verify_Bindings_Tests is
-- Tests derived from `rsa_verify_main.adb` example.
--
-- Intended coverage (bindings exercised):
-- - Create_RNG
-- - Create_RSA
-- - Rsa_Set_RNG
-- - Rsa_Private_Key_Decode
-- - Rsa_Public_Key_Decode
-- - Rsa_SSL_Sign
-- - Rsa_SSL_Verify
-- - RSA_Public_Encrypt
-- - RSA_Private_Decrypt
--
-- The implementation will use the exact embedded DER keys and test vectors
-- from the example to avoid assumptions about external files.
function Suite return AUnit.Test_Suites.Access_Test_Suite;
end RSA_Verify_Bindings_Tests;

View File

@@ -0,0 +1,146 @@
with AUnit.Assertions;
with AUnit.Test_Caller;
with WolfSSL;
with Test_Support;
package body SHA256_Bindings_Tests is
----------------------------------------------------------------------------
-- Helpers
----------------------------------------------------------------------------
procedure Compute_SHA256
(Input : WolfSSL.Byte_Array;
Hash : out WolfSSL.SHA256_Hash;
Result : out Integer)
is
SHA256 : WolfSSL.SHA256_Type;
R : Integer;
begin
-- SHA256 instances are dynamically allocated; no index is required.
WolfSSL.Create_SHA256 (SHA256 => SHA256, Result => R);
if R /= 0 then
Result := R;
return;
end if;
WolfSSL.Update_SHA256 (SHA256 => SHA256, Byte => Input, Result => R);
if R /= 0 then
Result := R;
WolfSSL.Free_SHA256 (SHA256 => SHA256);
return;
end if;
WolfSSL.Finalize_SHA256
(SHA256 => SHA256,
Hash => Hash,
Result => R);
Result := R;
WolfSSL.Free_SHA256 (SHA256 => SHA256);
end Compute_SHA256;
----------------------------------------------------------------------------
-- Tests
----------------------------------------------------------------------------
procedure Test_SHA256_Asdf_Known_Vector (F : in out Fixture) is
pragma Unreferenced (F);
Hash : WolfSSL.SHA256_Hash;
R : Integer;
Input : constant WolfSSL.Byte_Array := Test_Support.Bytes ("asdf");
Expected_Hash : constant WolfSSL.Byte_Array :=
Test_Support.Hex_Bytes
(Test_Support.SHA256_Text
("F0E4C2F76C58916EC258F246851BEA091D14D4247A2FC3E18694461B1816E13B"));
begin
Compute_SHA256 (Input => Input, Hash => Hash, Result => R);
Test_Support.Assert_Success (R, "SHA256(asdf)");
-- Compare the hash bytes
declare
use type WolfSSL.Byte_Array;
Hash_Bytes : WolfSSL.Byte_Array (Expected_Hash'Range);
J : WolfSSL.Byte_Index := Expected_Hash'First;
begin
for I in Hash'Range loop
Hash_Bytes (J) := Hash (I);
J := WolfSSL.Byte_Index'Succ (J);
end loop;
AUnit.Assertions.Assert
(Hash_Bytes = Expected_Hash,
"SHA256('asdf') hash mismatch");
end;
end Test_SHA256_Asdf_Known_Vector;
procedure Test_SHA256_Empty_Message (F : in out Fixture) is
pragma Unreferenced (F);
Hash : WolfSSL.SHA256_Hash;
R : Integer;
-- Represent empty input as a null range, matching the existing test style.
Empty : constant WolfSSL.Byte_Array := (1 .. 0 => <>);
Expected_Hash : constant WolfSSL.Byte_Array :=
Test_Support.Hex_Bytes
(Test_Support.SHA256_Text
("E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855"));
begin
Compute_SHA256 (Input => Empty, Hash => Hash, Result => R);
Test_Support.Assert_Success (R, "SHA256(empty)");
-- Compare the hash bytes
declare
use type WolfSSL.Byte_Array;
Hash_Bytes : WolfSSL.Byte_Array (1 .. 32);
J : WolfSSL.Byte_Index := 1;
begin
for I in Hash'Range loop
Hash_Bytes (J) := Hash (I);
J := WolfSSL.Byte_Index'Succ (J);
end loop;
AUnit.Assertions.Assert
(Hash_Bytes = Expected_Hash,
"SHA256('') hash mismatch");
end;
end Test_SHA256_Empty_Message;
----------------------------------------------------------------------------
-- Statically allocated suite object; register tests at elaboration time
----------------------------------------------------------------------------
package Caller is new AUnit.Test_Caller (Fixture);
Suite_Object : aliased AUnit.Test_Suites.Test_Suite;
function Suite return AUnit.Test_Suites.Access_Test_Suite is
begin
return Suite_Object'Access;
end Suite;
begin
-- Register SHA256-related tests once at elaboration time.
-- Note: Caller.Create returns an access value; AUnit may still allocate
-- the test-case objects internally. This keeps the suite itself static.
AUnit.Test_Suites.Add_Test
(Suite_Object'Access,
Caller.Create
(Name => "SHA256('asdf') produces expected hash",
Test => Test_SHA256_Asdf_Known_Vector'Access));
AUnit.Test_Suites.Add_Test
(Suite_Object'Access,
Caller.Create
(Name => "SHA256('') produces expected hash",
Test => Test_SHA256_Empty_Message'Access));
end SHA256_Bindings_Tests;

View File

@@ -0,0 +1,24 @@
with AUnit.Test_Fixtures;
with AUnit.Test_Suites;
package SHA256_Bindings_Tests is
-- Tests for the WolfSSL SHA256 Ada bindings:
-- - Create_SHA256
-- - Update_SHA256
-- - Finalize_SHA256
--
-- This package follows AUnit's "Test_Caller" model (not Test_Cases with
-- Registration) to avoid depending on optional child units and to keep the
-- boilerplate small.
--
-- Suite returns a suite containing all SHA256-related tests.
type Fixture is new AUnit.Test_Fixtures.Test_Fixture with null record;
procedure Test_SHA256_Asdf_Known_Vector (F : in out Fixture);
procedure Test_SHA256_Empty_Message (F : in out Fixture);
function Suite return AUnit.Test_Suites.Access_Test_Suite;
end SHA256_Bindings_Tests;

View File

@@ -0,0 +1,121 @@
with AUnit.Assertions;
package body Test_Support is
----------------------------------------------------------------------------
-- Assertions
----------------------------------------------------------------------------
procedure Assert_Success (Result : Integer; What : String) is
begin
AUnit.Assertions.Assert
(Result = 0,
What & " failed, Result = " & Integer'Image (Result));
end Assert_Success;
----------------------------------------------------------------------------
-- Data helpers
----------------------------------------------------------------------------
function Bytes (S : String) return WolfSSL.Byte_Array is
-- WolfSSL.Byte_Array is Interfaces.C.char_array indexed by
-- WolfSSL.Byte_Index (size_t). Avoid doing arithmetic directly on that
-- index type; instead, use Natural for arithmetic and convert at the
-- point of indexing.
begin
if S'Length = 0 then
-- Return a null range for empty input
declare
Empty : WolfSSL.Byte_Array (1 .. 0);
begin
return Empty;
end;
end if;
declare
Last_N : constant Natural := S'Length - 1;
B : WolfSSL.Byte_Array (0 .. WolfSSL.Byte_Index (Last_N));
N : Natural := 0;
begin
for C of S loop
B (WolfSSL.Byte_Index (N)) :=
WolfSSL.Byte_Type'Val (Character'Pos (C));
N := N + 1;
end loop;
return B;
end;
end Bytes;
function Hex_Value (C : Character) return Natural is
begin
case C is
when '0' .. '9' =>
return Character'Pos (C) - Character'Pos ('0');
when 'A' .. 'F' =>
return 10 + (Character'Pos (C) - Character'Pos ('A'));
when 'a' .. 'f' =>
return 10 + (Character'Pos (C) - Character'Pos ('a'));
when others =>
AUnit.Assertions.Assert
(False,
"invalid hex character '" & C & "'");
return 0;
end case;
end Hex_Value;
function Hex_Bytes (Hex : String) return WolfSSL.Byte_Array is
Len : constant Natural := Hex'Length;
begin
AUnit.Assertions.Assert
(Len mod 2 = 0,
"hex string length must be even, got" & Integer'Image (Len));
declare
N : constant Natural := Len / 2;
begin
if N = 0 then
-- Return a null range for empty input
declare
Empty : WolfSSL.Byte_Array (1 .. 0);
begin
return Empty;
end;
end if;
declare
Last_N : constant Natural := N - 1;
B : WolfSSL.Byte_Array (0 .. WolfSSL.Byte_Index (Last_N));
Hi : Natural;
Lo : Natural;
J : Natural := 0;
begin
for K in 0 .. N - 1 loop
J := 2 * K;
Hi := Hex_Value (Hex (Hex'First + J));
Lo := Hex_Value (Hex (Hex'First + J + 1));
B (WolfSSL.Byte_Index (K)) :=
WolfSSL.Byte_Type'Val (16 * Hi + Lo);
end loop;
return B;
end;
end;
end Hex_Bytes;
function SHA256_Text (Hex : String) return WolfSSL.SHA256_As_String is
T : WolfSSL.SHA256_As_String;
I : Natural := 0;
begin
AUnit.Assertions.Assert
(Hex'Length = T'Length,
"SHA256 hex must be 64 characters, got" &
Integer'Image (Hex'Length));
for C of Hex loop
I := I + 1;
T (T'First + (I - 1)) := C;
end loop;
return T;
end SHA256_Text;
end Test_Support;

View File

@@ -0,0 +1,33 @@
with WolfSSL;
package Test_Support is
-- Small helpers to reduce test boilerplate and keep data declarations concise.
-----------------------------------------------------------------------------
-- Assertions
-----------------------------------------------------------------------------
-- Assert that a WolfSSL binding call returned success (0).
procedure Assert_Success (Result : Integer; What : String);
-----------------------------------------------------------------------------
-- Data helpers
-----------------------------------------------------------------------------
-- Convert a String into a WolfSSL.Byte_Array, byte-for-byte.
-- Intended for test vectors like keys/IVs/plaintext where ASCII is fine.
function Bytes (S : String) return WolfSSL.Byte_Array;
-- Convert a hex string (for example "0A1bFF") into a Byte_Array.
-- - Accepts both uppercase and lowercase hex.
-- - Requires an even number of hex characters.
function Hex_Bytes (Hex : String) return WolfSSL.Byte_Array;
-- Convert a hex string into a SHA256 text value.
-- This is handy for expected SHA256 digests ("64 hex chars").
function SHA256_Text (Hex : String) return WolfSSL.SHA256_As_String;
private
-- Put small internal helpers in the body; keep the spec minimal.
pragma Inline (Assert_Success);
end Test_Support;

View File

@@ -0,0 +1,23 @@
with AES_Bindings_Tests;
with RSA_Verify_Bindings_Tests;
with SHA256_Bindings_Tests;
package body Tests_Root_Suite is
-- Statically allocated (library-level) suite object.
-- Returning Root'Access is safe (no dangling pointer / accessibility issues),
-- and avoids heap allocation (so Valgrind stays clean).
Root : aliased AUnit.Test_Suites.Test_Suite;
function Suite return AUnit.Test_Suites.Access_Test_Suite is
begin
return Root'Access;
end Suite;
begin
-- Register all binding test suites at elaboration time.
AUnit.Test_Suites.Add_Test (Root'Access, SHA256_Bindings_Tests.Suite);
AUnit.Test_Suites.Add_Test (Root'Access, RSA_Verify_Bindings_Tests.Suite);
AUnit.Test_Suites.Add_Test (Root'Access, AES_Bindings_Tests.Suite);
end Tests_Root_Suite;

View File

@@ -0,0 +1,18 @@
with AUnit.Test_Suites;
-- Library-level root suite holder.
--
-- Purpose:
-- - Provide a statically-allocated (non-heap) top-level suite object.
-- - Return an Access_Test_Suite that safely designates a library-level object
-- (to satisfy Ada accessibility rules without Unrestricted_Access).
--
-- The body is responsible for populating the suite exactly once (typically at
-- elaboration time).
package Tests_Root_Suite is
-- Return the root test suite (statically allocated, library-level).
function Suite return AUnit.Test_Suites.Access_Test_Suite;
end Tests_Root_Suite;

View File

@@ -0,0 +1,15 @@
with AUnit.Reporter.Text;
with AUnit.Run;
with Tests_Root_Suite;
procedure Tests is
Reporter : AUnit.Reporter.Text.Text_Reporter;
-- Instantiate the generic AUnit runner with a *library-level* suite function.
-- This avoids Ada accessibility issues (no local objects' 'Access escaping)
-- and keeps the harness minimal.
procedure Runner is new AUnit.Run.Test_Runner (Tests_Root_Suite.Suite);
begin
Runner (Reporter);
end Tests;

View File

@@ -0,0 +1,36 @@
with "config/tests_config.gpr";
with "../wolfssl.gpr";
project Tests is
for Source_Dirs use ("src/", "src/support", "config/");
for Object_Dir use "obj/" & Tests_Config.Build_Profile;
for Create_Missing_Dirs use "True";
for Exec_Dir use "bin";
for Main use ("tests.adb");
package Compiler is
-- "-gnatyM0" disables the GNAT style check for maximum line length.
-- We keep it disabled for this tests project because some embedded
-- test vectors (e.g., DER keys) are long comma-separated literals that
-- would otherwise generate many "this line is too long" warnings.
for Default_Switches ("Ada") use
Tests_Config.Ada_Compiler_Switches & ("-gnatyM0");
end Compiler;
package Binder is
for Switches ("Ada") use ("-Es"); -- Symbolic traceback
end Binder;
package Linker is
-- WolfSSL uses libm on Linux/macOS; wolfssl.gpr already encodes OS-specifics,
-- but we repeat "-lm" here so the standalone tests executable links when
-- consumed without a full project tree.
for Switches ("Ada") use ("-lm");
end Linker;
package Install is
for Artifacts (".") use ("share");
end Install;
end Tests;

View File

@@ -0,0 +1,17 @@
{
aunit_test_results_add_success_leak
Memcheck:Leak
match-leak-kinds: definite,indirect
fun:malloc
fun:__gnat_malloc
fun:aunit__test_results__add_success
}
{
aunit_test_results_successes_leak
Memcheck:Leak
match-leak-kinds: definite,indirect
fun:malloc
fun:__gnat_malloc
fun:aunit__test_results__successes
}

View File

@@ -0,0 +1,89 @@
pragma Warnings (Off, "* is an internal GNAT unit");
with GNAT.Sockets.Thin_Common;
pragma Warnings (On, "* is an internal GNAT unit");
package body WolfSSL.Full_Runtime is
function WolfSSL_DTLS_Set_Peer
(ssl : WolfSSL_Type;
peer : GNAT.Sockets.Thin_Common.Sockaddr_Access;
peerSz : Interfaces.C.unsigned)
return int with
Convention => C,
External_Name => "wolfSSL_dtls_set_peer",
Import => True;
function DTLS_Set_Peer
(Ssl : WolfSSL_Type;
Address : GNAT.Sockets.Sock_Addr_Type)
return Subprogram_Result is
Sin : aliased GNAT.Sockets.Thin_Common.Sockaddr;
Length : Interfaces.C.int;
begin
GNAT.Sockets.Thin_Common.Set_Address
(Sin => Sin'Unchecked_Access,
Address => Address,
Length => Length);
pragma Assert (Length >= 0);
return
Subprogram_Result
(WolfSSL_DTLS_Set_Peer
(ssl => Ssl,
peer => Sin'Unchecked_Access,
peerSz => Interfaces.C.unsigned (Length)));
exception
when others =>
return Exception_Error;
end DTLS_Set_Peer;
procedure WolfSSL_Set_Psk_Client_Callback
(Ssl : WolfSSL_Type;
Cb : PSK_Client_Callback)
with
Convention => C,
External_Name => "wolfSSL_set_psk_client_callback",
Import => True;
procedure Set_PSK_Client_Callback
(Ssl : WolfSSL_Type;
Callback : PSK_Client_Callback) is
begin
WolfSSL_Set_Psk_Client_Callback (Ssl, Callback);
end Set_PSK_Client_Callback;
procedure WolfSSL_Set_Psk_Server_Callback
(Ssl : WolfSSL_Type;
Cb : PSK_Server_Callback)
with
Convention => C,
External_Name => "wolfSSL_set_psk_server_callback",
Import => True;
procedure Set_PSK_Server_Callback
(Ssl : WolfSSL_Type;
Callback : PSK_Server_Callback) is
begin
WolfSSL_Set_Psk_Server_Callback (Ssl, Callback);
end Set_PSK_Server_Callback;
procedure WolfSSL_CTX_Set_Psk_Server_Callback
(Ctx : Context_Type;
Cb : PSK_Server_Callback)
with
Convention => C,
External_Name => "wolfSSL_CTX_set_psk_server_callback",
Import => True;
procedure Set_Context_PSK_Server_Callback
(Context : Context_Type;
Callback : PSK_Server_Callback) is
begin
WolfSSL_CTX_Set_Psk_Server_Callback (Context, Callback);
end Set_Context_PSK_Server_Callback;
end WolfSSL.Full_Runtime;

View File

@@ -0,0 +1,77 @@
with GNAT.Sockets;
with Interfaces.C.Strings;
-- This package contains the subprograms that need the Ada run-time
-- to support the Interfaces.C.Strings and GNAT.Sockets packages.
-- An example of an Ada run-time that does not support this package
-- is the Zero Footprint run-time of the GNAT compiler.
package WolfSSL.Full_Runtime with SPARK_Mode is
function DTLS_Set_Peer
(Ssl : WolfSSL_Type;
Address : GNAT.Sockets.Sock_Addr_Type)
return Subprogram_Result with
Pre => Is_Valid (Ssl);
-- This function wraps the corresponding WolfSSL C function to allow
-- clients to use Ada socket types when implementing a DTLS client.
subtype chars_ptr is Interfaces.C.Strings.chars_ptr;
type PSK_Client_Callback is access function
(Ssl : WolfSSL_Type;
Hint : chars_ptr;
Identity : chars_ptr;
Id_Max_Length : unsigned;
Key : chars_ptr;
Key_Max_Length : unsigned)
return unsigned with
Convention => C;
-- Return value is the key length on success or zero on error.
-- parameters:
-- Ssl - Pointer to the wolfSSL structure
-- Hint - A stored string that could be displayed to provide a
-- hint to the user.
-- Identity - The ID will be stored here.
-- Id_Max_Length - Size of the ID buffer.
-- Key - The key will be stored here.
-- Key_Max_Length - The max size of the key.
--
-- The implementation of this callback will need `SPARK_Mode => Off`
-- since it will require the code to use the C memory model.
procedure Set_PSK_Client_Callback
(Ssl : WolfSSL_Type;
Callback : PSK_Client_Callback) with
Pre => Is_Valid (Ssl);
-- Sets the PSK client side callback.
type PSK_Server_Callback is access function
(Ssl : WolfSSL_Type;
Identity : chars_ptr;
Key : chars_ptr;
Key_Max_Length : unsigned)
return unsigned with
Convention => C;
-- Return value is the key length on success or zero on error.
-- PSK server callback parameters:
-- Ssl - Reference to the wolfSSL structure
-- Identity - The ID will be stored here.
-- Key - The key will be stored here.
-- Key_Max_Length - The max size of the key.
--
-- The implementation of this callback will need `SPARK_Mode => Off`
-- since it will require the code to use the C memory model.
procedure Set_PSK_Server_Callback
(Ssl : WolfSSL_Type;
Callback : PSK_Server_Callback) with
Pre => Is_Valid (Ssl);
-- Sets the PSK Server side callback.
procedure Set_Context_PSK_Server_Callback
(Context : Context_Type;
Callback : PSK_Server_Callback) with
Pre => Is_Valid (Context);
-- Sets the PSK callback for the server side in the WolfSSL Context.
end WolfSSL.Full_Runtime;

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
-- wolfssl.ads
--
-- Copyright (C) 2006-2023 wolfSSL Inc.
-- Copyright (C) 2006-2025 wolfSSL Inc.
--
-- This file is part of wolfSSL.
--
@@ -19,8 +19,7 @@
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
--
with GNAT.Sockets;
with Interfaces.C.Strings;
with Interfaces.C;
-- This package is annotated "with SPARK_Mode" that SPARK can verify
-- the API of this package is used correctly.
@@ -28,7 +27,15 @@ package WolfSSL with SPARK_Mode is
type Subprogram_Result is new Integer;
Success : constant Subprogram_Result;
-- Indicates success for some functions.
-- Do not use, unless you know what you do.
Failure : constant Subprogram_Result;
-- Indicates failure for some functions.
-- Do not use, unless you know what you do.
Exception_Error : constant := -1234567;
-- Indicates an exception was raised during a subprogram call.
function Initialize return Subprogram_Result;
-- Initializes the wolfSSL library for use. Must be called once per
@@ -41,22 +48,31 @@ package WolfSSL with SPARK_Mode is
subtype unsigned is Interfaces.C.unsigned;
subtype char_array is Interfaces.C.char_array; -- Remove?
subtype chars_ptr is Interfaces.C.Strings.chars_ptr;
subtype Byte_Type is Interfaces.C.char;
subtype Byte_Index is Interfaces.C.size_t range 0 .. 16_000;
subtype Byte_Array is Interfaces.C.char_array;
type Context_Type is limited private;
use type Interfaces.C.size_t;
type Context_Type is limited private with
Annotate => (GNATprove, Ownership, "Needs_Reclamation");
-- Instances of this type are called SSL Contexts.
function Is_Valid (Context : Context_Type) return Boolean;
function Is_Valid (Context : Context_Type) return Boolean with
Annotate => (GNATprove, Ownership, "Needs_Reclamation");
-- Indicates if the SSL Context has successfully been initialized.
-- If initialized, the SSL Context has allocated resources
-- that needs to be deallocated before application exit.
-- Annotation added for GNATprove ownership analysis.
-- https://docs.adacore.com/spark2014-docs/html/ug/en/appendix/additional_annotate_pragmas.html#annotation-for-enforcing-ownership-checking-on-a-private-type
type Method_Type is limited private;
type Method_Type is limited private with
Annotate => (GNATprove, Ownership, "Needs_Reclamation");
function Is_Valid (Method : Method_Type) return Boolean with
Annotate => (GNATprove, Ownership, "Needs_Reclamation");
-- Annotation added for GNATprove ownership analysis.
-- https://docs.adacore.com/spark2014-docs/html/ug/en/appendix/additional_annotate_pragmas.html#annotation-for-enforcing-ownership-checking-on-a-private-type
function TLSv1_2_Server_Method return Method_Type;
-- This function is used to indicate that the application is a server
@@ -90,16 +106,18 @@ package WolfSSL with SPARK_Mode is
-- This function is used to indicate that the application is a client
-- and will only support the DTLS 1.3 protocol.
procedure Create_Context (Method : Method_Type;
Context : out Context_Type);
procedure Create_Context (Method : in out Method_Type;
Context : out Context_Type) with
Post => not Is_Valid (Method);
-- This function creates a new SSL context, taking a desired SSL/TLS
-- protocol method for input.
-- If successful Is_Valid (Context) = True, otherwise False.
-- The Method is consumed by this operation and set to null.
procedure Free (Context : in out Context_Type) with
Pre => Is_Valid (Context),
Post => not Is_Valid (Context);
-- This function frees an allocated SSL Context object.
-- If Context is not valid, this is a no-op.
type Mode_Type is private;
@@ -165,7 +183,7 @@ package WolfSSL with SPARK_Mode is
-- PEM file types. Please see the examples for proper usage.
function Use_Certificate_Buffer (Context : Context_Type;
Input : char_array;
Input : Byte_Array;
Format : File_Format)
return Subprogram_Result with
Pre => Is_Valid (Context);
@@ -234,13 +252,17 @@ package WolfSSL with SPARK_Mode is
-- per buffer as long as the format is in PEM.
-- Please see the examples for proper usage.
type WolfSSL_Type is limited private;
type WolfSSL_Type is limited private with
Annotate => (GNATprove, Ownership, "Needs_Reclamation");
-- Instances of this type are called SSL Sessions.
function Is_Valid (Ssl : WolfSSL_Type) return Boolean;
function Is_Valid (Ssl : WolfSSL_Type) return Boolean with
Annotate => (GNATprove, Ownership, "Needs_Reclamation");
-- Indicates if the SSL Session has successfully been initialized.
-- If initialized, the SSL Session has allocated resources
-- that needs to be deallocated before application exit.
-- Annotation added for GNATprove ownership analysis.
-- https://docs.adacore.com/spark2014-docs/html/ug/en/appendix/additional_annotate_pragmas.html#annotation-for-enforcing-ownership-checking-on-a-private-type
procedure Create_WolfSSL (Context : Context_Type;
Ssl : out WolfSSL_Type) with
@@ -260,7 +282,7 @@ package WolfSSL with SPARK_Mode is
-- either ASN1 or PEM.
function Use_Certificate_Buffer (Ssl : WolfSSL_Type;
Input : char_array;
Input : Byte_Array;
Format : File_Format)
return Subprogram_Result with
Pre => Is_Valid (Ssl);
@@ -292,72 +314,6 @@ package WolfSSL with SPARK_Mode is
-- Format specifies the format type of the buffer; ASN1 or PEM.
-- Please see the examples for proper usage.
function DTLS_Set_Peer
(Ssl : WolfSSL_Type;
Address : GNAT.Sockets.Sock_Addr_Type)
return Subprogram_Result with
Pre => Is_Valid (Ssl);
-- This function wraps the corresponding WolfSSL C function to allow
-- clients to use Ada socket types when implementing a DTLS client.
type PSK_Client_Callback is access function
(Ssl : WolfSSL_Type;
Hint : chars_ptr;
Identity : chars_ptr;
Id_Max_Length : unsigned;
Key : chars_ptr;
Key_Max_Length : unsigned)
return unsigned with
Convention => C;
-- Return value is the key length on success or zero on error.
-- parameters:
-- Ssl - Pointer to the wolfSSL structure
-- Hint - A stored string that could be displayed to provide a
-- hint to the user.
-- Identity - The ID will be stored here.
-- Id_Max_Length - Size of the ID buffer.
-- Key - The key will be stored here.
-- Key_Max_Length - The max size of the key.
--
-- The implementation of this callback will need `SPARK_Mode => Off`
-- since it will require the code to use the C memory model.
procedure Set_PSK_Client_Callback
(Ssl : WolfSSL_Type;
Callback : PSK_Client_Callback) with
Pre => Is_Valid (Ssl);
-- Sets the PSK client side callback.
type PSK_Server_Callback is access function
(Ssl : WolfSSL_Type;
Identity : chars_ptr;
Key : chars_ptr;
Key_Max_Length : unsigned)
return unsigned with
Convention => C;
-- Return value is the key length on success or zero on error.
-- PSK server callback parameters:
-- Ssl - Reference to the wolfSSL structure
-- Identity - The ID will be stored here.
-- Key - The key will be stored here.
-- Key_Max_Length - The max size of the key.
--
-- The implementation of this callback will need `SPARK_Mode => Off`
-- since it will require the code to use the C memory model.
procedure Set_PSK_Server_Callback
(Ssl : WolfSSL_Type;
Callback : PSK_Server_Callback) with
Pre => Is_Valid (Ssl);
-- Sets the PSK Server side callback.
procedure Set_Context_PSK_Server_Callback
(Context : Context_Type;
Callback : PSK_Server_Callback) with
Pre => Is_Valid (Context);
-- Sets the PSK callback for the server side in the WolfSSL Context.
function Attach (Ssl : WolfSSL_Type;
Socket : Integer)
return Subprogram_Result with
@@ -422,7 +378,8 @@ package WolfSSL with SPARK_Mode is
end case;
end record;
function Read (Ssl : WolfSSL_Type) return Read_Result with
procedure Read (Ssl : WolfSSL_Type;
Result : out Read_Result) with
Pre => Is_Valid (Ssl);
-- This function reads a number of bytes from the SSL session (ssl)
-- internal read buffer into the buffer data. The bytes read are
@@ -450,8 +407,9 @@ package WolfSSL with SPARK_Mode is
end case;
end record;
function Write (Ssl : WolfSSL_Type;
Data : Byte_Array) return Write_Result with
procedure Write (Ssl : WolfSSL_Type;
Data : Byte_Array;
Result : out Write_Result) with
Pre => Is_Valid (Ssl);
-- The number of bytes written is returned.
-- This function writes bytes from the buffer, Data,
@@ -489,9 +447,9 @@ package WolfSSL with SPARK_Mode is
-- the call to Shutdown() when the underlying I/O is ready.
procedure Free (Ssl : in out WolfSSL_Type) with
Pre => Is_Valid (Ssl),
Post => not Is_Valid (Ssl);
-- Frees the resources allocated by the SSL session object.
-- If Ssl is not valid, this is a no-op.
function Connect (Ssl : WolfSSL_Type) return Subprogram_Result with
Pre => Is_Valid (Ssl);
@@ -543,20 +501,250 @@ package WolfSSL with SPARK_Mode is
Text : String (1 .. Last);
end record;
function Error (Code : Error_Code) return Error_Message;
procedure Error (Code : in Error_Code;
Message : in out Error_Message);
-- This function converts an error code returned by Get_Error(..)
-- into a more human readable error string. Code is the error code
-- returned by Get_error(). The maximum length of error strings is
-- 80 characters by default, as defined by MAX_ERROR_SZ
-- is wolfssl/wolfcrypt/error.h.
--
-- If Message has not been updated with a text, it may be because
-- an exception was raised during the execution of the subprogram.
function Max_Error_Size return Natural;
-- Returns the value of the defined MAX_ERROR_SZ integer
-- in wolfssl/wolfcrypt/error.h.
type RNG_Type is limited private with
Annotate => (GNATprove, Ownership, "Needs_Reclamation");
function Is_Valid (Key : RNG_Type) return Boolean with
Annotate => (GNATprove, Ownership, "Needs_Reclamation");
-- Indicates if the RNG has successfully been initialized.
-- Annotation added for GNATprove ownership analysis.
-- https://docs.adacore.com/spark2014-docs/html/ug/en/appendix/additional_annotate_pragmas.html#annotation-for-enforcing-ownership-checking-on-a-private-type
procedure Create_RNG (Key : in out RNG_Type;
Result : out Integer) with
Pre => not Is_Valid (Key),
Post => (if Result = 0 then Is_Valid (Key));
-- If successful Result = 0.
procedure Free_RNG (Key : in out RNG_Type) with
Pre => Is_Valid (Key),
Post => not Is_Valid (Key);
-- Frees resources associated with RNG and releases the underlying C object.
procedure RNG_Generate_Block (RNG : RNG_Type;
Output : out Byte_Array;
Result : out Integer) with
Pre => Is_Valid (RNG);
type HMAC_Hash is (MD5, SHA, SHA256, SHA384, SHA512, SHA3_224,
SHA3_256, SHA3_384, SHA3_512);
procedure PBKDF2 (Output : out Byte_Array;
Password : Byte_Array;
Salt : Byte_Array;
Iterations : Positive;
Key_Length : Positive;
HMAC : HMAC_Hash;
Result : out Integer);
type RSA_Key_Type is limited private with
Annotate => (GNATprove, Ownership, "Needs_Reclamation");
function Is_Valid (Key : RSA_Key_Type) return Boolean with
Annotate => (GNATprove, Ownership, "Needs_Reclamation");
-- Indicates if the RSA has successfully been initialized.
-- Annotation added for GNATprove ownership analysis.
-- https://docs.adacore.com/spark2014-docs/html/ug/en/appendix/additional_annotate_pragmas.html#annotation-for-enforcing-ownership-checking-on-a-private-type
procedure Create_RSA (Key : in out RSA_Key_Type;
Result : out Integer) with
Pre => not Is_Valid (Key),
Post => (if Result = 0 then Is_Valid (Key));
-- If successful Result = 0.
procedure Free_RSA (Key : in out RSA_Key_Type) with
Pre => Is_Valid (Key),
Post => not Is_Valid (Key);
-- Frees resources associated with RSA and releases the underlying C object.
procedure Rsa_Public_Key_Decode (Input : Byte_Array;
Index : in out Byte_Index;
Key : in out RSA_Key_Type;
Size : Integer;
Result : out Integer) with
Pre => Is_Valid (Key);
-- This function parses a DER-formatted RSA public key,
-- extracts the public key and stores it in the RsaKey structure
-- specified by the Key input argument. It also sets the distance
-- parsed in Index.
-- Note: A RsaKey structure contains two parts,
-- one public and one private key.
procedure Rsa_Private_Key_Decode (Input : Byte_Array;
Index : in out Byte_Index;
Key : in out RSA_Key_Type;
Size : Integer;
Result : out Integer) with
Pre => Is_Valid (Key);
-- This function parses a DER-formatted RSA private key,
-- extracts the private key and stores it in the RsaKey structure
-- specified by the Key input argument. It also sets the distance
-- parsed in Index.
-- Note: A RsaKey structure contains two parts,
-- one public and one private key.
procedure Rsa_Set_RNG (Key : in out Rsa_Key_Type;
RNG : in out RNG_Type;
Result : out Integer);
procedure Rsa_SSL_Sign (Input : Byte_Array;
Output : in out Byte_Array;
RSA : in out RSA_Key_Type;
RNG : in out RNG_Type;
Result : out Integer) with
Pre => Is_Valid (RSA) and Is_Valid (RNG);
-- The Output buffer must have the same size as the RSA key.
-- If successful Result = 0.
-- If Result < 0, then failure.
-- If Result > 0, then Success and is the size of the RSA key in bytes.
procedure Rsa_SSL_Verify (Input : Byte_Array;
Output : in out Byte_Array;
RSA : in out RSA_Key_Type;
Result : out Integer) with
Pre => Is_Valid (RSA);
-- If Result < 0, then failure.
-- If Result > 0, then digital signature in Input
-- successfully verified.
procedure RSA_Public_Encrypt (Input : Byte_Array;
Output : in out Byte_Array;
Index : out Byte_Index;
RSA : in out RSA_Key_Type;
RNG : in out RNG_Type;
Result : out Integer) with
Pre => Is_Valid (RSA);
-- This function encrypts a message from Input and stores the result
-- in Output. It requires an initialized public key and a random
-- number generator. As a side effect, this function will return
-- the bytes written to Output in Index.
procedure RSA_Private_Decrypt (Input : Byte_Array;
Output : in out Byte_Array;
Index : out Byte_Index;
RSA : in out RSA_Key_Type;
Result : out Integer) with
Pre => Is_Valid (RSA);
-- This functions provides private RSA decryption.
type SHA256_Type is limited private with
Annotate => (GNATprove, Ownership, "Needs_Reclamation");
function Is_Valid (SHA256 : SHA256_Type) return Boolean with
Annotate => (GNATprove, Ownership, "Needs_Reclamation");
-- Indicates if the SHA256 has successfully been initialized.
-- Annotation added for GNATprove ownership analysis.
-- https://docs.adacore.com/spark2014-docs/html/ug/en/appendix/additional_annotate_pragmas.html#annotation-for-enforcing-ownership-checking-on-a-private-type
procedure Create_SHA256 (SHA256 : in out SHA256_Type;
Result : out Integer) with
Pre => not Is_Valid (SHA256),
Post => (if Result = 0 then Is_Valid (SHA256));
-- If successful Result = 0.
procedure Free_SHA256 (SHA256 : in out SHA256_Type) with
Pre => Is_Valid (SHA256),
Post => not Is_Valid (SHA256);
-- Frees resources associated with SHA256 and releases the underlying C object.
-- If successful Result = 0.
procedure Update_SHA256 (SHA256 : in out SHA256_Type;
Byte : Byte_Array;
Result : out Integer) with
Pre => Is_Valid (SHA256);
-- If successful Result = 0.
subtype SHA256_As_String is String (1 .. 64);
subtype SHA256_Hash is Byte_Array (1 .. 32);
procedure Finalize_SHA256 (SHA256 : in out SHA256_Type;
Hash : out SHA256_Hash;
Result : out Integer) with
Pre => Is_Valid (SHA256);
-- If successful Result = 0.
type Device_Identifier is new Integer;
function Invalid_Device return Device_Identifier;
type AES_Type is limited private with
Annotate => (GNATprove, Ownership, "Needs_Reclamation");
function Is_Valid (AES : AES_Type) return Boolean with
Annotate => (GNATprove, Ownership, "Needs_Reclamation");
-- Indicates if the AES has successfully been initialized.
-- Annotation added for GNATprove ownership analysis.
-- https://docs.adacore.com/spark2014-docs/html/ug/en/appendix/additional_annotate_pragmas.html#annotation-for-enforcing-ownership-checking-on-a-private-type
procedure Create_AES (Device : Device_Identifier;
AES : in out AES_Type;
Result : out Integer) with
Pre => not Is_Valid (AES),
Post => (if Result = 0 then Is_Valid (AES));
-- If successful Is_Valid (AES) = True, and Result = 0.
procedure AES_Free (AES : in out AES_Type;
Result : out Integer) with
Pre => Is_Valid (AES),
Post => (if Result = 0 then not Is_Valid (AES));
-- Frees resources associated with AES and releases the underlying C object.
procedure AES_Set_Key (AES : AES_Type;
Key : Byte_Array;
Length : Integer;
IV : Byte_Array;
Dir : Integer;
Result : out Integer) with
Pre => Is_Valid (AES);
procedure AES_Set_IV (AES : AES_Type;
IV : Byte_Array;
Result : out Integer) with
Pre => Is_Valid (AES);
procedure AES_Set_Cbc_Encrypt (AES : AES_Type;
Output : out Byte_Array;
Input : Byte_Array;
Size : Integer;
Result : out Integer) with
Pre => Is_Valid (AES);
procedure AES_Set_Cbc_Decrypt (AES : AES_Type;
Output : out Byte_Array;
Input : Byte_Array;
Size : Integer;
Result : out Integer) with
Pre => Is_Valid (AES);
-- (Removed duplicate AES_Free declaration)
private
pragma SPARK_Mode (Off);
type chars_ptr is access all Character;
pragma Convention (C, chars_ptr);
pragma No_Strict_Aliasing (chars_ptr);
-- Since this type is used for external interfacing, with the pointer
-- coming from who knows where, it seems a good idea to turn off any
-- strict aliasing assumptions for this type.
subtype int is Interfaces.C.int; use type int;
type Opaque_Method is limited null record;
@@ -615,6 +803,13 @@ private
External_Name => "get_wolfssl_verify_default",
Import => True;
pragma Warnings (Off, "pragma Restrictions (No_Exception_Propagation)");
-- The compiler may check for warnings related to no exception
-- propagation if this code is compiled with the Zero
-- Footprint run-time. The constants exposed here in the Ada binding
-- have valid values defined in the WolfSSL library but the compiler
-- cannot know this since the values become known during run-time.
Verify_None : constant Mode_Type := Mode_Type (WolfSSL_Verify_None);
Verify_Peer : constant Mode_Type := Mode_Type (WolfSSL_Verify_Peer);
@@ -632,6 +827,7 @@ private
Verify_Default : constant Mode_Type :=
Mode_Type (WolfSSL_Verify_Default);
pragma Warnings (On, "pragma Restrictions (No_Exception_Propagation)");
type File_Format is new Unsigned_32;
@@ -650,6 +846,12 @@ private
External_Name => "get_wolfssl_filetype_default",
Import => True;
pragma Warnings (Off, "pragma Restrictions (No_Exception_Propagation)");
-- The compiler may check for warnings related to no exception
-- propagation if this code is compiled with the Zero
-- Footprint run-time. The constants exposed here in the Ada binding
-- have valid values defined in the WolfSSL library but the compiler
-- cannot know this since the values become known during run-time.
Format_Asn1 : constant File_Format :=
File_Format (WolfSSL_Filetype_Asn1);
@@ -658,6 +860,7 @@ private
Format_Default : constant File_Format :=
File_Format (WolfSSL_Filetype_Default);
pragma Warnings (On, "pragma Restrictions (No_Exception_Propagation)");
function Get_WolfSSL_Success return int with
Convention => C,
@@ -671,9 +874,11 @@ private
Success : constant Subprogram_Result :=
Subprogram_Result (Get_WolfSSL_Success);
-- Indicates success for some functions.
-- Do not use, unless you know what you do.
Failure : constant Subprogram_Result :=
Subprogram_Result (Get_WolfSSL_Failure);
Subprogram_Result (Get_WolfSSL_Failure);
function Get_WolfSSL_Error_Want_Read return int with
Convention => C,
@@ -689,6 +894,18 @@ private
Error_Code (Get_WolfSSL_Error_Want_Read);
Error_Want_Write : constant Error_Code :=
Error_Code (Get_WolfSSL_Error_Want_Write);
Error_Code (Get_WolfSSL_Error_Want_Write);
type Opaque_RNG is limited null record;
type RNG_Type is access Opaque_RNG with Convention => C;
type Opaque_RSA is limited null record;
type RSA_Key_Type is access Opaque_RSA with Convention => C;
type Opaque_Sha256 is limited null record;
type SHA256_Type is access Opaque_Sha256 with Convention => C;
type Opaque_AES is limited null record;
type AES_Type is access Opaque_AES with Convention => C;
end WolfSSL;

View File

@@ -11,16 +11,6 @@ library project WolfSSL is
"../../src",
"../../wolfcrypt/src");
-- Don't build the tls client or server application.
-- They are not needed in order to build the library.
for Excluded_Source_Files use
("tls_client_main.adb",
"tls_client.ads",
"tls_client.adb",
"tls_server_main.adb",
"tls_server.ads",
"tls_server.adb");
for Object_Dir use "obj";
for Library_Dir use "lib";
for Create_Missing_Dirs use "True";