diff --git a/Makefile b/Makefile
index a400823..c0f20f1 100644
--- a/Makefile
+++ b/Makefile
@@ -53,12 +53,21 @@ util: all-utils
CONFIG_EXTRA_DEPENDENCIES=
+CORE_CONFIG_DIR=core/config
+CORE_CONFIG_FILE=$(CORE_CONFIG_DIR)/coreConfig.h
+
+# ! -e $(CORE_CONFIG_FILE) ] || ! cmp -s $(1)/coreConfig.h $(CORE_CONFIG_FILE)
+define apply_core_config
+@if [ ! -e $(CORE_CONFIG_FILE) ] || ! cmp -s $(1)/coreConfig.h $(CORE_CONFIG_FILE); then cp $(1)/coreConfig.h $(CORE_CONFIG_FILE); echo cp $(1)/coreConfig.h $(CORE_CONFIG_FILE); echo WARNING: Applied new configuration also to core. You may need to recompile the core.;fi
+endef
+
+# ! -e $(CORE_CONFIG_FILE) ] || ! cmp -s $(1)/coreConfig.h $(CORE_CONFIG_FILE)
+define apply_core_config_non_exist
+@if [ ! -e $(CORE_CONFIG_FILE) ]; then cp $(1)/coreConfig.h $(CORE_CONFIG_FILE); echo cp $(1)/coreConfig.h $(CORE_CONFIG_FILE); echo WARNING: Applied new configuration also to core. You may need to recompile the core.;fi
+endef
+
# Use default config if no config is being used.
check-config: $(CONFIG_EXTRA_DEPENDENCIES)
- @if [ ! -e core/coreConfig.h ];then \
- cp configs/default/coreConfig.h core/coreConfig.h;\
- echo NOTE: Using default configuration from configs/default/coreConfig.h.;\
- fi
@if [ ! -e crypto/cryptoConfig.h ];then \
cp configs/default/cryptoConfig.h crypto/cryptoConfig.h;\
echo NOTE: Using default configuration from configs/default/cryptoConfig.h.;\
@@ -67,6 +76,7 @@ check-config: $(CONFIG_EXTRA_DEPENDENCIES)
cp configs/default/matrixsslConfig.h matrixssl/matrixsslConfig.h;\
echo NOTE: Using default configuration from configs/default/matrixsslConfig.h.;\
fi
+ $(call apply_core_config_non_exist,configs/default)
clean-config:
rm -f core/coreConfig.h crypto/cryptoConfig.h matrixssl/matrixsslConfig.h
@@ -74,9 +84,9 @@ clean-config:
# Apply any of pre-existing configurations from configs directory
%-config: configs/% $(CONFIG_EXTRA_DEPENDENCIES)
@echo Using $*Config.h.
- cp $MatrixSSL has been continuously maintained since 2002. It is the first open source small footprint SSL stack. Until recently, releases were tracked on http://freecode.com/projects/matrixssl
-MatrixSSL is an embedded SSL and TLS implementation designed for small footprint IoT devices requiring low overhead per connection. The library is less than 50Kb on disk with cipher suites. It includes client and server support through TLS 1.2, mutual authentication, session resumption, and implementations of RSA, ECC, AES, SHA1, SHA-256 and more. The source is well documented and contains portability layers for additional operating systems, cipher suites, and cryptography providers.
+MatrixSSL is an embedded SSL and TLS implementation designed for small footprint IoT devices requiring low overhead per connection. It includes client and server support through TLS 1.3, mutual authentication, session resumption, and implementations of RSA, ECC, AES, SHA1, SHA-256, ChaCha20-Poly1305 and more. The source is well documented and contains portability layers for additional operating systems, cipher suites, and cryptography providers.
Reporting Issues
@@ -23,9 +23,9 @@ Sensitive emails can be encrypted using the public key in this directory Features
-- < 50KB total footprint with crypto provider
-- SSL 3.0 and TLS 1.0, 1.1 and 1.2 server and client support
-- Included crypto library - RSA, ECC, AES, 3DES, ARC4, SHA1, SHA256, MD5
+- Small total footprint with crypto provider
+- SSL 3.0 and TLS 1.0, 1.1, 1.2 and 1.3 server and client support
+- Included crypto library - RSA, ECC, AES, 3DES, ARC4, SHA1, SHA256, MD5, ChaCha20-Poly1305
- Assembly language optimizations for Intel, ARM and MIPS
- Session re-keying and cipher renegotiation
- Full support for session resumption/caching
diff --git a/README.md b/README.md
index 1b0478e..cf1aad0 100644
--- a/README.md
+++ b/README.md
@@ -13,16 +13,16 @@ Lightweight Embedded SSL/TLS Implementation
##Overview
MatrixSSL has been continuously maintained since 2002. It is the first open source small footprint SSL stack. Until recently, releases were tracked on http://freecode.com/projects/matrixssl
-MatrixSSL is an embedded SSL and TLS implementation designed for small footprint IoT devices requiring low overhead per connection. The library is less than 50Kb on disk with cipher suites. It includes client and server support through TLS 1.2, mutual authentication, session resumption, and implementations of RSA, ECC, AES, SHA1, SHA-256 and more. The source is well documented and contains portability layers for additional operating systems, cipher suites, and cryptography providers.
+MatrixSSL is an embedded SSL and TLS implementation designed for small footprint IoT devices requiring low overhead per connection. It includes client and server support through TLS 1.3, mutual authentication, session resumption, and implementations of RSA, ECC, AES, SHA1, SHA-256, ChaCha20-Poly1305 and more. The source is well documented and contains portability layers for additional operating systems, cipher suites, and cryptography providers.
##Reporting Issues
Please email support@matrixssl.org.
Sensitive emails can be encrypted using the public key in this directory [pgp.asc](https://raw.githubusercontent.com/matrixssl/matrixssl/master/pgp.asc), Key fingerprint = `D6AD F1C5 E34E 696B 0953 556C 8BB2 B39A 2795 C6B3`.
##Features
-+ < 50KB total footprint with crypto provider
-+ SSL 3.0 and TLS 1.0, 1.1 and 1.2 server and client support
-+ Included crypto library - RSA, ECC, AES, 3DES, ARC4, SHA1, SHA256, MD5
++ Small total footprint with crypto provider
++ SSL 3.0 and TLS 1.0, 1.1, 1.2 and 1.3 server and client support
++ Included crypto library - RSA, ECC, AES, 3DES, ARC4, SHA1, SHA256, MD5, ChaCha20-Poly1305
+ Assembly language optimizations for Intel, ARM and MIPS
+ Session re-keying and cipher renegotiation
+ Full support for session resumption/caching
diff --git a/apps/common/Makefile b/apps/common/Makefile
index 3e2d916..a5f4690 100644
--- a/apps/common/Makefile
+++ b/apps/common/Makefile
@@ -15,8 +15,10 @@ CLIENT_COMMON_STATIC:=client_common_s.a
STATIC:=$(CLIENT_COMMON_STATIC)
# Optional extensions to CFLAGS/LDFLAGS
-CFLAGS+=$(CFLAGS_INTERNAL) -Wextra -Wno-old-style-declaration
-LDFLAGS+=$(LDFLAGS_INTERNAL) -Wextra
+CFLAGS_WARNINGS_EXTRA=-Wextra
+CFLAGS_WARNINGS_NO_OLD_STYLE_DECLARATION=-Wno-old-style-declaration
+CFLAGS+=$(CFLAGS_INTERNAL) $(CFLAGS_WARNINGS_EXTRA) $(CFLAGS_WARNINGS_NO_OLD_STYLE_DECLARATION)
+LDFLAGS+=$(LDFLAGS_INTERNAL) $(CFLAGS_WARNINGS_EXTRA)
# Allow selecting the client auth identity (ID_RSA, ID_ECDH_ECDSA,
# etc.) via an environment variable.
diff --git a/apps/common/client_common.c b/apps/common/client_common.c
index 9491949..2ee5c32 100644
--- a/apps/common/client_common.c
+++ b/apps/common/client_common.c
@@ -50,7 +50,7 @@ int appendCACert(unsigned char *buf, const size_t bufsize, size_t *bufused,
return 0; /* Does not fit into the buffer */
}
- memcpy(buf + *bufused, data, datasize);
+ Memcpy(buf + *bufused, data, datasize);
*bufused += datasize;
return 1;
}
@@ -61,10 +61,10 @@ int appendCACert(unsigned char *buf, const size_t bufsize, size_t *bufused,
int appendCAFilename(char *strbuf, const size_t strbufsize, const char *str)
{
static const char *sep = ";";
- const size_t strbuflen = strlen(strbuf);
- const size_t strseplen = (strbuflen == 0 ? 0 : strlen(sep));
+ const size_t strbuflen = Strlen(strbuf);
+ const size_t strseplen = (strbuflen == 0 ? 0 : Strlen(sep));
const size_t bufUnused = strbufsize - strbuflen - 1;
- const size_t len = strlen(str);
+ const size_t len = Strlen(str);
if (len == 0) {
return 1;
diff --git a/apps/common/client_common.h b/apps/common/client_common.h
index 553f333..703991f 100644
--- a/apps/common/client_common.h
+++ b/apps/common/client_common.h
@@ -35,13 +35,17 @@
#ifndef _h_CLIENT_COMMON
#define _h_CLIENT_COMMON
-#include
-#include
+#include "osdep_string.h"
+#include "osdep_ctype.h"
#include "matrixssl/matrixsslApi.h"
#include "core/coreApi.h"
#include "core/psUtil.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/*
If supporting client authentication, pick ONE identity to auto select a
certificate and private key that support desired algorithms.
@@ -86,14 +90,17 @@ typedef struct {
/* Function for loading the client certificate key material, must be != NULL */
load_key_func load_key;
+
+ /* Defines whether pre-shared keys are automatically loaded */
+ int loadPreSharedKeys;
} clientconfig_t;
extern clientconfig_t g_clientconfig;
-void clientconfigInitialize();
-void clientconfigFree();
-void clientconfigUseFileKeys();
-const char *clientconfigGetTrustedCA();
+void clientconfigInitialize(void);
+void clientconfigFree(void);
+void clientconfigUseFileKeys(void);
+const char *clientconfigGetTrustedCA(void);
int32 clientconfigLoadKeys(sslKeys_t *keys);
/* load_keys.c
@@ -121,6 +128,10 @@ extern int g_key_len;
int appendCACert(unsigned char *buf, const size_t bufsize, size_t *bufused,
const unsigned char *data, const size_t datasize);
int appendCAFilename(char *strbuf, const size_t strbufsize, const char *str);
-void chdirToAppsSSL();
+void chdirToAppsSSL(void);
+
+#ifdef __cplusplus
+};
+#endif
#endif /* _h_CLIENT_COMMON */
diff --git a/apps/common/clientconfig.c b/apps/common/clientconfig.c
index b7b5681..975ee9f 100644
--- a/apps/common/clientconfig.c
+++ b/apps/common/clientconfig.c
@@ -65,7 +65,7 @@ static const char* example_file_path(const char* filepath)
{
const char* ret_filepath = filepath;
unsigned char *tmp_buf;
- int32 tmp_buf_len;
+ psSizeL_t tmp_buf_len;
int32 rc;
rc = psGetFileBuf(NULL, filepath, &tmp_buf, &tmp_buf_len);
@@ -93,7 +93,7 @@ static const char* example_file_path(const char* filepath)
}
#endif /* EXAMPLE_FILE_KEYS */
-void clientconfigInitialize()
+void clientconfigInitialize(void)
{
g_clientconfig.ca_file = NULL;
g_clientconfig.default_ca_file = NULL;
@@ -105,17 +105,23 @@ void clientconfigInitialize()
# ifdef EXAMPLE_RSA_KEYS
g_clientconfig.cert_file = example_file_path(rsaCertFile);
g_clientconfig.privkey_file = example_file_path(rsaPrivkeyFile);
+# if defined(USE_RSA) && defined(USE_IDENTITY_CERTIFICATES)
g_clientconfig.load_key = &loadRsaKeysFromFile;
+# endif
g_clientconfig.loadKeysFromMemory = 0;
# elif defined(EXAMPLE_EC_KEYS)
g_clientconfig.cert_file = example_file_path(ecCertFile);
g_clientconfig.privkey_file = example_file_path(ecPrivkeyFile);
+# if defined(USE_ECC) && defined(USE_IDENTITY_CERTIFICATES)
g_clientconfig.load_key = &loadECDH_ECDSAKeysFromFile;
+# endif
g_clientconfig.loadKeysFromMemory = 0;
# elif defined(EXAMPLE_ECDH_RSA_KEYS)
g_clientconfig.cert_file = example_file_path(ecdhRsaCertFile);
g_clientconfig.privkey_file = example_file_path(ecdhRsaPrivkeyFile);
+# if defined(USE_ECC) && defined(USE_IDENTITY_CERTIFICATES)
g_clientconfig.load_key = &loadECDHRsaKeysFromFile;
+# endif
g_clientconfig.loadKeysFromMemory = 0;
# elif defined(USE_PSK_CIPHER_SUITE)
g_clientconfig.load_key = &loadPreSharedKeys;
@@ -125,11 +131,11 @@ void clientconfigInitialize()
# ifdef USE_HEADER_KEYS
g_clientconfig.cert_file = NULL;
g_clientconfig.privkey_file = NULL;
-# if defined(ID_RSA)
+# if defined(ID_RSA) && defined(USE_RSA) && defined(USE_IDENTITY_CERTIFICATES)
g_clientconfig.load_key = &loadRsaExampleKeys;
-# elif defined(ID_ECDH_RSA)
+# elif defined(ID_ECDH_RSA) && defined(USE_ECC) && defined(USE_IDENTITY_CERTIFICATES)
g_clientconfig.load_key = &loadECDHRsaExampleKeys;
-# elif defined(ID_ECDH_ECDSA)
+# elif defined(ID_ECDH_ECDSA) && defined(USE_ECC) && defined(USE_IDENTITY_CERTIFICATES)
g_clientconfig.load_key = &loadECDH_ECDSAExampleKeys;
# elif defined(USE_PSK_CIPHER_SUITE)
g_clientconfig.load_key = &loadPreSharedKeys;
@@ -140,13 +146,13 @@ void clientconfigInitialize()
buildCAStringFromFiles(&g_clientconfig.default_ca_file);
}
-void clientconfigFree()
+void clientconfigFree(void)
{
psFree((char*)g_clientconfig.default_ca_file, NULL);
g_clientconfig.default_ca_file = NULL;
}
-void clientconfigUseFileKeys()
+void clientconfigUseFileKeys(void)
{
/* Do not overwrite load_key if not loaded from memory */
if (g_clientconfig.loadKeysFromMemory) {
@@ -155,7 +161,7 @@ void clientconfigUseFileKeys()
}
}
-const char *clientconfigGetTrustedCA()
+const char *clientconfigGetTrustedCA(void)
{
if (g_clientconfig.ca_file) {
return g_clientconfig.ca_file;
@@ -186,7 +192,8 @@ int32 clientconfigLoadKeys(sslKeys_t *keys)
/* Additionally always load PSK keys unless they are already loaded
*/
if (g_clientconfig.load_key != &loadPreSharedKeys &&
- g_clientconfig.load_key != &loadExamplePreSharedKeys)
+ g_clientconfig.load_key != &loadExamplePreSharedKeys &&
+ g_clientconfig.loadPreSharedKeys)
{
rc = loadPreSharedKeys(keys);
diff --git a/apps/common/load_keys.c b/apps/common/load_keys.c
index b765a9a..77d0e60 100644
--- a/apps/common/load_keys.c
+++ b/apps/common/load_keys.c
@@ -180,7 +180,7 @@ void buildTrustedCABuf(unsigned char **CAstreamOut, int32 *CAstreamLenOut)
if (CAstreamLen > 0)
{
- CAstream = psMalloc(NULL, CAstreamLen);
+ CAstream = (unsigned char *)psMalloc(NULL, CAstreamLen);
}
if (NULL == CAstream) {
@@ -189,7 +189,7 @@ void buildTrustedCABuf(unsigned char **CAstreamOut, int32 *CAstreamLenOut)
return;
}
- memset(CAstream, 0x0, CAstreamLen);
+ Memset(CAstream, 0x0, CAstreamLen);
#ifdef USE_RSA_CIPHER_SUITE
appendCACert(CAstream, CAstreamLen, &bufused, RSACAS, sizeof(RSACAS));
@@ -261,7 +261,7 @@ void buildCAStringFromFiles(const char **CAfileOut)
if (CAstreamLen > 0)
{
- CAstream = psMalloc(NULL, CAstreamLen);
+ CAstream = (char *)psMalloc(NULL, CAstreamLen);
}
if (NULL == CAstream) {
@@ -269,7 +269,7 @@ void buildCAStringFromFiles(const char **CAfileOut)
return;
}
- memset(CAstream, 0x0, CAstreamLen);
+ Memset(CAstream, 0x0, CAstreamLen);
#ifdef USE_RSA_CIPHER_SUITE
appendCAFilename(CAstream, CAstreamLen, rsaCAFile);
@@ -303,7 +303,7 @@ void buildCAStringFromFiles(const char **CAfileOut)
*CAfileOut = CAstream;
}
-#if defined(USE_HEADER_KEYS) && defined(ID_RSA)
+#if defined(USE_HEADER_KEYS) && defined(ID_RSA) && defined(USE_RSA) && defined(USE_IDENTITY_CERTIFICATES)
int32 loadRsaExampleKeys(sslKeys_t *keys)
{
int32 rc;
@@ -377,9 +377,9 @@ error:
psFree(trustedCABuf, NULL);
return rc;
}
-#endif /* USE_HEADER_KEYS && ID_RSA */
+#endif /* USE_HEADER_KEYS && && ID_RSA && USE_RSA && USE_IDENTITY_CERTIFICATES */
-#if defined(USE_HEADER_KEYS) && defined(ID_ECDH_RSA)
+#if defined(USE_HEADER_KEYS) && defined(ID_ECDH_RSA) && defined(USE_ECC) && defined(USE_IDENTITY_CERTIFICATES)
int32 loadECDHRsaExampleKeys(sslKeys_t *keys)
{
int32 rc;
@@ -413,9 +413,9 @@ int32 loadECDHRsaExampleKeys(sslKeys_t *keys)
psFree(trustedCABuf, NULL);
return rc;
}
-#endif /* USE_HEADER_KEYS && ID_ECDH_RSA */
+#endif /* USE_HEADER_KEYS && ID_ECDH_RSA && USE_ECC && USE_IDENTITY_CERTIFICATES */
-#if defined(USE_HEADER_KEYS) && defined(ID_ECDH_ECDSA)
+#if defined(USE_HEADER_KEYS) && defined(ID_ECDH_ECDSA) && defined(USE_ECC) && defined(USE_IDENTITY_CERTIFICATES)
int32 loadECDH_ECDSAExampleKeys(sslKeys_t *keys)
{
int32 rc;
@@ -451,7 +451,7 @@ int32 loadECDH_ECDSAExampleKeys(sslKeys_t *keys)
psFree(trustedCABuf, NULL);
return rc;
}
-#endif /* USE_HEADER_KEYS && ID_ECDH_ECDSA */
+#endif /* USE_HEADER_KEYS && ID_ECDH_ECDSA && USE_ECC && USE_IDENTITY_CERTIFICATES */
#ifdef USE_PSK_CIPHER_SUITE
int32 loadExamplePreSharedKeys(sslKeys_t *keys)
@@ -492,7 +492,7 @@ int32 loadKeysFromFile(sslKeys_t *keys)
privFile = NULL;
}
-# if defined(USE_RSA) || defined(USE_ECC)
+# if defined(MATRIX_USE_FILE_SYSTEM) && defined(USE_IDENTITY_CERTIFICATES) && (defined(USE_RSA) || defined(USE_ECC))
psTrace("loadKeysFromFile()\n");
psTraceStr("Using CA: %s\n", pCA);
psTraceStr("Using certificate: %s\n", certFile);
@@ -527,7 +527,7 @@ int32 loadRsaKeysFromFile(sslKeys_t *keys)
privFile = NULL;
}
-#ifdef USE_RSA
+#if defined(USE_RSA) && defined(USE_IDENTITY_CERTIFICATES) && defined(MATRIX_USE_FILE_SYSTEM)
psTrace("loadRsaKeysFromFile()\n");
psTraceStr("Using CA: %s\n", pCA);
psTraceStr("Using certificate: %s\n", certFile);
@@ -562,7 +562,7 @@ int32 loadECDHRsaKeysFromFile(sslKeys_t *keys)
privFile = NULL;
}
-#ifdef USE_ECC
+#if defined(USE_ECC) && defined(USE_IDENTITY_CERTIFICATES) && defined(MATRIX_USE_FILE_SYSTEM)
psTrace("loadECDHRsaKeysFromFile()\n");
psTraceStr("Using CA: %s\n", pCA);
psTraceStr("Using certificate: %s\n", certFile);
@@ -597,7 +597,7 @@ int32 loadECDH_ECDSAKeysFromFile(sslKeys_t *keys)
privFile = NULL;
}
-#ifdef USE_ECC
+#if defined USE_ECC && defined(USE_IDENTITY_CERTIFICATES) && defined(MATRIX_USE_FILE_SYSTEM)
psTrace("loadECDH_ECDSAKeysFromFile()\n");
psTraceStr("Using CA: %s\n", pCA);
psTraceStr("Using certificate: %s\n", certFile);
diff --git a/apps/dtls/dtlsClient.c b/apps/dtls/dtlsClient.c
index cf4f83f..ef12a69 100644
--- a/apps/dtls/dtlsClient.c
+++ b/apps/dtls/dtlsClient.c
@@ -36,6 +36,8 @@
/* Currently this example uses _psTrace for tracing, so osdep.h is needed: */
#include "core/osdep.h"
#include "core/psUtil.h"
+#include "osdep_sys_time.h"
+#include "osdep_stdio.h"
#include "../common/client_common.h"
#if defined(USE_DTLS) && defined(USE_CLIENT_SIDE_SSL)
@@ -57,11 +59,9 @@ typedef struct
} sslDtls_t;
# ifndef MATRIX_TESTING_ENVIRONMENT /* Omit the message when testing. */
-# ifdef WIN32
-# pragma message("DO NOT USE THESE DEFAULT KEYS IN PRODUCTION ENVIRONMENTS.")
-# else
-# warning "DO NOT USE THESE DEFAULT KEYS IN PRODUCTION ENVIRONMENTS."
-# endif
+# define WARNING_MESSAGE "DO NOT USE THESE DEFAULT KEYS IN PRODUCTION ENVIRONMENTS."
+# define WARNING_MESSAGE_DEFAULT_KEY
+# include "pscompilerwarning.h"
# endif
# define ALLOW_ANON_CONNECTIONS 1
@@ -111,14 +111,14 @@ static SOCKET dtlsInitClientSocket(sslDtls_t **newCtx, ssl_t *ssl)
}
dtls->ssl = ssl;
- if ((dtls->fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
+ if ((dtls->fd = Socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
{
_psTrace("Error creating INET UDP socket\n");
psFree(dtls, NULL);
return INVALID_SOCKET;
}
- memset(&dtls->addr, 0x0, sizeof(struct sockaddr_in));
+ Memset(&dtls->addr, 0x0, sizeof(struct sockaddr_in));
dtls->addr.sin_family = AF_INET;
dtls->addr.sin_port = htons((short) g_port);
dtls->addr.sin_addr.s_addr = inet_addr(g_ip);
@@ -156,7 +156,7 @@ static int32 dtlsClientConnection(sslKeys_t *keys, sslSessionId_t *sid)
int drop_next_cipherspec_packet = 0;
# endif /* DTLS_TEST_LOST_CIPHERSPEC_CHANGE_REHANDSHAKE */
- memset(&options, 0x0, sizeof(sslSessOpts_t));
+ Memset(&options, 0x0, sizeof(sslSessOpts_t));
options.versionFlag = SSL_FLAGS_DTLS;
options.trustedCAindication = 1;
@@ -194,7 +194,7 @@ static int32 dtlsClientConnection(sslKeys_t *keys, sslSessionId_t *sid)
rehandshakeTestDone = resumedRehandshakeTestDone = 0;
weAreDone = 0; /* resumed handshake exit hint mechanism */
addrlen = sizeof(dtlsCtx->addr);
- memset(&from, 0x0, sizeof(struct sockaddr_in));
+ Memset(&from, 0x0, sizeof(struct sockaddr_in));
/*
Timeout mechanism is implemented according to guidelines in spec
@@ -265,7 +265,7 @@ READ_MORE:
FD_SET(fd, &readfd);
timeout.tv_sec = tSec;
- if ((val = select(fd + 1, &readfd, NULL, NULL, &timeout)) < 0)
+ if ((val = Select(fd + 1, &readfd, NULL, NULL, &timeout)) < 0)
{
if (SOCKET_ERRNO != EINTR)
{
@@ -460,7 +460,7 @@ static int32 sendHelloWorld(sslDtls_t *dtlsCtx)
int32 avail, len, ret;
_psTrace("DTLS handshake complete. Sending sample application data\n");
- len = (int32) strlen((char *) helloWorld) + 1;
+ len = (int32) Strlen((char *) helloWorld) + 1;
/*
Get free buffer, copy in plaintext, and encode
*/
@@ -469,7 +469,7 @@ static int32 sendHelloWorld(sslDtls_t *dtlsCtx)
return PS_MEM_FAIL;
}
avail = min(avail, len);
- strncpy((char *) buf, (char *) helloWorld, avail);
+ Strncpy((char *) buf, (char *) helloWorld, avail);
if ((ret = matrixSslEncodeWritebuf(dtlsCtx->ssl, avail)) < 0)
{
@@ -494,7 +494,7 @@ static int32 sendHelloWorld(sslDtls_t *dtlsCtx)
static void usage(void)
{
- printf("\nusage: client { option }\n"
+ Printf("\nusage: client { option }\n"
"\n"
"where option can be one of the following:\n"
"\n"
@@ -549,7 +549,7 @@ static void usage(void)
"serverPortNum is usually 443 or 4433. The cipherList is a comma separated list\n"
"of cipher numbers to propose. It should NOT contain any spaces.\n\n");
- printf("Common ciphers and the cipher number to use in the cipherList:\n"
+ Printf("Common ciphers and the cipher number to use in the cipherList:\n"
" 53 TLS_RSA_WITH_AES_256_CBC_SHA\n"
" 47 TLS_RSA_WITH_AES_128_CBC_SHA\n"
" 10 SSL_RSA_WITH_3DES_EDE_CBC_SHA\n"
@@ -569,16 +569,16 @@ static int32 parse_cipher_list(char *cipherListString,
numCiphers = 0;
while (cipherListString != NULL)
{
- cipher = (int32) strtol(cipherListString, &endPtr, 10);
+ cipher = (int32) Strtol(cipherListString, &endPtr, 10);
if (endPtr == cipherListString)
{
- printf("The remaining cipherList has no cipher numbers - '%s'\n",
+ Printf("The remaining cipherList has no cipher numbers - '%s'\n",
cipherListString);
return -1;
}
else if (size_of_cipher_array <= numCiphers)
{
- printf("Too many cipher numbers supplied. limit is %d\n",
+ Printf("Too many cipher numbers supplied. limit is %d\n",
size_of_cipher_array);
return -1;
}
@@ -591,7 +591,7 @@ static int32 parse_cipher_list(char *cipherListString,
}
else if (*endPtr != ',')
{
- printf("\n");
+ Printf("\n");
return -1;
}
@@ -610,11 +610,11 @@ static int32 process_cmd_options(int32 argc, char **argv)
char *cipherListString;
/* Set some default options: */
- memset(g_cipher, 0, sizeof(g_cipher));
- memset(g_ip, 0, sizeof(g_ip));
- memset(g_path, 0, sizeof(g_path));
+ Memset(g_cipher, 0, sizeof(g_cipher));
+ Memset(g_ip, 0, sizeof(g_ip));
+ Memset(g_path, 0, sizeof(g_path));
- strcpy(g_ip, "127.0.0.1");
+ Strcpy(g_ip, "127.0.0.1");
g_ciphers = 1;
g_cipher[0] = 47;
g_disableCertNameChk = 0;
@@ -635,6 +635,7 @@ static int32 process_cmd_options(int32 argc, char **argv)
#define ARG_CERT 2
#define ARG_KEY 3
#define ARG_KEYTYPE 4
+#define ARG_PSK 5
static struct option long_options[] =
{
@@ -653,6 +654,7 @@ static int32 process_cmd_options(int32 argc, char **argv)
{"cert", required_argument, NULL, ARG_CERT},
{"key", required_argument, NULL, ARG_KEY},
{"keytype", required_argument, NULL, ARG_KEYTYPE},
+ {"psk", no_argument, NULL, ARG_PSK},
{0, 0, 0, 0}
};
@@ -697,7 +699,7 @@ static int32 process_cmd_options(int32 argc, char **argv)
if ((key_len != 1024) && (key_len != 2048) && (key_len != 3072)
&& (key_len != 4096))
{
- printf("-k option must be followed by a key_len whose value "
+ Printf("-k option must be followed by a key_len whose value "
" must be 1024, 2048, 3072 or 4096\n");
return -1;
}
@@ -718,7 +720,7 @@ static int32 process_cmd_options(int32 argc, char **argv)
break;
case 's':
- strncpy(g_ip, optarg, 15);
+ Strncpy(g_ip, optarg, 15);
break;
# ifdef DTLS_PACKET_LOSS_TEST
@@ -726,12 +728,12 @@ static int32 process_cmd_options(int32 argc, char **argv)
packet_loss_prob = atoi(optarg);
if (packet_loss_prob < 0)
{
- printf("invalid -l option\n");
+ Printf("invalid -l option\n");
return -1;
}
if (packet_loss_prob > 0)
{
- printf("Client simulating packet loss with probability 1/%d\n",
+ Printf("Client simulating packet loss with probability 1/%d\n",
packet_loss_prob);
}
break;
@@ -763,21 +765,25 @@ static int32 process_cmd_options(int32 argc, char **argv)
break;
case ARG_KEYTYPE:
- if (strcmp("any", optarg) == 0) {
+ if (Strcmp("any", optarg) == 0) {
g_clientconfig.load_key = &loadKeysFromFile;
- } else if (strcmp("rsa", optarg) == 0) {
+ } else if (Strcmp("rsa", optarg) == 0) {
g_clientconfig.load_key = &loadRsaKeysFromFile;
- } else if (strcmp("ec", optarg) == 0) {
+ } else if (Strcmp("ec", optarg) == 0) {
g_clientconfig.load_key = &loadECDH_ECDSAKeysFromFile;
- } else if (strcmp("ecrsa", optarg) == 0) {
+ } else if (Strcmp("ecrsa", optarg) == 0) {
g_clientconfig.load_key = &loadECDHRsaKeysFromFile;
} else {
- printf("Invalid option: %s\n", optarg);
+ Printf("Invalid option: %s\n", optarg);
return -1;
}
g_clientconfig.loadKeysFromMemory = 0;
break;
+
+ case ARG_PSK:
+ g_clientconfig.loadPreSharedKeys = 1;
+ break;
#endif /* USE_GETOPT_LONG */
}
}
@@ -825,7 +831,7 @@ int32 main(int32 argc, char **argv)
clientconfigFree();
return 0;
}
- printf("client https://%s:%d%s "
+ Printf("client https://%s:%d%s "
"new:%d resumed:%d keylen:%d nciphers:%d\n",
g_ip, g_port, g_path, g_new, g_resumed, g_key_len,
g_ciphers);
@@ -838,7 +844,7 @@ int32 main(int32 argc, char **argv)
rv = MATRIXSSL_ERROR;
matrixSslNewSessionId(&sid, NULL);
- printf("=== %d new connections ===\n", g_new);
+ Printf("=== %d new connections ===\n", g_new);
for (rc = 0; rc < g_new; rc++)
{
matrixSslNewSessionId(&sid, NULL);
@@ -855,12 +861,12 @@ int32 main(int32 argc, char **argv)
}
if (g_new)
{
- printf("\n");
+ Printf("\n");
}
- printf("=== %d resumed connections ===\n", g_resumed);
+ Printf("=== %d resumed connections ===\n", g_resumed);
for (rc = 0; rc < g_resumed; rc++)
{
rv = dtlsClientConnection(keys, sid);
@@ -945,8 +951,11 @@ static int32 certCb(ssl_t *ssl, psX509Cert_t *cert, int32 alert)
cert->subject.commonName);
return SSL_ALLOW_ANON_CONNECTION;
}
- _psTrace("Certificate callback returning fatal alert\n");
- return alert;
+ else
+ {
+ _psTrace("Certificate callback returning fatal alert\n");
+ return alert;
+ }
}
psTraceStrDtls("Validated cert for: %s.\n", cert->subject.commonName);
@@ -962,7 +971,7 @@ static int32 certCb(ssl_t *ssl, psX509Cert_t *cert, int32 alert)
*/
int32 main(int32 argc, char **argv)
{
- printf("USE_DTLS and USE_CLIENT_SIDE_SSL must be enabled in " \
+ Printf("USE_DTLS and USE_CLIENT_SIDE_SSL must be enabled in " \
"matrixsslConfig.h at build time to run this application\n");
return -1;
}
diff --git a/apps/dtls/dtlsCommon.h b/apps/dtls/dtlsCommon.h
index d657694..bd97152 100644
--- a/apps/dtls/dtlsCommon.h
+++ b/apps/dtls/dtlsCommon.h
@@ -36,20 +36,20 @@
# ifdef USE_DTLS
-# include
-# include
-# include
-# include /* Defines FD_CLOEXEC, etc. */
-# include /* Defines EWOULDBLOCK, etc. */
+# include "osdep_stdlib.h"
+# include "osdep_string.h"
+# include "osdep_stdio.h"
+# include "osdep_fcntl.h" /* Defines FD_CLOEXEC, etc. */
+# include "osdep_errno.h" /* Defines EWOULDBLOCK, etc. */
# ifdef POSIX
# define USE_GETOPT_LONG
# ifdef USE_GETOPT_LONG
# include
# endif
-# include
-# include /* Defines AF_INET, etc. */
-# include /* sockaddr */
+# include "osdep_unistd.h"
+# include "osdep_netdb.h" /* Defines AF_INET, etc. */
+# include "osdep_sys_socket.h" /* sockaddr */
# include /* inet_addr */
# endif /* POSIX */
diff --git a/apps/dtls/dtlsServer.c b/apps/dtls/dtlsServer.c
index 533436f..a7d3085 100644
--- a/apps/dtls/dtlsServer.c
+++ b/apps/dtls/dtlsServer.c
@@ -31,8 +31,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* http://www.gnu.org/copyleft/gpl.html
*/
+#ifndef _POSIX_C_SOURCE
+# define _POSIX_C_SOURCE 200112L
+#endif
-#include /* Defines SIGTERM, etc. */
+#include "osdep_signal.h" /* Defines SIGTERM, etc. */
#ifdef OSX
# include /* Defines fd_set, etc. */
# define MSG_NOSIGNAL 0
@@ -42,6 +45,8 @@
/* Currently this example uses _psTrace for tracing, so osdep.h is needed: */
#include "core/osdep.h"
#include "core/psUtil.h"
+#include "osdep_sys_time.h"
+#include "osdep_stdio.h"
#ifdef USE_DTLS
@@ -79,7 +84,7 @@ static serverDtls_t *findClient(struct sockaddr_in addr);
static serverDtls_t *registerClient(struct sockaddr_in addr, SOCKET sock,
ssl_t *ssl);
static void clearClient(serverDtls_t *dtls);
-static void closeClientList();
+static void closeClientList(void);
static SOCKET newUdpSocket(char *ip, short port, int *err);
static int sigsetup(void);
static void sigsegv_handler(int);
@@ -92,11 +97,9 @@ static unsigned char *getaddrstring(struct sockaddr *addr, int withport);
# endif
# ifndef MATRIX_TESTING_ENVIRONMENT /* Omit the message when testing. */
-# ifdef WIN32
-# pragma message("DO NOT USE THESE DEFAULT KEYS IN PRODUCTION ENVIRONMENTS.")
-# else
-# warning "DO NOT USE THESE DEFAULT KEYS IN PRODUCTION ENVIRONMENTS."
-# endif
+# define WARNING_MESSAGE "DO NOT USE THESE DEFAULT KEYS IN PRODUCTION ENVIRONMENTS."
+# define WARNING_MESSAGE_DEFAULT_KEY
+# include "pscompilerwarning.h"
# endif
/* Pick ONE cipher suite type you want to use to auto select a certificate
@@ -369,7 +372,7 @@ static int32 certValidator(ssl_t *ssl, psX509Cert_t *cert, int32 alert)
static void usage(void)
{
- printf("\nusage: dltsServer { option }\n"
+ Printf("\nusage: dltsServer { option }\n"
"\n"
"where option can be one of the following:\n"
"\n"
@@ -411,7 +414,7 @@ static int32 process_cmd_options(int32 argc, char **argv)
if ((g_rsaKeySize != 1024) && (g_rsaKeySize != 2048)
&& (g_rsaKeySize != 3072) && (g_rsaKeySize != 4096))
{
- printf("invalid -r option\n");
+ Printf("invalid -r option\n");
return -1;
}
break;
@@ -422,7 +425,7 @@ static int32 process_cmd_options(int32 argc, char **argv)
&& (g_eccKeySize != 256) && (g_eccKeySize != 384)
&& (g_eccKeySize != 521))
{
- printf("invalid -e option\n");
+ Printf("invalid -e option\n");
return -1;
}
break;
@@ -431,7 +434,7 @@ static int32 process_cmd_options(int32 argc, char **argv)
g_ecdhKeySize = atoi(optarg);
if ((g_ecdhKeySize != 256) && (g_ecdhKeySize != 521))
{
- printf("invalid -d option\n");
+ Printf("invalid -d option\n");
return -1;
}
break;
@@ -441,12 +444,12 @@ static int32 process_cmd_options(int32 argc, char **argv)
packet_loss_prob = atoi(optarg);
if (packet_loss_prob < 0)
{
- printf("invalid -l option\n");
+ Printf("invalid -l option\n");
return -1;
}
if (packet_loss_prob > 0)
{
- printf("Server simulating packet loss with probability 1/%d\n",
+ Printf("Server simulating packet loss with probability 1/%d\n",
packet_loss_prob);
}
break;
@@ -455,7 +458,7 @@ static int32 process_cmd_options(int32 argc, char **argv)
g_port = atoi(optarg);
if (g_port < 0)
{
- printf("invalid -p option\n");
+ Printf("invalid -p option\n");
return -1;
}
}
@@ -488,7 +491,7 @@ int main(int argc, char **argv)
# endif
sslKeys_t *keys;
int32 freeBufLen, rc, val, recvLen, err, CAstreamLen;
- int32 sslBufLen, rcr, rcs, sendLen, recvfromBufLen;
+ int32 sslBufLen, rcr, rcs, recvfromBufLen;
sslSessOpts_t options;
# ifdef WIN32
@@ -548,15 +551,15 @@ int main(int argc, char **argv)
CAstreamLen = 0;
# ifdef USE_RSA
- memcpy(CAstream, RSACAS, sizeof(RSACAS));
+ Memcpy(CAstream, RSACAS, sizeof(RSACAS));
CAstreamLen += sizeof(RSACAS);
# ifdef USE_ECC
- memcpy(CAstream + CAstreamLen, ECDHRSACAS, sizeof(ECDHRSACAS));
+ Memcpy(CAstream + CAstreamLen, ECDHRSACAS, sizeof(ECDHRSACAS));
CAstreamLen += sizeof(ECDHRSACAS);
# endif
# endif
# ifdef USE_ECC
- memcpy(CAstream + CAstreamLen, ECCAS, sizeof(ECCAS));
+ Memcpy(CAstream + CAstreamLen, ECCAS, sizeof(ECCAS));
CAstreamLen += sizeof(ECCAS);
# endif
@@ -693,46 +696,46 @@ int main(int argc, char **argv)
# ifdef USE_RSA
if (g_rsaKeySize == 3072)
{
- CAstreamLen += (int32) strlen(rsaCA3072File) + 1;
+ CAstreamLen += (int32) Strlen(rsaCA3072File) + 1;
}
else
{
- CAstreamLen += (int32) strlen(rsaCAFile) + 1;
+ CAstreamLen += (int32) Strlen(rsaCAFile) + 1;
}
# ifdef USE_ECC
- CAstreamLen += (int32) strlen(ecdhRsaCAFile) + 1;
+ CAstreamLen += (int32) Strlen(ecdhRsaCAFile) + 1;
# endif
# endif
# ifdef USE_ECC
- CAstreamLen += (int32) strlen(ecCAFile) + 1;
+ CAstreamLen += (int32) Strlen(ecCAFile) + 1;
# endif
CAstream = psMalloc(NULL, CAstreamLen);
- memset(CAstream, 0x0, CAstreamLen);
+ Memset(CAstream, 0x0, CAstreamLen);
CAstreamLen = 0;
# ifdef USE_RSA
if (g_rsaKeySize == 3072)
{
- memcpy(CAstream, rsaCA3072File, strlen(rsaCA3072File));
- CAstreamLen += strlen(rsaCA3072File);
+ Memcpy(CAstream, rsaCA3072File, Strlen(rsaCA3072File));
+ CAstreamLen += Strlen(rsaCA3072File);
}
else
{
- memcpy(CAstream, rsaCAFile, strlen(rsaCAFile));
- CAstreamLen += strlen(rsaCAFile);
+ Memcpy(CAstream, rsaCAFile, Strlen(rsaCAFile));
+ CAstreamLen += Strlen(rsaCAFile);
}
# ifdef USE_ECC
- memcpy(CAstream + CAstreamLen, ";", 1); CAstreamLen++;
- memcpy(CAstream + CAstreamLen, ecdhRsaCAFile, strlen(ecdhRsaCAFile));
- CAstreamLen += strlen(ecdhRsaCAFile);
+ Memcpy(CAstream + CAstreamLen, ";", 1); CAstreamLen++;
+ Memcpy(CAstream + CAstreamLen, ecdhRsaCAFile, Strlen(ecdhRsaCAFile));
+ CAstreamLen += Strlen(ecdhRsaCAFile);
# endif
# endif
# ifdef USE_ECC
if (CAstreamLen > 0)
{
- memcpy(CAstream + CAstreamLen, ";", 1); CAstreamLen++;
+ Memcpy(CAstream + CAstreamLen, ";", 1); CAstreamLen++;
}
- memcpy(CAstream + CAstreamLen, ecCAFile, strlen(ecCAFile));
+ Memcpy(CAstream + CAstreamLen, ecCAFile, Strlen(ecCAFile));
# endif
/* Load Identiy */
@@ -784,7 +787,7 @@ int main(int argc, char **argv)
PSK_HEADER_TABLE[0].key,
sizeof(PSK_HEADER_TABLE[0].key),
PSK_HEADER_TABLE[0].id,
- strlen((const char *) PSK_HEADER_TABLE[0].id));
+ Strlen((const char *) PSK_HEADER_TABLE[0].id));
for (rc = 1; rc < PSK_HEADER_TABLE_COUNT; rc++)
{
@@ -824,7 +827,7 @@ int main(int argc, char **argv)
if needed (that reply may be a resend if reading a repeat message).
Individual client timeouts are then handled
*/
- val = select(sock + 1, &readfd, NULL, NULL, &timeout);
+ val = Select(sock + 1, &readfd, NULL, NULL, &timeout);
if (val > 0 && FD_ISSET(sock, &readfd))
{
@@ -863,7 +866,7 @@ int main(int argc, char **argv)
if not found */
if ((dtlsCtx = findClient(inaddr)) == NULL)
{
- memset(&options, 0x0, sizeof(sslSessOpts_t));
+ Memset(&options, 0x0, sizeof(sslSessOpts_t));
options.versionFlag = SSL_FLAGS_DTLS;
options.truncHmac = -1;
@@ -885,7 +888,7 @@ int main(int argc, char **argv)
freeBufLen = matrixSslGetReadbuf(ssl, &sslBuf);
psAssert(freeBufLen >= recvLen);
psAssert(freeBufLen == matrixDtlsGetPmtu());
- memcpy(sslBuf, recvfromBuf, recvLen);
+ Memcpy(sslBuf, recvfromBuf, recvLen);
/* Notify SSL state machine that we've received more data into the
ssl buffer retreived with matrixSslGetReadbuf. */
@@ -929,7 +932,7 @@ PROCESS_MORE_FROM_BUFFER:
while ((sslBufLen = matrixDtlsGetOutdata(ssl,
&sslBuf)) > 0)
{
- if ((sendLen = udpSend(dtlsCtx->fd, sslBuf, sslBufLen,
+ if ((udpSend(dtlsCtx->fd, sslBuf, sslBufLen,
(struct sockaddr *) &inaddr,
sizeof(struct sockaddr_in),
dtlsCtx->timeout,
@@ -1034,7 +1037,7 @@ static int32 handleResends(SOCKET sock)
psTime_t now;
unsigned char *sslBuf;
int16_t i;
- int32_t sendLen, sslBufLen, rc;
+ int32_t sslBufLen, rc;
uint32_t timeout, clientCount;
clientCount = 0; /* return code is number of active clients or < 0 on error */
@@ -1073,7 +1076,7 @@ static int32 handleResends(SOCKET sock)
while ((sslBufLen = matrixDtlsGetOutdata(ssl,
&sslBuf)) > 0)
{
- if ((sendLen = udpSend(dtlsCtx->fd, sslBuf, sslBufLen,
+ if ((udpSend(dtlsCtx->fd, sslBuf, sslBufLen,
(struct sockaddr *) &dtlsCtx->addr,
sizeof(struct sockaddr_in),
dtlsCtx->timeout / 2,
@@ -1144,7 +1147,7 @@ static SOCKET newUdpSocket(char *ip, short port, int *err)
struct sockaddr_in addr = { 0 };
SOCKET fd;
- if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
+ if ((fd = Socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
{
_psTraceInt("Error creating socket %d\n", SOCKET_ERRNO);
*err = SOCKET_ERRNO;
@@ -1191,15 +1194,15 @@ static void sigintterm_handler(int arg)
static int sigsetup(void)
{
/* set up cleanup handler */
- if (signal(SIGINT, sigintterm_handler) == SIG_ERR ||
+ if (Signal(SIGINT, sigintterm_handler) == SIG_ERR ||
# ifndef DEBUG_VALGRIND
- signal(SIGTERM, sigintterm_handler) == SIG_ERR ||
+ Signal(SIGTERM, sigintterm_handler) == SIG_ERR ||
# endif
- signal(SIGPIPE, SIG_IGN) == SIG_ERR)
+ Signal(SIGPIPE, SIG_IGN) == SIG_ERR)
{
return -1;
}
- if (signal(SIGSEGV, sigsegv_handler) == SIG_ERR)
+ if (Signal(SIGSEGV, sigsegv_handler) == SIG_ERR)
{
return -1;
}
@@ -1208,9 +1211,11 @@ static int sigsetup(void)
}
# ifdef USE_DTLS_DEBUG_TRACE
+#define NI_MAXHOST 1025
+#define NI_MAXSERV 32
/******************************************************************************/
/* Return a string representation of the socket address passed. The return
- * value is allocated with malloc() */
+ * value is allocated with Malloc() */
static unsigned char *getaddrstring(struct sockaddr *addr,
int withport)
{
@@ -1246,15 +1251,15 @@ static unsigned char *getaddrstring(struct sockaddr *addr,
/* This is a fairly bad failure - it'll fallback to IP if it
* just can't resolve */
_psTrace("failed lookup for getaddrstring");
- strcpy(hbuf, "UNKNOWN");
- strcpy(sbuf, "?");
+ Strcpy(hbuf, "UNKNOWN");
+ Strcpy(sbuf, "?");
}
if (withport)
{
- len = strlen(hbuf) + 2 + strlen(sbuf);
+ len = Strlen(hbuf) + 2 + Strlen(sbuf);
retstring = (char *) psMalloc(MATRIX_NO_POOL, len);
- snprintf(retstring, len, "%s:%s", hbuf, sbuf);
+ Snprintf(retstring, len, "%s:%s", hbuf, sbuf);
}
else
{
@@ -1344,7 +1349,7 @@ static void clearClient(serverDtls_t *dtls)
dtls->ssl = NULL;
dtls->connStatus = 0;
dtls->fd = 0;
- memset(&dtls->addr, 0x0, sizeof(struct sockaddr_in));
+ Memset(&dtls->addr, 0x0, sizeof(struct sockaddr_in));
return;
}
@@ -1391,7 +1396,7 @@ static void closeClientList()
*/
int32 main(int32 argc, char **argv)
{
- printf("USE_DTLS must be enabled in " \
+ Printf("USE_DTLS must be enabled in " \
"matrixsslConfig.h at build time to run this application\n");
return -1;
}
diff --git a/apps/ssl/XGetopt.c b/apps/ssl/XGetopt.c
index 795469c..7771205 100644
--- a/apps/ssl/XGetopt.c
+++ b/apps/ssl/XGetopt.c
@@ -172,7 +172,7 @@ int getopt(int argc, char *argv[], char *optstring)
return EOF;
}
- if (strcmp(argv[optind], "--") == 0)
+ if (Strcmp(argv[optind], "--") == 0)
{
optind++;
optarg = NULL;
@@ -189,7 +189,7 @@ int getopt(int argc, char *argv[], char *optstring)
}
c = *next++;
- cp = strchr(optstring, c);
+ cp = Strchr(optstring, c);
if (cp == NULL || c == ':')
{
diff --git a/apps/ssl/XGetopt.h b/apps/ssl/XGetopt.h
index 44b2313..75673c4 100644
--- a/apps/ssl/XGetopt.h
+++ b/apps/ssl/XGetopt.h
@@ -15,8 +15,8 @@
#ifndef XGETOPT_H
#define XGETOPT_H
-#include
-#include
+#include "osdep_stdio.h"
+#include "osdep_string.h"
extern int optind, opterr;
extern char *optarg;
diff --git a/apps/ssl/app.h b/apps/ssl/app.h
index b06ce8b..b8d0e53 100644
--- a/apps/ssl/app.h
+++ b/apps/ssl/app.h
@@ -43,14 +43,14 @@ extern "C" {
# include "core/coreApi.h"
# include "matrixssl/matrixsslApi.h"
-# include /* Defines EWOULDBLOCK, etc. */
-# include /* Defines FD_CLOEXEC, etc. */
-# include /* Defines malloc, exit, etc. */
+# include "osdep_errno.h" /* Defines EWOULDBLOCK, etc. */
+# include "osdep_fcntl.h" /* Defines FD_CLOEXEC, etc. */
+# include "osdep_stdlib.h" /* Defines malloc, exit, etc. */
# ifdef POSIX
-# include /* Defines AF_INET, etc. */
-# include /* Defines close() */
-# include /* Defines TCP_NODELAY, etc. */
+# include "osdep_netdb.h" /* Defines AF_INET, etc. */
+# include "osdep_unistd.h" /* Defines close() */
+# include "osdep_netinet_tcp.h" /* Defines TCP_NODELAY, etc. */
# include /* inet_addr */
# endif
@@ -108,6 +108,7 @@ typedef struct
psTime_t time; /* Last time there was activity */
uint32 timeout; /* in milliseconds*/
uint32 flags;
+ uint32 handshakeComplete;
unsigned char *parsebuf; /* Partial data */
uint32 parsebuflen;
uint32 bytes_received;
diff --git a/apps/ssl/client.c b/apps/ssl/client.c
index bc4d68d..3122a09 100644
--- a/apps/ssl/client.c
+++ b/apps/ssl/client.c
@@ -31,37 +31,60 @@
* http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
+#ifndef _POSIX_C_SOURCE
+# define _POSIX_C_SOURCE 200112L
+#endif
+
+#ifndef NEED_PS_TIME_CONCRETE
+# define NEED_PS_TIME_CONCRETE
+#endif
+
+#ifndef USE_MULTITHREADING
+# define USE_MULTITHREADING
+#endif
+
+/* This example uses osdep*.h to allow porting similar to MatrixSSL's libs. */
+#include "osdep_stddef.h"
+#include "osdep_time.h"
+#include "osdep_string.h"
+#include "osdep_stdio.h"
+#include "osdep_ctype.h"
+#include "osdep_sys_socket.h"
+#include "osdep-types.h"
-#include
-#include
-#include
-#include
-#include
#include "app.h"
+
+/* Command line arguments parsing: */
#ifndef WIN32
# define USE_GETOPT_LONG
# ifdef USE_GETOPT_LONG
# include
# else
-# include
+# include "osdep_unistd.h"
# endif
#else
# include "XGetopt.h"
#endif
+
+/* The MatrixSSL's API. */
#include "matrixssl/matrixsslApi.h"
-/* Currently this example uses _psTrace for tracing, so osdep.h is needed: */
-#include "core/osdep.h"
+#include "core/coreApi.h"
#include "core/psUtil.h"
+
# include "../common/client_common.h"
+# ifdef USE_TLS_1_3
+# include "testkeys/PSK/tls13_psk.h"
+# endif /* USE_TLS_1_3 */
+
#ifdef USE_CLIENT_SIDE_SSL
+static int g_use_psk;
+
# ifndef MATRIX_TESTING_ENVIRONMENT /* Omit the message when testing. */
-# ifdef WIN32
-# pragma message("DO NOT USE THESE DEFAULT KEYS IN PRODUCTION ENVIRONMENTS.")
-# else
-# warning "DO NOT USE THESE DEFAULT KEYS IN PRODUCTION ENVIRONMENTS."
-# endif
+# define WARNING_MESSAGE "DO NOT USE THESE DEFAULT KEYS IN PRODUCTION ENVIRONMENTS."
+# define WARNING_MESSAGE_DEFAULT_KEY
+# include "pscompilerwarning.h"
# endif
# define ALLOW_ANON_CONNECTIONS 0
@@ -81,12 +104,21 @@ static unsigned char g_httpRequestHdr[] = "GET %s HTTP/1.0\r\n"
"\r\n";
static const char g_strver[][8] =
-{ "SSL 3.0", "TLS 1.0", "TLS 1.1", "TLS 1.2" };
+{ "SSL 3.0", "TLS 1.0", "TLS 1.1", "TLS 1.2", "TLS 1.3" };
+static psList_t *g_groupList;
+static psSize_t g_num_key_shares;
+static psList_t *g_sigAlgsList;
+static psList_t *g_sigAlgsCertList;
+static psList_t *g_supportedVersionsList;
+static char g_early_data_file[256];
+static long int g_tls13_block_size;
+static long int g_min_dh_p_size;
static unsigned char g_matrixShutdownServer[] = "MATRIX_SHUTDOWN";
extern int opterr;
static char g_ip[16];
+static char g_server_name[256];
static char g_path[256];
static int g_port, g_new, g_resumed, g_ciphers, g_version, g_closeServer;
static int g_min_version, g_max_version, g_version_range_set;
@@ -95,6 +127,8 @@ static int g_max_verify_depth;
static uint16_t g_cipher[16];
static int g_trace;
static int g_keepalive;
+static int g_req_ocsp_stapling;
+static int g_disable_peer_authentication;
static uint32_t g_bytes_requested;
static uint8_t g_send_closure_alert;
@@ -122,6 +156,9 @@ static SOCKET lsocketConnect(char *ip, int32 port, int32 *err);
static void closeConn(ssl_t *ssl, SOCKET fd);
static int32_t extensionCb(ssl_t *ssl,
uint16_t extType, uint8_t extLen, void *e);
+# ifdef USE_TLS_1_3
+static int32_t sendEarlyData(ssl_t *ssl);
+# endif
# ifdef USE_CRL
static int32 fetchCRL(psPool_t *pool, char *url, uint32_t urlLen,
@@ -133,7 +170,7 @@ static int32_t fetchParseAndAuthCRLfromCert(psPool_t *pool, psX509Cert_t *cert,
example will show how to halt the handshake to go out and fetch and retry
the connection (command line option -n must be specified for multiple
connection attempts) */
-/* #define MIDHANDSHAKE_CRL_FETCH */
+#define MIDHANDSHAKE_CRL_FETCH
# ifndef MIDHANDSHAKE_CRL_FETCH
/* In the example where we stop the handhsake to go fetch the CRL files, we
@@ -169,20 +206,29 @@ static int32 httpsClientConnection(sslKeys_t *keys, sslSessionId_t *sid,
struct g_sslstats *stats)
{
tlsExtension_t *extension;
- int32 rc, transferred, len, sessionFlag, extLen;
- ssl_t *ssl;
+ int32 rc, transferred, len, extLen;
+ ssl_t *ssl = NULL;
unsigned char *buf, *ext;
httpConn_t cp;
SOCKET fd;
psTime_t t1, t2;
sslSessOpts_t options;
+ psList_t *sigAlg;
+ psList_t *supportedVersion;
+# ifdef USE_TLS_1_3
+ psList_t *group;
+ uint16_t groups[TLS_1_3_MAX_GROUPS] = {0};
+# endif
+ uint16_t sigAlgs[TLS_MAX_SIGNATURE_ALGORITHMS] = {0};
+ int32_t supportedVersions[TLS_MAX_SUPPORTED_VERSIONS] = {0};
+ psSize_t i;
# ifdef USE_ALPN
unsigned char *alpn[MAX_PROTO_EXT];
int32 alpnLen[MAX_PROTO_EXT];
# endif
- memset(&cp, 0x0, sizeof(httpConn_t));
+ Memset(&cp, 0x0, sizeof(httpConn_t));
if (g_alreadyopen == 0)
{
fd = lsocketConnect(g_ip, g_port, &rc);
@@ -201,45 +247,126 @@ static int32 httpsClientConnection(sslKeys_t *keys, sslSessionId_t *sid,
return PS_PLATFORM_FAIL;
}
- memset(&options, 0x0, sizeof(sslSessOpts_t));
+ Memset(&options, 0x0, sizeof(sslSessOpts_t));
- if (g_version_range_set)
+# ifdef USE_OCSP_RESPONSE
+ if (g_req_ocsp_stapling)
+ {
+ options.OCSPstapling = 1;
+ }
+# endif
+
+# ifdef USE_DH
+ rc = matrixSslSessOptsSetMinDhBits(&options, g_min_dh_p_size);
+ if (rc != PS_SUCCESS)
+ {
+ return rc;
+ }
+# endif
+
+# ifdef USE_TLS_1_3
+
+ /* Determine which groups to use. */
+ if (g_groupList != 0)
+ {
+ group = g_groupList;
+ i = 0;
+ while (group)
+ {
+ groups[i] = psGetNamedGroupId((const char*)group->item);
+ group = group->next;
+ i++;
+ }
+ rc = matrixSslSessOptsSetKeyExGroups(&options,
+ groups,
+ i,
+ g_num_key_shares);
+ if (rc < 0)
+ {
+ Printf("matrixSslSessOptsSetKeyExGroups failed\n");
+ goto L_CLOSE_ERR;
+ }
+ }
+ if (g_sigAlgsCertList != 0)
+ {
+ sigAlg = g_sigAlgsCertList;
+ i = 0;
+ while (sigAlg)
+ {
+ sigAlgs[i] = psGetNamedSigAlgId((const char*)sigAlg->item);
+ sigAlg = sigAlg->next;
+ i++;
+ }
+ rc = matrixSslSessOptsSetSigAlgsCert(&options,
+ sigAlgs,
+ i);
+ if (rc < 0)
+ {
+ Printf("matrixSslSessOptsSetSigAlgsCert failed\n");
+ goto L_CLOSE_ERR;
+ }
+ }
+
+# endif /* USE_TLS_1_3 */
+ if (g_sigAlgsList != 0)
+ {
+ sigAlg = g_sigAlgsList;
+ i = 0;
+ while (sigAlg)
+ {
+ sigAlgs[i] = psGetNamedSigAlgId((const char*)sigAlg->item);
+ sigAlg = sigAlg->next;
+ i++;
+ }
+ rc = matrixSslSessOptsSetSigAlgs(&options,
+ sigAlgs,
+ i);
+ if (rc < 0)
+ {
+ Printf("matrixSslSessOptsSetSigAlgs failed\n");
+ goto L_CLOSE_ERR;
+ }
+ }
+
+ /*
+ Get version information from (in order of priority):
+ - supported versions list (e.g. --tls-supported-versions 26,3)
+ - version range option (e.g. --tls-version-range 3,4)
+ - single version option (e.g. -V26)
+ */
+ if (g_supportedVersionsList)
+ {
+ supportedVersion = g_supportedVersionsList;
+ i = 0;
+ while (supportedVersion)
+ {
+ supportedVersions[i] = atoi((char* )supportedVersion->item);
+ supportedVersion = supportedVersion->next;
+ i++;
+ }
+ rc = matrixSslSessOptsSetClientTlsVersions(&options,
+ supportedVersions,
+ i);
+ if (rc < 0)
+ {
+ Printf("matrixSslSessOptsSetClientTlsVersions failed\n");
+ goto L_CLOSE_ERR;
+ }
+
+ }
+ else if (g_version_range_set)
{
rc = matrixSslSessOptsSetClientTlsVersionRange(&options,
g_min_version,
g_max_version);
if (rc < 0)
{
- return rc;
+ goto L_CLOSE_ERR;
}
}
- else
+ else if (g_version != 0)
{
-# ifdef SSL_FLAGS_SSLV3
- /* Corresponds to version 3.g_version */
- switch (g_version)
- {
- case 0:
- sessionFlag = SSL_FLAGS_SSLV3;
- break;
- case 1:
- sessionFlag = SSL_FLAGS_TLS_1_0;
- break;
- case 2:
- sessionFlag = SSL_FLAGS_TLS_1_1;
- break;
- case 3:
- sessionFlag = SSL_FLAGS_TLS_1_2;
- break;
- default:
- sessionFlag = SSL_FLAGS_TLS_1_0;
- break;
- }
-# else
- /* MatrixSSL <= 3.4.2 don't support setting version on request */
- sessionFlag = 0;
-# endif
- options.versionFlag = sessionFlag;
+ options.versionFlag = tlsMinVerToVersionFlag(g_version);
}
options.userPtr = keys;
@@ -253,20 +380,25 @@ static int32 httpsClientConnection(sslKeys_t *keys, sslSessionId_t *sid,
options.validateCertsOpts.max_verify_depth = g_max_verify_depth;
matrixSslNewHelloExtension(&extension, NULL);
- matrixSslCreateSNIext(NULL, (unsigned char *) g_ip, (uint32) strlen(g_ip),
- &ext, &extLen);
+ if (Strlen(g_server_name) == 0)
+ {
+ Memcpy(g_server_name, g_ip, Strlen(g_ip));
+ }
+ matrixSslCreateSNIext(NULL,
+ (unsigned char *) g_server_name, (uint32) Strlen(g_server_name),
+ &ext, &extLen);
matrixSslLoadHelloExtension(extension, ext, extLen, EXT_SNI);
psFree(ext, NULL);
# ifdef USE_ALPN
/* Application Layer Protocol Negotiation */
- alpn[0] = psMalloc(NULL, strlen("http/1.0"));
- memcpy(alpn[0], "http/1.0", strlen("http/1.0"));
- alpnLen[0] = strlen("http/1.0");
+ alpn[0] = (unsigned char *)psMalloc(NULL, Strlen("http/1.0"));
+ Memcpy(alpn[0], "http/1.0", Strlen("http/1.0"));
+ alpnLen[0] = Strlen("http/1.0");
- alpn[1] = psMalloc(NULL, strlen("http/1.1"));
- memcpy(alpn[1], "http/1.1", strlen("http/1.1"));
- alpnLen[1] = strlen("http/1.1");
+ alpn[1] = (unsigned char *)psMalloc(NULL, Strlen("http/1.1"));
+ Memcpy(alpn[1], "http/1.1", Strlen("http/1.1"));
+ alpnLen[1] = Strlen("http/1.1");
matrixSslCreateALPNext(NULL, 2, alpn, alpnLen, &ext, &extLen);
matrixSslLoadHelloExtension(extension, ext, extLen, EXT_ALPN);
@@ -275,27 +407,50 @@ static int32 httpsClientConnection(sslKeys_t *keys, sslSessionId_t *sid,
# endif
/* We are passing the IP address of the server as the expected name */
- /* To skip certificate subject name tests, pass NULL instead of g_ip */
+ /* To skip certificate subject name tests, pass NULL instead of
+ g_server_name */
if (g_disableCertNameChk == 0)
{
rc = matrixSslNewClientSession(&ssl, keys, sid, g_cipher, g_ciphers,
- certCb, g_ip, extension, extensionCb, &options);
-
-
+ certCb, g_server_name, extension, extensionCb, &options);
}
else
{
rc = matrixSslNewClientSession(&ssl, keys, sid, g_cipher, g_ciphers,
certCb, NULL, extension, extensionCb, &options);
}
-
- matrixSslDeleteHelloExtension(extension);
if (rc != MATRIXSSL_REQUEST_SEND)
{
- _psTraceInt("New Client Session Failed: %d. Exiting\n", rc);
- close(fd);
- return PS_ARG_FAIL;
+ psTraceInt("New Client Session Failed: %d. Exiting\n", rc);
+ rc = PS_ARG_FAIL;
+ goto L_CLOSE_ERR;
}
+
+# ifdef USE_TLS_1_3
+ /* TLS 1.3 early data sending from file. Early data must be sent right
+ after the matrixSslNewClientSession call */
+ if (Strlen(g_early_data_file) > 0 &&
+ matrixSslGetMaxEarlyData(ssl) > 0)
+ {
+ if (sendEarlyData(ssl) < 0)
+ {
+ rc = PS_FAILURE;
+ goto L_CLOSE_ERR;
+ }
+ }
+ if (g_tls13_block_size != 0)
+ {
+ rc = matrixSslSetTls13BlockPadding(ssl, g_tls13_block_size);
+ if (rc != PS_SUCCESS)
+ {
+ rc = PS_FAILURE;
+ goto L_CLOSE_ERR;
+ }
+ }
+# endif
+
+ matrixSslDeleteHelloExtension(extension);
+
WRITE_MORE:
while ((len = matrixSslGetOutdata(ssl, &buf)) > 0)
{
@@ -306,7 +461,7 @@ WRITE_MORE:
transferred = send(fd, buf, len, 0);
if (transferred <= 0)
{
- printf("Error sending\n");
+ Printf("Error sending\n");
goto L_CLOSE_ERR;
}
else
@@ -323,6 +478,14 @@ WRITE_MORE:
}
if (rc == MATRIXSSL_HANDSHAKE_COMPLETE)
{
+ Printf("TLS handshake complete.\n");
+
+ if (USING_TLS_1_3(ssl) && sid != NULL && g_resumed > 0)
+ {
+ /* Try to receive the server's NewSessionTicket. */
+ goto READ_MORE;
+ }
+
/* If we sent the Finished SSL message, initiate the HTTP req */
/* (This occurs on a resumption handshake) */
if ((rc = httpWriteRequest(ssl)) < 0)
@@ -368,25 +531,36 @@ READ_MORE:
# ifdef USE_EXT_CLIENT_CERT_KEY_LOADING
if (rc == PS_PENDING && matrixSslNeedClientCert(ssl))
{
- _psTrace("Loading client cert and key in response to " \
+ sslIdentity_t *id, *next;
+
+ psTrace("Loading client cert and key in response to " \
"CertificateRequest\n");
- if (ssl->keys->cert)
+
+ /* Clear previously set identities from the ssl->keys before
+ loading new ones.
+
+ On a typical application the 'identity' keys would not be
+ shared with initial NewClient call, and the ps-pending
+ driven/callback driven mechanisms */
+ for (id = ssl->keys->identity; id; id = next)
{
- psX509FreeCert(ssl->keys->cert);
- ssl->keys->cert = NULL;
- }
- if (ssl->keys->privKey.keysize > 0)
- {
- psClearPubKey(&ssl->keys->privKey);
+ next = id->next;
+ if (id->cert)
+ psX509FreeCert(id->cert);
+ psClearPubKey(&id->privKey);
+ psFree(id, ssl->keys->pool);
}
+ ssl->keys->identity = NULL;
+
if (matrixSslLoadKeys(ssl->keys,
g_on_demand_cert_file,
g_on_demand_key_file,
NULL, NULL, NULL) < 0)
{
- _psTrace("matrixSslLoadKeys failed\n");
+ psTrace("matrixSslLoadKeys failed\n");
exit(EXIT_FAILURE);
}
+ matrixSslSetClientIdentity(ssl, ssl->keys);
(void)matrixSslClientCertUpdated(ssl);
/* Retry now that we have the cert and the priv key. */
@@ -394,7 +568,7 @@ READ_MORE:
(uint32 *) &len);
if (rc < 0)
{
- _psTrace("Retry failed\n");
+ psTrace("Retry failed\n");
}
goto WRITE_MORE;
}
@@ -470,6 +644,7 @@ PROCESS_MORE:
}
goto WRITE_MORE;
# else
+ Printf("TLS handshake complete.\n");
/* We got the Finished SSL message, initiate the HTTP req */
if ((rc = httpWriteRequest(ssl)) < 0)
{
@@ -483,22 +658,22 @@ PROCESS_MORE:
# ifdef TEST_KEEP_PEER_CERTS
if (ssl->sec.cert == NULL)
{
- printf("Error: peer cert not kept\n");
+ Printf("Error: peer cert not kept\n");
return MATRIXSSL_ERROR;
}
else
{
- printf("OK: peer cert still available\n");
+ Printf("OK: peer cert still available\n");
}
if (ssl->sec.cert->unparsedBin == NULL ||
ssl->sec.cert->binLen <= 0)
{
- printf("Error: peer cert DER not kept\n");
+ Printf("Error: peer cert DER not kept\n");
return MATRIXSSL_ERROR;
}
else
{
- printf("OK: peer cert DER still available\n");
+ Printf("OK: peer cert DER still available\n");
}
# endif
closeConn(ssl, fd);
@@ -518,7 +693,7 @@ PROCESS_MORE:
closeConn(ssl, fd);
if (cp.parsebuf)
{
- free(cp.parsebuf);
+ Free(cp.parsebuf);
}
cp.parsebuf = NULL;
cp.parsebuflen = 0;
@@ -536,12 +711,22 @@ PROCESS_MORE:
psTraceBytes("HTTP DATA", buf, len);
if (g_print_http_response)
{
- char *resp_str = psMalloc(NULL, len+1);
+ char *resp_str = (char *)psMalloc(NULL, len+1);
- psMem2Str(resp_str, buf, len);
- resp_str[len] = '\0';
- _psTraceStr("%s", resp_str);
- free(resp_str);
+ if (resp_str != NULL)
+ {
+ psMem2Str(resp_str, buf, len);
+ resp_str[len] = '\0';
+ psTraceStr("%s", resp_str);
+ Free(resp_str);
+ }
+ else
+ {
+ /* Memory allocation failure. Skip trace. */
+ psTraceInt("HTTP RESPONSE: %d bytes of data.\n"
+ "(Printing omitted due to memory allocation "
+ "failure)\n", (int)len);
+ }
}
}
rc = matrixSslProcessedData(ssl, &buf, (uint32 *) &len);
@@ -557,7 +742,7 @@ PROCESS_MORE:
closeConn(ssl, fd);
if (cp.parsebuf)
{
- free(cp.parsebuf);
+ Free(cp.parsebuf);
}
cp.parsebuf = NULL;
cp.parsebuflen = 0;
@@ -589,7 +774,7 @@ PROCESS_MORE:
closeConn(ssl, fd);
if (cp.parsebuf)
{
- free(cp.parsebuf);
+ Free(cp.parsebuf);
}
cp.parsebuf = NULL;
cp.parsebuflen = 0;
@@ -610,7 +795,7 @@ PROCESS_MORE:
L_CLOSE_ERR:
if (cp.flags != HTTPS_COMPLETE)
{
- _psTrace("FAIL: No HTTP Response\n");
+ psTrace("FAIL: No HTTP Response\n");
}
matrixSslDeleteSession(ssl);
if (g_keepalive == 0)
@@ -619,7 +804,7 @@ L_CLOSE_ERR:
}
if (cp.parsebuf)
{
- free(cp.parsebuf);
+ Free(cp.parsebuf);
}
cp.parsebuf = NULL;
cp.parsebuflen = 0;
@@ -645,7 +830,7 @@ static int32 httpWriteRequest(ssl_t *ssl)
{
/* A value of 0 to the 'new' connections is the key to sending the
server a shutdown message */
- requested = strlen((char *) g_matrixShutdownServer) + 1;
+ requested = Strlen((char *) g_matrixShutdownServer) + 1;
if ((available = matrixSslGetWritebuf(ssl, &buf, requested)) < 0)
{
return PS_MEM_FAIL;
@@ -654,29 +839,29 @@ static int32 httpWriteRequest(ssl_t *ssl)
{
return PS_FAILURE;
}
- memset(buf, 0x0, requested); /* So strlen will work below */
- strncpy((char *) buf, (char *) g_matrixShutdownServer,
- (uint32) strlen((char *) g_matrixShutdownServer));
- if (matrixSslEncodeWritebuf(ssl, (uint32) strlen((char *) buf)) < 0)
+ Memset(buf, 0x0, requested); /* So strlen will work below */
+ Strncpy((char *) buf, (char *) g_matrixShutdownServer,
+ (uint32) Strlen((char *) g_matrixShutdownServer));
+ if (matrixSslEncodeWritebuf(ssl, (uint32) Strlen((char *) buf)) < 0)
{
return PS_MEM_FAIL;
}
return MATRIXSSL_REQUEST_SEND;
}
- requested = strlen((char *) g_httpRequestHdr) + strlen(g_path) + strlen(g_ip) + 1;
+ requested = Strlen((char *) g_httpRequestHdr) + Strlen(g_path) + Strlen(g_server_name) + 1;
if ((available = matrixSslGetWritebuf(ssl, &buf, requested)) < 0)
{
return PS_MEM_FAIL;
}
- requested = min(requested, available);
- snprintf((char *) buf, requested, (char *) g_httpRequestHdr, g_path, g_ip);
+ requested = PS_MIN(requested, available);
+ Snprintf((char *) buf, requested, (char *) g_httpRequestHdr, g_path, g_server_name);
if (g_trace)
{
- _psTraceStr("SEND: [%s]\n", (char *) buf);
+ psTraceStr("SEND: [%s]\n", (char *) buf);
}
- if (matrixSslEncodeWritebuf(ssl, strlen((char *) buf)) < 0)
+ if (matrixSslEncodeWritebuf(ssl, Strlen((char *) buf)) < 0)
{
return PS_MEM_FAIL;
}
@@ -685,7 +870,7 @@ static int32 httpWriteRequest(ssl_t *ssl)
static void usage(void)
{
- printf(
+ Printf(
"\nusage: client { options }\n"
"\n"
"Options can be one or more of the following:\n"
@@ -713,6 +898,9 @@ static void usage(void)
"--external-verify - RSA keyLen (if using client auth)\n"
@@ -725,6 +913,7 @@ static void usage(void)
" - Default 1\n"
"-m - Maximum depth for certificate verification\n"
"--depth \n"
+ "--num-key-shares - (TLS 1.3 only) Number of key shares to include in ClientHello.\n"
"-p - Port number for SSL/TLS server\n"
"--port \n"
" - Default 4433 (HTTPS is 443)\n"
@@ -734,6 +923,7 @@ static void usage(void)
"-s - IP address of server machine/interface\n"
"--server \n"
" - Default 127.0.0.1 (localhost)\n"
+ "--server-name - The server name to send in the SNI extension\n"
"-t - Enable printing of HTTP response\n"
"--response\n"
"-u - URL path, eg. '/index.html'\n"
@@ -741,14 +931,27 @@ static void usage(void)
" Generates an HTTPS request after TLS negotiation\n"
" Mutually exclusive with '-b' flag\n"
"-V - SSL/TLS version to use\n"
- "--tls \n"
- " - '0' SSL 3.0\n"
- " - '1' TLS 1.0\n"
- " - '2' TLS 1.1\n"
- " - '3' TLS 1.2 (default)\n"
+ "--tls - Selects a single TLS version to support\n"
+ " '0' SSL 3.0\n"
+ " '1' TLS 1.0\n"
+ " '2' TLS 1.1\n"
+ " '3' TLS 1.2\n"
+ " '4' TLS 1.3 (default)\n"
+ " '22' TLS 1.3 draft 22\n"
+ " '23' TLS 1.3 draft 23\n"
+ " '24' TLS 1.3 draft 24\n"
"--tls-version-range ,\n"
- " Set TLS version range, e.g.\n"
+ " - Set TLS version range, e.g.\n"
" 2,3 for TLS 1.1 - TLS 1.2\n"
+ " - Note: Only one of the version parameters should be supplied\n"
+ " (--tls, --tls-version-range or--tls-supported-versions)\n"
+ "--tls-supported-versions ,,...\n"
+ " - Lists the supported versions in priority order, e.g.\n"
+ " 23,3,2 for TLS 1.3 draft 23, TLS 1.2 and TLS 1.1\n"
+ " - Priority order is used only when TLS1.3 is enabled. Otherwise\n"
+ " the latest version has the highest priority.\n"
+ " - Note: Only one of the version parameters should be supplied\n"
+ " (--tls, --tls-version-range or --tls-supported-versions)\n"
"--no-cert - Unset client certificate\n"
"--cert \n"
" - Path to client certificate file\n"
@@ -759,11 +962,30 @@ static void usage(void)
" rsa (for RSA keys)\n"
" ec (for EC keys ECDSA signature)\n"
" ecrsa (for EC keys with RSA signature)\n"
+ "--groups \n"
+ " - Supported groups.\n"
+ " For example: secp256r1:secp384r1\n"
+ "--num-key-shares \n"
+ " - For how many groups (listed by --groups)\n"
+ " key share entries are generated in ClientHello.\n"
+ "--sig-algs \n"
+ " - Supported signature algorithms.\n"
+ " For example: ecdsa_secp256r1_sha256:rsa_pss_rsae_sha256\n"
+ "--sig-algs-cert \n"
+ " - Supported signature algorithms in TLS1.3 certs.\n"
+ " For example: ecdsa_secp256r1_sha256:rsa_pss_rsae_sha256\n"
+ "--early-data \n"
+ " - Send supplied file using TLS1.3 early data mechanism.\n"
+ " - Enable also -r or --resumed\n"
+ " For example: --early-data file.dat -r1\n"
+ " - Maximum of 16384 bytes is sent from the file.\n"
+ "--tls13-block-size\n"
+ " - Block size to pad TLS 1.3 records to.\n"
"\n");
}
/* Returns number of cipher numbers found, or -1 if an error. */
-# include
+# include "osdep_ctype.h"
static int32_t parse_cipher_list(char *cipherListString,
psCipher16_t cipher_array[], uint8_t size_of_cipher_array)
{
@@ -774,21 +996,21 @@ static int32_t parse_cipher_list(char *cipherListString,
numCiphers = 0;
while (cipherListString != NULL)
{
- cipher = strtol(cipherListString, &endPtr, 10);
+ cipher = Strtol(cipherListString, &endPtr, 10);
if (endPtr == cipherListString)
{
- printf("The remaining cipherList has no cipher numbers - '%s'\n",
+ Printf("The remaining cipherList has no cipher numbers - '%s'\n",
cipherListString);
return -1;
}
else if (size_of_cipher_array <= numCiphers)
{
- printf("Too many cipher numbers supplied. limit is %d\n",
+ Printf("Too many cipher numbers supplied. limit is %d\n",
size_of_cipher_array);
return -1;
}
cipher_array[numCiphers++] = cipher;
- while (*endPtr != '\0' && !isdigit(*endPtr))
+ while (*endPtr != '\0' && !Isdigit(*endPtr))
{
endPtr++;
}
@@ -808,13 +1030,13 @@ static int32 process_cmd_options(int32 argc, char **argv)
{
int optionChar, key_len, version, numCiphers;
char *cipherListString;
-
+ psList_t *versionRangeList;
/* Set some default options: */
- memset(g_cipher, 0, sizeof(g_cipher));
- memset(g_ip, 0, sizeof(g_ip));
- memset(g_path, 0, sizeof(g_path));
+ Memset(g_cipher, 0, sizeof(g_cipher));
+ Memset(g_ip, 0, sizeof(g_ip));
+ Memset(g_path, 0, sizeof(g_path));
- strcpy(g_ip, "127.0.0.1");
+ Strcpy(g_ip, "127.0.0.1");
g_bytes_requested = 0;
g_send_closure_alert = 1;
g_ciphers = 0;
@@ -824,7 +1046,7 @@ static int32 process_cmd_options(int32 argc, char **argv)
g_new = 1;
g_port = 4433;
g_resumed = 0;
- g_version = 3;
+ g_version = 0;
g_keepalive = 0;
opterr = 0;
@@ -839,6 +1061,18 @@ static int32 process_cmd_options(int32 argc, char **argv)
#define ARG_ON_DEMAND_CERT 5
#define ARG_ON_DEMAND_KEY 6
#define ARG_TLS_VERSION_RANGE 7
+#define ARG_GROUPS 8
+#define ARG_NUM_KEY_SHARES 9
+#define ARG_SIG_ALGS 10
+#define ARG_SIG_ALGS_CERT 11
+#define ARG_TLS_SUPPORTED_VERSIONS 12
+#define ARG_SERVER_NAME 13
+#define ARG_PSK 14
+#define ARG_EARLY_DATA 15
+#define ARG_REQ_OCSP_STAPLING 16
+#define ARG_DISABLE_PEER_AUTHENTICATION 17
+#define ARG_TLS13_BLOCK_SIZE 18
+#define ARG_MIN_DH_P_SIZE 19
static struct option long_options[] =
{
@@ -856,16 +1090,28 @@ static int32 process_cmd_options(int32 argc, char **argv)
{"port", required_argument, NULL, 'p'},
{"resumed", required_argument, NULL, 'r'},
{"server", required_argument, NULL, 's'},
+ {"server-name", required_argument, NULL, ARG_SERVER_NAME},
{"response", no_argument, NULL, 't'},
{"url", required_argument, NULL, 'u'},
{"tls", required_argument, NULL, 'V'},
{"tls-version-range", required_argument, NULL, ARG_TLS_VERSION_RANGE},
+ {"tls-supported-versions", required_argument, NULL, ARG_TLS_SUPPORTED_VERSIONS},
{"no-cert", no_argument, NULL, ARG_NO_CERT},
{"cert", required_argument, NULL, ARG_CERT},
{"key", required_argument, NULL, ARG_KEY},
{"on-demand-cert", required_argument, NULL, ARG_ON_DEMAND_CERT},
{"on-demand-key", required_argument, NULL, ARG_ON_DEMAND_KEY},
{"keytype", required_argument, NULL, ARG_KEYTYPE},
+ {"groups", required_argument, NULL, ARG_GROUPS},
+ {"num-key-shares", required_argument, NULL, ARG_NUM_KEY_SHARES},
+ {"sig-algs", required_argument, NULL, ARG_SIG_ALGS},
+ {"sig-algs-cert", required_argument, NULL, ARG_SIG_ALGS_CERT},
+ {"psk", no_argument, NULL, ARG_PSK},
+ {"early-data", required_argument, NULL, ARG_EARLY_DATA},
+ {"tls13-block-size", required_argument, NULL, ARG_TLS13_BLOCK_SIZE},
+ {"req-ocsp-stapling", no_argument, NULL, ARG_REQ_OCSP_STAPLING},
+ {"disable-peer-authentication", no_argument, NULL, ARG_DISABLE_PEER_AUTHENTICATION},
+ {"min-dh-p-size", required_argument, NULL, ARG_MIN_DH_P_SIZE},
{0, 0, 0, 0}
};
@@ -889,11 +1135,11 @@ static int32 process_cmd_options(int32 argc, char **argv)
case 'b':
if (*g_path)
{
- printf("-b and -u options cannot both be provided\n");
+ Printf("-b and -u options cannot both be provided\n");
return -1;
}
g_bytes_requested = atoi(optarg);
- snprintf(g_path, sizeof(g_path), "/bytes?%u", g_bytes_requested);
+ Snprintf(g_path, sizeof(g_path), "/bytes?%u", g_bytes_requested);
break;
case 'C':
@@ -917,17 +1163,16 @@ static int32 process_cmd_options(int32 argc, char **argv)
break;
case 'e':
- printf("-e option only supported when USE_EXT_CERTIFICATE_VERIFY_SIGNING " \
+ Printf("-e option only supported when USE_EXT_CERTIFICATE_VERIFY_SIGNING " \
"and USE_EXT_EXAMPLE_MODULE are defined\n");
return -1;
- break;
case 'k':
key_len = atoi(optarg);
if ((key_len != 1024) && (key_len != 2048)
&& (key_len != 3072) && (key_len != 4096))
{
- printf("-k option must be followed by a key_len whose value "
+ Printf("-k option must be followed by a key_len whose value "
" must be 1024, 2048, 3072 or 4096\n");
return -1;
}
@@ -959,24 +1204,26 @@ static int32 process_cmd_options(int32 argc, char **argv)
break;
case 's':
- strncpy(g_ip, optarg, 15);
+ Strncpy(g_ip, optarg, 15);
break;
case 'u':
if (*g_path)
{
- printf("-b and -u options cannot both be provided\n");
+ Printf("-b and -u options cannot both be provided\n");
return -1;
}
- strncpy(g_path, optarg, sizeof(g_path) - 1);
+ Strncpy(g_path, optarg, sizeof(g_path) - 1);
g_bytes_requested = 0;
break;
case 'V':
+ /* Single version. */
version = atoi(optarg);
- if (version < 0 || version > 3)
+ if (!matrixSslTlsVersionRangeSupported(version,
+ version))
{
- printf("Invalid version: %d\n", version);
+ Printf("Invalid version: %d\n", version);
return -1;
}
g_version = version;
@@ -1002,16 +1249,16 @@ static int32 process_cmd_options(int32 argc, char **argv)
break;
case ARG_KEYTYPE:
- if (strcmp("any", optarg) == 0) {
+ if (Strcmp("any", optarg) == 0) {
g_clientconfig.load_key = &loadKeysFromFile;
- } else if (strcmp("rsa", optarg) == 0) {
+ } else if (Strcmp("rsa", optarg) == 0) {
g_clientconfig.load_key = &loadRsaKeysFromFile;
- } else if (strcmp("ec", optarg) == 0) {
+ } else if (Strcmp("ec", optarg) == 0) {
g_clientconfig.load_key = &loadECDH_ECDSAKeysFromFile;
- } else if (strcmp("ecrsa", optarg) == 0) {
+ } else if (Strcmp("ecrsa", optarg) == 0) {
g_clientconfig.load_key = &loadECDHRsaKeysFromFile;
} else {
- printf("Invalid option: %s\n", optarg);
+ Printf("Invalid option: %s\n", optarg);
return -1;
}
@@ -1020,22 +1267,20 @@ static int32 process_cmd_options(int32 argc, char **argv)
case ARG_TLS_VERSION_RANGE:
{
- const char *versionRangeStr;
-
- versionRangeStr = optarg;
- if (strlen(versionRangeStr) != 3)
+ if (psParseList(NULL, optarg, ',', &versionRangeList) < 0)
{
- printf("Invalid version range string: %s\n",
- versionRangeStr);
+ Printf("Invalid version range string: %s\n",
+ optarg);
return -1;
}
- g_min_version = atoi(&versionRangeStr[0]);
- g_max_version = atoi(&versionRangeStr[2]);
+ g_min_version = atoi((char *)versionRangeList->item);
+ g_max_version = atoi((char *)versionRangeList->next->item);
+ psFreeList(versionRangeList, NULL);
if (!matrixSslTlsVersionRangeSupported(g_min_version,
g_max_version))
{
- printf("Unsupported version range: %s\n",
- versionRangeStr);
+ Printf("Unsupported version range: %s\n",
+ optarg);
return -1;
}
g_version_range_set = 1;
@@ -1046,7 +1291,7 @@ static int32 process_cmd_options(int32 argc, char **argv)
# ifdef USE_EXT_CLIENT_CERT_KEY_LOADING
g_on_demand_cert_file = optarg;
# else
- printf("Please enable USE_EXT_CLIENT_CERT_KEY_LOADING " \
+ Printf("Please enable USE_EXT_CLIENT_CERT_KEY_LOADING " \
"in matrixsslConfig.h for --on-demand-cert\n");
# endif
break;
@@ -1055,10 +1300,100 @@ static int32 process_cmd_options(int32 argc, char **argv)
# ifdef USE_EXT_CLIENT_CERT_KEY_LOADING
g_on_demand_key_file = optarg;
# else
- printf("Please enable USE_EXT_CLIENT_CERT_KEY_LOADING " \
+ Printf("Please enable USE_EXT_CLIENT_CERT_KEY_LOADING " \
"in matrixsslConfig.h for --on-demand-key\n");
# endif
break;
+
+ case ARG_GROUPS:
+ if (psParseList(NULL, optarg, ':', &g_groupList) < 0)
+ {
+ Printf("Invalid group list: %s\n", optarg);
+ }
+ break;
+
+ case ARG_NUM_KEY_SHARES:
+ g_num_key_shares = atoi(optarg);
+ if (g_num_key_shares > 10)
+ {
+ Printf("Invalid number of key shares: %hu\n", g_num_key_shares);
+ }
+ break;
+ case ARG_SIG_ALGS:
+ if (psParseList(NULL, optarg, ':', &g_sigAlgsList) < 0)
+ {
+ Printf("Invalid sig_alg list: %s\n", optarg);
+ }
+ break;
+ case ARG_SIG_ALGS_CERT:
+ if (psParseList(NULL, optarg, ':', &g_sigAlgsCertList) < 0)
+ {
+ Printf("Invalid sig_alg_cert list: %s\n", optarg);
+ }
+ break;
+ case ARG_TLS_SUPPORTED_VERSIONS:
+ if (psParseList(NULL, optarg, ',', &g_supportedVersionsList) < 0)
+ {
+ Printf("Invalid tls-supported-versions list: %s\n", optarg);
+ }
+ break;
+ case ARG_SERVER_NAME:
+ if (Strlen(optarg) > sizeof(g_server_name) - 1)
+ {
+ Printf("Server name argument too long\n");
+ exit(EXIT_FAILURE);
+ }
+ Strncpy(g_server_name, optarg, sizeof(g_server_name) - 1);
+ break;
+ case ARG_PSK:
+ g_clientconfig.loadPreSharedKeys = 1;
+ g_use_psk = 1;
+ break;
+ case ARG_EARLY_DATA:
+ Strcpy(g_early_data_file, optarg);
+ break;
+ case ARG_TLS13_BLOCK_SIZE:
+ {
+ char *end;
+
+ g_tls13_block_size = Strtol(optarg, &end, 10);
+ if (end == optarg
+ || g_tls13_block_size < 0
+ || g_tls13_block_size > TLS_1_3_MAX_INNER_PLAINTEXT_LEN)
+ {
+ Printf("Invalid tls13-block-size argument\n");
+ exit(EXIT_FAILURE);
+ }
+ Printf("Using TLS 1.3 block size %ld\n",
+ g_tls13_block_size);
+ }
+ break;
+ case ARG_REQ_OCSP_STAPLING:
+ g_req_ocsp_stapling = 1;
+ break;
+ case ARG_DISABLE_PEER_AUTHENTICATION:
+ g_disable_peer_authentication = 1;
+ break;
+ case ARG_MIN_DH_P_SIZE:
+ {
+ char *end;
+
+ g_min_dh_p_size = Strtol(optarg, &end, 10);
+ if (end == optarg
+ || g_min_dh_p_size <= 0)
+ {
+ Printf("Invaling min-dh-p argument\n");
+ exit(EXIT_FAILURE);
+ }
+ if (g_min_dh_p_size < MIN_DH_BITS)
+ {
+ Printf("Invalid min-dh-p argument: " \
+ "must be <= MIN_DH_BITS (= %u in this build)\n",
+ (unsigned int)MIN_DH_BITS);
+ exit(EXIT_FAILURE);
+ }
+ }
+ break;
#endif /* USE_GETOPT_LONG */
}
@@ -1070,14 +1405,14 @@ static int32 process_cmd_options(int32 argc, char **argv)
static void sslstatsPrintTime(const struct g_sslstats* stats, int conn_count)
{
# ifdef USE_HIGHRES_TIME
- printf("%d usec (%d avg usec/conn SSL handshake overhead)\n",
+ Printf("%d usec (%d avg usec/conn SSL handshake overhead)\n",
(int) stats->hstime, (int) (stats->hstime / conn_count));
- printf("%d usec (%d avg usec/conn SSL data overhead)\n",
+ Printf("%d usec (%d avg usec/conn SSL data overhead)\n",
(int) stats->datatime, (int) (stats->datatime / conn_count));
# else
- printf("%d msec (%d avg msec/conn SSL handshake overhead)\n",
+ Printf("%d msec (%d avg msec/conn SSL handshake overhead)\n",
(int) stats->hstime, (int) (stats->hstime / conn_count));
- printf("%d msec (%d avg msec/conn SSL data overhead)\n",
+ Printf("%d msec (%d avg msec/conn SSL data overhead)\n",
(int) stats->datatime, (int) (stats->datatime / conn_count));
# endif
}
@@ -1120,13 +1455,7 @@ int32 main(int32 argc, char **argv)
if ((rc = matrixSslOpen()) < 0)
{
- _psTrace("MatrixSSL library init failure. Exiting\n");
- return EXIT_FAILURE;
- }
-
- if (matrixSslNewKeys(&keys, NULL) < 0)
- {
- _psTrace("MatrixSSL library key init failure. Exiting\n");
+ psTrace("MatrixSSL library init failure. Exiting\n");
return EXIT_FAILURE;
}
@@ -1137,6 +1466,12 @@ int32 main(int32 argc, char **argv)
return 0;
}
+ if (matrixSslNewKeys(&keys, NULL) < 0)
+ {
+ psTrace("MatrixSSL library key init failure. Exiting\n");
+ return EXIT_FAILURE;
+ }
+
if (g_new <= 1 && g_resumed <= 1)
{
g_trace = 1;
@@ -1148,17 +1483,17 @@ int32 main(int32 argc, char **argv)
if (g_bytes_requested == 0 && *g_path == '\0')
{
- printf("client %s:%d "
- "new:%d resumed:%d keylen:%d nciphers:%d version:%s\n",
+ Printf("client %s:%d "
+ "new:%d resumed:%d keylen:%d nciphers:%d version:%d\n",
g_ip, g_port, g_new, g_resumed, g_key_len,
- g_ciphers, g_strver[g_version]);
+ g_ciphers, g_version);
}
else
{
- printf("client https://%s:%d%s "
- "new:%d resumed:%d keylen:%d nciphers:%d version:%s\n",
+ Printf("client https://%s:%d%s "
+ "new:%d resumed:%d keylen:%d nciphers:%d version:%d\n",
g_ip, g_port, g_path, g_new, g_resumed, g_key_len,
- g_ciphers, g_strver[g_version]);
+ g_ciphers, g_version);
}
if (!clientconfigLoadKeys(keys))
@@ -1166,6 +1501,24 @@ int32 main(int32 argc, char **argv)
return EXIT_FAILURE;
}
+# ifdef USE_TLS_1_3
+ if (g_use_psk)
+ {
+ /* Load the TLS 1.3 test PSK. */
+ rc = matrixSslLoadTls13Psk(keys,
+ g_tls13_test_psk_256,
+ sizeof(g_tls13_test_psk_256),
+ g_tls13_test_psk_id,
+ sizeof(g_tls13_test_psk_id),
+ NULL);
+ if (rc < 0)
+ {
+ psTrace("Unable to load PSK keys.\n");
+ return rc;
+ }
+ }
+# endif
+
# ifdef USE_CRL
/* One initialization step that can be taken is to run through the CA
files and see if any CRL URL distribution points are present.
@@ -1173,8 +1526,8 @@ int32 main(int32 argc, char **argv)
fetchParseAndAuthCRLfromCert(NULL, keys->CAcerts, keys->CAcerts);
# endif
- memset(&stats, 0x0, sizeof(struct g_sslstats));
- printf("=== %d new connections ===\n", g_new);
+ Memset(&stats, 0x0, sizeof(struct g_sslstats));
+ Printf("=== %d new connections ===\n", g_new);
if (g_new == 0)
{
@@ -1205,13 +1558,13 @@ int32 main(int32 argc, char **argv)
rc = httpsClientConnection(keys, sid, &stats);
if (rc < 0)
{
- printf("F %d/%d\n", i, g_new);
+ Printf("F %d/%d\n", i, g_new);
exit_code = EXIT_FAILURE;
goto out;
}
else
{
- printf("N"); fflush(stdout);
+ Printf("N"); Fflush(stdout);
}
/* Leave the final sessionID for resumed connections */
if (i + 1 < g_new)
@@ -1219,33 +1572,34 @@ int32 main(int32 argc, char **argv)
matrixSslDeleteSessionId(sid);
}
}
- printf("\n");
+ Printf("\n");
if (g_bytes_requested > 0)
{
psAssert(g_bytes_requested * g_new == stats.rbytes);
}
- printf("%d bytes received\n", stats.rbytes);
+ Printf("%d bytes received\n", stats.rbytes);
sslstatsPrintTime(&stats, g_new);
- memset(&stats, 0x0, sizeof(struct g_sslstats));
- printf("=== %d resumed connections ===\n", g_resumed);
+ Memset(&stats, 0x0, sizeof(struct g_sslstats));
+ Printf("=== %d resumed connections ===\n", g_resumed);
for (i = 0; i < g_resumed; i++)
{
rc = httpsClientConnection(keys, sid, &stats);
if (rc < 0)
{
- printf("f %d/%d\n", i, g_resumed);
+ Printf("f %d/%d\n", i, g_resumed);
exit_code = EXIT_FAILURE;
goto out;
}
else
{
- printf("R"); fflush(stdout);
+ Printf("Resumed session.\n");
+ Printf("R"); Fflush(stdout);
}
}
if (g_keepalive)
{
- printf("Closing socket\n");
+ Printf("Closing socket\n");
close(g_keepalive);
g_keepalive = 0;
}
@@ -1255,7 +1609,7 @@ int32 main(int32 argc, char **argv)
{
psAssert(g_bytes_requested * g_resumed == stats.rbytes);
}
- printf("\n%d bytes received\n", stats.rbytes);
+ Printf("\n%d bytes received\n", stats.rbytes);
sslstatsPrintTime(&stats, g_resumed);
}
@@ -1267,13 +1621,13 @@ out:
clientconfigFree();
- if (rc == MATRIXSSL_SUCCESS)
- {
- printf("TLS handshake complete.\n");
- }
+ psFreeList(g_sigAlgsCertList, NULL);
+ psFreeList(g_sigAlgsList, NULL);
+ psFreeList(g_supportedVersionsList, NULL);
+ psFreeList(g_groupList, NULL);
# ifdef WIN32
- _psTrace("Press any key to close");
+ psTrace("Press any key to close");
getchar();
# endif
return exit_code;
@@ -1334,19 +1688,19 @@ static int32_t extensionCb(ssl_t *ssl,
if (extType == EXT_ALPN)
{
- memset(proto, 0x0, 128);
+ Memset(proto, 0x0, 128);
/* two byte proto list len, one byte proto len, then proto */
c += 2; /* Skip proto list len */
len = *c; c++;
- memcpy(proto, c, len);
- printf("Server agreed to use %s\n", proto);
+ Memcpy(proto, c, len);
+ Printf("Server agreed to use %s\n", proto);
}
return PS_SUCCESS;
}
/******************************************************************************/
/*
- Example callback to show possiblie outcomes of certificate validation.
+ Example callback to show possible outcomes of certificate validation.
If this callback is not registered in matrixSslNewClientSession
the connection will be accepted or closed based on the alert value.
*/
@@ -1355,6 +1709,13 @@ static int32 certCb(ssl_t *ssl, psX509Cert_t *cert, int32 alert)
# ifndef USE_ONLY_PSK_CIPHER_SUITE
psX509Cert_t *next;
+ if (g_disable_peer_authentication)
+ {
+ psTraceStr("Allowing anonymous connection for: %s.\n",
+ cert->subject.commonName);
+ return SSL_ALLOW_ANON_CONNECTION;
+ }
+
/* An immediate SSL_ALERT_UNKNOWN_CA alert means we could not find the
CA to authenticate the server's certificate */
if (alert == SSL_ALERT_UNKNOWN_CA)
@@ -1370,7 +1731,7 @@ static int32 certCb(ssl_t *ssl, psX509Cert_t *cert, int32 alert)
(next->authFailFlags &
PS_CERT_AUTH_FAIL_VERIFY_DEPTH_FLAG))
{
- _psTrace("Maximum cert chain verify depth exceeded\n");
+ psTrace("Maximum cert chain verify depth exceeded\n");
return SSL_ALERT_UNKNOWN_CA;
}
}
@@ -1380,12 +1741,12 @@ static int32 certCb(ssl_t *ssl, psX509Cert_t *cert, int32 alert)
{
if (g_trace)
{
- _psTraceStr("Allowing anonymous connection for: %s.\n",
+ psTraceStr("Allowing anonymous connection for: %s.\n",
cert->subject.commonName);
}
return SSL_ALLOW_ANON_CONNECTION;
}
- _psTrace("ERROR: No matching CA found. Terminating connection\n");
+ psTrace("ERROR: No matching CA found. Terminating connection\n");
}
/* Check for "major" authentication problems within the server certificate
@@ -1406,7 +1767,7 @@ static int32 certCb(ssl_t *ssl, psX509Cert_t *cert, int32 alert)
{
if (next->authStatus == PS_CERT_AUTH_FAIL_SIG)
{
- _psTrace("Public key signature failure in server cert chain\n");
+ psTrace("Public key signature failure in server cert chain\n");
/* This should result in a BAD_CERTIFICATE alert */
alert = SSL_ALERT_BAD_CERTIFICATE;
break;
@@ -1414,7 +1775,7 @@ static int32 certCb(ssl_t *ssl, psX509Cert_t *cert, int32 alert)
if (next->authStatus == PS_CERT_AUTH_FAIL_DN)
{
/* A CA file was never located to support this chain */
- _psTrace("No CA file was found to support server's certificate\n");
+ psTrace("No CA file was found to support server's certificate\n");
/* This should result in a SSL_ALERT_UNKNOWN_CA alert */
alert = SSL_ALERT_UNKNOWN_CA;
break;
@@ -1422,7 +1783,7 @@ static int32 certCb(ssl_t *ssl, psX509Cert_t *cert, int32 alert)
if (next->authStatus == PS_CERT_AUTH_FAIL_AUTHKEY)
{
/* Subject and Issuer Key Id extension */
- _psTrace("Subject and Issuer Key Id mismatch error\n");
+ psTrace("Subject and Issuer Key Id mismatch error\n");
/* This should be a BAD_CERTIFICATE alert */
alert = SSL_ALERT_BAD_CERTIFICATE;
break;
@@ -1444,23 +1805,23 @@ static int32 certCb(ssl_t *ssl, psX509Cert_t *cert, int32 alert)
*/
if (alert == SSL_ALERT_CERTIFICATE_UNKNOWN)
{
- _psTraceStr("ERROR: %s not found in cert subject names\n",
+ psTraceStr("ERROR: %s not found in cert subject names\n",
ssl->expectedName);
}
if (alert == SSL_ALERT_CERTIFICATE_EXPIRED)
{
# ifdef POSIX
- _psTrace("ERROR: A cert did not fall within the notBefore/notAfter window\n");
+ psTrace("ERROR: A cert did not fall within the notBefore/notAfter window\n");
# else
- _psTrace("WARNING: Certificate date window validation not implemented\n");
+ psTrace("WARNING: Certificate date window validation not implemented\n");
alert = 0;
# endif
}
if (alert == SSL_ALERT_ILLEGAL_PARAMETER)
{
- _psTrace("ERROR: Found correct CA but X.509 extension details are wrong\n");
+ psTrace("ERROR: Found correct CA but X.509 extension details are wrong\n");
}
/* Key usage related problems on chain */
@@ -1470,11 +1831,11 @@ static int32 certCb(ssl_t *ssl, psX509Cert_t *cert, int32 alert)
{
if (next->authFailFlags & PS_CERT_AUTH_FAIL_KEY_USAGE_FLAG)
{
- _psTrace("CA keyUsage extension doesn't allow cert signing\n");
+ psTrace("CA keyUsage extension doesn't allow cert signing\n");
}
if (next->authFailFlags & PS_CERT_AUTH_FAIL_EKU_FLAG)
{
- _psTrace("Cert extendedKeyUsage extension doesn't allow TLS\n");
+ psTrace("Cert extendedKeyUsage extension doesn't allow TLS\n");
}
}
}
@@ -1483,7 +1844,7 @@ static int32 certCb(ssl_t *ssl, psX509Cert_t *cert, int32 alert)
{
/* Should never let a connection happen if this is set. There was
either a problem in the presented chain or in the final CA test */
- _psTrace("ERROR: Problem in certificate validation. Exiting.\n");
+ psTrace("ERROR: Problem in certificate validation. Exiting.\n");
}
@@ -1513,7 +1874,7 @@ RETRY_CRL_TEST_ONCE:
switch (next->revokedStatus)
{
case CRL_CHECK_CRL_EXPIRED:
- _psTrace("Have CRL but it is expired. Fetching new one\n");
+ psTrace("Have CRL but it is expired. Fetching new one\n");
/* Remove the CRL from the table */
expired = psCRL_GetCRLForCert(next);
if (expired)
@@ -1523,7 +1884,7 @@ RETRY_CRL_TEST_ONCE:
}
else
{
- _psTrace("Unexpected combo of expired but no CRL found\n");
+ psTrace("Unexpected combo of expired but no CRL found\n");
}
/* MOVING INTO CRL_CHECK_EXPECTED ON PURPOSE TO REFETCH */
case CRL_CHECK_EXPECTED:
@@ -1536,11 +1897,11 @@ RETRY_CRL_TEST_ONCE:
/* Only attempt this once so we don't get stuck in a loop */
if (retryOnce)
{
- _psTrace("Cert was not able to be tested against a CRL\n");
+ psTrace("Cert was not able to be tested against a CRL\n");
alert = SSL_ALERT_CERTIFICATE_UNKNOWN;
break;
}
- _psTrace("Cert expects CRL. Mid-handshake attempt being made\n");
+ psTrace("Cert expects CRL. Mid-handshake attempt being made\n");
/* This fetchParseAndAuthCRLfromCert will work on "next" as a chain
so it is correct that the server cert will look for the first
instance of CHECK_EXPECTED and pass that as the start of
@@ -1552,7 +1913,7 @@ RETRY_CRL_TEST_ONCE:
goto RETRY_CRL_TEST_ONCE;
# else /* MIDHANSHAKE_CRL_FETCH */
- _psTrace("Cert expects CRL. Failing handshake to go fetch it\n");
+ psTrace("Cert expects CRL. Failing handshake to go fetch it\n");
/* A more typical case if CRL testing is expected to be done is
to halt the handshake now, go out and fetch the CRLs and
try the connection again */
@@ -1566,45 +1927,44 @@ RETRY_CRL_TEST_ONCE:
possible */
if (count < CRL_MAX_SERVER_CERT_CHAIN)
{
- memset(g_crlDistURLs[count], 0, CRL_MAX_URL_LEN);
+ Memset(g_crlDistURLs[count], 0, CRL_MAX_URL_LEN);
psX509GetCRLdistURL(next, (char **) &url, &urlLen);
if (urlLen > CRL_MAX_URL_LEN)
{
- _psTraceInt("CLR URL distribution point longer than %d\n",
+ psTraceInt("CLR URL distribution point longer than %d\n",
CRL_MAX_URL_LEN);
}
else
{
- memcpy(g_crlDistURLs[count], url, urlLen);
+ Memcpy(g_crlDistURLs[count], url, urlLen);
count++;
}
}
else
{
- _psTraceInt("Server cert chain was longer than %d\n",
+ psTraceInt("Server cert chain was longer than %d\n",
CRL_MAX_SERVER_CERT_CHAIN);
}
break;
# endif /* MIDHANDSHAKE_CRL_FETCH */
- break;
case CRL_CHECK_NOT_EXPECTED:
- _psTrace("Cert didn't specify a CRL distribution point\n");
+ psTrace("Cert didn't specify a CRL distribution point\n");
break;
case CRL_CHECK_PASSED_AND_AUTHENTICATED:
- _psTrace("Cert passed CRL test and CRL was authenticated\n");
+ psTrace("Cert passed CRL test and CRL was authenticated\n");
break;
case CRL_CHECK_PASSED_BUT_NOT_AUTHENTICATED:
- _psTrace("Cert passed CRL test but CRL was not authenticated\n");
+ psTrace("Cert passed CRL test but CRL was not authenticated\n");
break;
case CRL_CHECK_REVOKED_AND_AUTHENTICATED:
- _psTrace("Cert was revoked by an authenticated CRL\n");
+ psTrace("Cert was revoked by an authenticated CRL\n");
alert = SSL_ALERT_CERTIFICATE_REVOKED;
break;
case CRL_CHECK_REVOKED_BUT_NOT_AUTHENTICATED:
- _psTrace("Cert was revoked but the CRL wasn't authenticated\n");
+ psTrace("Cert was revoked but the CRL wasn't authenticated\n");
alert = SSL_ALERT_CERTIFICATE_REVOKED;
break;
default:
@@ -1616,7 +1976,7 @@ RETRY_CRL_TEST_ONCE:
if (g_trace && alert == 0 && cert)
{
- _psTraceStr("SUCCESS: Validated cert for: %s.\n", cert->subject.commonName);
+ psTraceStr("SUCCESS: Validated cert for: %s.\n", cert->subject.commonName);
}
# endif /* !USE_ONLY_PSK_CIPHER_SUITE */
@@ -1642,8 +2002,8 @@ static void fetchSavedCRL(psX509Cert_t *potentialIssuers)
i++)
{
fetchParseAndAuthCRLfromUrl(NULL, g_crlDistURLs[i],
- strlen((char *) g_crlDistURLs[i]), potentialIssuers);
- memset(g_crlDistURLs[i], 0, CRL_MAX_URL_LEN);
+ Strlen((char *) g_crlDistURLs[i]), potentialIssuers);
+ Memset(g_crlDistURLs[i], 0, CRL_MAX_URL_LEN);
}
}
@@ -1664,13 +2024,13 @@ static int32_t fetchParseAndAuthCRLfromUrl(psPool_t *pool, unsigned char *url,
/* url need not be freed. It points into cert structure */
if (fetchCRL(NULL, (char *) url, urlLen, &crlBuf, &crlBufLen) < 0)
{
- _psTrace("Unable to fetch CRL\n");
+ psTrace("Unable to fetch CRL\n");
return -1;
}
/* Convert the CRL stream into our structure */
if (psX509ParseCRL(pool, &crl, crlBuf, crlBufLen) < 0)
{
- _psTrace("Unable to parse CRL\n");
+ psTrace("Unable to parse CRL\n");
psFree(crlBuf, pool);
return -1;
}
@@ -1689,7 +2049,7 @@ static int32_t fetchParseAndAuthCRLfromUrl(psPool_t *pool, unsigned char *url,
{
if (psX509AuthenticateCRL(ic, crl, NULL) >= 0)
{
- _psTrace("NOTE: Able to authenticate CRL\n");
+ psTrace("NOTE: Able to authenticate CRL\n");
break; /* Stop looking */
}
}
@@ -1723,14 +2083,14 @@ static int32_t fetchParseAndAuthCRLfromCert(psPool_t *pool, psX509Cert_t *cert,
/* url need not be freed. It points into cert structure */
if (fetchCRL(NULL, url, urlLen, &crlBuf, &crlBufLen) < 0)
{
- _psTrace("Unable to fetch CRL\n");
+ psTrace("Unable to fetch CRL\n");
sc = sc->next;
continue;
}
/* Convert the CRL stream into our structure */
if (psX509ParseCRL(pool, &crl, crlBuf, crlBufLen) < 0)
{
- _psTrace("Unable to parse CRL\n");
+ psTrace("Unable to parse CRL\n");
psFree(crlBuf, pool);
sc = sc->next;
continue;
@@ -1751,7 +2111,7 @@ static int32_t fetchParseAndAuthCRLfromCert(psPool_t *pool, psX509Cert_t *cert,
{
if (psX509AuthenticateCRL(ic, crl, NULL) >= 0)
{
- _psTrace("NOTE: Able to authenticate CRL\n");
+ psTrace("NOTE: Able to authenticate CRL\n");
break; /* Stop looking */
}
}
@@ -1771,7 +2131,7 @@ static int32_t fetchParseAndAuthCRLfromCert(psPool_t *pool, psX509Cert_t *cert,
{
if (psX509AuthenticateCRL(ic, crl, NULL) >= 0)
{
- _psTrace("NOTE: Able to authenticate CRL\n");
+ psTrace("NOTE: Able to authenticate CRL\n");
break; /* Stop looking */
}
}
@@ -1784,7 +2144,7 @@ static int32_t fetchParseAndAuthCRLfromCert(psPool_t *pool, psX509Cert_t *cert,
}
sc = sc->next;
}
- _psTraceInt("CRLs loaded: %d\n", numLoaded);
+ psTraceInt("CRLs loaded: %d\n", numLoaded);
return PS_SUCCESS;
}
@@ -1804,7 +2164,7 @@ __inline static size_t ptrdiff_safe(const void *end, const void *start, size_t s
{
return 0;
}
- d = end - start;
+ d = (const unsigned char *)end - (const unsigned char *)start;
if (d > sanity)
{
return sanity;
@@ -1839,7 +2199,8 @@ int32 fetchCRL(psPool_t *pool, char *url, uint32_t urlLen,
SOCKET fd;
struct hostent *ip;
struct in_addr intaddr;
- char *pageStart, *replyPtr, *ipAddr;
+ char *pageStart, *ipAddr;
+ const char *replyPtr;
char hostAddr[HOST_ADDR_LEN], getReq[GET_REQ_LEN];
int hostAddrLen, getReqLen, pageLen;
ssize_t transferred;
@@ -1850,11 +2211,11 @@ int32 fetchCRL(psPool_t *pool, char *url, uint32_t urlLen,
uint32_t crlBinLen;
/* Is URI in expected URL form? */
- if (strstr(url, "http://") == NULL)
+ if (Strstr(url, "http://") == NULL)
{
- if (strstr(url, "https://") == NULL)
+ if (Strstr(url, "https://") == NULL)
{
- _psTraceStr("fetchCRL: Unsupported CRL URI: %s\n", url);
+ psTraceStr("fetchCRL: Unsupported CRL URI: %s\n", url);
return -1;
}
httpUriLen = 8;
@@ -1867,30 +2228,30 @@ int32 fetchCRL(psPool_t *pool, char *url, uint32_t urlLen,
}
/* Parsing host and page and setting up IP address and GET request */
- if ((pageStart = strchr(url + httpUriLen, '/')) == NULL)
+ if ((pageStart = Strchr(url + httpUriLen, '/')) == NULL)
{
- _psTrace("fetchCRL: No host/page divider found\n");
+ psTrace("fetchCRL: No host/page divider found\n");
return -1;
}
if ((hostAddrLen = (int) (pageStart - url) - httpUriLen) > HOST_ADDR_LEN)
{
- _psTrace("fetchCRL: HOST_ADDR_LEN needs to be increased\n");
+ psTrace("fetchCRL: HOST_ADDR_LEN needs to be increased\n");
return -1; /* ipAddr too small to hold */
}
- memset(hostAddr, 0, HOST_ADDR_LEN);
- memcpy(hostAddr, url + httpUriLen, hostAddrLen);
+ Memset(hostAddr, 0, HOST_ADDR_LEN);
+ Memcpy(hostAddr, url + httpUriLen, hostAddrLen);
if ((ip = gethostbyname(hostAddr)) == NULL)
{
- _psTrace("fetchCRL: gethostbyname failed\n");
+ psTrace("fetchCRL: gethostbyname failed\n");
return -1;
}
- memcpy((char *) &intaddr, (char *) ip->h_addr_list[0],
+ Memcpy((char *) &intaddr, (char *) ip->h_addr_list[0],
(size_t) ip->h_length);
if ((ipAddr = inet_ntoa(intaddr)) == NULL)
{
- _psTrace("fetchCRL: inet_ntoa failed\n");
+ psTrace("fetchCRL: inet_ntoa failed\n");
return -1;
}
@@ -1899,7 +2260,7 @@ int32 fetchCRL(psPool_t *pool, char *url, uint32_t urlLen,
HOST_OH_LEN + ACCEPT_OH_LEN;
if (getReqLen > GET_REQ_LEN)
{
- _psTrace("fetchCRL: GET_REQ_LEN needs to be increased\n");
+ psTrace("fetchCRL: GET_REQ_LEN needs to be increased\n");
return -1;
}
@@ -1909,24 +2270,24 @@ int32 fetchCRL(psPool_t *pool, char *url, uint32_t urlLen,
/* Host: www.host.com */
/* Accept: * / * */
/* */
- memset(getReq, 0, GET_REQ_LEN);
- memcpy(getReq, crl_getHdr, GET_OH_LEN);
+ Memset(getReq, 0, GET_REQ_LEN);
+ Memcpy(getReq, crl_getHdr, GET_OH_LEN);
offset = GET_OH_LEN;
- memcpy(getReq + offset, pageStart, pageLen);
+ Memcpy(getReq + offset, pageStart, pageLen);
offset += pageLen;
- memcpy(getReq + offset, crl_httpHdr, HTTP_OH_LEN);
+ Memcpy(getReq + offset, crl_httpHdr, HTTP_OH_LEN);
offset += HTTP_OH_LEN;
- memcpy(getReq + offset, crl_hostHdr, HOST_OH_LEN);
+ Memcpy(getReq + offset, crl_hostHdr, HOST_OH_LEN);
offset += HOST_OH_LEN;
- memcpy(getReq + offset, hostAddr, hostAddrLen);
+ Memcpy(getReq + offset, hostAddr, hostAddrLen);
offset += hostAddrLen;
- memcpy(getReq + offset, crl_acceptHdr, ACCEPT_OH_LEN);
+ Memcpy(getReq + offset, crl_acceptHdr, ACCEPT_OH_LEN);
/* Connect and send */
fd = lsocketConnect(ipAddr, port, &err);
if (fd == INVALID_SOCKET || err != PS_SUCCESS)
{
- _psTraceInt("fetchCRL: socketConnect failed: %d\n", err);
+ psTraceInt("fetchCRL: socketConnect failed: %d\n", err);
return PS_PLATFORM_FAIL;
}
@@ -1936,7 +2297,7 @@ int32 fetchCRL(psPool_t *pool, char *url, uint32_t urlLen,
{
if ((transferred = send(fd, getReq + offset, getReqLen, 0)) < 0)
{
- _psTraceInt("fetchCRL: socket send failed: %d\n", errno);
+ psTraceInt("fetchCRL: socket send failed: %d\n", errno);
close(fd);
return PS_PLATFORM_FAIL;
}
@@ -1963,17 +2324,17 @@ int32 fetchCRL(psPool_t *pool, char *url, uint32_t urlLen,
recevied in the first call */
while ((transferred = recv(fd, crlChunk, HTTP_REPLY_CHUNK_SIZE, 0)) > 0)
{
- crlChunk[transferred] = 0; /* Ensure zero termination for strstr(). */
+ crlChunk[transferred] = 0; /* Ensure zero termination for Strstr(). */
if (crlBin == NULL)
{
/* Still getting the details of the HTTP response */
/* Did we get an OK response? */
if (sawOK == 0)
{
- if (strstr((const char *) crlChunk, "200 OK") == NULL)
+ if (Strstr((const char *) crlChunk, "200 OK") == NULL)
{
/* First chunk. Should be plenty large enough to hold */
- _psTrace("fetchCRL: server reply was not '200 OK'\n");
+ psTrace("fetchCRL: server reply was not '200 OK'\n");
close(fd);
return -1;
}
@@ -1982,13 +2343,13 @@ int32 fetchCRL(psPool_t *pool, char *url, uint32_t urlLen,
/* Length parse */
if (sawContentLength == 0)
{
- if ((replyPtr = strstr((const char *) crlChunk,
+ if ((replyPtr = Strstr((const char *) crlChunk,
"Content-Length: ")) == NULL)
{
/* Apparently Content-Length is not always going to be
there. See if we have the end of the header instead */
- if ((replyPtr = strstr((const char *) crlChunk, "\r\n\r\n"))
+ if ((replyPtr = Strstr((const char *) crlChunk, "\r\n\r\n"))
== NULL)
{
continue; /* saw neither. keep trying */
@@ -2019,7 +2380,7 @@ int32 fetchCRL(psPool_t *pool, char *url, uint32_t urlLen,
/* Data begins after CRLF CRLF */
- if ((replyPtr = strstr((const char *) crlChunk, "\r\n\r\n"))
+ if ((replyPtr = Strstr((const char *) crlChunk, "\r\n\r\n"))
== NULL)
{
continue;
@@ -2035,7 +2396,7 @@ int32 fetchCRL(psPool_t *pool, char *url, uint32_t urlLen,
/* Check buffer length appears acceptable */
if (crlBinLen < 1 || crlBinLen > CRL_MAX_LENGTH)
{
- _psTrace("fetchCRL: Unacceptable size for CRL\n");
+ psTrace("fetchCRL: Unacceptable size for CRL\n");
/* Note: If this fails you may need to check CRL_MAX_LENGTH,
as you possibly need to allow larger CRL. */
close(fd);
@@ -2043,9 +2404,9 @@ int32 fetchCRL(psPool_t *pool, char *url, uint32_t urlLen,
}
/* Allocate the CRL buffer. Will be full size if sawContentLength */
- if ((crlBin = psMalloc(pool, crlBinLen)) == NULL)
+ if ((crlBin = (unsigned char *)psMalloc(pool, crlBinLen)) == NULL)
{
- _psTrace("fetchCRL: Memory allocation error for CRL buffer\n");
+ psTrace("fetchCRL: Memory allocation error for CRL buffer\n");
close(fd);
return -1;
}
@@ -2058,7 +2419,7 @@ int32 fetchCRL(psPool_t *pool, char *url, uint32_t urlLen,
/* Will march crlBin forward so just assign output crlBuf now */
*crlBuf = crlBin;
*crlBufLen = crlBinLen;
- memcpy(crlBin, replyPtr, transferred);
+ Memcpy(crlBin, replyPtr, transferred);
crlBin += transferred;
psAssert((crlBin - *crlBuf) <= crlBinLen);
}
@@ -2067,7 +2428,7 @@ int32 fetchCRL(psPool_t *pool, char *url, uint32_t urlLen,
grown = 1;
/* Keep track of index to monitor size */
crlBinLen = transferred;
- memcpy(crlBin, replyPtr, transferred);
+ Memcpy(crlBin, replyPtr, transferred);
}
}
else
@@ -2075,7 +2436,7 @@ int32 fetchCRL(psPool_t *pool, char *url, uint32_t urlLen,
/* subsequent recv calls */
if (sawContentLength)
{
- memcpy(crlBin, crlChunk, transferred);
+ Memcpy(crlBin, crlChunk, transferred);
crlBin += transferred;
psAssert((crlBin - *crlBuf) <= crlBinLen);
}
@@ -2085,10 +2446,10 @@ int32 fetchCRL(psPool_t *pool, char *url, uint32_t urlLen,
{
/* not enough room. psRealloc */
grown++;
- crlBin = psRealloc(crlBin, HTTP_REPLY_CHUNK_SIZE * grown,
- pool);
+ crlBin = (unsigned char*)psRealloc(
+ crlBin, HTTP_REPLY_CHUNK_SIZE * grown, pool);
}
- memcpy(crlBin + crlBinLen, crlChunk, transferred);
+ Memcpy(crlBin + crlBinLen, crlChunk, transferred);
crlBinLen += transferred;
}
}
@@ -2123,10 +2484,10 @@ static SOCKET lsocketConnect(char *ip, int32 port, int32 *err)
int32 rc;
/* By default, this will produce a blocking socket */
- if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
+ if ((fd = Socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
- perror("socket()");
- _psTrace("Error creating socket\n");
+ perror("Socket()");
+ psTrace("Error creating socket\n");
*err = SOCKET_ERRNO;
return INVALID_SOCKET;
}
@@ -2148,22 +2509,22 @@ static SOCKET lsocketConnect(char *ip, int32 port, int32 *err)
{
uint32 len;
getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rc, &len);
- printf("SO_RCVBUF: %d\n", rc);
+ Printf("SO_RCVBUF: %d\n", rc);
}
# endif
# ifdef __APPLE__ /* MAC OS X */
rc = 1;
setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (void *) &rc, sizeof(rc));
# endif
- memset((char *) &addr, 0x0, sizeof(addr));
+ Memset((char *) &addr, 0x0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons((short) port);
addr.sin_addr.s_addr = inet_addr(ip);
- rc = connect(fd, (struct sockaddr *) &addr, sizeof(addr));
+ rc = Connect(fd, (struct sockaddr *) &addr, sizeof(addr));
if (rc < 0)
{
close(fd);
- perror("connect()");
+ perror("Connect()");
*err = SOCKET_ERRNO;
}
else
@@ -2172,6 +2533,55 @@ static SOCKET lsocketConnect(char *ip, int32 port, int32 *err)
}
return fd;
}
+
+# ifdef USE_TLS_1_3
+static int32_t sendEarlyData(ssl_t *ssl)
+{
+ FILE *fp = NULL;
+ unsigned char *earlyDataBuf;
+ int32_t earlyDataBufLen, earlyDataLen, maxEarlyData, encodedEarlyDataLen;
+
+ fp = Fopen(g_early_data_file, "r");
+ if (!fp)
+ {
+ psTrace("Failed to open early data file\n");
+ return PS_ARG_FAIL;
+ }
+ /* It is the caller's resposibility to keep track that not too much
+ early data is being sent. Data can be sent in multiple records. */
+ maxEarlyData = matrixSslGetMaxEarlyData(ssl);
+
+ /* Get writebuf for maximum early data length */
+ earlyDataBufLen = matrixSslGetWritebuf(ssl, &earlyDataBuf, maxEarlyData);
+ if (earlyDataBufLen <= 0)
+ {
+ Fclose(fp);
+ return PS_FAILURE;
+ }
+ /* Send only as many bytes as the received write buffer can fit. It might
+ be less than requested size in case the fragment size is small */
+ maxEarlyData = earlyDataBufLen;
+ earlyDataLen = Fread(earlyDataBuf, 1, maxEarlyData, fp);
+ if (earlyDataLen <= 0)
+ {
+ Fclose(fp);
+ return PS_FAILURE;
+ }
+ Fclose(fp);
+ encodedEarlyDataLen = matrixSslEncodeWritebuf(ssl, earlyDataLen);
+ if (encodedEarlyDataLen <= 0)
+ {
+ return PS_FAILURE;
+ }
+ if (matrixSslGetEarlyDataStatus(ssl) != MATRIXSSL_EARLY_DATA_SENT)
+ {
+ psTrace("Unexpected early data status. Exiting\n");
+ return PS_FAILURE;
+ }
+ return MATRIXSSL_SUCCESS;
+}
+# endif /* USE_TLS_1_3 */
+
#else
/******************************************************************************/
@@ -2180,11 +2590,10 @@ static SOCKET lsocketConnect(char *ip, int32 port, int32 *err)
*/
int32 main(int32 argc, char **argv)
{
- printf("USE_CLIENT_SIDE_SSL must be enabled in matrixsslConfig.h at build" \
+ Printf("USE_CLIENT_SIDE_SSL must be enabled in matrixsslConfig.h at build" \
" time to run this application\n");
return EXIT_FAILURE;
}
#endif /* USE_CLIENT_SIDE_SSL */
/******************************************************************************/
-
diff --git a/apps/ssl/http.c b/apps/ssl/http.c
index 7823b93..77130ea 100644
--- a/apps/ssl/http.c
+++ b/apps/ssl/http.c
@@ -33,8 +33,6 @@
/******************************************************************************/
#include "app.h"
-/* Currently this example uses _psTrace for tracing, so osdep.h is needed: */
-#include "core/osdep.h"
#include "core/psUtil.h"
/* #define TEST */
@@ -84,8 +82,9 @@ int32 httpBasicParse(httpConn_t *cp, unsigned char *buf, uint32 len,
{
return HTTPS_ERROR;
}
- cp->parsebuf = realloc(cp->parsebuf, l + cp->parsebuflen);
- memcpy(cp->parsebuf + cp->parsebuflen, tmp, l);
+ cp->parsebuf = (unsigned char *)Realloc(cp->parsebuf,
+ l + cp->parsebuflen);
+ Memcpy(cp->parsebuf + cp->parsebuflen, tmp, l);
cp->parsebuflen += l;
/* Parse the data out of the saved buffer first */
c = cp->parsebuf;
@@ -111,21 +110,21 @@ L_PARSE_LINE:
{
/*
if ((c + 1) != end) {
- _psTrace("HTTP data parsing not supported, ignoring.\n");
+ psTrace("HTTP data parsing not supported, ignoring.\n");
}
*/
if (cp->parsebuf != NULL)
{
- free(cp->parsebuf); cp->parsebuf = NULL;
+ Free(cp->parsebuf); cp->parsebuf = NULL;
cp->parsebuflen = 0;
if (len != 0)
{
- _psTrace("HTTP data parsing not supported, ignoring.\n");
+ psTrace("HTTP data parsing not supported, ignoring.\n");
}
}
if (trace)
{
- _psTrace("RECV COMPLETE HTTP MESSAGE\n");
+ psTrace("RECV COMPLETE HTTP MESSAGE\n");
}
return HTTPS_COMPLETE;
}
@@ -136,21 +135,21 @@ L_PARSE_LINE:
if (cp->parsebuf == NULL && (l = (int32) (end - tmp)) > 0)
{
cp->parsebuflen = l;
- cp->parsebuf = malloc(cp->parsebuflen);
+ cp->parsebuf = (unsigned char *)Malloc(cp->parsebuflen);
psAssert(cp->parsebuf != NULL);
- memcpy(cp->parsebuf, tmp, cp->parsebuflen);
+ Memcpy(cp->parsebuf, tmp, cp->parsebuflen);
}
return HTTPS_PARTIAL;
}
*(c - 1) = '\0'; /* Replace \r with \0 just for printing */
if (trace)
{
- _psTraceStr("RECV PARSED: [%s]\n", (char *) tmp);
+ psTraceStr("RECV PARSED: [%s]\n", (char *) tmp);
}
/* Finished parsing the saved buffer, now start parsing from incoming buf */
if (cp->parsebuf != NULL)
{
- free(cp->parsebuf); cp->parsebuf = NULL;
+ Free(cp->parsebuf); cp->parsebuf = NULL;
cp->parsebuflen = 0;
c = buf;
end = c + len;
@@ -161,7 +160,7 @@ L_PARSE_LINE:
}
goto L_PARSE_LINE;
- return HTTPS_ERROR;
+ /* This line if unreachable. */
}
/******************************************************************************/
diff --git a/apps/ssl/net.c b/apps/ssl/net.c
index 6c3e899..fad32d1 100644
--- a/apps/ssl/net.c
+++ b/apps/ssl/net.c
@@ -6,18 +6,32 @@
/*****************************************************************************
* Copyright (c) 2017 INSIDE Secure Oy. All Rights Reserved.
*
-* This confidential and proprietary software may be used only as authorized
-* by a licensing agreement from INSIDE Secure.
+* The latest version of this code is available at http://www.matrixssl.org
*
-* The entire notice above must be reproduced on all authorized copies that
-* may only be made to the extent permitted by a licensing agreement from
-* INSIDE Secure.
+* This software is open source; 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.
+*
+* This General Public License does NOT permit incorporating this software
+* into proprietary programs. If you are unable to comply with the GPL, a
+* commercial license for this software may be purchased from INSIDE at
+* http://www.insidesecure.com/
+*
+* This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+* http://www.gnu.org/copyleft/gpl.html
*****************************************************************************/
-#include
-#include
-#include
-#include
+#include "osdep_stdio.h"
+#include "osdep_stdlib.h"
+#include "osdep_string.h"
+#include "osdep_unistd.h"
#include "core/coreApi.h"
#include "matrixssl/matrixsslApi.h"
#include "matrixssl/matrixsslNet.h"
@@ -29,7 +43,7 @@
#define USE_MATRIX_NET_DEBUG
#undef DEBUGF /* Protect against possible multiple definition. */
#ifdef USE_MATRIX_NET_DEBUG
-# define DEBUGF(...) printf(__VA_ARGS__)
+# define DEBUGF(...) Printf(__VA_ARGS__)
#else
# define DEBUGF(...) do {} while (0)
#endif
@@ -40,6 +54,7 @@
# define FLAG_TLS_1_0 (1 << 10)
# define FLAG_TLS_1_1 (1 << 11)
# define FLAG_TLS_1_2 (1 << 12)
+# define FLAG_TLS_1_3 (1 << 13)
/* Highlight text from peer. */
static char start_remote_text[] = "\033[1m";
@@ -50,16 +65,16 @@ static uint16_t g_cipher[] = { 47 };
# define HTTP_BUFFER_SIZE (1024 * 1024)
-# define logMessage(l, t, ...) do { printf(#l " " #t ": " __VA_ARGS__); printf("\n"); } while (0) /* Log_Verbose, TAG, "Wrote %d bytes", transferred */
+# define logMessage(l, t, ...) do { Printf(#l " " #t ": " __VA_ARGS__); Printf("\n"); } while (0) /* Log_Verbose, TAG, "Wrote %d bytes", transferred */
static int usage(FILE *out, const char *program)
{
- fprintf(out, "usage: %s [options]\n", program);
- fprintf(out, "Where options may include: ");
- fprintf(out, "\t--help (-h) Get this usage\n");
- fprintf(out, "\t--host hostname Specify host or address\n");
- fprintf(out, "\t--port port Specify target port\n");
- fprintf(out, "\t--get http://url/ Get URL (supports HTTP protocol)\n");
+ Fprintf(out, "usage: %s [options]\n", program);
+ Fprintf(out, "Where options may include: ");
+ Fprintf(out, "\t--help (-h) Get this usage\n");
+ Fprintf(out, "\t--host hostname Specify host or address\n");
+ Fprintf(out, "\t--port port Specify target port\n");
+ Fprintf(out, "\t--get http://url/ Get URL (supports HTTP protocol)\n");
return 0;
}
@@ -76,7 +91,7 @@ int option(int *argc_p, char ***argv_p, const char *opt, char **target)
return 0; /* No space for argument with string. */
}
- if (strcmp((*argv_p)[1], opt) == 0)
+ if (Strcmp((*argv_p)[1], opt) == 0)
{
(*argc_p) -= 1;
(*argv_p)[1] = (*argv_p)[0];
@@ -129,7 +144,7 @@ static int32 getHTTPResponse(const char *url,
int do_get(const char *url, psSocketType_t type,
const char *capath, int tls_version)
{
- void *buf = malloc(HTTP_BUFFER_SIZE);
+ void *buf = Malloc(HTTP_BUFFER_SIZE);
size_t bufsz = HTTP_BUFFER_SIZE;
int32 res;
struct psSocketTls tls = { capath, tls_version };
@@ -147,7 +162,7 @@ int do_get(const char *url, psSocketType_t type,
if (!buf)
{
- fprintf(stderr, "Unable to allocate buffer %d bytes\n",
+ Fprintf(stderr, "Unable to allocate buffer %d bytes\n",
HTTP_BUFFER_SIZE);
return 2;
}
@@ -155,24 +170,24 @@ int do_get(const char *url, psSocketType_t type,
res = getHTTPResponse(url, buf, &bufsz, type, typespecific, func);
if (res == PS_INSECURE_PROTOCOL)
{
- fprintf(stderr, "Do not try to use capath or tls version with http protocol\n");
- fprintf(stderr, "these are for https protocol.\n");
+ Fprintf(stderr, "Do not try to use capath or tls version with http protocol\n");
+ Fprintf(stderr, "these are for https protocol.\n");
exit(1);
}
else if (res < 0)
{
/* Connection error. */
- fprintf(stderr, "Connect error: %d\n", res);
+ Fprintf(stderr, "Connect error: %d\n", res);
}
else if (res != 0)
{
/* HTTP error. */
- fprintf(stderr, "HTTP return code: %d\n", res);
+ Fprintf(stderr, "HTTP return code: %d\n", res);
}
else if (res == 0)
{
/* Write output (HTTP code 200 OK). */
- fwrite(buf, bufsz, 1, stdout);
+ Fwrite(buf, bufsz, 1, stdout);
}
return res >= 0 ? 0 : 1;
}
@@ -197,27 +212,27 @@ int do_dialog(psSocket_t *sock)
FD_ZERO(&fds);
FD_SET(STDIN_FILENO, &fds);
FD_SET(sockfd, &fds);
- select(sockfd + 1, &fds, NULL, NULL, NULL);
+ Select(sockfd + 1, &fds, NULL, NULL, NULL);
DEBUGF("an fd ready: stdin: %d sock_read: %d\n",
FD_ISSET(STDIN_FILENO, &fds),
FD_ISSET(sockfd, &fds));
if (count++ == 100000)
{
- printf("Finished\n");
+ Printf("Finished\n");
return 1;
}
buf.buf = buf.start = buf.end = ch1024;
buf.size = (uint32) sizeof(ch1024);
rc = psSocketReadAppendBuf(sock, &buf, PS_SOCKET_OPTION_NONBLOCK);
- printf("Got SOCK bytes: %d\n", rc);
+ Printf("Got SOCK bytes: %d\n", rc);
if (rc == 0)
{
- printf("Peer disconnected\n");
+ Printf("Peer disconnected\n");
return 0;
}
else if (rc > 0)
{
- printf("%s%.*s%s",
+ Printf("%s%.*s%s",
start_remote_text,
(int) (buf.end - buf.start),
(const char *) buf.start,
@@ -231,10 +246,10 @@ int do_dialog(psSocket_t *sock)
buf.size = (uint32) sizeof(ch1024);
rc = psSocketReadAppendBuf(STDIN_FILENO, &buf2,
PS_SOCKET_OPTION_NONBLOCK);
- printf("Got STDIN bytes: %d\n", rc);
+ Printf("Got STDIN bytes: %d\n", rc);
if (rc == 0)
{
- printf("Quit from keyboard\n");
+ Printf("Quit from keyboard\n");
return 0;
}
/* Copy input to send buffer. */
@@ -252,13 +267,13 @@ int do_dialog(psSocket_t *sock)
if (psSocketWriteShiftBuf(sock, &buf, 0) < 1)
{
- fprintf(stderr, "Connection error\n");
+ Fprintf(stderr, "Connection error\n");
return 1;
}
}
}
while (1);
- return rc;
+ /* Above loop newer breaks. */
}
int do_dialog_matrixssl(matrixSslInteract_t *msi_p)
@@ -283,14 +298,14 @@ int do_dialog_matrixssl(matrixSslInteract_t *msi_p)
FD_SET(STDIN_FILENO, &fds);
FD_SET(STDIN_FILENO, &except_fds);
FD_SET(sockfd, &fds);
- select(sockfd + 1, &fds, NULL, NULL, NULL);
+ Select(sockfd + 1, &fds, NULL, NULL, NULL);
DEBUGF("an fd ready stdin: %d sock_read: %d\n",
FD_ISSET(STDIN_FILENO, &fds),
FD_ISSET(sockfd, &fds));
if (count++ == 2000000000)
{
- printf("Finished\n");
+ Printf("Finished\n");
return 1;
}
buf.buf = buf.start = buf.end = ch1024;
@@ -301,24 +316,24 @@ int do_dialog_matrixssl(matrixSslInteract_t *msi_p)
alert_handler:
if (msi_p->ch2[0] == 1 && msi_p->ch2[1] == 0)
{
- printf("Peer terminated connection.\n");
+ Printf("Peer terminated connection.\n");
psSocketShutdown(sock, 0);
matrixSslInteractClose(msi_p);
return 0;
}
- fprintf(stderr, "Got alert: level=%d desc=%d\n",
+ Fprintf(stderr, "Got alert: level=%d desc=%d\n",
(int) msi_p->ch2[0], (int) msi_p->ch2[1]);
return 1;
}
if (rc == MATRIXSSL_NET_DISCONNECTED)
{
- fprintf(stderr, "The peer has disconnected\n");
+ Fprintf(stderr, "The peer has disconnected\n");
exit(0);
}
if (rc < 0)
{
- fprintf(stderr, "matrixSslInteract error: %d\n",
+ Fprintf(stderr, "matrixSslInteract error: %d\n",
(int) rc);
exit(1);
}
@@ -331,14 +346,14 @@ again_read:
buf.buf + buf.size - buf.end);
if (rc < 0)
{
- fprintf(stderr, "Read error: rc=%d\n", rc);
+ Fprintf(stderr, "Read error: rc=%d\n", rc);
return 1;
}
DEBUGF("Interact read gave %d\n", (int) rc);
- printf("%s", start_remote_text);
- printf("%.*s", (int) (rc), (const char *) buf.start);
- printf("%s", end_remote_text);
- fflush(stdout);
+ Printf("%s", start_remote_text);
+ Printf("%.*s", (int) (rc), (const char *) buf.start);
+ Printf("%s", end_remote_text);
+ Fflush(stdout);
}
psSocketSetOptions(sock, PS_SOCKET_OPTION_BLOCK);
@@ -363,7 +378,7 @@ again_read:
}
if (rc == 0)
{
- printf("Quit from keyboard\n");
+ Printf("Quit from keyboard\n");
return 0;
}
/* Copy input to send buffer. */
@@ -388,7 +403,7 @@ again_read:
buf.start,
buf.end - buf.start) < 0)
{
- fprintf(stderr, "Connection error\n");
+ Fprintf(stderr, "Connection error\n");
return 1;
}
/* Mark the buffer as handled. */
@@ -409,12 +424,12 @@ no_kbd_input:
}
if (rc == MATRIXSSL_NET_DISCONNECTED)
{
- fprintf(stderr, "The peer has disconnected\n");
+ Fprintf(stderr, "The peer has disconnected\n");
exit(0);
}
}
while (1);
- return rc;
+ /* Above loop never breaks. */
}
int do_dialog_client(const char *host, const char *port)
@@ -425,10 +440,10 @@ int do_dialog_client(const char *host, const char *port)
rc = psSocketConnect(host, port, 0, PS_SOCKET_STREAM, NULL, NULL, &sock);
if (rc == PS_SUCCESS)
{
- printf("Connected to %s:%s\n", host, port);
+ Printf("Connected to %s:%s\n", host, port);
return do_dialog(sock);
}
- printf("Unable to connect\n");
+ Printf("Unable to connect\n");
return 2;
}
@@ -469,7 +484,7 @@ int32 do_tls_handshake(matrixSslInteract_t *msi_p, int32 rc)
DEBUGF("wait for data from peer\n");
FD_ZERO(&fds);
FD_SET(sockfd, &fds);
- select(sockfd + 1, &fds, NULL, NULL, NULL);
+ Select(sockfd + 1, &fds, NULL, NULL, NULL);
}
else if (rc == MATRIXSSL_REQUEST_SEND ||
msi_p->send_len_left > 0)
@@ -477,7 +492,7 @@ int32 do_tls_handshake(matrixSslInteract_t *msi_p, int32 rc)
DEBUGF("wait for sending data to peer\n");
FD_ZERO(&fds);
FD_SET(sockfd, &fds);
- select(sockfd + 1, NULL, &fds, NULL, NULL);
+ Select(sockfd + 1, NULL, &fds, NULL, NULL);
}
/* if (rc != 0) */
DEBUGF("hs rc code: %d\n", rc);
@@ -509,6 +524,10 @@ static void set_tls_options_version(sslSessOpts_t *options_p, int tls)
{
options_p->versionFlag |= SSL_FLAGS_TLS_1_2;
}
+ if ((tls & FLAG_TLS_1_3) || tls == 0)
+ {
+ options_p->versionFlag |= SSL_FLAGS_TLS_1_3_DRAFT_23;
+ }
}
# ifdef USE_CLIENT_SIDE_SSL
@@ -524,24 +543,24 @@ int do_dialog_client_tls(const char *host, const char *port,
unsigned char *ext = NULL;
int32 extLen;
- memset(&options, 0x0, sizeof(sslSessOpts_t));
+ Memset(&options, 0x0, sizeof(sslSessOpts_t));
set_tls_options_version(&options, tls);
if (matrixSslOpen() < 0)
{
- fprintf(stderr, "Error initializing MatrixSSL\n");
+ Fprintf(stderr, "Error initializing MatrixSSL\n");
return 3;
}
if (matrixSslNewKeys(&keys, NULL) < 0)
{
- fprintf(stderr, "Error initializing MatrixSSL: "
+ Fprintf(stderr, "Error initializing MatrixSSL: "
"matrixSslNewKeys error\n");
return 3;
}
if (matrixSslNewSessionId(&sid, NULL) < 0)
{
- fprintf(stderr, "Error initializing MatrixSSL: "
+ Fprintf(stderr, "Error initializing MatrixSSL: "
"matrixSslNewSessionId error\n");
return 3;
}
@@ -559,7 +578,7 @@ int do_dialog_client_tls(const char *host, const char *port,
# endif
if (rc != PS_SUCCESS)
{
- fprintf(stderr, "No certificate material loaded.\n");
+ Fprintf(stderr, "No certificate material loaded.\n");
matrixSslDeleteSessionId(sid);
matrixSslDeleteKeys(keys);
matrixSslClose();
@@ -568,7 +587,7 @@ int do_dialog_client_tls(const char *host, const char *port,
}
matrixSslNewHelloExtension(&extension, NULL);
- matrixSslCreateSNIext(NULL, (unsigned char *) host, (uint32) strlen(host),
+ matrixSslCreateSNIext(NULL, (unsigned char *) host, (uint32) Strlen(host),
&ext, &extLen);
if (ext)
{
@@ -587,19 +606,19 @@ int do_dialog_client_tls(const char *host, const char *port,
if (rc >= PS_SUCCESS)
{
/* Interact until connected. */
- printf("Connected to %s:%s (using TLS)\n", host, port);
+ Printf("Connected to %s:%s (using TLS)\n", host, port);
rc = do_tls_handshake(&msi, rc);
if (rc == MATRIXSSL_REQUEST_CLOSE)
{
- printf("Connection close requested.\n");
+ Printf("Connection close requested.\n");
exit(1);
}
if (rc != PS_SUCCESS)
{
- printf("Handshake failure: %d\n", rc);
+ Printf("Handshake failure: %d\n", rc);
exit(1);
}
- printf("Successful handshake\n");
+ Printf("Successful handshake\n");
rc = do_dialog_matrixssl(&msi);
@@ -608,10 +627,10 @@ int do_dialog_client_tls(const char *host, const char *port,
matrixSslDeleteKeys(keys);
matrixSslClose();
- printf("Closed down\n");
+ Printf("Closed down\n");
return rc;
}
- printf("Unable to connect\n");
+ Printf("Unable to connect\n");
/* Free all allocated/opened resources. */
matrixSslDeleteSessionId(sid);
@@ -631,14 +650,14 @@ int do_dialog_server(const char *host, const char *port)
rc = psSocketListen(host, port, 0, 0, PS_SOCKET_STREAM, NULL, NULL, &sock);
if (rc == PS_SUCCESS)
{
- printf("Waiting for connection\n");
+ Printf("Waiting for connection\n");
rc = psSocketAccept(sock, 0, &sock2);
- printf("Connected.\n");
+ Printf("Connected.\n");
rc = do_dialog(sock2);
psSocketShutdown(sock, 0);
return rc;
}
- printf("Cannot listen to specified address/port\n");
+ Printf("Cannot listen to specified address/port\n");
return 2;
}
@@ -676,18 +695,18 @@ int do_dialog_server_tls(const char *host, const char *port,
unsigned char sessTicketName[16];
# endif
- memset(&options, 0x0, sizeof(sslSessOpts_t));
+ Memset(&options, 0x0, sizeof(sslSessOpts_t));
set_tls_options_version(&options, tls);
if (matrixSslOpen() < 0)
{
- fprintf(stderr, "Error initializing MatrixSSL\n");
+ Fprintf(stderr, "Error initializing MatrixSSL\n");
return 3;
}
if (matrixSslNewKeys(&keys, NULL) < 0)
{
- fprintf(stderr, "Error initializing MatrixSSL: "
+ Fprintf(stderr, "Error initializing MatrixSSL: "
"matrixSslNewKeys error\n");
return 3;
}
@@ -735,45 +754,45 @@ int do_dialog_server_tls(const char *host, const char *port,
rc = psSocketListen(host, port, 0, 0, PS_SOCKET_STREAM, NULL, NULL, &sock);
if (rc == PS_SUCCESS)
{
- printf("Waiting for connection\n");
+ Printf("Waiting for connection\n");
rc = matrixSslInteractBeginAccept(&msi, sock, 0,
keys, NULL, &options);
if (rc < 0)
{
- printf("Accept failed\n");
+ Printf("Accept failed\n");
exit(1);
}
if (rc >= PS_SUCCESS)
{
/* Interact until connected. */
- printf("Client connected\n");
+ Printf("Client connected\n");
/* TOOD: Fake read needed. */
rc = do_tls_handshake(&msi,
MATRIXSSL_REQUEST_RECV);
if (rc == MATRIXSSL_REQUEST_CLOSE)
{
- printf("Connection close requested.\n");
+ Printf("Connection close requested.\n");
exit(1);
}
if (rc != PS_SUCCESS)
{
- printf("Handshake failure: %d\n", rc);
+ Printf("Handshake failure: %d\n", rc);
exit(1);
}
- printf("Successful handshake\n");
+ Printf("Successful handshake\n");
rc = do_dialog_matrixssl(&msi);
/* Free all allocated/opened resources. */
matrixSslDeleteKeys(keys);
matrixSslClose();
- printf("Closed down\n");
+ Printf("Closed down\n");
psSocketShutdown(sock, 0);
return rc;
}
}
- printf("Cannot listen to specified address/port\n");
+ Printf("Cannot listen to specified address/port\n");
return 2;
}
# endif /* USE_SERVER_SIDE_SSL */
@@ -828,6 +847,10 @@ int main(int argc, char **argv)
{
tls_version |= FLAG_TLS_1_2;
}
+ else if (option(&argc, &argv, "--tlsv13", NULL))
+ {
+ tls_version |= FLAG_TLS_1_3;
+ }
else if (option(&argc, &argv, "--capath", &capath))
{
tls = 1; /* CApath also enables tls. */
@@ -856,7 +879,7 @@ int main(int argc, char **argv)
}
if (argc > 1)
{
- fprintf(stderr, "Invalid arguments: Unable to process %s\n",
+ Fprintf(stderr, "Invalid arguments: Unable to process %s\n",
argv[1]);
usage(stderr, argv[0]);
exit(1);
@@ -881,7 +904,7 @@ int main(int argc, char **argv)
certpath, keypath, capath,
tls_version));
# else
- fprintf(stderr, "USE_SERVER_SIDE_SSL required\n");
+ Fprintf(stderr, "USE_SERVER_SIDE_SSL required\n");
return EXIT_FAILURE;
# endif
}
@@ -894,7 +917,7 @@ int main(int argc, char **argv)
# ifdef USE_CLIENT_SIDE_SSL
exit(do_dialog_client_tls(host, port, capath, tls_version));
# else
- fprintf(stderr, "USE_CLIENT_SIDE_SSL required\n");
+ Fprintf(stderr, "USE_CLIENT_SIDE_SSL required\n");
return EXIT_FAILURE;
# endif
}
@@ -903,7 +926,7 @@ int main(int argc, char **argv)
exit(do_dialog_client(host, port));
}
- fprintf(stderr, "Invalid arguments\n");
+ Fprintf(stderr, "Invalid arguments\n");
usage(stderr, argv[0]);
exit(1);
return 0;
@@ -918,11 +941,11 @@ int main(int argc, char **argv)
int32 main(int32 argc, char **argv)
{
# ifndef USE_PS_NETWORKING
- printf("USE_PS_NETWORKING must be enabled at build"
+ Printf("USE_PS_NETWORKING must be enabled at build"
" time to run this application\n");
# endif
# ifdef USE_ONLY_PSK_CIPHER_SUITE
- printf("This application is not compatible with"
+ Printf("This application is not compatible with"
" USE_ONLY_PSK_CIPHER_SUITE.\n");
# endif
return 1;
diff --git a/apps/ssl/server.c b/apps/ssl/server.c
index 3dfc9dc..dcc3999 100644
--- a/apps/ssl/server.c
+++ b/apps/ssl/server.c
@@ -32,38 +32,56 @@
* http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
+#ifndef _POSIX_C_SOURCE
+# define _POSIX_C_SOURCE 200112L
+#endif
+
+#ifndef NEED_PS_TIME_CONCRETE
+# define NEED_PS_TIME_CONCRETE
+#endif
#include "app.h"
#include "matrixssl/matrixsslApi.h"
-/* Currently this example uses _psTrace for tracing, so osdep.h is needed: */
-#include "core/osdep.h"
#include "core/psUtil.h"
+#include "osdep_sys_socket.h"
+#include "osdep_sys_types.h"
+#include "osdep_sys_time.h"
#ifdef USE_SERVER_SIDE_SSL
# ifdef MATRIX_USE_FILE_SYSTEM
-# include /* Defines SIGTERM, etc. */
+# include "osdep_signal.h" /* Defines SIGTERM, etc. */
# ifndef MATRIX_TESTING_ENVIRONMENT /* Omit the message when testing. */
-# ifdef WIN32
-# pragma message("DO NOT USE THESE DEFAULT KEYS IN PRODUCTION ENVIRONMENTS.")
-# else
-# warning "DO NOT USE THESE DEFAULT KEYS IN PRODUCTION ENVIRONMENTS."
-# endif
+# define WARNING_MESSAGE "DO NOT USE THESE DEFAULT KEYS IN PRODUCTION ENVIRONMENTS."
+# define WARNING_MESSAGE_DEFAULT_KEY
+# include "pscompilerwarning.h"
# endif /* MATRIX_TESTING_ENVIRONMENT */
# define ALLOW_ANON_CONNECTIONS 1
# define SEND_CLOSURE_ALERT
-/* Default keys if nothing provided on command line */
-# define KEY_DIR "../../"
+/* Default keys and certs if nothing provided on command line */
+const char *key_dir;
+const char *testkeys_root = "testkeys";
+const char *testkeys_apps_ssl = "../../testkeys";
+const static char g_defaultCertFile[] = "RSA/2048_RSA.pem";
+const static char g_defaultPrivkeyFile[] = "RSA/2048_RSA_KEY.pem";
+const static char g_defaultCAFile[] = "RSA/2048_RSA_CA.pem";
-const static char g_defaultCertFile[] = "testkeys/RSA/2048_RSA.pem";
-const static char g_defaultPrivkeyFile[] = "testkeys/RSA/2048_RSA_KEY.pem";
-const static char g_defaultCAFile[] = "testkeys/RSA/2048_RSA_CA.pem";
+# ifdef USE_TLS_1_3
+# include "testkeys/PSK/tls13_psk.h"
+# endif /* USE_TLS_1_3 */
+
+static int g_use_psk;
+
+# ifdef USE_OCSP_RESPONSE
+static int g_test_ocsp_stapling_good;
+static int g_test_ocsp_stapling_revoked;
+# endif
# ifdef REQUIRE_DH_PARAMS
-const static char g_defaultDHParamFile[] = "testkeys/DH/1024_DH_PARAMS.pem";
+const static char g_defaultDHParamFile[] = "DH/2048_DH_PARAMS.pem";
# endif
# ifdef USE_REHANDSHAKING
@@ -72,6 +90,12 @@ static int g_numRehandshakes;
static int g_maxRehandshakes;
# endif
+/*
+ Require client authentication?
+ Use --require-client-auth command line argument to enable.
+*/
+static int g_require_client_auth;
+
/********************************** Defines ***********************************/
# define SSL_TIMEOUT 45000 /* In milliseconds */
@@ -94,13 +118,24 @@ static int32 g_exitFlag;
static int g_port;
static int g_min_version;
static int g_max_version;
+static int g_use_default_versions;
static int g_disabledCiphers;
static uint16_t g_disabledCipher[SSL_MAX_DISABLED_CIPHERS];
+static psList_t *g_groupList;
+static psList_t *g_sigAlgsList;
+static psList_t *g_sigAlgsCertList;
+static psList_t *g_supportedVersionsList;
+static int g_max_early_data;
+static long int g_tls13_block_size;
+static int g_allow_out_of_date_cert_chain;
# define MAX_KEYFILE_PATH 256
+# define MAX_SERVER_NAME 256
# define MAX_PASSWORD_LEN MAX_KEYFILE_PATH
+
static char g_keyfilePath[MAX_KEYFILE_PATH];
static char g_privkeyFile[MAX_KEYFILE_PATH];
+static char g_serverName[MAX_SERVER_NAME];
static char g_identityCert[MAX_KEYFILE_PATH];
static char g_dhParamFile[MAX_KEYFILE_PATH];
static char g_caFile[MAX_KEYFILE_PATH];
@@ -114,7 +149,24 @@ static unsigned char g_httpResponseHdr[] = "HTTP/1.0 200 OK\r\n"
"Content-length: 9\r\n"
"\r\n"
"MatrixSSL";
-
+# ifdef USE_TLS_1_3
+static const char *g_httpResponseHeaderTls13 = "HTTP/1.1 200 OK\r\n"
+ "Server: MatrixSSL " MATRIXSSL_VERSION "\r\n"
+ "Connection: close\r\n"
+ "Cache-Control: no-cache\r\n"
+ "Content-Type: text/html; charset=UTF-8\r\n"
+ "Content-Length: 187\r\n"
+ "\r\n\r\n"
+ "\n"
+ "\n"
+ " \n"
+ " Connected to MatrixSSL Server\n"
+ " \n"
+ "\n"
+ " MatrixSSL now supports TLS 1.3
\n"
+ "\n"
+ "\n";
+# endif
# ifdef USE_STATELESS_SESSION_TICKETS
static int32 sessTicketCb(void *keys, unsigned char name[16], short found);
static unsigned char sessTicketSymKey[32] = { 0 };
@@ -128,6 +180,10 @@ static int32 httpWriteResponse(httpConn_t *conn);
static int setSocketOptions(SOCKET fd);
static SOCKET lsocketListen(short port, int32 *err);
static void closeConn(httpConn_t *cp, int32 reason);
+# ifdef USE_TLS_1_3
+static int32_t sendHtmlResponseTls13(ssl_t *ssl);
+# endif
+static int32_t sendHtmlResponse(ssl_t *ssl);
# ifdef POSIX
static void sigsegv_handler(int i);
@@ -135,6 +191,26 @@ static void sigintterm_handler(int i);
static int32 sighandlers(void);
# endif /* POSIX */
+# ifdef MATRIX_USE_FILE_SYSTEM
+/* Check whether we are in the root directory of MatrixSSL.
+ Used to determine paths of default certificates and keys. */
+static psBool_t cwdIsMatrixRoot(void)
+{
+ psRes_t rc;
+ unsigned char *buf;
+ psSizeL_t len;
+
+ rc = psGetFileBuf(NULL, "testkeys/RSA/2048_RSA_KEY.pem", &buf, &len);
+ if (rc != PS_SUCCESS)
+ {
+ return PS_FALSE;
+ }
+
+ psFree(buf, NULL);
+ return PS_TRUE;
+}
+# endif
+
/************************ Handshake Callback Functions ************************/
/* A server will make use of a certificate callback if client authentication
is being used. This callback will be invoked during the handshake to
@@ -170,16 +246,58 @@ int32 sessTicketCb(void *keys, unsigned char name[16], short found)
void SNIcallback(void *ssl, char *hostname, int32 hostnameLen,
sslKeys_t **newKeys)
{
- ssl_t *lssl = ssl;
+ ssl_t *lssl = (ssl_t *)ssl;
+ char *str = Malloc(hostnameLen + 1);
+ psSize_t expectedLen;
- *newKeys = lssl->keys;
+ Memcpy(str, hostname, hostnameLen);
+ str[hostnameLen] = '\0';
+ Printf("Hostname in ClientHello SNI extension: %s\n", str);
+
+ expectedLen = Strlen(g_serverName);
+
+ if (expectedLen != 0 &&
+ (hostnameLen != expectedLen ||
+ Memcmp(hostname, g_serverName, hostnameLen)))
+ {
+ Printf("Received unrecognized server name in the SNI extension\n");
+ *newKeys = NULL;
+ }
+ else
+ {
+ *newKeys = lssl->keys;
+ }
+
+ Free(str);
}
int32 setProtocolVersions(sslSessOpts_t *options)
{
- return matrixSslSessOptsSetServerTlsVersionRange(options,
- g_min_version,
- g_max_version);
+ psList_t *supportedVersion;
+ int32_t supportedVersions[TLS_MAX_SUPPORTED_VERSIONS] = {0};
+ psSize_t i;
+ int32 rc;
+ if (g_supportedVersionsList)
+ {
+ supportedVersion = g_supportedVersionsList;
+ i = 0;
+ while (supportedVersion)
+ {
+ supportedVersions[i] = atoi((char* )supportedVersion->item);
+ supportedVersion = supportedVersion->next;
+ i++;
+ }
+ rc = matrixSslSessOptsSetServerTlsVersions(options,
+ supportedVersions,
+ i);
+ }
+ else
+ {
+ rc = matrixSslSessOptsSetServerTlsVersionRange(options,
+ g_min_version,
+ g_max_version);
+ }
+ return rc;
}
/******************************************************************************/
@@ -190,15 +308,15 @@ static uint64_t g_handshakes = 0;
static void displayStats(void)
{
static uint64_t s_handshakes = 0; /* last value displayed */
- static time_t s_t = (time_t) 0; /* last time displayed */
- time_t t;
+ static psTimeSeconds_t s_t = (psTimeSeconds_t) 0; /* last time displayed */
+ psTimeSeconds_t t;
if (g_handshakes > s_handshakes)
{
- t = time(NULL);
+ t = psGetEpochTime();
if (t > s_t)
{
- printf("%u CPS\n",
+ Printf("%u CPS\n",
(uint32_t) (g_handshakes - s_handshakes) / (uint32_t) (t - s_t));
s_handshakes = g_handshakes;
s_t = t;
@@ -227,8 +345,16 @@ static int32 selectLoop(sslKeys_t *keys, SOCKET lfd)
unsigned char *buf;
int32 rc, len, transferred, val, specialAppData;
unsigned char rSanity, wSanity, acceptSanity;
+ psList_t *sigAlg;
+ uint16_t sigAlgs[TLS_MAX_SIGNATURE_ALGORITHMS] = {0};
sslSessOpts_t options;
+ psSize_t i;
+# ifdef USE_TLS_1_3
+ psSize_t groupsLen;
+ psList_t *group;
+ uint16_t groups[TLS_1_3_MAX_GROUPS] = {0};
+# endif
DLListInit(&connsTmp);
rc = PS_SUCCESS;
@@ -277,7 +403,7 @@ static int32 selectLoop(sslKeys_t *keys, SOCKET lfd)
}
/* Use select to check for events on the sockets */
- if ((val = select(maxfd + 1, &readfd, &writefd, NULL, &timeout)) <= 0)
+ if ((val = Select(maxfd + 1, &readfd, &writefd, NULL, &timeout)) <= 0)
{
/* On error, restore global connections list */
while (!DLListIsEmpty(&connsTmp))
@@ -315,29 +441,123 @@ static int32 selectLoop(sslKeys_t *keys, SOCKET lfd)
close(fd);
return PS_PLATFORM_FAIL;
}
- cp = malloc(sizeof(httpConn_t));
+ cp = (httpConn_t *)Malloc(sizeof(httpConn_t));
if (cp == NULL)
{
close(fd);
return PS_MEM_FAIL;
}
- memset(cp, 0x0, sizeof(httpConn_t));
+ Memset(cp, 0x0, sizeof(httpConn_t));
- memset(&options, 0x0, sizeof(sslSessOpts_t));
+ Memset(&options, 0x0, sizeof(sslSessOpts_t));
options.userPtr = keys;
/* options.extendedMasterSecret = 1; / * Require * / */
- if (setProtocolVersions(&options) < 0)
+ if (g_use_default_versions == 0 &&
+ setProtocolVersions(&options) < 0)
{
+ Printf("setProtocolVersions failed\n");
close(fd);
return PS_ARG_FAIL;
}
+# ifdef USE_TLS_1_3
+ options.tls13SessionMaxEarlyData = g_max_early_data;
- if ((rc = matrixSslNewServerSession(&cp->ssl, keys, NULL,
- &options)) < 0)
+ /* Determine which groups to use. */
+ if (g_groupList != 0)
{
- close(fd);
- continue;
+ group = g_groupList;
+ i = groupsLen = 0;
+ while (group)
+ {
+ groups[i] = psGetNamedGroupId((const char*)group->item);
+ group = group->next;
+ groupsLen++;
+ i++;
+ }
+ rc = matrixSslSessOptsSetKeyExGroups(&options,
+ groups,
+ groupsLen,
+ 1);
+ if (rc < 0)
+ {
+ Printf("matrixSslSessOptsSetKeyExGroups failed\n");
+ return rc;
+ }
}
+ if (g_sigAlgsCertList != 0)
+ {
+ sigAlg = g_sigAlgsCertList;
+ i = 0;
+ while (sigAlg)
+ {
+ sigAlgs[i] = psGetNamedSigAlgId((const char*)sigAlg->item);
+ sigAlg = sigAlg->next;
+ i++;
+ }
+ rc = matrixSslSessOptsSetSigAlgsCert(&options,
+ sigAlgs,
+ i);
+ if (rc < 0)
+ {
+ Printf("matrixSslSessOptsSetSigAlgsCert failed\n");
+ return rc;
+ }
+ }
+# endif /* USE_TLS_1_3 */
+ if (g_sigAlgsList != 0)
+ {
+ sigAlg = g_sigAlgsList;
+ i = 0;
+ while (sigAlg)
+ {
+ sigAlgs[i] = psGetNamedSigAlgId((const char*)sigAlg->item);
+ if (sigAlgs[i] == 0)
+ {
+ Printf("Invalid signature algorithm parameter\n");
+ return PS_ARG_FAIL;
+ }
+ sigAlg = sigAlg->next;
+ i++;
+ }
+ rc = matrixSslSessOptsSetSigAlgs(&options,
+ sigAlgs,
+ i);
+ if (rc < 0)
+ {
+ Printf("matrixSslSessOptsSetSigAlgs failed\n");
+ return rc;
+ }
+ }
+
+ if (g_require_client_auth)
+ {
+ if ((rc = matrixSslNewServerSession(&cp->ssl, keys, certCb,
+ &options)) < 0)
+ {
+ close(fd);
+ continue;
+ }
+ }
+ else
+ {
+ if ((rc = matrixSslNewServerSession(&cp->ssl, keys, NULL,
+ &options)) < 0)
+ {
+ close(fd);
+ continue;
+ }
+ }
+# ifdef USE_TLS_1_3
+ if (g_tls13_block_size != 0)
+ {
+ rc = matrixSslSetTls13BlockPadding(cp->ssl, g_tls13_block_size);
+ if (rc != PS_SUCCESS)
+ {
+ close(fd);
+ continue;
+ }
+ }
+# endif
matrixSslRegisterSNICallback(cp->ssl, SNIcallback);
cp->fd = fd;
cp->timeout = SSL_TIMEOUT;
@@ -347,7 +567,7 @@ static int32 selectLoop(sslKeys_t *keys, SOCKET lfd)
DLListInsertTail(&connsTmp, &cp->List);
/* Fake that there is read data available, no harm if there isn't */
FD_SET(cp->fd, &readfd);
-/* _psTraceInt("=== New Client %d ===\n", cp->fd); */
+/* psTraceInt("=== New Client %d ===\n", cp->fd); */
}
}
@@ -369,6 +589,7 @@ WRITE_MORE:
{
/* Could get a EWOULDBLOCK since we don't check FD_ISSET */
transferred = (int32) send(cp->fd, buf, len, MSG_DONTWAIT);
+ /*psTraceBytes("++ sent", buf, transferred);*/
if (transferred <= 0)
{
# ifdef WIN32
@@ -399,23 +620,25 @@ WRITE_MORE:
}
else if (rc == MATRIXSSL_HANDSHAKE_COMPLETE)
{
+ Printf("Got HANDSHAKE_COMPLETE from SentData\n");
/* If the protocol is server initiated, send data here */
+ cp->handshakeComplete = 1;
g_handshakes++;
# ifdef USE_REHANDSHAKING
if (g_doSelfInitiatedRehandshakeTest &&
g_numRehandshakes < g_maxRehandshakes)
{
/* Full rehandshake */
- printf("Server initiating re-handshake\n");
+ Printf("Server initiating re-handshake\n");
if (matrixSslEncodeRehandshake(cp->ssl, NULL,
# ifdef USE_CLIENT_AUTH
- certCb,
+ g_require_client_auth ? certCb : NULL,
# else
NULL,
# endif /* USE_CLIENT_AUTH */
SSL_OPTION_FULL_HANDSHAKE, NULL, 0) < 0)
{
- printf("matrixSslEncodeRehandshake failed\n");
+ Printf("matrixSslEncodeRehandshake failed\n");
exit(1);
}
g_numRehandshakes++;
@@ -456,8 +679,10 @@ WRITE_MORE:
continue; /* Next connection */
}
- /* If we are sending response data and it's all encoded and sent, close conn */
- if (cp->bytes_requested > 0 &&
+ /* If we are sending response data and it's all encoded and sent, close conn.
+ Do not close connection if handshake is not finished which is the case with
+ TLS1.3 early data */
+ if (cp->handshakeComplete == 1 && cp->bytes_requested > 0 &&
cp->bytes_requested == cp->bytes_sent &&
matrixSslGetOutdata(cp->ssl, &buf) <= 0)
{
@@ -495,7 +720,7 @@ READ_MORE:
}
continue; /* Next connection */
}
-
+ psTraceBytes("+++ Got", buf, transferred);
/* If EOF, remote socket closed. This is semi-normal closure.
Officially, we should close on closure alert. */
if (transferred == 0)
@@ -522,12 +747,14 @@ PROCESS_MORE:
switch (rc)
{
case MATRIXSSL_HANDSHAKE_COMPLETE:
+ Printf("Got HANDSHAKE_COMPLETE from RecvData\n");
+ cp->handshakeComplete = 1;
g_handshakes++;
/* If the protocol is server initiated, send data here */
goto READ_MORE;
case MATRIXSSL_APP_DATA:
case MATRIXSSL_APP_DATA_COMPRESSED:
- /* psTraceBytes("DATA", buf, len); */
+ psTraceBytes("App data from client", buf, len);
/* First test to see if this is one of the special data
requests used for testing.
@@ -536,42 +763,42 @@ PROCESS_MORE:
*/
specialAppData = 0;
if (len > 11 &&
- strncmp((char *) buf, "GET /bytes?", 11) == 0)
+ Strncmp((char *) buf, "GET /bytes?", 11) == 0)
{
cp->bytes_requested = atoi((char *) buf + 11);
if (cp->bytes_requested <
- strlen((char *) g_httpResponseHdr) ||
+ Strlen((char *) g_httpResponseHdr) ||
cp->bytes_requested > 1073741824)
{
cp->bytes_requested =
- (uint32) strlen((char *) g_httpResponseHdr);
+ (uint32) Strlen((char *) g_httpResponseHdr);
}
cp->bytes_sent = 0;
specialAppData = 1;
}
/* A special test for TLS 1.0 where BEAST workaround used */
if (len > 10 &&
- strncmp((char *) buf, "ET /bytes?", 10) == 0)
+ Strncmp((char *) buf, "ET /bytes?", 10) == 0)
{
cp->bytes_requested = atoi((char *) buf + 10);
if (cp->bytes_requested <
- strlen((char *) g_httpResponseHdr) ||
+ Strlen((char *) g_httpResponseHdr) ||
cp->bytes_requested > 1073741824)
{
cp->bytes_requested =
- (uint32) strlen((char *) g_httpResponseHdr);
+ (uint32) Strlen((char *) g_httpResponseHdr);
}
cp->bytes_sent = 0;
specialAppData = 1;
}
/* Shutdown the server */
if (len >= 15 &&
- strncmp((char *) buf, "MATRIX_SHUTDOWN", 15) == 0)
+ Strncmp((char *) buf, "MATRIX_SHUTDOWN", 15) == 0)
{
g_exitFlag = 1;
rc = matrixSslEncodeClosureAlert(cp->ssl);
psAssert(rc >= 0);
- _psTrace("Got MATRIX_SHUTDOWN. Exiting\n");
+ psTrace("Got MATRIX_SHUTDOWN. Exiting\n");
goto WRITE_MORE;
}
@@ -579,7 +806,7 @@ PROCESS_MORE:
{
if ((rc = httpBasicParse(cp, buf, len, 0)) < 0)
{
- _psTrace("Couldn't parse HTTP data. Closing...\n");
+ psTrace("Couldn't parse HTTP data. Closing...\n");
closeConn(cp, PS_PROTOCOL_FAIL);
continue; /* Next connection */
}
@@ -600,10 +827,24 @@ PROCESS_MORE:
/* psAssert(rc >= 0); */
# endif
rc = matrixSslProcessedData(cp->ssl, &buf, (uint32 *) &len);
+ if (!cp->handshakeComplete)
+ {
+ /* If handshake is not yet completed we received
+ TLS1.3 early data. Continue the handshake based
+ on the result */
+ if (rc == MATRIXSSL_REQUEST_SEND)
+ {
+ goto WRITE_MORE;
+ }
+ if (rc == MATRIXSSL_REQUEST_RECV)
+ {
+ goto READ_MORE;
+ }
+ }
if (rc > 0)
{
/* Additional data is available, but we ignore it */
- _psTrace("HTTP data parsing not supported, ignoring.\n");
+ psTrace("HTTP data parsing not supported, ignoring.\n");
closeConn(cp, PS_SUCCESS);
continue; /* Next connection */
}
@@ -684,8 +925,7 @@ static int32 httpWriteResponse(httpConn_t *cp)
{
unsigned char *buf;
ssl_t *ssl;
- int32 available, len, rc;
-
+ int32 len, rc;
ssl = cp->ssl;
/* The /bytes? HTTP request assigns bytes_requested */
@@ -716,16 +956,16 @@ static int32 httpWriteResponse(httpConn_t *cp)
{
len = rc; /* could have been shortened due to max_frag */
}
- memset(buf, 'J', len);
+ Memset(buf, 'A', len);
if (cp->bytes_sent == 0)
{
/* Overwrite first N bytes with HTTP header the first time */
- strncpy((char *) buf, (char *) g_httpResponseHdr,
- strlen((char *) g_httpResponseHdr));
+ Strncpy((char *) buf, (char *) g_httpResponseHdr,
+ Strlen((char *) g_httpResponseHdr));
}
if ((rc = matrixSslEncodeWritebuf(ssl, len)) < 0)
{
- printf("couldn't encode data %d\n", rc);
+ Printf("couldn't encode data %d\n", rc);
}
cp->bytes_sent += len;
/*
@@ -737,6 +977,7 @@ static int32 httpWriteResponse(httpConn_t *cp)
{
if ((len = (int32) send(cp->fd, buf, len, MSG_DONTWAIT)) > 0)
{
+ psTraceBytes("++ sent:", buf, len);
rc = matrixSslSentData(ssl, len);
/* psAssert(rc != MATRIXSSL_REQUEST_SEND); / * Some data remains * / */
}
@@ -745,24 +986,80 @@ static int32 httpWriteResponse(httpConn_t *cp)
return MATRIXSSL_REQUEST_SEND;
}
- /* Usual reply */
- if ((available = matrixSslGetWritebuf(ssl, &buf,
- (uint32) strlen((char *) g_httpResponseHdr) + 1)) < 0)
+# ifdef USE_TLS_1_3
+ if (ssl->flags & SSL_FLAGS_TLS_1_3_NEGOTIATED)
{
- return PS_MEM_FAIL;
+ rc = sendHtmlResponseTls13(ssl);
}
- strncpy((char *) buf, (char *) g_httpResponseHdr, available);
- /* psTraceBytes("Replying", buf, (uint32)strlen((char *)buf)); */
- if (matrixSslEncodeWritebuf(ssl, (uint32) strlen((char *) buf)) < 0)
+ else
{
- return PS_MEM_FAIL;
+ rc = sendHtmlResponse(ssl);
}
+# else
+ rc = sendHtmlResponse(ssl);
+# endif /* USE_TLS_1_3 */
+
+ if (rc != PS_SUCCESS)
+ {
+ return rc;
+ }
+
return MATRIXSSL_REQUEST_SEND;
}
+# ifdef USE_TLS_1_3
+static int32_t sendHtmlResponseTls13(ssl_t *ssl)
+{
+ uint32_t len;
+ int32_t available;
+ int32_t rc;
+ unsigned char *buf;
+
+ len = (uint32) Strlen(g_httpResponseHeaderTls13) + 1;
+ printf("length: %zu\n", Strlen(g_httpResponseHeaderTls13));
+ available = matrixSslGetWritebuf(ssl, &buf, len);
+ if (available < 0)
+ {
+ return PS_MEM_FAIL;
+ }
+ Strncpy((char*)buf, g_httpResponseHeaderTls13, len);
+ rc = matrixSslEncodeWritebuf(ssl, len);
+ if (rc < 0)
+ {
+ return PS_MEM_FAIL;
+ }
+ rc = matrixSslEncodeClosureAlert(ssl);
+
+ return rc;
+}
+# endif
+
+static int32_t sendHtmlResponse(ssl_t *ssl)
+{
+ int32_t available;
+ int32_t rc;
+ unsigned char *buf;
+
+ available = matrixSslGetWritebuf(ssl, &buf,
+ (uint32) Strlen((char *) g_httpResponseHdr) + 1);
+ if (available < 0)
+ {
+ return PS_MEM_FAIL;
+ }
+ Strncpy((char *) buf, (char *) g_httpResponseHdr, available);
+
+ rc = matrixSslEncodeWritebuf(ssl, (uint32) Strlen((char *) buf));
+ if (rc < 0)
+ {
+ return PS_MEM_FAIL;
+ }
+
+ return PS_SUCCESS;
+}
+
static void usage(void)
{
- printf(
+ Printf(
"\nusage: server { options }\n"
"\n"
"Options can be one or more of the following:\n"
@@ -770,8 +1067,12 @@ static void usage(void)
"-c - Server certificate file\n"
"-k - Server private key file of certificate\n"
"-a - CA certificate file\n"
+ "-A - Require client authentication\n"
+ "-K - Use a test PSK in TLS 1.3 handshakes\n"
"-p - Private key password\n"
"-d - Diffie-Hellman parameters file\n"
+ "-g - (TLS 1.3 only): Colon-separated list of\n"
+ " TLS 1.3 NamedGroups to support for key exchange.\n"
"-D - Directory path to certificate, private key, \n"
" and Diffie-Hellman parameter files\n"
"-P - Port number\n"
@@ -783,18 +1084,29 @@ static void usage(void)
" - '10' SSL_RSA_WITH_3DES_EDE_CBC_SHA\n"
" - '5' SSL_RSA_WITH_RC4_128_SHA\n"
" - '4' SSL_RSA_WITH_RC4_128_MD5\n"
- "-v - SSL/TLS version to use\n"
+ "-v - Select single SSL/TLS version to use\n"
" - '0' SSL 3.0\n"
" - '1' TLS 1.0\n"
" - '2' TLS 1.1\n"
" - '3' TLS 1.2 (default)\n"
+ " - '4' TLS 1.3\n"
"-V , - SSL/TLS version range to use, e.g. '-V 2,3'\n"
+ " - Note: Only one of -v, -V or -W should be supplied\n"
+ "-W , - SSL/TLS enabled versions in priority order, e.g. '-W 4,2\n"
+ " - Note: Only one of -v, -V or -W should be supplied\n"
+ "-S - Supported signature algorithms.\n"
+ " For example: ecdsa_secp256r1_sha256:rsa_pss_rsae_sha256\n"
+ "-C - Supported signature algorithms in TLS1.3 certs.\n"
+ " For example: ecdsa_secp256r1_sha256:rsa_pss_rsae_sha256\n"
+ "-E - Enable early data support for TLS1.3 with maximum accepted amount.\n"
+ " - Maximum early data is 16384 bytes"
+ "-b - Block size to pad TLS 1.3 records to.\n"
"\n");
}
/* Returns number of cipher numbers found, or -1 if an error. */
-# include
+# include "osdep_ctype.h"
static int32_t parse_cipher_list(char *cipherListString,
psCipher16_t cipher_array[], uint8_t size_of_cipher_array)
{
@@ -805,21 +1117,21 @@ static int32_t parse_cipher_list(char *cipherListString,
numCiphers = 0;
while (cipherListString != NULL)
{
- cipher = strtol(cipherListString, &endPtr, 10);
+ cipher = Strtol(cipherListString, &endPtr, 10);
if (endPtr == cipherListString)
{
- printf("The remaining cipherList has no cipher numbers - '%s'\n",
+ Printf("The remaining cipherList has no cipher numbers - '%s'\n",
cipherListString);
return -1;
}
else if (size_of_cipher_array <= numCiphers)
{
- printf("Too many cipher numbers supplied. limit is %d\n",
+ Printf("Too many cipher numbers supplied. limit is %d\n",
size_of_cipher_array);
return -1;
}
cipher_array[numCiphers++] = cipher;
- while (*endPtr != '\0' && !isdigit(*endPtr))
+ while (*endPtr != '\0' && !Isdigit(*endPtr))
{
endPtr++;
}
@@ -838,22 +1150,26 @@ static int32_t parse_cipher_list(char *cipherListString,
static int32 process_cmd_options(int32 argc, char **argv)
{
int optionChar, str_len, version, numCiphers;
- char *cipherListString, *versionRangeStr;
+ char *cipherListString;
+ psList_t *versionRangeList;
/* Start with all options zeroized. */
- memset(g_keyfilePath, 0, MAX_KEYFILE_PATH);
- memset(g_privkeyFile, 0, MAX_KEYFILE_PATH);
- memset(g_identityCert, 0, MAX_KEYFILE_PATH);
- memset(g_dhParamFile, 0, MAX_KEYFILE_PATH);
- memset(g_caFile, 0, MAX_KEYFILE_PATH);
- memset(g_password, 0, MAX_PASSWORD_LEN);
+ Memset(g_keyfilePath, 0, MAX_KEYFILE_PATH);
+ Memset(g_privkeyFile, 0, MAX_KEYFILE_PATH);
+ Memset(g_serverName, 0, MAX_SERVER_NAME);
+ Memset(g_identityCert, 0, MAX_KEYFILE_PATH);
+ Memset(g_dhParamFile, 0, MAX_KEYFILE_PATH);
+ Memset(g_caFile, 0, MAX_KEYFILE_PATH);
+ Memset(g_password, 0, MAX_PASSWORD_LEN);
g_port = HTTPS_PORT;
g_min_version = g_max_version = 3;
g_disabledCiphers = 0;
opterr = 0;
- while ((optionChar = getopt(argc, argv, "c:d:a:D:hk:p:P:v:V:x:r:")) != -1)
+ while ((optionChar = getopt(argc,
+ argv,
+ "c:d:g:a:Bb:AD:hKk:n:oOp:P:v:V:x:r:S:C:W:E:")) != -1)
{
switch (optionChar)
{
@@ -875,63 +1191,127 @@ static int32 process_cmd_options(int32 argc, char **argv)
case 'D':
/* Directory for key and cert location */
- str_len = strlen(optarg);
+ str_len = Strlen(optarg);
if (str_len > MAX_KEYFILE_PATH - 1)
{
return -1;
}
- strncpy(g_keyfilePath, optarg, str_len);
+ Strncpy(g_keyfilePath, optarg, str_len);
break;
case 'c':
/* Certfile */
- str_len = strlen(optarg);
+ str_len = Strlen(optarg);
if (str_len > MAX_KEYFILE_PATH - 1)
{
return -1;
}
- strncpy(g_identityCert, optarg, str_len);
+ Strncpy(g_identityCert, optarg, str_len);
break;
case 'a':
/* Cert authority file */
- str_len = strlen(optarg);
+ str_len = Strlen(optarg);
if (str_len > MAX_KEYFILE_PATH - 1)
{
return -1;
}
- strncpy(g_caFile, optarg, str_len);
+ Strncpy(g_caFile, optarg, str_len);
+ break;
+
+ case 'A':
+ /* Require client authentication. */
+ g_require_client_auth = 1;
+ break;
+
+ case 'b':
+ /* TLS 1.3 block size. */
+ {
+ char *end;
+
+ g_tls13_block_size = Strtol(optarg, &end, 10);
+ if (end == optarg
+ || g_tls13_block_size < 0
+ || g_tls13_block_size > TLS_1_3_MAX_INNER_PLAINTEXT_LEN)
+ {
+ Printf("Invalid tls13-block-size argument\n");
+ exit(EXIT_FAILURE);
+ }
+ Printf("Using TLS 1.3 block side %ld\n", g_tls13_block_size);
+ break;
+ }
+
+ case 'B':
+ /* Allow the server to load an out-of-date certificate chain. */
+ g_allow_out_of_date_cert_chain = 1;
break;
case 'd':
/* Diffie-Hellman parameters */
- str_len = strlen(optarg);
+ str_len = Strlen(optarg);
if (str_len > MAX_KEYFILE_PATH - 1)
{
return -1;
}
- strncpy(g_dhParamFile, optarg, str_len);
+ Strncpy(g_dhParamFile, optarg, str_len);
break;
+ case 'g':
+ /* Key exchange groups to support. */
+ if (psParseList(NULL, optarg, ':', &g_groupList) < 0)
+ {
+ Printf("Invalid group list: %s\n", optarg);
+ }
+ break;
case 'k':
/* Keyfile */
- str_len = strlen(optarg);
+ str_len = Strlen(optarg);
if (str_len > MAX_KEYFILE_PATH - 1)
{
return -1;
}
- strncpy(g_privkeyFile, optarg, str_len);
+ Strncpy(g_privkeyFile, optarg, str_len);
break;
+ case 'K':
+ /* PSK. TODO: use the PSK provided in optarg. Now this arg
+ causes us to perform a PSK handshake using the use the
+ TLS 1.3 PSK (testkeys/PSK/tls13_psk.h). */
+ g_use_psk = 1;
+ break;
+
+ case 'n':
+ /* Server name. */
+ str_len = Strlen(optarg);
+ if (str_len > MAX_SERVER_NAME - 1)
+ {
+ return -1;
+ }
+ Strncpy(g_serverName, optarg, str_len);
+ break;
+
+# ifdef USE_OCSP_RESPONSE
+ case 'o':
+ /* Test OCSP stapling with a "good" response. */
+ g_test_ocsp_stapling_good = 1;
+ break;
+ case 'O':
+ /* Test OCSP stapling with a "revoked" response.
+ Note that for this test to work, the 256_EC.pem
+ server cert should be used. */
+ g_test_ocsp_stapling_revoked = 1;
+ break;
+# endif
+
case 'p':
/* password */
- str_len = strlen(optarg);
+ str_len = Strlen(optarg);
if (str_len > MAX_KEYFILE_PATH - 1)
{
return -1;
}
- strncpy(g_password, optarg, str_len);
+ Strncpy(g_password, optarg, str_len);
break;
case 'P':
@@ -943,7 +1323,7 @@ static int32 process_cmd_options(int32 argc, char **argv)
g_doSelfInitiatedRehandshakeTest = 1;
g_maxRehandshakes = atoi(optarg);
#else
- printf("Need USE_REHANDSHAKING for re-handshake test\n");
+ Printf("Need USE_REHANDSHAKING for re-handshake test\n");
exit(EXIT_FAILURE);
#endif
break;
@@ -954,29 +1334,63 @@ static int32 process_cmd_options(int32 argc, char **argv)
if (!matrixSslTlsVersionRangeSupported(version,
version))
{
- printf("Invalid version: %d\n", version);
+ Printf("Invalid version: %d\n", version);
return -1;
}
g_min_version = g_max_version = version;
break;
case 'V':
- /* Version range. */
- versionRangeStr = optarg;
- if (strlen(versionRangeStr) != 3)
+ if (psParseList(NULL, optarg, ',', &versionRangeList) < 0 ||
+ versionRangeList->next == NULL)
{
- printf("Invalid version range string: %s\n", versionRangeStr);
+ Printf("Invalid version range string: %s\n",
+ optarg);
return -1;
}
- g_min_version = atoi(&versionRangeStr[0]);
- g_max_version = atoi(&versionRangeStr[2]);
+ g_min_version = atoi((char *)versionRangeList->item);
+ g_max_version = atoi((char *)versionRangeList->next->item);
+ psFreeList(versionRangeList, NULL);
if (!matrixSslTlsVersionRangeSupported(g_min_version,
g_max_version))
{
- printf("Unsupported version range: %s\n", versionRangeStr);
+ Printf("Unsupported version range: %s\n",
+ optarg);
return -1;
}
break;
+ case 'W':
+ if (psParseList(NULL, optarg, ',', &g_supportedVersionsList) < 0)
+ {
+ Printf("Invalid tls-supported-versions list: %s\n", optarg);
+ }
+ if (Strcmp((char*)g_supportedVersionsList[0].item, "default") == 0)
+ {
+ g_use_default_versions = 1;
+ }
+ break;
+ case 'S':
+ if (psParseList(NULL, optarg, ':', &g_sigAlgsList) < 0)
+ {
+ Printf("Invalid sig_alg list: %s\n", optarg);
+ }
+ break;
+ case 'C':
+ if (psParseList(NULL, optarg, ':', &g_sigAlgsCertList) < 0)
+ {
+ Printf("Invalid sig_alg_cert list: %s\n", optarg);
+ }
+ break;
+ case 'E':
+ if (optarg != NULL)
+ {
+ g_max_early_data = atoi(optarg);
+ }
+ else
+ {
+ g_max_early_data = 16384;
+ }
+ break;
}
}
@@ -1022,7 +1436,7 @@ int32 main(int32 argc, char **argv)
if ((rc = matrixSslOpen()) < 0)
{
- _psTrace("MatrixSSL library init failure. Exiting\n");
+ psTrace("MatrixSSL library init failure. Exiting\n");
return rc;
}
@@ -1037,23 +1451,33 @@ int32 main(int32 argc, char **argv)
return 0;
}
+# ifdef MATRIX_USE_FILE_SYSTEM
+ if (cwdIsMatrixRoot())
+ {
+ key_dir = testkeys_root;
+ }
+ else
+ {
+ key_dir = testkeys_apps_ssl;
+ }
+# endif
# ifdef USE_STATELESS_SESSION_TICKETS
if (psGetPrngLocked(sessTicketSymKey, sizeof(sessTicketSymKey), NULL) < 0
|| psGetPrngLocked(sessTicketMacKey, sizeof(sessTicketMacKey), NULL) < 0
|| psGetPrngLocked(sessTicketName, sizeof(sessTicketName), NULL) < 0)
{
- _psTrace("Error generating session ticket encryption key\n");
+ psTrace("Error generating session ticket encryption key\n");
return EXIT_FAILURE;
}
if (matrixSslLoadSessionTicketKeys(keys, sessTicketName,
sessTicketSymKey, sizeof(sessTicketSymKey),
sessTicketMacKey, sizeof(sessTicketMacKey)) < 0)
{
- _psTrace("Error loading session ticket encryption key\n");
+ psTrace("Error loading session ticket encryption key\n");
return EXIT_FAILURE;
}
matrixSslSetSessionTicketCallback(keys, sessTicketCb);
- _psTrace("Session Ticket resumption enabled\n");
+ psTrace("Session Ticket resumption enabled\n");
# endif
@@ -1063,20 +1487,20 @@ int32 main(int32 argc, char **argv)
/* User provided a cert */
if (g_keyfilePath[0] != 0)
{
- snprintf(certpath, FILENAME_MAX - 1, "%s/%s",
+ Snprintf(certpath, FILENAME_MAX - 1, "%s/%s",
g_keyfilePath, g_identityCert);
}
else
{
- snprintf(certpath, FILENAME_MAX - 1, "%s", g_identityCert);
+ Snprintf(certpath, FILENAME_MAX - 1, "%s", g_identityCert);
}
}
else
{
/* Default cert */
- _psTrace("WARNING: Do not use sample certificate file in production\n");
- snprintf(certpath, FILENAME_MAX - 1, "%s/%s",
- KEY_DIR, g_defaultCertFile);
+ psTrace("WARNING: Do not use sample certificate file in production\n");
+ Snprintf(certpath, FILENAME_MAX - 1, "%s/%s",
+ key_dir, g_defaultCertFile);
}
if (g_privkeyFile[0] != 0)
@@ -1084,20 +1508,20 @@ int32 main(int32 argc, char **argv)
/* User provided a key */
if (g_keyfilePath[0] != 0)
{
- snprintf(keypath, FILENAME_MAX - 1, "%s/%s",
+ Snprintf(keypath, FILENAME_MAX - 1, "%s/%s",
g_keyfilePath, g_privkeyFile);
}
else
{
- snprintf(keypath, FILENAME_MAX - 1, "%s", g_privkeyFile);
+ Snprintf(keypath, FILENAME_MAX - 1, "%s", g_privkeyFile);
}
}
else
{
/* Default key */
- _psTrace("WARNING: Do not use sample private key file in production\n");
- snprintf(keypath, FILENAME_MAX - 1, "%s/%s",
- KEY_DIR, g_defaultPrivkeyFile);
+ psTrace("WARNING: Do not use sample private key file in production\n");
+ Snprintf(keypath, FILENAME_MAX - 1, "%s/%s",
+ key_dir, g_defaultPrivkeyFile);
}
if (g_caFile[0] != 0)
@@ -1105,41 +1529,93 @@ int32 main(int32 argc, char **argv)
/* User provided a CA file */
if (g_keyfilePath[0] != 0)
{
- snprintf(capath, FILENAME_MAX - 1, "%s/%s",
+ Snprintf(capath, FILENAME_MAX - 1, "%s/%s",
g_keyfilePath, g_caFile);
}
else
{
- snprintf(capath, FILENAME_MAX - 1, "%s", g_caFile);
+ Snprintf(capath, FILENAME_MAX - 1, "%s", g_caFile);
}
}
else
{
/* Default key */
- snprintf(capath, FILENAME_MAX - 1, "%s/%s",
- KEY_DIR, g_defaultCAFile);
+ Snprintf(capath, FILENAME_MAX - 1, "%s/%s",
+ key_dir, g_defaultCAFile);
}
- /* Still don't have a generic key loading function. Try RSA first and
- then ECC if that doesn't load */
-# ifdef USE_RSA
- if ((rc = matrixSslLoadRsaKeys(keys, certpath, keypath, g_password, capath)) < 0)
+# ifdef USE_TLS_1_3
+ if (g_use_psk)
{
-# endif /* USE_RSA */
-# ifdef USE_ECC_CIPHER_SUITE
- if ((rc = matrixSslLoadEcKeys(keys, certpath, keypath, g_password, capath)) < 0)
- {
- _psTrace("Unable to load key material. Exiting\n");
- return rc;
+ /* Load the TLS 1.3 test PSK. */
+ rc = matrixSslLoadTls13Psk(keys,
+ g_tls13_test_psk_256,
+ sizeof(g_tls13_test_psk_256),
+ g_tls13_test_psk_id,
+ sizeof(g_tls13_test_psk_id),
+ NULL);
+ if (rc < 0)
+ {
+ psTrace("Unable to load PSK keys.\n");
+ return rc;
+ }
}
-# else
- _psTrace("Unable to load key material. Please enable RSA or ECC from config.\n");
- return rc;
-# endif /* USE_ECC_CIPHER_SUITE */
-# ifdef USE_RSA
-}
-# endif /* USE_RSA */
+# endif
+# if !defined(USE_ONLY_PSK_CIPHER_SUITE)
+ {
+ matrixSslLoadKeysOpts_t loadKeysOpts;
+
+ Memset(&loadKeysOpts, 0, sizeof(loadKeysOpts));
+
+ if (g_allow_out_of_date_cert_chain)
+ {
+ loadKeysOpts.flags = LOAD_KEYS_OPT_ALLOW_OUT_OF_DATE_CERT_PARSE;
+ }
+ rc = matrixSslLoadKeys(keys,
+ certpath,
+ keypath,
+ g_password,
+ capath,
+ &loadKeysOpts);
+ if (rc < 0)
+ {
+ psTrace("Unable to load key material. Exiting\n");
+ return rc;
+ }
+ }
+# endif
+
+# ifdef USE_OCSP_RESPONSE
+ {
+ if (g_test_ocsp_stapling_good)
+ {
+# include "testkeys/OCSP/responses/OCSP_256_EC_GOOD.h"
+
+ rc = matrixSslLoadOCSPResponse(keys,
+ ocsp_256_ec_good,
+ sizeof(ocsp_256_ec_good));
+ if (rc < 0)
+ {
+ psTraceInt("matrixSslLoadOCSPResponse failed: %d\n", rc);
+ }
+ psTrace("Good OCSP response loaded for 256_EC.pem\n");
+ }
+ else if (g_test_ocsp_stapling_revoked)
+ {
+# include "testkeys/OCSP/responses/OCSP_256_EC_REVOKED.h"
+
+ rc = matrixSslLoadOCSPResponse(keys,
+ ocsp_256_ec_revoked,
+ sizeof(ocsp_256_ec_revoked));
+ if (rc < 0)
+ {
+ psTraceInt("matrixSslLoadOCSPResponse failed: %d\n", rc);
+ }
+ psTrace("Revoked OCSP response loaded for 256_EC.pem\n");
+ }
+ }
+# endif
# ifdef REQUIRE_DH_PARAMS
if (g_dhParamFile[0] != 0)
@@ -1147,23 +1623,23 @@ int32 main(int32 argc, char **argv)
/* User provided DH params */
if (g_keyfilePath[0] != 0)
{
- snprintf(certpath, FILENAME_MAX - 1, "%s/%s",
+ Snprintf(certpath, FILENAME_MAX - 1, "%s/%s",
g_keyfilePath, g_dhParamFile);
}
else
{
- snprintf(certpath, FILENAME_MAX - 1, "%s", g_dhParamFile);
+ Snprintf(certpath, FILENAME_MAX - 1, "%s", g_dhParamFile);
}
}
else
{
/* Default DH params */
- snprintf(certpath, FILENAME_MAX - 1, "%s/%s",
- KEY_DIR, g_defaultDHParamFile);
+ Snprintf(certpath, FILENAME_MAX - 1, "%s/%s",
+ key_dir, g_defaultDHParamFile);
}
if ((rc = matrixSslLoadDhParams(keys, certpath)) < 0)
{
- _psTrace("Unable to load static key material. Exiting\n");
+ psTrace("Unable to load static key material. Exiting\n");
return rc;
}
# endif
@@ -1183,7 +1659,7 @@ int32 main(int32 argc, char **argv)
/* Create the listening socket that will accept incoming connections */
if ((lfd = lsocketListen(g_port, &err)) == INVALID_SOCKET)
{
- _psTraceInt("Can't listen on port %d\n", g_port);
+ psTraceInt("Can't listen on port %d\n", g_port);
goto L_EXIT;
}
@@ -1209,8 +1685,12 @@ L_EXIT:
{
close(lfd);
}
+ matrixSslDeleteKeys(keys);
matrixSslClose();
-
+ psFreeList(g_groupList, NULL);
+ psFreeList(g_sigAlgsCertList, NULL);
+ psFreeList(g_sigAlgsList, NULL);
+ psFreeList(g_supportedVersionsList, NULL);
return 0;
}
@@ -1235,6 +1715,7 @@ static void closeConn(httpConn_t *cp, int32 reason)
/* psTraceBytes("closure alert", buf, len); */
if ((len = (int32) send(cp->fd, buf, len, MSG_DONTWAIT)) > 0)
{
+ psTraceBytes("++ sent:", buf, len);
matrixSslSentData(cp->ssl, len);
}
}
@@ -1243,7 +1724,7 @@ static void closeConn(httpConn_t *cp, int32 reason)
if (cp->parsebuf != NULL)
{
psAssert(cp->parsebuflen > 0);
- free(cp->parsebuf);
+ Free(cp->parsebuf);
cp->parsebuflen = 0;
}
@@ -1255,13 +1736,13 @@ static void closeConn(httpConn_t *cp, int32 reason)
}
if (reason >= 0)
{
-/* _psTraceInt("=== Closing Client %d ===\n", cp->fd); */
+/* psTraceInt("=== Closing Client %d ===\n", cp->fd); */
}
else
{
- _psTraceInt("=== Closing Client %d on Error ===\n", cp->fd);
+ psTraceInt("=== Closing Client %d on Error ===\n", cp->fd);
}
- free(cp);
+ Free(cp);
}
/******************************************************************************/
@@ -1273,9 +1754,9 @@ static SOCKET lsocketListen(short port, int32 *err)
struct sockaddr_in addr = { 0 };
SOCKET fd;
- if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
+ if ((fd = Socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
- _psTrace("Error creating listen socket\n");
+ psTrace("Error creating listen socket\n");
*err = SOCKET_ERRNO;
return INVALID_SOCKET;
}
@@ -1291,18 +1772,18 @@ static SOCKET lsocketListen(short port, int32 *err)
if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0)
{
close(fd);
- _psTrace("Can't bind socket. Port in use or insufficient privilege\n");
+ psTrace("Can't bind socket. Port in use or insufficient privilege\n");
*err = SOCKET_ERRNO;
return INVALID_SOCKET;
}
if (listen(fd, SOMAXCONN) < 0)
{
close(fd);
- _psTrace("Error listening on socket\n");
+ psTrace("Error listening on socket\n");
*err = SOCKET_ERRNO;
return INVALID_SOCKET;
}
- _psTraceInt("Listening on port %d\n", port);
+ psTraceInt("Listening on port %d\n", port);
return fd;
}
@@ -1362,10 +1843,10 @@ static int setSocketOptions(SOCKET fd)
*/
static int32 sighandlers(void)
{
- if (signal(SIGINT, sigintterm_handler) == SIG_ERR ||
- signal(SIGTERM, sigintterm_handler) == SIG_ERR ||
- signal(SIGPIPE, SIG_IGN) == SIG_ERR ||
- signal(SIGSEGV, sigsegv_handler) == SIG_ERR)
+ if (Signal(SIGINT, sigintterm_handler) == SIG_ERR ||
+ Signal(SIGTERM, sigintterm_handler) == SIG_ERR ||
+ Signal(SIGPIPE, SIG_IGN) == SIG_ERR ||
+ Signal(SIGSEGV, sigsegv_handler) == SIG_ERR)
{
return PS_PLATFORM_FAIL;
}
@@ -1375,7 +1856,7 @@ static int32 sighandlers(void)
/* Warn on segmentation violation */
static void sigsegv_handler(int unused)
{
- printf("Segfault! Please report this as a bug to support@peersec.com\n");
+ Printf("Segfault! Please report this as a bug to support@peersec.com\n");
exit(EXIT_FAILURE);
}
@@ -1383,7 +1864,7 @@ static void sigsegv_handler(int unused)
static void sigintterm_handler(int unused)
{
g_exitFlag = 1; /* Rudimentary exit flagging */
- printf("Exiting due to interrupt.\n");
+ Printf("Exiting due to interrupt.\n");
}
# endif /* POSIX */
@@ -1396,7 +1877,7 @@ static void sigintterm_handler(int unused)
*/
int32 main(int32 argc, char **argv)
{
- printf("USE_SERVER_SIDE_SSL must be enabled in matrixsslConfig.h at build" \
+ Printf("USE_SERVER_SIDE_SSL must be enabled in matrixsslConfig.h at build" \
" time to run this application\n");
return -1;
}
@@ -1405,11 +1886,11 @@ int32 main(int32 argc, char **argv)
/******************************************************************************/
#else
-# include
+# include "osdep_stdio.h"
int main(int argc, char **argv)
{
- printf("You need to #define MATRIX_USE_FILE_SYSTEM for this test\n");
+ Printf("You need to #define MATRIX_USE_FILE_SYSTEM for this test\n");
return 1;
}
diff --git a/common.mk b/common.mk
index 56ead70..5d1192a 100644
--- a/common.mk
+++ b/common.mk
@@ -5,388 +5,12 @@
#
#-------------------------------------------------------------------------------
-# Allow building inclusion paths relative to location of common.mk file.
-COMMON_MK_PATH:=$(dir $(lastword $(MAKEFILE_LIST)))
+# Find core library.
+-include corepath.mk
-# Allow extra CFLAGS, CPPFLAGS and LDFLAGS to be used.
-CFLAGS_DEBUGGABLE=$(DEBUGGABLE)
-CPPFLAGS_DEBUGGABLE=$(DEBUGGABLE)
-LDFLAGS += $(EXTRA_LDFLAGS) $(LDFLAGS_MAKEFILES)
-CFLAGS += $(CFLAGS_STANDARD) $(CFLAGS_PLATFORM) $(CFLAGS_ADDITIONAL) $(CFLAGS_WARNINGS) $(CFLAGS_CPU) $(CFLAGS_ASM) $(CFLAGS_PROFILE) $(CFLAGS_MAKEFILES) $(CFLAGS_DEBUGGABLE) $(CFLAGS_EXTRA) $(EXTRA_CFLAGS)
-CPPFLAGS += $(CPPFLAGS_STANDARD) $(CPPFLAGS_PLATFORM) $(CPPFLAGS_ADDITIONAL) $(CPPFLAGS_WARNINGS) $(CPPFLAGS_CPU) $(CPPFLAGS_CPPPU) $(CPPFLAGS_ASM) $(CPPFLAGS_PROFILE) $(CPPFLAGS_MAKEFILES) $(CPPFLAGS_DEBUGGABLE) $(CPPFLAGS_EXTRA) $(EXTRA_CPPFLAGS)
-
-#-------------------------------------------------------------------------------
-## Makefile variables that must be defined in this file
-# @param[out] $(BUILD) Set here for release or debug
-BUILD:=release ##< Release build strips binary and optimizes
-#BUILD:=debug ##< Debug build keeps debug symbols and disables compiler optimizations. Assembly language optimizations remain enabled
-
-#-------------------------------------------------------------------------------
-## Makefile variables that are read by this file.
-# @param[in] $(MATRIXSSL_ROOT) Must be set to root MatrixSSL directory
-# @param[in] $(CC) Used to determine the target platform, which will differ
-# from host if cross compiling.
-# @param[in] $(CPU) If set, should be the target cpu for the compiler,
-# suitable for the '-mcpu=' flag. See 'gcc --help=target' for valid values.
-# @param[in] $(SRC) List of source files to be compiled. Used to make $(OBJS),
-# the list of object files to build.
-
-#-------------------------------------------------------------------------------
-## Makefile variables that are modified by this file
-# @param[in,out] $(CFLAGS) Appended with many options as determined by this file, to be passed to compiler
-# @param[in,out] $(LDFLAGS) Appended with many options as determined by this file, to be passed to linker
-
-#-------------------------------------------------------------------------------
-## Makefile variables that are created by this file
-# @param[out] $(OSDEP) Set to platform code directory (./core/$OSDEP/osdep.c), based on $(CC)
-# @param[out] $(CCARCH) Set to compilers target architecture, based on $(CC)
-# @param[out] $(STRIP) Set to the executable to use to strip debug symbols from executables
-# @param[out] $(STROPS) Human readable description of relevant MatrixSSL compile options.
-# @param[out] $(O) Set to the target platform specific object file extension
-# @param[out] $(A) Set to the target phatform specific static library (archive) file extension
-# @param[out] $(E) Set to the target platform specific executable file extension
-# @param[out] $(OBJS) Set to the list of objects that is to be built
-
-#-------------------------------------------------------------------------------
-
-## Auto-detect cross compiler for some platforms based on environment variables
-
-# Execute commands in environment with default locale.
-CLEAN_ENV=LC_ALL=POSIX
-
-## Based on the value of CC, determine the target, eg.
-# x86_64-redhat-linux
-# i686-linux-gnu
-# x86_64-apple-darwin14.0.0
-# arm-linux-gnueabi
-# arm-linux-gnueabihf
-# arm-none-eabi
-# mips-linux-gnu
-# mipsisa64-octeon-elf-gcc
-# powerpc-linux-gnu
-# i386-redhat-linux
-# x86_64-redhat-linux
-ifeq '$(CCARCH)' ''
-CCARCH:=$(shell $(CLEAN_ENV) $(CC) $(CFLAGS_ARCHITECTURE_VARIANT) $(FLAGS_ARCHITECTURE_VARIANT) -print-multiarch)
-ifeq '$(CCARCH)' ''
-CCARCH:=$(shell $(CLEAN_ENV) $(CC) -v 2>&1 | sed -n '/Target: / s/// p')
-ifeq '$(CCARCH)' ''
-# Could not obtain target triplet: Try still -dumpmachine (supported by
-# some versions of GCC)
-CCARCH:=$(shell $(CLEAN_ENV) $(CC) -dumpmachine)
-ifeq '$(CCARCH)' ''
-$(error Unable to determine compiler architecture.
-$(CC) $(CFLAGS_ARCHITECTURE_VARIANT) $(FLAGS_ARCHITECTURE_VARIANT) -print-multiarch or $(CC) -v or $(CC) -dumpmachine does not work. Please, provide CCARCH manually via an environment variable.)
-endif
-endif
-endif
-ifeq ($(origin CCARCH),file)
-ifneq ($(MAKECMDGOALS),clean)
-ifneq ($(MAKECMDGOALS),clobber)
-$(info Compiling target architecture: $(CCARCH))
-$(info If this is incorrect, provide the CCARCH variable manually to make.)
-endif
-endif
-endif
-endif
-CCVER:=$(shell $(CC) --version 2>&1)
-STROPTS:="Built for $(CCARCH)"
-
-## uname of the Host environment, eg.
-# Linux
-# Darwin
-# @note Unused
-#UNAME:=$(shell uname)
-
-## Standard file extensions for Linux/OS X.
-O:=.o
-A:=.a
-E=
-
-# Check if this version of make supports undefine
-ifneq (,$(findstring undefine,$(.FEATURES)))
- HAVE_UNDEFINE:=1
+ifeq '$(CORE_PATH)' ''
+CORE_PATH:=$(patsubst %/,%/core,$(dir $(lastword $(MAKEFILE_LIST))))
endif
-#On OS X, Xcode sets CURRENT_VARIANT to normal, debug or profile
-ifneq (,$(findstring -apple,$(CCARCH)))
- ifneq (,$(findstring ebug,$(CONFIGURATION)))
- MATRIX_DEBUG:=1
- endif
-endif
-
-# Select options affecting C language and API standards to enable.
-C_STD:=
-ifneq (,$(findstring (GCC),$(CCVER)))
- ifneq (,$(findstring 3.4,$(CCVER)))
- # Enable linux platform extensions for APIs and provide the length of
- # types.
- # Also remove spurious warnings on some opaque types
- ifneq (,$(findstring x86_64,$(CCARCH)))
- C_STD := -D_GNU_SOURCE -D__SIZEOF_LONG_LONG__=8 -DSIZEOF_LONG=8
- else
- C_STD := -D_GNU_SOURCE -D__SIZEOF_LONG_LONG__=8 -DSIZEOF_LONG=4
- endif
- endif
-endif
-
-#Manually enable debug here
-#MATRIX_DEBUG:=1
-
-ifdef MATRIX_DEBUG
- OPT:=-O0 -g -DDEBUG -Wall
- #OPT+=-Wconversion
- STRIP:=test # no-op
-endif
-ifndef MATRIX_DEBUG
- OPT:=-O3 -Wall # Default compile for speed
- ifneq (,$(findstring -none,$(CCARCH)))
- OPT:=-Os -Wall # Compile bare-metal for size
- endif
- STRIP:=strip
-endif
-CFLAGS+=$(OPT) $(C_STD)
-
-ifdef MATRIX_SSL_TRACE
- CFLAGS+=-DUSE_SSL_HANDSHAKE_MSG_TRACE
- CFLAGS+=-DUSE_SSL_INFORMATIONAL_TRACE
- CFLAGS+=-DUSE_DTLS_DEBUG_TRACE
-endif
-
-ifeq "$(COMMON_MK_NO_TARGETS)" ""
-default: $(BUILD)
-
-debug:
- @$(MAKE) compile "MATRIX_DEBUG=1"
-
-release:
- @$(MAKE) $(JOBS) compile
-endif
-
-ifeq ($(SSH_PACKAGE),1)
- CFLAGS+=-DSSH_PACKAGE
-endif
-
-# 64 Bit Intel Target
-ifneq (,$(findstring x86_64-,$(CCARCH)))
- CFLAGS_ARCHITECTURE_VARIANT=-m64
- STROPTS+=", 64-bit Intel RSA/ECC ASM"
- # Provide flags for AES-NI if the host supports it (assumes Host is Target)
- ifneq (,$(findstring -linux,$(CCARCH)))
- ifeq ($(shell grep -o -m1 aes /proc/cpuinfo),aes)
- CFLAGS_ENABLE_AESNI=-maes -mpclmul -msse4.1
- CFLAGS_ENABLE_AES=-maes
- CFLAGS+=$(CFLAGS_ENABLE_AES)
- STROPTS+=", AES-NI ASM"
- endif
- endif
- ifneq (,$(findstring apple,$(CCARCH)))
- ifeq ($(shell sysctl -n hw.optional.aes),1)
- CFLAGS_ENABLE_AESNI=-maes -mpclmul -msse4.1
- CFLAGS_ENABLE_AES=-maes
- CFLAGS+=$(CFLAGS_ENABLE_AES)
- STROPTS+=", AES-NI ASM"
- endif
- endif
-endif
-
-# 32 Bit Intel Target
-ifneq (,$(findstring i586-,$(CCARCH)))
- CFLAGS_ARCHITECTURE_VARIANT=-m32
- ifneq (,$(findstring edison,$(shell uname -n)))
- ifneq (,$(findstring -O3,$(OPT)))
- #Edison does not like -O3
- OPT:=-O2
- endif
- CFLAGS+=-DEDISON
- CFLAGS_ENABLE_AESNI=-maes -mpclmul -msse4.1
- CFLAGS_ENABLE_AES=-maes
- CFLAGS+=$(CFLAGS_ENABLE_AES)
- STROPTS+=", 32-bit Intel RSA/ECC ASM, AES-NI ASM, Intel Edison"
- else
- STROPTS+=", 32-bit Intel RSA/ECC ASM"
- endif
-endif
-
-# 32 Bit Intel Target Alternate
-ifneq (,$(findstring i686-,$(CCARCH)))
- CFLAGS_ARCHITECTURE_VARIANT=-m32
- STROPTS+=", 32-bit Intel RSA/ECC ASM"
-endif
-ifneq (,$(findstring i386-,$(CCARCH)))
- STROPTS+=", 32-bit Intel RSA/ECC ASM"
-endif
-
-# MIPS Target
-ifneq (,$(findstring mips-,$(CCARCH)))
- STROPTS+=", 32-bit MIPS RSA/ECC ASM"
-endif
-
-# MIPS64 Target
-ifneq (,$(filter mips%64-,$(CCARCH)))
-endif
-
-# ARM Target
-ifneq (,$(findstring arm,$(CCARCH)))
- STROPTS+=", 32-bit ARM RSA/ECC ASM"
- ifneq (,$(findstring linux-,$(CCARCH)))
- HARDWARE:=$(shell sed -n '/Hardware[ \t]*: / s/// p' /proc/cpuinfo)
- # Raspberry Pi Host and Target
- ifneq (,$(findstring BCM2708,$(HARDWARE)))
- CFLAGS+=-DRASPBERRYPI -mfpu=vfp -mfloat-abi=hard -ffast-math -march=armv6zk -mtune=arm1176jzf-s
- STROPTS+=", Raspberry Pi"
- endif
- # Raspberry Pi 2 Host and Target
- ifneq (,$(findstring BCM2709,$(HARDWARE)))
- ifneq (,$(findstring 4.6,$(CCVER)))
- CFLAGS+=-march=armv7-a
- else
- # Newer gcc (4.8+ supports this cpu type)
- CFLAGS+=-mcpu=cortex-a7
- endif
- CFLAGS+=-DRASPBERRYPI2 -mfpu=neon-vfpv4 -mfloat-abi=hard
- STROPTS+=", Raspberry Pi2"
- endif
- # Beagleboard/Beaglebone Host and Target
- ifneq (,$(findstring AM33XX,$(HARDWARE)))
- CFLAGS+=-BEAGLEBOARD -mfpu=neon -mfloat-abi=hard -ffast-math -march=armv7-a -mtune=cortex-a8
- STROPTS+=", Beagleboard"
- endif
- # Samsung Exynos 5 (Can also -mtune=cortex-a15 or a8)
- ifneq (,$(findstring EXYNOS5,$(HARDWARE)))
- CFLAGS+=-DEXYNOS5 -mfpu=neon -mfloat-abi=hard -ffast-math -march=armv7-a
- STROPTS+=", Exynos 5"
- endif
- ifdef HAVE_UNDEFINE
- undefine HARDWARE
- endif
- endif
-endif
-
-CFLAGS_GARBAGE_COLLECTION=-ffunction-sections -fdata-sections
-ifdef MATRIX_DEBUG
-CFLAGS+=$(CFLAGS_GARBAGE_COLLECTION)
-endif
-ifndef MATRIX_DEBUG
-CFLAGS_OMIT_FRAMEPOINTER=-fomit-frame-pointer
-CFLAGS+=$(CFLAGS_GARBAGE_COLLECTION) $(CFLAGS_OMIT_FRAMEPOINTER)
-endif
-
-# If we are using clang (it may be invoked via 'cc' or 'gcc'),
-# handle minor differences in compiler behavior vs. gcc
-ifneq (,$(findstring clang,$(CCVER)))
- CFLAGS+=-Wno-error=unused-variable -Wno-error=\#warnings -Wno-error=\#pragma-messages
-endif
-
-# Handle differences between the OS X ld and GNU ld
-ifneq (,$(findstring -apple,$(CCARCH)))
- LDFLAGS_GARBAGE_COLLECTION=-Wl,-dead_strip
-else
- LDFLAGS_GARBAGE_COLLECTION+=-Wl,--gc-sections
-endif
-
-# Optionally turn on garbage collection.
-ifeq '$(NO_LINKER_GARBAGE_COLLECTION)' ''
-LDFLAGS += $(LDFLAGS_GARBAGE_COLLECTION)
-endif
-
-CFLAGS+=-I$(MATRIXSSL_ROOT)
-
-#ifdef USE_OPENSSL_CRYPTO
-#USE_OPENSSL_CRYPTO:=1
-ifdef USE_OPENSSL_CRYPTO
- OPENSSL_ROOT:=/opt/openssl-1.0.2d
- ifdef OPENSSL_ROOT
- # Statically link against a given openssl tree
- CFLAGS+=-I$(OPENSSL_ROOT)/include
- LDFLAGS+=$(OPENSSL_ROOT)/libcrypto.a -ldl
- endif
- ifneq (,$(findstring -apple,$(CCARCH)))
- # Dynamically link against the system default openssl tree
- # Apple has deprecated the built in openssl, so suppress warnings here
- CFLAGS+=-Wno-error=deprecated-declarations -Wno-deprecated-declarations
- LDFLAGS+=-lcrypto
- OPENSSL_ROOT=included_in_the_OS
- endif
- ifneq (,$(findstring -linux,$(CCARCH)))
- # Dynamically link against the sytem default openssl tree
- LDFLAGS+=-lcrypto
- OPENSSL_ROOT=shall_be_included_in_distribution
- endif
- ifndef OPENSSL_ROOT
- $(error Please define OPENSSL_ROOT)
- endif
- CFLAGS+=-DUSE_OPENSSL_CRYPTO
- STROPTS+=", USE_OPENSSL_CRYPTO"
-endif
-#endif
-
-# Include optional support for libsodium
--include $(COMMON_MK_PATH)/makefiles/libsodium_support.mk
-
-# Linux Target
-ifneq (,$(findstring -linux,$(CCARCH)))
- OSDEP:=POSIX
- #For USE_HIGHRES_TIME
- LDFLAGS+=-lrt
- #For multithreading
- LDFLAGS+=-lpthread
-endif
-
-# OS X Target
-ifneq (,$(findstring -apple,$(CCARCH)))
- OSDEP:=POSIX
- CFLAGS+=-isystem -I/usr/include
-endif
-
-# Bare Metal / RTOS Target
-ifneq (,$(findstring -none,$(CCARCH)))
- OSDEP:=METAL
- CFLAGS+=-fno-exceptions -fno-unwind-tables -fno-non-call-exceptions -fno-asynchronous-unwind-tables -ffreestanding -fno-builtin -nostartfiles
- ifneq (,$(findstring cortex-,$(CPU)))
- CFLAGS+=-mthumb -mcpu=$(CPU) -mslow-flash-data
- ifeq (cortex-m4,$(CPU))
- CFLAGS+=-mcpu=cortex-m4 -mtune=cortex-m4
- endif
- ifeq (cortex-m3,$(CPU))
- CFLAGS+=-mcpu=cortex-m3 -mtune=cortex-m3 -mfpu=vpf
- endif
- ifeq (cortex-m0,$(CPU))
- CFLAGS+=-mcpu=cortex-m0 -mtune=cortex-m0 -mfpu=vpf
- endif
- endif
-endif
-
-# This must be defined after OSDEP, because core/Makefile uses OSDEP in SRC
-OBJS=$(SRC:.c=.o) $(SRC:.S:*.o)
-
-# Remove extra spaces in CFLAGS
-#CFLAGS=$(strip $(CFLAGS))
-
-ifneq (,$(filter defines,$(MAKECMDGOALS)))
-# Display the precompiler defines for the current build settings
-# The rule is only available if explicitly requested on command line.
-
-defines:
- :| $(CC) $(CFLAGS) -dM -E -x c -
-endif
-
-# Introduce here paths to additional build files (services) available.
-use_prepkg_mk=$(MATRIXSSL_ROOT)/makefiles/prepkg.mk
-use_testsupp_mk=$(MATRIXSSL_ROOT)/makefiles/testsupp.mk
-use_rules_mk=$(MATRIXSSL_ROOT)/makefiles/rules.mk
-
-# Provide names of built packages for interpackage references
-# Note: Some of these may not be built in some cases.
-LIBCORE_S_A=$(MATRIXSSL_ROOT)/core/libcore_s$(A)
-LIBCRYPT_S_A=$(MATRIXSSL_ROOT)/crypto/libcrypt_s$(A)
-LIBCMS_S_A=$(MATRIXSSL_ROOT)/crypto/cms/libcms_s$(A)
-LIBSSL_S_A=$(MATRIXSSL_ROOT)/matrixssl/libssl_s$(A)
-
-# Optional external libraries
-LIBZ=-lz
-LIBDL=-ldl
-LIBTHREAD=-lpthread
-
-# When linking use default compiler front-end
-CC_LD=$(CC)
+# The common.mk is replaced by equivalent functionality within core.
+include $(CORE_PATH)/makefiles/detect-and-rules.mk
diff --git a/configs/default/coreConfig.h b/configs/default/coreConfig.h
index d8a568f..a0e9380 100644
--- a/configs/default/coreConfig.h
+++ b/configs/default/coreConfig.h
@@ -5,7 +5,7 @@
* Configuration settings for Matrix core module.
*/
/*
- * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) 2013-2018 INSIDE Secure Corporation
* Copyright (c) PeerSec Networks, 2002-2011
* All Rights Reserved
*
@@ -37,12 +37,64 @@
/******************************************************************************/
-/* Configurable features */
+/* Debug and tracing configuration */
/******************************************************************************/
+
+/**
+ Select tracing facility.
+ Default: Use psLogf, which is used in all of MatrixSSL, CL etc. and
+ allows log redirection.
+
+ On the smallest embedded targets platform using PS_NO_LOGF may provide
+ footprint benefits but will limit logging capabilities.
+ */
+
+/* Uncomment to use previous generation logging facility: */
+/* #define PS_NO_LOGF */
+
+/* When using psLogf, logging messages by default go to the binary, but
+ they are not shown unless enabled by environment variables or
+ filter loaded with psLogfSetHookEnabledCheck() function.
+
+ Enable macros below to completely remove specified logging class. */
+/* #define PS_NO_LOGF_FATAL */
+/* #define PS_NO_LOGF_ERROR */
+/* #define PS_NO_LOGF_WARNING */
+/* #define PS_NO_LOGF_INFO */
+/* #define PS_NO_LOGF_VERBOSE */
+/* #define PS_NO_LOGF_DEBUG */
+/* #define PS_NO_LOGF_TRACE */
+/* #define PS_NO_LOGF_CALL_TRACE */
+
+/* MatrixSSL contains extensive tracing capabilities. The lines below
+ disable trace and call trace message levels, unless debug build.
+ Omitting the messages will improve performance and create smaller
+ executables with a degradation in debugging capabilities. */
+# ifndef DEBUG
+# ifndef PS_NO_LOGF_TRACE
+# define PS_NO_LOGF_TRACE
+# endif
+# ifndef PS_NO_LOGF_CALL_TRACE
+# define PS_NO_LOGF_CALL_TRACE
+# endif
+# endif
+
+/* File and line information consumes some storage and may reveal details on
+ structure of software. This information is omitted from production builds,
+ but included within "debug build". If you want to include file and line
+ information also on production builds, disable the lines below. */
+# ifndef DEBUG
+# ifndef PS_NO_LOGF_FILELINE
+# define PS_NO_LOGF_FILELINE
+# endif
+# endif
+
/**
Enable various levels of trace.
When these option is turned off, messages are silently
discarded and their text does not take space in the binary image.
+ Note: These are legacy configuration, and it is recommended to use
+ PS_NO_LOGF_* above, unless PS_NO_LOGF is set.
*/
/* #define USE_CORE_TRACE */
# ifndef NO_CORE_ERROR
@@ -52,18 +104,9 @@
# define USE_CORE_ASSERT
# endif
-/**
- When logging or tracing use psLog.h APIs.
-
- Generally, using psLog.h allows more control over logging, because
- it is possible to filter log and tracing information more efficiently.
- However, this feature comes with a footprint cost, so the feature can be
- disabled by setting NO_PS_LOGF_COMMON or by commenting out USE_PS_LOGF_COMMON
- below.
- */
-#ifdef NO_PS_LOGF_COMMON
-#define USE_PS_LOGF_COMMON
-#endif /* NO_PS_LOGF_COMMON */
+/******************************************************************************/
+/* Other Configurable features */
+/******************************************************************************/
/**
If enabled, calls to the psError set of APIs will perform a platform
@@ -84,11 +127,17 @@
# endif /* NO_MULTITHREADING */
/**
- Include the psNetwork family of APIs
+ Include the psNetwork family of APIs.
These APIs allow simple high-level socket api.
+ The API derive from BSD Sockets, and therefore it can only be used
+ on devices which have the prerequisitive APIs.
+ MatrixSSL itself can be used also be used without PS networking, but
+ many of example programs and MatrixSSLNet are based on PS networking.
*/
-# define USE_PS_NETWORKING
+# ifndef NO_PS_NETWORKING
+# define USE_PS_NETWORKING
+# endif /* NO_PS_NETWORKING */
#endif /* _h_PS_CORECONFIG */
diff --git a/configs/default/cryptoConfig.h b/configs/default/cryptoConfig.h
index c5ade0e..aa08c14 100644
--- a/configs/default/cryptoConfig.h
+++ b/configs/default/cryptoConfig.h
@@ -64,6 +64,13 @@
# define MIN_RSA_BITS 1024
+/* The configuration can define set minimum for RSA public exponent.
+
+ For CL crypto, the default is 65537 (according to FIPS 186-4 standard).
+ It can be overridden on line below:
+ */
+/* #define MIN_RSA_PUBLIC_EXPONENT 65537 *//* Valid values 3, 5, 17, 65537. */
+
# define MIN_DH_BITS 1024
# define USE_BURN_STACK/**< @security Zero sensitive data from the stack. */
@@ -78,6 +85,16 @@
/**< @note Enable verification of DSA signatures in certificate validation.
Works only when using the CL/SL library. @pre USE_CERT_PARSE. */
/* #define USE_DSA_VERIFY */
+# ifdef USE_DH
+/**< @note Enable this if you intent to support Diffie-Hellman groups larger
+ than 4096. Usually such large groups are not used. */
+/* #define USE_LARGE_DH_GROUPS */
+# endif /* USE_DH */
+/**< @note Enable ECDHE with Curve25519. */
+# define USE_X25519
+/**< @note Enable Pure EdDSA Curve25519 (Ed25519) signatures.
+ @pre USE_ECC, USE_SHA512. */
+# define USE_ED25519
/******************************************************************************/
/**
@@ -125,11 +142,22 @@
TLS clients and servers. These cipher suites are not allowed in FIPS
mode of operation.
*/
-/* #define USE_CHACHA20_POLY1305_IETF */
+# define USE_CHACHA20_POLY1305_IETF
/** @security 3DES is still relatively secure, however is deprecated for TLS */
# define USE_3DES
+/******************************************************************************/
+/**
+ Legacy ciphers.
+ These ciphers have been deprecated, but may be occasionally required
+ for legacy compatibility. Usage of these cipher suites should be avoided
+ as these may represent small or moderate risk.
+
+ Note: The RC4 cipher below need to disabled according to RFC 7465.
+*/
+/* #define USE_ARC4 */
+
/******************************************************************************/
/**
Digest algorithms.
@@ -184,6 +212,14 @@
/* Please enable, unless using no HMAC algorithms. */
# define USE_HMAC
+/**
+ HMAC-based Extract-and-Expand Key Derivation Function (HKDF) (RFC 5869).
+ Needed in TLS 1.3 key derivation.
+*/
+# if defined(USE_HMAC_SHA256) || defined(USE_HMAC_SHA384)
+# define USE_HKDF
+# endif
+
/******************************************************************************/
/**
X.509 Certificates/PKI
diff --git a/configs/default/matrixsslConfig.h b/configs/default/matrixsslConfig.h
index a4c0347..472b4b1 100644
--- a/configs/default/matrixsslConfig.h
+++ b/configs/default/matrixsslConfig.h
@@ -75,6 +75,11 @@ extern "C" {
at the cost of a slower TLS handshake.
*/
+/** TLS 1.3 ciphers */
+# define USE_TLS_AES_128_GCM_SHA256
+# define USE_TLS_AES_256_GCM_SHA384
+# define USE_TLS_CHACHA20_POLY1305_SHA256
+
/** Ephemeral ECC DH keys, ECC DSA certificates */
# define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA/**< @security NIST_SHOULD */
# define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA/**< @security NIST_MAY */
@@ -166,6 +171,17 @@ extern "C" {
TLS_DHE_DSS_WITH_* and TLS_RSA_WITH_AES_*_CCM cipher suites cannot be
enabled as they are not supported. */
+/******************************************************************************/
+/**
+ Legacy cipher suites.
+ These cipher suites have been deprecated, but may be occasionally required
+ for legacy compatibility. Usage of these cipher suites should be avoided
+ as these may represent small or moderate risk.
+
+ Note: The RC4 cipher suites below need to disabled according to RFC 7465.
+*/
+/* #define USE_SSL_RSA_WITH_RC4_128_SHA *//**< @security NIST_SHALL_NOT */
+
/******************************************************************************/
/**
Ephemeral key cache support.
@@ -183,15 +199,23 @@ extern "C" {
/**
Configure Support for TLS protocol versions.
Define one of:
- USE_TLS_1_2_AND_ABOVE
- USE_TLS_1_1_AND_ABOVE
- USE_TLS_1_0_AND_ABOVE
+ USE_TLS_1_2_AND_ABOVE (TLS 1.2 and 1.3)
+ USE_TLS_1_1_AND_ABOVE (TLS 1.1, 1.2 and 1.3)
+ USE_TLS_1_0_AND_ABOVE (TLS 1.0, 1.1, 1.2 and 1.3)
@note There is no option for enabling SSL3.0 at this level
*/
# define USE_TLS_1_1_AND_ABOVE/**< @security default 1_1_AND_ABOVE */
/* #define USE_TLS_1_2_AND_ABOVE *//**< @security better than 1_1_AND_ABOVE if no backwards compatiblity concerns */
/* #define USE_TLS_1_0_AND_ABOVE *//**< @security no longer recommended. */
+/** Enable support for session resumption in TLS 1.3. */
+# define USE_TLS_1_3_RESUMPTION
+
+/** TLS 1.3 code has not yet been footprint-optimized. For this reason,
+ it is possible to separately leave all TLS 1.3 code out of the build
+ by enabling this. */
+/* #define DISABLE_TLS_1_3 */
+
/******************************************************************************/
/**
Datagram TLS support.
diff --git a/configs/noecc/coreConfig.h b/configs/noecc/coreConfig.h
index d8a568f..a0e9380 100644
--- a/configs/noecc/coreConfig.h
+++ b/configs/noecc/coreConfig.h
@@ -5,7 +5,7 @@
* Configuration settings for Matrix core module.
*/
/*
- * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) 2013-2018 INSIDE Secure Corporation
* Copyright (c) PeerSec Networks, 2002-2011
* All Rights Reserved
*
@@ -37,12 +37,64 @@
/******************************************************************************/
-/* Configurable features */
+/* Debug and tracing configuration */
/******************************************************************************/
+
+/**
+ Select tracing facility.
+ Default: Use psLogf, which is used in all of MatrixSSL, CL etc. and
+ allows log redirection.
+
+ On the smallest embedded targets platform using PS_NO_LOGF may provide
+ footprint benefits but will limit logging capabilities.
+ */
+
+/* Uncomment to use previous generation logging facility: */
+/* #define PS_NO_LOGF */
+
+/* When using psLogf, logging messages by default go to the binary, but
+ they are not shown unless enabled by environment variables or
+ filter loaded with psLogfSetHookEnabledCheck() function.
+
+ Enable macros below to completely remove specified logging class. */
+/* #define PS_NO_LOGF_FATAL */
+/* #define PS_NO_LOGF_ERROR */
+/* #define PS_NO_LOGF_WARNING */
+/* #define PS_NO_LOGF_INFO */
+/* #define PS_NO_LOGF_VERBOSE */
+/* #define PS_NO_LOGF_DEBUG */
+/* #define PS_NO_LOGF_TRACE */
+/* #define PS_NO_LOGF_CALL_TRACE */
+
+/* MatrixSSL contains extensive tracing capabilities. The lines below
+ disable trace and call trace message levels, unless debug build.
+ Omitting the messages will improve performance and create smaller
+ executables with a degradation in debugging capabilities. */
+# ifndef DEBUG
+# ifndef PS_NO_LOGF_TRACE
+# define PS_NO_LOGF_TRACE
+# endif
+# ifndef PS_NO_LOGF_CALL_TRACE
+# define PS_NO_LOGF_CALL_TRACE
+# endif
+# endif
+
+/* File and line information consumes some storage and may reveal details on
+ structure of software. This information is omitted from production builds,
+ but included within "debug build". If you want to include file and line
+ information also on production builds, disable the lines below. */
+# ifndef DEBUG
+# ifndef PS_NO_LOGF_FILELINE
+# define PS_NO_LOGF_FILELINE
+# endif
+# endif
+
/**
Enable various levels of trace.
When these option is turned off, messages are silently
discarded and their text does not take space in the binary image.
+ Note: These are legacy configuration, and it is recommended to use
+ PS_NO_LOGF_* above, unless PS_NO_LOGF is set.
*/
/* #define USE_CORE_TRACE */
# ifndef NO_CORE_ERROR
@@ -52,18 +104,9 @@
# define USE_CORE_ASSERT
# endif
-/**
- When logging or tracing use psLog.h APIs.
-
- Generally, using psLog.h allows more control over logging, because
- it is possible to filter log and tracing information more efficiently.
- However, this feature comes with a footprint cost, so the feature can be
- disabled by setting NO_PS_LOGF_COMMON or by commenting out USE_PS_LOGF_COMMON
- below.
- */
-#ifdef NO_PS_LOGF_COMMON
-#define USE_PS_LOGF_COMMON
-#endif /* NO_PS_LOGF_COMMON */
+/******************************************************************************/
+/* Other Configurable features */
+/******************************************************************************/
/**
If enabled, calls to the psError set of APIs will perform a platform
@@ -84,11 +127,17 @@
# endif /* NO_MULTITHREADING */
/**
- Include the psNetwork family of APIs
+ Include the psNetwork family of APIs.
These APIs allow simple high-level socket api.
+ The API derive from BSD Sockets, and therefore it can only be used
+ on devices which have the prerequisitive APIs.
+ MatrixSSL itself can be used also be used without PS networking, but
+ many of example programs and MatrixSSLNet are based on PS networking.
*/
-# define USE_PS_NETWORKING
+# ifndef NO_PS_NETWORKING
+# define USE_PS_NETWORKING
+# endif /* NO_PS_NETWORKING */
#endif /* _h_PS_CORECONFIG */
diff --git a/configs/noecc/cryptoConfig.h b/configs/noecc/cryptoConfig.h
index b49a44f..30dbf7e 100644
--- a/configs/noecc/cryptoConfig.h
+++ b/configs/noecc/cryptoConfig.h
@@ -64,6 +64,13 @@
# define MIN_RSA_BITS 1024
+/* The configuration can define set minimum for RSA public exponent.
+
+ For CL crypto, the default is 65537 (according to FIPS 186-4 standard).
+ It can be overridden on line below:
+ */
+/* #define MIN_RSA_PUBLIC_EXPONENT 65537 *//* Valid values 3, 5, 17, 65537. */
+
# define MIN_DH_BITS 1024
# define USE_BURN_STACK/**< @security Zero sensitive data from the stack. */
@@ -78,6 +85,16 @@
/**< @note Enable verification of DSA signatures in certificate validation.
Works only when using the CL/SL library. @pre USE_CERT_PARSE. */
/* #define USE_DSA_VERIFY */
+# ifdef USE_DH
+/**< @note Enable this if you intent to support Diffie-Hellman groups larger
+ than 4096. Usually such large groups are not used. */
+/* #define USE_LARGE_DH_GROUPS */
+# endif /* USE_DH */
+/**< @note Enable ECDHE with Curve25519. */
+/* #define USE_X25519 */
+/**< @note Enable Pure EdDSA Curve25519 (Ed25519) signatures.
+ @pre USE_ECC, USE_SHA512. */
+/* #define USE_ED25519 */
/******************************************************************************/
/**
@@ -125,11 +142,22 @@
TLS clients and servers. These cipher suites are not allowed in FIPS
mode of operation.
*/
-/* #define USE_CHACHA20_POLY1305_IETF */
+# define USE_CHACHA20_POLY1305_IETF
/** @security 3DES is still relatively secure, however is deprecated for TLS */
# define USE_3DES
+/******************************************************************************/
+/**
+ Legacy ciphers.
+ These ciphers have been deprecated, but may be occasionally required
+ for legacy compatibility. Usage of these cipher suites should be avoided
+ as these may represent small or moderate risk.
+
+ Note: The RC4 cipher below need to disabled according to RFC 7465.
+*/
+/* #define USE_ARC4 */
+
/******************************************************************************/
/**
Digest algorithms.
@@ -184,6 +212,14 @@
/* Please enable, unless using no HMAC algorithms. */
# define USE_HMAC
+/**
+ HMAC-based Extract-and-Expand Key Derivation Function (HKDF) (RFC 5869).
+ Needed in TLS 1.3 key derivation.
+*/
+# if defined(USE_HMAC_SHA256) || defined(USE_HMAC_SHA384)
+# define USE_HKDF
+# endif
+
/******************************************************************************/
/**
X.509 Certificates/PKI
diff --git a/configs/noecc/matrixsslConfig.h b/configs/noecc/matrixsslConfig.h
index 2e018e7..29e697b 100644
--- a/configs/noecc/matrixsslConfig.h
+++ b/configs/noecc/matrixsslConfig.h
@@ -75,6 +75,11 @@ extern "C" {
at the cost of a slower TLS handshake.
*/
+/** TLS 1.3 ciphers */
+# define USE_TLS_AES_128_GCM_SHA256
+# define USE_TLS_AES_256_GCM_SHA384
+# define USE_TLS_CHACHA20_POLY1305_SHA256
+
/** Ephemeral ECC DH keys, ECC DSA certificates */
/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA *//**< @security NIST_SHOULD */
/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA *//**< @security NIST_MAY */
@@ -166,6 +171,17 @@ extern "C" {
TLS_DHE_DSS_WITH_* and TLS_RSA_WITH_AES_*_CCM cipher suites cannot be
enabled as they are not supported. */
+/******************************************************************************/
+/**
+ Legacy cipher suites.
+ These cipher suites have been deprecated, but may be occasionally required
+ for legacy compatibility. Usage of these cipher suites should be avoided
+ as these may represent small or moderate risk.
+
+ Note: The RC4 cipher suites below need to disabled according to RFC 7465.
+*/
+/* #define USE_SSL_RSA_WITH_RC4_128_SHA *//**< @security NIST_SHALL_NOT */
+
/******************************************************************************/
/**
Ephemeral key cache support.
@@ -183,15 +199,23 @@ extern "C" {
/**
Configure Support for TLS protocol versions.
Define one of:
- USE_TLS_1_2_AND_ABOVE
- USE_TLS_1_1_AND_ABOVE
- USE_TLS_1_0_AND_ABOVE
+ USE_TLS_1_2_AND_ABOVE (TLS 1.2 and 1.3)
+ USE_TLS_1_1_AND_ABOVE (TLS 1.1, 1.2 and 1.3)
+ USE_TLS_1_0_AND_ABOVE (TLS 1.0, 1.1, 1.2 and 1.3)
@note There is no option for enabling SSL3.0 at this level
*/
# define USE_TLS_1_1_AND_ABOVE/**< @security default 1_1_AND_ABOVE */
/* #define USE_TLS_1_2_AND_ABOVE *//**< @security better than 1_1_AND_ABOVE if no backwards compatiblity concerns */
/* #define USE_TLS_1_0_AND_ABOVE *//**< @security no longer recommended. */
+/** Enable support for session resumption in TLS 1.3. */
+# define USE_TLS_1_3_RESUMPTION
+
+/** TLS 1.3 code has not yet been footprint-optimized. For this reason,
+ it is possible to separately leave all TLS 1.3 code out of the build
+ by enabling this. */
+# define DISABLE_TLS_1_3
+
/******************************************************************************/
/**
Datagram TLS support.
diff --git a/configs/nonfips/coreConfig.h b/configs/nonfips/coreConfig.h
deleted file mode 100644
index 1dc1ecf..0000000
--- a/configs/nonfips/coreConfig.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/**
- * @file coreConfig.h
- * @version $Format:%h%d$
- *
- * Configuration settings for Matrix core module.
- */
-/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
- *
- * The latest version of this code is available at http://www.matrixssl.org
- *
- * This software is open source; 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.
- *
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
- *
- * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
- */
-/******************************************************************************/
-
-#ifndef _h_PS_CORECONFIG
-#define _h_PS_CORECONFIG
-
-
-/******************************************************************************/
-/* Configurable features */
-/******************************************************************************/
-/**
- Enable various levels of trace.
- When these option is turned off, messages are silently
- discarded and their text does not take space in the binary image.
-*/
-//#define USE_CORE_TRACE
-#ifndef NO_CORE_ERROR
- #define USE_CORE_ERROR
-#endif
-#ifndef NO_CORE_ASSERT
- #define USE_CORE_ASSERT
-#endif
-
-/**
- If enabled, calls to the psError set of APIs will perform a platform
- abort on the exeutable to aid in debugging.
-*/
-#ifdef DEBUG
-//#define HALT_ON_PS_ERROR /* NOT RECOMMENDED FOR PRODUCTION BUILDS */
-#endif
-
-/**
- Include the psCoreOsdepMutex family of APIs
-
- @note If intending to compile crypto-cl, then this flag should
- always be set.
-*/
-#ifndef NO_MULTITHREADING
-#define USE_MULTITHREADING
-#endif /* NO_MULTITHREADING */
-
-/**
- Include the psNetwork family of APIs
-
- These APIs allow simple high-level socket api.
- */
-#define USE_PS_NETWORKING
-
-#endif /* _h_PS_CORECONFIG */
-
-/******************************************************************************/
-
diff --git a/configs/nonfips/cryptoConfig.h b/configs/nonfips/cryptoConfig.h
deleted file mode 100644
index 3a07dc4..0000000
--- a/configs/nonfips/cryptoConfig.h
+++ /dev/null
@@ -1,217 +0,0 @@
-/**
- * @file cryptoConfig.h
- * @version $Format:%h%d$
- *
- * Configuration file for crypto features.
- */
-/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
- *
- * The latest version of this code is available at http://www.matrixssl.org
- *
- * This software is open source; 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.
- *
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
- *
- * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
- */
-/******************************************************************************/
-
-#ifndef _h_PS_CRYPTOCONFIG
-#define _h_PS_CRYPTOCONFIG
-
-/******************************************************************************/
-/* Configurable features */
-/******************************************************************************/
-/**
- Define to enable psTrace*Crypto APIs for debugging the crypto module.
-*/
-//#define USE_CRYPTO_TRACE
-
-#ifdef DEBUG
-//#define CRYPTO_ASSERT /**< Extra sanity asserts */
-#endif
-
-/******************************************************************************/
-/*
- Use built-in cryptographic library delivered with MatrixSSL
-*/
-#define USE_NATIVE_RSA /* Default built-in software support */
-
-/******************************************************************************/
-/**
- Security related settings.
-
- @security MIN_*_BITS is the minimum supported key sizes in bits, weaker
- keys will be rejected.
-*/
-#define MIN_ECC_BITS 192/**< @security Affects ECC curves below */
-
-#define MIN_RSA_BITS 1024
-
-#define MIN_DH_BITS 1024
-
-#define USE_BURN_STACK/**< @security Zero sensitive data from the stack. */
-
-/******************************************************************************/
-/**
- Public-Key Algorithm Support.
-*/
-#define USE_RSA
-#define USE_ECC
-#define USE_DH
-/**< @note Enable verification of DSA signatures in certificate validation.
- Works only when using the CL/SL library. */
-//#define USE_DSA_VERIFY
-
-/******************************************************************************/
-/**
- Build the PKCS and ASN1 extra CL sublibraries.
- These are needed by the CL_PKCS API.
-*/
-
-/******************************************************************************/
-
-/**
- Define to enable the individual NIST Prime curves.
- @see http://csrc.nist.gov/groups/ST/toolkit/documents/dss/NISTReCur.pdf
-*/
-#ifdef USE_ECC
- #define USE_SECP192R1/**< @security FIPS allowed for sig ver only. */
- #define USE_SECP224R1
- #define USE_SECP256R1/**< @security NIST_SHALL */
- #define USE_SECP384R1/**< @security NIST_SHALL */
- #define USE_SECP521R1
-#endif
-
-/**
- Define to enable the individual Brainpool curves.
- @see https://tools.ietf.org/html/rfc5639
- @security WARNING: Public points on Brainpool curves are not validated
-*/
-#ifdef USE_ECC
-//#define USE_BRAIN224R1
-//#define USE_BRAIN256R1
-//#define USE_BRAIN384R1
-//#define USE_BRAIN512R1
-#endif
-
-/******************************************************************************/
-/**
- Symmetric and AEAD ciphers.
- @security Deprecated ciphers must be enabled in cryptolib.h
-*/
-//#define USE_AES /* Enable/Disable AES */
-#define USE_AES_CBC
-#define USE_AES_GCM
-
-#ifdef USE_LIBSODIUM
-//#define USE_CHACHA20_POLY1305
-#endif
-
-/** @security 3DES is still relatively secure, however is deprecated for TLS */
-#define USE_3DES
-
-/******************************************************************************/
-/**
- Digest algorithms.
-
- @note SHA256 and above are used with TLS 1.2, and also used for
- certificate signatures on some certificates regardless of TLS version.
-
- @security MD5 is deprecated, but still required in combination with SHA-1
- for TLS handshakes before TLS 1.2, meaning that the strength is at least
- that of SHA-1 in this usage. The only other usage of MD5 by TLS is for
- certificate signatures and MD5 based cipher suites. Both of which are
- disabled at compile time by default.
-
- @security SHA1 will be deprecated in the future, but is still required in
- combination with MD5 for versions prior to TLS 1.2. In addition, SHA1
- certificates are still commonly used, so SHA1 support may be needed
- to validate older certificates. It is possible to completely disable
- SHA1 using TLS 1.2 and SHA2 based ciphersuites, and interacting
- only with newer certificates.
-*/
-//#define USE_SHA224 /**< @note Used only for cert signature */
-#define USE_SHA256/**< @note Required for TLS 1.2 and above */
-#define USE_HMAC_SHA256
-#define USE_SHA384/**< @pre USE_SHA512 */
-#define USE_HMAC_SHA384
-#define USE_SHA512
-
-/**
- @security SHA-1 based hashes are deprecated but enabled by default
- @note ENABLE_SHA1_SIGNED_CERTS can additionally be configured below.
-*/
-#define USE_SHA1
-#define USE_HMAC_SHA1
-
-/**
- @security MD5 is considered insecure, but required by TLS < 1.2
- @note ENABLE_MD5_SIGNED_CERTS can additionally be configured below.
-*/
-#define USE_MD5
-#define USE_MD5SHA1/* Required for < TLS 1.2 Handshake */
-#define USE_HMAC_MD5/* TODO currently needed for prf */
-
-/**
- @security MD2 is considered insecure, but is sometimes used for
- verification of legacy root certificate signatures.
- @note MD2 signature verification also requires
- ENABLE_MD5_SIGNED_CERTS and USE_MD5.
-*/
-//#define USE_MD2
-
-/* Please enable, unless using no HMAC algorithms. */
-#define USE_HMAC
-
-/******************************************************************************/
-/**
- X.509 Certificates/PKI
-*/
-#define USE_BASE64_DECODE
-#define USE_X509
-#define USE_CERT_PARSE/**< Usually required. @pre USE_X509 */
-#define USE_FULL_CERT_PARSE/**< @pre USE_CERT_PARSE */
- /**< Support extra distinguished name attributes that SHOULD be supported according to RFC 5280. */
-//#define USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD
- /**< Support extra distinguished name attributes not mentioned in RFC 5280. */
-//#define USE_EXTRA_DN_ATTRIBUTES
-//#define ENABLE_CA_CERT_HASH /**< Used only for TLS trusted CA ind ext. */
-//#define ENABLE_MD5_SIGNED_CERTS /** @security Accept MD5 signed certs? */
-#define ENABLE_SHA1_SIGNED_CERTS/** @security Accept SHA1 signed certs? */
- /**< @security Allow parsing of locally trusted v1 root certs? */
-//#define ALLOW_VERSION_1_ROOT_CERT_PARSE
-#define USE_CRL/***< @pre USE_FULL_CERT_PARSE */
-#define USE_OCSP/**< @pre USE_SHA1 */
-
-/******************************************************************************/
-/**
- Various PKCS standards support
-*/
-#define USE_PRIVATE_KEY_PARSING
-//#define USE_PKCS5 /**< v2.0 PBKDF encrypted priv keys. @pre USE_3DES */
-#define USE_PKCS8/* Alternative private key storage format */
-#define USE_PKCS12/**< @pre USE_PKCS8 */
-#define USE_PKCS1_OAEP/* OAEP padding algorithm */
-#define USE_PKCS1_PSS/* PSS padding algorithm */
-
-#endif /* _h_PS_CRYPTOCONFIG */
-
-/******************************************************************************/
-
diff --git a/configs/nonfips/matrixsslConfig.h b/configs/nonfips/matrixsslConfig.h
deleted file mode 100644
index 0cf7b0f..0000000
--- a/configs/nonfips/matrixsslConfig.h
+++ /dev/null
@@ -1,336 +0,0 @@
-/**
- * @file matrixsslConfig.h
- * @version $Format:%h%d$
- *
- * Configuration settings for building the MatrixSSL library.
- * This configuration is intended to be used in FIPS Mode of operation.
- * The configuration aims to be compatible with NIST SP 800-52 Rev 1 and
- * to enable the most commonly used cipher suites.
- */
-/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
- *
- * The latest version of this code is available at http://www.matrixssl.org
- *
- * This software is open source; 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.
- *
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
- *
- * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
- */
-/******************************************************************************/
-
-#ifndef _h_MATRIXSSLCONFIG
-#define _h_MATRIXSSLCONFIG
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- NIST SP 800-52 Rev 1 Conformance.
- Guidelines for the Selection, Configuration, and Use of Transport Layer
- Security (TLS) Implementations
- The key words "shall", "shall not", "should", "should not" and "may"
- are used as references to the NIST SP 800-52 Rev 1. Algorithms marked as
- "shall" must not be disabled unless NIST SP 800-52 Rev 1 compatibility
- is not relevant.
- @see http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-52r1.pdf
-*/
-
-/******************************************************************************/
-/**
- Show which SSL messages are created and parsed
-*/
-//#define USE_SSL_HANDSHAKE_MSG_TRACE
-
-/**
- Informational trace that could help pinpoint problems with SSL connections
-*/
-//#define USE_SSL_INFORMATIONAL_TRACE
-//#define USE_DTLS_DEBUG_TRACE
-
-/******************************************************************************/
-/**
- Recommended cipher suites.
- Define the following to enable various cipher suites
- At least one of these must be defined. If multiple are defined,
- the handshake negotiation will determine which is best for the connection.
- @note Ephemeral ciphersuites offer perfect forward security (PFS)
- at the cost of a slower TLS handshake.
-*/
-
-/** Ephemeral ECC DH keys, ECC DSA certificates */
-#define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA/**< @security NIST_SHOULD */
-#define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA/**< @security NIST_MAY */
-/* TLS 1.2 ciphers */
-#define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256/**< @security NIST_SHOULD */
-#define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384/**< @security NIST_MAY */
-#define USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256/**< @security NIST_SHOULD */
-#define USE_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384/**< @security NIST_SHOULD */
-//#define USE_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
-
-/** Ephemeral ECC DH keys, RSA certificates */
-#define USE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA/**< @security NIST_SHOULD */
-#define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
-/* TLS 1.2 ciphers */
-#define USE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256/**< @security NIST_SHOULD */
-#define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384/**< @security NIST_MAY */
-#define USE_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256/**< @security NIST_SHOULD */
-#define USE_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384/**< @security NIST_SHOULD */
-//#define USE_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
-
-/** Ephemeral Diffie-Hellman ciphersuites, with RSA certificates */
-#define USE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
-#define USE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
-/* TLS 1.2 ciphers */
-#define USE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
-#define USE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
-
-/** Non-Ephemeral RSA keys/certificates */
-#define USE_TLS_RSA_WITH_AES_128_CBC_SHA/**< @security NIST_SHALL */
-#define USE_TLS_RSA_WITH_AES_256_CBC_SHA/**< @security NIST_SHOULD */
-/* TLS 1.2 ciphers */
-#define USE_TLS_RSA_WITH_AES_128_CBC_SHA256/**< @security NIST_MAY */
-#define USE_TLS_RSA_WITH_AES_256_CBC_SHA256/**< @security NIST_MAY */
-#define USE_TLS_RSA_WITH_AES_128_GCM_SHA256/**< @security NIST_SHALL */
-#define USE_TLS_RSA_WITH_AES_256_GCM_SHA384/**< @security NIST_SHOULD */
-
-/******************************************************************************/
-/**
- These cipher suites are secure, but not widely deployed.
-*/
-
-/** Ephemeral Diffie-Hellman ciphersuites, with RSA certificates */
-#define USE_SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
-
-/** Ephemeral Diffie-Hellman ciphersuites, with PSK authentication */
-#define USE_TLS_DHE_PSK_WITH_AES_128_CBC_SHA/**< @security NIST_SHOULD_NOT */
-#define USE_TLS_DHE_PSK_WITH_AES_256_CBC_SHA/**< @security NIST_SHOULD_NOT */
-
-/** Ephemeral ECC DH keys, RSA certificates */
-#define USE_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA/**< @security NIST_SHOULD */
-
-/** Pre-Shared Key Ciphers.
- NIST SP 800-52 Rev 1 recommends against using PSK unless neccessary
- See NIST SP 800-52 Rev 1 Appendix C */
-#define USE_TLS_PSK_WITH_AES_128_CBC_SHA/**< @security NIST_SHOULD_NOT */
-#define USE_TLS_PSK_WITH_AES_256_CBC_SHA/**< @security NIST_SHOULD_NOT */
-/* TLS 1.2 ciphers */
-#define USE_TLS_PSK_WITH_AES_128_CBC_SHA256/**< @security NIST_SHOULD_NOT */
-#define USE_TLS_PSK_WITH_AES_256_CBC_SHA384/**< @security NIST_SHOULD_NOT */
-
-/** Non-Ephemeral ECC DH keys, ECC DSA certificates */
-#define USE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA/**< @security NIST_MAY */
-#define USE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA/**< @security NIST_MAY */
-/* TLS 1.2 ciphers */
-#define USE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256/**< @security NIST_MAY */
-#define USE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384/**< @security NIST_MAY */
-#define USE_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256/**< @security NIST_MAY */
-#define USE_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384/**< @security NIST_MAY */
-
-/** Non-Ephemeral ECC DH keys, RSA certificates */
-#define USE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
-#define USE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
-/* TLS 1.2 ciphers */
-#define USE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
-#define USE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
-#define USE_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
-#define USE_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
-
-/** Non-Ephemeral RSA keys/certificates */
-#define USE_SSL_RSA_WITH_3DES_EDE_CBC_SHA/**< @security NIST_SHALL */
-
-/** @note Some of (non-mandatory) cipher suites mentioned in NIST SP 800-52
- Rev 1 are not supported by the MatrixSSL / MatrixDTLS.
- ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA (NIST SP 800-52 Rev 1 "should")
- is rarely used cipher suite and is not supported.
- Also (NIST SP 800-52 Rev 1 "may") TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
- TLS_DHE_DSS_WITH_* and TLS_RSA_WITH_AES_*_CCM cipher suites cannot be
- enabled as they are not supported. */
-
-/******************************************************************************/
-/**
- Ephemeral key cache support.
- If not using cache, new key exchange keys are created for each TLS session.
- If using cache, keys are generated initially, and re-used in each
- subsequent TLS connection within a given time frame and usage count.
- @see ECC_EPHEMERAL_CACHE_SECONDS and ECC_EPHEMERAL_CACHE_USAGE
-
- @security Do not cache Ephemeral ECC keys as it is against some standards,
- including NIST SP 800-56A, when in FIPS 140-2 mode of operation.
-*/
-//#define NO_ECC_EPHEMERAL_CACHE /**< @security NIST_SHALL */
-
-/******************************************************************************/
-/**
- Configure Support for TLS protocol versions.
- Define one of:
- USE_TLS_1_2_AND_ABOVE
- USE_TLS_1_1_AND_ABOVE
- USE_TLS_1_0_AND_ABOVE
- @note There is no option for enabling SSL3.0 at this level
-*/
-#define USE_TLS_1_1_AND_ABOVE/**< @security default 1_1_AND_ABOVE */
-//#define USE_TLS_1_2_AND_ABOVE /**< @security better than 1_1_AND_ABOVE if no backwards compatiblity concerns */
-//#define USE_TLS_1_0_AND_ABOVE /**< @security no longer recommended. */
-
-/******************************************************************************/
-/**
- Datagram TLS support.
- Enables DTLS in addition to TLS.
- @pre TLS_1_1
-*/
-#define USE_DTLS
-
-/******************************************************************************/
-/**
- Compile time support for server or client side SSL
-*/
-#define USE_CLIENT_SIDE_SSL
-#define USE_SERVER_SIDE_SSL
-
-/******************************************************************************/
-/**
- Client certificate authentication
-*/
-#define USE_CLIENT_AUTH
-
-/**
- Enable if the server should send an empty CertificateRequest message if
- no CA files have been loaded
-*/
-//#define SERVER_CAN_SEND_EMPTY_CERT_REQUEST
-
-/**
- Enabling this define will allow the server to "downgrade" a client auth
- handshake to a standard handshake if the client replies to a
- CERTIFICATE_REQUEST with an empty CERTIFICATE message. The user callback
- will be called with a NULL cert in this case and the user can determine if
- the handshake should continue in a non-client auth state.
-*/
-//#define SERVER_WILL_ACCEPT_EMPTY_CLIENT_CERT_MSG
-
-/******************************************************************************/
-/**
- Enable the Application Layer Protocol Negotiation extension.
- Servers and Clients will still have to use the required public API to
- set protocols and register application callbacks to negotiate the
- protocol that will be tunneled over TLS.
- @see ALPN section in the developer's guide for information.
- */
-//#define USE_ALPN
-
-/******************************************************************************/
-/**
- Enable the Trusted CA Indication CLIENT_HELLO extension. Will send the
- sha1 hash of each CA file to the server for help in server selection.
- This extra level of define is to help isolate the SHA1 requirement
-*/
-//#define USE_TRUSTED_CA_INDICATION /**< @security NIST_SHOULD */
-
-/******************************************************************************/
-/**
- A client side configuration that requires a server to provide an OCSP
- response if the client uses the certitificate status request extension.
- The "must staple" terminology is typically associated with certificates
- at the X.509 layer but it is a good description of what is being required
- of the server at the TLS level.
- @pre USE_OCSP must be enbled at the crypto level and the client application
- must use the OCSPstapling session option at run time for this setting to
- have any effect
-*/
-#ifdef USE_OCSP
-#define USE_OCSP_MUST_STAPLE /**< @security NIST_SHALL */
-#endif
-
-/******************************************************************************/
-/**
- Rehandshaking support.
-
- Enabling USE_REHANDSHAKING will allow secure-rehandshakes using the
- protocol defined in RFC 5748 which fixed a critical exploit in
- the standard TLS specification.
-
- @security Looking towards TLS 1.3, which removes re-handshaking, this
- feature is disabled by default.
-*/
-//#define USE_REHANDSHAKING
-
-/******************************************************************************/
-/**
- If SERVER you may define the number of sessions to cache and how
- long a session will remain valid in the cache from first access.
- Session caching enables very fast "session resumption handshakes".
-
- SSL_SESSION_TABLE_SIZE minimum value is 1
- SSL_SESSION_ENTRY_LIFE is in milliseconds, minimum 0
-
- @note Session caching can be disabled by setting SSL_SESSION_ENTRY_LIFE to 0
- however, this will also immediately expire SESSION_TICKETS below.
-*/
-#ifdef USE_SERVER_SIDE_SSL
-#define SSL_SESSION_TABLE_SIZE 32
-#define SSL_SESSION_ENTRY_LIFE (86400*1000)/* one day, in milliseconds */
-#endif
-
-/******************************************************************************/
-/**
- Use RFC 5077 session resumption mechanism. The SSL_SESSION_ENTRY_LIFE
- define applies to this method as well as the standard method. The
- SSL_SESSION_TICKET_LIST_LEN is the max size of the server key list.
-*/
-#define USE_STATELESS_SESSION_TICKETS
-#define SSL_SESSION_TICKET_LIST_LEN 32
-
-/******************************************************************************/
-/**
- The initial buffer sizes for send and receive buffers in each ssl_t session.
- Buffers are internally grown if more incoming or outgoing data storage is
- needed, up to a maximum of SSL_MAX_BUF_SIZE. Once the memory used by the
- buffer again drops below SSL_DEFAULT_X_BUF_SIZE, the buffer will be reduced
- to this size. Most standard SSL handshakes require on the order of 1024 B.
-
- SSL_DEFAULT_x_BUF_SIZE value in bytes, maximum SSL_MAX_BUF_SIZE
- */
-#ifndef USE_DTLS
-#can_define SSL_DEFAULT_IN_BUF_SIZE 1500 /* Base recv buf size, bytes */
-#can_define SSL_DEFAULT_OUT_BUF_SIZE 1500 /* Base send buf size, bytes */
-#else
-/******************************************************************************/
-/**
- The Path Maximum Transmission Unit is the largest datagram that can be
- sent or recieved. It is beyond the scope of DTLS to negotiate this value
- so make sure both sides have agreed on this value. This is an enforced
- limitation in MatrixDTLS so connections will not succeed if a peer has a
- PTMU set larger than this value.
-*/
-#define DTLS_PMTU 1500/* 1500 Default/Maximum datagram len */
-#define SSL_DEFAULT_IN_BUF_SIZE DTLS_PMTU/* See PMTU comments above */
-#define SSL_DEFAULT_OUT_BUF_SIZE DTLS_PMTU/* See PMTU comments above */
-
-//#define DTLS_SEND_RECORDS_INDIVIDUALLY /* Max one record per datagram */
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _h_MATRIXCONFIG */
-/******************************************************************************/
-
diff --git a/configs/psk/coreConfig.h b/configs/psk/coreConfig.h
index 3a09ef6..edd7dfe 100644
--- a/configs/psk/coreConfig.h
+++ b/configs/psk/coreConfig.h
@@ -5,7 +5,7 @@
* Configuration settings for Matrix core module.
*/
/*
- * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) 2013-2018 INSIDE Secure Corporation
* Copyright (c) PeerSec Networks, 2002-2011
* All Rights Reserved
*
@@ -37,12 +37,64 @@
/******************************************************************************/
-/* Configurable features */
+/* Debug and tracing configuration */
/******************************************************************************/
+
+/**
+ Select tracing facility.
+ Default: Use psLogf, which is used in all of MatrixSSL, CL etc. and
+ allows log redirection.
+
+ On the smallest embedded targets platform using PS_NO_LOGF may provide
+ footprint benefits but will limit logging capabilities.
+ */
+
+/* Uncomment to use previous generation logging facility: */
+/* #define PS_NO_LOGF */
+
+/* When using psLogf, logging messages by default go to the binary, but
+ they are not shown unless enabled by environment variables or
+ filter loaded with psLogfSetHookEnabledCheck() function.
+
+ Enable macros below to completely remove specified logging class. */
+/* #define PS_NO_LOGF_FATAL */
+/* #define PS_NO_LOGF_ERROR */
+/* #define PS_NO_LOGF_WARNING */
+/* #define PS_NO_LOGF_INFO */
+/* #define PS_NO_LOGF_VERBOSE */
+/* #define PS_NO_LOGF_DEBUG */
+/* #define PS_NO_LOGF_TRACE */
+/* #define PS_NO_LOGF_CALL_TRACE */
+
+/* MatrixSSL contains extensive tracing capabilities. The lines below
+ disable trace and call trace message levels, unless debug build.
+ Omitting the messages will improve performance and create smaller
+ executables with a degradation in debugging capabilities. */
+# ifndef DEBUG
+# ifndef PS_NO_LOGF_TRACE
+# define PS_NO_LOGF_TRACE
+# endif
+# ifndef PS_NO_LOGF_CALL_TRACE
+# define PS_NO_LOGF_CALL_TRACE
+# endif
+# endif
+
+/* File and line information consumes some storage and may reveal details on
+ structure of software. This information is omitted from production builds,
+ but included within "debug build". If you want to include file and line
+ information also on production builds, disable the lines below. */
+# ifndef DEBUG
+# ifndef PS_NO_LOGF_FILELINE
+# define PS_NO_LOGF_FILELINE
+# endif
+# endif
+
/**
Enable various levels of trace.
When these option is turned off, messages are silently
discarded and their text does not take space in the binary image.
+ Note: These are legacy configuration, and it is recommended to use
+ PS_NO_LOGF_* above, unless PS_NO_LOGF is set.
*/
/* #define USE_CORE_TRACE */
# ifndef NO_CORE_ERROR
@@ -52,18 +104,9 @@
# define USE_CORE_ASSERT
# endif
-/**
- When logging or tracing use psLog.h APIs.
-
- Generally, using psLog.h allows more control over logging, because
- it is possible to filter log and tracing information more efficiently.
- However, this feature comes with a footprint cost, so the feature can be
- disabled by setting NO_PS_LOGF_COMMON or by commenting out USE_PS_LOGF_COMMON
- below.
- */
-#ifdef NO_PS_LOGF_COMMON
-#define USE_PS_LOGF_COMMON
-#endif /* NO_PS_LOGF_COMMON */
+/******************************************************************************/
+/* Other Configurable features */
+/******************************************************************************/
/**
If enabled, calls to the psError set of APIs will perform a platform
@@ -84,11 +127,17 @@
# endif /* NO_MULTITHREADING */
/**
- Include the psNetwork family of APIs
+ Include the psNetwork family of APIs.
These APIs allow simple high-level socket api.
+ The API derive from BSD Sockets, and therefore it can only be used
+ on devices which have the prerequisitive APIs.
+ MatrixSSL itself can be used also be used without PS networking, but
+ many of example programs and MatrixSSLNet are based on PS networking.
*/
-# define USE_PS_NETWORKING
+# ifndef NO_PS_NETWORKING
+# define USE_PS_NETWORKING
+# endif /* NO_PS_NETWORKING */
#endif /* _h_PS_CORECONFIG */
diff --git a/configs/psk/cryptoConfig.h b/configs/psk/cryptoConfig.h
index 4caf4cd..6f7c767 100644
--- a/configs/psk/cryptoConfig.h
+++ b/configs/psk/cryptoConfig.h
@@ -64,6 +64,13 @@
# define MIN_RSA_BITS 1024
+/* The configuration can define set minimum for RSA public exponent.
+
+ For CL crypto, the default is 65537 (according to FIPS 186-4 standard).
+ It can be overridden on line below:
+ */
+/* #define MIN_RSA_PUBLIC_EXPONENT 65537 *//* Valid values 3, 5, 17, 65537. */
+
# define MIN_DH_BITS 1024
/* #define USE_BURN_STACK *//**< @security Zero sensitive data from the stack. */
@@ -78,6 +85,16 @@
/**< @note Enable verification of DSA signatures in certificate validation.
Works only when using the CL/SL library. @pre USE_CERT_PARSE. */
/* #define USE_DSA_VERIFY */
+# ifdef USE_DH
+/**< @note Enable this if you intent to support Diffie-Hellman groups larger
+ than 4096. Usually such large groups are not used. */
+/* #define USE_LARGE_DH_GROUPS */
+# endif /* USE_DH */
+/**< @note Enable ECDHE with Curve25519. */
+/* #define USE_X25519 */
+/**< @note Enable Pure EdDSA Curve25519 (Ed25519) signatures.
+ @pre USE_ECC, USE_SHA512. */
+/* #define USE_ED25519 */
/******************************************************************************/
/**
@@ -130,6 +147,17 @@
/** @security 3DES is still relatively secure, however is deprecated for TLS */
/* #define USE_3DES */
+/******************************************************************************/
+/**
+ Legacy ciphers.
+ These ciphers have been deprecated, but may be occasionally required
+ for legacy compatibility. Usage of these cipher suites should be avoided
+ as these may represent small or moderate risk.
+
+ Note: The RC4 cipher below need to disabled according to RFC 7465.
+*/
+/* #define USE_ARC4 */
+
/******************************************************************************/
/**
Digest algorithms.
@@ -184,6 +212,14 @@
/* Please enable, unless using no HMAC algorithms. */
# define USE_HMAC
+/**
+ HMAC-based Extract-and-Expand Key Derivation Function (HKDF) (RFC 5869).
+ Needed in TLS 1.3 key derivation.
+*/
+# if defined(USE_HMAC_SHA256) || defined(USE_HMAC_SHA384)
+/* #define USE_HKDF */
+# endif
+
/******************************************************************************/
/**
X.509 Certificates/PKI
diff --git a/configs/psk/matrixsslConfig.h b/configs/psk/matrixsslConfig.h
index d69f685..008677d 100644
--- a/configs/psk/matrixsslConfig.h
+++ b/configs/psk/matrixsslConfig.h
@@ -75,6 +75,11 @@ extern "C" {
at the cost of a slower TLS handshake.
*/
+/** TLS 1.3 ciphers */
+/* #define USE_TLS_AES_128_GCM_SHA256 */
+/* #define USE_TLS_AES_256_GCM_SHA384 */
+/* #define USE_TLS_CHACHA20_POLY1305_SHA256 */
+
/** Ephemeral ECC DH keys, ECC DSA certificates */
/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA *//**< @security NIST_SHOULD */
/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA *//**< @security NIST_MAY */
@@ -166,6 +171,17 @@ extern "C" {
TLS_DHE_DSS_WITH_* and TLS_RSA_WITH_AES_*_CCM cipher suites cannot be
enabled as they are not supported. */
+/******************************************************************************/
+/**
+ Legacy cipher suites.
+ These cipher suites have been deprecated, but may be occasionally required
+ for legacy compatibility. Usage of these cipher suites should be avoided
+ as these may represent small or moderate risk.
+
+ Note: The RC4 cipher suites below need to disabled according to RFC 7465.
+*/
+/* #define USE_SSL_RSA_WITH_RC4_128_SHA *//**< @security NIST_SHALL_NOT */
+
/******************************************************************************/
/**
Ephemeral key cache support.
@@ -183,15 +199,23 @@ extern "C" {
/**
Configure Support for TLS protocol versions.
Define one of:
- USE_TLS_1_2_AND_ABOVE
- USE_TLS_1_1_AND_ABOVE
- USE_TLS_1_0_AND_ABOVE
+ USE_TLS_1_2_AND_ABOVE (TLS 1.2 and 1.3)
+ USE_TLS_1_1_AND_ABOVE (TLS 1.1, 1.2 and 1.3)
+ USE_TLS_1_0_AND_ABOVE (TLS 1.0, 1.1, 1.2 and 1.3)
@note There is no option for enabling SSL3.0 at this level
*/
/* #define USE_TLS_1_1_AND_ABOVE *//**< @security default 1_1_AND_ABOVE */
# define USE_TLS_1_2_AND_ABOVE/**< @security better than 1_1_AND_ABOVE if no backwards compatiblity concerns */
/* #define USE_TLS_1_0_AND_ABOVE *//**< @security no longer recommended. */
+/** Enable support for session resumption in TLS 1.3. */
+/* #define USE_TLS_1_3_RESUMPTION */
+
+/** TLS 1.3 code has not yet been footprint-optimized. For this reason,
+ it is possible to separately leave all TLS 1.3 code out of the build
+ by enabling this. */
+# define DISABLE_TLS_1_3
+
/******************************************************************************/
/**
Datagram TLS support.
diff --git a/configs/rsaonly/coreConfig.h b/configs/rsaonly/coreConfig.h
index d8a568f..a0e9380 100644
--- a/configs/rsaonly/coreConfig.h
+++ b/configs/rsaonly/coreConfig.h
@@ -5,7 +5,7 @@
* Configuration settings for Matrix core module.
*/
/*
- * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) 2013-2018 INSIDE Secure Corporation
* Copyright (c) PeerSec Networks, 2002-2011
* All Rights Reserved
*
@@ -37,12 +37,64 @@
/******************************************************************************/
-/* Configurable features */
+/* Debug and tracing configuration */
/******************************************************************************/
+
+/**
+ Select tracing facility.
+ Default: Use psLogf, which is used in all of MatrixSSL, CL etc. and
+ allows log redirection.
+
+ On the smallest embedded targets platform using PS_NO_LOGF may provide
+ footprint benefits but will limit logging capabilities.
+ */
+
+/* Uncomment to use previous generation logging facility: */
+/* #define PS_NO_LOGF */
+
+/* When using psLogf, logging messages by default go to the binary, but
+ they are not shown unless enabled by environment variables or
+ filter loaded with psLogfSetHookEnabledCheck() function.
+
+ Enable macros below to completely remove specified logging class. */
+/* #define PS_NO_LOGF_FATAL */
+/* #define PS_NO_LOGF_ERROR */
+/* #define PS_NO_LOGF_WARNING */
+/* #define PS_NO_LOGF_INFO */
+/* #define PS_NO_LOGF_VERBOSE */
+/* #define PS_NO_LOGF_DEBUG */
+/* #define PS_NO_LOGF_TRACE */
+/* #define PS_NO_LOGF_CALL_TRACE */
+
+/* MatrixSSL contains extensive tracing capabilities. The lines below
+ disable trace and call trace message levels, unless debug build.
+ Omitting the messages will improve performance and create smaller
+ executables with a degradation in debugging capabilities. */
+# ifndef DEBUG
+# ifndef PS_NO_LOGF_TRACE
+# define PS_NO_LOGF_TRACE
+# endif
+# ifndef PS_NO_LOGF_CALL_TRACE
+# define PS_NO_LOGF_CALL_TRACE
+# endif
+# endif
+
+/* File and line information consumes some storage and may reveal details on
+ structure of software. This information is omitted from production builds,
+ but included within "debug build". If you want to include file and line
+ information also on production builds, disable the lines below. */
+# ifndef DEBUG
+# ifndef PS_NO_LOGF_FILELINE
+# define PS_NO_LOGF_FILELINE
+# endif
+# endif
+
/**
Enable various levels of trace.
When these option is turned off, messages are silently
discarded and their text does not take space in the binary image.
+ Note: These are legacy configuration, and it is recommended to use
+ PS_NO_LOGF_* above, unless PS_NO_LOGF is set.
*/
/* #define USE_CORE_TRACE */
# ifndef NO_CORE_ERROR
@@ -52,18 +104,9 @@
# define USE_CORE_ASSERT
# endif
-/**
- When logging or tracing use psLog.h APIs.
-
- Generally, using psLog.h allows more control over logging, because
- it is possible to filter log and tracing information more efficiently.
- However, this feature comes with a footprint cost, so the feature can be
- disabled by setting NO_PS_LOGF_COMMON or by commenting out USE_PS_LOGF_COMMON
- below.
- */
-#ifdef NO_PS_LOGF_COMMON
-#define USE_PS_LOGF_COMMON
-#endif /* NO_PS_LOGF_COMMON */
+/******************************************************************************/
+/* Other Configurable features */
+/******************************************************************************/
/**
If enabled, calls to the psError set of APIs will perform a platform
@@ -84,11 +127,17 @@
# endif /* NO_MULTITHREADING */
/**
- Include the psNetwork family of APIs
+ Include the psNetwork family of APIs.
These APIs allow simple high-level socket api.
+ The API derive from BSD Sockets, and therefore it can only be used
+ on devices which have the prerequisitive APIs.
+ MatrixSSL itself can be used also be used without PS networking, but
+ many of example programs and MatrixSSLNet are based on PS networking.
*/
-# define USE_PS_NETWORKING
+# ifndef NO_PS_NETWORKING
+# define USE_PS_NETWORKING
+# endif /* NO_PS_NETWORKING */
#endif /* _h_PS_CORECONFIG */
diff --git a/configs/rsaonly/cryptoConfig.h b/configs/rsaonly/cryptoConfig.h
index 16eaf03..8b4b4ba 100644
--- a/configs/rsaonly/cryptoConfig.h
+++ b/configs/rsaonly/cryptoConfig.h
@@ -64,6 +64,13 @@
# define MIN_RSA_BITS 1024
+/* The configuration can define set minimum for RSA public exponent.
+
+ For CL crypto, the default is 65537 (according to FIPS 186-4 standard).
+ It can be overridden on line below:
+ */
+/* #define MIN_RSA_PUBLIC_EXPONENT 65537 *//* Valid values 3, 5, 17, 65537. */
+
# define MIN_DH_BITS 1024
# define USE_BURN_STACK/**< @security Zero sensitive data from the stack. */
@@ -78,6 +85,16 @@
/**< @note Enable verification of DSA signatures in certificate validation.
Works only when using the CL/SL library. @pre USE_CERT_PARSE. */
/* #define USE_DSA_VERIFY */
+# ifdef USE_DH
+/**< @note Enable this if you intent to support Diffie-Hellman groups larger
+ than 4096. Usually such large groups are not used. */
+/* #define USE_LARGE_DH_GROUPS */
+# endif /* USE_DH */
+/**< @note Enable ECDHE with Curve25519. */
+/* #define USE_X25519 */
+/**< @note Enable Pure EdDSA Curve25519 (Ed25519) signatures.
+ @pre USE_ECC, USE_SHA512. */
+/* #define USE_ED25519 */
/******************************************************************************/
/**
@@ -125,11 +142,22 @@
TLS clients and servers. These cipher suites are not allowed in FIPS
mode of operation.
*/
-/* #define USE_CHACHA20_POLY1305_IETF */
+# define USE_CHACHA20_POLY1305_IETF
/** @security 3DES is still relatively secure, however is deprecated for TLS */
# define USE_3DES
+/******************************************************************************/
+/**
+ Legacy ciphers.
+ These ciphers have been deprecated, but may be occasionally required
+ for legacy compatibility. Usage of these cipher suites should be avoided
+ as these may represent small or moderate risk.
+
+ Note: The RC4 cipher below need to disabled according to RFC 7465.
+*/
+/* #define USE_ARC4 */
+
/******************************************************************************/
/**
Digest algorithms.
@@ -184,6 +212,14 @@
/* Please enable, unless using no HMAC algorithms. */
# define USE_HMAC
+/**
+ HMAC-based Extract-and-Expand Key Derivation Function (HKDF) (RFC 5869).
+ Needed in TLS 1.3 key derivation.
+*/
+# if defined(USE_HMAC_SHA256) || defined(USE_HMAC_SHA384)
+# define USE_HKDF
+# endif
+
/******************************************************************************/
/**
X.509 Certificates/PKI
diff --git a/configs/rsaonly/matrixsslConfig.h b/configs/rsaonly/matrixsslConfig.h
index 8276e82..9b6e612 100644
--- a/configs/rsaonly/matrixsslConfig.h
+++ b/configs/rsaonly/matrixsslConfig.h
@@ -75,6 +75,11 @@ extern "C" {
at the cost of a slower TLS handshake.
*/
+/** TLS 1.3 ciphers */
+# define USE_TLS_AES_128_GCM_SHA256
+# define USE_TLS_AES_256_GCM_SHA384
+# define USE_TLS_CHACHA20_POLY1305_SHA256
+
/** Ephemeral ECC DH keys, ECC DSA certificates */
/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA *//**< @security NIST_SHOULD */
/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA *//**< @security NIST_MAY */
@@ -166,6 +171,17 @@ extern "C" {
TLS_DHE_DSS_WITH_* and TLS_RSA_WITH_AES_*_CCM cipher suites cannot be
enabled as they are not supported. */
+/******************************************************************************/
+/**
+ Legacy cipher suites.
+ These cipher suites have been deprecated, but may be occasionally required
+ for legacy compatibility. Usage of these cipher suites should be avoided
+ as these may represent small or moderate risk.
+
+ Note: The RC4 cipher suites below need to disabled according to RFC 7465.
+*/
+/* #define USE_SSL_RSA_WITH_RC4_128_SHA *//**< @security NIST_SHALL_NOT */
+
/******************************************************************************/
/**
Ephemeral key cache support.
@@ -183,15 +199,23 @@ extern "C" {
/**
Configure Support for TLS protocol versions.
Define one of:
- USE_TLS_1_2_AND_ABOVE
- USE_TLS_1_1_AND_ABOVE
- USE_TLS_1_0_AND_ABOVE
+ USE_TLS_1_2_AND_ABOVE (TLS 1.2 and 1.3)
+ USE_TLS_1_1_AND_ABOVE (TLS 1.1, 1.2 and 1.3)
+ USE_TLS_1_0_AND_ABOVE (TLS 1.0, 1.1, 1.2 and 1.3)
@note There is no option for enabling SSL3.0 at this level
*/
# define USE_TLS_1_1_AND_ABOVE/**< @security default 1_1_AND_ABOVE */
/* #define USE_TLS_1_2_AND_ABOVE *//**< @security better than 1_1_AND_ABOVE if no backwards compatiblity concerns */
/* #define USE_TLS_1_0_AND_ABOVE *//**< @security no longer recommended. */
+/** Enable support for session resumption in TLS 1.3. */
+# define USE_TLS_1_3_RESUMPTION
+
+/** TLS 1.3 code has not yet been footprint-optimized. For this reason,
+ it is possible to separately leave all TLS 1.3 code out of the build
+ by enabling this. */
+# define DISABLE_TLS_1_3
+
/******************************************************************************/
/**
Datagram TLS support.
diff --git a/configs/tls/coreConfig.h b/configs/tls/coreConfig.h
index d8a568f..a0e9380 100644
--- a/configs/tls/coreConfig.h
+++ b/configs/tls/coreConfig.h
@@ -5,7 +5,7 @@
* Configuration settings for Matrix core module.
*/
/*
- * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) 2013-2018 INSIDE Secure Corporation
* Copyright (c) PeerSec Networks, 2002-2011
* All Rights Reserved
*
@@ -37,12 +37,64 @@
/******************************************************************************/
-/* Configurable features */
+/* Debug and tracing configuration */
/******************************************************************************/
+
+/**
+ Select tracing facility.
+ Default: Use psLogf, which is used in all of MatrixSSL, CL etc. and
+ allows log redirection.
+
+ On the smallest embedded targets platform using PS_NO_LOGF may provide
+ footprint benefits but will limit logging capabilities.
+ */
+
+/* Uncomment to use previous generation logging facility: */
+/* #define PS_NO_LOGF */
+
+/* When using psLogf, logging messages by default go to the binary, but
+ they are not shown unless enabled by environment variables or
+ filter loaded with psLogfSetHookEnabledCheck() function.
+
+ Enable macros below to completely remove specified logging class. */
+/* #define PS_NO_LOGF_FATAL */
+/* #define PS_NO_LOGF_ERROR */
+/* #define PS_NO_LOGF_WARNING */
+/* #define PS_NO_LOGF_INFO */
+/* #define PS_NO_LOGF_VERBOSE */
+/* #define PS_NO_LOGF_DEBUG */
+/* #define PS_NO_LOGF_TRACE */
+/* #define PS_NO_LOGF_CALL_TRACE */
+
+/* MatrixSSL contains extensive tracing capabilities. The lines below
+ disable trace and call trace message levels, unless debug build.
+ Omitting the messages will improve performance and create smaller
+ executables with a degradation in debugging capabilities. */
+# ifndef DEBUG
+# ifndef PS_NO_LOGF_TRACE
+# define PS_NO_LOGF_TRACE
+# endif
+# ifndef PS_NO_LOGF_CALL_TRACE
+# define PS_NO_LOGF_CALL_TRACE
+# endif
+# endif
+
+/* File and line information consumes some storage and may reveal details on
+ structure of software. This information is omitted from production builds,
+ but included within "debug build". If you want to include file and line
+ information also on production builds, disable the lines below. */
+# ifndef DEBUG
+# ifndef PS_NO_LOGF_FILELINE
+# define PS_NO_LOGF_FILELINE
+# endif
+# endif
+
/**
Enable various levels of trace.
When these option is turned off, messages are silently
discarded and their text does not take space in the binary image.
+ Note: These are legacy configuration, and it is recommended to use
+ PS_NO_LOGF_* above, unless PS_NO_LOGF is set.
*/
/* #define USE_CORE_TRACE */
# ifndef NO_CORE_ERROR
@@ -52,18 +104,9 @@
# define USE_CORE_ASSERT
# endif
-/**
- When logging or tracing use psLog.h APIs.
-
- Generally, using psLog.h allows more control over logging, because
- it is possible to filter log and tracing information more efficiently.
- However, this feature comes with a footprint cost, so the feature can be
- disabled by setting NO_PS_LOGF_COMMON or by commenting out USE_PS_LOGF_COMMON
- below.
- */
-#ifdef NO_PS_LOGF_COMMON
-#define USE_PS_LOGF_COMMON
-#endif /* NO_PS_LOGF_COMMON */
+/******************************************************************************/
+/* Other Configurable features */
+/******************************************************************************/
/**
If enabled, calls to the psError set of APIs will perform a platform
@@ -84,11 +127,17 @@
# endif /* NO_MULTITHREADING */
/**
- Include the psNetwork family of APIs
+ Include the psNetwork family of APIs.
These APIs allow simple high-level socket api.
+ The API derive from BSD Sockets, and therefore it can only be used
+ on devices which have the prerequisitive APIs.
+ MatrixSSL itself can be used also be used without PS networking, but
+ many of example programs and MatrixSSLNet are based on PS networking.
*/
-# define USE_PS_NETWORKING
+# ifndef NO_PS_NETWORKING
+# define USE_PS_NETWORKING
+# endif /* NO_PS_NETWORKING */
#endif /* _h_PS_CORECONFIG */
diff --git a/configs/tls/cryptoConfig.h b/configs/tls/cryptoConfig.h
index 806bc79..dd3b3b7 100644
--- a/configs/tls/cryptoConfig.h
+++ b/configs/tls/cryptoConfig.h
@@ -64,6 +64,13 @@
# define MIN_RSA_BITS 1024
+/* The configuration can define set minimum for RSA public exponent.
+
+ For CL crypto, the default is 65537 (according to FIPS 186-4 standard).
+ It can be overridden on line below:
+ */
+/* #define MIN_RSA_PUBLIC_EXPONENT 65537 *//* Valid values 3, 5, 17, 65537. */
+
# define MIN_DH_BITS 1024
# define USE_BURN_STACK/**< @security Zero sensitive data from the stack. */
@@ -78,6 +85,16 @@
/**< @note Enable verification of DSA signatures in certificate validation.
Works only when using the CL/SL library. @pre USE_CERT_PARSE. */
/* #define USE_DSA_VERIFY */
+# ifdef USE_DH
+/**< @note Enable this if you intent to support Diffie-Hellman groups larger
+ than 4096. Usually such large groups are not used. */
+/* #define USE_LARGE_DH_GROUPS */
+# endif /* USE_DH */
+/**< @note Enable ECDHE with Curve25519. */
+# define USE_X25519
+/**< @note Enable Pure EdDSA Curve25519 (Ed25519) signatures.
+ @pre USE_ECC, USE_SHA512. */
+# define USE_ED25519
/******************************************************************************/
/**
@@ -125,11 +142,22 @@
TLS clients and servers. These cipher suites are not allowed in FIPS
mode of operation.
*/
-/* #define USE_CHACHA20_POLY1305_IETF */
+# define USE_CHACHA20_POLY1305_IETF
/** @security 3DES is still relatively secure, however is deprecated for TLS */
# define USE_3DES
+/******************************************************************************/
+/**
+ Legacy ciphers.
+ These ciphers have been deprecated, but may be occasionally required
+ for legacy compatibility. Usage of these cipher suites should be avoided
+ as these may represent small or moderate risk.
+
+ Note: The RC4 cipher below need to disabled according to RFC 7465.
+*/
+/* #define USE_ARC4 */
+
/******************************************************************************/
/**
Digest algorithms.
@@ -184,6 +212,14 @@
/* Please enable, unless using no HMAC algorithms. */
# define USE_HMAC
+/**
+ HMAC-based Extract-and-Expand Key Derivation Function (HKDF) (RFC 5869).
+ Needed in TLS 1.3 key derivation.
+*/
+# if defined(USE_HMAC_SHA256) || defined(USE_HMAC_SHA384)
+# define USE_HKDF
+# endif
+
/******************************************************************************/
/**
X.509 Certificates/PKI
diff --git a/configs/tls/matrixsslConfig.h b/configs/tls/matrixsslConfig.h
index a4c0347..472b4b1 100644
--- a/configs/tls/matrixsslConfig.h
+++ b/configs/tls/matrixsslConfig.h
@@ -75,6 +75,11 @@ extern "C" {
at the cost of a slower TLS handshake.
*/
+/** TLS 1.3 ciphers */
+# define USE_TLS_AES_128_GCM_SHA256
+# define USE_TLS_AES_256_GCM_SHA384
+# define USE_TLS_CHACHA20_POLY1305_SHA256
+
/** Ephemeral ECC DH keys, ECC DSA certificates */
# define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA/**< @security NIST_SHOULD */
# define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA/**< @security NIST_MAY */
@@ -166,6 +171,17 @@ extern "C" {
TLS_DHE_DSS_WITH_* and TLS_RSA_WITH_AES_*_CCM cipher suites cannot be
enabled as they are not supported. */
+/******************************************************************************/
+/**
+ Legacy cipher suites.
+ These cipher suites have been deprecated, but may be occasionally required
+ for legacy compatibility. Usage of these cipher suites should be avoided
+ as these may represent small or moderate risk.
+
+ Note: The RC4 cipher suites below need to disabled according to RFC 7465.
+*/
+/* #define USE_SSL_RSA_WITH_RC4_128_SHA *//**< @security NIST_SHALL_NOT */
+
/******************************************************************************/
/**
Ephemeral key cache support.
@@ -183,15 +199,23 @@ extern "C" {
/**
Configure Support for TLS protocol versions.
Define one of:
- USE_TLS_1_2_AND_ABOVE
- USE_TLS_1_1_AND_ABOVE
- USE_TLS_1_0_AND_ABOVE
+ USE_TLS_1_2_AND_ABOVE (TLS 1.2 and 1.3)
+ USE_TLS_1_1_AND_ABOVE (TLS 1.1, 1.2 and 1.3)
+ USE_TLS_1_0_AND_ABOVE (TLS 1.0, 1.1, 1.2 and 1.3)
@note There is no option for enabling SSL3.0 at this level
*/
# define USE_TLS_1_1_AND_ABOVE/**< @security default 1_1_AND_ABOVE */
/* #define USE_TLS_1_2_AND_ABOVE *//**< @security better than 1_1_AND_ABOVE if no backwards compatiblity concerns */
/* #define USE_TLS_1_0_AND_ABOVE *//**< @security no longer recommended. */
+/** Enable support for session resumption in TLS 1.3. */
+# define USE_TLS_1_3_RESUMPTION
+
+/** TLS 1.3 code has not yet been footprint-optimized. For this reason,
+ it is possible to separately leave all TLS 1.3 code out of the build
+ by enabling this. */
+/* #define DISABLE_TLS_1_3 */
+
/******************************************************************************/
/**
Datagram TLS support.
diff --git a/configs/tls13/coreConfig.h b/configs/tls13/coreConfig.h
new file mode 100644
index 0000000..a0e9380
--- /dev/null
+++ b/configs/tls13/coreConfig.h
@@ -0,0 +1,145 @@
+/**
+ * @file coreConfig.h
+ * @version $Format:%h%d$
+ *
+ * Configuration settings for Matrix core module.
+ */
+/*
+ * Copyright (c) 2013-2018 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
+ *
+ * The latest version of this code is available at http://www.matrixssl.org
+ *
+ * This software is open source; 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.
+ *
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
+ *
+ * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+/******************************************************************************/
+
+#ifndef _h_PS_CORECONFIG
+# define _h_PS_CORECONFIG
+
+
+/******************************************************************************/
+/* Debug and tracing configuration */
+/******************************************************************************/
+
+/**
+ Select tracing facility.
+ Default: Use psLogf, which is used in all of MatrixSSL, CL etc. and
+ allows log redirection.
+
+ On the smallest embedded targets platform using PS_NO_LOGF may provide
+ footprint benefits but will limit logging capabilities.
+ */
+
+/* Uncomment to use previous generation logging facility: */
+/* #define PS_NO_LOGF */
+
+/* When using psLogf, logging messages by default go to the binary, but
+ they are not shown unless enabled by environment variables or
+ filter loaded with psLogfSetHookEnabledCheck() function.
+
+ Enable macros below to completely remove specified logging class. */
+/* #define PS_NO_LOGF_FATAL */
+/* #define PS_NO_LOGF_ERROR */
+/* #define PS_NO_LOGF_WARNING */
+/* #define PS_NO_LOGF_INFO */
+/* #define PS_NO_LOGF_VERBOSE */
+/* #define PS_NO_LOGF_DEBUG */
+/* #define PS_NO_LOGF_TRACE */
+/* #define PS_NO_LOGF_CALL_TRACE */
+
+/* MatrixSSL contains extensive tracing capabilities. The lines below
+ disable trace and call trace message levels, unless debug build.
+ Omitting the messages will improve performance and create smaller
+ executables with a degradation in debugging capabilities. */
+# ifndef DEBUG
+# ifndef PS_NO_LOGF_TRACE
+# define PS_NO_LOGF_TRACE
+# endif
+# ifndef PS_NO_LOGF_CALL_TRACE
+# define PS_NO_LOGF_CALL_TRACE
+# endif
+# endif
+
+/* File and line information consumes some storage and may reveal details on
+ structure of software. This information is omitted from production builds,
+ but included within "debug build". If you want to include file and line
+ information also on production builds, disable the lines below. */
+# ifndef DEBUG
+# ifndef PS_NO_LOGF_FILELINE
+# define PS_NO_LOGF_FILELINE
+# endif
+# endif
+
+/**
+ Enable various levels of trace.
+ When these option is turned off, messages are silently
+ discarded and their text does not take space in the binary image.
+ Note: These are legacy configuration, and it is recommended to use
+ PS_NO_LOGF_* above, unless PS_NO_LOGF is set.
+ */
+/* #define USE_CORE_TRACE */
+# ifndef NO_CORE_ERROR
+# define USE_CORE_ERROR
+# endif
+# ifndef NO_CORE_ASSERT
+# define USE_CORE_ASSERT
+# endif
+
+/******************************************************************************/
+/* Other Configurable features */
+/******************************************************************************/
+
+/**
+ If enabled, calls to the psError set of APIs will perform a platform
+ abort on the exeutable to aid in debugging.
+ */
+# ifdef DEBUG
+/* #define HALT_ON_PS_ERROR *//* NOT RECOMMENDED FOR PRODUCTION BUILDS */
+# endif
+
+/**
+ Include the psCoreOsdepMutex family of APIs
+
+ @note If intending to compile crypto-cl, then this flag should
+ always be set.
+*/
+# ifndef NO_MULTITHREADING
+# define USE_MULTITHREADING
+# endif /* NO_MULTITHREADING */
+
+/**
+ Include the psNetwork family of APIs.
+
+ These APIs allow simple high-level socket api.
+ The API derive from BSD Sockets, and therefore it can only be used
+ on devices which have the prerequisitive APIs.
+ MatrixSSL itself can be used also be used without PS networking, but
+ many of example programs and MatrixSSLNet are based on PS networking.
+ */
+# ifndef NO_PS_NETWORKING
+# define USE_PS_NETWORKING
+# endif /* NO_PS_NETWORKING */
+
+#endif /* _h_PS_CORECONFIG */
+
+/******************************************************************************/
+
diff --git a/configs/tls13/cryptoConfig.h b/configs/tls13/cryptoConfig.h
new file mode 100644
index 0000000..aa08c14
--- /dev/null
+++ b/configs/tls13/cryptoConfig.h
@@ -0,0 +1,301 @@
+/**
+ * @file cryptoConfig.h
+ * @version $Format:%h%d$
+ *
+ * Configuration file for crypto features.
+ */
+/*
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
+ *
+ * The latest version of this code is available at http://www.matrixssl.org
+ *
+ * This software is open source; 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.
+ *
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
+ *
+ * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+/******************************************************************************/
+
+#ifndef _h_PS_CRYPTOCONFIG
+# define _h_PS_CRYPTOCONFIG
+
+/******************************************************************************/
+/* Configurable features */
+/******************************************************************************/
+/**
+ Define to enable psTrace*Crypto APIs for debugging the crypto module.
+ */
+/* #define USE_CRYPTO_TRACE */
+
+# ifdef DEBUG
+/* #define CRYPTO_ASSERT *//**< Extra sanity asserts */
+# endif
+
+/******************************************************************************/
+/*
+ Use built-in cryptographic library delivered with MatrixSSL
+ */
+# define USE_NATIVE_RSA /* Default built-in software support */
+
+/******************************************************************************/
+/**
+ Security related settings.
+
+ @security MIN_*_BITS is the minimum supported key sizes in bits, weaker
+ keys will be rejected.
+ */
+# define MIN_ECC_BITS 192/**< @security Affects ECC curves below */
+
+# define MIN_RSA_BITS 1024
+
+/* The configuration can define set minimum for RSA public exponent.
+
+ For CL crypto, the default is 65537 (according to FIPS 186-4 standard).
+ It can be overridden on line below:
+ */
+/* #define MIN_RSA_PUBLIC_EXPONENT 65537 *//* Valid values 3, 5, 17, 65537. */
+
+# define MIN_DH_BITS 1024
+
+# define USE_BURN_STACK/**< @security Zero sensitive data from the stack. */
+
+/******************************************************************************/
+/**
+ Public-Key Algorithm Support.
+ */
+# define USE_RSA
+# define USE_ECC
+# define USE_DH
+/**< @note Enable verification of DSA signatures in certificate validation.
+ Works only when using the CL/SL library. @pre USE_CERT_PARSE. */
+/* #define USE_DSA_VERIFY */
+# ifdef USE_DH
+/**< @note Enable this if you intent to support Diffie-Hellman groups larger
+ than 4096. Usually such large groups are not used. */
+/* #define USE_LARGE_DH_GROUPS */
+# endif /* USE_DH */
+/**< @note Enable ECDHE with Curve25519. */
+# define USE_X25519
+/**< @note Enable Pure EdDSA Curve25519 (Ed25519) signatures.
+ @pre USE_ECC, USE_SHA512. */
+# define USE_ED25519
+
+/******************************************************************************/
+/**
+ Build the PKCS and ASN1 extra CL sublibraries.
+ These are needed by the CL_PKCS API.
+ */
+
+/******************************************************************************/
+
+/**
+ Define to enable the individual NIST Prime curves.
+ @see http://csrc.nist.gov/groups/ST/toolkit/documents/dss/NISTReCur.pdf
+ */
+# ifdef USE_ECC
+# define USE_SECP192R1/**< @security FIPS allowed for sig ver only. */
+# define USE_SECP224R1
+# define USE_SECP256R1/**< @security NIST_SHALL */
+# define USE_SECP384R1/**< @security NIST_SHALL */
+# define USE_SECP521R1
+# endif
+
+/**
+ Define to enable the individual Brainpool curves.
+ @see https://tools.ietf.org/html/rfc5639
+ @security WARNING: Public points on Brainpool curves are not validated
+ */
+# ifdef USE_ECC
+/* #define USE_BRAIN224R1 */
+/* #define USE_BRAIN256R1 */
+/* #define USE_BRAIN384R1 */
+/* #define USE_BRAIN512R1 */
+# endif
+
+/******************************************************************************/
+/**
+ Symmetric and AEAD ciphers.
+ @security Deprecated ciphers must be enabled in cryptolib.h
+ */
+/* #define USE_AES *//* Enable/Disable AES */
+# define USE_AES_CBC
+# define USE_AES_GCM
+
+/** If you want new ciphersuites specified in RFC 7539 enable this.
+ Currently CHACHA20-based cipher suites are only supported by the newest
+ TLS clients and servers. These cipher suites are not allowed in FIPS
+ mode of operation.
+*/
+# define USE_CHACHA20_POLY1305_IETF
+
+/** @security 3DES is still relatively secure, however is deprecated for TLS */
+# define USE_3DES
+
+/******************************************************************************/
+/**
+ Legacy ciphers.
+ These ciphers have been deprecated, but may be occasionally required
+ for legacy compatibility. Usage of these cipher suites should be avoided
+ as these may represent small or moderate risk.
+
+ Note: The RC4 cipher below need to disabled according to RFC 7465.
+*/
+/* #define USE_ARC4 */
+
+/******************************************************************************/
+/**
+ Digest algorithms.
+
+ @note SHA256 and above are used with TLS 1.2, and also used for
+ certificate signatures on some certificates regardless of TLS version.
+
+ @security MD5 is deprecated, but still required in combination with SHA-1
+ for TLS handshakes before TLS 1.2, meaning that the strength is at least
+ that of SHA-1 in this usage. The define USE_MD5SHA1 can be used to enable
+ MD5 only for this purpose. The only other usage of MD5 by TLS is for
+ certificate signatures and MD5 based cipher suites. Both of which are
+ disabled at compile time by default.
+
+ @security SHA1 will be deprecated in the future, but is still required in
+ combination with MD5 for versions prior to TLS 1.2. In addition, SHA1
+ certificates are still commonly used, so SHA1 support may be needed
+ to validate older certificates. It is possible to completely disable
+ SHA1 using TLS 1.2 and SHA2 based ciphersuites, and interacting
+ only with newer certificates.
+ */
+/* #define USE_SHA224 *//**< @note Used only for cert signature */
+# define USE_SHA256/**< @note Required for TLS 1.2 and above */
+# define USE_HMAC_SHA256
+# define USE_SHA384/**< @pre USE_SHA512 */
+# define USE_HMAC_SHA384
+# define USE_SHA512
+
+/**
+ @security SHA-1 based hashes are deprecated but enabled by default
+ @note ENABLE_SHA1_SIGNED_CERTS can additionally be configured below.
+ */
+# define USE_SHA1
+# define USE_HMAC_SHA1
+
+/**
+ @security MD5 is considered insecure, but required by TLS < 1.2
+ @note ENABLE_MD5_SIGNED_CERTS can additionally be configured below.
+ */
+# define USE_MD5
+# define USE_MD5SHA1/* Required for < TLS 1.2 Handshake */
+# define USE_HMAC_MD5
+
+/**
+ @security MD2 is considered insecure, but is sometimes used for
+ verification of legacy root certificate signatures.
+ @note MD2 signature verification also requires
+ ENABLE_MD5_SIGNED_CERTS and USE_MD5.
+ */
+/* #define USE_MD2 */
+
+/* Please enable, unless using no HMAC algorithms. */
+# define USE_HMAC
+
+/**
+ HMAC-based Extract-and-Expand Key Derivation Function (HKDF) (RFC 5869).
+ Needed in TLS 1.3 key derivation.
+*/
+# if defined(USE_HMAC_SHA256) || defined(USE_HMAC_SHA384)
+# define USE_HKDF
+# endif
+
+/******************************************************************************/
+/**
+ X.509 Certificates/PKI
+ */
+# define USE_BASE64_DECODE
+# define USE_X509/**< Enable minimal X.509 support. */
+# define USE_CERT_PARSE/**< Enable TBSCertificate parsing. Usually required. @pre USE_X509 */
+# define USE_FULL_CERT_PARSE/**< @pre USE_CERT_PARSE */
+/**< Support extra distinguished name attributes that SHOULD be supported according to RFC 5280. */
+/* #define USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD */
+/**< Support extra distinguished name attributes not mentioned in RFC 5280. */
+/* #define USE_EXTRA_DN_ATTRIBUTES */
+/* #define ENABLE_CA_CERT_HASH *//**< Used only for TLS trusted CA ind ext. */
+/* #define ENABLE_MD5_SIGNED_CERTS *//** @security Accept MD5 signed certs? */
+
+/**
+ @security SHA-1 based signatures are insecure, as SHA-1 can no longer
+ be considered collision resistant (https://shattered.it/static/shattered.pdf).
+ Enable if compatibility with old certificates is required.
+ */
+/* #define ENABLE_SHA1_SIGNED_CERTS */
+
+/**< @security Allow parsing of locally trusted v1 root certs? */
+/* #define ALLOW_VERSION_1_ROOT_CERT_PARSE */
+/**
+ When parsing certificates, always also retain the unparsed DER data.
+ Enabling this has the same effect as setting the
+ CERT_STORE_UNPARSED_BUFFER flag in each psX509ParseCert call.
+ */
+/* #define ALWAYS_KEEP_CERT_DER */
+/**
+ Always attempt to match expectedName with the subject CN, even if
+ a supported, but non-matching subjectAltName was presented.
+ The default behaviour is to check the CN only when no supported SAN
+ was presented, in accordance with Section 6.4.4 of RFC 6125.
+ */
+/* #define ALWAYS_CHECK_SUBJECT_CN_IN_HOSTNAME_VALIDATION */
+# define USE_CRL/***< @pre USE_FULL_CERT_PARSE */
+# ifdef USE_CRL
+/**
+ Allow CRL authentication to succeed even when signer CA's cert does not
+ have the keyUsage extension and thus no cRLSign bit.
+ Note that RFC 5280 requires CRL issuer certs to have the keyUsage extension
+ and the cRLSign bit.
+ */
+/* #define ALLOW_CRL_ISSUERS_WITHOUT_KEYUSAGE */
+# endif
+/**
+ Enable OCSP response and request handling.
+*/
+/* #define USE_OCSP *//**< @pre USE_SHA1 */
+# ifdef USE_OCSP
+# define USE_OCSP_RESPONSE
+# define USE_OCSP_REQUEST
+# elif defined(USE_X509) && defined(USE_SHA1)
+/**
+ Enable parsing and writing of OCSP responses. This is enough
+ to support OCSP stapling.
+*/
+# define USE_OCSP_RESPONSE /**< @pre USE_SHA1 */
+#endif /* USE_OCSP */
+
+/******************************************************************************/
+/**
+ Various PKCS standards support
+ */
+# define USE_PRIVATE_KEY_PARSING
+# define USE_PKCS5/**< v2.0 PBKDF encrypted priv keys. @pre USE_3DES */
+/**< Enable PBKDF1 in priv key PEM encryption. @pre USE_PKCS5 and @pre USE_MD5. @security Not recommended. */
+# define USE_PBKDF1
+# define USE_PKCS8/* Alternative private key storage format */
+# define USE_PKCS12/**< @pre USE_PKCS8 */
+# define USE_PKCS1_OAEP/* OAEP padding algorithm */
+# define USE_PKCS1_PSS/* PSS padding algorithm */
+
+#endif /* _h_PS_CRYPTOCONFIG */
+
+/******************************************************************************/
+
diff --git a/configs/tls13/matrixsslConfig.h b/configs/tls13/matrixsslConfig.h
new file mode 100644
index 0000000..472b4b1
--- /dev/null
+++ b/configs/tls13/matrixsslConfig.h
@@ -0,0 +1,432 @@
+/**
+ * @file matrixsslConfig.h
+ * @version $Format:%h%d$
+ *
+ * Configuration settings for building the MatrixSSL library.
+ * This configuration is intended to be used in FIPS Mode of operation.
+ * The configuration aims to be compatible with NIST SP 800-52 Rev 1 and
+ * to enable the most commonly used cipher suites.
+ */
+/*
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
+ *
+ * The latest version of this code is available at http://www.matrixssl.org
+ *
+ * This software is open source; 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.
+ *
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
+ *
+ * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+/******************************************************************************/
+
+#ifndef _h_MATRIXSSLCONFIG
+# define _h_MATRIXSSLCONFIG
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+/**
+ NIST SP 800-52 Rev 1 Conformance.
+ Guidelines for the Selection, Configuration, and Use of Transport Layer
+ Security (TLS) Implementations
+ The key words "shall", "shall not", "should", "should not" and "may"
+ are used as references to the NIST SP 800-52 Rev 1. Algorithms marked as
+ "shall" must not be disabled unless NIST SP 800-52 Rev 1 compatibility
+ is not relevant.
+ @see http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-52r1.pdf
+ */
+
+/******************************************************************************/
+/**
+ Show which SSL messages are created and parsed
+ */
+/* #define USE_SSL_HANDSHAKE_MSG_TRACE */
+
+/**
+ Informational trace that could help pinpoint problems with SSL connections
+ */
+/* #define USE_SSL_INFORMATIONAL_TRACE */
+/* #define USE_DTLS_DEBUG_TRACE */
+
+/******************************************************************************/
+/**
+ Recommended cipher suites.
+ Define the following to enable various cipher suites
+ At least one of these must be defined. If multiple are defined,
+ the handshake negotiation will determine which is best for the connection.
+ @note Ephemeral ciphersuites offer perfect forward security (PFS)
+ at the cost of a slower TLS handshake.
+ */
+
+/** TLS 1.3 ciphers */
+# define USE_TLS_AES_128_GCM_SHA256
+# define USE_TLS_AES_256_GCM_SHA384
+# define USE_TLS_CHACHA20_POLY1305_SHA256
+
+/** Ephemeral ECC DH keys, ECC DSA certificates */
+# define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA/**< @security NIST_SHOULD */
+# define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA/**< @security NIST_MAY */
+/* TLS 1.2 ciphers */
+# define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256/**< @security NIST_SHOULD */
+# define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384/**< @security NIST_MAY */
+# define USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256/**< @security NIST_SHOULD */
+# define USE_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384/**< @security NIST_SHOULD */
+/** CHACHA20-POLY1305 cipher suites according to RFC 7905. */
+/* #define USE_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 */
+
+/** Ephemeral ECC DH keys, RSA certificates */
+# define USE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA/**< @security NIST_SHOULD */
+# define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
+/* TLS 1.2 ciphers */
+# define USE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256/**< @security NIST_SHOULD */
+# define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384/**< @security NIST_MAY */
+# define USE_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256/**< @security NIST_SHOULD */
+# define USE_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384/**< @security NIST_SHOULD */
+/** CHACHA20-POLY1305 cipher suites according to RFC 7905. */
+/* #define USE_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 */
+
+/** Ephemeral Diffie-Hellman ciphersuites, with RSA certificates */
+/* #define USE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA */
+/* #define USE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA */
+/* TLS 1.2 ciphers */
+/* #define USE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 */
+/* #define USE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 */
+
+/** Non-Ephemeral RSA keys/certificates */
+# define USE_TLS_RSA_WITH_AES_128_CBC_SHA/**< @security NIST_SHALL */
+# define USE_TLS_RSA_WITH_AES_256_CBC_SHA/**< @security NIST_SHOULD */
+/* TLS 1.2 ciphers */
+# define USE_TLS_RSA_WITH_AES_128_CBC_SHA256/**< @security NIST_MAY */
+# define USE_TLS_RSA_WITH_AES_256_CBC_SHA256/**< @security NIST_MAY */
+# define USE_TLS_RSA_WITH_AES_128_GCM_SHA256/**< @security NIST_SHALL */
+# define USE_TLS_RSA_WITH_AES_256_GCM_SHA384/**< @security NIST_SHOULD */
+
+/******************************************************************************/
+/**
+ These cipher suites are secure, but not widely deployed.
+ */
+
+/** Ephemeral Diffie-Hellman ciphersuites, with RSA certificates */
+/* #define USE_SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA */
+
+/** Ephemeral Diffie-Hellman ciphersuites, with PSK authentication */
+/* #define USE_TLS_DHE_PSK_WITH_AES_128_CBC_SHA *//**< @security NIST_SHOULD_NOT */
+/* #define USE_TLS_DHE_PSK_WITH_AES_256_CBC_SHA *//**< @security NIST_SHOULD_NOT */
+
+/** Ephemeral ECC DH keys, RSA certificates */
+/* #define USE_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA *//**< @security NIST_SHOULD */
+
+/** Pre-Shared Key Ciphers.
+ NIST SP 800-52 Rev 1 recommends against using PSK unless neccessary
+ See NIST SP 800-52 Rev 1 Appendix C */
+# define USE_TLS_PSK_WITH_AES_128_CBC_SHA/**< @security NIST_SHOULD_NOT */
+# define USE_TLS_PSK_WITH_AES_256_CBC_SHA/**< @security NIST_SHOULD_NOT */
+/* TLS 1.2 ciphers */
+# define USE_TLS_PSK_WITH_AES_128_CBC_SHA256/**< @security NIST_SHOULD_NOT */
+# define USE_TLS_PSK_WITH_AES_256_CBC_SHA384/**< @security NIST_SHOULD_NOT */
+
+/** Non-Ephemeral ECC DH keys, ECC DSA certificates */
+# define USE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA/**< @security NIST_MAY */
+# define USE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA/**< @security NIST_MAY */
+/* TLS 1.2 ciphers */
+# define USE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256/**< @security NIST_MAY */
+# define USE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384/**< @security NIST_MAY */
+# define USE_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256/**< @security NIST_MAY */
+# define USE_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384/**< @security NIST_MAY */
+
+/** Non-Ephemeral ECC DH keys, RSA certificates */
+# define USE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
+# define USE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
+/* TLS 1.2 ciphers */
+# define USE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
+# define USE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
+# define USE_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
+# define USE_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
+
+/** Non-Ephemeral RSA keys/certificates */
+/* #define USE_SSL_RSA_WITH_3DES_EDE_CBC_SHA *//**< @security NIST_SHALL */
+
+/** @note Some of (non-mandatory) cipher suites mentioned in NIST SP 800-52
+ Rev 1 are not supported by the MatrixSSL / MatrixDTLS.
+ ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA (NIST SP 800-52 Rev 1 "should")
+ is rarely used cipher suite and is not supported.
+ Also (NIST SP 800-52 Rev 1 "may") TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
+ TLS_DHE_DSS_WITH_* and TLS_RSA_WITH_AES_*_CCM cipher suites cannot be
+ enabled as they are not supported. */
+
+/******************************************************************************/
+/**
+ Legacy cipher suites.
+ These cipher suites have been deprecated, but may be occasionally required
+ for legacy compatibility. Usage of these cipher suites should be avoided
+ as these may represent small or moderate risk.
+
+ Note: The RC4 cipher suites below need to disabled according to RFC 7465.
+*/
+/* #define USE_SSL_RSA_WITH_RC4_128_SHA *//**< @security NIST_SHALL_NOT */
+
+/******************************************************************************/
+/**
+ Ephemeral key cache support.
+ If not using cache, new key exchange keys are created for each TLS session.
+ If using cache, keys are generated initially, and re-used in each
+ subsequent TLS connection within a given time frame and usage count.
+ @see ECC_EPHEMERAL_CACHE_SECONDS and ECC_EPHEMERAL_CACHE_USAGE
+
+ @security Do not cache Ephemeral ECC keys as it is against some standards,
+ including NIST SP 800-56A, when in FIPS 140-2 mode of operation.
+ */
+/* #define NO_ECC_EPHEMERAL_CACHE *//**< @security NIST_SHALL */
+
+/******************************************************************************/
+/**
+ Configure Support for TLS protocol versions.
+ Define one of:
+ USE_TLS_1_2_AND_ABOVE (TLS 1.2 and 1.3)
+ USE_TLS_1_1_AND_ABOVE (TLS 1.1, 1.2 and 1.3)
+ USE_TLS_1_0_AND_ABOVE (TLS 1.0, 1.1, 1.2 and 1.3)
+ @note There is no option for enabling SSL3.0 at this level
+ */
+# define USE_TLS_1_1_AND_ABOVE/**< @security default 1_1_AND_ABOVE */
+/* #define USE_TLS_1_2_AND_ABOVE *//**< @security better than 1_1_AND_ABOVE if no backwards compatiblity concerns */
+/* #define USE_TLS_1_0_AND_ABOVE *//**< @security no longer recommended. */
+
+/** Enable support for session resumption in TLS 1.3. */
+# define USE_TLS_1_3_RESUMPTION
+
+/** TLS 1.3 code has not yet been footprint-optimized. For this reason,
+ it is possible to separately leave all TLS 1.3 code out of the build
+ by enabling this. */
+/* #define DISABLE_TLS_1_3 */
+
+/******************************************************************************/
+/**
+ Datagram TLS support.
+ Enables DTLS in addition to TLS.
+ @pre TLS_1_1
+ */
+# define USE_DTLS
+
+/******************************************************************************/
+/**
+ Compile time support for server or client side SSL
+ */
+# define USE_CLIENT_SIDE_SSL
+# define USE_SERVER_SIDE_SSL
+
+/******************************************************************************/
+/**
+ Allow the server to parse SSL 2.0 ClientHello messages even when the
+ server does not actually support SSL 2.0. As per RFC 5246, E.2:
+
+ "... even TLS servers that do not support SSL 2.0 MAY accept version
+ 2.0 CLIENT-HELLO messages."
+
+ This option is for compatibility with clients that support
+ SSL 2.0 but are ready to negotiate a higher version such as TLS 1.0.
+ Note that enabling this option will only allow parsing of the SSL 2.0
+ ClientHellos; it will not enable support for the SSL 2.0 protocol.
+ Only 32-byte challenges in the SSL 2.0 ClientHello are supported.
+*/
+# ifdef USE_SERVER_SIDE_SSL
+/* #define ALLOW_SSLV2_CLIENT_HELLO_PARSE */
+# endif
+
+/******************************************************************************/
+/**
+ Client certificate authentication
+ */
+# define USE_CLIENT_AUTH
+
+# ifdef USE_CLIENT_AUTH
+/**
+ Enable the handshake_messages signature in the CertificateVerify
+ protocol message to be signed using an external module.
+ */
+/* #define USE_EXT_CERTIFICATE_VERIFY_SIGNING */
+# ifdef USE_EXT_CERTIFICATE_VERIFY_SIGNING
+/**
+ Compile an example external module that allows the
+ USE_EXT_CERTIFICATE_VERIFY_SIGNING feature to be tested using the example
+ client program and sslTest.
+ */
+/* #define USE_EXT_EXAMPLE_MODULE */
+# endif
+
+/**
+ Enable loading of a new client certificate and private key
+ in response to a CertificateRequest message from a server. This feature
+ allows the client program to e.g. select a client certificate
+ whose issuer is included in the server's list of trusted CAs
+ that was received in the CertificateRequest message.
+*/
+/* #define USE_EXT_CLIENT_CERT_KEY_LOADING */
+# endif /* USE_CLIENT_AUTH */
+
+/**
+ Enable if the server should send an empty CertificateRequest message if
+ no CA files have been loaded
+ */
+/* #define SERVER_CAN_SEND_EMPTY_CERT_REQUEST */
+
+/**
+ Enabling this define will allow the server to "downgrade" a client auth
+ handshake to a standard handshake if the client replies to a
+ CERTIFICATE_REQUEST with an empty CERTIFICATE message. The user callback
+ will be called with a NULL cert in this case and the user can determine if
+ the handshake should continue in a non-client auth state.
+ */
+/* #define SERVER_WILL_ACCEPT_EMPTY_CLIENT_CERT_MSG */
+
+/******************************************************************************/
+/**
+ Allow partial parsing of CA certificate bundles. By default, loading of
+ CA files via matrixSslLoadRsaKeys, etc. will fail if the bundle contains
+ a certificate not supported by MatrixSSL's current configuration. When
+ this define is enabled, the parsing of some CA certificates is allowed fail.
+ When parsing of a CA cert fails, a dummy psX509Cert_t with will be added
+ to the CAcerts list. Consult the parseStatus members for details on why
+ the parsing of a specific certificate failed.
+ */
+/* #define ALLOW_CA_BUNDLE_PARTIAL_PARSE */
+
+/******************************************************************************/
+/**
+ Enable the Application Layer Protocol Negotiation extension.
+ Servers and Clients will still have to use the required public API to
+ set protocols and register application callbacks to negotiate the
+ protocol that will be tunneled over TLS.
+ @see ALPN section in the developer's guide for information.
+ */
+/* #define USE_ALPN */
+
+/******************************************************************************/
+/**
+ Enable the Trusted CA Indication CLIENT_HELLO extension. Will send the
+ sha1 hash of each CA file to the server for help in server selection.
+ This extra level of define is to help isolate the SHA1 requirement
+ */
+/* #define USE_TRUSTED_CA_INDICATION *//**< @security NIST_SHOULD */
+
+/******************************************************************************/
+/**
+ A client side configuration that requires a server to provide an OCSP
+ response if the client uses the certitificate status request extension.
+ The "must staple" terminology is typically associated with certificates
+ at the X.509 layer but it is a good description of what is being required
+ of the server at the TLS level.
+ @pre USE_OCSP_RESPONSE must be enabled at the crypto level and the client
+ application must use the OCSPstapling session option at run time for this
+ setting to have any effect
+ */
+# ifdef USE_OCSP_RESPONSE
+# define USE_OCSP_MUST_STAPLE /**< @security NIST_SHALL */
+# endif
+
+/******************************************************************************/
+/**
+ Rehandshaking support.
+
+ Enabling USE_REHANDSHAKING will allow secure-rehandshakes using the
+ protocol defined in RFC 5748 which fixed a critical exploit in
+ the standard TLS specification.
+
+ @security Looking towards TLS 1.3, which removes re-handshaking, this
+ feature is disabled by default.
+ */
+/* #define USE_REHANDSHAKING */
+
+/******************************************************************************//**
+ False Start support for Chrome and Firefox browsers.
+ @see https://tools.ietf.org/html/rfc7918
+
+ Some versions of Firefox browser and Chrome browser include support for
+ False Start. This flag will enable server side support on MatrixSSL
+ operating as server for client using false start feature.
+
+ @note April 2012: Google has announced this feature will be removed in
+ version 20 of their browser due to industry compatibility issues.
+ However because there are other browsers using the feature, this feature
+ is often recommendable to enable for maximal browser compatibility.
+ */
+# define USE_SERVER_SIDE_FALSE_START_SUPPORT
+
+/******************************************************************************/
+/**
+ If SERVER you may define the number of sessions to cache and how
+ long a session will remain valid in the cache from first access.
+ Session caching enables very fast "session resumption handshakes".
+
+ SSL_SESSION_TABLE_SIZE minimum value is 1
+ SSL_SESSION_ENTRY_LIFE is in milliseconds, minimum 0
+
+ @note Session caching can be disabled by setting SSL_SESSION_ENTRY_LIFE to 0
+ however, this will also immediately expire SESSION_TICKETS below.
+ */
+# ifdef USE_SERVER_SIDE_SSL
+# define SSL_SESSION_TABLE_SIZE 32
+# define SSL_SESSION_ENTRY_LIFE (86400 * 1000)/* one day, in milliseconds */
+# endif
+
+/******************************************************************************/
+/**
+ Use RFC 5077 session resumption mechanism. The SSL_SESSION_ENTRY_LIFE
+ define applies to this method as well as the standard method. The
+ SSL_SESSION_TICKET_LIST_LEN is the max size of the server key list.
+ */
+# define USE_STATELESS_SESSION_TICKETS
+# define SSL_SESSION_TICKET_LIST_LEN 32
+
+/******************************************************************************/
+/**
+ The initial buffer sizes for send and receive buffers in each ssl_t session.
+ Buffers are internally grown if more incoming or outgoing data storage is
+ needed, up to a maximum of SSL_MAX_BUF_SIZE. Once the memory used by the
+ buffer again drops below SSL_DEFAULT_X_BUF_SIZE, the buffer will be reduced
+ to this size. Most standard SSL handshakes require on the order of 1024 B.
+
+ SSL_DEFAULT_x_BUF_SIZE value in bytes, maximum SSL_MAX_BUF_SIZE
+ */
+# ifndef USE_DTLS
+# define SSL_DEFAULT_IN_BUF_SIZE 1500 /* Base recv buf size, bytes */
+# define SSL_DEFAULT_OUT_BUF_SIZE 1500 /* Base send buf size, bytes */
+# else
+/******************************************************************************/
+/**
+ The Path Maximum Transmission Unit is the largest datagram that can be
+ sent or recieved. It is beyond the scope of DTLS to negotiate this value
+ so make sure both sides have agreed on this value. This is an enforced
+ limitation in MatrixDTLS so connections will not succeed if a peer has a
+ PTMU set larger than this value.
+ */
+# define DTLS_PMTU 1500 /* 1500 Default/Maximum datagram len */
+# define SSL_DEFAULT_IN_BUF_SIZE DTLS_PMTU /* See PMTU comments above */
+# define SSL_DEFAULT_OUT_BUF_SIZE DTLS_PMTU /* See PMTU comments above */
+
+/* #define DTLS_SEND_RECORDS_INDIVIDUALLY *//* Max one record per datagram */
+# endif
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif /* _h_MATRIXCONFIG */
+/******************************************************************************/
+
diff --git a/core/GNUmakefile b/core/GNUmakefile
new file mode 100644
index 0000000..19bca06
--- /dev/null
+++ b/core/GNUmakefile
@@ -0,0 +1,95 @@
+#
+# Makefile for core static library
+#
+# Copyright (c) 2013-2017 INSIDE Secure Corporation. All Rights Reserved.
+#
+
+ifeq ($(wildcard Makefile),)
+
+# Override according to the type of the system
+OSDEP=osdep/POSIX
+SRC_CORE=\
+ memset_s.c \
+ corelib_main.c \
+ corelib_trace.c \
+ corelib_date.c \
+ corelib_strings.c \
+ corelib_list.c \
+ psbuf.c \
+ psUtil.c \
+ psStat.c \
+ $(OSDEP)/osdep.c \
+ osdep/ANSI/osdep_break.c \
+ $(OSDEP)/psLog.c \
+ $(OSDEP)/psPrnf.c \
+ c_lib.c \
+ cl_basic.c \
+ debug_abort.c \
+ debug_printf.c \
+ psprintf.c \
+ psmalloc.c \
+ psmalloc_ext.c \
+ sfzclbuffer.c \
+ sfzclcalendar.c \
+ sfzclfastalloc.c \
+ sfzclfileio.c \
+ sfzclmalloc.c \
+ sfzclmemparser.c \
+ sfzcltimemeasure.c \
+ sfzclobstack.c \
+ sfzclsnprintf.c \
+ sfzclbase64.c \
+ sfzclstr.c \
+ sfzcltime.c \
+ osdep/ANSI/spal_memory_ansi.c \
+ utils.c \
+ $(OSDEP)/spal_posix_mutex.c \
+ $(OSDEP)/spal_posix_semaphore.c \
+ $(OSDEP)/spal_posix_sleep.c \
+ $(OSDEP)/spal_posix_thread.c \
+ sl_cpu.c \
+ sl_neon.c \
+ osdep/src/cl_memset.c \
+ osdep/src/runtime.c
+
+# Flags for garbage collection to allow selection of a subset of libcore_s.a.
+CFLAGS_GARBAGE_COLLECTION ?= -ffunction-sections -fdata-sections
+
+noinst_LIBRARIES=libcore_s.a libsfzutf_s.a libtestsupp_s.a
+libcore_s_a_SOURCES=$(SRC_CORE)
+libcore_s_a_API=core
+libcore_s_a_CFLAGS=$(CFLAGS_POSITION_INDEPENDENT) $(CFLAGS_GARBAGE_COLLECTION)
+VPATH+=src
+
+libsfzutf_s_a_SOURCES=$(addprefix testsupp/src/sfzutf/, \
+sfzutf.c sfzutf-heap.c sfzutf_interactive.c sfzutf_main_stdio.c \
+sfzutf-perf.c sfzutf-stack.c sfzutf-utils.c)
+libsfzutf_s_a_API=core sfzutf
+libsfzutf_s_a_CFLAGS=$(CFLAGS_POSITION_INDEPENDENT)
+
+libtestsupp_s_a_SOURCES=$(addprefix testsupp/src/, testsupp.c)
+libtestsupp_s_a_API=core testsupp
+libtestsupp_s_a_CFLAGS=$(CFLAGS_POSITION_INDEPENDENT)
+
+# Special case: on ARM platforms sl_neon.c needs NEON compilation flags.
+include makefiles/platform_specific.mk
+sl_neon_c_CFLAGS=$(CFLAGS_ENABLE_NEON)
+
+CORE_DIR=../core
+include $(CORE_DIR)/makefiles/rules.mk
+
+CPPFLAGS_EXTRACT_MACROS=-dM
+# Allows to check configuration options.
+parse-config:
+ echo '#include "coreConfig.h"' | $(CC) $(CFLAGS) -I config $(CPPFLAGS_EXTRACT_MACROS) -E -x c -
+
+else
+
+# Makefile exists. Let it override this build file.
+# (Note: This modifies priority of make built-in lookup priority.)
+# This rule will allow the user to override this GNUmakefile with
+# build rules from eg. cmake.
+
+include Makefile
+
+endif
diff --git a/core/Makefile b/core/Makefile
deleted file mode 100644
index 49cfb6f..0000000
--- a/core/Makefile
+++ /dev/null
@@ -1,52 +0,0 @@
-#
-# Makefile for core static library
-#
-# Copyright (c) 2013-2016 INSIDE Secure Corporation. All Rights Reserved.
-#
-
-MATRIXSSL_ROOT:=..
-include $(MATRIXSSL_ROOT)/common.mk
-
-SRC:=\
- memset_s.c \
- corelib.c \
- psbuf.c \
- psUtil.c \
- $(OSDEP)/osdep.c \
- $(OSDEP)/psLog.c \
- $(OSDEP)/psPrnf.c
-
-ASM:=memset_s.s
-
-# Generated files
-STATIC:=libcore_s.a
-
-CFLAGS+=$(CFLAGS_ARCHITECTURE_VARIANT) $(FLAGS_ARCHITECTURE_VARIANT)
-LDFLAGS+=$(LDFLAGS_ARCHITECTURE_VARIANT) $(FLAGS_ARCHITECTURE_VARIANT)
-
-all: compile
-
-compile: $(ASM) $(OBJS) $(STATIC)
-
-# Special rule to build memset_s function without optimization
-memset_s.o: memset_s.c
- $(CC) -O0 -Wall -ffunction-sections -fdata-sections -o $@ $(CFLAGS_MEMSET_S) $(CFLAGS_ARCHITECTURE_VARIANT) $(FLAGS_ARCHITECTURE_VARIANT) -c $<
-
-# Generate the (.s) assembly file to verify zero is being performed
-$(ASM): memset_s.c
- $(CC) -O0 -g -fverbose-asm $(CFLAGS_MEMSET_S) $(ASFLAGS_ARCHITECTURE_VARIANT) $(FLAGS_ARCHITECTURE_VARIANT) -S $<
-
-# Additional Dependencies
-$(OBJS): $(MATRIXSSL_ROOT)/common.mk Makefile *.h
-
-# Build the static library
-
-$(STATIC): $(OBJS)
- $(AR) -rcu $@ $^
-
-clean:
- rm -f $(STATIC) $(OBJS) $(ASM)
-
-# Allows to check configuration options.
-parse-config:
- echo '#include "coreConfig.h"' | $(CC) $(CFLAGS) -dM -E -x c -
diff --git a/core/Makefile.inc b/core/Makefile.inc
new file mode 100644
index 0000000..e521327
--- /dev/null
+++ b/core/Makefile.inc
@@ -0,0 +1,21 @@
+#
+# Path and linkage information for core static library
+#
+# Copyright (c) 2017 INSIDE Secure. All Rights Reserved.
+#
+
+# This Makefile.inc is used from other Makefiles to reference
+# parts of the core library.
+
+# Find path of the current directory (unless previously specified)
+ifeq '$(origin CORE_PATH)' 'undefined'
+CORE_PATH:=$(patsubst %/,%/,$(dir $(lastword $(MAKEFILE_LIST))))
+endif
+
+# Find path of the core module
+CFLAGS_CORE_INCLUDE=\
+-I$(CORE_PATH)/config -I$(CORE_PATH)/include -I$(CORE_PATH)/osdep/include \
+-I$(CORE_PATH)/include/sfzcl -I$(CORE_PATH)/osdep/include
+
+LIB_CORE_S=$(CORE_PATH)/libcore_s.a
+LDADD_CORE_S=$(CORE_PATH)/libcore_s.a -lpthread
diff --git a/core/apps/GNUmakefile b/core/apps/GNUmakefile
new file mode 100644
index 0000000..a2efd07
--- /dev/null
+++ b/core/apps/GNUmakefile
@@ -0,0 +1,27 @@
+#
+# Makefile for core testing
+#
+# Copyright (c) 2013-2016 INSIDE Secure Corporation. All Rights Reserved.
+#
+
+ifeq ($(wildcard Makefile),)
+
+EXTRA_PROGRAMS=log logcc
+log_SOURCES=log.c
+log_API=core
+logcc_SOURCES=logcc.cc
+logcc_API=core
+
+CORE_DIR=../../core
+include $(CORE_DIR)/makefiles/rules.mk
+
+else
+
+# Makefile exists. Let it override this build file.
+# (Note: This modifies priority of make built-in lookup priority.)
+# This rule will allow the user to override this GNUmakefile with
+# build rules from eg. cmake.
+
+include Makefile
+
+endif
diff --git a/core/apps/log.c b/core/apps/log.c
new file mode 100644
index 0000000..a25c9cf
--- /dev/null
+++ b/core/apps/log.c
@@ -0,0 +1,181 @@
+/* This program illustrates logging. */
+
+/* Note: This program is intended to run with all logging messages on. */
+
+#ifndef _h_PS_CORECONFIG
+# ifdef MATRIX_CONFIGURATION_INCDIR_FIRST
+# include /* Must be first included */
+# else
+# include "coreConfig.h" /* Must be first included */
+# endif
+#endif /* _h_PS_CORECONFIG */
+
+/* Override any possible disabled logging, except verbose.
+ This is neccessary, because the program is dependent on
+ messages working as expected.
+ Note: Normally do this setting via "coreConfig.h" */
+#undef PS_NO_LOGF_FATAL
+#undef PS_NO_LOGF_ERROR
+#undef PS_NO_LOGF_WARNING
+#undef PS_NO_LOGF_INFO
+#undef PS_NO_LOGF_DEBUG
+#undef PS_NO_LOGF_TRACE
+#undef PS_NO_LOGF_CALL_TRACE
+
+/* Intentionally omit one message class to see those messages are
+ never detected by hook functions.
+ Note: Normally do this setting via "coreConfig.h" */
+#ifndef PS_NO_LOGF_VERBOSE
+#define PS_NO_LOGF_VERBOSE
+#endif /* PS_NO_LOGF_VERBOSE */
+
+#include "psLog.h"
+
+#ifndef debugf
+#define debugf(x, ...) PS_LOGF_DEBUG(UNIT, x ,##__VA_ARGS__ )
+#endif
+#ifndef tracef
+#define tracef(x, ...) PS_LOGF_TRACE(UNIT, x ,##__VA_ARGS__ )
+#endif
+
+void helper(void)
+{
+ tracef("Helper function starts\n");
+ tracef("Helper function finished\n");
+}
+
+#include "osdep_stdio.h"
+#include "osdep_assert.h"
+
+/* Combined count of seen logs (in hex).
+ Note: Although kludgy, a single counter allows short comparison of all
+ counts. */
+unsigned long long Counts = 0x0;
+
+int hooked_0(const char *level, const char *unit)
+{
+ if (level == psLogf_Log_CallTrace) Counts += 0x1;
+ if (level == psLogf_Log_Trace) Counts += 0x10;
+ if (level == psLogf_Log_Verbose) Counts += 0x100;
+ if (level == psLogf_Log_Debug) Counts += 0x1000;
+ if (level == psLogf_Log_Info) Counts += 0x10000;
+ if (level == psLogf_Log_Warning) Counts += 0x100000;
+ if (level == psLogf_Log_Error) Counts += 0x1000000;
+ if (level == psLogf_Log_Fatal) Counts += 0x10000000;
+ return 0;
+}
+
+int hooked_1(const char *level, const char *unit)
+{
+ if (level == psLogf_Log_CallTrace) Counts += 0x1;
+ if (level == psLogf_Log_Trace) Counts += 0x10;
+ if (level == psLogf_Log_Verbose) Counts += 0x100;
+ if (level == psLogf_Log_Debug) Counts += 0x1000;
+ if (level == psLogf_Log_Info) Counts += 0x10000;
+ if (level == psLogf_Log_Warning) Counts += 0x100000;
+ if (level == psLogf_Log_Error) Counts += 0x1000000;
+ if (level == psLogf_Log_Fatal) Counts += 0x10000000;
+ return 1;
+}
+
+#ifndef Vprintf
+#define Vprintf vprintf /* osdep_stdio.h may not have wrapper for vprintf. */
+#endif
+
+int hooked_print_context(const char *level,
+ const char *unit,
+ const char *format_string,
+ va_list va)
+{
+ if (level == psLogf_Log_Trace)
+ {
+ /* Logging classes supported by the function.
+ This function intentionally only supports trace. */
+ Vprintf(format_string, va);
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+int hooked_print_no_context(const char *level,
+ const char *unit,
+ const char *format_string,
+ va_list va)
+{
+ if (level == psLogf_Log_Trace)
+ {
+ /* Logging classes supported by the function.
+ This function intentionally only supports trace. */
+ PS_LOGF_RAW_FMT(format_string, va); /* Omit context. */
+ Vprintf(format_string, va);
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+int hooked(void)
+{
+ psLogfSetHookEnabledCheck(hooked_0);
+ /* All logging is disabled: */
+ tracef("Omitted trace1\n");
+ tracef("Omitted trace2\n");
+ debugf("Omitted debug1\n");
+ Assert(Counts == 0x1020);
+ /* Try all message types once. */
+ PS_LOGF_CALL_TRACE(LOG, "calltrace (%d)", 0);
+ PS_LOGF_TRACE(LOG, "trace (%d)", 1);
+ PS_LOGF_VERBOSE(LOG, "verbose (%d)", 2);
+ PS_LOGF_DEBUG(LOG, "debug (%d)", 3);
+ PS_LOGF_INFO(LOG, "info (%d)", 4);
+ PS_LOGF_WARNING(LOG, "warning (%d)", 5);
+ PS_LOGF_ERROR(LOG, "error (%d)", 6);
+ PS_LOGF_FATAL(LOG, "fatal (%d)", 7);
+ Assert(Counts == 0x11112031);
+ psLogfSetHookEnabledCheck(hooked_1);
+ psLogfSetHookPrintf(hooked_print_context);
+ /* All logging is enabled: */
+#ifdef PS_NO_LOGF_FILELINE
+ tracef("Log message with context (partial context due to %s)\n",
+ "PS_NO_LOGF_FILELINE");
+#else
+ tracef("Log message with context (if available)\n");
+ Printf("Note: Configuration #define %s will omit file+line.\n",
+ "PS_NO_LOGF_FILELINE");
+#endif
+ psLogfSetHookPrintf(hooked_print_no_context);
+ debugf("Log message that is filtered within printing function.\n");
+ tracef("Log message without context\n");
+ psLogfSetHookPrintf(hooked_print_context);
+ tracef("Finished with hooking test (displayed as log message)\n");
+ Assert(Counts == 0x11113061);
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ /* Note: If you see the program printing nothing, try
+ setting environment variables, eg. PS_ENABLE_LOG=1,
+ Or try ltrace -e getenv ./log. */
+
+ if (argc >= 2 && argv[1][0] == '-' && argv[1][1] == 'f')
+ {
+ Printf("Illustrate hooks\n");
+ return hooked();
+ }
+
+ Printf("This program demonstrates logging functions.\n");
+ Printf("Normally you should see nothing as debug and trace\n");
+ Printf("defaults blocked. However, if you enable debugging via\n");
+ Printf("environment variables such as PS_ENABLE_LOG all the log will be\n");
+ Printf("visible.\n");
+ Printf("Alternative invocations: %s -f - illustrate hooking\n", argv[0]);
+
+ debugf("Program starts\n");
+ helper();
+ debugf("Program finished\n");
+ return 0;
+}
diff --git a/core/apps/logcc.cc b/core/apps/logcc.cc
new file mode 100644
index 0000000..88589d5
--- /dev/null
+++ b/core/apps/logcc.cc
@@ -0,0 +1,2 @@
+/* The same facilities are also available from C++. */
+#include "log.c"
diff --git a/core/config/cf_impldefs.h b/core/config/cf_impldefs.h
new file mode 100644
index 0000000..12ba371
--- /dev/null
+++ b/core/config/cf_impldefs.h
@@ -0,0 +1,104 @@
+/* cf_impldefs.h
+ *
+ * Description: Configuration options for Framework/IMPLDEFS implementation
+ */
+
+/*****************************************************************************
+* Copyright (c) 2007-2016 INSIDE Secure Oy. All Rights Reserved.
+*
+* The latest version of this code is available at http://www.matrixssl.org
+*
+* This software is open source; 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.
+*
+* This General Public License does NOT permit incorporating this software
+* into proprietary programs. If you are unable to comply with the GPL, a
+* commercial license for this software may be purchased from INSIDE at
+* http://www.insidesecure.com/
+*
+* This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+* http://www.gnu.org/copyleft/gpl.html
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_CF_IMPLDEFS_H
+#define INCLUDE_GUARD_CF_IMPLDEFS_H 1
+
+/*
+ All L_PRINTFs (ie. all debug/trace and panic messages).
+ */
+#undef IMPLDEFS_CF_DISABLE_DEBUG_L_PRINTF
+
+
+/*
+ L_DEBUG print outs.
+ */
+#undef IMPLDEFS_CF_DISABLE_L_DEBUG
+
+#ifdef CFG_IMPLDEFS_NO_DEBUG
+# define IMPLDEFS_CF_DISABLE_L_DEBUG
+#endif
+
+
+/*
+ L_TRACE print outs.
+ */
+#undef IMPLDEFS_CF_DISABLE_L_TRACE
+
+/*
+ ASSERT() macro, i.e. assertion checks.
+ */
+#undef IMPLDEFS_CF_DISABLE_ASSERT
+
+#ifdef CFG_IMPLDEFS_NO_DEBUG
+# define IMPLDEFS_CF_DISABLE_ASSERT
+#endif
+
+/*
+ PRECONDITION() macro, ie. function contract input checks.
+ */
+#undef IMPLDEFS_CF_DISABLE_PRECONDITION
+
+#ifdef CFG_IMPLDEFS_NO_DEBUG
+# define IMPLDEFS_CF_DISABLE_PRECONDITION
+#endif
+
+/*
+ POSTCONDITION() macro, ie. function contract output checks.
+ */
+#undef IMPLDEFS_CF_DISABLE_POSTCONDITION
+
+#ifdef CFG_IMPLDEFS_NO_DEBUG
+# define IMPLDEFS_CF_DISABLE_POSTCONDITION
+#endif
+
+/**
+ All assertion and function contract checks.
+ (Ie. ASSERT(), PRECONDITION(), and POSTCONDITION() macros.)
+ */
+#undef IMPLDEFS_CF_DISABLE_ASSERTION_CHECK
+
+#ifdef CFG_IMPLDEFS_NO_DEBUG
+# define IMPLDEFS_CF_DISABLE_ASSERTION_CHECK
+#endif
+
+/** Functionality that is omitted.
+ Old sfzcl_snprintf (with renderer support) is no longer used by default. */
+#define NO_SFZCL_SNPRINTF 1
+
+/* Support for ISO 8859-2, 8859-3, and 8859-4 character set is omitted.
+ For characters beyond ASCII, UTF-8 needs to be used instead. */
+/* #define USE_SFZCL_CHARSET_ISO_8859_2_CONVERTER 1 */
+/* #define USE_SFZCL_CHARSET_ISO_8859_3_CONVERTER 2 */
+/* #define USE_SFZCL_CHARSET_ISO_8859_4_CONVERTER 3 */
+
+#endif /* INCLUDE_GUARD_CF_IMPLDEFS_H */
+
+/* end of file cf_impldefs.h */
diff --git a/core/config/cfg_pkcslib.h b/core/config/cfg_pkcslib.h
new file mode 100644
index 0000000..e057741
--- /dev/null
+++ b/core/config/cfg_pkcslib.h
@@ -0,0 +1,76 @@
+/* cfg_pkcslib.h
+ *
+ * Description: PKCS library distribution constants
+ */
+
+/*****************************************************************************
+* Copyright (c) 2007-2017 INSIDE Secure Oy. All Rights Reserved.
+*
+* The latest version of this code is available at http://www.matrixssl.org
+*
+* This software is open source; 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.
+*
+* This General Public License does NOT permit incorporating this software
+* into proprietary programs. If you are unable to comply with the GPL, a
+* commercial license for this software may be purchased from INSIDE at
+* http://www.insidesecure.com/
+*
+* This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+* http://www.gnu.org/copyleft/gpl.html
+*****************************************************************************/
+
+#ifndef CFG_PKCSLIB_H
+#define CFG_PKCSLIB_H
+
+/* This configure must be enabled to use MD5 digests.
+ The MD5 digests have been demonstrated to be insecure and therefore
+ they are not recommended. Support for MD5 digests can
+ be disabled by this switch if needed. */
+#define SFZCLDIST_CRYPT_MD5
+
+/* Uncomment if making freestanding build. */
+/* Freestanding build will work on bare operating systems without
+ basic ISO C90/C99/C11 time, string, I/O and dynamic memory management
+ libraries. */
+/* #define SFZCLDIST_FREESTANDING */
+
+/* Provide SIZEOF_LONG to sfzclmp. */
+#ifndef SIZEOF_LONG
+# ifdef __LP64__
+# define SIZEOF_LONG 8
+# else
+# define SIZEOF_LONG 4
+# endif
+#endif
+
+/* ---- Predefined options ---- */
+
+/* The library is designed for this option combination and
+ altering these options means the build procedure and tests need
+ to be tweaked to adjust. */
+
+/* Cryptographic options. */
+#define WITH_RSA
+#define SFZCLDIST_CERT
+#define SFZCLDIST_CRYPT_DL
+#define SFZCLDIST_CRYPTO_HASH
+#define SFZCLDIST_CRYPT_SHA
+#define SFZCLDIST_CRYPT_DSA
+#define SFZCLDIST_CRYPTO_PK
+#define SFZCLDIST_CRYPTO
+#define SFZCLDIST_CRYPT
+#define SFZCLDIST_CRYPT_DES
+#define SFZCLDIST_CRYPT_SHA256
+
+#endif /* CFG_PKCSLIB_H */
+
+/* end of file cfg_pkcslib.h */
diff --git a/core/config/cfg_spal.h b/core/config/cfg_spal.h
new file mode 100644
index 0000000..2db31bb
--- /dev/null
+++ b/core/config/cfg_spal.h
@@ -0,0 +1,75 @@
+/* cfg_spal.h
+ *
+ * Description: SPAL configuration constants.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2007-2016 INSIDE Secure Oy. All Rights Reserved.
+*
+* The latest version of this code is available at http://www.matrixssl.org
+*
+* This software is open source; 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.
+*
+* This General Public License does NOT permit incorporating this software
+* into proprietary programs. If you are unable to comply with the GPL, a
+* commercial license for this software may be purchased from INSIDE at
+* http://www.insidesecure.com/
+*
+* This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+* http://www.gnu.org/copyleft/gpl.html
+*****************************************************************************/
+
+#ifndef INCLUSION_GUARD_CFG_SPAL_H
+#define INCLUSION_GUARD_CFG_SPAL_H
+
+/* These are configuration constants for SPAL.
+ The values have been tested with 32-bit and 64-bit Linux environments.
+ Depending on target OS values may have to be adjusted. */
+
+#if defined(__x86_64__) || defined(__aarch64__)
+/* For 64-bit environments: use wider pthread type. */
+# define SPAL_CFG_THREAD_TYPE long int
+#endif
+
+#if defined(__x86_64__) || defined(__aarch64__)
+/* For 64 bit environments: try doubling the storage size. */
+# if defined (__APPLE__)
+# define SPAL_CFG_MUTEX_SIZE 128
+# else
+# define SPAL_CFG_MUTEX_SIZE 64
+# endif /* APPLE */
+# define SPAL_CFG_MUTEX_ALIGN_TYPE long int
+#else
+# ifdef WIN32
+/* This value is needed by the Win32 build */
+# define SPAL_CFG_MUTEX_SIZE 36
+# else
+/* These value are large enough for encountered 32-bit linux variants. */
+# define SPAL_CFG_MUTEX_SIZE 28
+# endif
+# define SPAL_CFG_MUTEX_ALIGN_TYPE long int
+#endif
+
+
+#if defined(__x86_64__) || defined(__aarch64__)
+/* For 64 bit environments: try doubling the storage size. */
+# define SPAL_CFG_SEMAPHORE_SIZE 40
+# define SPAL_CFG_SEMAPHORE_ALIGN_TYPE void *
+#else
+/* These value are large enough for encountered 32-bit linux variants. */
+# define SPAL_CFG_SEMAPHORE_SIZE 20
+# define SPAL_CFG_SEMAPHORE_ALIGN_TYPE void *
+#endif
+
+#endif /* Include Guard */
+
+/* end of file cfg_spal.h */
diff --git a/core/config/coreConfig.h b/core/config/coreConfig.h
new file mode 100644
index 0000000..a0e9380
--- /dev/null
+++ b/core/config/coreConfig.h
@@ -0,0 +1,145 @@
+/**
+ * @file coreConfig.h
+ * @version $Format:%h%d$
+ *
+ * Configuration settings for Matrix core module.
+ */
+/*
+ * Copyright (c) 2013-2018 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
+ *
+ * The latest version of this code is available at http://www.matrixssl.org
+ *
+ * This software is open source; 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.
+ *
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
+ *
+ * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+/******************************************************************************/
+
+#ifndef _h_PS_CORECONFIG
+# define _h_PS_CORECONFIG
+
+
+/******************************************************************************/
+/* Debug and tracing configuration */
+/******************************************************************************/
+
+/**
+ Select tracing facility.
+ Default: Use psLogf, which is used in all of MatrixSSL, CL etc. and
+ allows log redirection.
+
+ On the smallest embedded targets platform using PS_NO_LOGF may provide
+ footprint benefits but will limit logging capabilities.
+ */
+
+/* Uncomment to use previous generation logging facility: */
+/* #define PS_NO_LOGF */
+
+/* When using psLogf, logging messages by default go to the binary, but
+ they are not shown unless enabled by environment variables or
+ filter loaded with psLogfSetHookEnabledCheck() function.
+
+ Enable macros below to completely remove specified logging class. */
+/* #define PS_NO_LOGF_FATAL */
+/* #define PS_NO_LOGF_ERROR */
+/* #define PS_NO_LOGF_WARNING */
+/* #define PS_NO_LOGF_INFO */
+/* #define PS_NO_LOGF_VERBOSE */
+/* #define PS_NO_LOGF_DEBUG */
+/* #define PS_NO_LOGF_TRACE */
+/* #define PS_NO_LOGF_CALL_TRACE */
+
+/* MatrixSSL contains extensive tracing capabilities. The lines below
+ disable trace and call trace message levels, unless debug build.
+ Omitting the messages will improve performance and create smaller
+ executables with a degradation in debugging capabilities. */
+# ifndef DEBUG
+# ifndef PS_NO_LOGF_TRACE
+# define PS_NO_LOGF_TRACE
+# endif
+# ifndef PS_NO_LOGF_CALL_TRACE
+# define PS_NO_LOGF_CALL_TRACE
+# endif
+# endif
+
+/* File and line information consumes some storage and may reveal details on
+ structure of software. This information is omitted from production builds,
+ but included within "debug build". If you want to include file and line
+ information also on production builds, disable the lines below. */
+# ifndef DEBUG
+# ifndef PS_NO_LOGF_FILELINE
+# define PS_NO_LOGF_FILELINE
+# endif
+# endif
+
+/**
+ Enable various levels of trace.
+ When these option is turned off, messages are silently
+ discarded and their text does not take space in the binary image.
+ Note: These are legacy configuration, and it is recommended to use
+ PS_NO_LOGF_* above, unless PS_NO_LOGF is set.
+ */
+/* #define USE_CORE_TRACE */
+# ifndef NO_CORE_ERROR
+# define USE_CORE_ERROR
+# endif
+# ifndef NO_CORE_ASSERT
+# define USE_CORE_ASSERT
+# endif
+
+/******************************************************************************/
+/* Other Configurable features */
+/******************************************************************************/
+
+/**
+ If enabled, calls to the psError set of APIs will perform a platform
+ abort on the exeutable to aid in debugging.
+ */
+# ifdef DEBUG
+/* #define HALT_ON_PS_ERROR *//* NOT RECOMMENDED FOR PRODUCTION BUILDS */
+# endif
+
+/**
+ Include the psCoreOsdepMutex family of APIs
+
+ @note If intending to compile crypto-cl, then this flag should
+ always be set.
+*/
+# ifndef NO_MULTITHREADING
+# define USE_MULTITHREADING
+# endif /* NO_MULTITHREADING */
+
+/**
+ Include the psNetwork family of APIs.
+
+ These APIs allow simple high-level socket api.
+ The API derive from BSD Sockets, and therefore it can only be used
+ on devices which have the prerequisitive APIs.
+ MatrixSSL itself can be used also be used without PS networking, but
+ many of example programs and MatrixSSLNet are based on PS networking.
+ */
+# ifndef NO_PS_NETWORKING
+# define USE_PS_NETWORKING
+# endif /* NO_PS_NETWORKING */
+
+#endif /* _h_PS_CORECONFIG */
+
+/******************************************************************************/
+
diff --git a/core/config/sl_chacha20poly1305ietf_config.h b/core/config/sl_chacha20poly1305ietf_config.h
new file mode 100644
index 0000000..168b2ab
--- /dev/null
+++ b/core/config/sl_chacha20poly1305ietf_config.h
@@ -0,0 +1,124 @@
+/**
+ * @file ps_chacha20poly1305ietf_config.h
+ * @version $Format:%h%d$
+ *
+ * Header for SafeZone Chacha20-poly1305: Configuration.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2017 INSIDE Secure Oy. All Rights Reserved.
+*
+* The latest version of this code is available at http://www.matrixssl.org
+*
+* This software is open source; 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.
+*
+* This General Public License does NOT permit incorporating this software
+* into proprietary programs. If you are unable to comply with the GPL, a
+* commercial license for this software may be purchased from INSIDE at
+* http://www.insidesecure.com/
+*
+* This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+* http://www.gnu.org/copyleft/gpl.html
+*****************************************************************************/
+
+
+/******************************************************************************/
+
+#ifndef _h_SL_CHACHA20_POLY1305IETF_CONFIG
+# define _h_SL_CHACHA20_POLY1305IETF_CONFIG
+
+/* Define this if you wish to use generic utility functions even when
+ you are not using Chacha20. */
+#define USE_SL_SODIUM
+
+/* Provide list of APIs and facilities available on the target platform and
+ configure the components for optimal performance on the target. */
+
+/* When porting the module to foreign target, it is possible that some of
+ these need to be changed to best adapt for the platform. */
+
+# if defined USE_SL_CHACHA20_POLY1305_IETF || defined USE_SL_SODIUM
+# ifdef USE_MULTITHREADING
+# define HAVE_PTHREAD_PRIO_INHERIT 1
+# define HAVE_PTHREAD 1
+# define _POSIX_PTHREAD_SEMANTICS 1
+# endif /* USE_MULTITHREADING */
+
+# ifndef STDC_HEADERS
+# define STDC_HEADERS
+# endif
+
+# if defined __linux__ || defined __android__
+# define HAVE_SYS_TYPES_H 1
+# define HAVE_SYS_STAT_H 1
+# define HAVE_SYS_MMAN_H 1
+# define HAVE_DLFCN_H 1
+# endif
+
+# define HAVE_STDLIB_H 1
+# define HAVE_STRING_H 1
+# define HAVE_MEMORY_H 1
+# define HAVE_STRINGS_H 1
+# define HAVE_INTTYPES_H 1
+# define HAVE_STDINT_H 1
+# define HAVE_UNISTD_H 1
+
+/* X86/X86-64 SIMD instructions: MMX, SSE, and AVX. */
+# if defined __i386__ || defined __x86_64__
+# define HAVE_MMINTRIN_H 1
+# define HAVE_EMMINTRIN_H 1
+# define HAVE_PMMINTRIN_H 1
+# define HAVE_TMMINTRIN_H 1
+# define HAVE_SMMINTRIN_H 1
+# define HAVE_AVXINTRIN_H 1
+# ifdef USE_X86_AVX2 /* By default omit AVX2 which requires a new compiler. */
+# define HAVE_AVX2INTRIN_H 1
+# endif
+# define HAVE_WMMINTRIN_H 1
+# define HAVE_AVX_ASM 1
+# endif
+
+# define NATIVE_LITTLE_ENDIAN 1
+# ifdef __x86_64__
+# define HAVE_AMD64_ASM 1
+# define HAVE_TI_MODE 1
+# endif
+# if defined __i386__ || defined __x86_64__
+# define HAVE_CPUID 1
+# endif
+# define HAVE_WEAK_SYMBOLS 1
+# define HAVE_ATOMIC_OPS 1
+# define HAVE_MMAP 1
+# define HAVE_MLOCK 1
+# define HAVE_MADVISE 1
+# define HAVE_NANOSLEEP 1
+# define HAVE_POSIX_MEMALIGN 1
+# define HAVE_GETPID 1
+
+# define ASM_HIDE_SYMBOL .hidden
+# define CPU_UNALIGNED_ACCESS 1
+
+# define NO_SODIUM_MEMORY_MANAGEMENT 1 /* Omit memory management functions. */
+
+# ifdef __android__
+# define HAVE_ANDROID_GETCPUFEATURES
+# endif /* __android__ */
+
+# ifndef NO_SODIUM_MEMORY_MANAGEMENT
+# define HAVE_MPROTECT 1
+# else
+# undef HAVE_MPROTECT
+# endif
+
+# endif
+#endif /* _h_SL_CHACHA20_POLY1305IETF_CONFIG */
+
diff --git a/core/corelib.c b/core/corelib.c
deleted file mode 100644
index 24fb9ab..0000000
--- a/core/corelib.c
+++ /dev/null
@@ -1,1090 +0,0 @@
-/**
- * @file corelib.c
- * @version $Format:%h%d$
- *
- * Open and Close APIs and utilities for Matrix core library.
- */
-/*
- * Copyright (c) 2013-2017 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
- *
- * The latest version of this code is available at http://www.matrixssl.org
- *
- * This software is open source; 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.
- *
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
- *
- * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
- */
-/******************************************************************************/
-
-#include "coreApi.h"
-#include "osdep.h"
-#include "psUtil.h"
-
-#ifdef USE_MULTITHREADING
-/* A mutex for concurrency control of functions implemented in this file.
- Obvious exception are psCoreOpen() and psCoreClose(). */
-static psMutex_t corelibMutex;
-#endif /* USE_MULTITHREADING */
-
-/******************************************************************************/
-/*
- Open (initialize) the Core module
- The config param should always be passed as:
- PSCORE_CONFIG
- */
-static char g_config[32] = "N";
-
-/******************************************************************************/
-int32 psCoreOpen(const char *config)
-{
- if (*g_config == 'Y')
- {
- return PS_CORE_IS_OPEN;
- }
- strncpy(g_config, PSCORE_CONFIG, sizeof(g_config) - 1);
- if (strncmp(g_config, config, strlen(PSCORE_CONFIG)) != 0)
- {
- psErrorStr( "Core config mismatch.\n" \
- "Library: " PSCORE_CONFIG \
- "\nCurrent: %s\n", config);
- return -1;
- }
-
- if (osdepTimeOpen() < 0)
- {
- psTraceCore("osdepTimeOpen failed\n");
- return PS_FAILURE;
- }
- if (osdepEntropyOpen() < 0)
- {
- psTraceCore("osdepEntropyOpen failed\n");
- osdepTimeClose();
- return PS_FAILURE;
- }
-
-#ifdef USE_MULTITHREADING
- if (osdepMutexOpen() < 0)
- {
- psTraceCore("osdepMutexOpen failed\n");
- osdepEntropyClose();
- osdepTimeClose();
- return PS_FAILURE;
- }
- if (psCreateMutex(&corelibMutex, 0) < 0)
- {
- psTraceCore("psCreateMutex failed\n");
- osdepMutexClose();
- osdepEntropyClose();
- osdepTimeClose();
- return PS_FAILURE;
- }
-#endif /* USE_MULTITHREADING */
-
- return PS_SUCCESS;
-}
-
-/******************************************************************************/
-void psCoreClose(void)
-{
- if (*g_config == 'Y')
- {
- *g_config = 'N';
-
-#ifdef USE_MULTITHREADING
- psDestroyMutex(&corelibMutex);
- osdepMutexClose();
-#endif /* USE_MULTITHREADING */
-
- osdepEntropyClose();
-
- osdepTimeClose();
- }
-}
-
-/******************************************************************************/
-/**
- Constant time memory comparison - like memcmp but w/o data dependent branch.
- @security SECURITY - Should be used when comparing values that use or have
- been derived or have been decrypted/encrypted/signed from secret information.
-
- @param[in] s1 Pointer to first buffer to compare
- @param[in] s2 Pointer to first buffer to compare
- @param[in] len number of bytes to compare in s1 and s2
- @return 0 on successful match, nonzero on failure.
- */
-int32 memcmpct(const void *s1, const void *s2, size_t len)
-{
- int xor = 0;
-
- while (len > 0)
- {
- len--;
- xor |= ((unsigned char *) s1)[len] ^ ((unsigned char *) s2)[len];
- }
- return xor;
-}
-
-/******************************************************************************/
-/*
- ERROR FUNCTIONS
- Tap into platform trace and break execution if DEBUG compile
-
- Modules should tie themselves to these low levels
- with compile-time defines
- */
-void _psError(const char *msg)
-{
- _psTrace(msg);
- _psTrace("\n");
-#ifdef HALT_ON_PS_ERROR
- osdepBreak();
-#endif
-}
-void _psErrorInt(const char *msg, int32 val)
-{
- _psTraceInt(msg, val);
- _psTrace("\n");
-#ifdef HALT_ON_PS_ERROR
- osdepBreak();
-#endif
-}
-void _psErrorStr(const char *msg, const char *val)
-{
- _psTraceStr(msg, val);
- _psTrace("\n");
-#ifdef HALT_ON_PS_ERROR
- osdepBreak();
-#endif
-}
-
-/*
- copy 'len' bytes from 'b' to 's', converting all to printable characters
- */
-void psMem2Str(char *s, const unsigned char *b, uint32 len)
-{
- for (; len > 0; len--)
- {
- if (*b > 31 && *b < 127)
- {
- *s = *b;
- }
- else
- {
- *s = '.';
- }
- b++;
- s++;
- }
-}
-
-void psTraceBytes(const char *tag, const unsigned char *p, int l)
-{
- char s[17];
- int i;
-
- s[16] = '\0';
- if (tag)
- {
- _psTraceStr("psTraceBytes(%s, ", tag);
- _psTraceInt("%d);", l);
- }
- else
- {
- _psTrace("\"");
- }
- for (i = 0; i < l; i++)
- {
- if (!(i & 0xF))
- {
- if (tag)
- {
- if (i != 0)
- {
- psMem2Str(s, p - 16, 16);
- _psTraceStr(" %s", s);
- }
-#ifdef _LP64
- _psTraceInt("\n0x%08x:", (int64) p);
-#else
- _psTraceInt("\n0x%04x:", (int32) p);
-#endif
- }
- else
- {
- _psTrace("\"\n\"");
- }
- }
- if (tag)
- {
- _psTraceInt("%02x ", *p++);
- }
- else
- {
- _psTraceInt("\\x%02x", *p++);
- }
- }
- if (tag)
- {
- memset(s, 0x0, 16);
- i = l & 0xF;
- psMem2Str(s, p - i, (unsigned int) i);
- for (; i < 16; i++)
- {
- _psTrace(" ");
- }
- _psTraceStr(" %s", s);
- _psTrace("\n");
- }
- else
- {
- _psTrace("\"\n");
- }
-}
-
-/******************************************************************************/
-/*
- Creates a simple linked list from a given stream and separator char
-
- Memory info:
- Callers do not have to free 'items' on function failure.
- */
-int32 psParseList(psPool_t *pool, char *list, const char separator,
- psList_t **items)
-{
- psList_t *litems, *start, *prev;
- uint32 itemLen, listLen;
- char *tmp;
-
- *items = NULL;
- prev = NULL;
-
- listLen = (int32) strlen(list) + 1;
- if (listLen == 1)
- {
- return PS_ARG_FAIL;
- }
- start = litems = psMalloc(pool, sizeof(psList_t));
- if (litems == NULL)
- {
- return PS_MEM_FAIL;
- }
- memset(litems, 0, sizeof(psList_t));
-
- while (listLen > 0)
- {
- itemLen = 0;
- tmp = list;
- if (litems == NULL)
- {
- litems = psMalloc(pool, sizeof(psList_t));
- if (litems == NULL)
- {
- psFreeList(start, pool);
- return PS_MEM_FAIL;
- }
- memset(litems, 0, sizeof(psList_t));
- prev->next = litems;
-
- }
- while (*list != separator && *list != '\0')
- {
- itemLen++;
- listLen--;
- list++;
- }
- litems->item = psMalloc(pool, itemLen + 1);
- if (litems->item == NULL)
- {
- psFreeList(start, pool);
- return PS_MEM_FAIL;
- }
- litems->len = itemLen;
- memset(litems->item, 0x0, itemLen + 1);
- memcpy(litems->item, tmp, itemLen);
- list++;
- listLen--;
- prev = litems;
- litems = litems->next;
- }
- *items = start;
- return PS_SUCCESS;
-}
-
-void psFreeList(psList_t *list, psPool_t *pool)
-{
- psList_t *next, *current;
-
- if (list == NULL)
- {
- return;
- }
- current = list;
- while (current)
- {
- next = current->next;
- if (current->item)
- {
- psFree(current->item, pool);
- }
- psFree(current, pool);
- current = next;
- }
-}
-
-/******************************************************************************/
-/*
- Clear the stack deeper than the caller to erase any potential secrets
- or keys.
- */
-void psBurnStack(uint32 len)
-{
- unsigned char buf[32];
-
- memset_s(buf, sizeof(buf), 0x0, sizeof(buf));
- if (len > (uint32) sizeof(buf))
- {
- psBurnStack(len - sizeof(buf));
- }
-}
-
-/******************************************************************************/
-/*
- Free pointed memory and clear the pointer to avoid accidental
- double free.
- */
-void psFreeAndClear(void *ptrptr, psPool_t *pool)
-{
- void *ptr;
-
- if (ptrptr != NULL)
- {
- ptr = *(void **) ptrptr;
- psFree(ptr, pool);
- *(void **) ptrptr = NULL;
- PS_PARAMETER_UNUSED(pool); /* Parameter can be unused. */
- }
-}
-
-#if defined __unix__ || defined __unix || (defined (__APPLE__) && defined (__MACH__))
-# include /* Possibly provides _POSIX_VERSION. */
-/* 32-bit Unix machines may need workaround for Year 2038.
- 64-bit Unix machines generally use large enough time_t. */
-# if !defined __LP64__ && !defined __ILP64__
-# define USE_UNIX_Y2038_WORKAROUND 1
-# endif
-#endif /* __unix__ */
-
-#ifdef _POSIX_VERSION
-# define USE_GMTIME_R /* On posix systems, we use gmtime_r() */
-#endif /* _POSIX_VERSION */
-
-/******************************************************************************/
-/*
- Get broken-down time, similar to time returned by gmtime(), but avoiding
- the race condition. The function only applies offset if it does not cause
- overflow.
- */
-PSPUBLIC int32 psBrokenDownTimeImportSeconds(psBrokenDownTime_t *t,
- psTimeSeconds_t s)
-{
- int32 ret = PS_FAILURE;
- struct tm *tm;
- time_t time = s;
-
-#ifdef USE_GMTIME_R
- /* Note: This command assumes psBrokenDownTime_t and struct tm use
- exactly the same representation. If you optimize storage space of
- psBrokenDownTime_t, then transfer each field separately. */
- tm = gmtime_r(&time, t);
- if (tm != NULL)
- {
- ret = PS_SUCCESS;
- }
-#else
- /* Use mutex to lock. */
- psLockMutex(&corelibMutex);
- tm = gmtime(&time);
- if (tm)
- {
- /* Note: This command assumes psBrokenDownTime_t and struct tm use
- exactly the same representation. If you optimize storage space of
- psBrokenDownTime_t, then transfer each field separately. */
- memcpy(t, tm, sizeof(*t));
- ret = PS_SUCCESS;
- }
- psUnlockMutex(&corelibMutex);
-#endif
-
-#ifdef USE_UNIX_Y2038_WORKAROUND
- /* Workaround for time_t overflow in 2038 on 32-bit Linux/Unix: */
- if (time < 0 && t->tm_year < 70)
- {
- /* Overflow of dat has occurred. Fix the date, using
- psBrokenDownTimeAdd(). This may possibly result in an estimate
- because the computation here does not know of details like
- leap seconds assigned in future. The result should be precise to
- few seconds. */
- /* Note: Adjustment in three parts, because adjustment is too large
- to be processed at once.
- Note: 0x100000000 == 883612800 * 4 + 760516096. */
- (void) psBrokenDownTimeAdd(t, 883612800 * 2);
- (void) psBrokenDownTimeAdd(t, 883612800 * 2);
- (void) psBrokenDownTimeAdd(t, 760516096);
- }
-#endif /* USE_UNIX_Y2038_WORKAROUND */
- return ret;
-}
-
-/*
- Get broken-down time, similar to time returned by gmtime(), but avoiding
- the race condition. The function only applies offset if it does not cause
- overflow.
- */
-PSPUBLIC int32 psGetBrokenDownGMTime(psBrokenDownTime_t *t, int offset)
-{
- int32 ret;
- time_t current_time;
- psTimeSeconds_t offseted_time;
-
- current_time = time(NULL);
- if (current_time == ((time_t) -1))
- {
- return PS_FAILURE;
- }
-
- /* Handle negative offsets here. */
- offseted_time = ((psTimeSeconds_t) current_time) + offset;
- /* In case of overflow or positive offset, use time without offset. */
- if ((offset < 0 && offseted_time > current_time) || (offset > 0))
- {
- offseted_time = current_time;
- }
-
- ret = psBrokenDownTimeImportSeconds(t, offseted_time);
- /* Handle positive offsets here. */
- if (ret == PS_SUCCESS && offset > 0)
- {
- ret = psBrokenDownTimeAdd(t, offset);
- }
- return ret;
-}
-
-/* Compute number of days in month. */
-static int mdays(const psBrokenDownTime_t *t)
-{
- static unsigned char days_tab[] = {
- /* Jan */ 31, /* Most Feb */ 28,31, 30, 31, 30, 31, 31, 30, 31, 30, 31
- };
- unsigned char days;
-
- if (t->tm_mon > 11)
- {
- return -1;
- }
- days = days_tab[t->tm_mon];
- if (days == 28)
- {
- /* Note: This computation does not consider possible corrections once
- every 3200 years. */
- int year = t->tm_year + 1900;
- int is_leap_year = (year % 4) == 0 &&
- ((year % 100) != 0 || (year % 400) == 0);
- days += is_leap_year;
- }
- return days;
-}
-
-/******************************************************************************/
-/*
- Compute broken-down time, with specified offset. The initial broken
- down time t must have been previously initialized. This function only
- needs to support positive offset (including 0).
- */
-PSPUBLIC int32 psBrokenDownTimeAdd(psBrokenDownTime_t *res, int32 offset)
-{
- if (offset < 0)
- {
- return PS_FAILURE;
- }
-
- /* Quick path for multiples of 28 years. */
- while (offset > 883612800)
- {
- /* Quick addition of exactly 28 years (the cycle of Gregorian calendar,
- 7 * 4 * 365.25 * 24 * 60 * 60 seconds). */
- offset -= 883612800;
- res->tm_year += 28;
- }
-
- if (offset == 0)
- {
- return PS_SUCCESS;
- }
-
- /* Note: this function is approximate in presence of leap seconds. */
- res->tm_sec += offset;
- if (res->tm_sec >= 60)
- {
- res->tm_min += res->tm_sec / 60;
- res->tm_sec %= 60;
- }
- if (res->tm_min >= 60)
- {
- res->tm_hour += res->tm_min / 60;
- res->tm_min %= 60;
- }
- if (res->tm_hour >= 24)
- {
- res->tm_mday += res->tm_hour / 24;
- res->tm_wday += res->tm_hour / 24;
- res->tm_wday %= 7;
- res->tm_hour %= 24;
- }
- /* Do month days, months & years as a loop. */
- while (res->tm_mday > mdays(res))
- {
- res->tm_mday -= mdays(res);
- res->tm_mon += 1;
- if (res->tm_mon > 11)
- {
- res->tm_mon -= 12;
- res->tm_year++;
- }
- /* Note: tm_yday is not updated. */
- res->tm_hour %= 60;
- }
- return PS_SUCCESS;
-}
-
-/******************************************************************************/
-/*
- Format BrokenDown Time String with 4 digit year.
- The string format will be "YYYYMMDDHHMMSSZ". Z and NIL are included.
- */
-PSPUBLIC int32 psBrokenDownTimeStr(const psBrokenDownTime_t *t,
- char (*string)[PS_BROKENDOWN_TIME_STR_LEN])
-{
- size_t len = strftime(*string, PS_BROKENDOWN_TIME_STR_LEN,
- "%Y%m%d%H%M%SZ", t);
-
- return len == PS_BROKENDOWN_TIME_STR_LEN - 1 ? PS_SUCCESS : PS_FAILURE;
-}
-
-/* Helper function to read specified amount of digits.
- The number read shall be within boundaries. On parse errors function returns
- (unsigned) -1, otherwise the parsed number. */
-static unsigned parse_digits(
- const unsigned char **c_p,
- unsigned digits, unsigned minimum, unsigned maximum)
-{
- const unsigned char *c = *c_p;
- unsigned result = 0;
-
- while (digits)
- {
- if (*c < '0' || *c > '9')
- {
- return (unsigned) -1;
- }
- result *= 10;
- result += *c - '0';
- c++;
- digits--;
- }
-
- *c_p = c;
-
- if (result < minimum || result > maximum)
- {
- return (unsigned) -1;
- }
-
- return result;
-}
-
-/******************************************************************************/
-/**
- Verify a string has nearly valid date range format and length,
- and return it in broken-down time format.
- */
-static unsigned char parsedate_zulu(const unsigned char *p,
- unsigned int time_len,
- unsigned int year_len,
- psBrokenDownTime_t *target,
- int strict)
-{
- unsigned year, month, mday, hour, min, sec;
- const unsigned char *c = p;
- psBrokenDownTime_t check_only;
-
- if (!target)
- {
- /* Use check_only as target. */
- target = &check_only;
- }
-
- /* Zeroize all fields as some systems have extra fields
- in struct tm. */
- memset(target, 0, sizeof(*target));
-
- if (year_len == 4)
- {
- /* Format shall be YYYYMMDDHHMMSSZ (according to RFC 5280). */
- if (time_len != 15 && strict)
- {
- return 0;
- }
- /* Flexible: allow Z to be replaced with anything. */
- if (time_len < 14 && !strict)
- {
- return 0;
- }
- year = parse_digits(&c, 4, 1900, 2999);
- }
- else if (year_len == 2)
- {
- /* Format shall be YYMMDDHHMMSSZ (according to RFC 5280). */
- if (time_len != 13 && strict)
- {
- return 0;
- }
- if (time_len < 12 && !strict)
- {
- return 0;
- }
- year = parse_digits(&c, 2, 0, 99);
- }
- else
- {
- return 0;
- }
-
- if (year == (unsigned) -1)
- {
- return 0;
- }
-
- month = parse_digits(&c, 2, 1, 12);
- if (month == (unsigned) -1)
- {
- return 0;
- }
-
- mday = parse_digits(&c, 2, 1, 31);
- if (mday == (unsigned) -1)
- {
- return 0;
- }
-
- hour = parse_digits(&c, 2, 0, 23);
- if (hour == (unsigned) -1)
- {
- return 0;
- }
-
- min = parse_digits(&c, 2, 0, 59);
- if (min == (unsigned) -1)
- {
- return 0;
- }
-
- /* This allows up-to 1 leap second.
- (Note: could check that leap second only occurs at 23:59:60 on
- end of Jun 30 or Dec 31 (such as on 31 Dec 2016 23:59:60), but
- rules for insertion of leap seconds may change. */
- sec = parse_digits(&c, 2, 0, 60);
- if (sec == (unsigned) -1)
- {
- return 0;
- }
-
- /* Require all times in X.509 materials to be Zulu time, as is correct
- according to RFC 5280. */
- if (strict && *c != 'Z')
- {
- return 0;
- }
- else
- {
- /* Ignore time zone. The time zone shall be Zulu according to RFC 5280,
- for X.509 certificates, CRL, OCSP etc. These times will be matched
- exactly. However, some old systems may use certificates with some
- other time zone. When handling those, the times will not be handled
- exactly, but the inaccuracy will be within a day. */
- }
-
- /* Convert 2 or 4 digit year to tm format (year after 1900).
- Two digit years are interpreted according to RFC 5280. */
- if (year < 50)
- {
- year += 100;
- }
- else if (year >= 1900)
- {
- year -= 1900;
- }
- else if (year >= 100)
- {
- /* years 100-1900 cannot be represented in psBrokenDownTime_t. */
- return 0;
- }
- else
- {
- /* Two digit year 50-99 is already correct. */
- }
-
- target->tm_year = (int) year;
- target->tm_mon = (int) month - 1;
- target->tm_mday = (int) mday;
- target->tm_hour = (int) hour;
- target->tm_min = (int) min;
- target->tm_sec = (int) sec;
- /* Note: target->tm_wday and target->tm_yday are not set. */
- if (target->tm_mday > mdays(target))
- {
- /* No such day in this month. */
- memset(target, 0, sizeof(*target));
- return 0;
- }
- return 1;
-}
-
-/******************************************************************************/
-/*
- Import BrokenDown Time from String format. Number of digits in year
- can be provided via an option. The string format recommended is
- "YYYYMMDDHHMMSSZ".
- This function only supports Zulu time, any other time zone will be ignored.
- */
-PSPUBLIC int32 psBrokenDownTimeImport(
- psBrokenDownTime_t *t,
- const char *string, size_t time_string_len,
- unsigned int opts)
-{
- unsigned char res;
-
- /* Reject very long strings as illegal. */
- if (time_string_len > 255)
- {
- return PS_FAILURE;
- }
-
- res = parsedate_zulu((const unsigned char *) string,
- (unsigned int) time_string_len,
- (opts & PS_BROKENDOWN_TIME_IMPORT_2DIGIT_YEAR) ?
- 2 : 4, t,
- (opts & PS_BROKENDOWN_TIME_IMPORT_STRICT_ZULU));
-
- return res ? PS_SUCCESS : PS_FAILURE;
-}
-
-/******************************************************************************/
-/*
- Compute broken-down times, returning <0, 0 or >0 according to t1 being
- smaller, equal or greater than t2.
- */
-PSPUBLIC int psBrokenDownTimeCmp(const psBrokenDownTime_t *t1,
- const psBrokenDownTime_t *t2)
-{
- char s1[PS_BROKENDOWN_TIME_STR_LEN] = { '!', 0 };
- char s2[PS_BROKENDOWN_TIME_STR_LEN] = { 0 };
-
- /* The dates are represented using YYYYMMDDHHMMSSZ for comparison.
- I.e. comparison ignores tm_wday, tm_yday, and tm_isdst. */
- (void) psBrokenDownTimeStr(t1, &s1);
- (void) psBrokenDownTimeStr(t2, &s2);
- /* If you wish to debug time comparisons, you can enable next lines. */
- /* _psTraceStr("Comparing t1: %s against ", s1); */
- /* _psTraceStr("t2: %s ", s2); */
- /* _psTraceInt("got: %d\n", memcmp(s1, s2, sizeof(s1))); */
- return memcmp(s1, s2, sizeof(s1));
-}
-
-/******************************************************************************/
-/*
- Helper function for String conversion.
- */
-static int32 psToUtfXString(psPool_t *pool,
- const unsigned char *input, size_t input_len,
- psStringType_t input_type,
- unsigned char **output, size_t *output_len,
- int oclen, int opts)
-{
- int32 err;
- psParseBuf_t in;
- psDynBuf_t out;
- size_t ignored_size;
- int clen = 1;
- unsigned char bytes0[4] = { 0, 0, 0, 0 };
- const unsigned short *map = NULL;
- const unsigned short map_t61[256] =
- {
- /* T.61 maps most of the ASCII as-is. */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 0, 0, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 0, 93, 0, 95,
- 0, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
- 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 0, 124,
- 0, 0, 127,
- /* Control characters. */
- 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141,
- 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155,
- 156, 157, 158, 159,
- /* Extended characters */
- 160, 161, 162, 163, 36, 165, 166, 167, 168, 0, 0, 171, 0, 0, 0, 0,
- 176, 177, 178, 179, 180, 181, 182, 183, 184, 0, 0, 187, 188, 189, 190,
- 191,
- 0, 0x300, 0x301, 0x302, 0x303, 0x304, 0x306, 0x307, 0x308,
- 0, 0x30A, 0x327, 0x332, 0x30B, 0x328, 0x30C,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0x2126, 0xC6, 0xD0, 0xAA, 0x126, 0, 0x132, 0x13F, 0x141, 0xD8, 0x152,
- 0xBA, 0xDE, 0x166, 0x14A, 0x149, 0x138, 0xE6, 0x111, 0xF0, 0x127,
- 0x131, 0x133, 0x140, 0x142, 0xF8, 0x153, 0xDF, 0xFE, 0x167, 0x14B, 0
- };
- if ((opts & ~PS_STRING_DUAL_NIL) != 0)
- {
- return PS_UNSUPPORTED_FAIL;
- }
-
- switch (input_type)
- {
- case PS_STRING_NUMERIC_STRING:
- case PS_STRING_PRINTABLE_STRING:
- /* These are subsets of ASCII. */
- break;
- case PS_STRING_TELETEX_STRING:
- /* Superset of ASCII. */
- map = map_t61;
- break;
- case PS_STRING_UTF8_STRING:
- /* UTF-8 characters. */
- clen = 0;
- break;
- case PS_STRING_UTF16_STRING:
- case PS_STRING_BMP_STRING:
- /* UCS2 characters. */
- clen = 2;
- break;
- default:
- return PS_UNSUPPORTED_FAIL;
- }
-
- /* Sequence of 16-bit characters has to have even length. */
- if (clen == 2 && (input_len & 1) > 0)
- {
- return PS_FAILURE;
- }
-
- err = psParseBufFromStaticData(&in, input, input_len);
- if (err != PS_SUCCESS)
- {
- return err;
- }
-
- /* Create dynamic buffer with initial size estimate being the same
- than input + termination character(s). */
- err = psDynBufInit(pool, &out,
- ((input_len + 2) * oclen)) ? PS_SUCCESS : PS_MEM_FAIL;
- if (err != PS_SUCCESS)
- {
- return err;
- }
-
- if (clen == 0)
- {
- /* UTF-8: */
- while(psParseBufCanReadUtf8(&in))
- {
- unsigned int chr = psParseBufReadUtf8(&in);
- if (oclen == 1)
- {
- (void) psDynBufAppendUtf8(&out, chr);
- }
- else if (oclen == 2)
- {
- (void) psDynBufAppendUtf16(&out, chr);
- }
- else /* oclen == 4 */
- {
- (void) psDynBufAppendUtf32(&out, chr);
- }
- }
- }
- else if (clen == 1)
- {
- while (psParseCanRead(&in, 1))
- {
- unsigned short chr = (unsigned short) *in.buf.start;
-
- if (map)
- {
- chr = map[chr];
- }
- if ((chr >= 1 && chr <= 127) || (map && chr >= 1))
- {
- if (oclen == 1)
- {
- (void) psDynBufAppendUtf8(&out, chr);
- }
- else
- {
- if (oclen == 4)
- {
- (void) psDynBufAppendUtf16(&out, 0);
- }
- (void) psDynBufAppendUtf16(&out, chr);
- }
- }
- else
- {
- /* non-ASCII character (eight bit set) or \0. */
- err = PS_LIMIT_FAIL;
- }
- psParseBufSkipBytes(&in, (unsigned char *) &chr, 1);
- }
- }
- else /* clen == 2 */
- {
- while (psParseCanRead(&in, 2))
- {
- unsigned char a[2];
- uint16_t chr;
- memcpy(a, in.buf.start, 2);
- chr = a[0];
- chr <<= 8;
- chr |= a[1];
- if (chr != 0 && (chr < 0xd800 || chr > 0xdfff))
- {
- /* ASCII or other page 0 characters. */
- if (oclen == 1)
- {
- (void) psDynBufAppendUtf8(&out, chr);
- }
- else if (oclen == 2)
- {
- (void) psDynBufAppendUtf16(&out, chr);
- }
- else /* oclen == 4 */
- {
- (void) psDynBufAppendUtf32(&out, chr);
- }
- }
- else if ((chr >= 0xd800 && chr <= 0xdbff) &&
- input_type == PS_STRING_UTF16_STRING &&
- psParseCanRead(&in, 4))
- {
- /* surrogates. */
- unsigned char b[2];
- unsigned int c;
- memcpy(b, in.buf.start + 2, 2);
-
- c = (chr & 0x3FF) << 10;
- c |= ((b[0] & 0x3) << 8) | b[1];
- if (b[0] < 0xDC || b[0] > 0xDF)
- {
- /* Invalid code point third byte needs to be 0xDC..0xDF. */
- err = PS_LIMIT_FAIL;
- }
- if (oclen == 1)
- {
- (void) psDynBufAppendUtf8(&out, c + 0x010000);
- }
- else if (oclen == 2)
- {
- (void) psDynBufAppendUtf16(&out, c + 0x010000);
- }
- else /* oclen == 4 */
- {
- (void) psDynBufAppendUtf32(&out, c + 0x010000);
- }
- psParseBufSkipBytes(&in, a, 2);
- memcpy(a, b, 2);
- }
- else
- {
- /* surrogate pair or \0. These are invalid code points BMP. */
- err = PS_LIMIT_FAIL;
- }
- psParseBufSkipBytes(&in, a, 2);
- }
- }
-
- if (output_len == NULL)
- {
- output_len = &ignored_size;
- }
-
- /* Append terminating \0 or \0\0. x oclen */
- psDynBufAppendOctets(&out, bytes0, oclen);
- if ((opts & PS_STRING_DUAL_NIL) != 0)
- {
- psDynBufAppendOctets(&out, bytes0, oclen);
- }
-
- if (err == PS_SUCCESS)
- {
- *output = psDynBufDetach(&out, output_len);
- *output_len -= (opts & PS_STRING_DUAL_NIL) ? 2 * oclen : oclen;
- if (*output == NULL)
- {
- return PS_MEM_FAIL;
- }
- }
- else
- {
- psDynBufUninit(&out);
- }
- return err;
-}
-
-PSPUBLIC int32 psToUtf8String(psPool_t *pool,
- const unsigned char *input, size_t input_len,
- psStringType_t input_type,
- unsigned char **output, size_t *output_len,
- int opts)
-{
- return psToUtfXString(pool, input, input_len, input_type,
- output, output_len, 1, opts);
-}
-
-PSPUBLIC int32 psToUtf16String(psPool_t *pool,
- const unsigned char *input, size_t input_len,
- psStringType_t input_type,
- unsigned char **output, size_t *output_len,
- int opts)
-{
- return psToUtfXString(pool, input, input_len, input_type,
- output, output_len, 2, opts);
-}
-
-PSPUBLIC int32 psToUtf32String(psPool_t *pool,
- const unsigned char *input, size_t input_len,
- psStringType_t input_type,
- unsigned char **output, size_t *output_len,
- int opts)
-{
- return psToUtfXString(pool, input, input_len, input_type,
- output, output_len, 4, opts);
-}
-
-/******************************************************************************/
-
diff --git a/core/include/c_lib.h b/core/include/c_lib.h
new file mode 100644
index 0000000..438acb2
--- /dev/null
+++ b/core/include/c_lib.h
@@ -0,0 +1,135 @@
+/* c_lib.h
+ *
+ * Description: Wrappers for C Library functions.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2007-2016 INSIDE Secure Oy. All Rights Reserved.
+*
+* The latest version of this code is available at http://www.matrixssl.org
+*
+* This software is open source; 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.
+*
+* This General Public License does NOT permit incorporating this software
+* into proprietary programs. If you are unable to comply with the GPL, a
+* commercial license for this software may be purchased from INSIDE at
+* http://www.insidesecure.com/
+*
+* This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\
+* http://www.gnu.org/copyleft/gpl.html
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_C_LIB_H
+#define INCLUDE_GUARD_C_LIB_H
+
+#include "public_defs.h"
+
+#if __STDC_VERSION__ >= 199901L
+# define RESTRICT restrict
+#else
+# define RESTRICT
+#endif /* __STDC_VERSION__ >= 199901L */
+
+void *
+c_memcpy(
+ void *RESTRICT s1,
+ const void *RESTRICT s2,
+ size_t n);
+
+void *
+c_memmove(
+ void *s1,
+ const void *s2,
+ size_t n);
+
+
+void *
+c_memset(
+ void *s,
+ int c,
+ size_t n);
+
+
+int
+c_memcmp(
+ const void *s1,
+ const void *s2,
+ size_t n);
+
+
+int
+c_strcmp(
+ const char *s1,
+ const char *s2);
+
+
+char *
+c_strcpy(
+ char *RESTRICT s1,
+ const char *RESTRICT s2);
+
+char *
+c_strcat(
+ char *dest,
+ const char *src);
+
+char *
+c_strncpy(
+ char *dest,
+ const char *src,
+ size_t n);
+
+int
+c_strncmp(
+ const char *s1,
+ const char *s2,
+ size_t n);
+
+size_t
+c_strlen(
+ const char *s);
+
+char *
+c_strstr(
+ const char *str1,
+ const char *str2);
+
+
+long
+c_strtol(
+ const char *str,
+ char **endptr,
+ int16_t radix);
+
+char *
+c_strchr(
+ const char *str,
+ int32_t c);
+
+int
+c_tolower(
+ int c);
+
+int
+c_toupper(
+ int c);
+
+
+int *
+c_memchr(
+ const void *buf,
+ int32_t ch,
+ size_t num);
+
+#endif /* Include guard */
+
+/* end of file c_lib.h */
diff --git a/core/include/cl_basic.h b/core/include/cl_basic.h
new file mode 100644
index 0000000..eeb1798
--- /dev/null
+++ b/core/include/cl_basic.h
@@ -0,0 +1,124 @@
+/* cl_basic.h
+ *
+ * Basic Utility operations aiding correctly implementing cryptography.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2016-2017 INSIDE Secure Oy. All Rights Reserved.
+*
+* The latest version of this code is available at http://www.matrixssl.org
+*
+* This software is open source; 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.
+*
+* This General Public License does NOT permit incorporating this software
+* into proprietary programs. If you are unable to comply with the GPL, a
+* commercial license for this software may be purchased from INSIDE at
+* http://www.insidesecure.com/
+*
+* This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\
+* http://www.gnu.org/copyleft/gpl.html
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_CL_BASIC_H
+#define INCLUDE_GUARD_CL_BASIC_H
+
+#include "cl_types_base.h"
+#include "cl_header_begin.h"
+
+/** @defgroup CL11BASIC The CL Lib API Functions: Utility functions
+ * CL Lib 1.1 API: Utility Functions
+ *
+ * CL Lib 1.1 is commonly used in programs aiming to implement cryptography
+ * correctly. This file defines some useful utility functionality to be
+ * used with cryptographic functionality. These functions do not have
+ * CLS API counterparts as the functions never need locking.
+ * @{
+ */
+
+/** Fill memory with given value.
+ * This function fills given memory area with given byte.
+ * The memory fill operation happens even if the C compiler can detect the
+ * area is no longer needed. This is beneficial for Cryptography, where it
+ * is important to carefully erase all memory areas containing sensitive
+ * materials to ensure they do not accidentally leak.
+ *
+ * @param s Target area
+ * @param smax Size of whole target area
+ * @param c Byte to use (usually 0; only 8 bits of the value is used.)
+ * @param n The number of bytes to erase.
+ */
+void CL_MemSet(void *s, CL_DataLen_t smax, int c, CL_DataLen_t n);
+
+/** Check if two memory areas have identical contents.
+ *
+ * If array sizes differ, the function returns 0.
+ * This function compares contents of two memory areas for equality in
+ * data independent time.
+ *
+ * @param p1 Source area 1
+ * @param sz1 Size of source area 1
+ * @param p2 Source area 2
+ * @param sz2 Size of source area 2
+ * @retval 1 only if the areas are same size and have same contents.
+ */
+int CL_MemEqual(const void *p1, size_t sz1, const void *p2, size_t sz2);
+
+/** Compare two arrays and identify if one of arrays is smaller, or same
+ * than the other array.
+ *
+ * If array sizes differ, the function always returns <0 or >0.
+ * This function compares contents of two memory areas in
+ * data independent time. The comparison is based on value of bytes, resulting
+ * e.g. ASCII code based sorting of the values.
+ *
+ * @param p1 Source area 1
+ * @param sz1 Size of source area 1
+ * @param p2 Source area 2
+ * @param sz2 Size of source area 2
+ * @retval <0 If source area is smaller.
+ * @retval 0 If the areas are equal.
+ * @retval >0 If source area is greater.
+ */
+int CL_MemCmp(const void *p1, size_t sz1, const void *p2, size_t sz2);
+
+/** Compare two arrays and identify if one of arrays is smaller, or same
+ * than the other array, with masking for the last byte.
+ *
+ * If array sizes differ, the function always returns <0 or >0.
+ * This function compares contents of two memory areas in
+ * data independent time. The comparison is based on value of bytes, resulting
+ * e.g. ASCII code based sorting of the values.
+ *
+ * This function can be seen as a special version of CL_MemCmp(), which
+ * partially ignore the last byte(s).
+ *
+ * @param p1 Source area 1
+ * @param sz1 Size of source area 1
+ * @param p2 Source area 2
+ * @param sz2 Size of source area 2
+ * @param mask1 Mask for the last byte of source area 1
+ * @param mask2 Mask for the last byte of source area 2
+ * @retval <0 If source area is smaller.
+ * @retval 0 If the areas are equal.
+ * @retval >0 If source area is greater.
+ */
+int CL_MemCmpEndMask(const void *p1, size_t sz1, const void *p2, size_t sz2,
+ const unsigned char mask1,
+ const unsigned char mask2);
+
+/** @} */
+
+#include "cl_header_end.h"
+
+#endif /* INCLUDE_GUARD_CL_BASIC_H */
+
+/* end of file cl_basic.h */
diff --git a/core/include/cl_header_begin.h b/core/include/cl_header_begin.h
new file mode 100644
index 0000000..5f49684
--- /dev/null
+++ b/core/include/cl_header_begin.h
@@ -0,0 +1,24 @@
+/** @file cl_header_start.h
+
+ @copyright Copyright (c) 2017 INSIDE Secure Oy. All Rights Reserved.
+
+ Start header file.
+ */
+
+/* CL header files are intended for C.
+ This header produces sufficient prologue to introduce
+ header file in C mode. */
+
+/* Note: Add CL_NO_EXTERN_C to predefined symbols if you have manually
+ created extern "C" block. */
+
+/* Unusual multi-inclusion guard as multi-inclusion is allowed. */
+#ifndef CL_HEADER_BEGIN_H
+#define CL_HEADER_BEGIN_H 1
+#if defined __cplusplus && !defined CL_NO_EXTERN_C
+extern "C" {
+#endif
+
+#undef CL_HEADER_BEGIN_H /* Allow multiple inclusion and nesting. */
+#endif /* CL_HEADER_BEGIN_H */
+
diff --git a/core/include/cl_header_end.h b/core/include/cl_header_end.h
new file mode 100644
index 0000000..b5d4aa4
--- /dev/null
+++ b/core/include/cl_header_end.h
@@ -0,0 +1,23 @@
+/** @file cl_header_start.h
+
+ @copyright Copyright (c) 2017 INSIDE Secure Oy. All Rights Reserved.
+
+ End header file.
+ */
+
+/* CL header files are intended for C.
+ This header produces sufficient epilogue to switch back to usual mode
+ of the compiler. */
+
+/* Note: Add CL_NO_EXTERN_C to predefined symbols if you have manually
+ created extern "C" block. */
+
+/* Unusual multi-inclusion guard as multi-inclusion is allowed. */
+#ifndef CL_HEADER_END_H
+#define CL_HEADER_END_H 1
+
+#if defined __cplusplus && !defined CL_NO_EXTERN_C
+}
+#endif
+#undef CL_HEADER_END_H /* Forget this include was already defined. */
+#endif /* CL_HEADER_END_H */
diff --git a/core/include/cl_types_base.h b/core/include/cl_types_base.h
new file mode 100644
index 0000000..b2734d0
--- /dev/null
+++ b/core/include/cl_types_base.h
@@ -0,0 +1,290 @@
+/* cl_types_base.h
+ *
+ * Data types used by SafeZone CL Lib.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2017 INSIDE Secure Oy. All Rights Reserved.
+*
+* The latest version of this code is available at http://www.matrixssl.org
+*
+* This software is open source; 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.
+*
+* This General Public License does NOT permit incorporating this software
+* into proprietary programs. If you are unable to comply with the GPL, a
+* commercial license for this software may be purchased from INSIDE at
+* http://www.insidesecure.com/
+*
+* This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\
+* http://www.gnu.org/copyleft/gpl.html
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_CL_TYPES_BASE_H
+#define INCLUDE_GUARD_CL_TYPES_BASE_H
+
+/* Include C99 boolean. */
+#include "osdep_stdbool.h"
+
+#include "cl_header_begin.h"
+
+/* Note: the following headers must exist in compilation environments
+ compliant with ISO C99. In compilation environments prior ISO C99,
+ replacements of stdint.h may need to be provided. The replacement
+ only needs to define subset of full ISO C99 stdint.h.
+
+ Alternatively, you may define CL_NO_STDDEF_H and CL_NO_STDINT_H and
+ define, e.g. using compiler definitions or -Duint32_t=int or
+ preincludes the appropriate configuration for your platform.
+
+ Note: The remaining files of CL attempt to avoid any reference to
+ stddef.h or stdint.h. */
+#ifndef CL_NO_STDDEF_H
+# include "osdep_stddef.h"
+#else
+/* You shall provide replacements for stddef.h (definition of ). */
+#endif /* CL_NO_STDDEF_H */
+
+#ifndef CL_NO_STDINT_H
+# include "osdep_stdint.h"
+#else
+/* You shall provide replacements for stdint.h
+ (definitions of uint8_t, uint16_t, uint32_t, uintptr_t). */
+#endif /* CL_NO_STDINT_H */
+
+/** @addtogroup CL11TYPES
+ @{ */
+
+/******************************************************************************/
+/*
+ macros for function definitions.
+ */
+/** @defgroup CL11TYPES_CONVENTIONS The CL Lib types: API interface details
+ * @ingroup CL11TYPES
+ *
+ * Macros used to detail usage of API.
+ * @{
+ */
+
+# ifndef CL_C99
+# if defined(__cplusplus) || !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
+# define CL_C99(X)
+# else
+/** C99 only code.
+ Produce output for compiler that is only processed if compiler is in C99
+ mode or later. This macro can be used to use security enhancing constructs
+ in C99 without losing backwards compatibility with ANSI-C or C++. */
+# define CL_C99(X) X
+# endif
+# endif
+#ifndef CL_AT_LEAST
+/** Pointer needs to point at least x items.
+ Usage of this macro enhances interface with known restrictions on
+ intended amount of input elements. The macro is intended for compiler
+ guidance and documentation.
+ */
+#define CL_AT_LEAST(x) CL_C99(static) x
+#endif /* CL_AT_LEAST */
+#ifndef CL_AT_LEAST_EXPR
+/** Pointer needs to point at least x items.
+ Usage of this macro enhances interface with known restrictions on
+ intended amount of input elements. The macro is intended for compiler
+ guidance and documentation.
+
+ The limit is expressed as expression of other inputs to the function.
+
+ @note: Due to implementation, the value of expr needs to be at least 1. */
+#define CL_AT_LEAST_EXPR(x) CL_C99(static) 1
+#endif /* CL_AT_LEAST_EXPR */
+#ifndef CL_EXACTLY
+/** Pointer needs to point exactly x items.
+ Usage of this macro enhances interface with known restrictions on
+ intended amount of input elements. The macro is intended for compiler
+ guidance and documentation.
+ */
+#define CL_EXACTLY(x) CL_C99(static) x
+#endif /* CL_EXACTLY */
+#ifndef CL_EXACTLY_EXPR
+/** Pointer needs to point exactly x items.
+ Usage of this macro enhances interface with known restrictions on
+ intended amount of input elements. The macro is intended for compiler
+ guidance and documentation.
+
+ @note: Due to implementation, the value of expr needs to be at least 1. */
+#define CL_EXACTLY_EXPR(x) CL_C99(static) 1
+#endif /* CL_EXACTLY_EXPR */
+
+/** @} */
+
+/** @defgroup CL11TYPES_DIR The CL Lib types: Data direction
+ * @ingroup CL11TYPES
+ *
+ * Data direction indicators in function API.
+ *
+ * Access types used in function definitions.
+ * These are used to describe mapping between FIPS 140-2
+ * logical interfaces and the function API.
+ * @{
+ */
+#define CL_DI /* Data Input */ /**< @brief The pointed memory area acts as Data Input. */
+#define CL_DO /* Data Output */ /**< @brief The pointed memory area acts as Data Output. */
+#define CL_SO /* Status Output */ /**< @brief The pointed memory area acts as Status Output. */
+#define CL_HO /* Handle Output */ /**< @brief The pointed memory area acts as Handle Output.
+ [For purposes of FIPS 140-2 Logical interfaces, the
+ handle Output is considered Status Output.] */
+
+/* Note:
+ * The actual pointer values passed to the function parameters are
+ * considered Control Input for purposes FIPS 140-2, but depending
+ * on the value, the pointed memory area can be considered
+ * Data Input/Data Output. Also, all values provided on the function call
+ * (not via pointer) are considered Control Input. */
+
+/** @} */
+
+/*
+ * Definitions for Data Types used by CL interface.
+ */
+
+/** @defgroup CL11TYPES_COMMON The CL Lib types: Common
+ * @ingroup CL11TYPES
+ *
+ * Common data types for CL Lib API.
+ *
+ * The basic data types are based on C99 types.
+ * In absence of these ISO C99 types, other data types with equivalent
+ * size and range can be substituted.
+ * @{
+ */
+
+/** 64-bit unsigned integer
+
+ sizeof(CL_UInt64_t) == 8 \n
+ \f$alignment \leq 8\f$ \n
+ range \f$[0,2^{64}-1]\f$
+ */
+typedef uint64_t CL_UInt64_t;
+/** 32-bit unsigned integer
+
+ sizeof(CL_UInt32_t) == 4 \n
+ \f$alignment \leq 4\f$ \n
+ range \f$[0,2^{32}-1]\f$
+ */
+typedef uint32_t CL_UInt32_t;
+/** 16-bit unsigned integer
+
+ sizeof(CL_UInt16_t) == 2 \n
+ \f$alignment \leq 2\f$ \n
+ range \f$[0,65535]\f$
+ */
+typedef uint16_t CL_UInt16_t;
+/** 8-bit unsigned integer
+
+ sizeof(CL_UInt8_t) == 1 \n
+ alignment == 1 \n
+ range \f$[0,255]\f$
+ */
+typedef uint8_t CL_UInt8_t;
+
+/* Short aliases for above, just for convenience. */
+typedef CL_UInt8_t CL_U8_t; /**< Short for CL_UInt8_t. */
+typedef CL_UInt16_t CL_U16_t; /**< Short for CL_UInt16_t. */
+typedef CL_UInt32_t CL_U32_t; /**< Short for CL_UInt32_t. */
+typedef CL_UInt64_t CL_U64_t; /**< Short for CL_UInt64_t. */
+
+/* Type definitions for Key or Data Input. */
+typedef const CL_U8_t *CL_KeyPtr_t; /**< Pointer to key material. */
+typedef const CL_U8_t *CL_DataInPtr_t; /**< Input octets (Data Input). */
+
+typedef CL_U8_t CL_Data_t; /**< Type for arrays of data. */
+
+/* Type definitions for Data Output. */
+typedef CL_U8_t *CL_DataOutPtr_t; /**< Output octets (Data Output). */
+
+/* Type definitions for size of Input/Output or negotiating output size. */
+typedef CL_U32_t CL_KeyLen_t; /**< The Length of key material. */
+typedef CL_U32_t CL_DataLen_t; /**< The length of Input/Output data. */
+typedef CL_DataLen_t *CL_DataLenPtr_t; /**< The length of Output data
+ in functions using variable size. */
+typedef CL_U32_t CL_BitsLen_t; /**< Length of Input/Key data, in bits. */
+typedef CL_U32_t CL_Count_t; /**< The number of items. */
+
+/* Type definitions for functions returning combined return value. */
+typedef int CL_RvOrSize_t;
+#define CL_RV_OR_SIZE_OK_MAX ((CL_RvOrSize_t)0x7FFFFFFF)
+
+#ifndef CL_ASSET_32BIT
+/* Assets (handles to key material and objects stored via CL.)
+ For convenience, the functions in this API use type corresponding
+ to type required by the API entry point. */
+typedef CL_U64_t CL_AnyAsset_t; /**< Any type of Asset. */
+#ifndef CL_ASSET_64BIT
+#define CL_ASSET_64BIT 1 /* Compile time detect current 64-bit assets. */
+#endif
+#else
+/* backwards compatibility with platforms using 32-bit asset.
+ Avoid this flag on all platforms. */
+typedef CL_U32_t CL_AnyAsset_t; /**< Any type of Asset. */
+#endif
+
+typedef CL_AnyAsset_t CL_KeyAsset_t; /**< Key reference. */
+typedef CL_AnyAsset_t CL_StateAsset_t; /**< IV/temporary digest reference. */
+typedef CL_KeyAsset_t CL_KeyExtraAsset_t; /**< Key extra asset. */
+
+/* An array of key assets (for output of key derivation to assets.)
+ The key derivation functions allow the output to be created into
+ an array of key assets. This allows the user of key derivation functions
+ to implement key material to keys convertion easily and securely.
+ (Please, reference chapter 7.3 in NIST SP 800-108 @cite nist_sp_800_108
+ for details on Converting Key Material to Cryptographic Keys.)
+ This same convention is used in addition to key derivation functions
+ with other functions where convention is commonly used (Key Transport). */
+typedef const CL_KeyAsset_t *CL_KeyAssetArray_t; /**< Asset Array */
+/* Number of entriens in asset array. */
+typedef CL_Count_t CL_KeyAssetArrayCount_t; /**< Asset Array Length */
+
+/* New asset is allocated by function. */
+typedef CL_AnyAsset_t * const CL_AnyAssetNew_t; /**< Function allocates new asset (out). */
+typedef CL_AnyAssetNew_t CL_KeyAssetNew_t; /**< Function allocates new asset for key (out). */
+typedef CL_AnyAssetNew_t CL_TrustedKeyAssetNew_t; /**< Function allocates new asset for trusted key (out). */
+
+/* Locals (handles to key material and objects stored for use with CL.
+ These are just pointers with associated policy.)
+ For convenience, the functions in this API use type corresponding
+ to type required by the API entry point. */
+struct CL_Local;
+typedef struct CL_Local *CL_AnyLocal_t; /**< Any type of Local. */
+typedef CL_AnyLocal_t CL_KeyLocal_t; /**< Key reference. */
+typedef CL_AnyLocal_t CL_StateLocal_t; /**< IV/temporary digest reference. */
+typedef CL_KeyLocal_t CL_KeyExtraLocal_t; /**< Key extra local. */
+
+/* An array of key locals (for output of key derivation to locals.)
+ The key derivation functions allow the output to be created into
+ an array of key locals. This allows the user of key derivation functions
+ to implement key material to keys convertion easily and securely.
+ (Please, reference chapter 7.3 in NIST SP 800-108 @cite nist_sp_800_108
+ for details on Converting Key Material to Cryptographic Keys.)
+ This same convention is used in addition to key derivation functions
+ with other functions where convention is commonly used (Key Transport). */
+typedef const CL_KeyLocal_t *CL_KeyLocalArray_t; /**< Local Array */
+/* Number of entriens in local array. */
+typedef CL_Count_t CL_KeyLocalArrayCount_t; /**< Local Array Length */
+
+/* New local is allocated by function. */
+typedef CL_AnyLocal_t * const CL_AnyLocalNew_t; /**< Function allocates new local (out). */
+typedef CL_AnyLocalNew_t CL_KeyLocalNew_t; /**< Function allocates new local for key (out). */
+typedef CL_AnyLocalNew_t CL_TrustedKeyLocalNew_t; /**< Function allocates new local for trusted key (out). */
+
+/** @} */
+
+#include "cl_header_end.h"
+
+#endif /* INCLUDE_GUARD_CL_TYPES_BASE_H */
diff --git a/core/include/core/README.txt b/core/include/core/README.txt
new file mode 100644
index 0000000..3c7a9e8
--- /dev/null
+++ b/core/include/core/README.txt
@@ -0,0 +1 @@
+This directory is to support #include "core/*.h"
diff --git a/core/include/core/coreApi.h b/core/include/core/coreApi.h
new file mode 100644
index 0000000..c730ffa
--- /dev/null
+++ b/core/include/core/coreApi.h
@@ -0,0 +1 @@
+#include "../coreApi.h"
diff --git a/core/include/core/osdep.h b/core/include/core/osdep.h
new file mode 100644
index 0000000..ab2bae6
--- /dev/null
+++ b/core/include/core/osdep.h
@@ -0,0 +1 @@
+#include "../../osdep/include/osdep.h"
diff --git a/core/include/core/psUtil.h b/core/include/core/psUtil.h
new file mode 100644
index 0000000..311db0c
--- /dev/null
+++ b/core/include/core/psUtil.h
@@ -0,0 +1 @@
+#include "../psUtil.h"
diff --git a/core/coreApi.h b/core/include/coreApi.h
similarity index 87%
rename from core/coreApi.h
rename to core/include/coreApi.h
index 35f7f69..02bb01f 100644
--- a/core/coreApi.h
+++ b/core/include/coreApi.h
@@ -5,7 +5,7 @@
* Prototypes for the Matrix core public APIs.
*/
/*
- * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) 2013-2018 INSIDE Secure Corporation
* Copyright (c) PeerSec Networks, 2002-2011
* All Rights Reserved
*
@@ -47,6 +47,7 @@ extern "C" {
# include "osdep-types.h"
# include "list.h"
# include "psmalloc.h"
+# include "osdep_stdio.h"
/******************************************************************************/
/*
@@ -230,7 +231,7 @@ extern psPool_t * const psStaticAllocationsPool;
/******************************************************************************/
/* Public APIs */
-# include
+# include "osdep_time.h"
/******************************************************************************/
/* struct tm is standard for representing broken-down time in C89, C99 and
@@ -254,7 +255,13 @@ PSPUBLIC void psFreeAndClear(void *ptrptr, psPool_t *pool);
Public interface to functionality defined by functions in C89/C99 standards.
These function may be substituted with OS/psdep.c in nonstandard
systems.
+*/
+/* Return time in seconds since the epoch (1970-01-01 00:00:00)
+ or (psTimeSeconds_t) -1 on error. */
+PSPUBLIC psTimeSeconds_t psGetEpochTime(void);
+
+/*
Return broken-down time similar to gmtime(&time(NULL)). The function allows
offset in seconds.
*/
@@ -267,6 +274,8 @@ PSPUBLIC int32 psBrokenDownTimeAdd(psBrokenDownTime_t *res, int32 offset);
length. */
PSPUBLIC int32 psBrokenDownTimeStr(const psBrokenDownTime_t *t1,
char (*string)[PS_BROKENDOWN_TIME_STR_LEN]);
+PSPUBLIC int32 psBrokenDownTimeStrTwoDigitYear(const psBrokenDownTime_t *t,
+ char (*string)[PS_BROKENDOWN_TIME_STR_LEN]);
# define PS_BROKENDOWN_TIME_IMPORT_STRICT_ZULU 1 /* Require Z as timezone. */
# define PS_BROKENDOWN_TIME_IMPORT_2DIGIT_YEAR 2 /* Use two digit year for
range 1950-2049. */
@@ -296,11 +305,11 @@ PSPUBLIC int32 psCompareTime(psTime_t a, psTime_t b, void *userPtr);
# ifdef MATRIX_USE_FILE_SYSTEM
# ifdef USE_POSIX
-PSPUBLIC int32 psGetFileBufFp(psPool_t *pool, FILE *fp,
- unsigned char **buf, int32 *bufLen);
+PSPUBLIC psRes_t psGetFileBufFp(psPool_t *pool, FILE *fp,
+ unsigned char **buf, psSizeL_t *bufLen);
# endif /* USE_POSIX */
-PSPUBLIC int32 psGetFileBuf(psPool_t *pool, const char *fileName,
- unsigned char **buf, int32 *bufLen);
+PSPUBLIC psRes_t psGetFileBuf(psPool_t *pool, const char *fileName,
+ unsigned char **buf, psSizeL_t *bufLen);
# endif /* MATRIX_USE_FILE_SYSTEM */
# ifdef USE_MULTITHREADING
@@ -318,11 +327,23 @@ PSPUBLIC void psDestroyMutex(psMutex_t *mutex);
# define psDestroyMutex(A)
# endif /* USE_MULTITHREADING */
+/* Convert memory bytes to string.
+ Characters outside ASCII and non-printable characters are replaced
+ with dot characters.
+ The resulting string s is exactly len bytes long and it is not
+ zero-terminated. */
+PSPUBLIC void psMem2Str(char *s, const unsigned char *b, uint32 len);
+
+/* Create hexadecimal trace of packet or bianry data.
+ This function is an internal helper function for debug printing
+ hexadecimal data such as network packets or protocol messages. */
+void psTraceBytes(const char *tag, const unsigned char *p, int l);
+
/******************************************************************************/
/*
Internal list helpers
*/
-extern int32 psParseList(psPool_t *pool, char *list, const char separator,
+extern int32 psParseList(psPool_t *pool, const char *list, const char separator,
psList_t **items);
extern void psFreeList(psList_t *list, psPool_t *pool);
@@ -369,7 +390,7 @@ typedef enum
with psFree(). The string will have terminating \0.
* output_len will be written string length not counting terminating \0.
output_len can be provided as NULL if user wants to use functions like
- strlen() to obtain length of the string instead.
+ Strlen() to obtain length of the string instead.
*/
PSPUBLIC int32 psToUtf8String(psPool_t *pool,
const unsigned char *input, size_t input_len,
@@ -411,60 +432,38 @@ PSPUBLIC int32 psToUtf32String(psPool_t *pool,
unsigned char **output, size_t *output_len,
int opts);
-/******************************************************************************/
/*
- Statistics helpers
- */
+ Convert an ASCII hex representation to a binary buffer.
+ Decode enough data out of 'hex' buffer to produce 'binlen' bytes in 'bin'
+ Two digits of ASCII hex map to the high and low nybbles (in that order),
+ so this function assumes that 'hex' points to 2x 'binlen' bytes of data.
+ Return the number of bytes processed from hex (2x binlen) or < 0 on error.
+*/
+PSPUBLIC int32 psHexToBinary(unsigned char *hex,
+ unsigned char *bin,
+ int32 binlen);
-/** Number of samples to store take for running average. */
-# define STAT_AVG_SAMPLES 32
+/*
+ Each bin char converts to two hex values. High four bits for first hex
+ value and low four for second in pair.
+*/
+PSPUBLIC int32 psBinaryToHex(unsigned char *bin,
+ int32 binLen,
+ char *hex);
-typedef struct
-{
- uint32_t h; /**< High water */
- uint32_t a[STAT_AVG_SAMPLES]; /**< Values */
- uint32_t atot; /**< Running total of a[] values */
- uint16_t ai; /**< Most recent index into a[] */
- uint16_t an; /**< Current number of valid entries in a[] */
-} psAvgStat_t;
-
-__inline static void STAT_INC_AVG(psAvgStat_t *s, uint32_t val)
-{
- /* Update high water */
- if (val > s->h)
- {
- s->h = val;
- }
- if (s->an < STAT_AVG_SAMPLES)
- {
- /* Update total number of stats, if not at max */
- s->an++;
- }
- else
- {
- /* Subtract the oldest value from the running total, if we're replacing */
- s->atot -= s->a[s->ai];
- }
- /* Point to next entry, replace it and increment running total */
- s->ai = (s->ai + 1) % STAT_AVG_SAMPLES;
- s->a[s->ai] = val;
- s->atot += val;
-}
-
-__inline static uint32_t STAT_AVG(psAvgStat_t *s)
-{
- return s->atot / s->an;
-}
-
-__inline static uint32_t STAT_HIGH(psAvgStat_t *s)
-{
- return s->h;
-}
+/*
+ Case insignificant comparison of two strings. Case insignificance is
+ only effective for ASCII characters.
+*/
+PSPUBLIC int32 psStrCaseCmp(const char *s1, const char *s2);
# ifdef __cplusplus
}
# endif
+/* Additional extended functionality, that is currently not intended to be
+ used directly. */
+#include "private/coreApiExt.h"
+
#endif /* _h_PS_COREAPI */
/******************************************************************************/
-
diff --git a/core/include/export.h b/core/include/export.h
new file mode 100644
index 0000000..c33bced
--- /dev/null
+++ b/core/include/export.h
@@ -0,0 +1,44 @@
+
+#ifndef sodium_export_H
+#define sodium_export_H
+
+#ifndef __GNUC__
+# ifdef __attribute__
+# undef __attribute__
+# endif
+# define __attribute__(a)
+#endif
+
+#ifdef SODIUM_STATIC
+# define SODIUM_EXPORT
+#else
+# if defined(_MSC_VER)
+# ifdef SODIUM_DLL_EXPORT
+# define SODIUM_EXPORT __declspec(dllexport)
+# else
+# define SODIUM_EXPORT __declspec(dllimport)
+# endif
+# else
+# if defined(__SUNPRO_C)
+# ifndef __GNU_C__
+# define SODIUM_EXPORT __attribute__ (visibility(__global))
+# else
+# define SODIUM_EXPORT __attribute__ __global
+# endif
+# elif defined(_MSG_VER)
+# define SODIUM_EXPORT extern __declspec(dllexport)
+# else
+# define SODIUM_EXPORT __attribute__ ((visibility ("default")))
+# endif
+# endif
+#endif
+
+#ifndef CRYPTO_ALIGN
+# if defined(__INTEL_COMPILER) || defined(_MSC_VER)
+# define CRYPTO_ALIGN(x) __declspec(align(x))
+# else
+# define CRYPTO_ALIGN(x) __attribute__ ((aligned(x)))
+# endif
+#endif
+
+#endif
diff --git a/core/include/implementation_defs.h b/core/include/implementation_defs.h
new file mode 100644
index 0000000..f7b85e2
--- /dev/null
+++ b/core/include/implementation_defs.h
@@ -0,0 +1,569 @@
+/* implementation_defs.h
+ *
+ * Description: See below.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2007-2016 INSIDE Secure Oy. All Rights Reserved.
+*
+* The latest version of this code is available at http://www.matrixssl.org
+*
+* This software is open source; 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.
+*
+* This General Public License does NOT permit incorporating this software
+* into proprietary programs. If you are unable to comply with the GPL, a
+* commercial license for this software may be purchased from INSIDE at
+* http://www.insidesecure.com/
+*
+* This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\
+* http://www.gnu.org/copyleft/gpl.html
+*****************************************************************************/
+
+/*
+ This header provides implementation definitions required by the
+ SafeZone Software Modules. The definitions are used only in the
+ implementation code including module internal header and
+ implementation files. This header file shall not be included from
+ any public header.
+
+ The definitions provided are:
+
+ - possibility to use static inline for function definitions
+ - MIN() and MAX() macros
+ - BIT_N constants
+ - BIT_CLEAR, BIT_SET, BIT_IS_SET macros
+ - definition of NULL
+ - definition of offsetof
+ - macro PARAMETER_NOT_USED
+ - Logging macros
+ - macro PRECONDITION
+ - macro POSTCONDITION
+ - macro PANIC
+
+ This particular header should is used for building on basic
+ development platforms that are Linux and Win32.
+ */
+
+#ifndef INCLUDE_GUARD_IMPLEMENTATION_DEFS_H
+#define INCLUDE_GUARD_IMPLEMENTATION_DEFS_H
+
+
+#include "public_defs.h" /* include public defs for convenience */
+#include "cf_impldefs.h" /* include configuration options */
+
+/*
+ Enable static inline
+ */
+#if (defined(WIN32) || defined(__CC_ARM))
+# define inline __inline
+#endif
+
+
+/* MIN, MAX
+
+ Evaluate to maximum or minimum of two values.
+
+ NOTE:
+
+ warning for side-effects on the following two macros since the
+ arguments are evaluated twice changing this to inline functions is
+ problematic because of type incompatibilities
+ */
+#define MIN(_x, _y) ((_x) < (_y) ? (_x) : (_y))
+#define MAX(_x, _y) ((_x) > (_y) ? (_x) : (_y))
+
+/* BIT_n
+
+ Bit positions for 32-bit values.
+
+ using postfix "U" to be compatible with uint32
+ ("UL" is not needed and gives lint warning)
+ */
+#define BIT_0 0x00000001U
+#define BIT_1 0x00000002U
+#define BIT_2 0x00000004U
+#define BIT_3 0x00000008U
+#define BIT_4 0x00000010U
+#define BIT_5 0x00000020U
+#define BIT_6 0x00000040U
+#define BIT_7 0x00000080U
+#define BIT_8 0x00000100U
+#define BIT_9 0x00000200U
+#define BIT_10 0x00000400U
+#define BIT_11 0x00000800U
+#define BIT_12 0x00001000U
+#define BIT_13 0x00002000U
+#define BIT_14 0x00004000U
+#define BIT_15 0x00008000U
+#define BIT_16 0x00010000U
+#define BIT_17 0x00020000U
+#define BIT_18 0x00040000U
+#define BIT_19 0x00080000U
+#define BIT_20 0x00100000U
+#define BIT_21 0x00200000U
+#define BIT_22 0x00400000U
+#define BIT_23 0x00800000U
+#define BIT_24 0x01000000U
+#define BIT_25 0x02000000U
+#define BIT_26 0x04000000U
+#define BIT_27 0x08000000U
+#define BIT_28 0x10000000U
+#define BIT_29 0x20000000U
+#define BIT_30 0x40000000U
+#define BIT_31 0x80000000U
+#define BIT_ALL 0xffffffffU
+
+
+/* BIT_CLEAR
+
+ Clear bits enabled __bit in variable __bits.
+ */
+#define BIT_CLEAR(__bits, __bit) \
+ do { \
+ (__bits) &= ~(__bit); \
+ } while (0)
+
+
+/* BIT_SET
+
+ Enable bits enabled __bit in variable __bits.
+ */
+#define BIT_SET(__bits, __bit) \
+ do { \
+ (__bits) |= (__bit); \
+ } while (0)
+
+
+/* BIT_IS_SET
+
+ Evaluate to true if one or more bits enabled in __bit are
+ enabled in __bits.
+ */
+#define BIT_IS_SET(__bits, __bit) (((__bits) & (__bit)) != 0)
+
+
+/* ALIGNED_TO
+
+ Return true if Value is Alignment aligned; false otherwise. That is
+ if Value modulo Alignment equals 0.
+
+ NOTE: Only Alignments that are power of 2 are supported. False is
+ returned is Alignment is not a power of 2.
+ */
+#define ALIGNED_TO(Value, Alignment) \
+ ((((((Alignment) & (Alignment - 1)) == 0) && \
+ ((uintptr_t) (Value) & (Alignment - 1))) == 0) ? true : false)
+
+
+/* PARAMETER_NOT_USED()
+
+ To mark function input parameters that are purposely not used in
+ the function and to prevent compiler warnings on them.
+ */
+#define PARAMETER_NOT_USED(__identifier) \
+ do { if (__identifier) {} } while (0)
+
+
+/* IDENTIFIER_NOT_USED()
+
+ To mark function input parameters or local variables that are
+ purposely not used in the function and
+ to prevent compiler warnings on them.
+ */
+#define IDENTIFIER_NOT_USED(__identifier) \
+ do { if (__identifier) {} } while (0)
+
+
+/* NULL
+ */
+#ifndef NULL
+# define NULL 0
+#endif
+
+
+/* offsetof
+ */
+#ifndef offsetof
+# define offsetof(type, member) ((size_t) &(((type *) NULL)->member))
+#endif
+
+
+/* alignmentof
+ */
+#define alignmentof(type) (offsetof(struct { char x; type y; }, y))
+#ifdef WIN32
+# pragma warning(disable: 4116)
+#endif
+
+
+/* L_STRINGIFY
+
+ Convert parameter preprocessor token to a string constant.
+ */
+#define L_STRINGIFY(x) #x
+
+
+/* L_TOSTRING
+
+ Convert value of parameter preprocessor constant token to a string.
+ */
+#define L_TOSTRING(x) L_STRINGIFY(x)
+
+
+/* __FILELINE__
+
+ Macro __FILELINE__ combines __FILE__ and __LINE__ preprocessor
+ macros into a single macro with a string value.
+ As an example: If __FILE__ would have value "file.c" and
+ __LINE__ value 24, the __FILELINE__ would become "file.c:24".
+
+ Some compilers have the full path in __FILE__.
+ Some compilers have __MODULE__, which is __FILE__ but without the path.
+ */
+#undef __FILELINE__
+#ifdef __MODULE__
+# define __FILELINE__ __MODULE__ ":" L_TOSTRING(__LINE__)
+#else
+# define __FILELINE__ __FILE__ ":" L_TOSTRING(__LINE__)
+#endif
+
+#ifndef IMPLDEFS_CF_DISABLE_DEBUG_L_PRINTF
+# include "implementation_defs_log.h"
+#else /* IMPLDEFS_CF_DISABLE_DEBUG_L_PRINTF */
+# define L_PRINTF(__level, __flow, ...) \
+ do { /* L_PRINTF disabled */ L_PRINTF_NOT_USED(#__VA_ARGS__) } while (0)
+# define L_PRINTF_NOT_USED(string) /* empty */
+#endif /* !IMPLDEFS_CF_DISABLE_DEBUG_L_PRINTF */
+
+/* FUNCTION_NAME
+
+ Macro that expands a pointer to a constant character string giving
+ representing a name of the function in which used.
+
+ C99 standard specifies this as __func__, VC uses __FUNCTION__.
+
+ */
+#ifdef WIN32
+# define FUNCTION_NAME __FUNCTION__
+#else
+# define FUNCTION_NAME __func__
+#endif
+
+#include "psLog.h" /* SafeZone/Matrix common logging framework */
+/* L_DEBUG
+
+ The L_DEBUG macro takes a debug flow as its first argument and the
+ variable part is fprintf-style format string and it's parameters.
+ */
+#define L_DEBUG(__flow, fmt, ...) PS_LOGF_DEBUG_LN(__flow, fmt ,##__VA_ARGS__ )
+
+#include "psLog.h" /* SafeZone/Matrix common logging framework */
+/* L_TRACE
+
+ The L_TRACE macro takes a debug flow as its first argument and the
+ variable part is fprintf-style format string and it's parameters.
+ */
+#define L_TRACE(__flow, fmt, ...) PS_LOGF_TRACE_LN(__flow, fmt ,##__VA_ARGS__ )
+
+/* L_TESTLOG
+
+ The L_TESTLOG macro is used internally by unit testing.
+ Although L_TESTLOG seems similar to L_DEBUG and L_TRACE,
+ it must not be used directly (except from CHECK_* implementation).
+ Also, it is typically required that logs printed with this statement
+ are immediately printed out where as other logs may be delayed.
+ */
+#define L_TESTLOG(__event, ...) \
+ L_PRINTF( LL_TESTLOG, __event, __VA_ARGS__ )
+
+/* ASSERTION_CHECK()
+
+ The ASSERTION_CHECK macro is a helper macro for implementing actual
+ assertion macros: ASSERT(), PRECONDITION, and POSTCONDITION.
+
+ The macro check given condition. When condition evaluates to false
+ the execution is aborted. By default this is done calling
+ DEBUG_abort() function declared below in this header.
+
+ The macro aborts the execution calling. By default this is done calling
+ DEBUG_abort() function declared below in this header.
+
+ This macro should not be called directly.
+ */
+#ifdef IMPLDEFS_CF_DISABLE_DEBUG_L_PRINTF
+# ifdef __KERNEL__
+# define ASSERTION_CHECK(__flow, __condition, __description) \
+ ({ if (!(__condition)) { BUG(); } })
+# else
+# define ASSERTION_CHECK(__flow, __condition, __description) \
+ (void) ((__condition) ? 0 : \
+ ( DEBUG_abort(), 0 ) )
+# endif /* __KERNEL__ */
+#else /* !defined IMPLDEFS_CF_DISABLE_DEBUG_L_PRINTF */
+# ifdef __KERNEL__
+# define ASSERTION_CHECK(__flow, __condition, __description) \
+ ({ if (!(__condition)) { L_PRINTF(LL_ASSERT, __flow, __description \
+ ", function %s: %s", __FUNCTION__, \
+ #__condition); \
+ BUG(); } })
+# else
+# define ASSERTION_CHECK(__flow, __condition, __description) \
+ (void) ((__condition) ? 0 : \
+ ( L_PRINTF(LL_ASSERT, \
+ __flow, \
+ __description ", function %s: %s", \
+ __FUNCTION__, \
+ #__condition), \
+ DEBUG_abort(), \
+ 0 ) )
+# endif /* __KERNEL__ */
+#endif /* IMPLDEFS_CF_DISABLE_DEBUG_L_PRINTF */
+
+#ifdef IMPLDEFS_CF_DISABLE_ASSERTION_CHECK
+/* Disable all assertion checks and contract checks. */
+
+# ifndef IMPLDEFS_CF_DISABLE_ASSERT
+# define IMPLDEFS_CF_DISABLE_ASSERT
+# endif
+
+# ifndef IMPLDEFS_CF_DISABLE_PRECONDITION
+# define IMPLDEFS_CF_DISABLE_PRECONDITION
+# endif
+
+# ifndef IMPLDEFS_CF_DISABLE_POSTCONDITION
+# define IMPLDEFS_CF_DISABLE_POSTCONDITION
+# endif
+#endif /* IMPLDEFS_CF_DISABLE_ASSERTION_CHECK */
+
+
+/* ASSERT()
+
+ The ASSERT macro provides a "normal" assert.
+ */
+#ifndef IMPLDEFS_CF_DISABLE_ASSERT
+# define ASSERT(__condition) \
+ ASSERTION_CHECK( \
+ LF_ASSERT, \
+ (__condition), \
+ "assertion failed")
+#else /* IMPLDEFS_CF_DISABLE_ASSERT */
+# define ASSERT(__condition) \
+ (void) ((__condition) ? 0 : 0)
+#endif /* !IMPLDEFS_CF_DISABLE_ASSERT */
+
+
+/* PARAMETER_CHECK
+
+ To validate the parameters passed into a function. This macro,
+ if turned on evaluates the given condition and if found to be
+ true, makes the calling function return the given second argument.
+ This macro should only be called in beginning of functions, after local
+ variables and PARAMETER_UNUSED. In the case of void functions, please
+ prefer to use PRECONDITION instead.
+ */
+#ifndef IMPLDEFS_CF_DISABLE_PARAMETER_CHECK
+# define PARAMETER_CHECK(__condition, __ret_val) \
+ if ((__condition)) return (__ret_val)
+#else /* IMPLDEFS_CF_DISABLE_PARAMETER_CHECK */
+# define PARAMETER_CHECK(__condition, __ret_val) \
+ do { /* PARAMETER checks disabled. */ } while (0)
+#endif /* !IMPLDEFS_CF_DISABLE_PARAMETER_CHECK */
+
+/* PRECONDITION
+
+ To define preconditions of a function. Preconditions are conditions
+ that the implementation of the function assumes to hold when the
+ function is called. Preconditions are not to be checked by
+ production builds and no errors are returned when preconditions do
+ not hold. Defining preconditions with this macro documents clearly
+ what is assumed to hold and provides a possibility to assert such
+ conditions on debug builds.
+ */
+#ifndef IMPLDEFS_CF_DISABLE_PRECONDITION
+# define PRECONDITION(__condition) \
+ ASSERTION_CHECK( \
+ LF_CONDITION, \
+ (__condition), \
+ "precondition failed")
+#else /* IMPLDEFS_CF_DISABLE_PRECONDITION */
+# define PRECONDITION(__condition) \
+ do { /* preconditions disabled. */ } while (0)
+#endif /* !IMPLDEFS_CF_DISABLE_PRECONDITION */
+
+/* POSTCONDITION
+
+ To define postconditions of a function. Same rationale as for
+ PRECONDITION above.
+ */
+#ifndef IMPLDEFS_CF_DISABLE_POSTCONDITION
+# define POSTCONDITION(__condition) \
+ ASSERTION_CHECK( \
+ LF_CONDITION, \
+ (__condition), \
+ "postcondition failed")
+#else /* IMPLDEFS_CF_DISABLE_POSTCONDITION */
+# define POSTCONDITION(__condition) \
+ do { /* postconditions disabled. */ } while (0)
+#endif /* !IMPLDEFS_CF_DISABLE_POSTCONDITION */
+
+
+/* PANIC()
+
+ Macro to be called from code branches that should never be reached.
+ The macro aborts the execution calling. By default this is done calling
+ DEBUG_abort() function declared below in this header.
+ */
+#ifdef IMPLDEFS_CF_DISABLE_DEBUG_L_PRINTF
+# ifdef __KERNEL__
+# define PANIC(...) BUG()
+# else
+# define PANIC(...) \
+ (void) \
+ (DEBUG_abort())
+# endif /* __KERNEL__ */
+#else /* !defined IMPLDEFS_CF_DISABLE_DEBUG_L_PRINTF */
+# ifdef __KERNEL__
+# define PANIC(...) \
+ ({ L_PRINTF( \
+ LL_ASSERT, \
+ LF_PANIC, \
+ "PANIC: " __VA_ARGS__); \
+ BUG(); })
+# else
+# define PANIC(...) \
+ (void) \
+ (L_PRINTF( \
+ LL_ASSERT, \
+ LF_PANIC, \
+ "PANIC: " __VA_ARGS__), \
+ DEBUG_abort())
+# endif /* __KERNEL__ */
+#endif /* IMPLDEFS_CF_DISABLE_DEBUG_L_PRINTF */
+
+
+/* COMPILE_GLOBAL_ASSERT
+
+ Macro to make global scope compile time assertions. The condition
+ must be a constant C expression (expression that can be evaluated
+ at compile time) evaluating to true when the required condition
+ holds and to false otherwise.
+
+ When condition evaluates to true the macro has no effect.
+
+ When condition evaluates to false the compilation fails due to
+ declaration of arrays of size -1.
+ */
+#define COMPILE_GLOBAL_ASSERT(condition) \
+ extern int global_assert_ ## description[1 - 2 * (!(condition))]
+
+
+/* COMPILE_STATIC_ASSERT
+
+ Macro to make function scope compile time assertions. The condition
+ must be a constant C expression (expression that can be evaluated
+ at compile time) evaluating to true when the required condition
+ holds and to false otherwise.
+
+ When condition evaluates to true the macro has no effect.
+
+ When condition evaluates to false the compilation fails due to
+ declaration of arrays of size -1.
+ */
+#define COMPILE_STATIC_ASSERT(condition) \
+ do { \
+ int static_assertion[1 - 2 * (!(condition))] = { 1 }; \
+ if (static_assertion[0]) \
+ { /* Nothing */ } \
+ } while (0)
+
+
+/* UNREACHABLE
+
+ Macro to mark locations that are never reached by code execution.
+ This macro can be used by compiler to analyze the source code and
+ notice paths that are never taken. Some compilers may use this
+ to optimize produced code betetr, other may use it to ensure the
+ patchs unreachable are factually unreachable.
+ */
+#define UNREACHABLE ASSERT(0 /* This code shall never be reached. */)
+
+
+/* Define C99 fixed with integer print formatting macros for Windows.
+ On most GCC platforms include
+ */
+
+#if defined(WIN32) || defined(__KERNEL__)
+
+# define PRId8 "hhd"
+# define PRIi8 "hhi"
+# define PRIo8 "hho"
+# define PRIu8 "hhu"
+# define PRIx8 "hhx"
+# define PRIX8 "hhX"
+
+# define PRId16 "hd"
+# define PRIi16 "hi"
+# define PRIo16 "ho"
+# define PRIu16 "hu"
+# define PRIx16 "hx"
+# define PRIX16 "hX"
+
+# define PRIi32 "i"
+# define PRId32 "d"
+# define PRIo32 "o"
+# define PRIu32 "u"
+# define PRIx32 "x"
+# define PRIX32 "X"
+
+# define PRIi64 "lli"
+# define PRId64 "lld"
+# define PRIo64 "llo"
+# define PRIu64 "llu"
+# define PRIx64 "llx"
+# define PRIX64 "llX"
+
+#elif (defined(__GNUC__) || defined(__CC_ARM))
+# include "osdep_inttypes.h"
+#else
+# error Unsupported platform
+#endif
+
+/* Definitions of functions defined in DEBUG module.
+ Always only use these via L_* macros. */
+extern void DEBUG_abort(void);
+
+/* DEBUG_printf has been deprecated.
+ Only provide prototype if explictly requested. */
+#ifdef IMPLDEFS_NEED_DEBUG_PRINTF
+#ifdef __GNUC__
+extern int DEBUG_printf(
+ const char *format, ...)
+__attribute__ ((format(printf, 1, 2)));
+#else
+extern int DEBUG_printf(
+ const char *format, ...);
+#endif
+#endif
+
+/* Make wide character type available.
+ Wide characters are actually not supported in debug printing,
+ but silently truncated to 8-bit characters. */
+#ifndef __WCHAR_TYPE__
+# include "osdep_wchar.h"
+# ifndef __WCHAR_TYPE__
+# define __WCHAR_TYPE__ wchar_t
+# endif /* __WCHAR_TYPE__ */
+#endif /* __WCHAR_TYPE__ */
+
+#endif /* Include guard */
+
+/* end of file implementation_defs.h */
diff --git a/core/include/implementation_defs_log.h b/core/include/implementation_defs_log.h
new file mode 100644
index 0000000..fa310f5
--- /dev/null
+++ b/core/include/implementation_defs_log.h
@@ -0,0 +1,177 @@
+/* implementation_defs_log.h
+ *
+ * Logging services for implementation_defs.h
+ */
+
+/*****************************************************************************
+* Copyright (c) 2016 INSIDE Secure Oy. All Rights Reserved.
+*
+* The latest version of this code is available at http://www.matrixssl.org
+*
+* This software is open source; 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.
+*
+* This General Public License does NOT permit incorporating this software
+* into proprietary programs. If you are unable to comply with the GPL, a
+* commercial license for this software may be purchased from INSIDE at
+* http://www.insidesecure.com/
+*
+* This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\
+* http://www.gnu.org/copyleft/gpl.html
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_IMPLEMENTATION_DEFS_LOG_H
+#define INCLUDE_GUARD_IMPLEMENTATION_DEFS_LOG_H
+
+#include "osdep_stdio.h"
+
+/* Define L_ENABLE/L_DISABLE/L_DEFAULT_ENABLE/L_DEFAULT_DISABLE macros.
+ These are used to define logging settings for LL_* (i.e. per log level)
+ and LF_* (i.e. per log type).
+ */
+#define L_ENABLE ,
+#define L_DISABLE , ,
+#define L_DEFAULT_ENABLE , , ,
+#define L_DEFAULT_DISABLE , , , ,
+
+/* Printing settings per log level.
+ */
+#ifndef LL_ASSERT_CONTROL
+# define LL_ASSERT__CONTROL L_ENABLE
+#endif
+#ifndef LL_CRIT__CONTROL
+# define LL_CRIT__CONTROL L_ENABLE /* Currently not provided by front-end */
+#endif
+#ifndef LL_INFO__CONTROL
+# define LL_INFO__CONTROL L_DISABLE /* Currently not provided by front-end */
+#endif
+#ifndef LL_DEBUG__CONTROL
+# define LL_DEBUG__CONTROL L_DEFAULT_ENABLE
+#endif
+#ifndef LL_TRACE__CONTROL
+# ifdef CFG_IMPLDEFS_ENABLE_TRACE
+# define LL_TRACE__CONTROL L_DEFAULT_ENABLE
+# else
+# define LL_TRACE__CONTROL L_DEFAULT_DISABLE
+# endif
+#endif
+#ifndef LL_TESTLOG__CONTROL
+# define LL_TESTLOG__CONTROL L_ENABLE
+#endif
+
+/* Printing settings per log field.
+ These are just examples (LF_DEBUG1 is log field never used).
+ */
+#define LF_DEBUG1__CONTROL L_ENABLE /* Enabled, override LL_* settings */
+#define LF_DEBUG2__CONTROL L_DISABLE /* Disabled, override LL_* setting */
+/* The following differ in default action: */
+#define LF_DEBUG3__CONTROL L_DEFAULT_ENABLE /* Follow LL_* setting */
+#define LF_DEBUG4__CONTROL L_DEFAULT_DISABLE /* Follow LL_* setting */
+
+/* L_CONCAT
+
+ Concatenate parameters.
+ */
+#define L_CONCAT(a, b) L_CONCAT_(a, b)
+#define L_CONCAT_(a, b) a ## b
+
+/* L_PRINTF
+
+ The L_PRINTF macro provides a single point of customization of the
+ debug output mechanism. It takes debug level as first argument,
+ debug flow as second and the variable argument containing fprintf-style
+ format string and it's arguments.
+
+ C99 requires that the ellipsis in macro calls contains at least one
+ argument (unlike in function calls). To enable calls to L_PRINTF
+ with plain format string, and to be able to concatenate a newline
+ to format string, the L_PRINTF_OUTPUT_WRAP macro has to be called
+ with single argument that is the list of the format string and rest
+ of the parameters within parentheses with an extra argument; an
+ empty string constant. This enables further macro layers to break
+ format string to a separate argument.
+
+ NOTE: Must not be called directly.
+ */
+/* Define L_PRINTF functionality, which uses
+ L_PRINTF_OUTPUT_WRAP_INVOKE to find handler for output. */
+#define L_PRINTF(__level, __flow, ...) \
+ L_PRINTF_OUTPUT_WRAP_INVOKE(__level, __flow)(( \
+ L_STRINGIFY(__level) ", " \
+ L_STRINGIFY(__flow) ", " \
+ __FILELINE__ ": " \
+ "%s: " \
+ __VA_ARGS__, ""))
+
+/* L_PRINTF_OUTPUT
+
+ Final macro that calls DEBUG_printf with format string and format
+ arguments. There is always as least one argument, the empty string
+ added by L_PRINTF, so format can be separated from the ellipsis.
+
+ The function DEBUG_printf, that is used for actual output, is
+ declared below in this header.
+
+ NOTE: Must not be called directly.
+ */
+/* Helper macro, which is invoked with #__VA_ARGS__ if the variable arguments
+ are not used */
+#define L_PRINTF_NOT_USED(string) /* empty */
+/* If output is enabled, this macro will be invoked. */
+#define L_PRINTF_OUTPUT(format, ...) \
+ (void) Printf(format "%s\n", FUNCTION_NAME, __VA_ARGS__)
+#define L_PRINTF_OUTPUT_WRAP(arg) L_PRINTF_OUTPUT arg
+
+/* If output is disabled, this macro will be invoked. */
+#define L_PRINTF_IGNORE(format, ...) \
+ (void) L_PRINTF_NOT_USED(#__VA_ARGS__) 0
+#define L_PRINTF_IGNORE_WRAP(arg) L_PRINTF_IGNORE arg
+
+/* Choose OUTPUT/IGNORE wrap to invoke, according to __level. */
+#define L_PRINTF_OUTPUT_WRAP_INVOKE(__level, __flow) \
+ L_PRINTF_OUTPUT_WRAP_INVOKE_((L_CONCAT(__level, __CONTROL), \
+ L_PRINTF_IGNORE_WRAP_INVOKE_DEFAULT(__flow), \
+ L_PRINTF_OUTPUT_WRAP_INVOKE_DEFAULT(__flow), \
+ L_PRINTF_IGNORE_WRAP, \
+ L_PRINTF_OUTPUT_WRAP, \
+ L_PRINTF_OUTPUT_WRAP_INVOKE_DEFAULT(__flow), ))
+
+#define L_PRINTF_OUTPUT_WRAP_INVOKE_(arg) L_PRINTF_OUTPUT_WRAP_INVOKE__ arg
+#define L_PRINTF_OUTPUT_WRAP_INVOKE__(ctrl, i1, i2, i3, i4, _d, ...) \
+ L_PRINTF_NOT_USED(#__VA_ARGS__) _d
+/* Choose OUTPUT/IGNORE wrap to invoke, according to __level,
+ defaulting to "output" */
+#define L_PRINTF_OUTPUT_WRAP_INVOKE_DEFAULT(__flow) \
+ L_PRINTF_OUTPUT_WRAP_INVOKE_DEFAULT_((L_CONCAT(__flow, __CONTROL), \
+ L_PRINTF_IGNORE_WRAP, \
+ L_PRINTF_OUTPUT_WRAP, \
+ L_PRINTF_IGNORE_WRAP, \
+ L_PRINTF_OUTPUT_WRAP, \
+ L_PRINTF_OUTPUT_WRAP, ))
+
+/* Choose OUTPUT/IGNORE wrap to invoke, according to __level,
+ defaulting to "ignore" */
+#define L_PRINTF_IGNORE_WRAP_INVOKE_DEFAULT(__flow) \
+ L_PRINTF_OUTPUT_WRAP_INVOKE_DEFAULT_((L_CONCAT(__flow, __CONTROL), \
+ L_PRINTF_IGNORE_WRAP, \
+ L_PRINTF_OUTPUT_WRAP, \
+ L_PRINTF_IGNORE_WRAP, \
+ L_PRINTF_OUTPUT_WRAP, \
+ L_PRINTF_IGNORE_WRAP, ))
+
+#define L_PRINTF_OUTPUT_WRAP_INVOKE_DEFAULT_(arg) \
+ L_PRINTF_OUTPUT_WRAP_INVOKE_DEFAULT__ arg
+#define L_PRINTF_OUTPUT_WRAP_INVOKE_DEFAULT__(ctrl, i1, i2, i3, i4, _d, ...) \
+ L_PRINTF_NOT_USED(#__VA_ARGS__) _d
+
+#endif /* INCLUDE_GUARD_IMPLEMENTATION_DEFS_LOG_H */
+
+/* end of file implementation_defs_log.h */
diff --git a/core/include/list.h b/core/include/list.h
new file mode 100644
index 0000000..3456bf0
--- /dev/null
+++ b/core/include/list.h
@@ -0,0 +1,41 @@
+/**
+ * @file list.h
+ * @version $Format:%h%d$
+ *
+ * List utilities.
+ */
+/*
+ * Copyright (c) 2013-2018 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
+ *
+ * The latest version of this code is available at http://www.matrixssl.org
+ *
+ * This software is open source; 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.
+ *
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
+ *
+ * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+/******************************************************************************/
+
+#ifndef INCLUDE_GUARD_LIST_H
+#define INCLUDE_GUARD_LIST_H 1
+
+/* This file is just compatibility alias for new name pslist.h. */
+#include "pslist.h"
+
+#endif /* INCLUDE_GUARD_LIST_H */
diff --git a/core/include/private/common.h b/core/include/private/common.h
new file mode 100644
index 0000000..278ba12
--- /dev/null
+++ b/core/include/private/common.h
@@ -0,0 +1,230 @@
+#ifndef common_H
+#define common_H 1
+
+#include "pscompilerdep.h"
+#include "osdep_stdint.h"
+#include "osdep_stdlib.h"
+#include "osdep_string.h"
+
+#define COMPILER_ASSERT(X) (void) sizeof(char[(X) ? 1 : -1])
+
+#define ROTL32(X, B) rotl32((X), (B))
+static inline uint32_t
+rotl32(const uint32_t x, const int b)
+{
+ return (x << b) | (x >> (32 - b));
+}
+
+#define ROTL64(X, B) rotl64((X), (B))
+static inline uint64_t
+rotl64(const uint64_t x, const int b)
+{
+ return (x << b) | (x >> (64 - b));
+}
+
+#define ROTR32(X, B) rotr32((X), (B))
+static inline uint32_t
+rotr32(const uint32_t x, const int b)
+{
+ return (x >> b) | (x << (32 - b));
+}
+
+#define ROTR64(X, B) rotr64((X), (B))
+static inline uint64_t
+rotr64(const uint64_t x, const int b)
+{
+ return (x >> b) | (x << (64 - b));
+}
+
+#define LOAD64_LE(SRC) load64_le(SRC)
+static inline uint64_t
+load64_le(const uint8_t src[8])
+{
+#ifdef NATIVE_LITTLE_ENDIAN
+ uint64_t w;
+ Memcpy(&w, src, sizeof w);
+ return w;
+#else
+ uint64_t w = (uint64_t) src[0];
+ w |= (uint64_t) src[1] << 8;
+ w |= (uint64_t) src[2] << 16;
+ w |= (uint64_t) src[3] << 24;
+ w |= (uint64_t) src[4] << 32;
+ w |= (uint64_t) src[5] << 40;
+ w |= (uint64_t) src[6] << 48;
+ w |= (uint64_t) src[7] << 56;
+ return w;
+#endif
+}
+
+#define STORE64_LE(DST, W) store64_le((DST), (W))
+static inline void
+store64_le(uint8_t dst[8], uint64_t w)
+{
+#ifdef NATIVE_LITTLE_ENDIAN
+ Memcpy(dst, &w, sizeof w);
+#else
+ dst[0] = (uint8_t) w; w >>= 8;
+ dst[1] = (uint8_t) w; w >>= 8;
+ dst[2] = (uint8_t) w; w >>= 8;
+ dst[3] = (uint8_t) w; w >>= 8;
+ dst[4] = (uint8_t) w; w >>= 8;
+ dst[5] = (uint8_t) w; w >>= 8;
+ dst[6] = (uint8_t) w; w >>= 8;
+ dst[7] = (uint8_t) w;
+#endif
+}
+
+#define LOAD32_LE(SRC) load32_le(SRC)
+static inline uint32_t
+load32_le(const uint8_t src[4])
+{
+#ifdef NATIVE_LITTLE_ENDIAN
+ uint32_t w;
+ Memcpy(&w, src, sizeof w);
+ return w;
+#else
+ uint32_t w = (uint32_t) src[0];
+ w |= (uint32_t) src[1] << 8;
+ w |= (uint32_t) src[2] << 16;
+ w |= (uint32_t) src[3] << 24;
+ return w;
+#endif
+}
+
+#define STORE32_LE(DST, W) store32_le((DST), (W))
+static inline void
+store32_le(uint8_t dst[4], uint32_t w)
+{
+#ifdef NATIVE_LITTLE_ENDIAN
+ Memcpy(dst, &w, sizeof w);
+#else
+ dst[0] = (uint8_t) w; w >>= 8;
+ dst[1] = (uint8_t) w; w >>= 8;
+ dst[2] = (uint8_t) w; w >>= 8;
+ dst[3] = (uint8_t) w;
+#endif
+}
+
+/* ----- */
+
+#define LOAD64_BE(SRC) load64_be(SRC)
+static inline uint64_t
+load64_be(const uint8_t src[8])
+{
+#ifdef NATIVE_BIG_ENDIAN
+ uint64_t w;
+ Memcpy(&w, src, sizeof w);
+ return w;
+#else
+ uint64_t w = (uint64_t) src[7];
+ w |= (uint64_t) src[6] << 8;
+ w |= (uint64_t) src[5] << 16;
+ w |= (uint64_t) src[4] << 24;
+ w |= (uint64_t) src[3] << 32;
+ w |= (uint64_t) src[2] << 40;
+ w |= (uint64_t) src[1] << 48;
+ w |= (uint64_t) src[0] << 56;
+ return w;
+#endif
+}
+
+#define STORE64_BE(DST, W) store64_be((DST), (W))
+static inline void
+store64_be(uint8_t dst[8], uint64_t w)
+{
+#ifdef NATIVE_BIG_ENDIAN
+ Memcpy(dst, &w, sizeof w);
+#else
+ dst[7] = (uint8_t) w; w >>= 8;
+ dst[6] = (uint8_t) w; w >>= 8;
+ dst[5] = (uint8_t) w; w >>= 8;
+ dst[4] = (uint8_t) w; w >>= 8;
+ dst[3] = (uint8_t) w; w >>= 8;
+ dst[2] = (uint8_t) w; w >>= 8;
+ dst[1] = (uint8_t) w; w >>= 8;
+ dst[0] = (uint8_t) w;
+#endif
+}
+
+#define LOAD32_BE(SRC) load32_be(SRC)
+static inline uint32_t
+load32_be(const uint8_t src[4])
+{
+#ifdef NATIVE_BIG_ENDIAN
+ uint32_t w;
+ Memcpy(&w, src, sizeof w);
+ return w;
+#else
+ uint32_t w = (uint32_t) src[3];
+ w |= (uint32_t) src[2] << 8;
+ w |= (uint32_t) src[1] << 16;
+ w |= (uint32_t) src[0] << 24;
+ return w;
+#endif
+}
+
+#define STORE32_BE(DST, W) store32_be((DST), (W))
+static inline void
+store32_be(uint8_t dst[4], uint32_t w)
+{
+#ifdef NATIVE_BIG_ENDIAN
+ Memcpy(dst, &w, sizeof w);
+#else
+ dst[3] = (uint8_t) w; w >>= 8;
+ dst[2] = (uint8_t) w; w >>= 8;
+ dst[1] = (uint8_t) w; w >>= 8;
+ dst[0] = (uint8_t) w;
+#endif
+}
+
+#ifndef __GNUC__
+# ifdef __attribute__
+# undef __attribute__
+# endif
+# define __attribute__(a)
+#endif
+
+#ifndef CRYPTO_ALIGN
+# if defined(__INTEL_COMPILER) || defined(_MSC_VER)
+# define CRYPTO_ALIGN(x) __declspec(align(x))
+# else
+# define CRYPTO_ALIGN(x) __attribute__ ((aligned(x)))
+# endif
+#endif
+
+#ifndef STACK_CRYPTO_ALIGN
+# if defined(__INTEL_COMPILER) || defined(_MSC_VER)
+# define STACK_CRYPTO_ALIGN(x) __declspec(align(x))
+# elif defined __ARMCC5
+/* ARMCC maximum alignment in stack is 8. */
+# define STACK_CRYPTO_ALIGN(x) __attribute__ ((aligned(8)))
+# define STACK_CRYPTO_ALIGN_MAX_8 /* Maximum for stack alignment is 8. */
+# else
+# define STACK_CRYPTO_ALIGN(x) __attribute__ ((aligned(x)))
+# endif
+#endif
+
+#if defined(_MSC_VER) && \
+ (defined(_M_X64) || defined(_M_AMD64) || defined(_M_IX86))
+
+# include
+
+# define HAVE_INTRIN_H 1
+# define HAVE_MMINTRIN_H 1
+# define HAVE_EMMINTRIN_H 1
+# define HAVE_PMMINTRIN_H 1
+# define HAVE_TMMINTRIN_H 1
+# define HAVE_SMMINTRIN_H 1
+# define HAVE_AVXINTRIN_H 1
+# if _MSC_VER >= 1600
+# define HAVE_WMMINTRIN_H 1
+# endif
+# if _MSC_VER >= 1700 && defined(_M_X64)
+# define HAVE_AVX2INTRIN_H 1
+# endif
+#elif defined(HAVE_INTRIN_H)
+# include
+#endif
+
+#endif
diff --git a/core/include/private/coreApiExt.h b/core/include/private/coreApiExt.h
new file mode 100644
index 0000000..6da7ea7
--- /dev/null
+++ b/core/include/private/coreApiExt.h
@@ -0,0 +1,130 @@
+/**
+ * @file coreApi.h
+ * @version $Format:%h%d$
+ *
+ * Internal or extended definitions for Matrix core.
+ */
+/*
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
+ *
+ * The latest version of this code is available at http://www.matrixssl.org
+ *
+ * This software is open source; 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.
+ *
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
+ *
+ * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+/******************************************************************************/
+
+#ifndef _h_PS_COREAPIEXT
+# define _h_PS_COREAPIEXT
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+# ifdef MATRIX_CONFIGURATION_INCDIR_FIRST
+# include /* Must be first included */
+# else
+# include "coreConfig.h" /* Must be first included */
+# endif
+# include "osdep-types.h"
+# include "list.h"
+# include "psmalloc.h"
+
+/******************************************************************************/
+/*
+ Statistics helpers
+ */
+
+/** Number of samples to store take for running average. */
+# define STAT_AVG_SAMPLES 32
+
+typedef struct
+{
+ uint32_t h; /**< High water */
+ uint32_t a[STAT_AVG_SAMPLES]; /**< Values */
+ uint32_t atot; /**< Running total of a[] values */
+ uint16_t ai; /**< Most recent index into a[] */
+ uint16_t an; /**< Current number of valid entries in a[] */
+} psAvgStat_t;
+
+static inline void STAT_INC_AVG(psAvgStat_t *s, uint32_t val)
+{
+ /* Update high water */
+ if (val > s->h)
+ {
+ s->h = val;
+ }
+ if (s->an < STAT_AVG_SAMPLES)
+ {
+ /* Update total number of stats, if not at max */
+ s->an++;
+ }
+ else
+ {
+ /* Subtract the oldest value from the running total, if we're replacing */
+ s->atot -= s->a[s->ai];
+ }
+ /* Point to next entry, replace it and increment running total */
+ s->ai = (s->ai + 1) % STAT_AVG_SAMPLES;
+ s->a[s->ai] = val;
+ s->atot += val;
+}
+
+static inline uint32_t STAT_AVG(psAvgStat_t *s)
+{
+ return s->atot / s->an;
+}
+
+static inline uint32_t STAT_HIGH(psAvgStat_t *s)
+{
+ return s->h;
+}
+
+/******************************************************************************/
+/*
+ Formatted printing.
+
+ These functions implement printf-like formatting.
+ Instead of the functions, please use e.g. Snprintf() for formatting
+ basic data types. For formatting more complex inputs, use psPrnf().
+ Note: On embedded platforms without standard formatting facilities,
+ these functions can be used to implement Snprintf().
+ */
+#include "osdep_stdarg.h"
+int psSbufprintf(psBuf_t *buf, const char *format, ...)
+#ifdef __GNUC__
+__attribute__((__format__(printf, 2, 3)))
+#endif /* __GNUC__ */
+;
+int psSnprintf(char *str, size_t size, const char *format, ...)
+#ifdef __GNUC__
+__attribute__((__format__(printf, 3, 4)))
+#endif /* __GNUC__ */
+;
+int psVsnprintf(char *str, size_t size, const char *format, va_list ap);
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif /* _h_PS_COREAPIEXT */
+/******************************************************************************/
+
diff --git a/core/psLog.h b/core/include/psLog.h
similarity index 89%
rename from core/psLog.h
rename to core/include/psLog.h
index 4665037..4338f8a 100644
--- a/core/psLog.h
+++ b/core/include/psLog.h
@@ -34,6 +34,9 @@
*/
/******************************************************************************/
+#ifndef _h_PS_LOG
+# define _h_PS_LOG 1
+
#ifndef _h_PS_CORECONFIG
# ifdef MATRIX_CONFIGURATION_INCDIR_FIRST
# include /* Must be first included */
@@ -42,9 +45,6 @@
# endif
#endif /* _h_PS_CORECONFIG */
-#ifndef _h_PS_LOG
-# define _h_PS_LOG
-
# ifndef PS_NO_LOGF
/* Define a common logging framework.
If you want to use previous MatrixSSL logging facilities only,
@@ -58,8 +58,10 @@
#else
# define PS_LOGF_FORMAT3_4 /* No formatting code. */
#endif
-
-#include /* Variable length function arguments are used for
+
+#include "cl_header_begin.h"
+
+#include "osdep_stdarg.h" /* Variable length function arguments are used for
formatting. */
/* This string is used as token when logging function is called to "probe"
@@ -80,7 +82,7 @@ Invocation: PS_LOGF_COMMON(Log_Level, CODE_UNIT, PS_LOGF_TYPE, "File:Line: ", \
psLogf_fmt, ( ,##__VA_ARGS__ ))
#define PS_LOGF_COMMON1(psLogf_ll, psLogf_cu, psLogf_type, psLogf_ctx, \
psLogf_fmt, psLogf_args) \
-PS_LOGF_CONCATENATE(PS_LOGF_COMMON_, psLogf_ll)(PS_LOGF_STRINGIZE(psLogf_ll), PS_LOGF_STRINGIZE(psLogf_cu), PS_LOGF_CONCATENATE(PS_LOGF_FORMAT_LOG_, psLogf_type)(PS_LOGF_STRINGIZE(psLogf_cu), psLogf_ctx, psLogf_fmt, psLogf_args))
+PS_LOGF_CONCATENATE(PS_LOGF_COMMON_, psLogf_ll)(PS_LOGF_LL_STRINGIZE(psLogf_ll), PS_LOGF_STRINGIZE(psLogf_cu), PS_LOGF_CONCATENATE(PS_LOGF_FORMAT_LOG_, psLogf_type)(PS_LOGF_STRINGIZE(psLogf_cu), psLogf_ctx, psLogf_fmt, psLogf_args))
/* This is generic log checking macro.
The calls to psTrace functions will map to this macro.
@@ -90,7 +92,7 @@ PS_LOGF_CONCATENATE(PS_LOGF_COMMON_, psLogf_ll)(PS_LOGF_STRINGIZE(psLogf_ll), PS
logging is not enabled.
Invocation: PS_LOGF_IS_ENABLED(Log_Level, CODE_UNIT) */
#define PS_LOGF_IS_ENABLED(psLogf_ll, psLogf_cu) \
- PS_LOGF_CONCATENATE(PS_LOGF_COMMON_IS_ENABLED_, psLogf_ll)(PS_LOGF_STRINGIZE(psLogf_ll), PS_LOGF_STRINGIZE(psLogf_cu))
+ PS_LOGF_CONCATENATE(PS_LOGF_COMMON_IS_ENABLED_, psLogf_ll)(PS_LOGF_LL_STRINGIZE(psLogf_ll), PS_LOGF_STRINGIZE(psLogf_cu))
/* Function called for fatal logs.
Note: This function is only ever called just before software goes down. */
@@ -321,20 +323,16 @@ void psLogfDisable(const char *module_or_level);
psLogfCallTrace(psLogf_llstr, psLogf_custr, PS_LOGF_FMT_IS_ENABLED)
#endif
-/* Typedef for log levels. */
-typedef enum
-{
- PS_LOGF_UNKNOWN, /* For messages of unknown type. */
- PS_LOGF_CALL_TRACE,
- PS_LOGF_TRACE,
- PS_LOGF_VERBOSE,
- PS_LOGF_DEBUG,
- PS_LOGF_INFO,
- PS_LOGF_WARNING,
- PS_LOGF_ERROR,
- PS_LOGF_FATAL
-} psLogfLevel_t;
-
+/* Logging level (as unique) strings. */
+extern const char psLogf_Log_CallTrace[];
+extern const char psLogf_Log_Trace[];
+extern const char psLogf_Log_Verbose[];
+extern const char psLogf_Log_Debug[];
+extern const char psLogf_Log_Info[];
+extern const char psLogf_Log_Warning[];
+extern const char psLogf_Log_Error[];
+extern const char psLogf_Log_Fatal[];
+
/* Convenience formatting */
#define PS_LOGF_CALL_TRACE(tag, fmt, ...) \
PS_LOGF_COMMON(Log_CallTrace, tag, \
@@ -430,7 +428,18 @@ typedef enum
#define PS_LOGF_GET_ARGS(...) __VA_ARGS__
/* Common representation of context: Source code file and line. */
-#define PS_LOGF_FILELINE __FILE__ ":" PS_LOGF_STRINGIZE(__LINE__) ": "
+#ifdef PS_LOGF_FILE
+/* Provide name for the source file using macro PS_LOGF_FILE, for instance
+ from compiler invocation. */
+# define PS_LOGF_FILELINE PS_LOGF_FILE ":" PS_LOGF_STRINGIZE(__LINE__) ": "
+#else
+# ifdef __GNUC__
+/* On GNU C use __BASE_FILE__, which contains less directory path. */
+# define PS_LOGF_FILELINE __BASE_FILE__ ":" PS_LOGF_STRINGIZE(__LINE__) ": "
+# else
+# define PS_LOGF_FILELINE __FILE__ ":" PS_LOGF_STRINGIZE(__LINE__) ": "
+# endif
+#endif
#ifdef PS_NO_LOGF_FILELINE
/* Omit file name and line number information.
This is good for file size and for avoiding leaking details of software
@@ -447,6 +456,11 @@ typedef enum
#define PS_LOGF_STRINGIZE1(psLogf_arg) PS_LOGF_STRINGIZE2(psLogf_arg)
#define PS_LOGF_STRINGIZE2(psLogf_arg) #psLogf_arg
+/* Stringify log levels to constant strings. */
+#define PS_LOGF_LL_STRINGIZE(psLogf_arg) PS_LOGF_LL_STRINGIZE1(psLogf_arg)
+#define PS_LOGF_LL_STRINGIZE1(psLogf_arg) PS_LOGF_LL_STRINGIZE2(psLogf_arg)
+#define PS_LOGF_LL_STRINGIZE2(psLogf_arg) psLogf_##psLogf_arg
+
/* Standard C preprocessor concatenation idiom. */
#define PS_LOGF_CONCATENATE(psLogf_arg1, psLogf_arg2) \
PS_LOGF_CONCATENATE1(psLogf_arg1, psLogf_arg2)
@@ -511,6 +525,31 @@ psLogfSetHookPrintfFunction_t psLogfSetHookPrintf(
} \
} while(0)
+#include "cl_header_end.h"
+
+# else
+/* Without psLogf, direct usage of PS_ macros is not available. */
+#define PS_LOGF_CALL_TRACE(...) do { /* call trace not available */ } while(0)
+#define PS_LOGF_TRACE(...) do { /* trace logging not available */ } while(0)
+#define PS_LOGF_VERBOSE(...) do { /* verbose not available */ } while(0)
+#define PS_LOGF_DEBUG(...) do { /* debug logging not available */ } while(0)
+#define PS_LOGF_INFO(...) do { /* info logging not available */ } while(0)
+#define PS_LOGF_WARNING(...) do { /* warning logging not available */ } while(0)
+#define PS_LOGF_ERROR(...) do { /* error logging not available */ } while(0)
+#define PS_LOGF_FATAL(...) \
+ do { /* fatal error logging not available */ } while(0)
+#define PS_LOGF_CALL_TRACE_LN(...) \
+ do { /* call trace not available */ } while(0)
+#define PS_LOGF_TRACE_LN(...) do { /* trace logging not available */ } while(0)
+#define PS_LOGF_VERBOSE_LN(...) do { /* verbose not available */ } while(0)
+#define PS_LOGF_DEBUG_LN(...) do { /* debug logging not available */ } while(0)
+#define PS_LOGF_INFO_LN(...) do { /* info logging not available */ } while(0)
+#define PS_LOGF_WARNING_LN(...) \
+ do { /* warning logging not available */ } while(0)
+#define PS_LOGF_ERROR_LN(...) do { /* error logging not available */ } while(0)
+#define PS_LOGF_FATAL_LN(...) \
+ do { /* fatal error logging not available */ } while(0)
+
# endif /* PS_NO_LOGF */
#endif /* _h_PS_LOG */
diff --git a/core/psPrnf.h b/core/include/psPrnf.h
similarity index 89%
rename from core/psPrnf.h
rename to core/include/psPrnf.h
index dde5ae0..b05ab02 100644
--- a/core/psPrnf.h
+++ b/core/include/psPrnf.h
@@ -3,7 +3,7 @@
* @version $Format:%h%d$
*
* Extended formatting: Allow complex objects to be printed with
- * printf() style formatting.
+ * Printf() style formatting.
*
* These macros and functions can be used in programs using SafeZone
* and MatrixSSL software or related software components.
@@ -35,6 +35,9 @@
*/
/******************************************************************************/
+#ifndef INCLUDE_GUARD_PSPRNF_H
+#define INCLUDE_GUARD_PSPRNF_H 1
+
#ifndef _h_PS_CORECONFIG
# ifdef MATRIX_CONFIGURATION_INCDIR_FIRST
# include /* Must be first included */
@@ -44,6 +47,7 @@
#endif /* _h_PS_CORECONFIG */
#include "osdep-types.h"
+#include "osdep_stddef.h"
/* Only needs stub psPool_t. */
#ifndef PS_POOL_T_DEFINED
@@ -52,7 +56,7 @@ typedef int32 psPool_t;
#endif
#ifndef _h_PS_PRNF
-#include
+#include "osdep_stdarg.h"
# define _h_PS_PRNF
# ifndef PS_NO_PRNF
# define PS_PRNF_STRUCT_VARIABLE_LENGTH_MEMBER 1
@@ -118,7 +122,7 @@ typedef struct
/** Indefinite size string.
Some functions accept this instead of size as identifier to request determination of size from
- string (using strlen()).
+ string (using Strlen()).
*/
#define PS_SIZE_STR (~(psSizeL_t)0)
@@ -136,6 +140,8 @@ const char *psPrnfStr(psPrnf_t *ctx, const char *str);
const char *psPrnfSStr(psPrnf_t *ctx, const char *str, psSizeL_t len);
const char *psPrnfQStr(psPrnf_t *ctx, const char *str);
const char *psPrnfHex(psPrnf_t *ctx, const unsigned char *hex, psSizeL_t len);
+const char *psPrnfHexPsFree(psPrnf_t *ctx, unsigned char *dec, psSizeL_t len, psPool_t *pool);
+const char *psPrnfDecPsFree(psPrnf_t *ctx, unsigned char *hex, psSizeL_t len, psPool_t *pool, int (*formatter)(const unsigned char *, unsigned long, char *, unsigned long));
const char *psPrnfHex2(psPrnf_t *ctx, const unsigned char *hex, psSizeL_t len);
const char *psPrnfBase64(psPrnf_t *ctx, const unsigned char *octets, psSizeL_t len,
int(*formatter)(const unsigned char *, size_t, const char *, char **));
@@ -276,6 +282,29 @@ char *psAsprnf_(psPool_t *pool, psPrnf_t *ctx, const char *fmt, ...) __attribute
#define PSA_SLMW_HEX(p, n) \
psPrnfHex2(&psPrnfCtx, ((unsigned char *)(p)), (4 * (n)))
+/** MatrixSSL big integer as hexadecimal (no prefix).
+
+ Format arguments (pstm_t *) as a string containing
+ number.
+ Note: Executing this macro requires `pstm.h`.
+*/
+#define PSA_PSTM_HEX(p) \
+ psPrnfHexPsFree(&psPrnfCtx, \
+ pstm_to_unsigned_bin_alloc(NULL, p), \
+ pstm_unsigned_bin_size_nullsafe(p), NULL)
+
+/** MatrixSSL big integer as decimal (no prefix).
+
+ Format arguments (pstm_t *) as a string containing
+ number.
+ Note: Executing this macro requires `pstm.h` and `cl_bu.h`.
+*/
+#define PSA_PSTM_DEC(p) \
+ psPrnfDecPsFree(&psPrnfCtx, \
+ pstm_to_unsigned_bin_alloc(NULL, p), \
+ pstm_unsigned_bin_size_nullsafe(p), NULL, \
+ &CL_BUCBIN_ToDec)
+
/** Extended format big integer as hexadecimal (no prefix).
Format argument (CL_BUC_t *) as a string containing decimal number.
@@ -334,4 +363,7 @@ char *psAsprnf_(psPool_t *pool, psPrnf_t *ctx, const char *fmt, ...) __attribute
# define PS_PRNF_CTX psPrnf_t psPrnfCtx = { NULL, 0 }
# endif
#endif
+
+#endif /* INCLUDE_GUARD_PSPRNF_H */
+
/* end of psPrnf.h */
diff --git a/core/include/psStat.h b/core/include/psStat.h
new file mode 100644
index 0000000..c0c4a1d
--- /dev/null
+++ b/core/include/psStat.h
@@ -0,0 +1,89 @@
+/* psStat.h
+ * Functions for computing misc useful statistics. Work-in-progress.
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2018 INSIDE Secure Oy. All Rights Reserved.
+*
+* The latest version of this code is available at http://www.matrixssl.org
+*
+* This software is open source; 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.
+*
+* This General Public License does NOT permit incorporating this software
+* into proprietary programs. If you are unable to comply with the GPL, a
+* commercial license for this software may be purchased from INSIDE at
+* http://www.insidesecure.com/
+*
+* This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\
+* http://www.gnu.org/copyleft/gpl.html
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_PSSTAT_H
+#define INCLUDE_GUARD_PSSTAT_H
+
+typedef struct
+{
+ int filled;
+ int num_diffs;
+ int num_matches;
+ int first_diff_ix;
+ int last_diff_ix;
+ int num_match_runs;
+ int avg_match_run_len;
+ int num_diff_runs;
+ int avg_diff_run_len;
+ /* Longest common substring (LCSS): */
+ int lcss_start_ix;
+ int lcss_end_ix;
+ int lcss_len;
+ int lcss_freq;
+ /* Longest uncommon substring (LUSS): */
+ int luss_start_ix;
+ int luss_end_ix;
+ int luss_len;
+ int luss_freq;
+ const unsigned char *a;
+ const char *aName;
+ const unsigned char *b;
+ const char *bName;
+ psSizeL_t len;
+} psStatCompByteSeqResult_t;
+
+typedef struct
+{
+ int lcss_max_prefix_len;
+ int luss_max_prefix_len;
+} psStatPrintCompByteSeqResultOpts_t;
+
+/** Compare two byte sequences and compute statistics, such as the
+ number of mismatches, the longest common subsequence, etc.
+ The result can be printed with psPrintCompByteSeqResult. */
+psStatCompByteSeqResult_t psStatCompByteSeq(const unsigned char *a,
+ const char *aName,
+ const unsigned char *b,
+ const char *bName,
+ psSizeL_t len);
+
+/** Print the result of psStatByteSeq. */
+void psStatPrintCompByteSeqResult(psStatCompByteSeqResult_t res,
+ psStatPrintCompByteSeqResultOpts_t *opts);
+
+/** Simple hex dump without extra printouts (c.f. psTraceBytes). */
+void psStatPrintHexSimple(char *resultBuf,
+ psSizeL_t resultBufLen,
+ const unsigned char *bytes,
+ psSizeL_t bytesLen);
+
+#endif /* INCLUDE_GUARD_PSSTAT_H */
+
+/* end of file psStat.h */
diff --git a/core/psUtil.h b/core/include/psUtil.h
similarity index 86%
rename from core/psUtil.h
rename to core/include/psUtil.h
index ea9cf78..8302cbc 100644
--- a/core/psUtil.h
+++ b/core/include/psUtil.h
@@ -36,6 +36,13 @@
*/
/******************************************************************************/
+/* This inclusion guard is for compilers which check existence of
+ inclusion guard. The main part of file is protected via _h_PS_UTIL.
+ The remaining part intentionally takes effect when the file is multiply
+ included. */
+#ifndef INCLUDE_GUARD_PSUTIL_H
+#define INCLUDE_GUARD_PSUTIL_H 1
+
#ifndef _h_PS_UTIL
# define _h_PS_UTIL
@@ -77,6 +84,14 @@
# endif /* __STDC_VERSION__ >= 199901L */
# endif /* __STDC_VERSION__ */
+/* GNU C specific */
+#ifdef __GNUC__
+# define PS_GCC_SPECIFIC(x) x
+#else
+/* Not supported on this compiler. */
+# define PS_GCC_SPECIFIC(x)
+#endif
+
/* Tell compiler a variable is intended that it can be set, but not used.
(The variable is for debugging, future extension or used in some
conditionally disabled/unifdeffed branches of execution). */
@@ -112,8 +127,8 @@
software components, and the definition here is provided as convenience for
software using matrixssl. */
# ifndef psAssert
-# include
-# define psAssert(x) assert(x)
+# include "osdep_assert.h"
+# define psAssert(x) Assert(x)
# endif /* psAssert already defined */
/* produce debug output: This output is directed to standard output.
@@ -122,22 +137,22 @@
software components, and the definition here is provided as convenience for
software using matrixssl. */
# ifndef psTrace
-# include
-# define psPrint(x) printf("%s", (x))
-# define psPrintInt(x, i) printf(x, (i))
-# define psPrintStr(x, s) printf(x, (s))
-# define psPrintPtr(x, p) printf(x, (p))
-# define psTrace(x) printf("%s", (x))
-# define psTraceInt(x, i) printf(x, (i))
-# define psTraceStr(x, s) printf(x, (s))
-# define psTracePtr(x, p) printf(x, (p))
-# define psError(x) fprintf(stderr, "%s", (x))
-# define psErrorInt(x, i) fprintf(stderr, x, (i))
-# define psErrorStr(x, s) fprintf(stderr, (s))
-# define psErrorPtr(x, p) fprintf(stderr, (p))
-# define psPrintf(...) printf(__VA_ARGS__)
-# define psTracef(...) printf(__VA_ARGS__)
-# define psErrorf(...) fprintf(stderr, __VA_ARGS__)
+# include "osdep_stdio.h"
+# define psPrint(x) Printf("%s", (x))
+# define psPrintInt(x, i) Printf(x, (i))
+# define psPrintStr(x, s) Printf(x, (s))
+# define psPrintPtr(x, p) Printf(x, (p))
+# define psTrace(x) Printf("%s", (x))
+# define psTraceInt(x, i) Printf(x, (i))
+# define psTraceStr(x, s) Printf(x, (s))
+# define psTracePtr(x, p) Printf(x, (p))
+# define psError(x) Fprintf(stderr, "%s", (x))
+# define psErrorInt(x, i) Fprintf(stderr, x, (i))
+# define psErrorStr(x, s) Fprintf(stderr, (s))
+# define psErrorPtr(x, p) Fprintf(stderr, (p))
+# define psPrintf(...) Printf(__VA_ARGS__)
+# define psTracef(...) Printf(__VA_ARGS__)
+# define psErrorf(...) Fprintf(stderr, __VA_ARGS__)
# endif
/* Equivalent to sizeof, but returns result in psSize_t type. */
@@ -182,11 +197,11 @@
PS_C99_OR_OLDER(& ((type [constant_length]) { 0 }), \
psMemzeroSR(alloca(sizeof(ptr_name)), sizeof(ptr_name)))
-# include
+# include "osdep_stdlib.h"
/* Allocate specified sized zero initialized item dynamically. */
# define PS_TEMP_ALLOC_ARRAYZ_DYNAMIC(type, ptr_name, constant_length) \
- PS_CPLUSPLUS_CAST(type(*)[constant_length]) calloc(sizeof(ptr_name), 1)
+ PS_CPLUSPLUS_CAST(type(*)[constant_length]) Calloc(sizeof(ptr_name), 1)
/* Allocate specified sized zero initialized item from stack. */
# define PS_TEMP_FREE_ARRAYZ_STACK(ptr_name) \
@@ -194,7 +209,7 @@
/* Allocate specified sized zero initialized item from stack. */
# define PS_TEMP_FREE_ARRAYZ_DYNAMIC(ptr_name) \
- free(psMemzeroSR(ptr_name, sizeof(ptr_name)))
+ Free(psMemzeroSR(ptr_name, sizeof(ptr_name)))
/* Return specified type. */
# define PS_TEMP_RETURN_DUP_STACK(ptr_name, dupfunc) \
@@ -259,16 +274,16 @@ void psFreeN(void *ptr);
/* These are implemented as macros, to allow compiler intrinsics to be
used. */
-# include
+# include "osdep_string.h"
/* Simple C string functions.
Some of the APIs use them via these macros. */
-# define psMemcpy memcpy
-# define psMemmove memmove
-# define psMemset memset
-# define psStrcmp strcmp
-# define psStrncmp strncmp
-# define psStrlen strlen
+# define psMemcpy Memcpy
+# define psMemmove Memmove
+# define psMemset Memset
+# define psStrcmp Strcmp
+# define psStrncmp Strncmp
+# define psStrlen Strlen
PS_EXTERN_C_END
@@ -303,4 +318,8 @@ PS_EXTERN_C_END
PS_TEMP_RETURN_DUP_STACK(ptr_name, dupfunc)
#endif /* PS_TEMP_IS_DYNAMIC */
+#undef INCLUDE_GUARD_PSUTIL_H /* Process this file partially if multiply
+ included. */
+#endif /* INCLUDE_GUARD_PSUTIL_H */
+
/* end of psUtil.h */
diff --git a/core/psbuf.h b/core/include/psbuf.h
similarity index 62%
rename from core/psbuf.h
rename to core/include/psbuf.h
index b766f5a..5b4f99f 100644
--- a/core/psbuf.h
+++ b/core/include/psbuf.h
@@ -35,7 +35,7 @@
# define _h_PS_BUF
# include "coreApi.h"
-# include
+# include "osdep_string.h"
/* API for psBuf initialization and basic usage.*/
void *psBufInit(psPool_t *pool, psBuf_t *buf, size_t capacity);
@@ -59,16 +59,17 @@ int32_t psBufFromData(psPool_t *pool, psBuf_t *buf,
const void *data, size_t len);
-static __inline int psBufEq(const psBuf_t *buf1, const psBuf_t *buf2)
+static inline int psBufEq(const psBuf_t *buf1, const psBuf_t *buf2)
{
return (buf1->end - buf1->start) == (buf2->end - buf2->start) &&
buf1->start != NULL &&
buf2->start != NULL &&
- memcmp(buf1->start, buf2->start, (buf1->end - buf1->start))
+ Memcmp(buf1->start, buf2->start, (buf1->end - buf1->start))
== 0;
}
-static __inline void *psBufAppendChar(psBuf_t *buf, char ch)
+#include
+static inline void *psBufAppendChar(psBuf_t *buf, char ch)
{
void *loc = psBufAppendSize(buf, 1);
@@ -79,7 +80,7 @@ static __inline void *psBufAppendChar(psBuf_t *buf, char ch)
return loc;
}
-static __inline void *psBufPrependChar(psBuf_t *buf, char ch)
+static inline void *psBufPrependChar(psBuf_t *buf, char ch)
{
void *loc = psBufPrependSize(buf, 1);
@@ -94,11 +95,12 @@ static __inline void *psBufPrependChar(psBuf_t *buf, char ch)
void *psDynBufInit(psPool_t *pool, psDynBuf_t *db, size_t capacity);
void psDynBufUninit(psDynBuf_t *db);
void *psDynBufDetach(psDynBuf_t *db, size_t *len_p);
+void *psDynBufDetachPsSize(psDynBuf_t *db, psSize_t *len_p);
void *psDynBufAppendSize(psDynBuf_t *db, size_t sz);
void psDynBufReservePrepend(psDynBuf_t *db, size_t sz);
void *psDynBufPrependSize(psDynBuf_t *db, size_t sz);
-static __inline void *psDynBufAppendChar(psDynBuf_t *db, char ch)
+static inline void *psDynBufAppendChar(psDynBuf_t *db, char ch)
{
void *loc = psDynBufAppendSize(db, 1);
@@ -109,11 +111,25 @@ static __inline void *psDynBufAppendChar(psDynBuf_t *db, char ch)
return loc;
}
+static __inline void *psDynBufAppendByte(psDynBuf_t *db, unsigned char ch)
+{
+ void *loc = psDynBufAppendSize(db, 1);
+
+ if (loc)
+ {
+ *(unsigned char *) loc = ch;
+ }
+ return loc;
+}
+
+void *psDynBufAppendAsBigEndianUint16(psDynBuf_t *db, uint16_t val);
+void *psDynBufAppendAsBigEndianUint32(psDynBuf_t *db, uint32_t val);
+
void *psDynBufAppendUtf8(psDynBuf_t *db, int chr);
void *psDynBufAppendUtf16(psDynBuf_t *db, int chr);
void *psDynBufAppendUtf32(psDynBuf_t *db, int chr);
-static __inline void *psDynBufPrependChar(psDynBuf_t *db, char ch)
+static inline void *psDynBufPrependChar(psDynBuf_t *db, char ch)
{
void *loc = psDynBufPrependSize(db, 1);
@@ -124,48 +140,63 @@ static __inline void *psDynBufPrependChar(psDynBuf_t *db, char ch)
return loc;
}
-static __inline void *psDynBufAppendStr(psDynBuf_t *db, const char *s)
+static inline void *psDynBufAppendStr(psDynBuf_t *db, const char *s)
{
- size_t len = s ? strlen(s) : 0;
+ size_t len = s ? Strlen(s) : 0;
void *loc = psDynBufAppendSize(db, len);
if (loc)
{
- memcpy(loc, s, len);
+ Memcpy(loc, s, len);
}
return loc;
}
-static __inline void *psDynBufPrependStr(psDynBuf_t *db, const char *s)
+static inline void *psDynBufPrependStr(psDynBuf_t *db, const char *s)
{
- size_t len = s ? strlen(s) : 0;
+ size_t len = s ? Strlen(s) : 0;
void *loc = psDynBufPrependSize(db, len);
if (loc)
{
- memcpy(loc, s, len);
+ Memcpy(loc, s, len);
}
return loc;
}
-static __inline void *psDynBufAppendOctets(psDynBuf_t *db, const void *data,
+static inline void *psDynBufAppendOctets(psDynBuf_t *db, const void *data,
size_t len)
{
void *loc = psDynBufAppendSize(db, len);
if (loc)
{
- memcpy(loc, data, len);
+ Memcpy(loc, data, len);
}
return loc;
}
-static __inline void *psDynBufAppendBuf(psDynBuf_t *db, const psBuf_t *b)
+static inline void *psDynBufAppendOctetNTimes(psDynBuf_t *db,
+ uint8_t octet,
+ size_t n)
+{
+ size_t i;
+ void *loc;
+
+ for (i = 0; i < n; i++)
+ {
+ loc = psDynBufAppendOctets(db, &octet, 1);
+ }
+
+ return loc;
+}
+
+static inline void *psDynBufAppendBuf(psDynBuf_t *db, const psBuf_t *b)
{
return psDynBufAppendOctets(db, b->start, b->end - b->start);
}
-static __inline void *psDynBufAppendParseBuf(psDynBuf_t *db,
+static inline void *psDynBufAppendParseBuf(psDynBuf_t *db,
const psParseBuf_t *pb)
{
if (!pb || pb->err)
@@ -175,8 +206,8 @@ static __inline void *psDynBufAppendParseBuf(psDynBuf_t *db,
}
return psDynBufAppendBuf(db, &(pb->buf));
}
-
-static __inline void *psDynBufIncorporateDynBuf(psDynBuf_t *db, psDynBuf_t *db2)
+
+static inline void *psDynBufIncorporateDynBuf(psDynBuf_t *db, psDynBuf_t *db2)
{
size_t len;
void *data = psDynBufDetach(db2, &len);
@@ -202,10 +233,10 @@ void *psDynBufSubFinish(psDynBuf_t *sub);
# define psDynBufAppendStrf(ps_dyn_buf_p, ...) \
do { \
char tmp; \
- size_t len = 1 + snprintf(&tmp, 1, __VA_ARGS__); \
+ size_t len = 1 + Snprintf(&tmp, 1, __VA_ARGS__); \
char *target = psDynBufAppendSize((ps_dyn_buf_p), len); \
if (target) { \
- snprintf(target, len, __VA_ARGS__); \
+ Snprintf(target, len, __VA_ARGS__); \
(ps_dyn_buf_p)->buf.end -= 1; \
} \
} while (0)
@@ -242,17 +273,17 @@ char *psDynBufAppendAsn1Oid(psDynBuf_t *db,
char *psDynBufBeginConstructedTag(psDynBuf_t *db, psDynBuf_t *sub);
char *psDynBufEndConstructedTag(psDynBuf_t *sub, unsigned char tag);
-static __inline char *psDynBufBeginSequence(psDynBuf_t *db, psDynBuf_t *sub)
+static inline char *psDynBufBeginSequence(psDynBuf_t *db, psDynBuf_t *sub)
{
return psDynBufBeginConstructedTag(db, sub);
}
-static __inline char *psDynBufEndSequence(psDynBuf_t *sub)
+static inline char *psDynBufEndSequence(psDynBuf_t *sub)
{
return psDynBufEndConstructedTag(sub, 0x30);
}
-static __inline int32_t psDynBufDetachBuf(psDynBuf_t *db, psBuf_t *target)
+static inline int32_t psDynBufDetachBuf(psDynBuf_t *db, psBuf_t *target)
{
size_t sz;
void *buf;
@@ -272,12 +303,33 @@ static __inline int32_t psDynBufDetachBuf(psDynBuf_t *db, psBuf_t *target)
return PS_SUCCESS;
}
+/* Append a TLS representation language vector.
+
+ The minLen and maxLen arguments are the minimum and maximum
+ vector lengths. They must be must be taken from the vector
+ specification. For example, "opaque key_exchange<1..2^16-1>"
+ would be encoded with minLen = 1, maxLen = (1 << 16) - 1.
+
+ @param[out] db DynBuf where to append the vector.
+ @param[in] minLen Minimum vector length, as defined by spec.
+ @param[in] maxLen Maximum vector length, as defined by spec.
+ Maximum vector length in the TLS specification is currently
+ 2^24 - 1. This function checks that maxLen does not exceed this.
+ @param[in] data The data to encode into the vector.
+ @param[in] len Number of data octets to encode.
+ */
+int32_t psDynBufAppendTlsVector(psDynBuf_t *db,
+ size_t minLen,
+ size_t maxLen,
+ const unsigned char *data,
+ size_t len);
+
/* Start parsing static data using psParseBuf_t. */
int32_t psParseBufFromStaticData(psParseBuf_t *pb,
const void *data, size_t len);
/* Check if there is sufficient data to parse left. */
-static __inline int psParseCanRead(const psParseBuf_t *pb, size_t nbytes)
+static inline int psParseCanRead(const psParseBuf_t *pb, size_t nbytes)
{
size_t bytes_readable;
@@ -290,6 +342,191 @@ static __inline int psParseCanRead(const psParseBuf_t *pb, size_t nbytes)
return bytes_readable >= nbytes;
}
+static inline size_t psParseGetRemainingLen(const psParseBuf_t *pb)
+{
+ size_t bytes_readable;
+
+ if (pb->err)
+ {
+ return 0;
+ }
+
+ bytes_readable = pb->buf.end - pb->buf.start;
+ return bytes_readable;
+}
+
+static __inline int psParseTlsRecordHeader(psParseBuf_t *pb,
+ unsigned char *type,
+ unsigned char *majVer,
+ unsigned char *minVer,
+ unsigned short *len)
+{
+ int can_read;
+
+ can_read = psParseCanRead(pb, 5);
+ if (!can_read)
+ {
+ return 0;
+ }
+
+ *type = (unsigned char) *(pb->buf.start); pb->buf.start++;
+ *majVer = (unsigned char) *(pb->buf.start); pb->buf.start++;
+ *minVer = (unsigned char) *(pb->buf.start); pb->buf.start++;
+ *len = (unsigned char) *(pb->buf.start); pb->buf.start++;
+ *len <<= 8;
+ *len += (unsigned char) *(pb->buf.start); pb->buf.start++;
+
+ return 5;
+}
+
+static __inline int psParseTlsHandshakeHeader(psParseBuf_t *pb,
+ unsigned char *type,
+ unsigned int *len)
+{
+ int can_read;
+
+ can_read = psParseCanRead(pb, 4);
+ if (!can_read)
+ {
+ return 0;
+ }
+
+ *type = (unsigned char) *(pb->buf.start); pb->buf.start++;
+ *len = (unsigned char) *(pb->buf.start); pb->buf.start++;
+ *len <<= 8;
+ *len += (unsigned char) *(pb->buf.start); pb->buf.start++;
+ *len <<= 8;
+ *len += (unsigned char) *(pb->buf.start); pb->buf.start++;
+
+ return 4;
+}
+
+static __inline int psParseOctet(psParseBuf_t *pb,
+ unsigned char *octet)
+{
+ if (!psParseCanRead(pb, 1))
+ {
+ return 0;
+ }
+
+ *octet = (unsigned char)*pb->buf.start; pb->buf.start++;
+
+ return 1;
+}
+
+int psParseTlsVariableLengthVec(const unsigned char *start,
+ const unsigned char *end,
+ psSizeL_t minLen,
+ psSizeL_t maxLen,
+ psSizeL_t *vecDataLen);
+
+/** Maps to psParseTlsVariableLengthVec. */
+static __inline psResSize_t psParseBufParseTlsVector(psParseBuf_t *pb,
+ psSizeL_t minLen,
+ psSizeL_t maxLen,
+ psSizeL_t *vecDataLen)
+{
+ int rc;
+
+ if (pb->err)
+ {
+ return PS_FAILURE;
+ }
+
+ rc = psParseTlsVariableLengthVec(pb->buf.start,
+ pb->buf.end,
+ minLen,
+ maxLen,
+ vecDataLen);
+ if (rc < 0)
+ {
+ return rc;
+ }
+ /* rc == number of length octets. */
+
+ pb->buf.start += rc;
+
+ return rc;
+}
+
+static __inline int psParseBufTryParseOctets(psParseBuf_t *pb,
+ size_t num_octets,
+ unsigned char *parsed_octets)
+{
+ size_t i;
+
+ if (!psParseCanRead(pb, num_octets))
+ {
+ return 0;
+ }
+
+ for (i = 0; i < num_octets; i++)
+ {
+ parsed_octets[i] = (unsigned char)*pb->buf.start;
+ pb->buf.start++;
+ }
+
+ return num_octets;
+}
+
+static __inline int psParseBufTryParseBigEndianUint16(psParseBuf_t *pb,
+ uint16_t *value)
+{
+ uint16_t val = 0;
+
+ if (!psParseCanRead(pb, 2))
+ {
+ return 0;
+ }
+
+ val = (*pb->buf.start << 8); pb->buf.start++;
+ val |= *pb->buf.start; pb->buf.start++;
+
+ *value = val;
+
+ return 2;
+}
+
+static __inline int psParseBufTryParseBigEndianUint32(psParseBuf_t *pb,
+ uint32_t *value)
+{
+ uint32_t val = 0;
+
+ if (!psParseCanRead(pb, 4))
+ {
+ return 0;
+ }
+
+ val = (*pb->buf.start << 24); pb->buf.start++;
+ val |= (*pb->buf.start << 16); pb->buf.start++;
+ val |= (*pb->buf.start << 8); pb->buf.start++;
+ val |= *pb->buf.start; pb->buf.start++;
+
+ *value = val;
+
+ return 4;
+}
+
+
+static __inline int psParseTryForward(psParseBuf_t *pb,
+ size_t num_bytes)
+{
+ if (!psParseCanRead(pb, num_bytes))
+ {
+ return 0;
+ }
+
+ pb->buf.start += num_bytes;
+
+ return num_bytes;
+}
+
+static __inline void psParseForward(psParseBuf_t *pb,
+ size_t num_bytes)
+{
+ pb->buf.start += num_bytes;
+}
+
/* Check if there is sufficient data to parse left. */
PSPUBLIC int psParseBufCanReadUtf8(const psParseBuf_t *pb);
@@ -386,5 +623,25 @@ int32_t psParseBufCopyUntilByte(psParseBuf_t *pb, unsigned char stopbyte,
parsing position. */
int32_t psParseBufCopyN(const psParseBuf_t *pb, size_t reqLen,
unsigned char *target, size_t *targetlen);
+
+static inline
+int32_t psParseBufCopyNPsSize(const psParseBuf_t *pb,
+ psSize_t reqLen,
+ unsigned char *target,
+ psSize_t *targetlen)
+{
+ size_t tLen;
+ int32_t rc;
+
+ tLen = *targetlen;
+ rc = psParseBufCopyN(pb, reqLen, target, &tLen);
+ if (tLen > (size_t)PS_SIZE_MAX)
+ {
+ return PS_LIMIT_FAIL;
+ }
+ *targetlen = tLen;
+
+ return rc;
+}
#endif /* _h_PS_BUF */
/* end of file psbuf.h */
diff --git a/core/include/pscompilerdep.h b/core/include/pscompilerdep.h
new file mode 100644
index 0000000..867fa11
--- /dev/null
+++ b/core/include/pscompilerdep.h
@@ -0,0 +1,114 @@
+/**
+ * @file pscompilerdep.h
+ * @version $Format:%h%d$
+ *
+ * Compiler Pragmas/Diagnostics Capabilities Abstraction.
+ */
+/*
+ * Copyright (c) 2018 INSIDE Secure Corporation
+ * All Rights Reserved
+ *
+ * The latest version of this code is available at http://www.matrixssl.org
+ *
+ * This software is open source; 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.
+ *
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
+ *
+ * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+/******************************************************************************/
+
+#ifndef _h_PS_COMPILERDEP
+# define _h_PS_COMPILERDEP
+
+/* Compiler detection. */
+
+/* Detect GCC 4.x series. */
+# ifdef __GNUC__
+# if __GNUC__ == 4
+# define __GNUC4__ /* 4.x series GNU C. These default to C89 standard,
+ which has to be considered in some of the code. */
+# endif
+/* For all GCC versions, provide version as single number for easier range
+ matching. */
+# define __GCC_VERSION ((__GNUC__ * 1000000) | \
+ (__GNUC_MINOR__ * 1000) | \
+ (__GNUC_PATCHLEVEL__))
+# else /* __GNUC__ */
+# define __GCC_VERSION 0 /* No GCC. */
+# endif
+
+/* Detect ARM DS-5 compiler. */
+# ifdef __ARMCC_VERSION
+# if __ARMCC_VERSION < 6000000
+# define __ARMCC5 /* armcc prior 6.0 (not clang-based) */
+# undef inline
+# define inline __inline /* Use compiler specific inline keyword. */
+# endif
+# endif /* __ARMCC_VERSION */
+
+/* Mark API function as deprecated. */
+#define PSDEPRECATED /* the following function is deprecated. */
+
+/* Control for diagnostics on deprecated functions.
+ PSDEPRECATED_START ... PSDEPRECATED_END allows section where
+ deprected functions are allowed. */
+#ifdef __GNUC__
+#if ( __GNUC__ == 4 && __GNUC_MINOR__ >= 8 ) || __GNUC__ >= 5
+#define PSDEPRECATED_START /* Omit deprecated warnings */ \
+ _Pragma( "GCC diagnostic push" ) \
+ _Pragma( "GCC diagnostic ignored \"-Wdeprecated-declarations\"" )
+#define PSDEPRECATED_END /* end section with omitted warnings */ \
+ _Pragma( "GCC diagnostic pop" )
+#endif
+#endif
+
+/* Mark API function as deprecated, and warn when it is used if compiler
+ provides the capability. This only happens on GCC 4.8 or later. */
+#ifdef PSDEPRECATED_START
+#define PSDEPRECATED_WARN __attribute__((__deprecated__))
+#else
+#define PSDEPRECATED_WARN /* silently ignored on compilers
+ not providing PSDEPRECATED_START.
+ Note: Header will still advice function is
+ deprecated. */
+#endif
+
+/* If compiling source files that intentionally use deprecated functions,
+ omit warnings. (For instance implementation may use deprecated functions
+ internally as components of implementation.) */
+#ifdef CONTAINS_DEPRECATED_FUNCTION_CALLS
+#undef PSDEPRECATED_WARN
+#define PSDEPRECATED_WARN PSDEPRECATED
+#endif /* CONTAINS_DEPRECATED_FUNCTION_CALLS */
+
+#ifndef PSDEPRECATED_START
+#define PSDEPRECATED_START /* this code may call deprecated functions. */
+#define PSDEPRECATED_END /* end of section. */
+#endif
+
+#ifdef __GNUC__
+/* Mark intentionally unused functions. */
+#define PSFUNC_UNUSED __attribute__((__unused__))
+#else
+/* Mark intentionally unused functions (can used compiler specific
+ directive) here. */
+#define PSFUNC_UNUSED /* __attribute__((__unused__)) */
+#endif
+
+
+#endif /* _h_PS_COMPILERDEP */
+
diff --git a/core/include/pscompilerwarning.h b/core/include/pscompilerwarning.h
new file mode 100644
index 0000000..043bfe1
--- /dev/null
+++ b/core/include/pscompilerwarning.h
@@ -0,0 +1,86 @@
+/**
+ * @file pscompilerwarning.h
+ * @version $Format:%h%d$
+ *
+ * Compiler Warning: Similar to #warning "XXX", but with handling
+ * to support as many compilers as possible.
+ */
+/*
+ * Copyright (c) 2018 INSIDE Secure Corporation
+ * All Rights Reserved
+ *
+ * The latest version of this code is available at http://www.matrixssl.org
+ *
+ * This software is open source; 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.
+ *
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
+ *
+ * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+/******************************************************************************/
+
+/* Use multiple inclusion allowed pattern. */
+#ifndef PSCOMPILER_WARNING_INCLUDED
+# define PSCOMPILER_WARNING_INCLUDED 1
+
+# ifndef WARNING_MESSAGE
+# error "Preprocessor WARNING_MESSAGE is not defined."
+# error "Usage: #define WARNING_MESSAGE \"Warning Message.\"\n#include \"pscompilerwarning.h\""
+# endif
+
+/* Get compiler version if not known. */
+# ifndef __GCC_VERSION
+# include "pscompilerdep.h"
+# endif /* __GCC_VERSION */
+
+/* Detect common compilers with support for #warning. */
+# if defined(__GNUC__) || defined(_ARMCC5)
+# ifndef COMPILER_CAN_DO_WARNING
+# define COMPILER_CAN_DO_WARNING 1
+# endif /* COMPILER_CAN_DO_WARNING */
+# endif /* for compilers with #warning support. */
+
+/* Default branches for for common compile time warnings. */
+# if defined WARNING_MESSAGE_DEFAULT_KEY && defined COMPILER_CAN_DO_WARNING
+# warning "DO NOT USE THESE DEFAULT KEYS IN PRODUCTION ENVIRONMENTS."
+/* Use the common #pragma message syntax for producing warnings. */
+# elif !defined COMPILER_DOES_NOT_SUPPORT_PRAGMA_MESSAGE
+# define PSCOMPILERWARNING_STRING_(m_arg_) #m_arg_
+# define PSCOMPILERWARNING_STRING(m_arg_) PSCOMPILERWARNING_STRING_(m_arg_)
+# ifdef _MSC_VER
+# pragma message("WARNING: " PSCOMPILERWARNING_STRING(WARNING_MESSAGE))
+# elif defined __ARMCC5
+/* We produce the warning with #warning, but the message will unfortunately
+ not be able to inline WARNING_MESSAGE with this compiler. */
+# warning "Source file issued warning messages. See the source file for details."
+# else
+/* Produce a warning in a compiler specific way. */
+# endif
+# else
+ /* Compiler with support for generic pragma message. */
+# pragma message "WARNING: " PSCOMPILERWARNING_STRING(WARNING_MESSAGE)
+# endif
+
+/* Undefine the message for next use. */
+# undef PSCOMPILERWARNING_STRING_
+# undef PSCOMPILERWARNING_STRING
+
+# undef WARNING_MESSAGE
+# undef WARNING_MESSAGE_DEFAULT_KEY
+
+/* Allow multiple inclusion. */
+# undef PSCOMPILER_WARNING_INCLUDED
+#endif /* PSCOMPILER_WARNING_INCLUDED */
diff --git a/core/list.h b/core/include/pslist.h
similarity index 95%
rename from core/list.h
rename to core/include/pslist.h
index bcca563..2966b96 100644
--- a/core/list.h
+++ b/core/include/pslist.h
@@ -1,11 +1,11 @@
/**
- * @file list.h
+ * @file pslist.h
* @version $Format:%h%d$
*
* List utilities.
*/
/*
- * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) 2013-2018 INSIDE Secure Corporation
* Copyright (c) PeerSec Networks, 2002-2011
* All Rights Reserved
*
@@ -32,8 +32,10 @@
*/
/******************************************************************************/
-#ifndef _h_PS_COREUTIL
-# define _h_PS_COREUTIL
+#ifndef _h_PS_LIST
+# define _h_PS_LIST
+
+#include "osdep-types.h"
/********************************** Defines ***********************************/
/*
@@ -59,7 +61,7 @@
*
* Insert *pMyFoo after the head:
* foo *pMyFoo;
- * pMyFoo = malloc(sizeof(foo));
+ * pMyFoo = Malloc(sizeof(foo));
* DLListInsertHead(&FooListHead, &pMyFoo->List);
*
* Do the same but place at tail:
@@ -88,7 +90,7 @@
* pList = DLListGetHead(&FooListHead);
* pMyFoo = DLListGetContainer(pList, foo, List);
* DestroyFoo(pMyFoo);
- * free(pMyFoo);
+ * Free(pMyFoo);
* }
*/
typedef struct _DLListEntry
@@ -165,6 +167,6 @@ typedef struct psList
psSize_t len;
} psList_t;
-#endif /* _h_PS_COREUTIL */
+#endif /* _h_PS_LIST */
/******************************************************************************/
diff --git a/core/psmalloc.h b/core/include/psmalloc.h
similarity index 90%
rename from core/psmalloc.h
rename to core/include/psmalloc.h
index 9b09e11..5bab2ab 100644
--- a/core/psmalloc.h
+++ b/core/include/psmalloc.h
@@ -56,19 +56,19 @@
/*
Native memory routines
*/
-# include /* malloc, free, etc... */
+# include "osdep_stdlib.h"
# define MAX_MEMORY_USAGE 0
# define psOpenMalloc() 0
# define psCloseMalloc()
# define psDefineHeap(A, B)
# define psAddPoolCache(A, B)
-# define psMalloc(A, B) malloc(B)
-# define psCalloc(A, B, C) calloc(B, C)
-# define psMallocNoPool malloc
-# define psRealloc(A, B, C) realloc(A, B)
-# define psFree(A, B) free(A)
-# define psFreeNoPool free
+# define psMalloc(A, B) Malloc(B)
+# define psCalloc(A, B, C) Calloc(B, C)
+# define psMallocNoPool Malloc
+# define psRealloc(A, B, C) Realloc(A, B)
+# define psFree(A, B) Free(A)
+# define psFreeNoPool Free
#ifndef PS_POOL_T_DEFINED
#define PS_POOL_T_DEFINED
diff --git a/core/psnet.h b/core/include/psnet.h
similarity index 90%
rename from core/psnet.h
rename to core/include/psnet.h
index 62ae65c..0e4e84d 100644
--- a/core/psnet.h
+++ b/core/include/psnet.h
@@ -4,21 +4,44 @@
*/
/*****************************************************************************
-* Copyright (c) 2007-2017 INSIDE Secure Oy. All Rights Reserved.
+* Copyright (c) 2007-2018 INSIDE Secure Oy. All Rights Reserved.
*
-* This confidential and proprietary software may be used only as authorized
-* by a licensing agreement from INSIDE Secure.
+* The latest version of this code is available at http://www.matrixssl.org
*
-* The entire notice above must be reproduced on all authorized copies that
-* may only be made to the extent permitted by a licensing agreement from
-* INSIDE Secure.
+* This software is open source; 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.
+*
+* This General Public License does NOT permit incorporating this software
+* into proprietary programs. If you are unable to comply with the GPL, a
+* commercial license for this software may be purchased from INSIDE at
+* http://www.insidesecure.com/
+*
+* This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\
+* http://www.gnu.org/copyleft/gpl.html
*****************************************************************************/
#ifndef INCLUDE_GUARD_PSNET_H
-#define INCLUDE_GUARD_PSNET_H
+# define INCLUDE_GUARD_PSNET_H
+
+# ifdef MATRIX_CONFIGURATION_INCDIR_FIRST
+# include /* Must be first included */
+# else
+# include "coreConfig.h" /* Must be first included */
+# endif
+
+# ifdef USE_PS_NETWORKING
+# include "osdep_stddef.h"
+# include "osdep_unistd.h"
+# endif /* USE_PS_NETWORKING */
-#include
-#include
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/core/include/psunreachable_begin.h b/core/include/psunreachable_begin.h
new file mode 100644
index 0000000..0449af7
--- /dev/null
+++ b/core/include/psunreachable_begin.h
@@ -0,0 +1,42 @@
+/**
+ * @file pscompilerdep.h
+ * @version $Format:%h%d$
+ *
+ * Mark unreachable code.
+ */
+/*
+ * Copyright (c) 2018 INSIDE Secure Corporation
+ * All Rights Reserved
+ *
+ * The latest version of this code is available at http://www.matrixssl.org
+ *
+ * This software is open source; 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.
+ *
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
+ *
+ * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+/******************************************************************************/
+
+#include "pscompilerdep.h"
+
+/* Tell compiler it is ok code appears unreachable. */
+
+#ifdef __ARMCC5
+
+#pragma push
+#pragma diag_suppress 111
+#endif
diff --git a/core/include/psunreachable_end.h b/core/include/psunreachable_end.h
new file mode 100644
index 0000000..cfb89a7
--- /dev/null
+++ b/core/include/psunreachable_end.h
@@ -0,0 +1,40 @@
+/**
+ * @file pscompilerdep.h
+ * @version $Format:%h%d$
+ *
+ * Mark unreachable code.
+ */
+/*
+ * Copyright (c) 2018 INSIDE Secure Corporation
+ * All Rights Reserved
+ *
+ * The latest version of this code is available at http://www.matrixssl.org
+ *
+ * This software is open source; 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.
+ *
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
+ *
+ * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+/******************************************************************************/
+
+#include "pscompilerdep.h"
+
+/* End unreachable. */
+
+#ifdef __ARMCC5
+#pragma pop
+#endif
diff --git a/core/include/public_defs.h b/core/include/public_defs.h
new file mode 100644
index 0000000..4677bdf
--- /dev/null
+++ b/core/include/public_defs.h
@@ -0,0 +1,125 @@
+/* public_defs.h
+ *
+ * Description: See below.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2007-2016 INSIDE Secure Oy. All Rights Reserved.
+*
+* The latest version of this code is available at http://www.matrixssl.org
+*
+* This software is open source; 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.
+*
+* This General Public License does NOT permit incorporating this software
+* into proprietary programs. If you are unable to comply with the GPL, a
+* commercial license for this software may be purchased from INSIDE at
+* http://www.insidesecure.com/
+*
+* This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\
+* http://www.gnu.org/copyleft/gpl.html
+*****************************************************************************/
+
+/*
+ This header provides public definitions required by the SafeZone
+ Software Modules. The definitions are considered public, because
+ they are required by the public API headers.
+
+ - C99 exact-width integer types, e.g. uint32_t
+ - C99 Boolean
+
+ This particular header should is used for building on basic
+ development platforms that are Linux and Win32.
+
+ */
+
+#ifndef INCLUDE_GUARD_PUBLIC_DEFS_H
+#define INCLUDE_GUARD_PUBLIC_DEFS_H
+
+/* Detect compiler and include compiler specific macros. */
+#include "pscompilerdep.h"
+
+#if defined(WIN32)
+
+typedef signed char int8_t;
+typedef signed short int16_t;
+typedef signed int int32_t;
+typedef signed long long int64_t;
+
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+typedef unsigned long long uint64_t;
+
+typedef uint32_t size_t;
+typedef uint32_t uintptr_t;
+
+typedef uint8_t bool;
+
+# define true 1
+# define false 0
+
+# define INT8_MIN (-128)
+# define INT8_MAX (127)
+
+# define INT16_MIN (-32768)
+# define INT16_MAX (32767)
+
+# define INT32_MIN (-2147483647 - 1)
+# define INT32_MAX (2147483647)
+
+# define INT64_MIN (-9223372036854775808LL)
+# define INT64_MAX (9223372036854775807LL)
+# define UINT64_MAX (18446744073709551615ULL)
+
+# define UINT8_MAX (255)
+
+# define UINT16_MAX (65535)
+
+# define UINT32_MAX (4294967295)
+
+# define restrict
+
+#elif (defined(__KERNEL__))
+
+/* Kernel module build (for linux)
+ This build does not use the usual osdep_*.h. */
+
+# include
+# include
+
+/* Limits for types */
+# define INT8_MIN (-128)
+# define INT8_MAX (127)
+# define INT16_MIN (-32768)
+# define INT16_MAX (32767)
+# define INT32_MIN (-2147483647 - 1)
+# define INT32_MAX (2147483647)
+# define INT64_MIN (-9223372036854775807LL - 1)
+# define INT64_MAX (9223372036854775807LL)
+# define UINT8_MAX (255)
+# define UINT16_MAX (65535)
+# define UINT32_MAX (4294967295U)
+# define UINT64_MAX (18446744073709551615ULL)
+
+#elif (defined(__GNUC__) || defined(__CC_ARM))
+
+# include "osdep_stdint.h" /* exact width integers */
+# include "osdep_stdbool.h" /* Boolean */
+# include "osdep_stddef.h" /* offsetof, size_t */
+
+#else
+# error Unsupported platform
+#endif
+
+#endif /* Include guard */
+
+/* end of file public_defs.h */
diff --git a/core/include/runtime.h b/core/include/runtime.h
new file mode 100644
index 0000000..0ea1dbc
--- /dev/null
+++ b/core/include/runtime.h
@@ -0,0 +1,46 @@
+
+#ifndef sodium_runtime_H
+#define sodium_runtime_H
+
+#include "export.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+SODIUM_EXPORT
+int SLSodium_runtime_has_neon(void);
+
+SODIUM_EXPORT
+int SLSodium_runtime_has_sse2(void);
+
+SODIUM_EXPORT
+int SLSodium_runtime_has_sse3(void);
+
+SODIUM_EXPORT
+int SLSodium_runtime_has_ssse3(void);
+
+SODIUM_EXPORT
+int SLSodium_runtime_has_sse41(void);
+
+SODIUM_EXPORT
+int SLSodium_runtime_has_avx(void);
+
+SODIUM_EXPORT
+int SLSodium_runtime_has_avx2(void);
+
+SODIUM_EXPORT
+int SLSodium_runtime_has_pclmul(void);
+
+SODIUM_EXPORT
+int SLSodium_runtime_has_aesni(void);
+
+/* ------------------------------------------------------------------------- */
+
+int SLSodium_runtime_get_cpu_features(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/core/include/sfzcl/sfzclbase64.h b/core/include/sfzcl/sfzclbase64.h
new file mode 100644
index 0000000..fa5eb9d
--- /dev/null
+++ b/core/include/sfzcl/sfzclbase64.h
@@ -0,0 +1,77 @@
+/* sfzclbase64.h
+
+ Functions to convert to and from base64 format.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2006-2016 INSIDE Secure Oy. All Rights Reserved.
+*
+* The latest version of this code is available at http://www.matrixssl.org
+*
+* This software is open source; 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.
+*
+* This General Public License does NOT permit incorporating this software
+* into proprietary programs. If you are unable to comply with the GPL, a
+* commercial license for this software may be purchased from INSIDE at
+* http://www.insidesecure.com/
+*
+* This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+* http://www.gnu.org/copyleft/gpl.html
+*****************************************************************************/
+
+#ifndef SFZCLBASE64_H
+#define SFZCLBASE64_H
+
+/** Convert data from base64 format to binary.
+
+ @return
+ Returns xmallocated data buffer and length in buf_len.
+
+ */
+unsigned char *sfzcl_base64_to_buf(const unsigned char *str, size_t *buf_len);
+
+/** Remove unneeded whitespace (everything that is not in base64!).
+
+ If len is 0, use Strlen(str) to get length of data.
+
+ @return
+ Returns new xmallocated string containing the string.
+
+ */
+unsigned char *sfzcl_base64_remove_whitespace(const unsigned char *str,
+ size_t len);
+
+/** Removes headers/footers (and other crud) before and after the
+ base64-encoded data.
+
+ Will not modify the contents of str.
+
+ @param str
+ Pointer to the string.
+
+ @param len
+ The length of the string.
+
+ @param start_ret
+ Starting index of the base64 data.
+
+ @param end_ret
+ Ending index of the base64 data.
+
+ @return
+ Returns TRUE if successful. In case of an error, returns FALSE.
+
+ */
+bool sfzcl_base64_remove_headers(const unsigned char *str, size_t len,
+ size_t *start_ret, size_t *end_ret);
+
+#endif /* SFZCLBASE64_H */
diff --git a/core/include/sfzcl/sfzclbuffer.h b/core/include/sfzcl/sfzclbuffer.h
new file mode 100644
index 0000000..9c75382
--- /dev/null
+++ b/core/include/sfzcl/sfzclbuffer.h
@@ -0,0 +1,140 @@
+/* sfzclbuffer.h
+
+ Description:
+ Code for manipulating variable-size buffers where you can
+ easily append data and consume it from either end. Routines
+ with prefix sfzcl_xbuffer will call sfzcl_fatal (thus not
+ returning) if they fail to obtain memory.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2006-2016 INSIDE Secure Oy. All Rights Reserved.
+*
+* The latest version of this code is available at http://www.matrixssl.org
+*
+* This software is open source; 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.
+*
+* This General Public License does NOT permit incorporating this software
+* into proprietary programs. If you are unable to comply with the GPL, a
+* commercial license for this software may be purchased from INSIDE at
+* http://www.insidesecure.com/
+*
+* This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+* http://www.gnu.org/copyleft/gpl.html
+*****************************************************************************/
+
+#ifndef SFZCLBUFFER_H
+#define SFZCLBUFFER_H
+
+typedef enum
+{
+ SFZCL_BUFFER_OK = 0,
+ SFZCL_BUFFER_ERROR
+} SfzclBufferStatus;
+
+/* This is buffer record. Even if its contents are visible here, one
+ should use the function interface to access them. The content is
+ visible here only to allow allocation from the stack. */
+typedef struct SfzclBufferRec
+{
+ unsigned char *buf; /* SfzclBuffer for data. */
+ size_t offset; /* Offset of first byte containing data. */
+ size_t end; /* Offset of last byte containing data. */
+ size_t alloc; /* Number of bytes allocated for data. */
+ /* The `dynamic' flag tells whether or not this struct is allocated
+ by a call to `SPAL_Memory_Alloc', in which case `dynamic' is TRUE, or
+ whether this struct is allocated from stack, in a global
+ variable, or inside another heap-allocated object, in which case
+ the `dynamic' flag is FALSE. It is used as a sanity check. */
+ bool dynamic;
+ /* The `borrowed' flag is TRUE if and only if the `buf' is memory
+ managed by this struct. This is the default, but it is possible to
+ use `sfzcl_buffer_wrap' to wrap a SfzclBuffer around given memory, in
+ which case we shall not resize the buf. */
+ bool borrowed;
+ uint16_t size_index; /* Index to a table giving the size of the
+ buffer in bytes. */
+} *SfzclBuffer, SfzclBufferStruct;
+
+/* Allocates and initializes a new buffer structure. */
+
+SfzclBuffer sfzcl_buffer_allocate(void);
+/* Zeroes and frees any memory used by the buffer and its data structures. */
+
+void sfzcl_buffer_free(SfzclBuffer buffer);
+
+/* Initializes an already allocated buffer structure. */
+
+void sfzcl_buffer_init(SfzclBuffer buffer);
+
+/* Frees any memory used by the buffer, first zeroing the whole area.
+ The buffer structure itself is not freed. */
+
+void sfzcl_buffer_uninit(SfzclBuffer buffer);
+
+/* Wrap a given memory area `mem' of length `n_bytes' inside the given
+ SfzclBuffer `buf'. The `buffer' is assumed uninited. */
+
+void sfzcl_buffer_wrap(SfzclBuffer buffer, unsigned char *mem, size_t n_bytes);
+
+/* This function steal the data from buffer to caller. It moves the
+ buffer's content to the beginning of the allocated memory, realloc
+ it to the current size, and leave the buffer in an uninited
+ state. Fill in the returned buffer size into 'len' if it not a NULL
+ pointer. */
+
+unsigned char *sfzcl_buffer_steal(SfzclBuffer buffer, size_t *len);
+
+/* Clears any data from the buffer, making it empty. This does not
+ zero the memory. This does not free the memory used by the buffer. */
+
+void sfzcl_buffer_clear(SfzclBuffer buffer);
+
+/* Appends data to the buffer, expanding it if necessary. */
+
+SfzclBufferStatus sfzcl_buffer_append(SfzclBuffer buffer,
+ const unsigned char *data, size_t len);
+/* Appends space to the buffer, expanding the buffer if necessary.
+ This does not actually copy the data into the buffer, but instead
+ returns a pointer to the allocated region. */
+
+SfzclBufferStatus sfzcl_buffer_append_space(SfzclBuffer buffer,
+ unsigned char **datap, size_t len);
+/* Appends NUL-terminated C-strings <...> to the buffer. The argument
+ list must be terminated with a NULL pointer. */
+
+SfzclBufferStatus sfzcl_buffer_append_cstrs(SfzclBuffer buffer, ...);
+#ifndef SFZCLDIST_SCM_ALIEN_RUN
+SfzclBufferStatus sfzcl_buffer_append_cstrs_va(SfzclBuffer buffer, va_list ap);
+#endif /* SFZCLDIST_SCM_ALIEN_RUN */
+
+/* Returns the number of bytes of data in the buffer. */
+
+size_t sfzcl_buffer_len(const SfzclBuffer buffer);
+
+/* Returns the number of bytes allocated, but not yet in use. */
+
+size_t sfzcl_buffer_space(const SfzclBuffer buffer);
+
+/* Consumes the given number of bytes from the beginning of the buffer. */
+
+SfzclBufferStatus sfzcl_buffer_consume(SfzclBuffer buffer, size_t bytes);
+
+/* Consumes the given number of bytes from the end of the buffer. */
+
+SfzclBufferStatus sfzcl_buffer_consume_end(SfzclBuffer buffer, size_t bytes);
+
+/* Returns a pointer to the first used byte in the buffer. */
+
+unsigned char *sfzcl_buffer_ptr(const SfzclBuffer buffer);
+
+#endif /* SFZCLBUFFER_H */
diff --git a/core/include/sfzcl/sfzcldsprintf.h b/core/include/sfzcl/sfzcldsprintf.h
new file mode 100644
index 0000000..6d670f7
--- /dev/null
+++ b/core/include/sfzcl/sfzcldsprintf.h
@@ -0,0 +1,45 @@
+/* sfzcldsprintf.h
+ */
+
+/*****************************************************************************
+* Copyright (c) 2006-2016 INSIDE Secure Oy. All Rights Reserved.
+*
+* The latest version of this code is available at http://www.matrixssl.org
+*
+* This software is open source; 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.
+*
+* This General Public License does NOT permit incorporating this software
+* into proprietary programs. If you are unable to comply with the GPL, a
+* commercial license for this software may be purchased from INSIDE at
+* http://www.insidesecure.com/
+*
+* This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+* http://www.gnu.org/copyleft/gpl.html
+*****************************************************************************/
+
+#ifndef SFZCLDSPRINTF_H
+#define SFZCLDSPRINTF_H
+
+/* This function is similar to Snprintf (indeed, this function, too,
+ uses vsnprintf()); it takes a format argument which specifies the
+ subsequent arguments, and writes them to a string using the
+ format-string. This function differs from snprintf in that this
+ allocates the buffer itself, and returns a pointer to the allocated
+ string (in str). This function never fails. (if there is not
+ enough memory, sfzcl_xrealloc() calls sfzcl_fatal())
+
+ The returned string must be freed by the caller. Returns the number
+ of characters written. */
+int sfzcl_dsprintf(char **str, const char *format, ...);
+int sfzcl_dvsprintf(char **str, const char *format, va_list ap);
+
+#endif /* SFZCLDSPRINTF_H */
diff --git a/core/include/sfzcl/sfzclenum.h b/core/include/sfzcl/sfzclenum.h
new file mode 100644
index 0000000..28ffb70
--- /dev/null
+++ b/core/include/sfzcl/sfzclenum.h
@@ -0,0 +1,48 @@
+/* sfzclenum.h
+
+ Functions for mapping keywords to numbers and vice versa.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2006-2016 INSIDE Secure Oy. All Rights Reserved.
+*
+* The latest version of this code is available at http://www.matrixssl.org
+*
+* This software is open source; 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.
+*
+* This General Public License does NOT permit incorporating this software
+* into proprietary programs. If you are unable to comply with the GPL, a
+* commercial license for this software may be purchased from INSIDE at
+* http://www.insidesecure.com/
+*
+* This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+* http://www.gnu.org/copyleft/gpl.html
+*****************************************************************************/
+
+#ifndef SFZCLENUM_H
+#define SFZCLENUM_H
+
+/* Array of keyword - numeric value pairs. The array is terminated by
+ an entry with NULL name. */
+typedef struct
+{
+ const char *name;
+ long code;
+} *SfzclKeyword, SfzclKeywordStruct;
+
+/* Finds the name of a keyword corresponding to the numeric value.
+ Returns a pointer to a constant name string, or NULL if there is no
+ keyword matching the numeric value. */
+const char *sfzcl_find_keyword_name(const SfzclKeywordStruct *keywords,
+ long code);
+
+#endif /* SFZCLENUM_H */
diff --git a/core/include/sfzcl/sfzclfastalloc.h b/core/include/sfzcl/sfzclfastalloc.h
new file mode 100644
index 0000000..93a1d82
--- /dev/null
+++ b/core/include/sfzcl/sfzclfastalloc.h
@@ -0,0 +1,78 @@
+/* sfzclfastalloc.h
+ */
+
+/*****************************************************************************
+* Copyright (c) 2006-2016 INSIDE Secure Oy. All Rights Reserved.
+*
+* The latest version of this code is available at http://www.matrixssl.org
+*
+* This software is open source; 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.
+*
+* This General Public License does NOT permit incorporating this software
+* into proprietary programs. If you are unable to comply with the GPL, a
+* commercial license for this software may be purchased from INSIDE at
+* http://www.insidesecure.com/
+*
+* This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+* http://www.gnu.org/copyleft/gpl.html
+*****************************************************************************/
+
+#ifndef SFZCLFASTALLOC_H_INCLUDED
+#define SFZCLFASTALLOC_H_INCLUDED
+
+typedef struct SfzclFastMemoryAllocatorRec *SfzclFastMemoryAllocator;
+
+/** Initialize a new memory allocator for fixed-sized blobs.
+ `blob_size' is the size of the blobs. `blob_quant' is the number of
+ blobs for which room will be reserved atomically. Both `blob_size'
+ and `blob_quant' must be larger than zero. */
+SfzclFastMemoryAllocator sfzcl_fastalloc_initialize(int blob_size,
+ int blob_quant);
+
+/** Uninitialize a memory allocator. All allocated blobs must have been
+ freed, otherwise sfzcl_fatal() may be triggered. */
+void sfzcl_fastalloc_uninitialize(SfzclFastMemoryAllocator allocator);
+
+/** Allocate a new blob of the size `blob_size'. The returned data is
+ correctly aligned for all kinds of purposes. The data is not
+ necessarily initialized.
+
+ This can return NULL if lower-level memory allocation can. */
+void *sfzcl_fastalloc_alloc(SfzclFastMemoryAllocator allocator);
+
+/** Free an individual blob. */
+void sfzcl_fastalloc_free(SfzclFastMemoryAllocator allocator, void *data);
+
+/** You do not need to access these structures directly but the
+ declarations must be public so that the macros above can work. */
+typedef struct
+{
+ void *free_chain;
+} SfzclFastallocProtoBlob;
+
+typedef struct sfzcl_fastalloc_blobs
+{
+ void *blobs;
+ struct sfzcl_fastalloc_blobs *next;
+} SfzclFastallocBlobs;
+
+struct SfzclFastMemoryAllocatorRec
+{
+ int total_size;
+ int allocated;
+ int blob_size;
+ int blob_quant;
+ SfzclFastallocBlobs *blobs;
+ SfzclFastallocProtoBlob *free_chain;
+};
+
+#endif /** SFZCLFASTALLOC_H_INCLUDED */
diff --git a/core/include/sfzcl/sfzclfileio.h b/core/include/sfzcl/sfzclfileio.h
new file mode 100644
index 0000000..92e15cd
--- /dev/null
+++ b/core/include/sfzcl/sfzclfileio.h
@@ -0,0 +1,155 @@
+/* sfzclfileio.h
+
+ Description : Read and write file from and to the disk
+ in various formats. The reading functions
+ with suffix with_limit have a maximum length
+ for the file that is being read.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2006-2016 INSIDE Secure Oy. All Rights Reserved.
+*
+* The latest version of this code is available at http://www.matrixssl.org
+*
+* This software is open source; 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.
+*
+* This General Public License does NOT permit incorporating this software
+* into proprietary programs. If you are unable to comply with the GPL, a
+* commercial license for this software may be purchased from INSIDE at
+* http://www.insidesecure.com/
+*
+* This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+* http://www.gnu.org/copyleft/gpl.html
+*****************************************************************************/
+
+#ifndef SFZCLFILEIO_H
+#define SFZCLFILEIO_H
+
+/* Read binary file from the disk. Return mallocated buffer and the size of the
+ buffer. If the reading of file failes return FALSE. If the file name is NULL
+ or "-" then read from the stdin. */
+bool sfzcl_read_file(const char *file_name,
+ unsigned char **buf, size_t *buf_len);
+/* Read binary file from the disk giving a size limit for the
+ file. Return mallocated buffer and the size of the buffer. If the
+ reading of file failes return FALSE. If the file name is NULL or
+ "-" then read from the stdin. The size_limit is in bytes. If zero
+ is used, the read file will try to read the whole file.
+
+ If the file size exceeds the size_limit (given in bytes), FALSE
+ is returned. */
+bool sfzcl_read_file_with_limit(const char *file_name,
+ uint32_t size_limit,
+ unsigned char **buf, size_t *buf_len);
+
+/* Read base 64 encoded file from the disk. Return mallocated buffer and the
+ size of the buffer. If the reading of file failes return FALSE. If the file
+ name is NULL or "-" then read from the stdin. */
+bool sfzcl_read_file_base64(const char *file_name,
+ unsigned char **buf, size_t *buf_len);
+
+/* Read pem/hexl/binary file from the disk. Return mallocated buffer and the
+ size of the buffer. If the reading of file failes return FALSE. If the file
+ name starts with :p: then assume file is pem encoded, if it starts with :h:
+ then it is assumed to be hexl format, and if it starts with :b: then it is
+ assumed to be binary. If no :[bph]: is given then file is assumed to be
+ binary. If any other letter is given between colons then warning message is
+ printed and operation fails. If the file name is NULL or "-" then
+ read from the stdin (":p:-" == stdin in pem encoded format). */
+bool sfzcl_read_gen_file(const char *file_name,
+ unsigned char **buf, size_t *buf_len);
+
+/* Read pem/hexl/binary file from the disk. Return mallocated buffer
+ and the size of the buffer. If the reading of file failes return
+ FALSE. If the file name starts with :p: then assume file is pem
+ encoded, if it starts with :h: then it is assumed to be hexl
+ format, and if it starts with :b: then it is assumed to be
+ binary. If no :[bph]: is given then file is assumed to be
+ binary. If any other letter is given between colons then warning
+ message is printed and operation fails. If the file name is NULL or
+ "-" then read from the stdin (":p:-" == stdin in pem encoded
+ format). The size_limit is in bytes. If zero is used, the read file
+ will try to read the whole file.
+
+ If the file size exceeds the size_limit (given in bytes), FALSE
+ is returned. */
+bool sfzcl_read_gen_file_with_limit(const char *file_name,
+ uint32_t size_limit,
+ unsigned char **buf, size_t *buf_len);
+
+/* Write binary file to the disk. If the write fails retuns FALSE. If the file
+ name is NULL or "-" then write to the stdout */
+bool sfzcl_write_file(const char *file_name,
+ const unsigned char *buf, size_t buf_len);
+
+/* Some predefined size limits to be used with functions that limit
+ the size of the file read. Adjust or add more if necessary. */
+
+/* Use this as a size_limit argument not to have any max
+ length for the file */
+#define SFZCL_READ_FILE_NO_LIMIT 0
+
+/* A default size limit for config files, etc... */
+#define SFZCL_READ_FILE_LIMIT_CONFIG_FILE 1024000
+
+/* A default size limit for certificates, keys, etc. */
+#define SFZCL_READ_FILE_LIMIT_CRYPTO_OBJ 96000
+
+/* Commonly used PEM begin and end strings */
+
+/* Generic pem encoded block */
+#define SFZCL_PEM_GENERIC_BEGIN "-----BEGIN PEM ENCODED DATA-----"
+#define SFZCL_PEM_GENERIC_END "-----END PEM ENCODED DATA-----"
+#define SFZCL_PEM_GENERIC SFZCL_PEM_GENERIC_BEGIN, SFZCL_PEM_GENERIC_END
+
+/* X.509 Certificate Block */
+#define SFZCL_PEM_X509_BEGIN "-----BEGIN X509 CERTIFICATE-----"
+#define SFZCL_PEM_X509_END "-----END X509 CERTIFICATE-----"
+#define SFZCL_PEM_X509 SFZCL_PEM_X509_BEGIN, SFZCL_PEM_X509_END
+
+/* SFZCL X.509 Private Key Block */
+#define SFZCL_PEM_SFZCL_PRV_KEY_BEGIN "-----BEGIN SFZCL X.509 PRIVATE KEY-----"
+#define SFZCL_PEM_SFZCL_PRV_KEY_END "-----END SFZCL X.509 PRIVATE KEY-----"
+#define SFZCL_PEM_SFZCL_PRV_KEY \
+ SFZCL_PEM_SFZCL_PRV_KEY_BEGIN, SFZCL_PEM_SFZCL_PRV_KEY_END
+
+/* X.509 Certificate Revocation List Block */
+#define SFZCL_PEM_X509_CRL_BEGIN "-----BEGIN X509 CRL-----"
+#define SFZCL_PEM_X509_CRL_END "-----END X509 CRL-----"
+#define SFZCL_PEM_X509_CRL SFZCL_PEM_X509_CRL_BEGIN, SFZCL_PEM_X509_CRL_END
+
+/* PKCS#10 Certificate Request Block */
+#define SFZCL_PEM_CERT_REQ_BEGIN "-----BEGIN CERTIFICATE REQUEST-----"
+#define SFZCL_PEM_CERT_REQ_END "-----END CERTIFICATE REQUEST-----"
+#define SFZCL_PEM_CERT_REQ SFZCL_PEM_CERT_REQ_BEGIN, SFZCL_PEM_CERT_REQ_END
+
+/* PKCS#1 Private Key block */
+#define SFZCL_PEM_PKCS1_RSA_BEGIN "-----BEGIN RSA PRIVATE KEY-----"
+#define SFZCL_PEM_PKCS1_RSA_END "-----END RSA PRIVATE KEY-----"
+#define SFZCL_PEM_PKCS1_RSA SFZCL_PEM_PKCS1_RSA_BEGIN, SFZCL_PEM_PKCS1_RSA_END
+
+#define SFZCL_PEM_PKCS1_DSA_BEGIN "-----BEGIN DSA PRIVATE KEY-----"
+#define SFZCL_PEM_PKCS1_DSA_END "-----END DSA PRIVATE KEY-----"
+#define SFZCL_PEM_PKCS1_DSA SFZCL_PEM_PKCS1_DSA_BEGIN, SFZCL_PEM_PKCS1_DSA_END
+
+/* PKCS#8 Private Key block */
+#define SFZCL_PEM_PKCS8_BEGIN "-----BEGIN PRIVATE KEY-----"
+#define SFZCL_PEM_PKCS8_END "-----END PRIVATE KEY-----"
+#define SFZCL_PEM_PKCS8 SFZCL_PEM_PKCS8_BEGIN, SFZCL_PEM_PKCS8_END
+
+/* Encrypted PKCS#8 Private Key block */
+#define SFZCL_PEM_ENCRYPTED_PKCS8_BEGIN "-----BEGIN ENCRYPTED PRIVATE KEY-----"
+#define SFZCL_PEM_ENCRYPTED_PKCS8_END "-----END ENCRYPTED PRIVATE KEY-----"
+#define SFZCL_PEM_ENCRYPTED_PKCS8 \
+ SFZCL_PEM_ENCRYPTED_PKCS8_BEGIN, SFZCL_PEM_ENCRYPTED_PKCS8_END
+
+#endif /* SFZCLFILEIO_H */
diff --git a/core/include/sfzcl/sfzclgetput.h b/core/include/sfzcl/sfzclgetput.h
new file mode 100644
index 0000000..cd6234e
--- /dev/null
+++ b/core/include/sfzcl/sfzclgetput.h
@@ -0,0 +1,213 @@
+/* sfzclgetput.h
+
+ Macros for storing and retrieving integers in msb first and lsb
+ first order. This interface can also be called from the other
+ thread than SFZCL main thread.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2006-2016 INSIDE Secure Oy. All Rights Reserved.
+*
+* The latest version of this code is available at http://www.matrixssl.org
+*
+* This software is open source; 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.
+*
+* This General Public License does NOT permit incorporating this software
+* into proprietary programs. If you are unable to comply with the GPL, a
+* commercial license for this software may be purchased from INSIDE at
+* http://www.insidesecure.com/
+*
+* This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+* http://www.gnu.org/copyleft/gpl.html
+*****************************************************************************/
+
+#ifndef SFZCLGETPUT_H
+#define SFZCLGETPUT_H
+
+#define SFZCL_GET_8BIT(cp) (*(unsigned char *) (cp))
+#define SFZCL_PUT_8BIT(cp, value) (*(unsigned char *) (cp)) = \
+ (unsigned char) (value)
+#define SFZCL_GET_4BIT_LOW(cp) (*(unsigned char *) (cp) & 0x0f)
+#define SFZCL_GET_4BIT_HIGH(cp) ((*(unsigned char *) (cp) >> 4) & 0x0f)
+#define SFZCL_PUT_4BIT_LOW(cp, value) (*(unsigned char *) (cp) = \
+ (unsigned char) ((*(unsigned char *) (cp) & 0xf0) | ((value) & 0x0f)))
+#define SFZCL_PUT_4BIT_HIGH(cp, value) (*(unsigned char *) (cp) = \
+ (unsigned char) ((*(unsigned char *) (cp) & 0x0f) | (((value) & 0x0f) << 4)))
+
+#ifdef SFZCLUINT64_IS_64BITS
+# define SFZCL_GET_64BIT(cp) (((uint64_t) SFZCL_GET_32BIT((cp)) << 32) | \
+ ((uint64_t) SFZCL_GET_32BIT((cp) + 4)))
+# define SFZCL_PUT_64BIT(cp, value) do { \
+ SFZCL_PUT_32BIT((cp), (uint32_t) ((uint64_t) (value) >> 32)); \
+ SFZCL_PUT_32BIT((cp) + 4, (uint32_t) (value)); } while (0)
+# define SFZCL_GET_64BIT_LSB_FIRST(cp) \
+ (((uint64_t) SFZCL_GET_32BIT_LSB_FIRST((cp))) | \
+ ((uint64_t) SFZCL_GET_32BIT_LSB_FIRST((cp) + 4) << 32))
+# define SFZCL_PUT_64BIT_LSB_FIRST(cp, value) do { \
+ SFZCL_PUT_32BIT_LSB_FIRST((cp), (uint32_t) (value)); \
+ SFZCL_PUT_32BIT_LSB_FIRST((cp) + 4, \
+ (uint32_t) ((uint64_t) (value) >> 32)); \
+} while (0)
+
+# define SFZCL_GET_40BIT(cp) (((uint64_t) SFZCL_GET_8BIT((cp)) << 32) | \
+ ((uint64_t) SFZCL_GET_32BIT((cp) + 1)))
+# define SFZCL_PUT_40BIT(cp, value) do { \
+ SFZCL_PUT_8BIT((cp), (uint32_t) ((uint64_t) (value) >> 32)); \
+ SFZCL_PUT_32BIT((cp) + 1, (uint32_t) (value)); } while (0)
+
+# define SFZCL_GET_40BIT_LSB_FIRST(cp) \
+ (((uint64_t) SFZCL_GET_32BIT_LSB_FIRST((cp))) | \
+ ((uint64_t) SFZCL_GET_8BIT((cp) + 4) << 32))
+# define SFZCL_PUT_40BIT_LSB_FIRST(cp, value) do { \
+ SFZCL_PUT_32BIT_LSB_FIRST((cp), (uint32_t) (value)); \
+ SFZCL_PUT_8BIT((cp) + 4, \
+ (uint32_t) ((uint64_t) (value) >> 32)); } while (0)
+
+#else /* SFZCLUINT64_IS_64BITS */
+# define SFZCL_GET_64BIT(cp) ((uint64_t) SFZCL_GET_32BIT((cp) + 4))
+# define SFZCL_PUT_64BIT(cp, value) do { \
+ SFZCL_PUT_32BIT((cp), 0L); \
+ SFZCL_PUT_32BIT((cp) + 4, (uint32_t) (value)); } while (0)
+# define SFZCL_GET_64BIT_LSB_FIRST(cp) ((uint64_t) SFZCL_GET_32BIT((cp)))
+# define SFZCL_PUT_64BIT_LSB_FIRST(cp, value) do { \
+ SFZCL_PUT_32BIT_LSB_FIRST((cp), (uint32_t) (value)); \
+ SFZCL_PUT_32BIT_LSB_FIRST((cp) + 4, 0L); } while (0)
+
+# define SFZCL_GET_40BIT(cp) ((uint64_t) SFZCL_GET_32BIT((cp) + 1))
+# define SFZCL_PUT_40BIT(cp, value) do { \
+ SFZCL_PUT_8BIT((cp), 0); \
+ SFZCL_PUT_32BIT((cp) + 1, (uint32_t) (value)); } while (0)
+# define SFZCL_GET_40BIT_LSB_FIRST(cp) \
+ ((uint64_t) SFZCL_GET_32BIT_LSB_FIRST((cp)))
+# define SFZCL_PUT_40BIT_LSB_FIRST(cp, value) do { \
+ SFZCL_PUT_32BIT_LSB_FIRST((cp), (uint32_t) (value)); \
+ SFZCL_PUT_8BIT((cp) + 4, 0); } while (0)
+
+#endif /* SFZCLUINT64_IS_64BITS */
+
+#define SFZCL_GET_24BIT(cp) \
+ ((((unsigned long) ((unsigned char *) (cp))[0]) << 16) | \
+ (((unsigned long) ((unsigned char *) (cp))[1]) << 8) | \
+ ((unsigned long) ((unsigned char *) (cp))[2]))
+#define SFZCL_GET_24BIT_LSB_FIRST(cp) \
+ ((((unsigned long) ((unsigned char *) (cp))[2]) << 16) | \
+ (((unsigned long) ((unsigned char *) (cp))[1]) << 8) | \
+ ((unsigned long) ((unsigned char *) (cp))[0]))
+#define SFZCL_PUT_24BIT(cp, value) do { \
+ ((unsigned char *) (cp))[0] = (unsigned char) ((value) >> 16); \
+ ((unsigned char *) (cp))[1] = (unsigned char) ((value) >> 8); \
+ ((unsigned char *) (cp))[2] = (unsigned char) (value); } while (0)
+#define SFZCL_PUT_24BIT_LSB_FIRST(cp, value) do { \
+ ((unsigned char *) (cp))[2] = (unsigned char) ((value) >> 16); \
+ ((unsigned char *) (cp))[1] = (unsigned char) ((value) >> 8); \
+ ((unsigned char *) (cp))[0] = (unsigned char) (value); } while (0)
+
+/*------------ macros for storing/extracting msb first words -------------*/
+
+#define SFZCL_GET_32BIT(cp) \
+ ((((unsigned long) ((unsigned char *) (cp))[0]) << 24) | \
+ (((unsigned long) ((unsigned char *) (cp))[1]) << 16) | \
+ (((unsigned long) ((unsigned char *) (cp))[2]) << 8) | \
+ ((unsigned long) ((unsigned char *) (cp))[3]))
+
+#define SFZCL_GET_16BIT(cp) \
+ ((uint16_t) ((((unsigned long) ((unsigned char *) (cp))[0]) << 8) | \
+ ((unsigned long) ((unsigned char *) (cp))[1])))
+
+#define SFZCL_PUT_32BIT(cp, value) do { \
+ ((unsigned char *) (cp))[0] = (unsigned char) ((value) >> 24); \
+ ((unsigned char *) (cp))[1] = (unsigned char) ((value) >> 16); \
+ ((unsigned char *) (cp))[2] = (unsigned char) ((value) >> 8); \
+ ((unsigned char *) (cp))[3] = (unsigned char) (value); } while (0)
+
+#define SFZCL_PUT_16BIT(cp, value) do { \
+ ((unsigned char *) (cp))[0] = (unsigned char) ((value) >> 8); \
+ ((unsigned char *) (cp))[1] = (unsigned char) (value); } while (0)
+
+/*------------ macros for storing/extracting lsb first words -------------*/
+
+#define SFZCL_GET_32BIT_LSB_FIRST(cp) \
+ (((unsigned long) ((unsigned char *) (cp))[0]) | \
+ (((unsigned long) ((unsigned char *) (cp))[1]) << 8) | \
+ (((unsigned long) ((unsigned char *) (cp))[2]) << 16) | \
+ (((unsigned long) ((unsigned char *) (cp))[3]) << 24))
+
+#define SFZCL_GET_16BIT_LSB_FIRST(cp) \
+ ((uint16_t) (((unsigned long) ((unsigned char *) (cp))[0]) | \
+ (((unsigned long) ((unsigned char *) (cp))[1]) << 8)))
+
+#define SFZCL_PUT_32BIT_LSB_FIRST(cp, value) do { \
+ ((unsigned char *) (cp))[0] = (unsigned char) (value); \
+ ((unsigned char *) (cp))[1] = (unsigned char) ((value) >> 8); \
+ ((unsigned char *) (cp))[2] = (unsigned char) ((value) >> 16); \
+ ((unsigned char *) (cp))[3] = (unsigned char) ((value) >> 24); } while (0)
+
+#define SFZCL_PUT_16BIT_LSB_FIRST(cp, value) do { \
+ ((unsigned char *) (cp))[0] = (unsigned char) (value); \
+ ((unsigned char *) (cp))[1] = (unsigned char) ((value) >> 8); } while (0)
+
+/* This `|| 1' thing disables the GCC i386 optimizations. They seem
+ to be very mysticly broken so it is better to disable them. */
+#if !defined(NO_INLINE_GETPUT) && defined(__i386__) && defined(__GNUC__)
+
+/* Intel i386 processor, using AT&T syntax for gcc compiler. */
+
+# undef SFZCL_GET_32BIT_LSB_FIRST
+# undef SFZCL_GET_16BIT_LSB_FIRST
+# undef SFZCL_PUT_32BIT_LSB_FIRST
+# undef SFZCL_PUT_16BIT_LSB_FIRST
+# undef SFZCL_GET_32BIT
+# undef SFZCL_PUT_32BIT
+
+/* Lsb first cases could be done efficiently also with just C-definitions
+ to just copy values. i386 has no alignment restrictions. */
+
+# define SFZCL_GET_32BIT_LSB_FIRST(cp) (*(uint32_t *) (cp))
+# define SFZCL_GET_16BIT_LSB_FIRST(cp) (*(uint16_t *) (cp))
+# define SFZCL_PUT_32BIT_LSB_FIRST(cp, x) (*(uint32_t *) (cp)) = (x)
+# define SFZCL_PUT_16BIT_LSB_FIRST(cp, x) (*(uint16_t *) (cp)) = (x)
+
+/* Getting bytes msb first */
+
+# ifdef NO_386_COMPAT
+# define SFZCL_GET_32BIT(cp) \
+ ({ \
+ uint32_t __v__; \
+ __asm__ volatile ("movl (%1), %%ecx; " \
+ "bswap %%ecx;" \
+ : "=c" (__v__) \
+ : "r" (cp) : "cc"); \
+ __v__; \
+ })
+# else
+# define SFZCL_GET_32BIT(cp) \
+ ({ \
+ uint32_t __v__; \
+ __asm__ volatile ("movl (%1), %%ecx; rolw $8, %%cx; " \
+ "roll $16, %%ecx; rolw $8, %%cx;" \
+ : "=c" (__v__) \
+ : "r" (cp) : "cc"); \
+ __v__; \
+ })
+
+# endif
+
+# define SFZCL_PUT_32BIT(cp, v) \
+ __asm__ volatile ("movl %1, %%ecx; rolw $8, %%cx; " \
+ "roll $16, %%ecx; rolw $8, %%cx;" \
+ "movl %%ecx, (%0);" \
+ : : "S" (cp), "a" ((uint32_t) (v)) : "%ecx", "memory", "cc")
+
+
+#endif /* __i386__ */
+
+#endif /* GETPUT_H */
diff --git a/core/include/sfzcl/sfzclglobals.h b/core/include/sfzcl/sfzclglobals.h
new file mode 100644
index 0000000..a1db19d
--- /dev/null
+++ b/core/include/sfzcl/sfzclglobals.h
@@ -0,0 +1,69 @@
+/* sfzclglobals.h
+ */
+
+/*****************************************************************************
+* Copyright (c) 2006-2016 INSIDE Secure Oy. All Rights Reserved.
+*
+* The latest version of this code is available at http://www.matrixssl.org
+*
+* This software is open source; 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.
+*
+* This General Public License does NOT permit incorporating this software
+* into proprietary programs. If you are unable to comply with the GPL, a
+* commercial license for this software may be purchased from INSIDE at
+* http://www.insidesecure.com/
+*
+* This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+* http://www.gnu.org/copyleft/gpl.html
+*****************************************************************************/
+
+#ifndef SFZCLGLOBALS_H
+#define SFZCLGLOBALS_H
+
+/* To use global variables in code you have to do following:
+
+ old code new code
+
+ ** Declaration of global variable **
+
+ extern int foobar; SFZCL_GLOBAL_DECLARE(int, foobar);
+ ********#define foobar SFZCL_GLOBAL_USE(foobar)
+
+ ** Definiation of global variable **
+ int foobar; SFZCL_GLOBAL_DEFINE(int, foobar);
+
+ ** Initialization of global variable (this must be inside the
+ ** init function or similar, all global variables are initialized to
+ ** zero at the beginning). If SFZCL_GLOBAL_INIT is not called then
+ ** first use of variable might print out warning about use of
+ ** uninitialized global variable (if warnings are enabled).
+ ** Warning might also be printed out if the SFZCL_GLOBAL_INIT is called
+ ** multiple times without calls to sfzcl_global_reset or
+ ** sfzcl_global_uninit + init.
+
+ int foobar = 1; ** this is not allowed
+
+ foobar = 1; SFZCL_GLOBAL_INIT(foobar,1);
+
+ ** Using the global variable
+
+ foobar = 1; foobar = 1; ** i.e no changes
+ foobar = foobar++; foobar = foobar++;
+
+ */
+
+#define SFZCL_GLOBAL_USE(var) sfzcl_global_ ## var
+#define SFZCL_GLOBAL_DECLARE(type, var) extern type sfzcl_global_ ## var
+#define SFZCL_GLOBAL_DEFINE(type, var) type sfzcl_global_ ## var
+#define SFZCL_GLOBAL_INIT(var, value) (sfzcl_global_ ## var) = (value)
+
+#endif /* SFZCLGLOBALS_H */
diff --git a/core/include/sfzcl/sfzclincludes.h b/core/include/sfzcl/sfzclincludes.h
new file mode 100644
index 0000000..b58ade6
--- /dev/null
+++ b/core/include/sfzcl/sfzclincludes.h
@@ -0,0 +1,127 @@
+/* sfzclincludes.h
+ */
+
+/*****************************************************************************
+* Copyright (c) 2002-2016 INSIDE Secure Oy. All Rights Reserved.
+*
+* The latest version of this code is available at http://www.matrixssl.org
+*
+* This software is open source; 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.
+*
+* This General Public License does NOT permit incorporating this software
+* into proprietary programs. If you are unable to comply with the GPL, a
+* commercial license for this software may be purchased from INSIDE at
+* http://www.insidesecure.com/
+*
+* This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+* http://www.gnu.org/copyleft/gpl.html
+*****************************************************************************/
+
+#ifndef SFZCLINCLUDES_H
+#define SFZCLINCLUDES_H
+
+#include "cfg_pkcslib.h"
+#include "public_defs.h"
+#include "c_lib.h"
+#include "spal_mutex.h"
+#include "spal_memory.h"
+#include "spal_semaphore.h"
+#include "spal_result.h"
+#include "sfzclmalloc.h"
+#include "sfzclsnprintf.h"
+#include "sfzcltime.h"
+#include "sfzclsnprintf.h"
+
+/* The amount of static memory for MP ints. */
+#define SFZCL_MP_INTEGER_BIT_SIZE_STATIC 0
+
+#if defined( WIN32)
+/* Windows API */
+# ifndef SFZCLDIST_FREESTANDING
+# include "osdep_windows.h"
+# include "osdep_winbase.h"
+# include "osdep_fcntl.h"
+# endif /* !SFZCLDIST_FREESTANDING */
+
+# define SIZEOF_SHORT 2
+# define SIZEOF_INT 4
+# define SIZEOF_LONG 4 /* WIN64 uses LLP64 convention. */
+# define SFZCLUINT64_IS_64BITS
+# define SFZCL_C64(x) (x)
+
+#else
+/* Other platform. */
+
+# ifndef SFZCLDIST_FREESTANDING
+# include "osdep_stdlib.h"
+# include "osdep_ctype.h"
+# include "osdep_sys_time.h"
+# include "osdep_string.h"
+# include "osdep_stdio.h"
+# endif /* !SFZCLDIST_FREESTANDING */
+
+# ifndef SIZEOF_SHORT
+# define SIZEOF_SHORT 2
+# endif /* SIZEOF_SHORT */
+# ifndef SIZEOF_INT
+# define SIZEOF_INT 4
+# endif /* SIZEOF_INT */
+# ifndef SIZEOF_LONG
+# define SIZEOF_LONG 8
+# endif /* SIZEOF_LONG */
+
+#endif /* WIN32 */
+
+#define COMPILE_SFZCL_SIZE_GLOBAL_ASSERT(condition) \
+ extern int sfzl_size_global_assert[1 - 2 * (!(condition))]
+
+COMPILE_SFZCL_SIZE_GLOBAL_ASSERT(SIZEOF_SHORT == sizeof(short));
+COMPILE_SFZCL_SIZE_GLOBAL_ASSERT(SIZEOF_INT == sizeof(int));
+COMPILE_SFZCL_SIZE_GLOBAL_ASSERT(SIZEOF_LONG == sizeof(long));
+
+#ifndef TRUE
+# define TRUE 1
+#endif
+
+#ifndef FALSE
+# define FALSE 0
+#endif
+
+/* Defines related to segmented memory architectures. */
+#ifndef NULL_FNPTR
+# define NULL_FNPTR NULL
+#else
+# define HAVE_SEGMENTED_MEMORY 1
+#endif
+
+#ifdef SFZCLDIST_FREESTANDING
+/* Provide emulation of is* (ctype.h) operations required by CertLib */
+
+# undef isdigit
+# define Isdigit(x) ((x) >= '0' && (x) <= '9')
+
+# undef isalpha
+# define Isalpha(x) (((x) | 32) >= 'a' && ((x) | 32) <= 'z')
+
+# undef isxalpha
+# define Isxalpha(x) (((x) | 32) >= 'a' && ((x) | 32) <= 'f')
+
+# undef isxdigit
+# define Isxdigit(x) (Isdigit(x) || Isxalpha(x))
+
+# undef isspace
+# define Isspace(x) ((x) <= 32 && ((x) == 32 || (x) == '\f' || (x) == '\n' || \
+ (x) == '\r' || (x) == '\t' || (x) == '\v'))
+
+#endif /* SFZCLDIST_FREESTANDING */
+
+#endif /* SFZCLINCLUDES_H */
diff --git a/core/include/sfzcl/sfzclmalloc.h b/core/include/sfzcl/sfzclmalloc.h
new file mode 100644
index 0000000..2a57dc8
--- /dev/null
+++ b/core/include/sfzcl/sfzclmalloc.h
@@ -0,0 +1,54 @@
+/* sfzclmalloc.h
+
+ Versions of malloc and friends that check their results, and never return
+ failure (they call fatal if they encounter an error).
+
+ These functions MUST be multi thread safe, if the system is using threads.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2006-2016 INSIDE Secure Oy. All Rights Reserved.
+*
+* The latest version of this code is available at http://www.matrixssl.org
+*
+* This software is open source; 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.
+*
+* This General Public License does NOT permit incorporating this software
+* into proprietary programs. If you are unable to comply with the GPL, a
+* commercial license for this software may be purchased from INSIDE at
+* http://www.insidesecure.com/
+*
+* This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+* http://www.gnu.org/copyleft/gpl.html
+*****************************************************************************/
+
+#ifndef SFZCLMALLOC_H
+#define SFZCLMALLOC_H
+
+#include "public_defs.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+void *sfzcl_strdup(const void *str);
+
+void *sfzcl_memdup(const void *data, size_t len);
+
+void *sfzcl_realloc(void *ptr, size_t old_size, size_t new_size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SFZCLMALLOC_H */
diff --git a/core/include/sfzcl/sfzclmemparser.h b/core/include/sfzcl/sfzclmemparser.h
new file mode 100644
index 0000000..eaf770e
--- /dev/null
+++ b/core/include/sfzcl/sfzclmemparser.h
@@ -0,0 +1,111 @@
+/* sfzclmemparser.h
+ *
+ * Description: Parse memory area.
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2016 INSIDE Secure Oy. All Rights Reserved.
+*
+* The latest version of this code is available at http://www.matrixssl.org
+*
+* This software is open source; 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.
+*
+* This General Public License does NOT permit incorporating this software
+* into proprietary programs. If you are unable to comply with the GPL, a
+* commercial license for this software may be purchased from INSIDE at
+* http://www.insidesecure.com/
+*
+* This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+* http://www.gnu.org/copyleft/gpl.html
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_SFZCLMEMPARSER_H
+#define INCLUDE_GUARD_SFZCLMEMPARSER_H
+
+typedef struct SfzclMemParserRec
+{
+ const unsigned char *Memory_p;
+ size_t Remaining;
+ unsigned int Error : 1;
+} SfzclMemParserStruct;
+
+typedef uint32_t SfzclMemParserOptionsBitmask;
+#define SFZCL_MEMPARSER_MIN_MULT 0x00000001
+#define SFZCL_MEMPARSER_MAX_MULT 0x00000100
+#define SFZCL_MEMPARSER_MIN_MAX_MULT 0x00000101
+#define SFZCL_MEMPARSER_MIN_MASK 0x000000ff
+#define SFZCL_MEMPARSER_MAX_MASK 0x0000ff00
+#define SFZCL_MEMPARSER_NUM_ACCEPT_INITIAL_BLANK 0x00020000
+#define SFZCL_MEMPARSER_NUM_ACCEPT_INITIAL_ZERO 0x00040000
+#define SFZCL_MEMPARSER_STR_ACCEPT_SPACE 0x00100000
+
+/* Initialize parser with specified memory area. */
+void sfzcl_memparser_init_mem(
+ SfzclMemParserStruct * const MemParserUninitialized_p,
+ const unsigned char *Memory_p,
+ size_t Length);
+
+/* Init memory parsing using specified string. */
+void sfzcl_memparser_init_string(
+ SfzclMemParserStruct * const MemParserUninitialized_p,
+ const char *String_p);
+
+/* Request remaining length. (Returns 0 if the parser is in error state.) */
+size_t sfzcl_memparser_remaining_length(
+ SfzclMemParserStruct * const MemParser_p);
+
+/* Macro for querying end of string condition without errors */
+#define SFZCL_MEMPARSER_IS_END(MemParser_p) \
+ ((!sfzcl_memparser_remaining_length(MemParser_p)) && \
+ (!sfzcl_memparser_is_error(MemParser_p)))
+
+/* Check if sfzcl_memparser is in error state. */
+bool sfzcl_memparser_is_error(
+ SfzclMemParserStruct * const MemParser_p);
+
+/* Read uinteger value. In case of parse error, zero is returned and error
+ state is set. */
+unsigned long sfzcl_memparser_read_uinteger(
+ SfzclMemParserStruct * const MemParser_p,
+ SfzclMemParserOptionsBitmask Options);
+
+/* Read string: returns number of characters read. */
+size_t sfzcl_memparser_read_string(
+ SfzclMemParserStruct * const MemParser_p,
+ SfzclMemParserOptionsBitmask Options,
+ char *String,
+ size_t StringBytes);
+
+/* Skip characters from specified string.
+ Return number of characters skipped. */
+size_t sfzcl_memparser_skip_span(
+ SfzclMemParserStruct * const MemParser_p,
+ SfzclMemParserOptionsBitmask Options,
+ const char *Span);
+
+/* Accept specified string.
+ Return true/false, sets error state if false. */
+bool sfzcl_memparser_accept_string(
+ SfzclMemParserStruct * const MemParser_p,
+ const char *String_p);
+
+#define SFZCL_MEMPARSER_SKIP_WHITE(MemParser_p) \
+ (void) sfzcl_memparser_skip_span( \
+ MemParser_p, \
+ (SFZCL_MEMPARSER_MIN_MULT * 0) | \
+ (SFZCL_MEMPARSER_MAX_MULT * 255), \
+ " \f\n\r\t\v")
+
+#endif /* Include Guard */
+
+/* end of file sfzclmemparser.h */
diff --git a/core/include/sfzcl/sfzclobstack.h b/core/include/sfzcl/sfzclobstack.h
new file mode 100644
index 0000000..3def60e
--- /dev/null
+++ b/core/include/sfzcl/sfzclobstack.h
@@ -0,0 +1,113 @@
+/* sfzclobstack.h
+ */
+
+/*****************************************************************************
+* Copyright (c) 2006-2016 INSIDE Secure Oy. All Rights Reserved.
+*
+* The latest version of this code is available at http://www.matrixssl.org
+*
+* This software is open source; 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.
+*
+* This General Public License does NOT permit incorporating this software
+* into proprietary programs. If you are unable to comply with the GPL, a
+* commercial license for this software may be purchased from INSIDE at
+* http://www.insidesecure.com/
+*
+* This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+* http://www.gnu.org/copyleft/gpl.html
+*****************************************************************************/
+
+/*
+ Mallocation to a context, with out possibility to free specific elements.
+ */
+
+#ifndef SFZCLOBSTACK_H
+#define SFZCLOBSTACK_H
+
+typedef struct SfzclObStackContextRec *SfzclObStackContext;
+
+/** Configuration data structure for the obstack. */
+typedef struct SfzclObStackConfRec
+{
+ size_t prealloc_size; /** Amount of memory is preallocated for the
+ obstack. This is still left allocated for
+ the obstack after clear, i.e after clear
+ this much can always be allocated before
+ failure (note, that alignment might consume
+ some amount here too). The preallocated size
+ is for actual memory allocations, i.e the
+ contexts etc used are not consumed from
+ this. The max_size must be 9 words larger
+ than prealloc_size, otherwise the alloc will
+ fail. Value 0 means no preallocation is
+ done. */
+ size_t max_size; /** Maximum size of the memory used for the
+ whole obstack. This includes all data, i.e
+ also the data header structures, and data
+ not yet returned, but already allocated.
+ When this is used, then allocations start to
+ fail. Note, that even when the first
+ allocation fails, there can still be some
+ empty areas in the obstack, i.e some smaller
+ allocations, can still succeded. Value 0
+ means there is no limit for the memory used.
+ */
+} *SfzclObStackConf, SfzclObStackConfStruct;
+
+/** Initialize the mallocation context with given configuration. The
+ configuration can be NULL in which case the defaults are used (4000 bytes of
+ prealloc, and no max size). The same context can be used for all data of all
+ sizes. The data can only be freed by clearing the whole stack. This function
+ uses memory efficient algorithm, which tries not to allocate too much data
+ (best-fit, fragmentation is not problem here, as single pieces cannot be
+ freed from the obstack). This means that allocating 1 byte only takes less
+ than 1.005 bytes of data, thus this is optimal for allocating strings etc.
+
+ The obstack can be preallocated to have certain amount of memory in the
+ beginning and that memory is never freed by the sfzcl_obstack_clear (i.e if
+ the obstack is reused it still contains the same preallocated memory).
+ Obstack can also have maximum limit of memory it can consume. This maximum
+ limit includes all headers and internal structures, thus the actual amount
+ of memory which can be allocated from the obstack can be smaller than the
+ maximum limit.
+
+ This function returns NULL if there was an error when allocating the obstack
+ (preallocation failed, or the maximum limit didn't allow enough memory for
+ the preallocated buffer and headers). */
+
+SfzclObStackContext sfzcl_obstack_create(SfzclObStackConf config);
+
+/** Free all data allocated using this particular context and the context. This
+ function makes all allocated space invalid. */
+
+void sfzcl_obstack_destroy(SfzclObStackContext context);
+
+/** Frees all data allocated using this obstack, but keeps the context. This
+ effectively clears the obstack. If the obstack had preallocated data, then
+ preallocated memory is not freed to the system, but will be returned by the
+ first new allocations from the obstack. */
+
+void sfzcl_obstack_clear(SfzclObStackContext context);
+
+/** Allocate byte buffer of length size from the context. If enough
+ memory is not available the function will return NULL. */
+
+/** Allocated data is not aligned. */
+unsigned char *sfzcl_obstack_alloc_unaligned(SfzclObStackContext context,
+ size_t size);
+
+/** Allocated data is aligned to 8-byte boundary or if item is less than 8 bytes
+ then aligned to 4 (4-7 bytes) or 2 (2-3) byte boundary. This should be
+ enough for all datatypes. */
+void *sfzcl_obstack_alloc(SfzclObStackContext context, size_t size);
+
+#endif /* SFZCLOBSTACK_H */
diff --git a/core/include/sfzcl/sfzclsnprintf.h b/core/include/sfzcl/sfzclsnprintf.h
new file mode 100644
index 0000000..937f872
--- /dev/null
+++ b/core/include/sfzcl/sfzclsnprintf.h
@@ -0,0 +1,93 @@
+/* sfzclsnprintf.h
+
+ Header file for sfzclsnprintf.c
+ */
+
+/*****************************************************************************
+* Copyright (c) 2006-2016 INSIDE Secure Oy. All Rights Reserved.
+*
+* The latest version of this code is available at http://www.matrixssl.org
+*
+* This software is open source; 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.
+*
+* This General Public License does NOT permit incorporating this software
+* into proprietary programs. If you are unable to comply with the GPL, a
+* commercial license for this software may be purchased from INSIDE at
+* http://www.insidesecure.com/
+*
+* This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+* http://www.gnu.org/copyleft/gpl.html
+*****************************************************************************/
+
+#ifndef SNPRINTF_H
+#define SNPRINTF_H
+
+#include "osdep_stdarg.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* Type of functions that implement formatting `external' data types.
+ `buf' is the buf where something should be written, `buf_size' the
+ maximum number of characters that can be written. `precision' is
+ either -1 or a non-negative number supplied by the user; its
+ interpretation is chosen by the rendering function. `datum' is the
+ actual value to render.
+
+ The functions must return the number of characters written.
+
+ If the renderer would have liked to write more characters than
+ there was room in `buf_size', the renderer should return the value
+ `buf_size' + 1 (but have written only `buf_size' characters, of
+ course).
+
+ As a relaxation, the functions ARE allowed to write the NUL byte at
+ buf[buf_size], i.e. at the `buf_size'+1th character. However, this
+ is not necessary and doing or doing not has no effect whatsoever. */
+typedef int (*SfzclSnprintfRenderer) (char *buf, int buf_size,
+ int precision, void *datum);
+
+/* Write formatted text to buffer 'str', using format string 'format'.
+ Returns number of characters written, or negative if error
+ occurred. Buffer's size is given in 'size'. Format string is
+ understood as defined in ANSI C.
+
+ NOTE: This does NOT work identically with BSD's snprintf.
+
+ Integers: Ansi C says that precision specifies the minimun number
+ of digits to print. BSD's version however counts the prefixes (+,
+ -, ' ', '0x', '0X', octal prefix '0'...) as 'digits'.
+
+ Also, BSD implementation does not permit padding integers to
+ specified width with zeros on left (in front of the prefixes), it
+ uses spaces instead, even when Ansi C only forbids padding with
+ zeros on the right side of numbers.
+
+ This version can also be extended using %@, which takes
+ SfzclSnprintfRenderer argument and void *, and calls that
+ SfzclSnprintfRenderer function to render the actual data.
+
+ Additionally, some versions consider running out of space an error;
+ we do not, and instead return normally; this is consistent with C99
+ standard.
+ */
+
+int sfzcl_snprintf(char *str, size_t size, const char *format, ...);
+int sfzcl_vsnprintf(char *str, size_t size, const char *format, va_list ap);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SNPRINTF_H */
diff --git a/core/include/sfzcl/sfzclstr.h b/core/include/sfzcl/sfzclstr.h
new file mode 100644
index 0000000..f8b5190
--- /dev/null
+++ b/core/include/sfzcl/sfzclstr.h
@@ -0,0 +1,230 @@
+/* sfzclstr.h
+ */
+
+/*****************************************************************************
+* Copyright (c) 2006-2016 INSIDE Secure Oy. All Rights Reserved.
+*
+* The latest version of this code is available at http://www.matrixssl.org
+*
+* This software is open source; 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.
+*
+* This General Public License does NOT permit incorporating this software
+* into proprietary programs. If you are unable to comply with the GPL, a
+* commercial license for this software may be purchased from INSIDE at
+* http://www.insidesecure.com/
+*
+* This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+* http://www.gnu.org/copyleft/gpl.html
+*****************************************************************************/
+
+#ifndef SFZCLSTR_H
+#define SFZCLSTR_H
+
+#include "c_lib.h"
+
+/** Policy: SFZCL is not going to support all special character sets or
+ country specific ASCII sets. That would be almost impossible. It is
+ hoped that the UTF-8 will become de facto standard in near future
+ and atleast after 2003 as hoped by PKIX, thus we concentrate our
+ support for that set.
+
+ Why UTF-8 is the choice? Mainly because it extends the US-ASCII in
+ a transparent way and has the full power of UCS-4 and UCS-2. I
+ feel, and probably other too, that having just one common character
+ set is best for us all. */
+
+/** Following charsets are only ones supported at the moment. */
+typedef enum
+{
+ /** Given any as argument to conversion function will convert the
+ string into smallest charset it fits into. */
+ SFZCL_CHARSET_ANY = -1,
+
+ /** The basic charset (a subset of ASCII). Usually printable
+ strings are case insensitive. */
+ SFZCL_CHARSET_PRINTABLE,
+
+ /** Another relative of ASCII, but instead of letters such as '@'
+ there are some like 'A' with acute. Equivalent to ISO 646. */
+ SFZCL_CHARSET_VISIBLE,
+
+ /** US ASCII. Handled as a 7 bits of the Unicode standard. */
+ SFZCL_CHARSET_US_ASCII,
+
+ /** ISO 8859-1:1987, or ISO latin1. Equivalent to the US ASCII. */
+ SFZCL_CHARSET_ISO_8859_1,
+ /** ISO 8859-2:1987 character set. */
+ SFZCL_CHARSET_ISO_8859_2,
+ /** ISO 8859-3:1988 character set. */
+ SFZCL_CHARSET_ISO_8859_3,
+ /** ISO 8859-4:1988 character set. */
+ SFZCL_CHARSET_ISO_8859_4,
+
+ /** ISO-8859-15 character set, a.k.a Latin9, a.k.a Latin0. */
+ SFZCL_CHARSET_ISO_8859_15,
+
+ /** T.61/Teletex string. */
+ SFZCL_CHARSET_T61,
+
+ /** 16 bit Basic Multilingual Plane (BMP), or UCS-2 as in ISO 10646-1. */
+ SFZCL_CHARSET_BMP,
+
+ /** 32 bit Universal Character Set, or UCS-4 as in ISO 10646-1. */
+ SFZCL_CHARSET_UNIVERSAL,
+
+ /** UTF-8 encoding format for UCS-2 and UCS-4. */
+ SFZCL_CHARSET_UTF8
+} SfzclCharset;
+
+/** The size of the 16-bit character set. */
+#define SFZCL_CHARSET_BMP_SIZE 65536
+
+/** Our string type. */
+typedef struct SfzclStrRec *SfzclStr;
+
+/* Initialization. */
+
+/** This function makes a character string in given `charset', e.g. the
+ input data given in octet array `str' whose length is `str_length'
+ is converted into the internal presentation which is returned.
+
+ This function keeps the input string untouched.
+
+ The function will return NULL if the given input can not be a
+ presenation of string using charset, or if memory allocation for
+ the internal presentation fails. */
+SfzclStr
+sfzcl_str_new(SfzclCharset charset, const void *str, size_t str_length);
+
+/** This function makes a character string in given `charset', e.g. the
+ input data given in octet array `str' whose length is `str_length'
+ is converted into the internal presentation which is returned.
+
+ This function steals the input string. It must no longer be
+ referenced directly by the caller.
+
+ The function will return NULL if the given input can not be a
+ presenation of string using charset, or if memory allocation for
+ the internal presentation fails. */
+SfzclStr
+sfzcl_str_make(SfzclCharset charset, unsigned char *str, size_t str_length);
+
+/** Free a string that is no longer used. */
+void sfzcl_str_free(SfzclStr str);
+
+/** Get pointer to internal string representation. */
+unsigned char *sfzcl_str_get_data(SfzclStr in_str, size_t *out_str_length);
+
+/** This function frees the wrapper data structure only, not the
+ underlying string. */
+void sfzcl_str_free_wrapper(SfzclStr str);
+
+/* Character set operations. */
+
+/** Convert a string to some particular character set. Usually one
+ cannot expect to convert a string into character set with less
+ characters. However, the opposite does work. Returns NULL if
+ fails. */
+SfzclStr sfzcl_str_charset_convert(SfzclStr str, SfzclCharset charset);
+
+/** Get the charset used for the string internally. */
+SfzclCharset sfzcl_str_charset_get(SfzclStr str);
+
+/** Convert a string represented as an array of binary data to
+ another array of binary data. */
+void *sfzcl_charset_convert_generic(SfzclCharset charset_in,
+ const void *str_in,
+ size_t str_in_length,
+ SfzclCharset charset_out,
+ size_t *str_out_len);
+
+/* Elementary manipulation. */
+
+/** Duplicate a string. */
+SfzclStr sfzcl_str_dup(SfzclStr str);
+
+/** Comparison. */
+typedef enum
+{
+ SFZCL_STR_ORDREL_LT = -1, /** Less than. */
+ SFZCL_STR_ORDREL_EQ = 0, /** Equal. */
+ SFZCL_STR_ORDREL_GT = 1, /** Greater than. */
+ SFZCL_STR_ORDREL_IC = 2 /** Incomparable. */
+} SfzclStrOrdRel;
+
+/** Comparison of two strings. Returns an element of the type
+ SfzclStrOrdRel */
+SfzclStrOrdRel sfzcl_str_cmp(SfzclStr op1, SfzclStr op2);
+
+/* Output conversions. */
+
+/** This function returns the string encoded into a byte sequence. */
+unsigned char *sfzcl_str_get(SfzclStr str, size_t *str_length);
+
+/** This function returns the string encoded into a byte sequence, and
+ transformed by a) taking all the 'unnecessary' whitespace away b)
+ making letters lower-case in printable strings. */
+unsigned char *sfzcl_str_get_canonical(SfzclStr str, size_t *str_length);
+
+/* Cast functions between unsigned and signed character strings. */
+
+static inline
+unsigned char *sfzcl_ustr(char *string)
+{
+ return (unsigned char *) string;
+}
+
+static inline
+const unsigned char *sfzcl_custr(const char *string)
+{
+ return (const unsigned char *) string;
+}
+
+static inline
+const char *sfzcl_csstr(const unsigned char *string)
+{
+ return (const char *) string;
+}
+
+static inline
+char *sfzcl_sstr(unsigned char *string)
+{
+ return (char *) string;
+}
+
+static inline
+unsigned char *sfzcl_ustrncpy(unsigned char *s1,
+ const unsigned char *s2, size_t n)
+{
+ return (unsigned char *) c_strncpy((char *) s1,
+ (const char *) s2,
+ n);
+}
+
+static inline
+int sfzcl_usstrcmp(const unsigned char *s1,
+ const unsigned char *s2)
+{
+ return c_strcmp((const char *) s1, (const char *) s2);
+}
+
+static inline
+int sfzcl_usstrncmp(const unsigned char *s1,
+ const unsigned char *s2,
+ size_t n)
+{
+ return c_strncmp((const char *) s1, (const char *) s2, n);
+}
+
+#endif /* SFZCLSTR_H */
+
+/* end of file sfzclstr.h */
diff --git a/core/include/sfzcl/sfzcltime.h b/core/include/sfzcl/sfzcltime.h
new file mode 100644
index 0000000..ab97b16
--- /dev/null
+++ b/core/include/sfzcl/sfzcltime.h
@@ -0,0 +1,104 @@
+/* sfzcltime.h
+
+ Calendar time retrieval and manipulation.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2006-2016 INSIDE Secure Oy. All Rights Reserved.
+*
+* The latest version of this code is available at http://www.matrixssl.org
+*
+* This software is open source; 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.
+*
+* This General Public License does NOT permit incorporating this software
+* into proprietary programs. If you are unable to comply with the GPL, a
+* commercial license for this software may be purchased from INSIDE at
+* http://www.insidesecure.com/
+*
+* This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+* http://www.gnu.org/copyleft/gpl.html
+*****************************************************************************/
+
+#ifndef SFZCLTIME_H
+#define SFZCLTIME_H
+
+typedef int64_t SfzclTime;
+
+typedef struct SfzclCalendarTimeRec
+{
+ uint8_t second; /* 0-61 */
+ uint8_t minute; /* 0-59 */
+ uint8_t hour; /* 0-23 */
+ uint8_t monthday; /* 1-31 */
+ uint8_t month; /* 0-11 */
+ int32_t year; /* Absolute value of year. 1999=1999. */
+ uint8_t weekday; /* 0-6, 0=sunday */
+ uint16_t yearday; /* 0-365 */
+ int32_t utc_offset; /* Seconds from UTC (positive=east) */
+ bool dst; /* FALSE=non-DST, TRUE=DST */
+} *SfzclCalendarTime, SfzclCalendarTimeStruct;
+
+typedef struct SfzclTimeValueRec
+{
+ int64_t seconds;
+ int64_t microseconds;
+} *SfzclTimeValue, SfzclTimeValueStruct;
+
+/* Returns seconds from epoch "January 1 1970, 00:00:00 UTC". */
+SfzclTime sfzcl_time(void);
+
+/* Fills the calendar structure according to ``current_time''. */
+void sfzcl_calendar_time(SfzclTime current_time,
+ SfzclCalendarTime calendar_ret, bool local_time);
+
+/* Return time string in RFC-2550 compatible format. Returned string
+ is allocated with SPAL_Memory_Alloc and has to be freed with SPAL_Memory_Free by
+ the caller. */
+char *sfzcl_time_string(SfzclTime input_time);
+
+/* Format time string in RFC-2550 compatible format as snprintf renderer. The
+ datum points to the SfzclTime. */
+int sfzcl_time_render(unsigned char *buf, int buf_size, int precision,
+ void *datum);
+
+/* Format time string in RFC-2550 compatible format as snprintf renderer. The
+ datum points to the memory buffer having the 32-bit long time in seconds
+ from the epoch in the network byte order. */
+int sfzcl_time32buf_render(unsigned char *buf, int buf_size, int precision,
+ void *datum);
+
+/* Return a time string that is formatted to be more or less human
+ readable. It is somewhat like the one returned by ctime(3) but
+ contains no newline in the end. Returned string is allocated with
+ SPAL_Memory_Alloc and has to be freed with SPAL_Memory_Free by the caller. */
+char *sfzcl_readable_time_string(SfzclTime input_time, bool local_time);
+
+/* Convert SfzclCalendarTime to SfzclTime. If the dst is set to TRUE then
+ daylight saving time is assumed to be set, if dst field is set to FALSE
+ then it is assumed to be off. It if it is set to -1 then the function tries
+ to find out if the dst was on or off at the time given.
+
+ Weekday and yearday fields are ignored in the conversion, but filled with
+ approriate values during the conversion. All other values are normalized to
+ their normal range during the conversion.
+
+ If the local_time is set to TRUE then dst and utc_offset values
+ are ignored.
+
+ If the time cannot be expressed as SfzclTime this function returns FALSE,
+ otherwise returns TRUE. */
+bool sfzcl_make_time(SfzclCalendarTime calendar_time,
+ SfzclTime *time_return, bool local_time);
+
+#endif /* SFZCLTIME_H */
+
+/* eof (sfzcltime.h) */
diff --git a/core/include/sfzcl/sfzcltimemeasure.h b/core/include/sfzcl/sfzcltimemeasure.h
new file mode 100644
index 0000000..5f8c936
--- /dev/null
+++ b/core/include/sfzcl/sfzcltimemeasure.h
@@ -0,0 +1,205 @@
+/* sfzcltimemeasure.h
+ */
+
+/*****************************************************************************
+* Copyright (c) 2006-2016 INSIDE Secure Oy. All Rights Reserved.
+*
+* The latest version of this code is available at http://www.matrixssl.org
+*
+* This software is open source; 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.
+*
+* This General Public License does NOT permit incorporating this software
+* into proprietary programs. If you are unable to comply with the GPL, a
+* commercial license for this software may be purchased from INSIDE at
+* http://www.insidesecure.com/
+*
+* This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+* http://www.gnu.org/copyleft/gpl.html
+*****************************************************************************/
+
+/*
+ Real time measuring.
+ */
+
+#ifndef SFZCLTIMEMEASURE_H
+#define SFZCLTIMEMEASURE_H
+
+typedef enum
+{
+ SFZCL_TIME_GRANULARITY_NANOSECOND = 0, /* 1/1000000000 seconds */
+ SFZCL_TIME_GRANULARITY_MICROSECOND, /* 1/1000000 seconds */
+ SFZCL_TIME_GRANULARITY_MILLISECOND, /* 1/1000 seconds */
+ SFZCL_TIME_GRANULARITY_SECOND, /* 1 second */
+ SFZCL_TIME_GRANULARITY_MINUTE, /* 60 seconds */
+ SFZCL_TIME_GRANULARITY_HOUR, /* 60x60 seconds */
+ SFZCL_TIME_GRANULARITY_DAY, /* 24x60x60 seconds */
+ SFZCL_TIME_GRANULARITY_WEEK, /* 7x24x60x60 seconds */
+ SFZCL_TIME_GRANULARITY_MONTH_SIDEREAL, /* 2360592 seconds */
+ SFZCL_TIME_GRANULARITY_MONTH_SYNODIC, /* 2551443 seconds */
+ SFZCL_TIME_GRANULARITY_YEAR_ANOMALISTIC, /* 31558433 seconds */
+ SFZCL_TIME_GRANULARITY_YEAR_TROPICAL, /* 31556926 seconds */
+ SFZCL_TIME_GRANULARITY_YEAR_SIDEREAL /* 31558149 seconds */
+} SfzclTimeGranularity;
+
+#define SFZCL_TIME_GRANULARITY_MONTH SFZCL_TIME_GRANULARITY_MONTH_SIDEREAL
+#define SFZCL_TIME_GRANULARITY_YEAR SFZCL_TIME_GRANULARITY_YEAR_SIDEREAL
+
+struct SfzclTimeValRec
+{
+ uint64_t seconds; /* Overlaps in 584 billion years (if really 64 bits) */
+ uint32_t nanoseconds;
+};
+
+typedef struct SfzclTimeValRec *SfzclTimeVal;
+
+struct SfzclTimeMeasureRec
+{
+ struct SfzclTimeValRec start;
+ struct SfzclTimeValRec cumulated;
+ bool running;
+};
+
+typedef struct SfzclTimeMeasureRec *SfzclTimeMeasure, SfzclTimeMeasureStruct;
+
+/*
+ * SfzclTimeT is a return type for functions returning seconds,
+ * milliseconds etc. In systems that do not support floating
+ * point numbers, it is always an integer type. Otherwise
+ * it can be either double precision floating point number or
+ * some integer type.
+ */
+
+#ifdef VXWORKS
+# undef HAVE_DOUBLE_FLOAT
+#endif
+
+#ifdef HAVE_DOUBLE_FLOAT
+typedef double SfzclTimeT;
+#else
+typedef int64_t SfzclTimeT;
+#endif
+
+/*
+ * Maximum value of time stamp. Time stamps never overwrap.
+ * They stop at SFZCL_TIME_STAMP_MAX if maximum value
+ * is exceeded.
+ */
+#define SFZCL_TIME_STAMP_MAX (~((uint64_t) 0))
+
+/*
+ * Can be used to initialize statically allocated timer.
+ * No separate `init' or `uninit' is needed, if this
+ * method is used.
+ *
+ * e.g. `static struct SfzclTimeMeasure timer =
+ * SFZCL_TIME_MEASURE_INITIALIZER;'
+ */
+#define SFZCL_TIME_MEASURE_INITIALIZER { { 0, 0 }, { 0, 0 }, FALSE }
+
+/*
+ * Init time measure structure to initial
+ * nonrunning state with zero cumulated time.
+ * This can be used instead of sfzcl_time_measure_allocate,
+ * if the timer structure is statically allocated by
+ * the application. In this case, no `uninit' function
+ * is needed. It is also initialize statically allocated
+ * timer structure with SFZCL_TIME_MEASURE_INITIALIZER.
+ */
+void sfzcl_time_measure_init(SfzclTimeMeasure timer);
+
+/*
+ * Allocates and returns a new nonrunning timer object.
+ */
+SfzclTimeMeasure sfzcl_time_measure_allocate(void);
+
+/*
+ * Frees an allocated timer object.
+ */
+void sfzcl_time_measure_free(SfzclTimeMeasure timer);
+
+/*
+ * Start the timer.
+ */
+void sfzcl_time_measure_start(SfzclTimeMeasure timer);
+
+/*
+ * Stop the timer.
+ */
+void sfzcl_time_measure_stop(SfzclTimeMeasure timer);
+
+/*
+ * Return TRUE if timer is running.
+ */
+bool sfzcl_time_measure_running(SfzclTimeMeasure timer);
+
+/*
+ * Reset the timer to zero.
+ * If timer is running before this call, the timer runs
+ * also after reset.
+ */
+void sfzcl_time_measure_reset(SfzclTimeMeasure timer);
+
+/*
+ * Set the timer to given value in seconds and nanoseconds (10e-9s).
+ * If timer is running before this call, the timer runs
+ * also after set operation.
+ */
+void sfzcl_time_measure_set_value(SfzclTimeMeasure timer,
+ uint64_t seconds, uint32_t nanoseconds);
+
+/*
+ * Get the cumulated running time of the timer.
+ * Timer can be either runnung or stopped.
+ */
+void sfzcl_time_measure_get_value(SfzclTimeMeasure timer,
+ uint64_t *seconds, uint32_t *nanoseconds);
+
+/*
+ * Return a time stamp from timer. Values returned by this function
+ * never overwrap. Instead if maximum timer value is exceeded,
+ * SFZCL_TIME_STAMP_MAX is always returned.
+ */
+uint64_t sfzcl_time_measure_stamp(SfzclTimeMeasure timer,
+ SfzclTimeGranularity granularity);
+/*
+ * Get the cumulated running time of the timer in seconds.
+ * Be aware that depending on SfzclTimeT, timer can overwrap
+ * at some point.
+ */
+SfzclTimeT sfzcl_time_measure_get(SfzclTimeMeasure timer,
+ SfzclTimeGranularity granularity);
+
+/*
+ * Calculate difference between time values beg and end and store
+ * result to ret.
+ */
+void sfzcl_time_measure_difference(SfzclTimeVal ret,
+ SfzclTimeVal beg, SfzclTimeVal end);
+
+/*
+ * Add time values tv1 and tv2 together and store result to ret.
+ */
+void sfzcl_time_measure_add(SfzclTimeVal ret, SfzclTimeVal tv1,
+ SfzclTimeVal tv2);
+
+/*
+ * A function implementing system time queries for different platforms.
+ * Be aware that granularity of time measurement may vary on different
+ * hardware and operating systems. Returns FALSE, if system time can't
+ * be retrieved (i.e. system call fails). This function returns time
+ * measured from arbitrary moment in the past. This can be time of
+ * last boot or some other random epoch.
+ */
+bool sfzcl_time_measure_system_time(SfzclTimeVal timeval);
+
+#endif /* ! SFZCLTIMEMEASURE_H */
+/* eof (sfzcltimemeasure.h) */
diff --git a/core/include/testsupp/info.h b/core/include/testsupp/info.h
new file mode 100644
index 0000000..1a8dc45
--- /dev/null
+++ b/core/include/testsupp/info.h
@@ -0,0 +1,55 @@
+/* info.h
+ *
+ * Helper for tests: Get information on platform.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2018 INSIDE Secure Oy. All Rights Reserved.
+*
+* The latest version of this code is available at http://www.matrixssl.org
+*
+* This software is open source; 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.
+*
+* This General Public License does NOT permit incorporating this software
+* into proprietary programs. If you are unable to comply with the GPL, a
+* commercial license for this software may be purchased from INSIDE at
+* http://www.insidesecure.com/
+*
+* This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\
+* http://www.gnu.org/copyleft/gpl.html
+*****************************************************************************/
+
+#ifndef TESTSUPP_INFO_H
+#define TESTSUPP_INFO_H 1
+
+#include "osdep_stdlib.h"
+
+static inline int TargetIs64Bit(void)
+{
+ /* Works for most environments. */
+ return sizeof(void *) > 4 || sizeof(long) > 4;
+}
+
+static inline int TargetEnableSlowTests(void)
+{
+ /* Allow tests which can take a long time. */
+ return !!Getenv("ENABLE_SLOW_TESTS") ||
+ !!Getenv("ENABLE_VERY_SLOW_TESTS");
+}
+
+static inline int TargetEnableVerySlowTests(void)
+{
+ /* Allow tests which can take a very long time. */
+ return !!Getenv("ENABLE_VERY_SLOW_TESTS");
+}
+
+#endif /* TESTSUPP_INFO_H */
diff --git a/core/include/testsupp/sfzutf-perf.h b/core/include/testsupp/sfzutf-perf.h
new file mode 100644
index 0000000..09d3c2a
--- /dev/null
+++ b/core/include/testsupp/sfzutf-perf.h
@@ -0,0 +1,150 @@
+/* sfzutf-perf.h
+ *
+ * Description: SFZUTF performance test suite header.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2008-2016 INSIDE Secure Oy. All Rights Reserved.
+*
+* The latest version of this code is available at http://www.matrixssl.org
+*
+* This software is open source; 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.
+*
+* This General Public License does NOT permit incorporating this software
+* into proprietary programs. If you are unable to comply with the GPL, a
+* commercial license for this software may be purchased from INSIDE at
+* http://www.insidesecure.com/
+*
+* This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\
+* http://www.gnu.org/copyleft/gpl.html
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_SFZUTF_PERF_H
+#define INCLUDE_GUARD_SFZUTF_PERF_H
+
+/* Include generic parts of SFZ UTF framework. */
+#include "sfzutf.h"
+
+/* These values correspond to systems where we use up-to 64 bits per
+ recorded time. Test count 10 is often quite good. Need to consider
+ making it more configurable. */
+
+#define SFZUTF_PERFTEST_ENTRIES 20
+#define SFZUTF_PERFTEST_COUNT 10
+#define SFZUTF_PERFTEST_ENTRIES_PER_COUNT 2
+
+/* START_PERF_TEST(name)/END_TEST pair allow defining performance tests. */
+
+void sfzutf_perf_test_begin(const char *funcname,
+ uint32_t repeats,
+ uint32_t perftest_array[SFZUTF_PERFTEST_ENTRIES]);
+void sfzutf_perf_test_update(uint32_t perftest_array_ent[
+ SFZUTF_PERFTEST_ENTRIES_PER_COUNT]);
+void sfzutf_perf_test_end(const char *funcname,
+ uint32_t perftest_array[SFZUTF_PERFTEST_ENTRIES]);
+
+#define PERF_INIT \
+ sfzutf_perf_test_begin(__func__, perftest_repeats, perftest_array); \
+ do \
+ { \
+ do
+
+#define PERF_TEST_BEGIN(repeats) \
+ uint32_t perftest_repeats = repeats; \
+ uint32_t perftest_array[SFZUTF_PERFTEST_ENTRIES]; \
+ uint32_t perftest_counter = 0
+
+#define START_PERF_TEST(name, repeats) \
+ START_TEST(name) \
+ { \
+ uint32_t perftest_repeats = repeats; \
+ uint32_t perftest_array[SFZUTF_PERFTEST_ENTRIES]; \
+ uint32_t perftest_counter = 0;
+
+#define PERF_EXIT \
+ while (0); \
+ sfzutf_perf_test_update(&perftest_array[perftest_counter * \
+ SFZUTF_PERFTEST_ENTRIES_PER_COUNT]); \
+ } while (++perftest_counter < SFZUTF_PERFTEST_COUNT); \
+ sfzutf_perf_test_end(__func__, perftest_array);
+
+#define END_PERF_TEST } \
+ END_TEST
+
+#ifdef SFZUTF_USE_PERF_WITH_CHECK
+/* Runs performance tests with bit diminished performance but checks
+ the results.
+ Notice: in this mode these completely match fail*(). */
+
+# define perf_fail_if(expr, ...) \
+ do { \
+ if (expr) { \
+ SFZUTF_FAILURE(1, "Failure '"#expr "' occurred: " __VA_ARGS__); \
+ } \
+ } while (0)
+
+# define perf_fail_unless(expr, ...) \
+ do { \
+ if (!(expr)) { \
+ SFZUTF_FAILURE(1, "Failure '"#expr "' occurred: " __VA_ARGS__); \
+ } \
+ } while (0)
+
+# define perf_fail(...) fail_if(1, __VA_ARGS__)
+
+# define perf(...) __VA_ARGS__
+
+#else /* SFZUTF_USE_PERF_WITH_CHECK */
+/* Maximum performance, omits all checks. */
+# define perf_fail_if(expr, ...) do {} while (0)
+# define perf_fail_unless(expr, ...) do {} while (0)
+# define perf_fail(...) do {} while (0)
+# define perf(...) do {} while (0)
+
+#endif /* SFZUTF_USE_PERF_WITH_CHECK */
+
+#define PERF_REP1(x) x
+#define PERF_REP10(x) x; x; x; x; x; x; x; x; x; x
+#define PERF_REP10A(x) x; x; x; x; x; x; x; x; x; x
+#ifdef __i386__
+/* This may be used on all architectures with large caches. */
+# define PERF_REP100(x) PERF_REP10A(PERF_REP10(x))
+#else /* Assume small caches. */
+# define PERF_REP100(x) \
+ do { unsigned int perf_looper; \
+ for (perf_looper = 0; perf_looper < 10; perf_looper++) \
+ { PERF_REP10(x); } \
+ } while (0)
+#endif /* __i386__ */
+
+/* These macros are always used as pairs.
+ The macro to use depends on desired test accuracy and
+ speed of test.
+
+ Guidelines: FAST == symmetric cryptographic operation with
+ >= 100 MIPS processor on 256 bytes of data
+ NORMAL == same processor but up-to 4096 bytes of data
+ SLOW == asymmetric operation (sign/verify)
+
+ For non-cryptographic operations, more work is needed to apply
+ these guidelines, but you can manage it. */
+
+#define PERF_TEST_FAST /* 100 */ 10
+#define PERF_TEST_NORMAL 10
+#define PERF_TEST_SLOW 1
+#define PERF_EXECUTE_TEST_FAST(x) /* PERF_REP100 */ PERF_INIT { PERF_REP10(x); } PERF_EXIT
+#define PERF_EXECUTE_TEST_NORMAL(x) PERF_INIT { PERF_REP10(x); } PERF_EXIT
+#define PERF_EXECUTE_TEST_SLOW(x) PERF_INIT { PERF_REP1(x); } PERF_EXIT
+
+#endif /* Include Guard */
+
+/* end of file sfzutf-perf.h */
diff --git a/core/include/testsupp/sfzutf-utils.h b/core/include/testsupp/sfzutf-utils.h
new file mode 100644
index 0000000..dfc3a48
--- /dev/null
+++ b/core/include/testsupp/sfzutf-utils.h
@@ -0,0 +1,152 @@
+/* sfzutf-utils.h
+ *
+ * Description: SFZUTF utility routines header.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2008-2016 INSIDE Secure Oy. All Rights Reserved.
+*
+* The latest version of this code is available at http://www.matrixssl.org
+*
+* This software is open source; 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.
+*
+* This General Public License does NOT permit incorporating this software
+* into proprietary programs. If you are unable to comply with the GPL, a
+* commercial license for this software may be purchased from INSIDE at
+* http://www.insidesecure.com/
+*
+* This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\
+* http://www.gnu.org/copyleft/gpl.html
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_SFZUTF_UTILS_H
+#define INCLUDE_GUARD_SFZUTF_UTILS_H
+
+#include "public_defs.h"
+#include "sfzutf.h"
+
+/* To supplement common need. */
+uint32_t sfzutf_strlen(const char *str);
+
+enum SfzUtfPtrSizeFormat
+{
+ SFZUTF_PTRSIZE_STRING_MSB_FIRST,
+ SFZUTF_PTRSIZE_STRING_LSB_FIRST,
+ SFZUTF_PTRSIZE_STRING_TEXT,
+};
+
+/* Short notations. */
+#define SUPS_MSBF SFZUTF_PTRSIZE_STRING_MSB_FIRST
+#define SUPS_LSBF SFZUTF_PTRSIZE_STRING_LSB_FIRST
+#define SUPS_TEXT SFZUTF_PTRSIZE_STRING_TEXT
+
+typedef struct sfzutf_ptrsize
+{
+ void *ptr;
+ uint32_t size;
+ uint32_t len;
+ enum SfzUtfPtrSizeFormat format;
+} SfzUtfPtrSize;
+
+/* Identifier for ptrsize purpose. */
+typedef unsigned short SfzUtfUtilsID;
+
+typedef struct sfzutf_ptrsize_ext
+{
+ SfzUtfPtrSize base;
+ struct sfzutf_ptrsize_ext *next;
+ SfzUtfEvent livetime;
+ SfzUtfUtilsID *purpose;
+ unsigned long long foralignment;
+} SfzUtfPtrSizeExt;
+
+SfzUtfPtrSize sfzutf_ptrsize_blank(uint32_t size);
+char *sfzutf_ptrsize_to_str(SfzUtfPtrSize sups);
+SfzUtfPtrSize sfzutf_ptrsize_from_str(const char *string,
+ enum SfzUtfPtrSizeFormat format);
+SfzUtfPtrSize sfzutf_ptrsize_from_mem(const void *mem,
+ uint32_t memlength,
+ enum SfzUtfPtrSizeFormat format);
+void sfzutf_ptrsize_free(SfzUtfPtrSize sups);
+
+SfzUtfPtrSize sfzutf_ptrsize_fill_with_ptrsize(SfzUtfPtrSize empty_target,
+ SfzUtfPtrSize filler);
+
+#define sfzutf_ptrsize_eq_ptrsize(ptrsize_1, ptrsize_2) \
+ (sfzutf_ptrsize_cmp_ptrsize(ptrsize_1, ptrsize_2) == 0)
+
+#define sfzutf_ptrsize_eq_str(ptrsize_1, str, format) \
+ (sfzutf_ptrsize_cmp_str(ptrsize_1, str, format) == 0)
+
+#define sfzutf_ptrsize_eq_mem(ptrsize_1, mem, len, format) \
+ (sfzutf_ptrsize_cmp_mem(ptrsize_1, mem, len, format) == 0)
+
+int sfzutf_ptrsize_cmp_ptrsize(SfzUtfPtrSize ptrsize_1,
+ SfzUtfPtrSize ptrsize_2);
+
+/* SFZUTF ptrsize default livetime is single test.
+ This function sets the livetime
+ (until end of test, testcase, suite or global). */
+void sfzutf_ptrsize_set_livetime(SfzUtfPtrSize ps,
+ SfzUtfEvent livetime);
+
+/* Extended ptrsize allocator. Avoid using the function directly. */
+void *sfzutf_ptrsize_ext_alloc(size_t size,
+ bool clear,
+ SfzUtfUtilsID *purpose,
+ SfzUtfEvent livetime);
+
+/* Entrypoint called by sfzutf core on various events.
+ Do not call directly. */
+void sfzutf_utils_event(SfzUtfEvent event,
+ const char *name,
+ const void *struct_ptr);
+
+/* Functions for discovering a ptrsize.
+ Do not call directly. */
+SfzUtfPtrSizeExt *sfzutf_find_ptrsize_ext_by_address(void *memaddress);
+SfzUtfPtrSizeExt *sfzutf_find_ptrsize_ext_by_purpose(SfzUtfUtilsID *purpose);
+SfzUtfPtrSizeExt *sfzutf_find_ptrsize_ext_by_livetime(SfzUtfEvent livetime);
+
+#define SFZUTF_UTILS_NEED_TEMPORARY(name, scope) \
+ do { \
+ static SfzUtfUtilsID name ## _id; \
+ SfzUtfPtrSizeExt *ex_T = sfzutf_find_ptrsize_ext_by_purpose( \
+ &name ## _id); \
+ if (ex_T) { name = ex_T->base.ptr; } else { name = NULL; } \
+ if (name == NULL) { name = sfzutf_ptrsize_ext_alloc(sizeof(*name), \
+ 1, \
+ &name ## _id, \
+ scope); } \
+ name = sfzutf_AssertNotNull(name); \
+ } while (0)
+
+/* Same than SFZUTF_NEED_TEMPORARY, but reservation is skipped if space
+ is not available. (Need to check pointer for null.) */
+#define SFZUTF_UTILS_TEMPORARY_BEGIN(name, scope) \
+ do { \
+ static SfzUtfUtilsID name ## _id; \
+ SfzUtfPtrSizeExt *ex_T = sfzutf_find_ptrsize_ext_by_purpose( \
+ &name ## _id); \
+ if (ex_T) { name = ex_T->base.ptr; } else { name = NULL; } \
+ if (name == NULL) { name = sfzutf_ptrsize_ext_alloc(sizeof(*name), \
+ 1, \
+ &name ## _id, \
+ scope); } \
+ if (!name) { unsupported_quick("Memory Not Available"); break; }
+
+#define SFZUTF_UTILS_TEMPORARY_END \
+ } while (0)
+
+#endif /* Include Guard */
+
+/* end of file sfzutf-utils.h */
diff --git a/core/include/testsupp/sfzutf.h b/core/include/testsupp/sfzutf.h
new file mode 100644
index 0000000..04472a2
--- /dev/null
+++ b/core/include/testsupp/sfzutf.h
@@ -0,0 +1,228 @@
+/* sfzutf.h
+ *
+ * Description: SFZUTF header.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2008-2016 INSIDE Secure Oy. All Rights Reserved.
+*
+* The latest version of this code is available at http://www.matrixssl.org
+*
+* This software is open source; 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.
+*
+* This General Public License does NOT permit incorporating this software
+* into proprietary programs. If you are unable to comply with the GPL, a
+* commercial license for this software may be purchased from INSIDE at
+* http://www.insidesecure.com/
+*
+* This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\
+* http://www.gnu.org/copyleft/gpl.html
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_SFZUTF_H
+#define INCLUDE_GUARD_SFZUTF_H
+
+#include "implementation_defs.h"
+
+/* Events related to test suite processing. */
+typedef enum
+{
+ SFZUTF_EVENT_BEGIN,
+ SFZUTF_EVENT_SUITE_BEGIN,
+ SFZUTF_EVENT_TCASE_BEGIN,
+ SFZUTF_EVENT_TEST_BEGIN,
+ SFZUTF_EVENT_TEST_END,
+ SFZUTF_EVENT_TCASE_END,
+ SFZUTF_EVENT_SUITE_END,
+ SFZUTF_EVENT_END,
+} SfzUtfEvent;
+
+/* Not using check from sourceforge => Need to define replacements here. */
+typedef void (*TFun)(int _i);
+typedef void (*SFun)(void);
+
+/* This is internal macro that implements FAILURE reporting via
+ implementation_defs.h */
+#ifdef GCOV_PROFILE
+void
+__gcov_flush(); /* Function to write profiles on disk. */
+
+# define SFZUTF_FAILURE(stub, ...) \
+ do { __gcov_flush(); \
+ L_TESTLOG(LF_FAILURE, __VA_ARGS__); \
+ DEBUG_abort(); \
+ } while (0)
+
+# define SFZUTF_UNSUPPORTED(...) \
+ __gcov_flush(); \
+ L_TESTLOG(LF_TEST_UNSUPPORTED, "Test unsupported"); \
+ fail(__VA_ARGS__) \
+
+#else /* !GCOV_PROFILE */
+# define SFZUTF_FAILURE(stub, ...) \
+ do { L_TESTLOG(LF_FAILURE, __VA_ARGS__); \
+ DEBUG_abort(); \
+ } while (0)
+
+# define SFZUTF_UNSUPPORTED(...) \
+ L_TESTLOG(LF_TEST_UNSUPPORTED, "Test unsupported"); \
+ fail(__VA_ARGS__)
+
+#endif /* GCOV_PROFILE */
+
+#define fail_if(expr, ...) \
+ do { \
+ if (expr) { \
+ SFZUTF_FAILURE(1, "Failure '"#expr "' occurred: " __VA_ARGS__); \
+ } \
+ } while (0)
+
+#define fail_unless(expr, ...) \
+ do { \
+ if (!(expr)) { \
+ SFZUTF_FAILURE(1, "Failure '"#expr "' occurred: " __VA_ARGS__); \
+ } \
+ } while (0)
+
+#define fail(...) fail_if(1, __VA_ARGS__)
+
+/* Mark test as unsupported if condition is true. */
+#define unsupported(...) \
+ do { \
+ SFZUTF_UNSUPPORTED(__VA_ARGS__); \
+ } while (0)
+
+#define unsupported_if(expr, ...) \
+ do { \
+ if (expr) { \
+ SFZUTF_UNSUPPORTED(__VA_ARGS__); \
+ } \
+ } while (0)
+
+#define unsupported_unless(expr, ...) \
+ do { \
+ if (!(expr)) { \
+ SFZUTF_UNSUPPORTED(__VA_ARGS__); \
+ } \
+ } while (0)
+
+#define unsupported_quick(...) \
+ do { \
+ L_TESTLOG(LF_TEST_NOTE_UNSUPPORTED, __VA_ARGS__); \
+ sfzutf_unsupported_quick(); \
+ } while (0)
+
+/* Test can declare that certain effect happening is to be considered
+ successful test, to be able to test error situation handling, even
+ for fatal errors. */
+#ifdef IMPLDEFS_CF_DISABLE_ASSERT
+
+# define SFZUTF_EXPECT_ASSERT \
+ unsupported("Assertions disabled.")
+
+#else /* !IMPLDEFS_CF_DISABLE_ASSERT */
+
+# define SFZUTF_EXPECT_ASSERT \
+ L_TESTLOG(LF_TEST_EXPECT_ASSERT, "expected assertion")
+
+#endif /* !IMPLDEFS_CF_DISABLE_ASSERT */
+
+#ifdef IMPLDEFS_CF_DISABLE_PRECONDITION
+
+# define SFZUTF_EXPECT_PRECONDITION \
+ unsupported("Preconditions disabled.")
+
+#else /* !IMPLDEFS_CF_DISABLE_PRECONDITION */
+
+# define SFZUTF_EXPECT_PRECONDITION \
+ L_TESTLOG(LF_TEST_EXPECT_PRECONDITION, "expected precondition")
+
+#endif /* !IMPLDEFS_CF_DISABLE_PRECONDITION */
+
+/* Provided for completeness. There should be no valid use for this. */
+#ifdef IMPLDEFS_CF_DISABLE_POSTCONDITION
+
+# define SFZUTF_EXPECT_POSTCONDITION \
+ unsupported("Postconditions disabled.")
+
+#else /* !IMPLDEFS_CF_DISABLE_POSTCONDITION */
+
+# define SFZUTF_EXPECT_POSTCONDITION \
+ L_TESTLOG(LF_TEST_EXPECT_POSTCONDITION, "expected postcondition")
+
+#endif /* !IMPLDEFS_CF_DISABLE_POSTCONDITION */
+
+#define START_TEST(name) \
+ static void name(int _i) \
+ { \
+ const char *funcname = #name; \
+ L_TESTLOG(LF_TESTFUNC_INVOKED, "%s:%d", #name, _i); \
+ do
+
+#define END_TEST while (0); \
+ if (sfzutf_unsupported_quick_process()) { \
+ L_TESTLOG(LF_TESTFUNC_UNSUPPORTED_QUICK, "%s:%d", funcname, _i); \
+ } else { \
+ L_TESTLOG(LF_TESTFUNC_SUCCESS, "%s:%d", funcname, _i); \
+ } \
+ }
+
+
+/* These are like START_TEST, but for fixtures whose are global. */
+#define DECLARE_FIXTURE_SETUP(name) void name(void)
+#define START_FIXTURE_SETUP(name) void name(void)
+#define END_FIXTURE_SETUP
+
+#define DECLARE_FIXTURE_TEARDOWN(name) void name(void)
+#define START_FIXTURE_TEARDOWN(name) void name(void)
+#define END_FIXTURE_TEARDOWN
+
+/* Each suite needs to provide this interface */
+void build_suite(void);
+
+/* Check allocation was successful. */
+void *sfzutf_AssertNotNull(const void *input);
+
+/* Helper for handier suite creation. */
+void sfzutf_suite_create(const char *name);
+void sfzutf_tcase_create(const char *name);
+void sfzutf_tcase_finish(void);
+
+#define sfzutf_test_add(func) sfzutf_test_add_fname(func, ""#func "")
+void sfzutf_test_add_fname(TFun TestFunc, const char *TestFuncName);
+
+#define sfzutf_loop_test_add(func, mi, ma) \
+ sfzutf_loop_test_add_fname(func, ""#func "", mi, ma)
+void sfzutf_loop_test_add_fname(TFun TestFunc,
+ const char *TestFuncName,
+ int mi, int ma);
+
+void sfzutf_tcase_add_fixture(SFun start, SFun end);
+
+void sfzutf_unsupported_quick(void);
+bool sfzutf_unsupported_quick_process(void);
+
+void sfzutf_interactive_start(
+ int (*getinputfunc)(char * const c_p));
+
+
+#ifdef STACK_MEASUREMENT
+# include "sfzutf-stack.h"
+#endif
+
+#ifdef HEAP_MEASUREMENT
+# include "sfzutf-heap.h"
+#endif
+
+#endif /* Include Guard */
+
+/* end of file sfzutf.h */
diff --git a/core/include/testsupp/testsupp.h b/core/include/testsupp/testsupp.h
new file mode 100644
index 0000000..5627847
--- /dev/null
+++ b/core/include/testsupp/testsupp.h
@@ -0,0 +1,270 @@
+/**
+ * @file testsupp.h
+ * @version $Format:%h%d$
+ *
+ * Common testing framework for building test programs.
+ */
+/*
+ * Copyright (c) 2017-2018 INSIDE Secure Corporation
+ * All Rights Reserved
+ *
+ * The latest version of this code is available at http://www.matrixssl.org
+ *
+ * This software is open source; 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.
+ *
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
+ *
+ * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+/******************************************************************************/
+
+#ifndef _h_TESTSUPP_H_
+# define _h_TESTSUPP_H_ 1
+
+# ifndef _h_PS_CORECONFIG
+# ifdef MATRIX_CONFIGURATION_INCDIR_FIRST
+# include /* Must be first included */
+# else
+# include "coreConfig.h" /* Must be first included */
+# endif
+# endif /* _h_PS_CORECONFIG */
+
+#include "cl_header_begin.h"
+
+/* Classification of test results. */
+typedef enum { OK, FAILED, WEAK, SKIPPED } TEST_RESULT;
+
+# ifndef TEST_TAG
+/* It is recommended to override the tag. */
+# define TEST_TAG TEST
+# endif /* TEST_TAG */
+
+# define debugf(x, ...) PS_LOGF_TRACE(TEST_TAG, x ,##__VA_ARGS__ )
+
+/* Internal variable for extended status information. */
+extern char extra_info[128];
+
+/* Breakpoint for tests. */
+int test(int condition);
+
+/* Breakpoint for failures. */
+TEST_RESULT fail(void);
+
+/* Reporting failures. */
+TEST_RESULT fail_at(const char *file, int line, const char *cond);
+
+/* Convenience macro for ensuring condition is true. */
+#define FAIL_IF(condition) \
+ do { \
+ if (test(condition)) { \
+ return fail_at(__FILE__, __LINE__, #condition); } \
+ } while (0)
+
+/* Find tests from command line input. */
+int test_match(int argc, char **argv, const char *string);
+
+/* List test. */
+# define TEST(fun) \
+ do { \
+ int res; \
+ if (argc == 2 && argv[1] != NULL && \
+ !Strcmp(argv[1], "--list")) { \
+ Printf("%s\n", #fun); \
+ break; \
+ } else if (test_match(argc, argv, #fun)) { \
+ Printf("%s ... ", #fun); \
+ Fflush(stdout); \
+ res = fun(); \
+ counter[(int) res]++; \
+ Printf("%s%s\n", res == OK ? "OK" : \
+ res == WEAK ? "OK (but size considered weak)" : \
+ res == SKIPPED ? "OK (not supported)" : \
+ "FAILED", extra_info); \
+ extra_info[0] = 0; \
+ } \
+ } while (0)
+
+TEST_RESULT ok_partial(const char *file, int line);
+#define OK_PARTIAL ok_partial(__FILE__, __LINE__)
+
+extern int counter[4];
+
+/* Provide usual facilities. */
+void testsupp_start_test_program(int argc, char **argv);
+
+/* Give test statistics. */
+int testsupp_summarize_results(void);
+
+/* Finish test, with handling of a special case: listing of tests.
+ Also includes testsupp_summarize_results() when needed. */
+int testsupp_finish(void);
+
+/* Process all tests registered via TestAdd(). */
+void testsupp_process(int argc, char **argv);
+
+/* Provide main.
+ Without oldstyle tests TESTSUPP_MAIN() will suffice. */
+#define TESTSUPP_MAIN(possible_oldstyle_test_and_semicolon) \
+int main(int argc, char **argv) \
+{ \
+ testsupp_start_test_program(argc, argv); \
+ testsupp_process(argc, argv); \
+ possible_oldstyle_test_and_semicolon \
+ return testsupp_finish(); \
+} \
+extern int require_semicolon
+
+/* Alternatively the test needs to implement main function.
+ Something like this: */
+# ifdef EXAMPLE_MAIN
+int main(int argc, char **argv)
+{
+ testsupp_start_test_program(argc, argv);
+ testsupp_process(argc, argv);
+
+ /* Tests can also be executed using the old style:
+ Define test function, list it with TEST(). */
+ TEST(TEST_OldStyle);
+
+ return testsupp_finish();
+}
+# endif /* EXAMPLE_MAIN */
+
+/* Internal part: using test entries directly. */
+
+#include "list.h"
+
+/* Defines single test, including its name, function to execute and
+ desired outcome. */
+struct TestEntry
+{
+ const char *TestName;
+ void *TestParameter;
+ enum { TEST_DISABLED, TEST_ENABLED } TestStatus;
+ TEST_RESULT TestExpectedResult;
+ TEST_RESULT (*TestFunction)(void);
+ void (*TestFreeFunction)(void);
+ DLListEntry dle;
+};
+
+/* Get name of the current test. */
+const char *CurrentTestGetName(void);
+
+/* Get parameter (generic void * pointer) of the current test. */
+void *CurrentTestGetParameter(void);
+
+/* Add test to list of tests. */
+void TestAdd(struct TestEntry *te);
+
+/* Process tests: print or execute them. */
+void TestProcess(int argc, char **argv);
+
+/* Clean memory reserved for tests. */
+void TestCleanup(void);
+
+/* Default AUTO_TEST parameters. */
+extern struct TestEntry AutoTestEntryDefault;
+
+/* Add test to list of tests to perform. */
+#define AUTO_TEST_ADD(name) AUTO_TEST_ADD_COMMON(name, )
+
+/* Add test to list, but disable it for now.
+ Test will only run if explicitly requested. */
+#define AUTO_TEST_ADD_DISABLED(name) \
+ AUTO_TEST_ADD_COMMON(name, te.TestStatus = TEST_DISABLED;)
+
+/* Add test to list, but expect it to fail.
+ This will reverse interpretation of test results. */
+#define AUTO_TEST_ADD_XFAIL(name) \
+ AUTO_TEST_ADD_COMMON(name, te.TestExpectedResult = FAILED;)
+
+/* Define a test and add it to tests to perform. */
+#define AUTO_TEST(name) AUTO_TEST_ADD(name); TEST_RESULT name(void)
+
+/* Define a test and add it to list of tests, but do not run it by default. */
+#define AUTO_TEST_DISABLED(name) \
+ AUTO_TEST_ADD_DISABLED(name); TEST_RESULT name(void)
+
+/* Define a test and add it to list of tests.
+ The test is expected to fail for now.
+ (E.g. missing test or software feature.) */
+#define AUTO_TEST_XFAIL(name) \
+ AUTO_TEST_ADD_XFAIL(name); TEST_RESULT name(void)
+
+/* Worker macros. */
+#define AUTO_TEST_ADD_CONCAT_(s_a, s_b) s_a ## s_b
+#define AUTO_TEST_ADD_CONCAT(s_a, s_b) AUTO_TEST_ADD_CONCAT_(s_a, s_b)
+
+/* Worker macro, use AUTO_TEST or AUTO_TEST_ADD etc. instead. */
+#define AUTO_TEST_ADD_COMMON(name, extra_code) \
+TEST_RESULT name(void); \
+static void AUTO_TEST_ADD_CONCAT(name,_constructor_auto_add)(void) \
+ PS_GCC_SPECIFIC(__attribute__((__constructor__))); \
+ \
+static void AUTO_TEST_ADD_CONCAT(name,_constructor_auto_add)(void) \
+{ \
+ static struct TestEntry te; \
+ te.TestName = #name; \
+ te.TestParameter = AutoTestEntryDefault.TestParameter; \
+ te.TestStatus = AutoTestEntryDefault.TestStatus; \
+ te.TestExpectedResult = AutoTestEntryDefault.TestExpectedResult; \
+ te.TestFunction = &name; \
+ te.TestFreeFunction = AutoTestEntryDefault.TestFreeFunction; \
+ extra_code \
+ \
+ TestAdd(&te); \
+}
+
+/* Examples of tests */
+# ifdef DO_NOT_COMPILE_TEST_EXAMPLES
+
+/* These examples intent to illustrate how to use AUTO_TEST and
+ its variants. (Note: also remember to use TESTSUPP_MAIN or equivalent. */
+
+AUTO_TEST(TEST_Arithmetic)
+{
+ FAIL_IF(1 + 1 != 2);
+ return OK;
+}
+
+AUTO_TEST(TEST_Arithmetic2)
+{
+ FAIL_IF(1 * 1 != 1);
+ return OK;
+}
+
+AUTO_TEST_DISABLED(TEST_Arithmetic3)
+{
+ /* Disabled the test due to a small error in the test. */
+ /* Test can be executed if explicitly requested. */
+ FAIL_IF(1.5 * 1.5 != 2.0);
+ return OK;
+}
+
+#include "math.h"
+AUTO_TEST_XFAIL(TEST_Arithmetic4)
+{
+ /* This test fails on most devices, because of math library precision. */
+ FAIL_IF(M_PI != 3.14);
+ return OK;
+}
+
+# endif /* DO_NOT_COMPILE_TEST_EXAMPLES */
+
+#include "cl_header_end.h"
+
+#endif /* testsupp.h */
+/* end of file testsupp.h */
diff --git a/core/include/testsupp/testsupp.hpp b/core/include/testsupp/testsupp.hpp
new file mode 100644
index 0000000..fb7a833
--- /dev/null
+++ b/core/include/testsupp/testsupp.hpp
@@ -0,0 +1,114 @@
+/* testsupp.hpp
+ *
+ * SafeZone/MatrixSSL specific wrapper for catch.hpp.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2017 INSIDE Secure Oy. All Rights Reserved.
+*
+* The latest version of this code is available at http://www.matrixssl.org
+*
+* This software is open source; 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.
+*
+* This General Public License does NOT permit incorporating this software
+* into proprietary programs. If you are unable to comply with the GPL, a
+* commercial license for this software may be purchased from INSIDE at
+* http://www.insidesecure.com/
+*
+* This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\
+* http://www.gnu.org/copyleft/gpl.html
+*****************************************************************************/
+
+#ifndef TESTSUPP_H
+#define TESTSUPP_H 1
+
+#ifdef TESTSUPP_MAIN
+#define CATCH_CONFIG_MAIN
+#endif
+
+/* Classification of test results (for compatibility with testsupp.h). */
+typedef enum { OK, FAILED, WEAK, SKIPPED } TEST_RESULT;
+
+/* Assumes catch.hpp 1.8.2. */
+#include "thirdparty/catch.hpp"
+
+/* Helper functionality to aid with catch.hpp we have developed. */
+
+/* Converts memory containing digest into std:string 0xdigestvalue. */
+#define HEXDIGEST(output_buffer, size) \
+ Util::rawMemoryToString((const void *)(output_buffer), (size))
+
+/* Converts memory to hexadecimal (any content). */
+#define HEX(output_buffer, size) \
+ Util::rawMemoryToString((const void *)(output_buffer), (size))
+
+/* Converts any content to string. */
+#define STRING(output_buffer, size) \
+ std::string((output_buffer), (output_buffer) + (size))
+
+/* Note: Also available: opt_WRITE_FILE(filename_string, data, size). */
+
+/* ----------------------------------------------------------------------- */
+
+/* Implementation of utility functions. */
+/* Note: This is under libboost license because of sources. */
+
+/* Loaned from catch.hpp with different endianness detail: */
+namespace Util {
+
+ const std::string unprintableString = "{?}";
+
+ static inline std::string rawMemoryToString(
+ const void *object,
+ std::size_t size)
+ {
+ // Reverse order for little endian architectures
+ int i = 0, end = static_cast( size ), inc = 1;
+
+ unsigned char const *bytes = static_cast(object);
+ std::ostringstream os;
+ os << "0x" << std::setfill('0') << std::hex;
+ for( ; i != end; i += inc )
+ os << std::setw(2) << static_cast(bytes[i]);
+ return os.str();
+ }
+}
+
+bool testsupp_write_debug_files;
+static inline
+void opt_WRITE_FILE(
+ const char *target,
+ const void *data,
+ size_t data_length)
+{
+ FILE *f;
+
+ if (!testsupp_write_debug_files && !getenv("TESTSUPP_WRITE_DEBUG_FILES"))
+ {
+ return; /* Do not produce debugging files. */
+ }
+
+ f = fopen(target, "w");
+ if (f)
+ {
+ if (fwrite(data, data_length, 1, f) != 1)
+ {
+ fprintf(stderr, "write error\n");
+ exit(1);
+ }
+ fprintf(stderr, "(Written %lu data bytes to %s)\n",
+ (long unsigned int) data_length, target);
+ }
+ fclose(f);
+}
+
+#endif /* testsupp.hpp */
diff --git a/core/include/testsupp/thirdparty/catch.hpp b/core/include/testsupp/thirdparty/catch.hpp
new file mode 100644
index 0000000..79036a4
--- /dev/null
+++ b/core/include/testsupp/thirdparty/catch.hpp
@@ -0,0 +1,11339 @@
+/*
+ * Catch v1.8.2
+ * Generated: 2017-03-13 21:18:33.619572
+ * ----------------------------------------------------------
+ * This file has been merged from multiple headers. Please don't edit it directly
+ * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
+#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
+
+#define TWOBLUECUBES_CATCH_HPP_INCLUDED
+
+#ifdef __clang__
+# pragma clang system_header
+#elif defined __GNUC__
+# pragma GCC system_header
+#endif
+
+// #included from: internal/catch_suppress_warnings.h
+
+#ifdef __clang__
+# ifdef __ICC // icpc defines the __clang__ macro
+# pragma warning(push)
+# pragma warning(disable: 161 1682)
+# else // __ICC
+# pragma clang diagnostic ignored "-Wglobal-constructors"
+# pragma clang diagnostic ignored "-Wvariadic-macros"
+# pragma clang diagnostic ignored "-Wc99-extensions"
+# pragma clang diagnostic ignored "-Wunused-variable"
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wpadded"
+# pragma clang diagnostic ignored "-Wc++98-compat"
+# pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
+# pragma clang diagnostic ignored "-Wswitch-enum"
+# pragma clang diagnostic ignored "-Wcovered-switch-default"
+# endif
+#elif defined __GNUC__
+# pragma GCC diagnostic ignored "-Wvariadic-macros"
+# pragma GCC diagnostic ignored "-Wunused-variable"
+
+ // For newer version we can use __Pragma to disable the warnings locally
+# if __GNUC__ == 4 && __GNUC_MINOR__ >= 4 && __GNUC_MINOR__ <= 7
+# pragma GCC diagnostic ignored "-Wparentheses"
+# endif
+
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wpadded"
+#endif
+#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
+# define CATCH_IMPL
+#endif
+
+#ifdef CATCH_IMPL
+# ifndef CLARA_CONFIG_MAIN
+# define CLARA_CONFIG_MAIN_NOT_DEFINED
+# define CLARA_CONFIG_MAIN
+# endif
+#endif
+
+// #included from: internal/catch_notimplemented_exception.h
+#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED
+
+// #included from: catch_common.h
+#define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED
+
+// #included from: catch_compiler_capabilities.h
+#define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
+
+// Detect a number of compiler features - mostly C++11/14 conformance - by compiler
+// The following features are defined:
+//
+// CATCH_CONFIG_CPP11_NULLPTR : is nullptr supported?
+// CATCH_CONFIG_CPP11_NOEXCEPT : is noexcept supported?
+// CATCH_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods
+// CATCH_CONFIG_CPP11_IS_ENUM : std::is_enum is supported?
+// CATCH_CONFIG_CPP11_TUPLE : std::tuple is supported
+// CATCH_CONFIG_CPP11_LONG_LONG : is long long supported?
+// CATCH_CONFIG_CPP11_OVERRIDE : is override supported?
+// CATCH_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr)
+// CATCH_CONFIG_CPP11_SHUFFLE : is std::shuffle supported?
+// CATCH_CONFIG_CPP11_TYPE_TRAITS : are type_traits and enable_if supported?
+
+// CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported?
+
+// CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported?
+// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
+// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
+// CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
+// ****************
+// Note to maintainers: if new toggles are added please document them
+// in configuration.md, too
+// ****************
+
+// In general each macro has a _NO_ form
+// (e.g. CATCH_CONFIG_CPP11_NO_NULLPTR) which disables the feature.
+// Many features, at point of detection, define an _INTERNAL_ macro, so they
+// can be combined, en-mass, with the _NO_ forms later.
+
+// All the C++11 features can be disabled with CATCH_CONFIG_NO_CPP11
+
+#ifdef __cplusplus
+
+# if __cplusplus >= 201103L
+# define CATCH_CPP11_OR_GREATER
+# endif
+
+# if __cplusplus >= 201402L
+# define CATCH_CPP14_OR_GREATER
+# endif
+
+#endif
+
+#ifdef __clang__
+
+# if __has_feature(cxx_nullptr)
+# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
+# endif
+
+# if __has_feature(cxx_noexcept)
+# define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
+# endif
+
+# if defined(CATCH_CPP11_OR_GREATER)
+# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
+ _Pragma( "clang diagnostic push" ) \
+ _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
+# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
+ _Pragma( "clang diagnostic pop" )
+# endif
+
+#endif // __clang__
+
+////////////////////////////////////////////////////////////////////////////////
+// Cygwin
+#ifdef __CYGWIN__
+
+# if !defined(CATCH_CONFIG_POSIX_SIGNALS)
+# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
+# endif
+
+// Required for some versions of Cygwin to declare gettimeofday
+// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
+# define _BSD_SOURCE
+
+#endif // __CYGWIN__
+
+////////////////////////////////////////////////////////////////////////////////
+// Borland
+#ifdef __BORLANDC__
+
+#endif // __BORLANDC__
+
+////////////////////////////////////////////////////////////////////////////////
+// EDG
+#ifdef __EDG_VERSION__
+
+#endif // __EDG_VERSION__
+
+////////////////////////////////////////////////////////////////////////////////
+// Digital Mars
+#ifdef __DMC__
+
+#endif // __DMC__
+
+////////////////////////////////////////////////////////////////////////////////
+// GCC
+#ifdef __GNUC__
+
+# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+# define CATCH_GCC_HAS_NEW_PRAGMA
+# endif
+
+# if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)
+# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
+# endif
+
+# if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) && defined(CATCH_GCC_HAS_NEW_PRAGMA)
+# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
+ _Pragma( "GCC diagnostic push" ) \
+ _Pragma( "GCC diagnostic ignored \"-Wparentheses\"" )
+# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
+ _Pragma( "GCC diagnostic pop" )
+# endif
+
+// - otherwise more recent versions define __cplusplus >= 201103L
+// and will get picked up below
+
+#endif // __GNUC__
+
+////////////////////////////////////////////////////////////////////////////////
+// Visual C++
+#ifdef _MSC_VER
+
+#define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
+
+#if (_MSC_VER >= 1600)
+# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
+# define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
+#endif
+
+#if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015))
+#define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
+#define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
+#define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE
+#define CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS
+#endif
+
+#endif // _MSC_VER
+
+////////////////////////////////////////////////////////////////////////////////
+
+// Use variadic macros if the compiler supports them
+#if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \
+ ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \
+ ( defined __GNUC__ && __GNUC__ >= 3 ) || \
+ ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L )
+
+#define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
+
+#endif
+
+// Use __COUNTER__ if the compiler supports it
+#if ( defined _MSC_VER && _MSC_VER >= 1300 ) || \
+ ( defined __GNUC__ && __GNUC__ >= 4 && __GNUC_MINOR__ >= 3 ) || \
+ ( defined __clang__ && __clang_major__ >= 3 )
+
+#define CATCH_INTERNAL_CONFIG_COUNTER
+
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// C++ language feature support
+
+// catch all support for C++11
+#if defined(CATCH_CPP11_OR_GREATER)
+
+# if !defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR)
+# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
+# endif
+
+# ifndef CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
+# define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
+# endif
+
+# ifndef CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
+# define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
+# endif
+
+# ifndef CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
+# define CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
+# endif
+
+# ifndef CATCH_INTERNAL_CONFIG_CPP11_TUPLE
+# define CATCH_INTERNAL_CONFIG_CPP11_TUPLE
+# endif
+
+# ifndef CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
+# define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
+# endif
+
+# if !defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG)
+# define CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG
+# endif
+
+# if !defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE)
+# define CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE
+# endif
+# if !defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR)
+# define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
+# endif
+# if !defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE)
+# define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE
+# endif
+# if !defined(CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS)
+# define CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS
+# endif
+
+#endif // __cplusplus >= 201103L
+
+// Now set the actual defines based on the above + anything the user has configured
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NO_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_NULLPTR
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_NOEXCEPT
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_GENERATED_METHODS
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_NO_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_IS_ENUM
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_CPP11_NO_TUPLE) && !defined(CATCH_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_TUPLE
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_VARIADIC_MACROS) && !defined(CATCH_CONFIG_NO_VARIADIC_MACROS) && !defined(CATCH_CONFIG_VARIADIC_MACROS)
+# define CATCH_CONFIG_VARIADIC_MACROS
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_NO_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_LONG_LONG
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_NO_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_OVERRIDE
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_NO_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_UNIQUE_PTR
+#endif
+// Use of __COUNTER__ is suppressed if __JETBRAINS_IDE__ is #defined (meaning we're being parsed by a JetBrains IDE for
+// analytics) because, at time of writing, __COUNTER__ is not properly handled by it.
+// This does not affect compilation
+#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) && !defined(__JETBRAINS_IDE__)
+# define CATCH_CONFIG_COUNTER
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_NO_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_SHUFFLE
+#endif
+# if defined(CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS) && !defined(CATCH_CONFIG_CPP11_NO_TYPE_TRAITS) && !defined(CATCH_CONFIG_CPP11_TYPE_TRAITS) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_TYPE_TRAITS
+# endif
+#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH)
+# define CATCH_CONFIG_WINDOWS_SEH
+#endif
+// This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
+#if !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS)
+# define CATCH_CONFIG_POSIX_SIGNALS
+#endif
+
+#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
+# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
+# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS
+#endif
+
+// noexcept support:
+#if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT)
+# define CATCH_NOEXCEPT noexcept
+# define CATCH_NOEXCEPT_IS(x) noexcept(x)
+#else
+# define CATCH_NOEXCEPT throw()
+# define CATCH_NOEXCEPT_IS(x)
+#endif
+
+// nullptr support
+#ifdef CATCH_CONFIG_CPP11_NULLPTR
+# define CATCH_NULL nullptr
+#else
+# define CATCH_NULL NULL
+#endif
+
+// override support
+#ifdef CATCH_CONFIG_CPP11_OVERRIDE
+# define CATCH_OVERRIDE override
+#else
+# define CATCH_OVERRIDE
+#endif
+
+// unique_ptr support
+#ifdef CATCH_CONFIG_CPP11_UNIQUE_PTR
+# define CATCH_AUTO_PTR( T ) std::unique_ptr
+#else
+# define CATCH_AUTO_PTR( T ) std::auto_ptr
+#endif
+
+#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
+#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
+#ifdef CATCH_CONFIG_COUNTER
+# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
+#else
+# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
+#endif
+
+#define INTERNAL_CATCH_STRINGIFY2( expr ) #expr
+#define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr )
+
+#include
+#include
+
+namespace Catch {
+
+ struct IConfig;
+
+ struct CaseSensitive { enum Choice {
+ Yes,
+ No
+ }; };
+
+ class NonCopyable {
+#ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ NonCopyable( NonCopyable const& ) = delete;
+ NonCopyable( NonCopyable && ) = delete;
+ NonCopyable& operator = ( NonCopyable const& ) = delete;
+ NonCopyable& operator = ( NonCopyable && ) = delete;
+#else
+ NonCopyable( NonCopyable const& info );
+ NonCopyable& operator = ( NonCopyable const& );
+#endif
+
+ protected:
+ NonCopyable() {}
+ virtual ~NonCopyable();
+ };
+
+ class SafeBool {
+ public:
+ typedef void (SafeBool::*type)() const;
+
+ static type makeSafe( bool value ) {
+ return value ? &SafeBool::trueValue : 0;
+ }
+ private:
+ void trueValue() const {}
+ };
+
+ template
+ inline void deleteAll( ContainerT& container ) {
+ typename ContainerT::const_iterator it = container.begin();
+ typename ContainerT::const_iterator itEnd = container.end();
+ for(; it != itEnd; ++it )
+ delete *it;
+ }
+ template
+ inline void deleteAllValues( AssociativeContainerT& container ) {
+ typename AssociativeContainerT::const_iterator it = container.begin();
+ typename AssociativeContainerT::const_iterator itEnd = container.end();
+ for(; it != itEnd; ++it )
+ delete it->second;
+ }
+
+ bool startsWith( std::string const& s, std::string const& prefix );
+ bool startsWith( std::string const& s, char prefix );
+ bool endsWith( std::string const& s, std::string const& suffix );
+ bool endsWith( std::string const& s, char suffix );
+ bool contains( std::string const& s, std::string const& infix );
+ void toLowerInPlace( std::string& s );
+ std::string toLower( std::string const& s );
+ std::string trim( std::string const& str );
+ bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
+
+ struct pluralise {
+ pluralise( std::size_t count, std::string const& label );
+
+ friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
+
+ std::size_t m_count;
+ std::string m_label;
+ };
+
+ struct SourceLineInfo {
+
+ SourceLineInfo();
+ SourceLineInfo( char const* _file, std::size_t _line );
+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ SourceLineInfo(SourceLineInfo const& other) = default;
+ SourceLineInfo( SourceLineInfo && ) = default;
+ SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
+ SourceLineInfo& operator = ( SourceLineInfo && ) = default;
+# endif
+ bool empty() const;
+ bool operator == ( SourceLineInfo const& other ) const;
+ bool operator < ( SourceLineInfo const& other ) const;
+
+ char const* file;
+ std::size_t line;
+ };
+
+ std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
+
+ // This is just here to avoid compiler warnings with macro constants and boolean literals
+ inline bool isTrue( bool value ){ return value; }
+ inline bool alwaysTrue() { return true; }
+ inline bool alwaysFalse() { return false; }
+
+ void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo );
+
+ void seedRng( IConfig const& config );
+ unsigned int rngSeed();
+
+ // Use this in variadic streaming macros to allow
+ // >> +StreamEndStop
+ // as well as
+ // >> stuff +StreamEndStop
+ struct StreamEndStop {
+ std::string operator+() {
+ return std::string();
+ }
+ };
+ template
+ T const& operator + ( T const& value, StreamEndStop ) {
+ return value;
+ }
+}
+
+#define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast( __LINE__ ) )
+#define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO );
+
+namespace Catch {
+
+ class NotImplementedException : public std::exception
+ {
+ public:
+ NotImplementedException( SourceLineInfo const& lineInfo );
+ NotImplementedException( NotImplementedException const& ) {}
+
+ virtual ~NotImplementedException() CATCH_NOEXCEPT {}
+
+ virtual const char* what() const CATCH_NOEXCEPT;
+
+ private:
+ std::string m_what;
+ SourceLineInfo m_lineInfo;
+ };
+
+} // end namespace Catch
+
+///////////////////////////////////////////////////////////////////////////////
+#define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO )
+
+// #included from: internal/catch_context.h
+#define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED
+
+// #included from: catch_interfaces_generators.h
+#define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED
+
+#include
+
+namespace Catch {
+
+ struct IGeneratorInfo {
+ virtual ~IGeneratorInfo();
+ virtual bool moveNext() = 0;
+ virtual std::size_t getCurrentIndex() const = 0;
+ };
+
+ struct IGeneratorsForTest {
+ virtual ~IGeneratorsForTest();
+
+ virtual IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) = 0;
+ virtual bool moveNext() = 0;
+ };
+
+ IGeneratorsForTest* createGeneratorsForTest();
+
+} // end namespace Catch
+
+// #included from: catch_ptr.hpp
+#define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+namespace Catch {
+
+ // An intrusive reference counting smart pointer.
+ // T must implement addRef() and release() methods
+ // typically implementing the IShared interface
+ template
+ class Ptr {
+ public:
+ Ptr() : m_p( CATCH_NULL ){}
+ Ptr( T* p ) : m_p( p ){
+ if( m_p )
+ m_p->addRef();
+ }
+ Ptr( Ptr const& other ) : m_p( other.m_p ){
+ if( m_p )
+ m_p->addRef();
+ }
+ ~Ptr(){
+ if( m_p )
+ m_p->release();
+ }
+ void reset() {
+ if( m_p )
+ m_p->release();
+ m_p = CATCH_NULL;
+ }
+ Ptr& operator = ( T* p ){
+ Ptr temp( p );
+ swap( temp );
+ return *this;
+ }
+ Ptr& operator = ( Ptr const& other ){
+ Ptr temp( other );
+ swap( temp );
+ return *this;
+ }
+ void swap( Ptr& other ) { std::swap( m_p, other.m_p ); }
+ T* get() const{ return m_p; }
+ T& operator*() const { return *m_p; }
+ T* operator->() const { return m_p; }
+ bool operator !() const { return m_p == CATCH_NULL; }
+ operator SafeBool::type() const { return SafeBool::makeSafe( m_p != CATCH_NULL ); }
+
+ private:
+ T* m_p;
+ };
+
+ struct IShared : NonCopyable {
+ virtual ~IShared();
+ virtual void addRef() const = 0;
+ virtual void release() const = 0;
+ };
+
+ template
+ struct SharedImpl : T {
+
+ SharedImpl() : m_rc( 0 ){}
+
+ virtual void addRef() const {
+ ++m_rc;
+ }
+ virtual void release() const {
+ if( --m_rc == 0 )
+ delete this;
+ }
+
+ mutable unsigned int m_rc;
+ };
+
+} // end namespace Catch
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+namespace Catch {
+
+ class TestCase;
+ class Stream;
+ struct IResultCapture;
+ struct IRunner;
+ struct IGeneratorsForTest;
+ struct IConfig;
+
+ struct IContext
+ {
+ virtual ~IContext();
+
+ virtual IResultCapture* getResultCapture() = 0;
+ virtual IRunner* getRunner() = 0;
+ virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0;
+ virtual bool advanceGeneratorsForCurrentTest() = 0;
+ virtual Ptr getConfig() const = 0;
+ };
+
+ struct IMutableContext : IContext
+ {
+ virtual ~IMutableContext();
+ virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
+ virtual void setRunner( IRunner* runner ) = 0;
+ virtual void setConfig( Ptr const& config ) = 0;
+ };
+
+ IContext& getCurrentContext();
+ IMutableContext& getCurrentMutableContext();
+ void cleanUpContext();
+ Stream createStream( std::string const& streamName );
+
+}
+
+// #included from: internal/catch_test_registry.hpp
+#define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED
+
+// #included from: catch_interfaces_testcase.h
+#define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED
+
+#include
+
+namespace Catch {
+
+ class TestSpec;
+
+ struct ITestCase : IShared {
+ virtual void invoke () const = 0;
+ protected:
+ virtual ~ITestCase();
+ };
+
+ class TestCase;
+ struct IConfig;
+
+ struct ITestCaseRegistry {
+ virtual ~ITestCaseRegistry();
+ virtual std::vector const& getAllTests() const = 0;
+ virtual std::vector const& getAllTestsSorted( IConfig const& config ) const = 0;
+ };
+
+ bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
+ std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config );
+ std::vector const& getAllTestCasesSorted( IConfig const& config );
+
+}
+
+namespace Catch {
+
+template
+class MethodTestCase : public SharedImpl {
+
+public:
+ MethodTestCase( void (C::*method)() ) : m_method( method ) {}
+
+ virtual void invoke() const {
+ C obj;
+ (obj.*m_method)();
+ }
+
+private:
+ virtual ~MethodTestCase() {}
+
+ void (C::*m_method)();
+};
+
+typedef void(*TestFunction)();
+
+struct NameAndDesc {
+ NameAndDesc( const char* _name = "", const char* _description= "" )
+ : name( _name ), description( _description )
+ {}
+
+ const char* name;
+ const char* description;
+};
+
+void registerTestCase
+ ( ITestCase* testCase,
+ char const* className,
+ NameAndDesc const& nameAndDesc,
+ SourceLineInfo const& lineInfo );
+
+struct AutoReg {
+
+ AutoReg
+ ( TestFunction function,
+ SourceLineInfo const& lineInfo,
+ NameAndDesc const& nameAndDesc );
+
+ template
+ AutoReg
+ ( void (C::*method)(),
+ char const* className,
+ NameAndDesc const& nameAndDesc,
+ SourceLineInfo const& lineInfo ) {
+
+ registerTestCase
+ ( new MethodTestCase( method ),
+ className,
+ nameAndDesc,
+ lineInfo );
+ }
+
+ ~AutoReg();
+
+private:
+ AutoReg( AutoReg const& );
+ void operator= ( AutoReg const& );
+};
+
+void registerTestCaseFunction
+ ( TestFunction function,
+ SourceLineInfo const& lineInfo,
+ NameAndDesc const& nameAndDesc );
+
+} // end namespace Catch
+
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
+ static void TestName(); \
+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); }\
+ static void TestName()
+ #define INTERNAL_CATCH_TESTCASE( ... ) \
+ INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); }
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
+ namespace{ \
+ struct TestName : ClassName{ \
+ void test(); \
+ }; \
+ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestName::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \
+ } \
+ void TestName::test()
+ #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
+ INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
+ Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) );
+
+#else
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_TESTCASE2( TestName, Name, Desc ) \
+ static void TestName(); \
+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\
+ static void TestName()
+ #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \
+ INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), Name, Desc )
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \
+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); }
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestCaseName, ClassName, TestName, Desc )\
+ namespace{ \
+ struct TestCaseName : ClassName{ \
+ void test(); \
+ }; \
+ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestCaseName::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \
+ } \
+ void TestCaseName::test()
+ #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\
+ INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, TestName, Desc )
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, Name, Desc ) \
+ Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) );
+#endif
+
+// #included from: internal/catch_capture.hpp
+#define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED
+
+// #included from: catch_result_builder.h
+#define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED
+
+// #included from: catch_result_type.h
+#define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED
+
+namespace Catch {
+
+ // ResultWas::OfType enum
+ struct ResultWas { enum OfType {
+ Unknown = -1,
+ Ok = 0,
+ Info = 1,
+ Warning = 2,
+
+ FailureBit = 0x10,
+
+ ExpressionFailed = FailureBit | 1,
+ ExplicitFailure = FailureBit | 2,
+
+ Exception = 0x100 | FailureBit,
+
+ ThrewException = Exception | 1,
+ DidntThrowException = Exception | 2,
+
+ FatalErrorCondition = 0x200 | FailureBit
+
+ }; };
+
+ inline bool isOk( ResultWas::OfType resultType ) {
+ return ( resultType & ResultWas::FailureBit ) == 0;
+ }
+ inline bool isJustInfo( int flags ) {
+ return flags == ResultWas::Info;
+ }
+
+ // ResultDisposition::Flags enum
+ struct ResultDisposition { enum Flags {
+ Normal = 0x01,
+
+ ContinueOnFailure = 0x02, // Failures fail test, but execution continues
+ FalseTest = 0x04, // Prefix expression with !
+ SuppressFail = 0x08 // Failures are reported but do not fail the test
+ }; };
+
+ inline ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {
+ return static_cast( static_cast( lhs ) | static_cast( rhs ) );
+ }
+
+ inline bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
+ inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }
+ inline bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; }
+
+} // end namespace Catch
+
+// #included from: catch_assertionresult.h
+#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED
+
+#include
+
+namespace Catch {
+
+ struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison;
+
+ struct DecomposedExpression
+ {
+ virtual ~DecomposedExpression() {}
+ virtual bool isBinaryExpression() const {
+ return false;
+ }
+ virtual void reconstructExpression( std::string& dest ) const = 0;
+
+ // Only simple binary comparisons can be decomposed.
+ // If more complex check is required then wrap sub-expressions in parentheses.
+ template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( T const& );
+ template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( T const& );
+ template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( T const& );
+ template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( T const& );
+ template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator % ( T const& );
+ template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( T const& );
+ template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( T const& );
+
+ private:
+ DecomposedExpression& operator = (DecomposedExpression const&);
+ };
+
+ struct AssertionInfo
+ {
+ AssertionInfo() {}
+ AssertionInfo( std::string const& _macroName,
+ SourceLineInfo const& _lineInfo,
+ std::string const& _capturedExpression,
+ ResultDisposition::Flags _resultDisposition );
+
+ std::string macroName;
+ SourceLineInfo lineInfo;
+ std::string capturedExpression;
+ ResultDisposition::Flags resultDisposition;
+ };
+
+ struct AssertionResultData
+ {
+ AssertionResultData() : decomposedExpression( CATCH_NULL )
+ , resultType( ResultWas::Unknown )
+ , negated( false )
+ , parenthesized( false ) {}
+
+ void negate( bool parenthesize ) {
+ negated = !negated;
+ parenthesized = parenthesize;
+ if( resultType == ResultWas::Ok )
+ resultType = ResultWas::ExpressionFailed;
+ else if( resultType == ResultWas::ExpressionFailed )
+ resultType = ResultWas::Ok;
+ }
+
+ std::string const& reconstructExpression() const {
+ if( decomposedExpression != CATCH_NULL ) {
+ decomposedExpression->reconstructExpression( reconstructedExpression );
+ if( parenthesized ) {
+ reconstructedExpression.insert( 0, 1, '(' );
+ reconstructedExpression.append( 1, ')' );
+ }
+ if( negated ) {
+ reconstructedExpression.insert( 0, 1, '!' );
+ }
+ decomposedExpression = CATCH_NULL;
+ }
+ return reconstructedExpression;
+ }
+
+ mutable DecomposedExpression const* decomposedExpression;
+ mutable std::string reconstructedExpression;
+ std::string message;
+ ResultWas::OfType resultType;
+ bool negated;
+ bool parenthesized;
+ };
+
+ class AssertionResult {
+ public:
+ AssertionResult();
+ AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
+ ~AssertionResult();
+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ AssertionResult( AssertionResult const& ) = default;
+ AssertionResult( AssertionResult && ) = default;
+ AssertionResult& operator = ( AssertionResult const& ) = default;
+ AssertionResult& operator = ( AssertionResult && ) = default;
+# endif
+
+ bool isOk() const;
+ bool succeeded() const;
+ ResultWas::OfType getResultType() const;
+ bool hasExpression() const;
+ bool hasMessage() const;
+ std::string getExpression() const;
+ std::string getExpressionInMacro() const;
+ bool hasExpandedExpression() const;
+ std::string getExpandedExpression() const;
+ std::string getMessage() const;
+ SourceLineInfo getSourceInfo() const;
+ std::string getTestMacroName() const;
+ void discardDecomposedExpression() const;
+ void expandDecomposedExpression() const;
+
+ protected:
+ AssertionInfo m_info;
+ AssertionResultData m_resultData;
+ };
+
+} // end namespace Catch
+
+// #included from: catch_matchers.hpp
+#define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
+
+namespace Catch {
+namespace Matchers {
+ namespace Impl {
+
+ template struct MatchAllOf;
+ template struct MatchAnyOf;
+ template struct MatchNotOf;
+
+ class MatcherUntypedBase {
+ public:
+ std::string toString() const {
+ if( m_cachedToString.empty() )
+ m_cachedToString = describe();
+ return m_cachedToString;
+ }
+
+ protected:
+ virtual ~MatcherUntypedBase();
+ virtual std::string describe() const = 0;
+ mutable std::string m_cachedToString;
+ private:
+ MatcherUntypedBase& operator = ( MatcherUntypedBase const& );
+ };
+
+ template
+ struct MatcherMethod {
+ virtual bool match( ObjectT const& arg ) const = 0;
+ };
+ template
+ struct MatcherMethod {
+ virtual bool match( PtrT* arg ) const = 0;
+ };
+
+ template
+ struct MatcherBase : MatcherUntypedBase, MatcherMethod {
+
+ MatchAllOf operator && ( MatcherBase const& other ) const;
+ MatchAnyOf operator || ( MatcherBase const& other ) const;
+ MatchNotOf operator ! () const;
+ };
+
+ template
+ struct MatchAllOf : MatcherBase {
+ virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE {
+ for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
+ if (!m_matchers[i]->match(arg))
+ return false;
+ }
+ return true;
+ }
+ virtual std::string describe() const CATCH_OVERRIDE {
+ std::string description;
+ description.reserve( 4 + m_matchers.size()*32 );
+ description += "( ";
+ for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
+ if( i != 0 )
+ description += " and ";
+ description += m_matchers[i]->toString();
+ }
+ description += " )";
+ return description;
+ }
+
+ MatchAllOf& operator && ( MatcherBase const& other ) {
+ m_matchers.push_back( &other );
+ return *this;
+ }
+
+ std::vector const*> m_matchers;
+ };
+ template
+ struct MatchAnyOf : MatcherBase {
+
+ virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE {
+ for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
+ if (m_matchers[i]->match(arg))
+ return true;
+ }
+ return false;
+ }
+ virtual std::string describe() const CATCH_OVERRIDE {
+ std::string description;
+ description.reserve( 4 + m_matchers.size()*32 );
+ description += "( ";
+ for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
+ if( i != 0 )
+ description += " or ";
+ description += m_matchers[i]->toString();
+ }
+ description += " )";
+ return description;
+ }
+
+ MatchAnyOf& operator || ( MatcherBase const& other ) {
+ m_matchers.push_back( &other );
+ return *this;
+ }
+
+ std::vector const*> m_matchers;
+ };
+
+ template
+ struct MatchNotOf : MatcherBase {
+
+ MatchNotOf( MatcherBase const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {}
+
+ virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE {
+ return !m_underlyingMatcher.match( arg );
+ }
+
+ virtual std::string describe() const CATCH_OVERRIDE {
+ return "not " + m_underlyingMatcher.toString();
+ }
+ MatcherBase const& m_underlyingMatcher;
+ };
+
+ template
+ MatchAllOf MatcherBase::operator && ( MatcherBase const& other ) const {
+ return MatchAllOf() && *this && other;
+ }
+ template
+ MatchAnyOf MatcherBase::operator || ( MatcherBase const& other ) const {
+ return MatchAnyOf() || *this || other;
+ }
+ template
+ MatchNotOf MatcherBase::operator ! () const {
+ return MatchNotOf( *this );
+ }
+
+ } // namespace Impl
+
+ // The following functions create the actual matcher objects.
+ // This allows the types to be inferred
+ // - deprecated: prefer ||, && and !
+ template
+ inline Impl::MatchNotOf Not( Impl::MatcherBase const& underlyingMatcher ) {
+ return Impl::MatchNotOf( underlyingMatcher );
+ }
+ template
+ inline Impl::MatchAllOf AllOf( Impl::MatcherBase const& m1, Impl::MatcherBase const& m2 ) {
+ return Impl::MatchAllOf() && m1 && m2;
+ }
+ template
+ inline Impl::MatchAllOf AllOf( Impl::MatcherBase const& m1, Impl::MatcherBase const& m2, Impl::MatcherBase const& m3 ) {
+ return Impl::MatchAllOf() && m1 && m2 && m3;
+ }
+ template
+ inline Impl::MatchAnyOf AnyOf( Impl::MatcherBase const& m1, Impl::MatcherBase const& m2 ) {
+ return Impl::MatchAnyOf() || m1 || m2;
+ }
+ template
+ inline Impl::MatchAnyOf AnyOf( Impl::MatcherBase const& m1, Impl::MatcherBase const& m2, Impl::MatcherBase const& m3 ) {
+ return Impl::MatchAnyOf() || m1 || m2 || m3;
+ }
+
+} // namespace Matchers
+
+using namespace Matchers;
+using Matchers::Impl::MatcherBase;
+
+} // namespace Catch
+
+namespace Catch {
+
+ struct TestFailureException{};
+
+ template class ExpressionLhs;
+
+ struct CopyableStream {
+ CopyableStream() {}
+ CopyableStream( CopyableStream const& other ) {
+ oss << other.oss.str();
+ }
+ CopyableStream& operator=( CopyableStream const& other ) {
+ oss.str(std::string());
+ oss << other.oss.str();
+ return *this;
+ }
+ std::ostringstream oss;
+ };
+
+ class ResultBuilder : public DecomposedExpression {
+ public:
+ ResultBuilder( char const* macroName,
+ SourceLineInfo const& lineInfo,
+ char const* capturedExpression,
+ ResultDisposition::Flags resultDisposition,
+ char const* secondArg = "" );
+
+ template
+ ExpressionLhs operator <= ( T const& operand );
+ ExpressionLhs operator <= ( bool value );
+
+ template
+ ResultBuilder& operator << ( T const& value ) {
+ m_stream.oss << value;
+ return *this;
+ }
+
+ ResultBuilder& setResultType( ResultWas::OfType result );
+ ResultBuilder& setResultType( bool result );
+
+ void endExpression( DecomposedExpression const& expr );
+
+ virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE;
+
+ AssertionResult build() const;
+ AssertionResult build( DecomposedExpression const& expr ) const;
+
+ void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal );
+ void captureResult( ResultWas::OfType resultType );
+ void captureExpression();
+ void captureExpectedException( std::string const& expectedMessage );
+ void captureExpectedException( Matchers::Impl::MatcherBase const& matcher );
+ void handleResult( AssertionResult const& result );
+ void react();
+ bool shouldDebugBreak() const;
+ bool allowThrows() const;
+
+ template
+ void captureMatch( ArgT const& arg, MatcherT const& matcher, char const* matcherString );
+
+ private:
+ AssertionInfo m_assertionInfo;
+ AssertionResultData m_data;
+ CopyableStream m_stream;
+
+ bool m_shouldDebugBreak;
+ bool m_shouldThrow;
+ };
+
+} // namespace Catch
+
+// Include after due to circular dependency:
+// #included from: catch_expression_lhs.hpp
+#define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED
+
+// #included from: catch_evaluate.hpp
+#define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable:4389) // '==' : signed/unsigned mismatch
+#pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)
+#endif
+
+#include
+
+namespace Catch {
+namespace Internal {
+
+ enum Operator {
+ IsEqualTo,
+ IsNotEqualTo,
+ IsLessThan,
+ IsGreaterThan,
+ IsLessThanOrEqualTo,
+ IsGreaterThanOrEqualTo
+ };
+
+ template struct OperatorTraits { static const char* getName(){ return "*error*"; } };
+ template<> struct OperatorTraits { static const char* getName(){ return "=="; } };
+ template<> struct OperatorTraits { static const char* getName(){ return "!="; } };
+ template<> struct OperatorTraits { static const char* getName(){ return "<"; } };
+ template<> struct OperatorTraits { static const char* getName(){ return ">"; } };
+ template<> struct OperatorTraits { static const char* getName(){ return "<="; } };
+ template<> struct OperatorTraits{ static const char* getName(){ return ">="; } };
+
+ template
+ inline T& opCast(T const& t) { return const_cast(t); }
+
+// nullptr_t support based on pull request #154 from Konstantin Baumann
+#ifdef CATCH_CONFIG_CPP11_NULLPTR
+ inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; }
+#endif // CATCH_CONFIG_CPP11_NULLPTR
+
+ // So the compare overloads can be operator agnostic we convey the operator as a template
+ // enum, which is used to specialise an Evaluator for doing the comparison.
+ template
+ class Evaluator{};
+
+ template
+ struct Evaluator {
+ static bool evaluate( T1 const& lhs, T2 const& rhs) {
+ return bool( opCast( lhs ) == opCast( rhs ) );
+ }
+ };
+ template
+ struct Evaluator {
+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
+ return bool( opCast( lhs ) != opCast( rhs ) );
+ }
+ };
+ template
+ struct Evaluator {
+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
+ return bool( opCast( lhs ) < opCast( rhs ) );
+ }
+ };
+ template
+ struct Evaluator {
+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
+ return bool( opCast( lhs ) > opCast( rhs ) );
+ }
+ };
+ template
+ struct Evaluator {
+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
+ return bool( opCast( lhs ) >= opCast( rhs ) );
+ }
+ };
+ template
+ struct Evaluator {
+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
+ return bool( opCast( lhs ) <= opCast( rhs ) );
+ }
+ };
+
+ template
+ bool applyEvaluator( T1 const& lhs, T2 const& rhs ) {
+ return Evaluator::evaluate( lhs, rhs );
+ }
+
+ // This level of indirection allows us to specialise for integer types
+ // to avoid signed/ unsigned warnings
+
+ // "base" overload
+ template
+ bool compare( T1 const& lhs, T2 const& rhs ) {
+ return Evaluator::evaluate( lhs, rhs );
+ }
+
+ // unsigned X to int
+ template bool compare( unsigned int lhs, int rhs ) {
+ return applyEvaluator( lhs, static_cast( rhs ) );
+ }
+ template bool compare( unsigned long lhs, int rhs ) {
+ return applyEvaluator( lhs, static_cast( rhs ) );
+ }
+ template bool compare( unsigned char lhs, int rhs ) {
+ return applyEvaluator( lhs, static_cast( rhs ) );
+ }
+
+ // unsigned X to long
+ template bool compare( unsigned int lhs, long rhs ) {
+ return applyEvaluator( lhs, static_cast( rhs ) );
+ }
+ template bool compare( unsigned long lhs, long rhs ) {
+ return applyEvaluator( lhs, static_cast