Merge pull request #6664 from joakim-strandberg/ada_windows_support

Ada windows support
This commit is contained in:
JacobBarthelmeh
2023-08-03 14:40:34 -06:00
committed by GitHub
9 changed files with 53 additions and 675 deletions

View File

@ -29,6 +29,7 @@ formal verification). To formally verify the Ada code in this repository
open the client.gpr with GNAT Studio and then select open the client.gpr with GNAT Studio and then select
SPARK -> Prove All Sources and use Proof Level 2. SPARK -> Prove All Sources and use Proof Level 2.
```
Summary of SPARK analysis Summary of SPARK analysis
========================= =========================
@ -47,6 +48,7 @@ Termination . . .
Concurrency . . . . . . Concurrency . . . . . .
--------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------
Total 172 17 (10%) . 155 (90%) . . Total 172 17 (10%) . 155 (90%) . .
```
## Compiler and Build System installation ## Compiler and Build System installation
@ -73,6 +75,13 @@ cd obj/
./tls_client_main 127.0.0.1 ./tls_client_main 127.0.0.1
``` ```
On Windows, build the executables with:
```sh
gprbuild -XOS=Windows default.gpr
gprbuild -XOS=Windows client.gpr
```
### GNAT FSF Compiler and GPRBuild manual installation ### GNAT FSF Compiler and GPRBuild manual installation
In May 2022 AdaCore announced the end of the GNAT Community releases. In May 2022 AdaCore announced the end of the GNAT Community releases.
Pre-built binaries for the GNAT FSF compiler and GPRBuild can be Pre-built binaries for the GNAT FSF compiler and GPRBuild can be
@ -82,18 +91,14 @@ Make sure the executables for the compiler and GPRBuild are on the PATH
and use gprbuild to build the source code. and use gprbuild to build the source code.
## Files ## Files
The file c_tls_client_main.c and c_tls_server_main.c are the TLS v1.3 The TLS v1.3 client example in the Ada/SPARK programming language
server and client examples using the WolfSSL library implemented using using the WolfSSL library can be found in the files:
the C programming language.
The translation of the C client example into the Ada/SPARK programming
language can be found in the files:
tls_client_main.adb tls_client_main.adb
tls_client.ads tls_client.ads
tls_client.adb tls_client.adb
The translation of the C server example into the Ada/SPARK programming The TLS v1.3 server example in the Ada/SPARK programming language
language can be found in the files: using the WolfSSL library can be found in the files:
tls_server_main.adb tls_server_main.adb
tls_server.ads tls_server.ads
tls_server.adb tls_server.adb

View File

