diff --git a/.editorconfig b/.editorconfig index 0ea0cc46c76..2a54ec49758 100644 --- a/.editorconfig +++ b/.editorconfig @@ -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 diff --git a/.github/workflows/ada.yml b/.github/workflows/ada.yml index 9691e425bce..d1d51d82b47 100644 --- a/.github/workflows/ada.yml +++ b/.github/workflows/ada.yml @@ -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: | - sudo apt-get update - sudo apt-get install -y gnat gprbuild + alr build + + echo "Running sha256_main example..." + alr run sha256_main - - name: Checkout wolfssl - uses: actions/checkout@master - with: - repository: wolfssl/wolfssl - path: wolfssl + echo "Running aes_verify_main example..." + alr run aes_verify_main - - name: Build wolfssl Ada - working-directory: ./wolfssl/wrapper/Ada + 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: | - mkdir obj - gprbuild default.gpr - gprbuild examples.gpr + sudo apt-get update + sudo apt-get install -y valgrind + valgrind --leak-check=full --error-exitcode=1 \ + --suppressions=valgrind.supp ./bin/tests + + - 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: 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 diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index feded367eb0..403d35c09d6 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -1348,6 +1348,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, diff --git a/wrapper/Ada/.gitignore b/wrapper/Ada/.gitignore index b672fdeaf35..5866d7bfa6b 100644 --- a/wrapper/Ada/.gitignore +++ b/wrapper/Ada/.gitignore @@ -1 +1,4 @@ -obj +/obj/ +/bin/ +/alire/ +/config/ diff --git a/wrapper/Ada/README.md b/wrapper/Ada/README.md index ac98f71aee4..1f091f943ab 100644 --- a/wrapper/Ada/README.md +++ b/wrapper/Ada/README.md @@ -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 diff --git a/wrapper/Ada/ada_binding.c b/wrapper/Ada/ada_binding.c index 19ed080b19d..c4d177fc9bf 100644 --- a/wrapper/Ada/ada_binding.c +++ b/wrapper/Ada/ada_binding.c @@ -26,7 +26,15 @@ /* wolfSSL */ #include #include +#include +#include +#include +#include + +/* 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; +} diff --git a/wrapper/Ada/alire.toml b/wrapper/Ada/alire.toml index 1af7e82e5d1..4ddd4ac462e 100644 --- a/wrapper/Ada/alire.toml +++ b/wrapper/Ada/alire.toml @@ -12,3 +12,6 @@ tags = ["ssl", "tls", "embedded", "spark"] [configuration.variables] STATIC_PSK = {type = "Boolean", default = false} + +[[depends-on]] +gnatprove = "^13.2.1" diff --git a/wrapper/Ada/default.gpr b/wrapper/Ada/default.gpr index 16809601bc4..d5705e60c12 100644 --- a/wrapper/Ada/default.gpr +++ b/wrapper/Ada/default.gpr @@ -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 diff --git a/wrapper/Ada/examples.gpr b/wrapper/Ada/examples.gpr deleted file mode 100644 index 218f93e51ed..00000000000 --- a/wrapper/Ada/examples.gpr +++ /dev/null @@ -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; diff --git a/wrapper/Ada/examples/.gitignore b/wrapper/Ada/examples/.gitignore new file mode 100644 index 00000000000..5866d7bfa6b --- /dev/null +++ b/wrapper/Ada/examples/.gitignore @@ -0,0 +1,4 @@ +/obj/ +/bin/ +/alire/ +/config/ diff --git a/wrapper/Ada/examples/alire.toml b/wrapper/Ada/examples/alire.toml new file mode 100644 index 00000000000..17b6be84cdd --- /dev/null +++ b/wrapper/Ada/examples/alire.toml @@ -0,0 +1,21 @@ +name = "examples" +description = "Examples using the wolfSSL Ada bindings" +version = "0.1.0-dev" + +authors = ["Juliusz Sosinowicz"] +maintainers = ["Juliusz Sosinowicz "] +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" diff --git a/wrapper/Ada/examples/examples.gpr b/wrapper/Ada/examples/examples.gpr new file mode 100644 index 00000000000..6e3b92622e6 --- /dev/null +++ b/wrapper/Ada/examples/examples.gpr @@ -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; diff --git a/wrapper/Ada/examples/src/aes_verify_main.adb b/wrapper/Ada/examples/src/aes_verify_main.adb new file mode 100644 index 00000000000..582a9f35d65 --- /dev/null +++ b/wrapper/Ada/examples/src/aes_verify_main.adb @@ -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_Key_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; diff --git a/wrapper/Ada/examples/src/rsa_verify_main.adb b/wrapper/Ada/examples/src/rsa_verify_main.adb new file mode 100644 index 00000000000..73b0285102f --- /dev/null +++ b/wrapper/Ada/examples/src/rsa_verify_main.adb @@ -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_Key_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; diff --git a/wrapper/Ada/examples/src/sha256_main.adb b/wrapper/Ada/examples/src/sha256_main.adb new file mode 100644 index 00000000000..ac6f90bf7f9 --- /dev/null +++ b/wrapper/Ada/examples/src/sha256_main.adb @@ -0,0 +1,48 @@ +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; + S : WolfSSL.SHA256_As_String; +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, + Text => S, + Result => R); + if R = 0 then + Put (S); + New_Line; + else + Put ("Finalization of SHA256 instance failed"); + New_Line; + end if; + + WolfSSL.Free_SHA256 (SHA256 => SHA256); +end SHA256_Main; diff --git a/wrapper/Ada/spark_sockets.adb b/wrapper/Ada/examples/src/spark_sockets.adb similarity index 100% rename from wrapper/Ada/spark_sockets.adb rename to wrapper/Ada/examples/src/spark_sockets.adb diff --git a/wrapper/Ada/spark_sockets.ads b/wrapper/Ada/examples/src/spark_sockets.ads similarity index 100% rename from wrapper/Ada/spark_sockets.ads rename to wrapper/Ada/examples/src/spark_sockets.ads diff --git a/wrapper/Ada/spark_terminal.adb b/wrapper/Ada/examples/src/spark_terminal.adb similarity index 100% rename from wrapper/Ada/spark_terminal.adb rename to wrapper/Ada/examples/src/spark_terminal.adb diff --git a/wrapper/Ada/spark_terminal.ads b/wrapper/Ada/examples/src/spark_terminal.ads similarity index 87% rename from wrapper/Ada/spark_terminal.ads rename to wrapper/Ada/examples/src/spark_terminal.ads index 1c516ca7b3a..f664ce08282 100644 --- a/wrapper/Ada/spark_terminal.ads +++ b/wrapper/Ada/examples/src/spark_terminal.ads @@ -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 diff --git a/wrapper/Ada/tls_client.adb b/wrapper/Ada/examples/src/tls_client.adb similarity index 87% rename from wrapper/Ada/tls_client.adb rename to wrapper/Ada/examples/src/tls_client.adb index 4cd56c08bd0..3ba6abc43b2 100644 --- a/wrapper/Ada/tls_client.adb +++ b/wrapper/Ada/examples/src/tls_client.adb @@ -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; diff --git a/wrapper/Ada/tls_client.ads b/wrapper/Ada/examples/src/tls_client.ads similarity index 84% rename from wrapper/Ada/tls_client.ads rename to wrapper/Ada/examples/src/tls_client.ads index aa1ad36e01a..02d286d7825 100644 --- a/wrapper/Ada/tls_client.ads +++ b/wrapper/Ada/examples/src/tls_client.ads @@ -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; diff --git a/wrapper/Ada/tls_client_main.adb b/wrapper/Ada/examples/src/tls_client_main.adb similarity index 100% rename from wrapper/Ada/tls_client_main.adb rename to wrapper/Ada/examples/src/tls_client_main.adb diff --git a/wrapper/Ada/tls_server.adb b/wrapper/Ada/examples/src/tls_server.adb similarity index 89% rename from wrapper/Ada/tls_server.adb rename to wrapper/Ada/examples/src/tls_server.adb index 64e4f988d1e..fca256b372b 100644 --- a/wrapper/Ada/tls_server.adb +++ b/wrapper/Ada/examples/src/tls_server.adb @@ -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 diff --git a/wrapper/Ada/tls_server.ads b/wrapper/Ada/examples/src/tls_server.ads similarity index 100% rename from wrapper/Ada/tls_server.ads rename to wrapper/Ada/examples/src/tls_server.ads diff --git a/wrapper/Ada/tls_server_main.adb b/wrapper/Ada/examples/src/tls_server_main.adb similarity index 100% rename from wrapper/Ada/tls_server_main.adb rename to wrapper/Ada/examples/src/tls_server_main.adb diff --git a/wrapper/Ada/include.am b/wrapper/Ada/include.am index cc2001e9a11..051fb65cc47 100644 --- a/wrapper/Ada/include.am +++ b/wrapper/Ada/include.am @@ -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 diff --git a/wrapper/Ada/tests/.gitignore b/wrapper/Ada/tests/.gitignore new file mode 100644 index 00000000000..5866d7bfa6b --- /dev/null +++ b/wrapper/Ada/tests/.gitignore @@ -0,0 +1,4 @@ +/obj/ +/bin/ +/alire/ +/config/ diff --git a/wrapper/Ada/tests/README.md b/wrapper/Ada/tests/README.md new file mode 100644 index 00000000000..e6df50741ef --- /dev/null +++ b/wrapper/Ada/tests/README.md @@ -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 +``` diff --git a/wrapper/Ada/tests/alire.toml b/wrapper/Ada/tests/alire.toml new file mode 100644 index 00000000000..f408f657fb8 --- /dev/null +++ b/wrapper/Ada/tests/alire.toml @@ -0,0 +1,15 @@ +name = "tests" +description = "Tests for the wolfssl ada bindings" +version = "0.1.0-dev" + +authors = ["Juliusz Sosinowicz"] +maintainers = ["Juliusz Sosinowicz "] +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" diff --git a/wrapper/Ada/tests/src/aes_bindings_tests.adb b/wrapper/Ada/tests/src/aes_bindings_tests.adb new file mode 100644 index 00000000000..f9469b0b7d9 --- /dev/null +++ b/wrapper/Ada/tests/src/aes_bindings_tests.adb @@ -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 (1 .. Plain'Length); + Decoded : WolfSSL.Byte_Array (1 .. Plain'Length); + + 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; \ No newline at end of file diff --git a/wrapper/Ada/tests/src/aes_bindings_tests.ads b/wrapper/Ada/tests/src/aes_bindings_tests.ads new file mode 100644 index 00000000000..d2a36cb0aff --- /dev/null +++ b/wrapper/Ada/tests/src/aes_bindings_tests.ads @@ -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; diff --git a/wrapper/Ada/tests/src/rsa_verify_bindings_tests.adb b/wrapper/Ada/tests/src/rsa_verify_bindings_tests.adb new file mode 100644 index 00000000000..48e4218d742 --- /dev/null +++ b/wrapper/Ada/tests/src/rsa_verify_bindings_tests.adb @@ -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_Key_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; diff --git a/wrapper/Ada/tests/src/rsa_verify_bindings_tests.ads b/wrapper/Ada/tests/src/rsa_verify_bindings_tests.ads new file mode 100644 index 00000000000..5a8c46fa224 --- /dev/null +++ b/wrapper/Ada/tests/src/rsa_verify_bindings_tests.ads @@ -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; \ No newline at end of file diff --git a/wrapper/Ada/tests/src/sha256_bindings_tests.adb b/wrapper/Ada/tests/src/sha256_bindings_tests.adb new file mode 100644 index 00000000000..bc674e0b443 --- /dev/null +++ b/wrapper/Ada/tests/src/sha256_bindings_tests.adb @@ -0,0 +1,187 @@ +with AUnit.Assertions; +with AUnit.Test_Caller; + +with WolfSSL; + +with Test_Support; + +package body SHA256_Bindings_Tests is + + ---------------------------------------------------------------------------- + -- Helpers + ---------------------------------------------------------------------------- + + procedure Assert_Text_Matches_Hash + (Hash : WolfSSL.SHA256_Hash; + Text : WolfSSL.SHA256_As_String; + Msg : String); + + procedure Compute_SHA256 + (Input : WolfSSL.Byte_Array; + Hash : out WolfSSL.SHA256_Hash; + Text : out WolfSSL.SHA256_As_String; + Result : out Integer); + + procedure Assert_Text_Matches_Hash + (Hash : WolfSSL.SHA256_Hash; + Text : WolfSSL.SHA256_As_String; + Msg : String) + is + use type WolfSSL.Byte_Array; + + Expected : constant WolfSSL.Byte_Array := Test_Support.Hex_Bytes (Text); + Actual : WolfSSL.Byte_Array (Expected'Range); + H : WolfSSL.Byte_Index := Hash'First; + begin + -- Copy bytes out of the hash into the expected-range buffer. + -- Do not assume Hash and Expected share the same index range. + for I in Actual'Range loop + Actual (I) := Hash (H); + H := WolfSSL.Byte_Index'Succ (H); + end loop; + AUnit.Assertions.Assert + (Text'Length = 64, + Msg & ": expected 64 hex chars, got" & Integer'Image (Text'Length)); + + -- `Finalize_SHA256` should generate uppercase hex, validate that expectation. + for J in Text'Range loop + declare + C : constant Character := Text (J); + begin + if C in '0' .. '9' or else C in 'A' .. 'F' then + null; + else + AUnit.Assertions.Assert + (False, + Msg & ": expected uppercase hex at pos" & + Integer'Image (J)); + end if; + end; + end loop; + + AUnit.Assertions.Assert + (Actual = Expected, + Msg & ": Text/Hash mismatch"); + end Assert_Text_Matches_Hash; + + procedure Compute_SHA256 + (Input : WolfSSL.Byte_Array; + Hash : out WolfSSL.SHA256_Hash; + Text : out WolfSSL.SHA256_As_String; + 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, + Text => Text, + 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; + Text : WolfSSL.SHA256_As_String; + R : Integer; + + Input : constant WolfSSL.Byte_Array := Test_Support.Bytes ("asdf"); + + Expected_Text : constant WolfSSL.SHA256_As_String := + Test_Support.SHA256_Text + ("F0E4C2F76C58916EC258F246851BEA091D14D4247A2FC3E18694461B1816E13B"); + begin + Compute_SHA256 (Input => Input, Hash => Hash, Text => Text, Result => R); + + Test_Support.Assert_Success (R, "SHA256(asdf)"); + + AUnit.Assertions.Assert + (Text = Expected_Text, + "SHA256('asdf') hex mismatch. Got: " & Text); + + Assert_Text_Matches_Hash + (Hash => Hash, Text => Text, Msg => "SHA256('asdf')"); + end Test_SHA256_Asdf_Known_Vector; + + procedure Test_SHA256_Empty_Message (F : in out Fixture) is + pragma Unreferenced (F); + + Hash : WolfSSL.SHA256_Hash; + Text : WolfSSL.SHA256_As_String; + R : Integer; + + -- Represent empty input as a null range, matching the existing test style. + Empty : constant WolfSSL.Byte_Array := (1 .. 0 => <>); + + Expected_Text : constant WolfSSL.SHA256_As_String := + Test_Support.SHA256_Text + ("E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855"); + begin + Compute_SHA256 (Input => Empty, Hash => Hash, Text => Text, Result => R); + + Test_Support.Assert_Success (R, "SHA256(empty)"); + + AUnit.Assertions.Assert + (Text = Expected_Text, + "SHA256('') hex mismatch. Got: " & Text); + + Assert_Text_Matches_Hash + (Hash => Hash, + Text => Text, + Msg => "SHA256('')"); + 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; diff --git a/wrapper/Ada/tests/src/sha256_bindings_tests.ads b/wrapper/Ada/tests/src/sha256_bindings_tests.ads new file mode 100644 index 00000000000..6a4b3ae3b2d --- /dev/null +++ b/wrapper/Ada/tests/src/sha256_bindings_tests.ads @@ -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; \ No newline at end of file diff --git a/wrapper/Ada/tests/src/support/test_support.adb b/wrapper/Ada/tests/src/support/test_support.adb new file mode 100644 index 00000000000..5c65e646051 --- /dev/null +++ b/wrapper/Ada/tests/src/support/test_support.adb @@ -0,0 +1,97 @@ +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. + Last_N : constant Natural := (if S'Length = 0 then 0 else 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 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; + Last_N : constant Natural := (if N = 0 then 0 else 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 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; \ No newline at end of file diff --git a/wrapper/Ada/tests/src/support/test_support.ads b/wrapper/Ada/tests/src/support/test_support.ads new file mode 100644 index 00000000000..0be4f82915e --- /dev/null +++ b/wrapper/Ada/tests/src/support/test_support.ads @@ -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; \ No newline at end of file diff --git a/wrapper/Ada/tests/src/support/tests_root_suite.adb b/wrapper/Ada/tests/src/support/tests_root_suite.adb new file mode 100644 index 00000000000..a25320396d2 --- /dev/null +++ b/wrapper/Ada/tests/src/support/tests_root_suite.adb @@ -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; \ No newline at end of file diff --git a/wrapper/Ada/tests/src/support/tests_root_suite.ads b/wrapper/Ada/tests/src/support/tests_root_suite.ads new file mode 100644 index 00000000000..5f5f5499fae --- /dev/null +++ b/wrapper/Ada/tests/src/support/tests_root_suite.ads @@ -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; \ No newline at end of file diff --git a/wrapper/Ada/tests/src/tests.adb b/wrapper/Ada/tests/src/tests.adb new file mode 100644 index 00000000000..0ed6faa033b --- /dev/null +++ b/wrapper/Ada/tests/src/tests.adb @@ -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; \ No newline at end of file diff --git a/wrapper/Ada/tests/tests.gpr b/wrapper/Ada/tests/tests.gpr new file mode 100644 index 00000000000..363dc7d49b4 --- /dev/null +++ b/wrapper/Ada/tests/tests.gpr @@ -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; diff --git a/wrapper/Ada/tests/valgrind.supp b/wrapper/Ada/tests/valgrind.supp new file mode 100644 index 00000000000..340dc952073 --- /dev/null +++ b/wrapper/Ada/tests/valgrind.supp @@ -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 +} diff --git a/wrapper/Ada/wolfssl-full_runtime.adb b/wrapper/Ada/wolfssl-full_runtime.adb new file mode 100644 index 00000000000..3f154ae0958 --- /dev/null +++ b/wrapper/Ada/wolfssl-full_runtime.adb @@ -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; diff --git a/wrapper/Ada/wolfssl-full_runtime.ads b/wrapper/Ada/wolfssl-full_runtime.ads new file mode 100644 index 00000000000..c6b3e650ba8 --- /dev/null +++ b/wrapper/Ada/wolfssl-full_runtime.ads @@ -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; diff --git a/wrapper/Ada/wolfssl.adb b/wrapper/Ada/wolfssl.adb index 2f7caba0b01..81cc6243a0d 100644 --- a/wrapper/Ada/wolfssl.adb +++ b/wrapper/Ada/wolfssl.adb @@ -1,6 +1,6 @@ -- wolfssl.adb -- --- Copyright (C) 2006-2023 wolfSSL Inc. +-- Copyright (C) 2006-2025 wolfSSL Inc. -- -- This file is part of wolfSSL. -- @@ -20,12 +20,7 @@ -- with Ada.Unchecked_Conversion; -pragma Warnings (Off, "* is an internal GNAT unit"); -with GNAT.Sockets.Thin_Common; -pragma Warnings (On, "* is an internal GNAT unit"); -with Interfaces.C.Extensions; -with Interfaces.C.Strings; -with System; +with WolfSSL; package body WolfSSL is @@ -34,7 +29,11 @@ package body WolfSSL is subtype long is Interfaces.C.long; subtype unsigned_long is Interfaces.C.unsigned_long; - WOLFSSL_SUCCESS : constant int := Get_WolfSSL_Success; + -- The first value in the Byte_Type range (Byte_Type'First), + -- used as the null byte (0). + nul : constant Byte_Type := Byte_Type'First; + + -- WOLFSSL_SUCCESS : constant int := Get_WolfSSL_Success; function Initialize_WolfSSL return int with Convention => C, @@ -63,6 +62,11 @@ package body WolfSSL is return Context /= null; end Is_Valid; + function Is_Valid (Method : Method_Type) return Boolean is + begin + return Method /= null; + end Is_Valid; + function WolfTLSv1_2_Server_Method return Method_Type with Convention => C, External_Name => "wolfTLSv1_2_server_method", @@ -147,10 +151,11 @@ package body WolfSSL is return Context_Type with Convention => C, External_Name => "wolfSSL_CTX_new", Import => True; - procedure Create_Context (Method : Method_Type; + procedure Create_Context (Method : in out Method_Type; Context : out Context_Type) is begin Context := WolfSSL_CTX_new (Method); + Method := null; end Create_Context; procedure WolfSSL_CTX_free (Context : Context_Type) with @@ -158,7 +163,9 @@ package body WolfSSL is procedure Free (Context : in out Context_Type) is begin - WolfSSL_CTX_free (Context); + if Context /= null then + WolfSSL_CTX_free (Context); + end if; Context := null; end Free; @@ -214,24 +221,32 @@ package body WolfSSL is procedure Set_Verify (Context : Context_Type; Mode : Mode_Type) is + pragma Warnings (Off, "pragma Restrictions (No_Exception_Propagation)"); + -- The values that Set_Verify may be called with have first + -- been int values, then converted into Mode_Type values and + -- here they are converted back to int. This can never fail + -- unless there is hardware failure or cosmic radiation has + -- done a bit flip. + V : constant int := int (Mode); + pragma Warnings (On, "pragma Restrictions (No_Exception_Propagation)"); begin WolfSSL_CTX_Set_Verify (Context => Context, - Mode => int (Mode), + Mode => V, Callback => null); end Set_Verify; - function WolfSSL_Get_Verify(Context : Context_Type) return int with + function WolfSSL_Get_Verify (Context : Context_Type) return int with Convention => C, External_Name => "wolfSSL_CTX_get_verify_mode", Import => True; function Get_Verify (Context : Context_Type) return Mode_Type is begin - return Mode_Type (WolfSSL_Get_Verify(Context)); + return Mode_Type (WolfSSL_Get_Verify (Context)); end Get_Verify; function Use_Certificate_File (Context : Context_Type; - File : char_array; + File : Byte_Array; Format : int) return int with Convention => C, @@ -242,30 +257,35 @@ package body WolfSSL is File : String; Format : File_Format) return Subprogram_Result is - Ctx : constant Context_Type := Context; - C : size_t; - F : char_array (1 .. File'Length + 1); - Result : int; begin - Interfaces.C.To_C (Item => File, - Target => F, - Count => C, - Append_Nul => True); - Result := Use_Certificate_File (Ctx, F (1 .. C), int (Format)); - return Subprogram_Result (Result); + declare + Ctx : constant Context_Type := Context; + F : Byte_Array (1 .. File'Length + 1); + Result : int; + begin + for I in File'Range loop + F (F'First + Byte_Index (I - File'First)) := Byte_Type (File (I)); + end loop; + F (F'Last) := nul; + Result := Use_Certificate_File (Ctx, F, int (Format)); + return Subprogram_Result (Result); + end; + exception + when others => + return Exception_Error; end Use_Certificate_File; function Use_Certificate_Buffer (Context : Context_Type; - Input : char_array; + Input : Byte_Array; Size : long; Format : int) return int with - Convention => C, - External_Name => "wolfSSL_CTX_use_certificate_buffer", - Import => True; + Convention => C, + External_Name => "wolfSSL_CTX_use_certificate_buffer", + Import => True; function Use_Certificate_Buffer (Context : Context_Type; - Input : char_array; + Input : Byte_Array; Format : File_Format) return Subprogram_Result is Result : int; @@ -273,10 +293,13 @@ package body WolfSSL is Result := Use_Certificate_Buffer (Context, Input, Input'Length, int (Format)); return Subprogram_Result (Result); + exception + when others => + return Exception_Error; end Use_Certificate_Buffer; function Use_Private_Key_File (Context : Context_Type; - File : char_array; + File : Byte_Array; Format : int) return int with Convention => C, @@ -287,21 +310,26 @@ package body WolfSSL is File : String; Format : File_Format) return Subprogram_Result is - Ctx : constant Context_Type := Context; - C : size_t; - F : char_array (1 .. File'Length + 1); - Result : int; begin - Interfaces.C.To_C (Item => File, - Target => F, - Count => C, - Append_Nul => True); - Result := Use_Private_Key_File (Ctx, F (1 .. C), int (Format)); - return Subprogram_Result (Result); + declare + Ctx : constant Context_Type := Context; + F : Byte_Array (1 .. File'Length + 1); + Result : int; + begin + for I in File'Range loop + F (F'First + Byte_Index (I - File'First)) := Byte_Type (File (I)); + end loop; + F (F'Last) := Byte_Type'Val (0); + Result := Use_Private_Key_File (Ctx, F, int (Format)); + return Subprogram_Result (Result); + end; + exception + when others => + return Exception_Error; end Use_Private_Key_File; function Use_Private_Key_Buffer (Context : Context_Type; - Input : char_array; + Input : Byte_Array; Size : long; Format : int) return int with @@ -318,15 +346,18 @@ package body WolfSSL is Result := Use_Private_Key_Buffer (Context, Input, Input'Length, int (Format)); return Subprogram_Result (Result); + exception + when others => + return Exception_Error; end Use_Private_Key_Buffer; function Load_Verify_Locations1 - (Context : Context_Type; - File : char_array; - Path : char_array) return int with - Convention => C, - External_Name => "wolfSSL_CTX_load_verify_locations", - Import => True; + (Context : Context_Type; + File : Byte_Array; + Path : Byte_Array) return int with + Convention => C, + External_Name => "wolfSSL_CTX_load_verify_locations", + Import => True; -- This function loads PEM-formatted CA certificate files into -- the SSL context (WOLFSSL_CTX). These certificates will be treated -- as trusted root certificates and used to verify certs received @@ -343,87 +374,86 @@ package body WolfSSL is -- attempt to load all files in the directory. This function expects -- PEM formatted CERT_TYPE file with header "--BEGIN CERTIFICATE--". - subtype char_array_ptr is Interfaces.C.Strings.char_array_access; - function Load_Verify_Locations2 - (Context : Context_Type; - File : char_array; - Path : char_array_ptr) return int with - Convention => C, - External_Name => "wolfSSL_CTX_load_verify_locations", - Import => True; + (Context : Context_Type; + File : Byte_Array; + Path : access Interfaces.C.char) return int with + Convention => C, + External_Name => "wolfSSL_CTX_load_verify_locations", + Import => True; function Load_Verify_Locations3 - (Context : Context_Type; - File : char_array_ptr; - Path : char_array) return int with - Convention => C, - External_Name => "wolfSSL_CTX_load_verify_locations", - Import => True; + (Context : Context_Type; + File : access Interfaces.C.char; + Path : Byte_Array) return int with + Convention => C, + External_Name => "wolfSSL_CTX_load_verify_locations", + Import => True; function Load_Verify_Locations4 - (Context : Context_Type; - File : char_array_ptr; - Path : char_array_ptr) return int with - Convention => C, - External_Name => "wolfSSL_CTX_load_verify_locations", - Import => True; + (Context : Context_Type; + File : access Interfaces.C.char; + Path : access Interfaces.C.char) return int with + Convention => C, + External_Name => "wolfSSL_CTX_load_verify_locations", + Import => True; function Load_Verify_Locations (Context : Context_Type; File : String; Path : String) return Subprogram_Result is - Ctx : constant Context_Type := Context; - FC : size_t; -- File Count, specifies the characters used in F. - F : aliased char_array := (1 .. File'Length + 1 => '#'); - - PC : size_t; -- Path Count, specifies the characters used in P. - P : aliased char_array := (1 .. Path'Length + 1 => '#'); - - Result : int; begin - if File = "" then - if Path = "" then - Result := Load_Verify_Locations4 (Ctx, null, null); + declare + Ctx : constant Context_Type := Context; + F : aliased Byte_Array := (1 .. File'Length + 1 => '#'); + P : aliased Byte_Array := (1 .. Path'Length + 1 => '#'); + Result : int; + begin + if File = "" then + if Path = "" then + Result := Load_Verify_Locations4 (Ctx, null, null); + else + for I in Path'Range loop + P (P'First + Byte_Index (I - Path'First)) := + Byte_Type (Path (I)); + end loop; + P (P'Last) := nul; + Result := Load_Verify_Locations3 (Ctx, null, P); + end if; else - Interfaces.C.To_C (Item => Path, - Target => P, - Count => PC, - Append_Nul => True); - Result := Load_Verify_Locations3 (Ctx, null, P); + for I in File'Range loop + F (F'First + Byte_Index (I - File'First)) := + Byte_Type (File (I)); + end loop; + F (F'Last) := nul; + if Path = "" then + Result := Load_Verify_Locations2 (Ctx, F, null); + else + for I in Path'Range loop + P (P'First + Byte_Index (I - Path'First)) := + Byte_Type (Path (I)); + end loop; + P (P'Last) := nul; + Result := Load_Verify_Locations1 (Context => Ctx, + File => F, + Path => P); + end if; end if; - else - Interfaces.C.To_C (Item => File, - Target => F, - Count => FC, - Append_Nul => True); - if Path = "" then - Result := Load_Verify_Locations2 (Ctx, F, null); - else - Interfaces.C.To_C (Item => Path, - Target => P, - Count => PC, - Append_Nul => True); - Interfaces.C.To_C (Item => Path, - Target => P, - Count => PC, - Append_Nul => True); - Result := Load_Verify_Locations1 (Context => Ctx, - File => F, - Path => P); - end if; - end if; - return Subprogram_Result (Result); + return Subprogram_Result (Result); + end; + exception + when others => + return Exception_Error; end Load_Verify_Locations; function Load_Verify_Buffer - (Context : Context_Type; - Input : char_array; - Size : int; - Format : int) return int with - Convention => C, - External_Name => "wolfSSL_CTX_load_verify_buffer", - Import => True; + (Context : Context_Type; + Input : Byte_Array; + Size : int; + Format : int) return int with + Convention => C, + External_Name => "wolfSSL_CTX_load_verify_buffer", + Import => True; function Load_Verify_Buffer (Context : Context_Type; Input : Byte_Array; @@ -432,10 +462,13 @@ package body WolfSSL is Result : int; begin Result := Load_Verify_Buffer (Context => Context, - Input => Input, - Size => Input'Length, - Format => int(Format)); + Input => Input, + Size => Input'Length, + Format => int(Format)); return Subprogram_Result (Result); + exception + when others => + return Exception_Error; end Load_Verify_Buffer; function Is_Valid (Ssl : WolfSSL_Type) return Boolean is @@ -456,7 +489,7 @@ package body WolfSSL is end Create_WolfSSL; function Use_Certificate_File (Ssl : WolfSSL_Type; - File : char_array; + File : Byte_Array; Format : int) return int with Convention => C, @@ -467,29 +500,35 @@ package body WolfSSL is File : String; Format : File_Format) return Subprogram_Result is - C : size_t; - F : char_array (1 .. File'Length + 1); - Result : int; begin - Interfaces.C.To_C (Item => File, - Target => F, - Count => C, - Append_Nul => True); - Result := Use_Certificate_File (Ssl, F (1 .. C), int (Format)); - return Subprogram_Result (Result); + declare + F : Byte_Array (1 .. File'Length + 1); + Result : int; + begin + for I in File'Range loop + F (F'First + Byte_Index (I - File'First)) := + Byte_Type (File (I)); + end loop; + F (F'Last) := nul; + Result := Use_Certificate_File (Ssl, F, int (Format)); + return Subprogram_Result (Result); + end; + exception + when others => + return Exception_Error; end Use_Certificate_File; function Use_Certificate_Buffer (Ssl : WolfSSL_Type; - Input : char_array; + Input : Byte_Array; Size : long; Format : int) return int with - Convention => C, - External_Name => "wolfSSL_use_certificate_buffer", - Import => True; + Convention => C, + External_Name => "wolfSSL_use_certificate_buffer", + Import => True; function Use_Certificate_Buffer (Ssl : WolfSSL_Type; - Input : char_array; + Input : Byte_Array; Format : File_Format) return Subprogram_Result is Result : int; @@ -497,34 +536,42 @@ package body WolfSSL is Result := Use_Certificate_Buffer (Ssl, Input, Input'Length, int (Format)); return Subprogram_Result (Result); + exception + when others => + return Exception_Error; end Use_Certificate_Buffer; function Use_Private_Key_File (Ssl : WolfSSL_Type; - File : char_array; + File : Byte_Array; Format : int) - return int with - Convention => C, - External_Name => "wolfSSL_use_PrivateKey_file", - Import => True; + return int with + Convention => C, + External_Name => "wolfSSL_use_PrivateKey_file", + Import => True; function Use_Private_Key_File (Ssl : WolfSSL_Type; File : String; Format : File_Format) return Subprogram_Result is - C : size_t; - F : char_array (1 .. File'Length + 1); - Result : int; begin - Interfaces.C.To_C (Item => File, - Target => F, - Count => C, - Append_Nul => True); - Result := Use_Private_Key_File (Ssl, F (1 .. C), int (Format)); - return Subprogram_Result (Result); + declare + F : Byte_Array (1 .. File'Length + 1); + Result : int; + begin + for I in File'Range loop + F (F'First + Byte_Index (I - File'First)) := Byte_Type (File (I)); + end loop; + F (F'Last) := nul; + Result := Use_Private_Key_File (Ssl, F, int (Format)); + return Subprogram_Result (Result); + end; + exception + when others => + return Exception_Error; end Use_Private_Key_File; function Use_Private_Key_Buffer (Ssl : WolfSSL_Type; - Input : char_array; + Input : Byte_Array; Size : long; Format : int) return int with @@ -541,88 +588,11 @@ package body WolfSSL is Result := Use_Private_Key_Buffer (Ssl, Input, Input'Length, int (Format)); return Subprogram_Result (Result); + exception + when others => + return Exception_Error; end Use_Private_Key_Buffer; - 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))); - - 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; - function WolfSSL_Set_Fd (Ssl : WolfSSL_Type; Fd : int) return int with Convention => C, External_Name => "wolfSSL_set_fd", @@ -631,15 +601,15 @@ package body WolfSSL is function Attach (Ssl : WolfSSL_Type; Socket : Integer) return Subprogram_Result is - Result : int := WolfSSL_Set_Fd (Ssl, int (Socket)); + Result : constant int := WolfSSL_Set_Fd (Ssl, int (Socket)); begin return Subprogram_Result (Result); end Attach; procedure WolfSSL_Keep_Arrays (Ssl : WolfSSL_Type) with - Convention => C, - External_Name => "wolfSSL_KeepArrays", - Import => True; + Convention => C, + External_Name => "wolfSSL_KeepArrays", + Import => True; procedure Keep_Arrays (Ssl : WolfSSL_Type) is begin @@ -653,7 +623,7 @@ package body WolfSSL is function Accept_Connection (Ssl : WolfSSL_Type) return Subprogram_Result is - Result : int := WolfSSL_Accept (Ssl); + Result : constant int := WolfSSL_Accept (Ssl); begin return Subprogram_Result (Result); end Accept_Connection; @@ -669,7 +639,7 @@ package body WolfSSL is end Free_Arrays; function WolfSSL_Read (Ssl : WolfSSL_Type; - Data : out char_array; + Data : out Byte_Array; Sz : int) return int with Convention => C, External_Name => "wolfSSL_read", @@ -704,41 +674,60 @@ package body WolfSSL is -- and and the application needs to call wolfSSL_read() again. -- Use wolfSSL_get_error() to get a specific error code. - function Read (Ssl : WolfSSL_Type) return Read_Result is - Data : char_array (1 .. Byte_Index'Last); - Size : int; + procedure Read (Ssl : WolfSSL_Type; + Result : out Read_Result) is begin - Size := WolfSSL_Read (Ssl, Data, int (Byte_Index'Last)); - if Size <= 0 then - return (Success => False, + Result := (Success => False, -- In case of exception. Last => 0, - Code => Subprogram_Result (Size)); - else - return (Success => True, - Last => Byte_Index (Size), - Buffer => Data (1 .. Byte_Index (Size))); - end if; + Code => Subprogram_Result (Exception_Error)); + declare + Data : Byte_Array (1 .. Byte_Index'Last); + Size : int; + begin + Size := WolfSSL_Read (Ssl, Data, int (Byte_Index'Last)); + if Size <= 0 then + Result := (Success => False, + Last => 0, + Code => Subprogram_Result (Size)); + else + Result := (Success => True, + Last => Byte_Index (Size), + Buffer => Data (1 .. Byte_Index (Size))); + end if; + end; + exception + when others => + null; end Read; function WolfSSL_Write (Ssl : WolfSSL_Type; - Data : char_array; + Data : Byte_Array; Sz : int) return int with Convention => C, External_Name => "wolfSSL_write", Import => True; - function Write (Ssl : WolfSSL_Type; - Data : Byte_Array) return Write_Result is - Size : constant int := Data'Length; - Result : int; + procedure Write (Ssl : WolfSSL_Type; + Data : Byte_Array; + Result : out Write_Result) is begin - Result := WolfSSL_Write (Ssl, Data, Size); - if Result > 0 then - return (Success => True, - Bytes_Written => Byte_Index (Result)); - else - return (Success => False, Code => Subprogram_Result (Result)); - end if; + Result := (Success => False, + Code => Subprogram_Result (Exception_Error)); + declare + Size : constant int := Data'Length; + R : int; + begin + R := WolfSSL_Write (Ssl, Data, Size); + if R > 0 then + Result := (Success => True, + Bytes_Written => Byte_Index (R)); + else + Result := (Success => False, Code => Subprogram_Result (R)); + end if; + end; + exception + when others => + null; end Write; function WolfSSL_Shutdown (Ssl : WolfSSL_Type) return int with @@ -753,9 +742,9 @@ package body WolfSSL is end Shutdown; function WolfSSL_Connect (Ssl : WolfSSL_Type) return int with - Convention => C, - External_Name => "wolfSSL_connect", - Import => True; + Convention => C, + External_Name => "wolfSSL_connect", + Import => True; function Connect (Ssl : WolfSSL_Type) return Subprogram_Result is Result : constant int := WolfSSL_Connect (Ssl); @@ -764,9 +753,9 @@ package body WolfSSL is end Connect; procedure WolfSSL_Free (Ssl : WolfSSL_Type) with - Convention => C, - External_Name => "wolfSSL_free", - Import => True; + Convention => C, + External_Name => "wolfSSL_free", + Import => True; procedure Free (Ssl : in out WolfSSL_Type) is begin @@ -778,9 +767,9 @@ package body WolfSSL is function WolfSSL_Get_Error (Ssl : WolfSSL_Type; Ret : int) return int with - Convention => C, - External_Name => "wolfSSL_get_error", - Import => True; + Convention => C, + External_Name => "wolfSSL_get_error", + Import => True; function Get_Error (Ssl : WolfSSL_Type; Result : Subprogram_Result) return Error_Code is @@ -791,29 +780,43 @@ package body WolfSSL is procedure WolfSSL_Error_String (Error : unsigned_long; Data : out Byte_Array; Size : unsigned_long) with - Convention => C, - External_Name => "wolfSSL_ERR_error_string_n", - Import => True; - - function Error (Code : Error_Code) return Error_Message is - S : String (1 .. Error_Message_Index'Last); - B : Byte_Array (1 .. size_t (Error_Message_Index'Last)); - C : Natural; + Convention => C, + External_Name => "wolfSSL_ERR_error_string_n", + Import => True; + + procedure Error (Code : in Error_Code; + Message : in out Error_Message) is + use type Byte_Type; -- Use unchecked conversion instead of type conversion to mimic C style -- conversion from int to unsigned long, avoiding the Ada overflow check. function To_Unsigned_Long is new Ada.Unchecked_Conversion - (Source => long, - Target => unsigned_long); - begin - WolfSSL_Error_String (Error => To_Unsigned_Long (long (Code)), - Data => B, - Size => To_Unsigned_Long (long (B'Last))); - Interfaces.C.To_Ada (Item => B, - Target => S, - Count => C, - Trim_Nul => True); - return (Last => C, - Text => S (1 .. C)); + (Source => long, + Target => unsigned_long); + begin + declare + S : String (1 .. Error_Message_Index'Last); + B : Byte_Array (1 .. size_t (Error_Message_Index'Last)); + L : Positive; + begin + WolfSSL_Error_String (Error => To_Unsigned_Long (long (Code)), + Data => B, + Size => To_Unsigned_Long (long (B'Last))); + for I in B'Range loop + L := S'First + Natural (I - B'First); + S (L) := Character (B (I)); + exit when B (I) = nul; + end loop; + if S (L) = Character (nul) then + Message := (Last => L - 1, + Text => S (1 .. L - 1)); + else + Message := (Last => L, + Text => S (1 .. L)); + end if; + end; + exception + when others => + null; end Error; function Get_WolfSSL_Max_Error_Size return int with @@ -826,4 +829,740 @@ package body WolfSSL is return Natural (Get_WolfSSL_Max_Error_Size); end Max_Error_Size; + function Is_Valid (Key : RNG_Key_Type) return Boolean is + begin + return Key /= null; + end Is_Valid; + + function Ada_New_RNG return RNG_Key_Type with + Convention => C, + External_Name => "ada_new_rng", + Import => True; + + procedure Ada_Free_RNG (Key : in RNG_Key_Type) with + Convention => C, + External_Name => "ada_free_rng", + Import => True; + + + + procedure Free_RNG (Key : in out RNG_Key_Type) is + begin + if Key = null then + return; + end if; + + -- wc_rng_free() already calls wc_FreeRng() internally. + Ada_Free_RNG (Key); + + -- Prevent accidental double-free and make Is_Valid return False. + Key := null; + end Free_RNG; + + procedure Create_RNG (Key : in out RNG_Key_Type; + Result : out Integer) is + begin + declare + R : int; + begin + -- Allocate RNG using the C wrapper, which internally calls + -- wc_rng_new(NULL, 0, NULL) as required. + Key := Ada_New_RNG; + + if Key = null then + Result := Exception_Error; + return; + end if; + + -- wc_rng_new() already calls wc_InitRng() internally, so no extra init. + Result := 0; + end; + exception + when others => + Result := Exception_Error; + end Create_RNG; + + function WC_RNG_Generate_Block (RNG : not null RNG_Key_Type; + Output : out Byte_Array; + Size : int) return int with + Convention => C, + External_Name => "wc_RNG_GenerateBlock", + Import => True; + + procedure RNG_Generate_Block (RNG : RNG_Key_Type; + Output : out Byte_Array; + Result : out Integer) is + begin + declare + R : int; + begin + R := WC_RNG_Generate_Block (RNG, Output, Output'Length); + Result := Integer (R); + end; + exception + when others => + Result := Exception_Error; + end RNG_Generate_Block; + + 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; + + function WC_PBKDF2 (Output : out Byte_Array; + Password : Byte_Array; + P_Length : int; + Salt : Byte_Array; + S_Length : int; + Iterations : int; + Key_Length : int; + Hash_Type : int) return int with + Convention => C, + External_Name => "wc_PBKDF2", + Import => True; + + function Ada_MD5 return int with + Convention => C, + External_Name => "ada_md5", + Import => True; + + function Ada_SHA return int with + Convention => C, + External_Name => "ada_sha", + Import => True; + + function Ada_SHA256 return int with + Convention => C, + External_Name => "ada_sha256", + Import => True; + + function Ada_SHA384 return int with + Convention => C, + External_Name => "ada_sha384", + Import => True; + + function Ada_SHA512 return int with + Convention => C, + External_Name => "ada_sha512", + Import => True; + + function Ada_SHA3_224 return int with + Convention => C, + External_Name => "ada_sha3_224", + Import => True; + + function Ada_SHA3_256 return int with + Convention => C, + External_Name => "ada_sha3_256", + Import => True; + + function Ada_SHA3_384 return int with + Convention => C, + External_Name => "ada_sha3_384", + Import => True; + + function Ada_SHA3_512 return int with + Convention => C, + External_Name => "ada_sha3_512", + Import => True; + + procedure PBKDF2 (Output : out Byte_Array; + Password : Byte_Array; + Salt : Byte_Array; + Iterations : Positive; + Key_Length : Positive; + HMAC : HMAC_Hash; + Result : out Integer) is + begin + declare + R : int; + H : int; + begin + case HMAC is + when MD5 => H := Ada_MD5; + when SHA => H := Ada_SHA; + when SHA256 => H := Ada_SHA256; + when SHA384 => H := Ada_SHA384; + when SHA512 => H := Ada_SHA512; + when SHA3_224 => H := Ada_SHA3_224; + when SHA3_256 => H := Ada_SHA3_256; + when SHA3_384 => H := Ada_SHA3_384; + when SHA3_512 => H := Ada_SHA3_512; + end case; + R := WC_PBKDF2 (Output => Output, + Password => Password, + P_Length => Password'Length, + Salt => Salt, + S_Length => Salt'Length, + Iterations => int (Iterations), + Key_Length => int (Key_Length), + Hash_Type => H); + Result := Integer (R); + end; + exception + when others => + Result := Exception_Error; + end PBKDF2; + + function Ada_RSA_Set_RNG (Key : not null RSA_Key_Type; + RNG : not null RNG_Key_Type) return int with + Convention => C, + External_Name => "ada_RsaSetRNG", + Import => True; + + procedure Rsa_Set_RNG (Key : in out Rsa_Key_Type; + RNG : in out RNG_Key_Type; + Result : out Integer) is + begin + declare + R : int; + begin + R := Ada_RSA_Set_RNG (Key, RNG); + Result := Integer (R); + end; + exception + when others => + Result := Exception_Error; + end Rsa_Set_RNG; + + function Is_Valid (Key : RSA_Key_Type) return Boolean is + begin + return Key /= null; + end Is_Valid; + + function Ada_New_RSA return RSA_Key_Type with + Convention => C, + External_Name => "ada_new_rsa", + Import => True; + + procedure Ada_Free_RSA (Key : in RSA_Key_Type) with + Convention => C, + External_Name => "ada_free_rsa", + Import => True; + + procedure Free_RSA (Key : in out RSA_Key_Type) is + begin + if Key = null then + return; + end if; + + -- wc_DeleteRsaKey() already calls wc_FreeRsaKey() internally. + Ada_Free_RSA (Key); + + -- Prevent accidental double-free and make Is_Valid return False. + Key := null; + end Free_RSA; + + procedure Create_RSA (Key : in out RSA_Key_Type; + Result : out Integer) is + begin + -- Allocate and initialize RSA key using the C wrapper. + -- The wrapper uses wc_NewRsaKey() and returns NULL on failure. + Key := Ada_New_RSA; + + if Key = null then + Result := Exception_Error; + return; + end if; + + -- wc_NewRsaKey() already calls wc_InitRsaKey_ex() internally. + Result := 0; + + exception + when others => + -- Avoid leaking the dynamically allocated RSA key on failure. + if Key /= null then + Ada_Free_RSA (Key); + Key := null; + end if; + Result := Exception_Error; + end Create_RSA; + + function RSA_Public_Key_Decode (Input : Byte_Array; + Index : in out int; + Key : not null RSA_Key_Type; + Size : int) return int with + Convention => C, + External_Name => "wc_RsaPublicKeyDecode", + Import => True; + + procedure Rsa_Public_Key_Decode (Input : Byte_Array; + Index : in out Byte_Index; + Key : in out RSA_Key_Type; + Size : Integer; + Result : out Integer) is + begin + declare + I : aliased int := int (Index); + R : constant int := + RSA_Public_Key_Decode (Input, I, Key, int (Size)); + begin + Index := WolfSSL.Byte_Index (I); + Result := Integer (R); + end; + exception + when others => + Result := Exception_Error; + end Rsa_Public_Key_Decode; + + function RSA_Private_Key_Decode (Input : Byte_Array; + Index : in out int; + Key : not null RSA_Key_Type; + Size : int) return int with + Convention => C, + External_Name => "wc_RsaPrivateKeyDecode", + Import => True; + + procedure Rsa_Private_Key_Decode (Input : Byte_Array; + Index : in out Byte_Index; + Key : in out RSA_Key_Type; + Size : Integer; + Result : out Integer) is + begin + declare + I : aliased int := int (Index); + R : constant int := + RSA_Private_Key_Decode (Input, I, Key, int (Size)); + begin + Index := WolfSSL.Byte_Index (I); + Result := Integer (R); + end; + exception + when others => + Result := Exception_Error; + end Rsa_Private_Key_Decode; + + function RSA_SSL_Sign (Input : Byte_Array; + In_Length : int; + Output : in out Byte_Array; + Out_Length : int; + RSA : not null RSA_Key_Type; + RNG : not null RNG_Key_Type) + return int with + Convention => C, + External_Name => "wc_RsaSSL_Sign", + Import => True; + + procedure Rsa_SSL_Sign (Input : Byte_Array; + Output : in out Byte_Array; + RSA : in out RSA_Key_Type; + RNG : in out RNG_Key_Type; + Result : out Integer) is + begin + declare + R : constant int := + RSA_SSL_Sign (Input, + Input'Length, + Output, + Output'Length, + RSA, + RNG); + begin + Result := Integer (R); + end; + exception + when others => + Result := Exception_Error; + end Rsa_SSL_Sign; + + function WC_RSA_SSL_Verify (Input : Byte_Array; + In_Length : int; + Output : in out Byte_Array; + Out_Length : int; + RSA : not null RSA_Key_Type) + return int with + Convention => C, + External_Name => "wc_RsaSSL_Verify", + Import => True; + + procedure Rsa_SSL_Verify (Input : Byte_Array; + Output : in out Byte_Array; + RSA : in out RSA_Key_Type; + Result : out Integer) is + begin + declare + R : constant int := + WC_RSA_SSL_Verify (Input, + Input'Length, + Output, + Output'Length, + RSA); + begin + Result := Integer (R); + end; + exception + when others => + Result := Exception_Error; + end Rsa_SSL_Verify; + + function WC_RSA_Public_Encrypt (Input : Byte_Array; + In_Length : int; + Output : in out Byte_Array; + Out_Length : int; + RSA : not null RSA_Key_Type; + RNG : not null RNG_Key_Type) + return int with + Convention => C, + External_Name => "wc_RsaPublicEncrypt", + Import => True; + + 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_Key_Type; + Result : out Integer) is + begin + Index := 0; + declare + R : constant int := + WC_RSA_Public_Encrypt (Input, + Input'Length, + Output, + Output'Length, + RSA, + RNG); + begin + Result := Integer (R); + if Result >= 0 then + Index := Byte_Index (Result); + end if; + end; + exception + when others => + Result := Exception_Error; + end RSA_Public_Encrypt; + + function WC_RSA_Private_Decrypt (Input : Byte_Array; + In_Length : int; + Output : in out Byte_Array; + Out_Length : int; + RSA : not null RSA_Key_Type) + return int with + Convention => C, + External_Name => "wc_RsaPrivateDecrypt", + Import => True; + + 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) is + begin + Index := 0; + declare + R : constant int := + WC_RSA_Private_Decrypt (Input, + Input'Length, + Output, + Output'Length, + RSA); + begin + Result := Integer (R); + if Result >= 0 then + Index := Byte_Index (Result); + end if; + end; + exception + when others => + Result := Exception_Error; + end RSA_Private_Decrypt; + + function Init_SHA256 (SHA256 : not null Sha256_Type) return int with + Convention => C, + External_Name => "wc_InitSha256", + Import => True; + + function SHA256_Update (SHA256 : not null Sha256_Type; + Byte : Byte_Array; + Length : int) return int with + Convention => C, + External_Name => "wc_Sha256Update", + Import => True; + + function SHA256_Final (SHA256 : not null Sha256_Type; + Hash : out Byte_Array) return int with + Convention => C, + External_Name => "wc_Sha256Final", + Import => True; + + function Is_Valid (SHA256 : SHA256_Type) return Boolean is + begin + return SHA256 /= null; + end Is_Valid; + + function Ada_New_SHA256 return SHA256_Type with + Convention => C, + External_Name => "ada_new_sha256", + Import => True; + + procedure Ada_Free_SHA256 (SHA256 : in SHA256_Type) with + Convention => C, + External_Name => "ada_free_sha256", + Import => True; + + procedure Free_SHA256 (SHA256 : in out SHA256_Type) is + -- Ensure any internal wolfCrypt resources are released (hardware locks, + -- etc.) before releasing the object storage itself. + procedure WC_Sha256_Free (SHA256 : not null SHA256_Type) with + Convention => C, + External_Name => "wc_Sha256Free", + Import => True; + begin + if SHA256 = null then + return; + end if; + + WC_Sha256_Free (SHA256); + Ada_Free_SHA256 (SHA256); + + -- Prevent accidental double-free and make Is_Valid return False. + SHA256 := null; + end Free_SHA256; + + procedure Create_SHA256 (SHA256 : in out SHA256_Type; + Result : out Integer) is + begin + declare + R : int; + begin + SHA256 := Ada_New_SHA256; + + if SHA256 = null then + Result := Exception_Error; + return; + end if; + + R := Init_SHA256 (SHA256); + Result := Integer (R); + + if Result /= 0 then + -- Avoid leaking the dynamically allocated SHA256 on init failure. + -- Also clear the handle to prevent accidental double-free by caller. + Ada_Free_SHA256 (SHA256); + SHA256 := null; + end if; + end; + exception + when others => + Result := Exception_Error; + end Create_SHA256; + + procedure Update_SHA256 (SHA256 : in out SHA256_Type; + Byte : Byte_Array; + Result : out Integer) is + begin + declare + R : int; + begin + R := SHA256_Update (SHA256, Byte, Byte'Length); + Result := Integer (R); + end; + exception + when others => + Result := Exception_Error; + end Update_SHA256; + + procedure Finalize_SHA256 (SHA256 : in out SHA256_Type; + Hash : out SHA256_Hash; + Text : out SHA256_As_String; + Result : out Integer) is + subtype Unsigned_8 is Interfaces.Unsigned_8; + + use type Unsigned_8; + + R : int; + Hex_Chars : constant array (Unsigned_8 range 0 .. 15) of Character := + "0123456789ABCDEF"; + I : Integer; + C : Integer; + begin + R := SHA256_Final (SHA256, Hash); + Result := Integer (R); + for Index in Positive range 1 .. 32 loop + I := 2 * (Index - 1) + 1; + C := Interfaces.C.char'Pos (Hash (size_t (Index))); + Text (I+0) := Hex_Chars ((Unsigned_8 (C) and 16#F0#) / 16); + Text (I+1) := Hex_Chars (Unsigned_8 (C) and 16#0F#); + end loop; + exception + when others => + Result := Exception_Error; + end Finalize_SHA256; + + function WC_Get_Invalid_Device_Identifier return int with + Convention => C, + External_Name => "get_wolfssl_invalid_devid", + Import => True; + + function Invalid_Device return Device_Identifier is + begin + return Device_Identifier (WC_Get_Invalid_Device_Identifier); + end Invalid_Device; + + function Is_Valid (AES : AES_Type) return Boolean is + begin + return AES /= null; + end Is_Valid; + + function Ada_New_AES (Device : int) + return AES_Type with + Convention => C, + External_Name => "ada_new_aes", + Import => True; + + procedure Ada_Free_AES (AES : in AES_Type) with + Convention => C, + External_Name => "ada_free_aes", + Import => True; + + procedure Create_AES (Device : Device_Identifier; + AES : in out AES_Type; + Result : out Integer) is + begin + declare + R : int; + begin + -- Allocate and initialize AES using the C wrapper. + -- The wrapper is expected to call wc_AesNew(NULL, devId, &ret) and + -- return NULL on failure. + AES := Ada_New_AES (int (Device)); + + if AES = null then + Result := Exception_Error; + return; + end if; + + -- wc_AesNew() already calls wc_AesInit() internally, so no extra init. + Result := 0; + end; + exception + when others => + -- Avoid leaking the dynamically allocated AES on failure. + if AES /= null then + Ada_Free_AES (AES); + AES := null; + end if; + Result := Exception_Error; + end Create_AES; + + function AES_Set_Key (AES : not null AES_Type; + Key : Byte_Array; + Length : int; + IV : Byte_Array; + Dir : int) return int with + Convention => C, + External_Name => "wc_AesSetKey", + Import => True; + + procedure AES_Set_Key (AES : AES_Type; + Key : Byte_Array; + Length : Integer; + IV : Byte_Array; + Dir : Integer; + Result : out Integer) is + begin + declare + R : int; + begin + R := AES_Set_Key (AES, Key, int (Length), IV, int (Dir)); + Result := Integer (R); + end; + exception + when others => + Result := Exception_Error; + end AES_Set_Key; + + function AES_Set_IV (AES : not null AES_Type; + IV : Byte_Array) return int with + Convention => C, + External_Name => "wc_AesSetIV", + Import => True; + + procedure AES_Set_IV (AES : AES_Type; + IV : Byte_Array; + Result : out Integer) is + begin + declare + R : int; + begin + R := AES_Set_IV (AES, IV); + Result := Integer (R); + end; + exception + when others => + Result := Exception_Error; + end AES_Set_IV; + + function AES_Set_Cbc_Encrypt (AES : not null AES_Type; + Output : out Byte_Array; + Input : Byte_Array; + Size : int) return int with + Convention => C, + External_Name => "wc_AesCbcEncrypt", + Import => True; + + procedure AES_Set_Cbc_Encrypt (AES : AES_Type; + Output : out Byte_Array; + Input : Byte_Array; + Size : Integer; + Result : out Integer) is + begin + declare + R : int; + begin + R := AES_Set_Cbc_Encrypt (AES, Output, Input, int (Size)); + Result := Integer (R); + end; + exception + when others => + Result := Exception_Error; + end AES_Set_Cbc_Encrypt; + + function AES_Set_Cbc_Decrypt (AES : not null AES_Type; + Output : out Byte_Array; + Input : Byte_Array; + Size : int) return int with + Convention => C, + External_Name => "wc_AesCbcDecrypt", + Import => True; + + procedure AES_Set_Cbc_Decrypt (AES : AES_Type; + Output : out Byte_Array; + Input : Byte_Array; + Size : Integer; + Result : out Integer) is + begin + declare + R : int; + begin + R := AES_Set_Cbc_Decrypt (AES, Output, Input, int (Size)); + Result := Integer (R); + end; + exception + when others => + Result := Exception_Error; + end AES_Set_Cbc_Decrypt; + + procedure AES_Free (AES : in out AES_Type; + Result : out Integer) is + begin + if AES = null then + Result := Exception_Error; + return; + end if; + + -- wc_AesDelete() already calls wc_AesFree() internally. + Ada_Free_AES (AES); + AES := null; + Result := 0; + exception + when others => + Result := Exception_Error; + end AES_Free; + +begin + null; end WolfSSL; diff --git a/wrapper/Ada/wolfssl.ads b/wrapper/Ada/wolfssl.ads index 2a247a676cc..50acf4b6767 100644 --- a/wrapper/Ada/wolfssl.ads +++ b/wrapper/Ada/wolfssl.ads @@ -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,8 +27,16 @@ 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 -- application and before any other call to the library. @@ -40,23 +47,32 @@ package WolfSSL with SPARK_Mode is -- used by the library. 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); @@ -291,72 +313,6 @@ package WolfSSL with SPARK_Mode is -- of a file. The buffer is provided by the Input argument. -- 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) @@ -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,251 @@ 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_Key_Type is limited private with + Annotate => (GNATprove, Ownership, "Needs_Reclamation"); + + function Is_Valid (Key : RNG_Key_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_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_RNG (Key : in out RNG_Key_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_Key_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_Key_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_Key_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_Key_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; + Text : out SHA256_As_String; + 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 +804,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 +828,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 +847,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,7 +861,8 @@ 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, External_Name => "get_wolfssl_success", @@ -671,10 +875,12 @@ 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, External_Name => "get_wolfssl_error_want_read", @@ -689,6 +895,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_Key_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; diff --git a/wrapper/Ada/wolfssl.gpr b/wrapper/Ada/wolfssl.gpr index 060c2bc6a08..9f0df5ba36b 100644 --- a/wrapper/Ada/wolfssl.gpr +++ b/wrapper/Ada/wolfssl.gpr @@ -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";