mirror of https://github.com/wolfSSL/wolfssl
Ada Bindings for wolfSSL. Credit Joakim Dahlgren Strandberg <joakimds@kth.se>
This commit is contained in:
parent
b8119af455
commit
d20a096ffa
|
@ -125,7 +125,7 @@ extern "C" {
|
|||
#define WOLFSSL_DER_TO_PEM
|
||||
#define WOLFSSL_CUSTOM_OID
|
||||
#define HAVE_OID_ENCODING
|
||||
//#define WOLFSSL_ASN_TEMPLATE /* Not enabled yet by default */
|
||||
#define WOLFSSL_ASN_TEMPLATE
|
||||
|
||||
/* Certificate Revocation */
|
||||
#define HAVE_OCSP
|
||||
|
|
|
@ -30648,9 +30648,9 @@ int wc_SetCustomExtension(Cert *cert, int critical, const char *oid,
|
|||
|
||||
ext = &cert->customCertExt[cert->customCertExtCount];
|
||||
|
||||
ext->oid = oid;
|
||||
ext->oid = (char*)oid;
|
||||
ext->crit = (critical == 0) ? 0 : 1;
|
||||
ext->val = der;
|
||||
ext->val = (byte*)der;
|
||||
ext->valSz = derSz;
|
||||
|
||||
cert->customCertExtCount++;
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
# Ada Binding Example
|
||||
|
||||
Download and install the GNAT community edition compiler and studio:
|
||||
https://www.adacore.com/download
|
||||
|
||||
Linux Install:
|
||||
|
||||
```sh
|
||||
chmod +x gnat-2021-20210519-x86_64-linux-bin
|
||||
./gnat-2021-20210519-x86_64-linux-bin
|
||||
```
|
||||
|
||||
```sh
|
||||
export PATH="/opt/GNAT/2021/bin:$PATH"
|
||||
gprclean
|
||||
gprbuild default.gpr
|
||||
|
||||
|
||||
./c_tls_server_main
|
||||
./tls_server_main &
|
||||
./c_tls_client_main 127.0.0.1
|
||||
```
|
|
@ -0,0 +1,86 @@
|
|||
/* ada_binding.c
|
||||
*
|
||||
* Copyright (C) 2006-2023 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL.
|
||||
*
|
||||
* 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-1335, USA
|
||||
*/
|
||||
|
||||
/* wolfSSL */
|
||||
#include <wolfssl/wolfcrypt/settings.h>
|
||||
|
||||
#include <wolfssl/ssl.h>
|
||||
|
||||
// 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
|
||||
// without the need to make a corresponding change in the Ada code.
|
||||
extern int get_wolfssl_success(void);
|
||||
extern int get_wolfssl_verify_none(void);
|
||||
extern int get_wolfssl_verify_peer(void);
|
||||
extern int get_wolfssl_verify_fail_if_no_peer_cert(void);
|
||||
extern int get_wolfssl_verify_client_once(void);
|
||||
extern int get_wolfssl_verify_post_handshake(void);
|
||||
extern int get_wolfssl_verify_fail_except_psk(void);
|
||||
extern int get_wolfssl_verify_default(void);
|
||||
|
||||
extern int get_wolfssl_filetype_asn1(void);
|
||||
extern int get_wolfssl_filetype_pem(void);
|
||||
extern int get_wolfssl_filetype_default(void);
|
||||
|
||||
extern int get_wolfssl_success(void) {
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
|
||||
extern int get_wolfssl_verify_none(void) {
|
||||
return WOLFSSL_VERIFY_NONE;
|
||||
}
|
||||
|
||||
extern int get_wolfssl_verify_peer(void) {
|
||||
return WOLFSSL_VERIFY_PEER;
|
||||
}
|
||||
|
||||
extern int get_wolfssl_verify_fail_if_no_peer_cert(void) {
|
||||
return WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT;
|
||||
}
|
||||
|
||||
extern int get_wolfssl_verify_client_once(void) {
|
||||
return WOLFSSL_VERIFY_CLIENT_ONCE;
|
||||
}
|
||||
|
||||
extern int get_wolfssl_verify_post_handshake(void) {
|
||||
return WOLFSSL_VERIFY_POST_HANDSHAKE;
|
||||
}
|
||||
|
||||
extern int get_wolfssl_verify_fail_except_psk(void) {
|
||||
return WOLFSSL_VERIFY_FAIL_EXCEPT_PSK;
|
||||
}
|
||||
|
||||
extern int get_wolfssl_verify_default(void) {
|
||||
return WOLFSSL_VERIFY_DEFAULT;
|
||||
}
|
||||
|
||||
extern int get_wolfssl_filetype_asn1(void) {
|
||||
return WOLFSSL_FILETYPE_ASN1;
|
||||
}
|
||||
|
||||
extern int get_wolfssl_filetype_pem(void) {
|
||||
return WOLFSSL_FILETYPE_PEM;
|
||||
}
|
||||
|
||||
extern int get_wolfssl_filetype_default(void) {
|
||||
return WOLFSSL_FILETYPE_DEFAULT;
|
||||
}
|
|
@ -0,0 +1,285 @@
|
|||
/* 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;
|
||||
}
|
|
@ -0,0 +1,361 @@
|
|||
/* 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;
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
project Default is
|
||||
for Languages use ("C", "Ada");
|
||||
|
||||
for Source_Dirs use (".",
|
||||
"../../",
|
||||
"../../src",
|
||||
"../../wolfcrypt/src");
|
||||
|
||||
for Object_Dir use "obj";
|
||||
|
||||
for Main use ("c_tls_client_main.c",
|
||||
"c_tls_server_main.c",
|
||||
"tls_server_main.adb");
|
||||
|
||||
package Naming is
|
||||
for Spec_Suffix ("C") use ".h";
|
||||
end Naming;
|
||||
|
||||
package Builder is
|
||||
for Global_Configuration_Pragmas use "gnat.adc";
|
||||
end Builder;
|
||||
|
||||
package Compiler is
|
||||
for Switches ("C") use
|
||||
("-DWOLFSSL_USER_SETTINGS",
|
||||
"-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");
|
||||
end Compiler;
|
||||
|
||||
package Linker is
|
||||
for Switches ("C") use
|
||||
("-lm"); -- To include the math library (used by WolfSSL).
|
||||
|
||||
for Switches ("Ada") use
|
||||
("-lm"); -- To include the math library (used by WolfSSL).
|
||||
end Linker;
|
||||
|
||||
end Default;
|
|
@ -0,0 +1 @@
|
|||
pragma Restrictions (No_Secondary_Stack);
|
|
@ -0,0 +1,19 @@
|
|||
# vim:ft=automake
|
||||
# included from Top Level Makefile.am
|
||||
# All paths should be given relative to the root
|
||||
|
||||
EXTRA_DIST+= wrapper/Ada/README.md
|
||||
EXTRA_DIST+= wrapper/Ada/default.gpr
|
||||
EXTRA_DIST+= wrapper/Ada/gnat.adc
|
||||
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.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.adb
|
||||
EXTRA_DIST+= wrapper/Ada/wolfssl.ads
|
|
@ -0,0 +1,81 @@
|
|||
-- Ada Standard Library packages.
|
||||
with Ada.Characters.Handling;
|
||||
with Ada.Command_Line;
|
||||
with Ada.Strings.Bounded;
|
||||
with Ada.Text_IO.Bounded_IO;
|
||||
|
||||
-- GNAT Library packages.
|
||||
with GNAT.Sockets;
|
||||
|
||||
-- The WolfSSL package.
|
||||
with WolfSSL;
|
||||
|
||||
package body Tls_Client is
|
||||
|
||||
use type WolfSSL.Mode_Type;
|
||||
use type WolfSSL.Byte_Index;
|
||||
use type WolfSSL.Byte_Array;
|
||||
|
||||
use all type WolfSSL.Subprogram_Result;
|
||||
|
||||
package Messages is new Ada.Strings.Bounded.Generic_Bounded_Length (Max => 200);
|
||||
use all type Messages.Bounded_String;
|
||||
|
||||
package Messages_IO is new Ada.Text_IO.Bounded_IO (Messages);
|
||||
|
||||
procedure Put_Line (Text : String) is
|
||||
begin
|
||||
Ada.Text_IO.Put_Line (Text);
|
||||
end Put_Line;
|
||||
|
||||
procedure Put_Line (Text : Messages.Bounded_String) is
|
||||
begin
|
||||
Messages_IO.Put_Line (Text);
|
||||
end Put_Line;
|
||||
|
||||
subtype Exit_Status is Ada.Command_Line.Exit_Status;
|
||||
|
||||
Exit_Status_Success : Exit_Status renames Ada.Command_Line.Success;
|
||||
Exit_Status_Failure : Exit_Status renames Ada.Command_Line.Failure;
|
||||
|
||||
procedure Set (Status : Exit_Status) is
|
||||
begin
|
||||
Ada.Command_Line.Set_Exit_Status (Status);
|
||||
end Set;
|
||||
|
||||
subtype Port_Type is GNAT.Sockets.Port_Type;
|
||||
|
||||
subtype Level_Type is GNAT.Sockets.Level_Type;
|
||||
|
||||
subtype Socket_Type is GNAT.Sockets.Socket_Type;
|
||||
subtype Option_Name is GNAT.Sockets.Option_Name;
|
||||
subtype Option_Type is GNAT.Sockets.Option_Type;
|
||||
subtype Family_Type is GNAT.Sockets.Family_Type;
|
||||
|
||||
subtype Sock_Addr_Type is GNAT.Sockets.Sock_Addr_Type;
|
||||
subtype Inet_Addr_Type is GNAT.Sockets.Inet_Addr_Type;
|
||||
|
||||
Socket_Error : exception renames GNAT.Sockets.Socket_Error;
|
||||
|
||||
Reuse_Address : Option_Name renames GNAT.Sockets.Reuse_Address;
|
||||
|
||||
Socket_Level : Level_Type renames GNAT.Sockets.Socket_Level;
|
||||
|
||||
Family_Inet : Family_Type renames GNAT.Sockets.Family_Inet;
|
||||
|
||||
Any_Inet_Addr : Inet_Addr_Type renames GNAT.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";
|
||||
|
||||
subtype Byte_Array is WolfSSL.Byte_Array;
|
||||
|
||||
procedure Run is
|
||||
A : Sock_Addr_Type;
|
||||
C : Socket_Type; -- Client socket.
|
||||
begin
|
||||
null; -- work in progress.
|
||||
end Run;
|
||||
|
||||
end Tls_Client;
|
|
@ -0,0 +1,5 @@
|
|||
package Tls_Client is
|
||||
|
||||
procedure Run;
|
||||
|
||||
end Tls_Client;
|
|
@ -0,0 +1,8 @@
|
|||
with Tls_Client; pragma Elaborate_All (Tls_Client);
|
||||
|
||||
-- Application entry point for the Ada translation of the
|
||||
-- tls client v1.3 example in C.
|
||||
procedure Tls_Client_Main is
|
||||
begin
|
||||
Tls_Client.Run;
|
||||
end Tls_Client_Main;
|
|
@ -0,0 +1,240 @@
|
|||
-- Ada Standard Library packages.
|
||||
with Ada.Characters.Handling;
|
||||
with Ada.Command_Line;
|
||||
with Ada.Strings.Bounded;
|
||||
with Ada.Text_IO.Bounded_IO;
|
||||
|
||||
-- GNAT Library packages.
|
||||
with GNAT.Sockets;
|
||||
|
||||
-- The WolfSSL package.
|
||||
with WolfSSL;
|
||||
|
||||
package body Tls_Server is
|
||||
|
||||
use type WolfSSL.Mode_Type;
|
||||
use type WolfSSL.Byte_Index;
|
||||
use type WolfSSL.Byte_Array;
|
||||
|
||||
use all type WolfSSL.Subprogram_Result;
|
||||
|
||||
package Messages is new Ada.Strings.Bounded.Generic_Bounded_Length (Max => 200);
|
||||
use all type Messages.Bounded_String;
|
||||
|
||||
package Messages_IO is new Ada.Text_IO.Bounded_IO (Messages);
|
||||
|
||||
procedure Put_Line (Text : String) is
|
||||
begin
|
||||
Ada.Text_IO.Put_Line (Text);
|
||||
end Put_Line;
|
||||
|
||||
procedure Put_Line (Text : Messages.Bounded_String) is
|
||||
begin
|
||||
Messages_IO.Put_Line (Text);
|
||||
end Put_Line;
|
||||
|
||||
subtype Exit_Status is Ada.Command_Line.Exit_Status;
|
||||
|
||||
Exit_Status_Success : Exit_Status renames Ada.Command_Line.Success;
|
||||
Exit_Status_Failure : Exit_Status renames Ada.Command_Line.Failure;
|
||||
|
||||
procedure Set (Status : Exit_Status) is
|
||||
begin
|
||||
Ada.Command_Line.Set_Exit_Status (Status);
|
||||
end Set;
|
||||
|
||||
subtype Port_Type is GNAT.Sockets.Port_Type;
|
||||
|
||||
subtype Level_Type is GNAT.Sockets.Level_Type;
|
||||
|
||||
subtype Socket_Type is GNAT.Sockets.Socket_Type;
|
||||
subtype Option_Name is GNAT.Sockets.Option_Name;
|
||||
subtype Option_Type is GNAT.Sockets.Option_Type;
|
||||
subtype Family_Type is GNAT.Sockets.Family_Type;
|
||||
|
||||
subtype Sock_Addr_Type is GNAT.Sockets.Sock_Addr_Type;
|
||||
subtype Inet_Addr_Type is GNAT.Sockets.Inet_Addr_Type;
|
||||
|
||||
Socket_Error : exception renames GNAT.Sockets.Socket_Error;
|
||||
|
||||
Reuse_Address : Option_Name renames GNAT.Sockets.Reuse_Address;
|
||||
|
||||
Socket_Level : Level_Type renames GNAT.Sockets.Socket_Level;
|
||||
|
||||
Family_Inet : Family_Type renames GNAT.Sockets.Family_Inet;
|
||||
|
||||
Any_Inet_Addr : Inet_Addr_Type renames GNAT.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";
|
||||
|
||||
subtype Byte_Array is WolfSSL.Byte_Array;
|
||||
|
||||
Reply : constant Byte_Array := "I hear ya fa shizzle!";
|
||||
|
||||
procedure Run is
|
||||
A : Sock_Addr_Type;
|
||||
L : Socket_Type; -- Listener socket.
|
||||
C : Socket_Type; -- Client socket.
|
||||
P : constant Port_Type := 11111;
|
||||
|
||||
Ch : Character;
|
||||
|
||||
Ssl : WolfSSL.Optional_WolfSSL;
|
||||
|
||||
Ctx : WolfSSL.Optional_Context;
|
||||
Result : WolfSSL.Subprogram_Result;
|
||||
M : Messages.Bounded_String;
|
||||
Shall_Continue : Boolean := True;
|
||||
|
||||
Bytes_Written : Integer;
|
||||
|
||||
Input : WolfSSL.Read_Result;
|
||||
begin
|
||||
GNAT.Sockets.Create_Socket (Socket => L);
|
||||
GNAT.Sockets.Set_Socket_Option (Socket => L,
|
||||
Level => Socket_Level,
|
||||
Option => (Name => Reuse_Address,
|
||||
Enabled => True));
|
||||
GNAT.Sockets.Bind_Socket (Socket => L,
|
||||
Address => (Family => Family_Inet,
|
||||
Addr => Any_Inet_Addr,
|
||||
Port => P));
|
||||
GNAT.Sockets.Listen_Socket (Socket => L,
|
||||
Length => 5);
|
||||
|
||||
-- Create and initialize WOLFSSL_CTX.
|
||||
WolfSSL.Create_Context (Method => WolfSSL.TLSv1_3_Server_Method,
|
||||
Context => Ctx);
|
||||
if not Ctx.Exists then
|
||||
Put_Line ("ERROR: failed to create WOLFSSL_CTX.");
|
||||
Set (Exit_Status_Failure);
|
||||
return;
|
||||
end if;
|
||||
|
||||
-- Require mutual authentication.
|
||||
WolfSSL.Set_Verify
|
||||
(Context => Ctx.Instance,
|
||||
Mode => WolfSSL.Verify_Peer & WolfSSL.Verify_Fail_If_No_Peer_Cert);
|
||||
|
||||
-- Load server certificates into WOLFSSL_CTX.
|
||||
Result := WolfSSL.Use_Certificate_File (Context => Ctx.Instance,
|
||||
File => CERT_FILE,
|
||||
Format => WolfSSL.Format_Pem);
|
||||
if Result = Failure then
|
||||
M := Messages.To_Bounded_String ("ERROR: failed to load ");
|
||||
Messages.Append (M, CERT_FILE);
|
||||
Messages.Append (M, ", please check the file.");
|
||||
Put_Line (M);
|
||||
Set (Exit_Status_Failure);
|
||||
return;
|
||||
end if;
|
||||
|
||||
-- Load server key into WOLFSSL_CTX.
|
||||
Result := WolfSSL.Use_Private_Key_File (Context => Ctx.Instance,
|
||||
File => KEY_FILE,
|
||||
Format => WolfSSL.Format_Pem);
|
||||
if Result = Failure then
|
||||
M := Messages.To_Bounded_String ("ERROR: failed to load ");
|
||||
Messages.Append (M, KEY_FILE);
|
||||
Messages.Append (M, ", please check the file.");
|
||||
Put_Line (M);
|
||||
Set (Exit_Status_Failure);
|
||||
return;
|
||||
end if;
|
||||
|
||||
Put_Line ("success to here at least");
|
||||
|
||||
-- Load client certificate as "trusted" into WOLFSSL_CTX.
|
||||
Result := WolfSSL.Load_Verify_Locations (Context => Ctx.Instance,
|
||||
File => CA_FILE,
|
||||
Path => "");
|
||||
if Result = Failure then
|
||||
M := Messages.To_Bounded_String ("ERROR: failed to load ");
|
||||
Messages.Append (M, CA_FILE);
|
||||
Messages.Append (M, ", please check the file.");
|
||||
Put_Line (M);
|
||||
Set (Exit_Status_Failure);
|
||||
return;
|
||||
end if;
|
||||
|
||||
while Shall_Continue loop
|
||||
Put_Line ("Waiting for a connection...");
|
||||
begin
|
||||
GNAT.Sockets.Accept_Socket (Server => L,
|
||||
Socket => C,
|
||||
Address => A);
|
||||
exception
|
||||
when Socket_Error =>
|
||||
Shall_Continue := False;
|
||||
Put_Line ("ERROR: failed to accept the connection.");
|
||||
end;
|
||||
|
||||
-- Create a WOLFSSL object.
|
||||
WolfSSL.Create_WolfSSL (Context => Ctx.Instance, Ssl => Ssl);
|
||||
if not Ssl.Exists then
|
||||
Put_Line ("ERROR: failed to create WOLFSSL object.");
|
||||
Set (Exit_Status_Failure);
|
||||
return;
|
||||
end if;
|
||||
|
||||
-- Attach wolfSSL to the socket.
|
||||
Result := WolfSSL.Attach (Ssl => Ssl.Instance,
|
||||
Socket => GNAT.Sockets.To_C (C));
|
||||
-- Establish TLS connection.
|
||||
Result := WolfSSL.Accept_Connection (Ssl.Instance);
|
||||
if Result = Failure then
|
||||
Put_Line ("Accept error.");
|
||||
Set (Exit_Status_Failure);
|
||||
return;
|
||||
end if;
|
||||
|
||||
Put_Line ("Client connected successfully.");
|
||||
|
||||
Input := WolfSSL.Read (Ssl.Instance);
|
||||
|
||||
if Input.Result /= Success then
|
||||
Put_Line ("Read error.");
|
||||
Set (Exit_Status_Failure);
|
||||
return;
|
||||
end if;
|
||||
|
||||
-- Print to stdout any data the client sends.
|
||||
M := Messages.To_Bounded_String ("");
|
||||
for I in Input.Buffer'Range loop
|
||||
Ch := Character (Input.Buffer (I));
|
||||
if Ada.Characters.Handling.Is_Graphic (Ch) then
|
||||
Messages.Append (M, Ch);
|
||||
else
|
||||
null;
|
||||
-- Ignore the "newline" characters at end of message.
|
||||
end if;
|
||||
end loop;
|
||||
Put_Line (M);
|
||||
|
||||
-- Check for server shutdown command.
|
||||
if Input.Last >= 8 then
|
||||
if Input.Buffer (1 .. 8) = "shutdown" then
|
||||
Put_Line ("Shutdown command issued!");
|
||||
Shall_Continue := False;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
Bytes_Written := WolfSSL.Write (Ssl.Instance, Reply);
|
||||
if Bytes_Written /= Reply'Length then
|
||||
Put_Line ("ERROR: failed to write.");
|
||||
end if;
|
||||
|
||||
Result := WolfSSL.Shutdown (Ssl.Instance);
|
||||
WolfSSL.Free (Ssl);
|
||||
GNAT.Sockets.Close_Socket (C);
|
||||
|
||||
Put_Line ("Shutdown complete.");
|
||||
end loop;
|
||||
GNAT.Sockets.Close_Socket (L);
|
||||
WolfSSL.Free (Context => Ctx);
|
||||
WolfSSL.Finalize;
|
||||
end Run;
|
||||
|
||||
end Tls_Server;
|
|
@ -0,0 +1,5 @@
|
|||
package Tls_Server is
|
||||
|
||||
procedure Run;
|
||||
|
||||
end Tls_Server;
|
|
@ -0,0 +1,8 @@
|
|||
with Tls_Server; pragma Elaborate_All (Tls_Server);
|
||||
|
||||
-- Application entry point for the Ada translation of the
|
||||
-- tls server v1.3 example in C.
|
||||
procedure Tls_Server_Main is
|
||||
begin
|
||||
Tls_Server.Run;
|
||||
end Tls_Server_Main;
|
|
@ -0,0 +1,385 @@
|
|||
/* user_settings.h
|
||||
*
|
||||
* Copyright (C) 2006-2023 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL.
|
||||
*
|
||||
* 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-1335, USA
|
||||
*/
|
||||
|
||||
|
||||
/* should be renamed to user_settings.h for customer use
|
||||
* generated from configure options ./configure --enable-all
|
||||
*
|
||||
* Cleaned up by David Garske
|
||||
*/
|
||||
|
||||
#ifndef WOLFSSL_USER_SETTINGS_H
|
||||
#define WOLFSSL_USER_SETTINGS_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Usually comes from configure -> config.h */
|
||||
#define HAVE_SYS_TIME_H
|
||||
|
||||
/* Features */
|
||||
#define SINGLE_THREADED
|
||||
#define WOLFSSL_IGNORE_FILE_WARN /* Ignore *.c include warnings */
|
||||
#define WOLFSSL_PUBLIC_MP /* Make math API's public */
|
||||
#define WOLFSSL_ENCRYPTED_KEYS /* Support for encrypted keys PKCS8 */
|
||||
#define WOLFSSL_SYS_CA_CERTS /* Enable ability to load CA certs from OS */
|
||||
|
||||
#if 0 /* Not needed */
|
||||
#define KEEP_PEER_CERT /* Retain peer's certificate */
|
||||
#define KEEP_OUR_CERT /* Keep our certificate */
|
||||
#define WOLFSSL_ALWAYS_VERIFY_CB /* Always call verify callback (configured via wolfSSL_CTX_set_verify API) */
|
||||
#define WOLFSSL_VERIFY_CB_ALL_CERTS /* Call verify callback for all intermediate certs */
|
||||
#define WOLFSSL_ALWAYS_KEEP_SNI
|
||||
#define WOLFSSL_EXTRA_ALERTS /* Allow sending other TLS alerts */
|
||||
#define HAVE_EX_DATA /* Enable "extra" EX data API's for user information in CTX/WOLFSSL */
|
||||
#define HAVE_EXT_CACHE
|
||||
#define ATOMIC_USER /* Enable Atomic Record Layer callbacks */
|
||||
#define HAVE_PK_CALLBACKS /* Enable public key callbacks */
|
||||
#define WOLFSSL_ALT_NAMES /* Allow alternate cert chain validation to any trusted cert (not entire chain presented by peer) */
|
||||
#define HAVE_NULL_CIPHER /* Enable use of TLS cipher suites without cipher (clear text / no encryption) */
|
||||
#define WOLFSSL_HAVE_CERT_SERVICE
|
||||
#define WOLFSSL_JNI
|
||||
#define WOLFSSL_SEP /* certificate policy set extension */
|
||||
#define WOLFCRYPT_HAVE_SRP
|
||||
#define WOLFSSL_HAVE_WOLFSCEP
|
||||
#define HAVE_PKCS7
|
||||
#define WOLFSSL_SIGNER_DER_CERT
|
||||
#define WOLFSSL_TRUST_PEER_CERT
|
||||
#define WOLFSSL_WOLFSSH
|
||||
#define WC_NO_ASYNC_THREADING
|
||||
#endif
|
||||
|
||||
/* TLS Features */
|
||||
#define WOLFSSL_TLS13
|
||||
#define WOLFSSL_EITHER_SIDE /* allow generic server/client method for WOLFSSL_CTX new */
|
||||
#define WOLFSSL_TLS13_NO_PEEK_HANDSHAKE_DONE
|
||||
|
||||
/* DTLS */
|
||||
#if 0
|
||||
#define WOLFSSL_DTLS
|
||||
#define WOLFSSL_MULTICAST
|
||||
|
||||
/* DTLS v1.3 is not yet included with enable-all */
|
||||
//#define WOLFSSL_DTLS13
|
||||
#endif
|
||||
|
||||
/* DG Disabled SSLv3 and TLSv1.0 - should avoid using */
|
||||
//#define WOLFSSL_ALLOW_SSLV3
|
||||
//#define WOLFSSL_ALLOW_TLSV10
|
||||
|
||||
/* TLS Extensions */
|
||||
#define HAVE_TLS_EXTENSIONS
|
||||
#define HAVE_SUPPORTED_CURVES
|
||||
#define HAVE_ONE_TIME_AUTH
|
||||
#define HAVE_SNI
|
||||
#define HAVE_ALPN
|
||||
#define HAVE_MAX_FRAGMENT
|
||||
#define HAVE_TRUNCATED_HMAC
|
||||
#define HAVE_SESSION_TICKET
|
||||
#define WOLFSSL_TICKET_HAVE_ID
|
||||
#define WOLFSSL_FORCE_CACHE_ON_TICKET
|
||||
#define HAVE_EXTENDED_MASTER
|
||||
#define HAVE_TRUSTED_CA
|
||||
#define HAVE_ENCRYPT_THEN_MAC
|
||||
#define WOLFSSL_POST_HANDSHAKE_AUTH
|
||||
#define WOLFSSL_SEND_HRR_COOKIE /* Used by DTLS v1.3 */
|
||||
#define HAVE_ANON /* anon cipher suites */
|
||||
#define HAVE_FALLBACK_SCSV /* TLS_FALLBACK_SCSV */
|
||||
#define WOLFSSL_EARLY_DATA
|
||||
#define HAVE_SERVER_RENEGOTIATION_INFO
|
||||
|
||||
/* TLS Session Cache */
|
||||
#define SESSION_CERTS
|
||||
#define PERSIST_SESSION_CACHE
|
||||
#define PERSIST_CERT_CACHE
|
||||
|
||||
/* Key and Certificate Generation */
|
||||
#define WOLFSSL_KEY_GEN
|
||||
#define WOLFSSL_CERT_GEN
|
||||
#define WOLFSSL_CERT_REQ
|
||||
#define WOLFSSL_CERT_EXT
|
||||
#define WOLFSSL_MULTI_ATTRIB
|
||||
#define HAVE_SMIME
|
||||
#define WOLFSSL_DER_LOAD
|
||||
#define ASN_BER_TO_DER /* BER to DER support */
|
||||
#define WOLFSSL_HAVE_ISSUER_NAMES /* Store pointers to issuer name components and their lengths and encodings */
|
||||
#define WOLFSSL_SUBJ_DIR_ATTR /* Enable support for SubjectDirectoryAttributes extension */
|
||||
#define WOLFSSL_SUBJ_INFO_ACC /* Enable support for SubjectInfoAccess extension */
|
||||
#define WOLFSSL_CERT_NAME_ALL /* Adds more certificate name capability at the cost of taking up more memory. Adds initials, givenname, dnQualifer for example */
|
||||
#define WOLFSSL_FPKI /* Enable support for FPKI (Federal PKI) extensions */
|
||||
#define WOLFSSL_AKID_NAME /* Enable support for full AuthorityKeyIdentifier extension. Only supports copying full AKID from an existing certificate */
|
||||
#define HAVE_CTS /* Ciphertext stealing interface */
|
||||
#define WOLFSSL_PEM_TO_DER
|
||||
#define WOLFSSL_DER_TO_PEM
|
||||
#define WOLFSSL_CUSTOM_OID
|
||||
#define HAVE_OID_ENCODING
|
||||
#define WOLFSSL_ASN_TEMPLATE
|
||||
|
||||
/* Certificate Revocation */
|
||||
#define HAVE_OCSP
|
||||
#define HAVE_CERTIFICATE_STATUS_REQUEST
|
||||
#define HAVE_CERTIFICATE_STATUS_REQUEST_V2
|
||||
#define HAVE_CRL
|
||||
#define HAVE_CRL_IO
|
||||
#define HAVE_IO_TIMEOUT
|
||||
//#define HAVE_CRL_MONITOR /* DG Disabled (Monitors CRL files on filesystem) - not portable feature */
|
||||
|
||||
|
||||
#if 1
|
||||
/* sp_int.c */
|
||||
#define WOLFSSL_SP_MATH_ALL
|
||||
#else
|
||||
/* Fast math key size 4096-bit max */
|
||||
#define USE_FAST_MATH
|
||||
#endif
|
||||
//#define HAVE___UINT128_T 1 /* DG commented: May not be portable */
|
||||
|
||||
/* Max Sizes */
|
||||
#define RSA_MAX_SIZE 4096
|
||||
#define FP_MAX_BITS 8192
|
||||
#define SP_INT_BITS 4096
|
||||
|
||||
|
||||
/* Timing Resistance */
|
||||
#define TFM_TIMING_RESISTANT
|
||||
#define ECC_TIMING_RESISTANT
|
||||
#define WC_RSA_BLINDING
|
||||
|
||||
/* DH Key Sizes */
|
||||
#define HAVE_FFDHE_2048
|
||||
#define HAVE_FFDHE_3072
|
||||
#define WOLFSSL_DH_EXTRA /* Enable additional DH key import/export */
|
||||
#define HAVE_DH_DEFAULT_PARAMS
|
||||
|
||||
/* ECC Features */
|
||||
#define HAVE_ECC
|
||||
#define TFM_ECC256
|
||||
#define ECC_SHAMIR
|
||||
#define WOLFSSL_CUSTOM_CURVES /* enable other curves (not just prime) */
|
||||
#define HAVE_ECC_SECPR2
|
||||
#define HAVE_ECC_SECPR3
|
||||
#define HAVE_ECC_BRAINPOOL
|
||||
#define HAVE_ECC_KOBLITZ
|
||||
#define HAVE_ECC_CDH /* Co-factor */
|
||||
#define HAVE_COMP_KEY /* Compressed key support */
|
||||
#define FP_ECC /* Fixed point caching - speed repeated operations against same key */
|
||||
#define HAVE_ECC_ENCRYPT
|
||||
#define WOLFCRYPT_HAVE_ECCSI
|
||||
#define WOLFCRYPT_HAVE_SAKKE
|
||||
#define WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT
|
||||
|
||||
/* RSA */
|
||||
#define WC_RSA_PSS
|
||||
#define WOLFSSL_PSS_LONG_SALT
|
||||
#define WC_RSA_NO_PADDING
|
||||
|
||||
/* AES */
|
||||
#define HAVE_AES_DECRYPT
|
||||
#define HAVE_AES_ECB
|
||||
#define WOLFSSL_AES_DIRECT
|
||||
#define WOLFSSL_AES_COUNTER
|
||||
#define HAVE_AESGCM
|
||||
#define GCM_TABLE_4BIT
|
||||
#define WOLFSSL_AESGCM_STREAM
|
||||
#define HAVE_AESCCM
|
||||
#define WOLFSSL_AES_OFB
|
||||
#define WOLFSSL_AES_CFB
|
||||
#define WOLFSSL_AES_XTS
|
||||
#define HAVE_AES_KEYWRAP
|
||||
#define WOLFSSL_AES_CBC_LENGTH_CHECKS
|
||||
#define WOLFSSL_USE_ALIGN
|
||||
#define WOLFSSL_AES_SIV
|
||||
|
||||
/* Hashing */
|
||||
#define WOLFSSL_SHA224
|
||||
#define WOLFSSL_SHA512
|
||||
#define WOLFSSL_SHA384
|
||||
#define WOLFSSL_SHAKE256
|
||||
#define WOLFSSL_SHA3
|
||||
#define WOLFSSL_HASH_FLAGS /* enable hash flag API's */
|
||||
#define WOLFSSL_SHAKE256
|
||||
|
||||
/* Additional Algorithms */
|
||||
#define HAVE_HASHDRBG
|
||||
#define HAVE_CURVE25519
|
||||
#define HAVE_ED25519
|
||||
#define WOLFSSL_ED25519_STREAMING_VERIFY
|
||||
#define CURVED25519_SMALL
|
||||
#define HAVE_ED448
|
||||
#define WOLFSSL_ED448_STREAMING_VERIFY
|
||||
#define HAVE_CURVE448
|
||||
#define HAVE_POLY1305
|
||||
#define HAVE_CHACHA
|
||||
#define HAVE_XCHACHA
|
||||
#define HAVE_HKDF
|
||||
#define HAVE_X963_KDF
|
||||
#define WOLFSSL_CMAC
|
||||
#define WOLFSSL_DES_ECB
|
||||
#define HAVE_BLAKE2
|
||||
#define HAVE_BLAKE2B
|
||||
#define HAVE_BLAKE2S
|
||||
#define WOLFSSL_SIPHASH
|
||||
#define HAVE_KEYING_MATERIAL
|
||||
#define WOLFSSL_HAVE_PRF
|
||||
|
||||
/* Encrypted Client Hello */
|
||||
#define HAVE_HPKE
|
||||
#define HAVE_ECH
|
||||
|
||||
/* Non-Standard Algorithms (DG disabled) */
|
||||
//#define HAVE_CAMELLIA
|
||||
//#define WOLFSSL_RIPEMD
|
||||
//#define HAVE_SCRYPT
|
||||
//#define WOLFSSL_MD2
|
||||
//#define WOLFSSL_ALLOW_RC4
|
||||
|
||||
/* Encoding */
|
||||
#define WOLFSSL_BASE16
|
||||
#define WOLFSSL_BASE64_ENCODE
|
||||
|
||||
|
||||
/* Openssl compatibility */
|
||||
#if 0 /* DG Disabled */
|
||||
/* Openssl compatibility API's */
|
||||
#define OPENSSL_EXTRA
|
||||
#define OPENSSL_ALL
|
||||
#define HAVE_OPENSSL_CMD
|
||||
#define SSL_TXT_TLSV1_2
|
||||
#define SSL_TXT_TLSV1_1
|
||||
#define OPENSSL_NO_SSL2
|
||||
#define OPENSSL_NO_SSL3
|
||||
#define NO_OLD_RNGNAME
|
||||
#define NO_OLD_WC_NAMES
|
||||
#define NO_OLD_SSL_NAMES
|
||||
#define NO_OLD_SHA_NAMES
|
||||
#define NO_OLD_MD5_NAME
|
||||
#define OPENSSL_NO_EC /* macro to enable ECC in openssl */
|
||||
#define WOLFSSL_VERBOSE_ERRORS
|
||||
#define ERROR_QUEUE_PER_THREAD
|
||||
#define WOLFSSL_ERROR_CODE_OPENSSL
|
||||
#define HAVE_WOLFSSL_SSL_H 1
|
||||
#define OPENSSL_COMPATIBLE_DEFAULTS
|
||||
|
||||
/* Openssl compatibility application specific */
|
||||
#define WOLFSSL_LIBWEBSOCKETS
|
||||
#define WOLFSSL_OPENSSH
|
||||
#define WOLFSSL_QT
|
||||
#define FORTRESS
|
||||
#define HAVE_WEBSERVER
|
||||
#define HAVE_LIGHTY
|
||||
#define WOLFSSL_NGINX
|
||||
#define WOLFSSL_HAPROXY
|
||||
#define HAVE_STUNNEL
|
||||
#define WOLFSSL_ASIO
|
||||
#define ASIO_USE_WOLFSSL
|
||||
#define BOOST_ASIO_USE_WOLFSSL
|
||||
#define WOLFSSL_OPENVPN
|
||||
|
||||
#define NO_WOLFSSL_STUB
|
||||
#endif
|
||||
|
||||
/* TLS static cipher support - off by default */
|
||||
#if 0
|
||||
#define WOLFSSL_STATIC_RSA
|
||||
#define WOLFSSL_STATIC_DH
|
||||
#define WOLFSSL_STATIC_PSK
|
||||
#endif
|
||||
|
||||
/* TLS sniffer support - off by default */
|
||||
#if 0
|
||||
#define WOLFSSL_STATIC_EPHEMERAL
|
||||
#define WOLFSSL_SNIFFER
|
||||
#endif
|
||||
|
||||
/* Deprecated */
|
||||
#define NO_DSA
|
||||
#define NO_MD4
|
||||
#define NO_MD5
|
||||
#define NO_OLD_TLS
|
||||
|
||||
/* Used to manually test disable edge cases */
|
||||
#ifdef TEST_DISABLES
|
||||
#define NO_SESSION_CACHE
|
||||
|
||||
//#define NO_ECC256
|
||||
//#define NO_ECC_KEY_EXPORT
|
||||
//#define NO_ECC_DHE
|
||||
//#define NO_ECC_SIGN
|
||||
//#define NO_ECC_VERIFY
|
||||
|
||||
//#define NO_RSA
|
||||
#define NO_DH
|
||||
|
||||
#define NO_SHA
|
||||
#define NO_SHA256
|
||||
#ifdef NO_SHA256
|
||||
#undef WOLFSSL_SHA224
|
||||
#endif
|
||||
#define NO_SHA512
|
||||
#ifdef NO_SHA512
|
||||
#undef WOLFSSL_SHA384
|
||||
#undef WOLFSSL_SHA512
|
||||
#undef HAVE_ED25519
|
||||
#endif
|
||||
|
||||
//#define NO_KDF
|
||||
//#define NO_HMAC
|
||||
|
||||
#define NO_RC4
|
||||
#define NO_DES3
|
||||
//#define NO_AES
|
||||
#define NO_AES_CBC
|
||||
#define WOLFSSL_NO_SHAKE128
|
||||
|
||||
#define NO_PSK
|
||||
#define NO_PWDBASED
|
||||
|
||||
//#define WOLFSSL_NO_TLS12
|
||||
|
||||
//#define NO_64BIT
|
||||
#define WOLFSSL_SP_NO_MALLOC
|
||||
#define NO_FILESYSTEM
|
||||
#define NO_WRITEV
|
||||
|
||||
#define NO_ERROR_STRINGS
|
||||
//#define NO_WOLFSSL_CLIENT
|
||||
//#define NO_WOLFSSL_SERVER
|
||||
|
||||
#define NO_MULTIBYTE_PRINT
|
||||
//#define NO_ASN_TIME
|
||||
//#define NO_ASN_CRYPT
|
||||
//#define NO_CODING
|
||||
#define NO_SIG_WRAPPER
|
||||
//#define NO_HASH_WRAPPER
|
||||
//#define WC_NO_HARDEN
|
||||
|
||||
//#define NO_CERTS
|
||||
//#define NO_ASN
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* WOLFSSL_USER_SETTINGS_H */
|
|
@ -0,0 +1,597 @@
|
|||
with Interfaces.C.Strings;
|
||||
|
||||
package body WolfSSL is
|
||||
|
||||
subtype size_t is Interfaces.C.size_t; use type size_t;
|
||||
|
||||
subtype long is Interfaces.C.long;
|
||||
|
||||
function Get_WolfSSL_Success return int with
|
||||
Convention => C,
|
||||
External_Name => "get_wolfssl_success",
|
||||
Import => True;
|
||||
|
||||
WOLFSSL_SUCCESS : constant int := Get_WolfSSL_Success;
|
||||
|
||||
function Initialize_WolfSSL return int with
|
||||
Convention => C,
|
||||
External_Name => "wolfSSL_Init",
|
||||
Import => True;
|
||||
|
||||
function Finalize_WolfSSL return int with
|
||||
Convention => C,
|
||||
External_Name => "wolfSSL_Cleanup",
|
||||
Import => True;
|
||||
|
||||
procedure Finalize is
|
||||
Result : constant int := Finalize_WolfSSL;
|
||||
begin
|
||||
if Result /= WOLFSSL_SUCCESS then
|
||||
raise Cleanup_Error;
|
||||
end if;
|
||||
end Finalize;
|
||||
|
||||
function WolfTLSv1_2_Server_Method return Method_Type with
|
||||
Convention => C,
|
||||
External_Name => "wolfTLSv1_2_server_method",
|
||||
Import => True;
|
||||
|
||||
function TLSv1_2_Server_Method return Method_Type is
|
||||
begin
|
||||
return WolfTLSv1_2_Server_Method;
|
||||
end TLSv1_2_Server_Method;
|
||||
|
||||
function WolfTLSv1_3_Server_Method return Method_Type with
|
||||
Convention => C,
|
||||
External_Name => "wolfTLSv1_3_server_method",
|
||||
Import => True;
|
||||
|
||||
function TLSv1_3_Server_Method return Method_Type is
|
||||
begin
|
||||
return WolfTLSv1_3_Server_Method;
|
||||
end TLSv1_3_Server_Method;
|
||||
|
||||
function WolfSSL_CTX_new (Method : Method_Type)
|
||||
return Context_Type with
|
||||
Convention => C, External_Name => "wolfSSL_CTX_new", Import => True;
|
||||
|
||||
procedure Create_Context (Method : Method_Type;
|
||||
Context : out Optional_Context) is
|
||||
C : constant Context_Type := WolfSSL_CTX_new (Method);
|
||||
begin
|
||||
if C = null then
|
||||
Context := (Exists => False);
|
||||
else
|
||||
Context := (Exists => True, Instance => C);
|
||||
end if;
|
||||
end Create_Context;
|
||||
|
||||
procedure WolfSSL_CTX_free (Context : Context_Type) with
|
||||
Convention => C, External_Name => "wolfSSL_CTX_free", Import => True;
|
||||
|
||||
procedure Free (Context : in out Optional_Context) is
|
||||
begin
|
||||
WolfSSL_CTX_free (Context.Instance);
|
||||
Context := (Exists => False);
|
||||
end Free;
|
||||
|
||||
type Opaque_X509_Store_Context is limited null record;
|
||||
type X509_Store_Context is access Opaque_X509_Store_Context with
|
||||
Convention => C;
|
||||
|
||||
type Verify_Callback is access function
|
||||
(A : int;
|
||||
Context : X509_Store_Context)
|
||||
return int
|
||||
with Convention => C;
|
||||
|
||||
procedure WolfSSL_CTX_Set_Verify (Context : Context_Type;
|
||||
Mode : int;
|
||||
Callback : Verify_Callback) with
|
||||
Convention => C,
|
||||
External_Name => "wolfSSL_CTX_set_verify",
|
||||
Import => True;
|
||||
-- This function sets the verification method for remote peers and
|
||||
-- also allows a verify callback to be registered with the SSL
|
||||
-- context. The verify callback will be called only when a
|
||||
-- verification failure has occurred. If no verify callback is
|
||||
-- desired, the NULL pointer can be used for verify_callback.
|
||||
-- The verification mode of peer certificates is a logically OR'd
|
||||
-- list of flags. The possible flag values include:
|
||||
-- SSL_VERIFY_NONE Client mode: the client will not verify the
|
||||
-- certificate received from the server and the handshake will
|
||||
-- continue as normal. Server mode: the server will not send a
|
||||
-- certificate request to the client. As such, client verification
|
||||
-- will not be enabled. SSL_VERIFY_PEER Client mode: the client will
|
||||
-- verify the certificate received from the server during the
|
||||
-- handshake. This is turned on by default in wolfSSL, therefore,
|
||||
-- using this option has no effect. Server mode: the server will send
|
||||
-- a certificate request to the client and verify the client
|
||||
-- certificate received. SSL_VERIFY_FAIL_IF_NO_PEER_CERT Client mode:
|
||||
-- no effect when used on the client side. Server mode:
|
||||
-- the verification will fail on the server side if the client fails
|
||||
-- to send a certificate when requested to do so (when using
|
||||
-- SSL_VERIFY_PEER on the SSL server).
|
||||
-- SSL_VERIFY_FAIL_EXCEPT_PSK Client mode: no effect when used on
|
||||
-- the client side. Server mode: the verification is the same as
|
||||
-- SSL_VERIFY_FAIL_IF_NO_PEER_CERT except in the case of a
|
||||
-- PSK connection. If a PSK connection is being made then the
|
||||
-- connection will go through without a peer cert.
|
||||
|
||||
function "&" (Left, Right : Mode_Type) return Mode_Type is
|
||||
L : constant Unsigned_32 := Unsigned_32 (Left);
|
||||
R : constant Unsigned_32 := Unsigned_32 (Right);
|
||||
begin
|
||||
return Mode_Type (L and R);
|
||||
end "&";
|
||||
|
||||
procedure Set_Verify (Context : Context_Type;
|
||||
Mode : Mode_Type) is
|
||||
begin
|
||||
WolfSSL_CTX_Set_Verify (Context => Context,
|
||||
Mode => int (Mode),
|
||||
Callback => null);
|
||||
end Set_Verify;
|
||||
|
||||
function Use_Certificate_File (Context : Context_Type;
|
||||
File : char_array;
|
||||
Format : int)
|
||||
return int with
|
||||
Convention => C,
|
||||
External_Name => "wolfSSL_CTX_use_certificate_file",
|
||||
Import => True;
|
||||
|
||||
function Use_Certificate_File (Context : Context_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_Certificate_File (Context, F (1 .. C), int (Format));
|
||||
if Result = WOLFSSL_SUCCESS then
|
||||
return Success;
|
||||
else
|
||||
return Failure;
|
||||
end if;
|
||||
end Use_Certificate_File;
|
||||
|
||||
function Use_Certificate_Buffer (Context : Context_Type;
|
||||
Input : char_array;
|
||||
Size : long;
|
||||
Format : int)
|
||||
return int with
|
||||
Convention => C,
|
||||
External_Name => "wolfSSL_CTX_use_certificate_buffer",
|
||||
Import => True;
|
||||
|
||||
function Use_Certificate_Buffer (Context : Context_Type;
|
||||
Input : char_array;
|
||||
Format : File_Format)
|
||||
return Subprogram_Result is
|
||||
Result : int;
|
||||
begin
|
||||
Result := Use_Certificate_Buffer (Context, Input,
|
||||
Input'Length, int (Format));
|
||||
if Result = WOLFSSL_SUCCESS then
|
||||
return Success;
|
||||
else
|
||||
return Failure;
|
||||
end if;
|
||||
end Use_Certificate_Buffer;
|
||||
|
||||
function Use_Private_Key_File (Context : Context_Type;
|
||||
File : char_array;
|
||||
Format : int)
|
||||
return int with
|
||||
Convention => C,
|
||||
External_Name => "wolfSSL_CTX_use_PrivateKey_file",
|
||||
Import => True;
|
||||
|
||||
function Use_Private_Key_File (Context : Context_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 (Context, F (1 .. C), int (Format));
|
||||
if Result = WOLFSSL_SUCCESS then
|
||||
return Success;
|
||||
else
|
||||
return Failure;
|
||||
end if;
|
||||
end Use_Private_Key_File;
|
||||
|
||||
function Use_Private_Key_Buffer (Context : Context_Type;
|
||||
Input : char_array;
|
||||
Size : long;
|
||||
Format : int)
|
||||
return int with
|
||||
Convention => C,
|
||||
External_Name => "wolfSSL_CTX_use_PrivateKey_buffer",
|
||||
Import => True;
|
||||
|
||||
function Use_Private_Key_Buffer (Context : Context_Type;
|
||||
Input : Byte_Array;
|
||||
Format : File_Format)
|
||||
return Subprogram_Result is
|
||||
Result : int;
|
||||
begin
|
||||
Result := Use_Private_Key_Buffer (Context, Input,
|
||||
Input'Length, int (Format));
|
||||
if Result = WOLFSSL_SUCCESS then
|
||||
return Success;
|
||||
else
|
||||
return Failure;
|
||||
end if;
|
||||
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;
|
||||
-- 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
|
||||
-- from peers during the SSL handshake. The root certificate file,
|
||||
-- provided by the file argument, may be a single certificate or a
|
||||
-- file containing multiple certificates. If multiple CA certs are
|
||||
-- included in the same file, wolfSSL will load them in the same order
|
||||
-- they are presented in the file. The path argument is a pointer to
|
||||
-- the name of a directory that contains certificates of trusted
|
||||
-- root CAs. If the value of file is not NULL, path may be specified
|
||||
-- as NULL if not needed. If path is specified and NO_WOLFSSL_DIR was
|
||||
-- not defined when building the library, wolfSSL will load all
|
||||
-- CA certificates located in the given directory. This function will
|
||||
-- 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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
function Load_Verify_Locations (Context : Context_Type;
|
||||
File : String;
|
||||
Path : String)
|
||||
return Subprogram_Result is
|
||||
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 (Context, null, null);
|
||||
else
|
||||
Interfaces.C.To_C (Item => Path,
|
||||
Target => P,
|
||||
Count => PC,
|
||||
Append_Nul => True);
|
||||
Result := Load_Verify_Locations3 (Context, null, P);
|
||||
end if;
|
||||
else
|
||||
Interfaces.C.To_C (Item => File,
|
||||
Target => F,
|
||||
Count => FC,
|
||||
Append_Nul => True);
|
||||
if Path = "" then
|
||||
Result := Load_Verify_Locations2 (Context, 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, F, P);
|
||||
end if;
|
||||
end if;
|
||||
if Result = WOLFSSL_SUCCESS then
|
||||
return Success;
|
||||
else
|
||||
return Failure;
|
||||
end if;
|
||||
end Load_Verify_Locations;
|
||||
|
||||
function Load_Verify_Buffer1
|
||||
(Context : Context_Type;
|
||||
Input : char_array;
|
||||
Size : int;
|
||||
Format : int) return int with
|
||||
Convention => C,
|
||||
External_Name => "wolfSSL_CTX_load_verify_buffer",
|
||||
Import => True;
|
||||
-- This function loads a CA certificate buffer into the WOLFSSL
|
||||
-- Context. It behaves like the non-buffered version, only differing
|
||||
-- in its ability to be called with a buffer as input instead of
|
||||
-- a file. The buffer is provided by the in argument of size sz.
|
||||
-- format specifies the format type of the buffer; SSL_FILETYPE_ASN1
|
||||
-- or SSL_FILETYPE_PEM. More than one CA certificate may be loaded
|
||||
-- per buffer as long as the format is in PEM. Please see
|
||||
-- the examples for proper usage.
|
||||
|
||||
function Load_Verify_Buffer (Context : Context_Type;
|
||||
Input : Byte_Array;
|
||||
Format : File_Format)
|
||||
return Subprogram_Result is
|
||||
Result : int;
|
||||
begin
|
||||
Result := Load_Verify_Buffer1 (Context => Context,
|
||||
Input => Input,
|
||||
Size => Input'Length,
|
||||
Format => int(Format));
|
||||
if Result = WOLFSSL_SUCCESS then
|
||||
return Success;
|
||||
else
|
||||
return Failure;
|
||||
end if;
|
||||
end Load_Verify_Buffer;
|
||||
|
||||
function WolfSSL_New (Context : Context_Type)
|
||||
return WolfSSL_Type with
|
||||
Convention => C,
|
||||
External_Name => "wolfSSL_new",
|
||||
Import => True;
|
||||
|
||||
procedure Create_WolfSSL (Context : Context_Type;
|
||||
Ssl : out Optional_WolfSSL) is
|
||||
Result : WolfSSL_Type := WolfSSL_New (Context);
|
||||
begin
|
||||
if Result /= null then
|
||||
Ssl := (Exists => True,
|
||||
Instance => Result);
|
||||
else
|
||||
Ssl := (Exists => False);
|
||||
end if;
|
||||
end Create_WolfSSL;
|
||||
|
||||
function WolfSSL_Set_Fd (Ssl : WolfSSL_Type; Fd : int) return int with
|
||||
Convention => C,
|
||||
External_Name => "wolfSSL_set_fd",
|
||||
Import => True;
|
||||
|
||||
function Attach (Ssl : WolfSSL_Type;
|
||||
Socket : Integer)
|
||||
return Subprogram_Result is
|
||||
Result : int := WolfSSL_Set_Fd (Ssl, int (Socket));
|
||||
begin
|
||||
if Result = WOLFSSL_SUCCESS then
|
||||
return Success;
|
||||
else
|
||||
return Failure;
|
||||
end if;
|
||||
end Attach;
|
||||
|
||||
procedure WolfSSL_Keep_Arrays (Ssl : WolfSSL_Type) with
|
||||
Convention => C,
|
||||
External_Name => "wolfSSL_KeepArrays",
|
||||
Import => True;
|
||||
|
||||
procedure Keep_Arrays (Ssl : WolfSSL_Type) is
|
||||
begin
|
||||
WolfSSL_Keep_Arrays (Ssl);
|
||||
end Keep_Arrays;
|
||||
|
||||
function WolfSSL_Accept (Ssl : WolfSSL_Type) return int with
|
||||
Convention => C,
|
||||
External_Name => "wolfSSL_accept",
|
||||
Import => True;
|
||||
|
||||
function Accept_Connection (Ssl : WolfSSL_Type)
|
||||
return Subprogram_Result is
|
||||
Result : int := WolfSSL_Accept (Ssl);
|
||||
begin
|
||||
if Result = WOLFSSL_SUCCESS then
|
||||
return Success;
|
||||
else
|
||||
return Failure;
|
||||
end if;
|
||||
end Accept_Connection;
|
||||
|
||||
procedure WolfSSL_Free_Arrays (Ssl : WolfSSL_Type) with
|
||||
Convention => C,
|
||||
External_Name => "wolfSSL_FreeArrays",
|
||||
Import => True;
|
||||
|
||||
procedure Free_Arrays (Ssl : WolfSSL_Type) is
|
||||
begin
|
||||
WolfSSL_Free_Arrays (Ssl);
|
||||
end Free_Arrays;
|
||||
|
||||
function WolfSSL_Read (Ssl : WolfSSL_Type;
|
||||
Data : out char_array;
|
||||
Sz : int) return int with
|
||||
Convention => C,
|
||||
External_Name => "wolfSSL_read",
|
||||
Import => True;
|
||||
-- This function reads sz bytes from the SSL session (ssl) internal
|
||||
-- read buffer into the buffer data. The bytes read are removed from
|
||||
-- the internal receive buffer. If necessary wolfSSL_read() will
|
||||
-- negotiate an SSL/TLS session if the handshake has not already
|
||||
-- been performed yet by wolfSSL_connect() or wolfSSL_accept().
|
||||
-- The SSL/TLS protocol uses SSL records which have a maximum size
|
||||
-- of 16kB (the max record size can be controlled by the
|
||||
-- MAX_RECORD_SIZE define in /wolfssl/internal.h). As such, wolfSSL
|
||||
-- needs to read an entire SSL record internally before it is able
|
||||
-- to process and decrypt the record. Because of this, a call to
|
||||
-- wolfSSL_read() will only be able to return the maximum buffer
|
||||
-- size which has been decrypted at the time of calling. There may
|
||||
-- be additional not-yet-decrypted data waiting in the internal
|
||||
-- wolfSSL receive buffer which will be retrieved and decrypted with
|
||||
-- the next call to wolfSSL_read(). If sz is larger than the number
|
||||
-- of bytes in the internal read buffer, SSL_read() will return
|
||||
-- the bytes available in the internal read buffer. If no bytes are
|
||||
-- buffered in the internal read buffer yet, a call to wolfSSL_read()
|
||||
-- will trigger processing of the next record.
|
||||
--
|
||||
-- The integer returned is the number of bytes read upon success.
|
||||
-- 0 will be returned upon failure. This may be caused by a either
|
||||
-- a clean (close notify alert) shutdown or just that the peer closed
|
||||
-- the connection. Call wolfSSL_get_error() for the specific
|
||||
-- error code. SSL_FATAL_ERROR will be returned upon failure when
|
||||
-- either an error occurred or, when using non-blocking sockets,
|
||||
-- the SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE error was received
|
||||
-- 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;
|
||||
begin
|
||||
Size := WolfSSL_Read (Ssl, Data, int (Byte_Index'Last));
|
||||
if Size < 0 then
|
||||
return (Result => Failure, Last => 0);
|
||||
else
|
||||
return (Result => Success,
|
||||
Last => Byte_Index (Size),
|
||||
Buffer => Data (1 .. Byte_Index (Size)));
|
||||
end if;
|
||||
end Read;
|
||||
|
||||
function WolfSSL_Write (Ssl : WolfSSL_Type;
|
||||
Data : char_array;
|
||||
Sz : int) return int with
|
||||
Convention => C,
|
||||
External_Name => "wolfSSL_write",
|
||||
Import => True;
|
||||
|
||||
function Write (Ssl : WolfSSL_Type;
|
||||
Data : Byte_Array) return Integer is
|
||||
Size : constant int := Data'Length;
|
||||
Result : int;
|
||||
begin
|
||||
Result := WolfSSL_Write (Ssl, Data, Size);
|
||||
return Integer (Result);
|
||||
end Write;
|
||||
|
||||
function WolfSSL_Shutdown (Ssl : WolfSSL_Type) return int with
|
||||
Convention => C,
|
||||
External_Name => "wolfSSL_shutdown",
|
||||
Import => True;
|
||||
-- This function shuts down an active SSL/TLS connection using
|
||||
-- the SSL session, ssl. This function will try to send a
|
||||
-- "close notify" alert to the peer. The calling application can
|
||||
-- choose to wait for the peer to send its "close notify" alert
|
||||
-- in response or just go ahead and shut down the underlying
|
||||
-- connection after directly calling wolfSSL_shutdown (to save
|
||||
-- resources). Either option is allowed by the TLS specification.
|
||||
-- If the underlying connection will be used again in the future,
|
||||
-- the complete two_directional shutdown procedure must be performed
|
||||
-- to keep synchronization intact between the peers.
|
||||
-- wolfSSL_shutdown() works with both blocking and non_blocking I/O.
|
||||
-- When the underlying I/O is non_blocking, wolfSSL_shutdown() will
|
||||
-- return an error if the underlying I/O could not satisfy the needs
|
||||
-- of wolfSSL_shutdown() to continue. In this case, a call to
|
||||
-- wolfSSL_get_error() will yield either SSL_ERROR_WANT_READ or
|
||||
-- SSL_ERROR_WANT_WRITE. The calling process must then repeat
|
||||
-- the call to wolfSSL_shutdown() when the underlying I/O is ready.
|
||||
|
||||
function Shutdown (Ssl : WolfSSL_Type) return Subprogram_Result is
|
||||
Result : constant int := WolfSSL_Shutdown (Ssl);
|
||||
begin
|
||||
if Result = WOLFSSL_SUCCESS then
|
||||
return Success;
|
||||
else
|
||||
return Failure;
|
||||
end if;
|
||||
end Shutdown;
|
||||
|
||||
function WolfSSL_Connect (Ssl : WolfSSL_Type) return int with
|
||||
Convention => C,
|
||||
External_Name => "wolfSSL_connect",
|
||||
Import => True;
|
||||
-- This function is called on the client side and initiates
|
||||
-- an SSL/TLS handshake with a server. When this function is called,
|
||||
-- the underlying communication channel has already been set up.
|
||||
-- wolfSSL_connect() works with both blocking and non_blocking I/O.
|
||||
-- When the underlying I/O is non_blocking, wolfSSL_connect() will
|
||||
-- return when the underlying I/O could not satisfy the needs
|
||||
-- of wolfSSL_connect to continue the handshake. In this case,
|
||||
-- a call to wolfSSL_get_error() will yield either
|
||||
-- SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE. The calling process
|
||||
-- must then repeat the call to wolfSSL_connect() when
|
||||
-- the underlying I/O is ready and wolfSSL will pick up where
|
||||
-- it left off. When using a non_blocking socket, nothing needs
|
||||
-- to be done, but select() can be used to check for the required
|
||||
-- condition. If the underlying I/O is blocking, wolfSSL_connect()
|
||||
-- will only return once the handshake has been finished or an error
|
||||
-- occurred. wolfSSL takes a different approach to certificate
|
||||
-- verification than OpenSSL does. The default policy for the client
|
||||
-- is to verify the server, this means that if you don't load CAs
|
||||
-- to verify the server you'll get a connect error,
|
||||
-- unable to verify (_155). It you want to mimic OpenSSL behavior
|
||||
-- of having SSL_connect succeed even if verifying the server fails
|
||||
-- and reducing security you can do this by calling:
|
||||
-- SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0); before calling
|
||||
-- SSL_new(); Though it's not recommended.
|
||||
|
||||
function Connect (Ssl : WolfSSL_Type) return Subprogram_Result is
|
||||
Result : constant int := WolfSSL_Connect (Ssl);
|
||||
begin
|
||||
if Result = WOLFSSL_SUCCESS then
|
||||
return Success;
|
||||
else
|
||||
return Failure;
|
||||
end if;
|
||||
end Connect;
|
||||
|
||||
procedure WolfSSL_Free (Ssl : WolfSSL_Type) with
|
||||
Convention => C,
|
||||
External_Name => "wolfSSL_free",
|
||||
Import => True;
|
||||
|
||||
procedure Free (Ssl : in out Optional_WolfSSL) is
|
||||
begin
|
||||
if Ssl.Exists then
|
||||
WolfSSL_Free (Ssl.Instance);
|
||||
end if;
|
||||
Ssl := (Exists => False);
|
||||
end Free;
|
||||
|
||||
Result : constant int := Initialize_WolfSSL;
|
||||
begin
|
||||
if Result /= WOLFSSL_SUCCESS then
|
||||
raise Initialization_Error;
|
||||
end if;
|
||||
end WolfSSL;
|
|
@ -0,0 +1,262 @@
|
|||
with Interfaces.C;
|
||||
|
||||
-- This package is annotated "with SPARK_Mode" that SPARK can verify
|
||||
-- the API of this package is used correctly. The body of this package
|
||||
-- cannot be formally verified since it calls C functions and uses
|
||||
-- access-to-object types which are not part of the SPARK subset of
|
||||
-- the Ada programming language.
|
||||
package WolfSSL with SPARK_Mode is
|
||||
|
||||
procedure Finalize;
|
||||
-- Must be called before application exit.
|
||||
|
||||
Initialization_Error : exception;
|
||||
-- Raised if error was encountered during initialization of the
|
||||
-- WolfSSL library. The WolfSSL libray is initialized during
|
||||
-- elaboration time.
|
||||
|
||||
Cleanup_Error : exception;
|
||||
-- Raised if error was encountered during application shutdown
|
||||
-- and cleanup of resources allocated by WolfSSL has failed.
|
||||
|
||||
subtype char_array is Interfaces.C.char_array; -- Remove?
|
||||
|
||||
subtype Byte_Index is Interfaces.C.size_t range 0 .. 16_000;
|
||||
subtype Byte_Array is Interfaces.C.char_array;
|
||||
|
||||
type Subprogram_Result is (Success, Failure);
|
||||
|
||||
type Context_Type is limited private;
|
||||
|
||||
type Optional_Context (Exists : Boolean := False) is record
|
||||
case Exists is
|
||||
when True => Instance : Context_Type;
|
||||
when False => null;
|
||||
end case;
|
||||
end record;
|
||||
|
||||
type Method_Type is limited private;
|
||||
|
||||
function TLSv1_2_Server_Method return Method_Type;
|
||||
function TLSv1_3_Server_Method return Method_Type;
|
||||
|
||||
procedure Create_Context (Method : Method_Type;
|
||||
Context : out Optional_Context);
|
||||
-- Create and initialize a WolfSSL context.
|
||||
|
||||
procedure Free (Context : in out Optional_Context) with
|
||||
Pre => Context.Exists,
|
||||
Post => not Context.Exists;
|
||||
|
||||
type Mode_Type is private;
|
||||
|
||||
function "&" (Left, Right : Mode_Type) return Mode_Type;
|
||||
|
||||
Verify_None : constant Mode_Type;
|
||||
|
||||
Verify_Peer : constant Mode_Type;
|
||||
|
||||
Verify_Fail_If_No_Peer_Cert : constant Mode_Type;
|
||||
|
||||
Verify_Client_Once : constant Mode_Type;
|
||||
|
||||
Verify_Post_Handshake : constant Mode_Type;
|
||||
|
||||
Verify_Fail_Except_Psk : constant Mode_Type;
|
||||
|
||||
Verify_Default : constant Mode_Type;
|
||||
|
||||
procedure Set_Verify (Context : Context_Type;
|
||||
Mode : Mode_Type);
|
||||
|
||||
type File_Format is private;
|
||||
|
||||
Format_Asn1 : constant File_Format;
|
||||
Format_Pem : constant File_Format;
|
||||
Format_Default : constant File_Format;
|
||||
|
||||
function Use_Certificate_File (Context : Context_Type;
|
||||
File : String;
|
||||
Format : File_Format)
|
||||
return Subprogram_Result;
|
||||
|
||||
function Use_Certificate_Buffer (Context : Context_Type;
|
||||
Input : char_array;
|
||||
Format : File_Format)
|
||||
return Subprogram_Result;
|
||||
|
||||
function Use_Private_Key_File (Context : Context_Type;
|
||||
File : String;
|
||||
Format : File_Format)
|
||||
return Subprogram_Result;
|
||||
|
||||
function Use_Private_Key_Buffer (Context : Context_Type;
|
||||
Input : Byte_Array;
|
||||
Format : File_Format)
|
||||
return Subprogram_Result;
|
||||
|
||||
function Load_Verify_Locations (Context : Context_Type;
|
||||
File : String;
|
||||
Path : String)
|
||||
return Subprogram_Result;
|
||||
|
||||
function Load_Verify_Buffer (Context : Context_Type;
|
||||
Input : Byte_Array;
|
||||
Format : File_Format)
|
||||
return Subprogram_Result;
|
||||
|
||||
type WolfSSL_Type is limited private;
|
||||
|
||||
type Optional_WolfSSL (Exists : Boolean := False) is record
|
||||
case Exists is
|
||||
when True => Instance : WolfSSL_Type;
|
||||
when False => null;
|
||||
end case;
|
||||
end record;
|
||||
|
||||
procedure Create_WolfSSL (Context : Context_Type;
|
||||
Ssl : out Optional_WolfSSL);
|
||||
|
||||
-- Attach wolfSSL to the socket.
|
||||
function Attach (Ssl : WolfSSL_Type;
|
||||
Socket : Integer)
|
||||
return Subprogram_Result;
|
||||
|
||||
procedure Keep_Arrays (Ssl : WolfSSL_Type);
|
||||
-- Don't free temporary arrays at end of handshake.
|
||||
|
||||
procedure Free_Arrays (Ssl : WolfSSL_Type);
|
||||
-- User doesn't need temporary arrays anymore, Free.
|
||||
|
||||
function Accept_Connection (Ssl : WolfSSL_Type)
|
||||
return Subprogram_Result;
|
||||
|
||||
-- This record type has discriminants with default values to be able
|
||||
-- to compile this code under the restriction no secondary stack.
|
||||
type Read_Result (Result : Subprogram_Result := Failure;
|
||||
Last : Byte_Index := Byte_Index'Last) is record
|
||||
case Result is
|
||||
when Success => Buffer : Byte_Array (1 .. Last);
|
||||
when Failure => null;
|
||||
end case;
|
||||
end record;
|
||||
|
||||
function Read (Ssl : WolfSSL_Type) return Read_Result;
|
||||
|
||||
-- The number of bytes written is returned.
|
||||
function Write (Ssl : WolfSSL_Type; Data : Byte_Array) return Integer;
|
||||
|
||||
function Shutdown (Ssl : WolfSSL_Type) return Subprogram_Result;
|
||||
|
||||
procedure Free (Ssl : in out Optional_WolfSSL) with
|
||||
Pre => Ssl.Exists,
|
||||
Post => not Ssl.Exists;
|
||||
|
||||
function Connect (Ssl : WolfSSL_Type) return Subprogram_Result;
|
||||
|
||||
private
|
||||
pragma SPARK_Mode (Off);
|
||||
|
||||
subtype int is Interfaces.C.int; use type int;
|
||||
|
||||
type Opaque_Method is limited null record;
|
||||
type Opaque_Context is limited null record;
|
||||
type Opaque_WolfSSL is limited null record;
|
||||
|
||||
-- Access-to-object types with convention C uses the same amount of
|
||||
-- memory for storing pointers as is done in the C programming
|
||||
-- language. The following access type definitions are used in
|
||||
-- the Ada binding to the WolfSSL library:
|
||||
type Context_Type is access Opaque_Context with Convention => C;
|
||||
type Method_Type is access Opaque_Method with Convention => C;
|
||||
type WolfSSL_Type is access Opaque_WolfSSL with Convention => C;
|
||||
|
||||
subtype Unsigned_32 is Interfaces.Unsigned_32; use type Unsigned_32;
|
||||
|
||||
type Mode_Type is new Unsigned_32;
|
||||
|
||||
-- The following imported subprograms are used to initialize
|
||||
-- the constants defined in the public part of this package
|
||||
-- specification. They cannot therefore be moved to the body
|
||||
-- of this package.
|
||||
|
||||
function WolfSSL_Verify_None return int with
|
||||
Convention => C,
|
||||
External_Name => "get_wolfssl_verify_none",
|
||||
Import => True;
|
||||
|
||||
function WolfSSL_Verify_Peer return int with
|
||||
Convention => C,
|
||||
External_Name => "get_wolfssl_verify_peer",
|
||||
Import => True;
|
||||
|
||||
function WolfSSL_Verify_Fail_If_No_Peer_Cert return int with
|
||||
Convention => C,
|
||||
External_Name => "get_wolfssl_verify_fail_if_no_peer_cert",
|
||||
Import => True;
|
||||
|
||||
function WolfSSL_Verify_Client_Once return int with
|
||||
Convention => C,
|
||||
External_Name => "get_wolfssl_verify_client_once",
|
||||
Import => True;
|
||||
|
||||
function WolfSSL_Verify_Post_Handshake return int with
|
||||
Convention => C,
|
||||
External_Name => "get_wolfssl_verify_post_handshake",
|
||||
Import => True;
|
||||
|
||||
function WolfSSL_Verify_Fail_Except_Psk return int with
|
||||
Convention => C,
|
||||
External_Name => "get_wolfssl_verify_fail_except_psk",
|
||||
Import => True;
|
||||
|
||||
function WolfSSL_Verify_Default return int with
|
||||
Convention => C,
|
||||
External_Name => "get_wolfssl_verify_default",
|
||||
Import => True;
|
||||
|
||||
Verify_None : constant Mode_Type := Mode_Type (WolfSSL_Verify_None);
|
||||
Verify_Peer : constant Mode_Type := Mode_Type (WolfSSL_Verify_Peer);
|
||||
|
||||
Verify_Fail_If_No_Peer_Cert : constant Mode_Type :=
|
||||
Mode_Type (WolfSSL_Verify_Fail_If_No_Peer_Cert);
|
||||
|
||||
Verify_Client_Once : constant Mode_Type :=
|
||||
Mode_Type (WolfSSL_Verify_Client_Once);
|
||||
|
||||
Verify_Post_Handshake : constant Mode_Type :=
|
||||
Mode_Type (WolfSSL_Verify_Post_Handshake);
|
||||
|
||||
Verify_Fail_Except_Psk : constant Mode_Type :=
|
||||
Mode_Type (WolfSSL_Verify_Fail_Except_Psk);
|
||||
|
||||
Verify_Default : constant Mode_Type :=
|
||||
Mode_Type (WolfSSL_Verify_Default);
|
||||
|
||||
type File_Format is new Unsigned_32;
|
||||
|
||||
function WolfSSL_Filetype_Asn1 return int with
|
||||
Convention => C,
|
||||
External_Name => "get_wolfssl_filetype_asn1",
|
||||
Import => True;
|
||||
|
||||
function WolfSSL_Filetype_Pem return int with
|
||||
Convention => C,
|
||||
External_Name => "get_wolfssl_filetype_pem",
|
||||
Import => True;
|
||||
|
||||
function WolfSSL_Filetype_Default return int with
|
||||
Convention => C,
|
||||
External_Name => "get_wolfssl_filetype_default",
|
||||
Import => True;
|
||||
|
||||
Format_Asn1 : constant File_Format :=
|
||||
File_Format (WolfSSL_Filetype_Asn1);
|
||||
|
||||
Format_Pem : constant File_Format :=
|
||||
File_Format (WolfSSL_Filetype_Pem);
|
||||
|
||||
Format_Default : constant File_Format :=
|
||||
File_Format (WolfSSL_Filetype_Default);
|
||||
|
||||
end WolfSSL;
|
|
@ -2,6 +2,7 @@
|
|||
# included from Top Level Makefile.am
|
||||
# All paths should be given relative to the root
|
||||
|
||||
include wrapper/Ada/include.am
|
||||
include wrapper/CSharp/include.am
|
||||
|
||||
EXTRA_DIST+= wrapper/python/README.md
|
||||
|
|
Loading…
Reference in New Issue