@ -1,285 +0,0 @@
/* c_tls_client_main.c
*
* Copyright (C) 2006-2023 wolfSSL Inc.
*
* This file is part of wolfSSL. (formerly known as CyaSSL)
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <wolfssl/wolfcrypt/settings.h>
/* the usual suspects */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/* socket includes */
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
/* wolfSSL */
#ifndef WOLFSSL_USER_SETTINGS
#include <wolfssl/options.h>
#endif
#include <wolfssl/ssl.h>
#include <wolfssl/wolfio.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#define DEFAULT_PORT 11111
#define CERT_FILE "../certs/client-cert.pem"
#define KEY_FILE "../certs/client-key.pem"
#define CA_FILE "../certs/ca-cert.pem"
#if defined(WOLFSSL_TLS13) && defined(HAVE_SECRET_CALLBACK)
#ifndef WOLFSSL_SSLKEYLOGFILE_OUTPUT
#define WOLFSSL_SSLKEYLOGFILE_OUTPUT "sslkeylog.log"
#endif
/* Callback function for TLS v1.3 secrets for use with Wireshark */
static int Tls13SecretCallback(WOLFSSL* ssl, int id, const unsigned char* secret,
int secretSz, void* ctx)
{
int i;
const char* str = NULL;
unsigned char clientRandom[32];
int clientRandomSz;
XFILE fp = stderr;
if (ctx) {
fp = XFOPEN((const char*)ctx, "ab");
if (fp == XBADFILE) {
return BAD_FUNC_ARG;
}
}
clientRandomSz = (int)wolfSSL_get_client_random(ssl, clientRandom,
sizeof(clientRandom));
if (clientRandomSz <= 0) {
printf("Error getting client random %d\n", clientRandomSz);
}
#if 0
printf("TLS Client Secret CB: Rand %d, Secret %d\n",
clientRandomSz, secretSz);
#endif
switch (id) {
case CLIENT_EARLY_TRAFFIC_SECRET:
str = "CLIENT_EARLY_TRAFFIC_SECRET"; break;
case EARLY_EXPORTER_SECRET:
str = "EARLY_EXPORTER_SECRET"; break;
case CLIENT_HANDSHAKE_TRAFFIC_SECRET:
str = "CLIENT_HANDSHAKE_TRAFFIC_SECRET"; break;
case SERVER_HANDSHAKE_TRAFFIC_SECRET:
str = "SERVER_HANDSHAKE_TRAFFIC_SECRET"; break;
case CLIENT_TRAFFIC_SECRET:
str = "CLIENT_TRAFFIC_SECRET_0"; break;
case SERVER_TRAFFIC_SECRET:
str = "SERVER_TRAFFIC_SECRET_0"; break;
case EXPORTER_SECRET:
str = "EXPORTER_SECRET"; break;
}
fprintf(fp, "%s ", str);
for (i = 0; i < clientRandomSz; i++) {
fprintf(fp, "%02x", clientRandom[i]);
}
fprintf(fp, " ");
for (i = 0; i < secretSz; i++) {
fprintf(fp, "%02x", secret[i]);
}
fprintf(fp, "\n");
if (fp != stderr) {
XFCLOSE(fp);
}
return 0;
}
#endif /* WOLFSSL_TLS13 && HAVE_SECRET_CALLBACK */
int main(int argc, char** argv)
{
int ret = 0;
#ifdef WOLFSSL_TLS13
int sockfd = SOCKET_INVALID;
struct sockaddr_in servAddr;
char buff[256];
size_t len;
/* declare wolfSSL objects */
WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;
/* Check for proper calling convention */
if (argc != 2) {
printf("usage: %s <IPv4 address>\n", argv[0]);
return 0;
}
/* Create a socket that uses an internet IPv4 address,
* Sets the socket to be stream based (TCP),
* 0 means choose the default protocol. */
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
fprintf(stderr, "ERROR: failed to create the socket\n");
ret = -1; goto exit;
}
/* Initialize the server address struct with zeros */
memset(&servAddr, 0, sizeof(servAddr));
/* Fill in the server address */
servAddr.sin_family = AF_INET; /* using IPv4 */
servAddr.sin_port = htons(DEFAULT_PORT); /* on DEFAULT_PORT */
/* Get the server IPv4 address from the command line call */
if (inet_pton(AF_INET, argv[1], &servAddr.sin_addr) != 1) {
fprintf(stderr, "ERROR: invalid address\n");
ret = -1; goto exit;
}
/* Connect to the server */
if ((ret = connect(sockfd, (struct sockaddr*) &servAddr, sizeof(servAddr)))
== -1) {
fprintf(stderr, "ERROR: failed to connect\n");
goto exit;
}
/*---------------------------------*/
/* Start of wolfSSL initialization and configuration */
/*---------------------------------*/
#if 0
wolfSSL_Debugging_ON();
#endif
/* Initialize wolfSSL */
if ((ret = wolfSSL_Init()) != WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: Failed to initialize the library\n");
goto exit;
}
/* Create and initialize WOLFSSL_CTX */
if ((ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method())) == NULL) {
fprintf(stderr, "ERROR: failed to create WOLFSSL_CTX\n");
ret = -1; goto exit;
}
/* Load client certificate into WOLFSSL_CTX */
if ((ret = wolfSSL_CTX_use_certificate_file(ctx, CERT_FILE, WOLFSSL_FILETYPE_PEM))
!= WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: failed to load %s, please check the file.\n",
CERT_FILE);
goto exit;
}
/* Load client key into WOLFSSL_CTX */
if ((ret = wolfSSL_CTX_use_PrivateKey_file(ctx, KEY_FILE, WOLFSSL_FILETYPE_PEM))
!= WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: failed to load %s, please check the file.\n",
KEY_FILE);
goto exit;
}
/* Load CA certificate into WOLFSSL_CTX */
if ((ret = wolfSSL_CTX_load_verify_locations(ctx, CA_FILE, NULL))
!= WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: failed to load %s, please check the file.\n",
CA_FILE);
goto exit;
}
/* Create a WOLFSSL object */
if ((ssl = wolfSSL_new(ctx)) == NULL) {
fprintf(stderr, "ERROR: failed to create WOLFSSL object\n");
ret = -1; goto exit;
}
/* Attach wolfSSL to the socket */
if ((ret = wolfSSL_set_fd(ssl, sockfd)) != WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: Failed to set the file descriptor\n");
goto exit;
}
#ifdef HAVE_SECRET_CALLBACK
/* required for getting random used */
wolfSSL_KeepArrays(ssl);
/* optional logging for wireshark */
wolfSSL_set_tls13_secret_cb(ssl, Tls13SecretCallback,
(void*)WOLFSSL_SSLKEYLOGFILE_OUTPUT);
#endif
/* Connect to wolfSSL on the server side */
if ((ret = wolfSSL_connect(ssl)) != WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: failed to connect to wolfSSL\n");
goto exit;
}
#ifdef HAVE_SECRET_CALLBACK
wolfSSL_FreeArrays(ssl);
#endif
/* Get a message for the server from stdin */
printf("Message for server: ");
memset(buff, 0, sizeof(buff));
if (fgets(buff, sizeof(buff), stdin) == NULL) {
fprintf(stderr, "ERROR: failed to get message for server\n");
ret = -1; goto exit;
}
len = strnlen(buff, sizeof(buff));
/* Send the message to the server */
if ((ret = wolfSSL_write(ssl, buff, len)) != (int)len) {
fprintf(stderr, "ERROR: failed to write entire message\n");
fprintf(stderr, "%d bytes of %d bytes were sent", ret, (int) len);
goto exit;
}
/* Read the server data into our buff array */
memset(buff, 0, sizeof(buff));
if ((ret = wolfSSL_read(ssl, buff, sizeof(buff)-1)) < 0) {
fprintf(stderr, "ERROR: failed to read\n");
goto exit;
}
/* Print to stdout any data the server sends */
printf("Server: %s\n", buff);
/* Return reporting a success */
ret = 0;
exit:
/* Cleanup and return */
if (sockfd != SOCKET_INVALID)
close(sockfd); /* Close the connection to the server */
if (ssl)
wolfSSL_free(ssl); /* Free the wolfSSL object */
if (ctx)
wolfSSL_CTX_free(ctx); /* Free the wolfSSL context object */
wolfSSL_Cleanup(); /* Cleanup the wolfSSL environment */
#else
printf("Example requires TLS v1.3\n");
#endif
(void)argc;
(void)argv;
return ret;
}

View File

@ -1,361 +0,0 @@
/* c_tls_server_main.c
*
* Copyright (C) 2006-2023 wolfSSL Inc.
*
* This file is part of wolfSSL. (formerly known as CyaSSL)
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <wolfssl/wolfcrypt/settings.h>
/* the usual suspects */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/* socket includes */
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#define HAVE_SIGNAL
#ifdef HAVE_SIGNAL
#include <signal.h> /* signal */
#endif
/* wolfSSL */
#ifndef WOLFSSL_USER_SETTINGS
#include <wolfssl/options.h>
#endif
#include <wolfssl/ssl.h>
#include <wolfssl/wolfio.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#define DEFAULT_PORT 11111
#define CERT_FILE "../certs/server-cert.pem"
#define KEY_FILE "../certs/server-key.pem"
#define CA_FILE "../certs/client-cert.pem"
#if defined(WOLFSSL_TLS13) && defined(HAVE_SECRET_CALLBACK)
#ifndef WOLFSSL_SSLKEYLOGFILE_OUTPUT
#define WOLFSSL_SSLKEYLOGFILE_OUTPUT "sslkeylog.log"
#endif
/* Callback function for TLS v1.3 secrets for use with Wireshark */
static int Tls13SecretCallback(WOLFSSL* ssl, int id, const unsigned char* secret,
int secretSz, void* ctx)
{
int i;
const char* str = NULL;
unsigned char serverRandom[32];
int serverRandomSz;
XFILE fp = stderr;
if (ctx) {
fp = XFOPEN((const char*)ctx, "ab");
if (fp == XBADFILE) {
return BAD_FUNC_ARG;
}
}
serverRandomSz = (int)wolfSSL_get_server_random(ssl, serverRandom,
sizeof(serverRandom));
if (serverRandomSz <= 0) {
printf("Error getting server random %d\n", serverRandomSz);
}
#if 0
printf("TLS Server Secret CB: Rand %d, Secret %d\n",
serverRandomSz, secretSz);
#endif
switch (id) {
case CLIENT_EARLY_TRAFFIC_SECRET:
str = "CLIENT_EARLY_TRAFFIC_SECRET"; break;
case EARLY_EXPORTER_SECRET:
str = "EARLY_EXPORTER_SECRET"; break;
case CLIENT_HANDSHAKE_TRAFFIC_SECRET:
str = "CLIENT_HANDSHAKE_TRAFFIC_SECRET"; break;
case SERVER_HANDSHAKE_TRAFFIC_SECRET:
str = "SERVER_HANDSHAKE_TRAFFIC_SECRET"; break;
case CLIENT_TRAFFIC_SECRET:
str = "CLIENT_TRAFFIC_SECRET_0"; break;
case SERVER_TRAFFIC_SECRET:
str = "SERVER_TRAFFIC_SECRET_0"; break;
case EXPORTER_SECRET:
str = "EXPORTER_SECRET"; break;
}
fprintf(fp, "%s ", str);
for (i = 0; i < (int)serverRandomSz; i++) {
fprintf(fp, "%02x", serverRandom[i]);
}
fprintf(fp, " ");
for (i = 0; i < secretSz; i++) {
fprintf(fp, "%02x", secret[i]);
}
fprintf(fp, "\n");
if (fp != stderr) {
XFCLOSE(fp);
}
return 0;
}
#endif /* WOLFSSL_TLS13 && HAVE_SECRET_CALLBACK */
static int mSockfd = SOCKET_INVALID;
static int mConnd = SOCKET_INVALID;
static int mShutdown = 0;
#ifdef HAVE_SIGNAL
static void sig_handler(const int sig)
{
fprintf(stderr, "SIGINT handled = %d.\n", sig);
mShutdown = 1;
if (mConnd != SOCKET_INVALID) {
close(mConnd); /* Close the connection to the client */
mConnd = SOCKET_INVALID;
}
if (mSockfd != SOCKET_INVALID) {
close(mSockfd); /* Close the socket listening for clients */
mSockfd = SOCKET_INVALID;
}
}
#endif
/* To execute the application: ./main */
int main(int argc, char** argv)
{
int ret = 0;
#ifdef WOLFSSL_TLS13
struct sockaddr_in servAddr;
struct sockaddr_in clientAddr;
socklen_t size = sizeof(clientAddr);
char buff[256];
size_t len;
const char* reply = "I hear ya fa shizzle!\n";
int on;
/* declare wolfSSL objects */
WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;
#ifdef HAVE_SIGNAL
signal(SIGINT, sig_handler);
#endif
/* Initialize the server address struct with zeros */
memset(&servAddr, 0, sizeof(servAddr));
/* Fill in the server address */
servAddr.sin_family = AF_INET; /* using IPv4 */
servAddr.sin_port = htons(DEFAULT_PORT); /* on DEFAULT_PORT */
servAddr.sin_addr.s_addr = INADDR_ANY; /* from anywhere */
/* Create a socket that uses an internet IPv4 address,
* Sets the socket to be stream based (TCP),
* 0 means choose the default protocol. */
if ((mSockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
fprintf(stderr, "ERROR: failed to create the socket\n");
goto exit;
}
/* make sure server is setup for reuse addr/port */
on = 1;
setsockopt(mSockfd, SOL_SOCKET, SO_REUSEADDR,
(char*)&on, (socklen_t)sizeof(on));
#ifdef SO_REUSEPORT
setsockopt(mSockfd, SOL_SOCKET, SO_REUSEPORT,
(char*)&on, (socklen_t)sizeof(on));
#endif
/* Bind the server socket to our port */
if (bind(mSockfd, (struct sockaddr*)&servAddr, sizeof(servAddr)) == -1) {
fprintf(stderr, "ERROR: failed to bind\n");
goto exit;
}
/* Listen for a new connection, allow 5 pending connections */
if (listen(mSockfd, 5) == -1) {
fprintf(stderr, "ERROR: failed to listen\n");
goto exit;
}
/*---------------------------------*/
/* Start of wolfSSL initialization and configuration */
/*---------------------------------*/
#if 0
wolfSSL_Debugging_ON();
#endif
/* Initialize wolfSSL */
if ((ret = wolfSSL_Init()) != WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: Failed to initialize the library\n");
goto exit;
}
/* Create and initialize WOLFSSL_CTX */
if ((ctx = wolfSSL_CTX_new(wolfTLSv1_3_server_method())) == NULL) {
fprintf(stderr, "ERROR: failed to create WOLFSSL_CTX\n");
ret = -1;
goto exit;
}
/* Require mutual authentication */
wolfSSL_CTX_set_verify(ctx,
WOLFSSL_VERIFY_PEER | WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
/* Load server certificates into WOLFSSL_CTX */
if ((ret = wolfSSL_CTX_use_certificate_file(ctx, CERT_FILE,
WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: failed to load %s, please check the file.\n",
CERT_FILE);
goto exit;
}
/* Load server key into WOLFSSL_CTX */
if ((ret = wolfSSL_CTX_use_PrivateKey_file(ctx, KEY_FILE,
WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: failed to load %s, please check the file.\n",
KEY_FILE);
goto exit;
}
/* Load client certificate as "trusted" into WOLFSSL_CTX */
if ((ret = wolfSSL_CTX_load_verify_locations(ctx, CA_FILE, NULL))
!= WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: failed to load %s, please check the file.\n",
CA_FILE);
goto exit;
}
/* Continue to accept clients until mShutdown is issued */
while (!mShutdown) {
printf("Waiting for a connection...\n");
/* Accept client connections */
if ((mConnd = accept(mSockfd, (struct sockaddr*)&clientAddr, &size))
== -1) {
fprintf(stderr, "ERROR: failed to accept the connection\n\n");
ret = -1; goto exit;
}
/* Create a WOLFSSL object */
if ((ssl = wolfSSL_new(ctx)) == NULL) {
fprintf(stderr, "ERROR: failed to create WOLFSSL object\n");
ret = -1; goto exit;
}
/* Attach wolfSSL to the socket */
wolfSSL_set_fd(ssl, mConnd);
#ifdef HAVE_SECRET_CALLBACK
/* required for getting random used */
wolfSSL_KeepArrays(ssl);
/* optional logging for wireshark */
wolfSSL_set_tls13_secret_cb(ssl, Tls13SecretCallback,
(void*)WOLFSSL_SSLKEYLOGFILE_OUTPUT);
#endif
/* Establish TLS connection */
if ((ret = wolfSSL_accept(ssl)) != WOLFSSL_SUCCESS) {
fprintf(stderr, "wolfSSL_accept error = %d\n",
wolfSSL_get_error(ssl, ret));
goto exit;
}
printf("Client connected successfully\n");
#ifdef HAVE_SECRET_CALLBACK
wolfSSL_FreeArrays(ssl);
#endif
/* Read the client data into our buff array */
memset(buff, 0, sizeof(buff));
if ((ret = wolfSSL_read(ssl, buff, sizeof(buff)-1)) < 0) {
fprintf(stderr, "ERROR: failed to read\n");
goto exit;
}
/* Print to stdout any data the client sends */
printf("Client: %s\n", buff);
/* Check for server shutdown command */
if (strncmp(buff, "shutdown", 8) == 0) {
printf("Shutdown command issued!\n");
mShutdown = 1;
}
/* Write our reply into buff */
memset(buff, 0, sizeof(buff));
memcpy(buff, reply, strlen(reply));
len = strnlen(buff, sizeof(buff));
/* Reply back to the client */
if ((ret = wolfSSL_write(ssl, buff, len)) != (int)len) {
fprintf(stderr, "ERROR: failed to write\n");
goto exit;
}
/* Cleanup after this connection */
wolfSSL_shutdown(ssl);
if (ssl) {
wolfSSL_free(ssl); /* Free the wolfSSL object */
ssl = NULL;
}
if (mConnd != SOCKET_INVALID) {
close(mConnd); /* Close the connection to the client */
mConnd = SOCKET_INVALID;
}
}
printf("Shutdown complete\n");
exit:
/* Cleanup and return */
if (ssl)
wolfSSL_free(ssl); /* Free the wolfSSL object */
if (mConnd != SOCKET_INVALID) {
close(mConnd); /* Close the connection to the client */
mConnd = SOCKET_INVALID;
}
if (mSockfd != SOCKET_INVALID) {
close(mSockfd); /* Close the socket listening for clients */
mSockfd = SOCKET_INVALID;
}
if (ctx)
wolfSSL_CTX_free(ctx); /* Free the wolfSSL context object */
wolfSSL_Cleanup(); /* Cleanup the wolfSSL environment */
#else
printf("Example requires TLS v1.3\n");
#endif /* WOLFSSL_TLS13 */
(void)argc;
(void)argv;
return ret;
}

View File

@ -1,4 +1,8 @@
project Client is project Client is
type OS_Kind is ("Windows", "Linux_Or_Mac");
OS : OS_Kind := external ("OS", "Linux_Or_Mac");
for Languages use ("C", "Ada"); for Languages use ("C", "Ada");
for Source_Dirs use (".", for Source_Dirs use (".",
@ -55,11 +59,16 @@ project Client is
end Compiler; end Compiler;
package Linker is package Linker is
for Switches ("C") use case OS is
("-lm"); -- To include the math library (used by WolfSSL). when "Windows" =>
for Switches ("Ada") use
("-lm", -- To include the math library (used by WolfSSL).
"-lcrypt32"); -- Needed on Windows.
for Switches ("Ada") use when "Linux_Or_Mac" =>
("-lm"); -- To include the math library (used by WolfSSL). for Switches ("Ada") use
("-lm"); -- To include the math library (used by WolfSSL).
end case;
end Linker; end Linker;
package Binder is package Binder is

View File

@ -1,4 +1,9 @@
project Default is project Default is
type OS_Kind is ("Windows", "Linux_Or_Mac");
OS : OS_Kind := external ("OS", "Linux_Or_Mac");
for Languages use ("C", "Ada"); for Languages use ("C", "Ada");
for Source_Dirs use (".", for Source_Dirs use (".",
@ -15,9 +20,7 @@ project Default is
for Object_Dir use "obj"; for Object_Dir use "obj";
for Main use ("c_tls_client_main.c", for Main use ("tls_server_main.adb");
"c_tls_server_main.c",
"tls_server_main.adb");
package Naming is package Naming is
for Spec_Suffix ("C") use ".h"; for Spec_Suffix ("C") use ".h";
@ -68,11 +71,16 @@ project Default is
end Compiler; end Compiler;
package Linker is package Linker is
for Switches ("C") use case OS is
("-lm"); -- To include the math library (used by WolfSSL). when "Windows" =>
for Switches ("Ada") use
("-lm", -- To include the math library (used by WolfSSL).
"-lcrypt32"); -- Needed on Windows.
for Switches ("Ada") use when "Linux_Or_Mac" =>
("-lm"); -- To include the math library (used by WolfSSL). for Switches ("Ada") use
("-lm"); -- To include the math library (used by WolfSSL).
end case;
end Linker; end Linker;
package Binder is package Binder is

View File

@ -6,8 +6,6 @@ EXTRA_DIST+= wrapper/Ada/README.md
EXTRA_DIST+= wrapper/Ada/default.gpr EXTRA_DIST+= wrapper/Ada/default.gpr
EXTRA_DIST+= wrapper/Ada/gnat.adc EXTRA_DIST+= wrapper/Ada/gnat.adc
EXTRA_DIST+= wrapper/Ada/ada_binding.c EXTRA_DIST+= wrapper/Ada/ada_binding.c
EXTRA_DIST+= wrapper/Ada/c_tls_client_main.c
EXTRA_DIST+= wrapper/Ada/c_tls_server_main.c
EXTRA_DIST+= wrapper/Ada/tls_client_main.adb EXTRA_DIST+= wrapper/Ada/tls_client_main.adb
EXTRA_DIST+= wrapper/Ada/tls_client.adb EXTRA_DIST+= wrapper/Ada/tls_client.adb
EXTRA_DIST+= wrapper/Ada/tls_client.ads EXTRA_DIST+= wrapper/Ada/tls_client.ads

View File

@ -101,9 +101,9 @@ package body Tls_Client with SPARK_Mode is
Any_Inet_Addr : Inet_Addr_Type renames SPARK_Sockets.Any_Inet_Addr; Any_Inet_Addr : Inet_Addr_Type renames SPARK_Sockets.Any_Inet_Addr;
CERT_FILE : constant String := "../certs/client-cert.pem"; CERT_FILE : constant String := "../../../certs/client-cert.pem";
KEY_FILE : constant String := "../certs/client-key.pem"; KEY_FILE : constant String := "../../../certs/client-key.pem";
CA_FILE : constant String := "../certs/ca-cert.pem"; CA_FILE : constant String := "../../../certs/ca-cert.pem";
subtype Byte_Array is WolfSSL.Byte_Array; subtype Byte_Array is WolfSSL.Byte_Array;

View File

@ -87,9 +87,9 @@ package body Tls_Server with SPARK_Mode is
Any_Inet_Addr : Inet_Addr_Type renames SPARK_Sockets.Any_Inet_Addr; Any_Inet_Addr : Inet_Addr_Type renames SPARK_Sockets.Any_Inet_Addr;
CERT_FILE : constant String := "../certs/server-cert.pem"; CERT_FILE : constant String := "../../../certs/server-cert.pem";
KEY_FILE : constant String := "../certs/server-key.pem"; KEY_FILE : constant String := "../../../certs/server-key.pem";
CA_FILE : constant String := "../certs/client-cert.pem"; CA_FILE : constant String := "../../../certs/client-cert.pem";
subtype Byte_Array is WolfSSL.Byte_Array; subtype Byte_Array is WolfSSL.Byte_Array;
@ -305,7 +305,11 @@ package body Tls_Server with SPARK_Mode is
Put_Line ("ERROR: failed to write full response."); Put_Line ("ERROR: failed to write full response.");
end if; end if;
Result := WolfSSL.Shutdown (Ssl); for I in 1 .. 3 loop
Result := WolfSSL.Shutdown (Ssl);
exit when Result = Success;
delay 0.001; -- Delay is expressed in seconds.
end loop;
if Result /= Success then if Result /= Success then
Put_Line ("ERROR: Failed to shutdown WolfSSL context."); Put_Line ("ERROR: Failed to shutdown WolfSSL context.");
end if; end if;

View File

@ -42,7 +42,7 @@ extern "C" {
#define WOLFSSL_IGNORE_FILE_WARN /* Ignore *.c include warnings */ #define WOLFSSL_IGNORE_FILE_WARN /* Ignore *.c include warnings */
#define WOLFSSL_PUBLIC_MP /* Make math API's public */ #define WOLFSSL_PUBLIC_MP /* Make math API's public */
#define WOLFSSL_ENCRYPTED_KEYS /* Support for encrypted keys PKCS8 */ #define WOLFSSL_ENCRYPTED_KEYS /* Support for encrypted keys PKCS8 */
#define WOLFSSL_SYS_CA_CERTS /* Enable ability to load CA certs from OS */ //#define WOLFSSL_SYS_CA_CERTS /* Enable ability to load CA certs from OS */
#if 0 /* Not needed */ #if 0 /* Not needed */
#define KEEP_PEER_CERT /* Retain peer's certificate */ #define KEEP_PEER_CERT /* Retain peer's certificate */