Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions Bdd/Targets/Common/BddTargetTlsSender_OpenSsl_PosixTcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@
#include "SolidSyslogPosixSleep.h"
#include "SolidSyslogPosixTcpStream.h"
#include "SolidSyslogStreamSender.h"
#include "SolidSyslogOpenSslPemFileCredentials.h"
#include "SolidSyslogOpenSslStream.h"

struct SolidSyslogResolver;

static struct SolidSyslogStream* underlyingStream;

static struct SolidSyslogOpenSslCredentials* credentials;
static struct SolidSyslogStream* tlsStream;
static struct SolidSyslogAddress* address;
static struct SolidSyslogSender* sender;
Expand All @@ -26,18 +28,22 @@ struct SolidSyslogSender* BddTargetTlsSender_Create(struct SolidSyslogResolver*
tlsStreamConfig = (struct SolidSyslogOpenSslStreamConfig) {0};
tlsStreamConfig.Transport = underlyingStream;
tlsStreamConfig.Sleep = SolidSyslogPosix_Sleep;
static struct SolidSyslogOpenSslPemFileCredentialsConfig credentialsConfig;
credentialsConfig = (struct SolidSyslogOpenSslPemFileCredentialsConfig) {0};
if (mtls)
{
tlsStreamConfig.CaBundlePath = BddTargetMtlsConfig_GetCaBundlePath();
credentialsConfig.CaBundlePath = BddTargetMtlsConfig_GetCaBundlePath();
credentialsConfig.ClientCertChainPath = BddTargetMtlsConfig_GetClientCertChainPath();
credentialsConfig.ClientKeyPath = BddTargetMtlsConfig_GetClientKeyPath();
tlsStreamConfig.ServerName = BddTargetMtlsConfig_GetServerName();
tlsStreamConfig.ClientCertChainPath = BddTargetMtlsConfig_GetClientCertChainPath();
tlsStreamConfig.ClientKeyPath = BddTargetMtlsConfig_GetClientKeyPath();
}
else
{
tlsStreamConfig.CaBundlePath = BddTargetTlsConfig_GetCaBundlePath();
credentialsConfig.CaBundlePath = BddTargetTlsConfig_GetCaBundlePath();
tlsStreamConfig.ServerName = BddTargetTlsConfig_GetServerName();
}
credentials = SolidSyslogOpenSslPemFileCredentials_Create(&credentialsConfig);
tlsStreamConfig.Credentials = credentials;
tlsStream = SolidSyslogOpenSslStream_Create(&tlsStreamConfig);

address = SolidSyslogPosixAddress_Create();
Expand All @@ -60,5 +66,6 @@ void BddTargetTlsSender_Destroy(void)
SolidSyslogStreamSender_Destroy(sender);
SolidSyslogPosixAddress_Destroy(address);
SolidSyslogOpenSslStream_Destroy(tlsStream);
SolidSyslogOpenSslPemFileCredentials_Destroy(credentials);
SolidSyslogPosixTcpStream_Destroy(underlyingStream);
}
15 changes: 11 additions & 4 deletions Bdd/Targets/Common/BddTargetTlsSender_OpenSsl_WinsockTcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "BddTargetTlsConfig.h"
#include "BddTargetTlsSender.h"
#include "SolidSyslogStreamSender.h"
#include "SolidSyslogOpenSslPemFileCredentials.h"
#include "SolidSyslogOpenSslStream.h"
#include "SolidSyslogWindowsSleep.h"
#include "SolidSyslogWinsockAddress.h"
Expand All @@ -13,6 +14,7 @@ struct SolidSyslogResolver;

static struct SolidSyslogStream* underlyingStream;

static struct SolidSyslogOpenSslCredentials* credentials;
static struct SolidSyslogStream* tlsStream;
static struct SolidSyslogAddress* address;
static struct SolidSyslogSender* sender;
Expand All @@ -25,18 +27,22 @@ struct SolidSyslogSender* BddTargetTlsSender_Create(struct SolidSyslogResolver*
tlsStreamConfig = (struct SolidSyslogOpenSslStreamConfig) {0};
tlsStreamConfig.Transport = underlyingStream;
tlsStreamConfig.Sleep = SolidSyslogWindows_Sleep;
static struct SolidSyslogOpenSslPemFileCredentialsConfig credentialsConfig;
credentialsConfig = (struct SolidSyslogOpenSslPemFileCredentialsConfig) {0};
if (mtls)
{
tlsStreamConfig.CaBundlePath = BddTargetMtlsConfig_GetCaBundlePath();
credentialsConfig.CaBundlePath = BddTargetMtlsConfig_GetCaBundlePath();
credentialsConfig.ClientCertChainPath = BddTargetMtlsConfig_GetClientCertChainPath();
credentialsConfig.ClientKeyPath = BddTargetMtlsConfig_GetClientKeyPath();
tlsStreamConfig.ServerName = BddTargetMtlsConfig_GetServerName();
tlsStreamConfig.ClientCertChainPath = BddTargetMtlsConfig_GetClientCertChainPath();
tlsStreamConfig.ClientKeyPath = BddTargetMtlsConfig_GetClientKeyPath();
}
else
{
tlsStreamConfig.CaBundlePath = BddTargetTlsConfig_GetCaBundlePath();
credentialsConfig.CaBundlePath = BddTargetTlsConfig_GetCaBundlePath();
tlsStreamConfig.ServerName = BddTargetTlsConfig_GetServerName();
}
credentials = SolidSyslogOpenSslPemFileCredentials_Create(&credentialsConfig);
tlsStreamConfig.Credentials = credentials;
tlsStream = SolidSyslogOpenSslStream_Create(&tlsStreamConfig);

address = SolidSyslogWinsockAddress_Create();
Expand All @@ -59,5 +65,6 @@ void BddTargetTlsSender_Destroy(void)
SolidSyslogStreamSender_Destroy(sender);
SolidSyslogWinsockAddress_Destroy(address);
SolidSyslogOpenSslStream_Destroy(tlsStream);
SolidSyslogOpenSslPemFileCredentials_Destroy(credentials);
SolidSyslogWinsockTcpStream_Destroy(underlyingStream);
}
22 changes: 22 additions & 0 deletions Core/Interface/SolidSyslogTunablesDefaults.h
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,28 @@
#error "SOLIDSYSLOG_TLS_STREAM_POOL_SIZE must be >= 1"
#endif

/**
* Role pool: TLS credentials. Number of credentials instances the library's
* internal static pool can simultaneously hold, across whichever backend is
* compiled in - a PEM-file source, caller-built vendor handles, or an
* integrator's own class reaching a secure element or key store. Each
* instance carries only where its material comes from, never the material.
*
* Default 1 - one source per TLS stream is the ordinary wiring, and the
* stream pool defaults to one. Bump it alongside
* SOLIDSYSLOG_TLS_STREAM_POOL_SIZE where several streams draw on separate
* sources.
*
* Floor: 1. Sub-floor values rejected at compile time.
*/
#ifndef SOLIDSYSLOG_TLS_CREDENTIALS_POOL_SIZE
#define SOLIDSYSLOG_TLS_CREDENTIALS_POOL_SIZE 1U
#endif

#if SOLIDSYSLOG_TLS_CREDENTIALS_POOL_SIZE < 1
#error "SOLIDSYSLOG_TLS_CREDENTIALS_POOL_SIZE must be >= 1"
#endif

/**
* Role pool: HMAC-SHA256 SecurityPolicy. Number of keyed HMAC policy
* instances the library's internal static pool can simultaneously hold,
Expand Down
2 changes: 2 additions & 0 deletions Platform/OpenSsl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

target_sources(${PROJECT_NAME} PRIVATE
Source/SolidSyslogOpenSslNullCredentials.c
Source/SolidSyslogOpenSslPemFileCredentials.c
Source/SolidSyslogOpenSslPemFileCredentialsStatic.c
Source/SolidSyslogOpenSslStream.c
Source/SolidSyslogOpenSslStreamStatic.c
Source/SolidSyslogOpenSslHmacSha256Policy.c
Expand Down
49 changes: 49 additions & 0 deletions Platform/OpenSsl/Interface/SolidSyslogOpenSslPemFileCredentials.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/* SPDX-FileCopyrightText: Copyright 2026 Cozens Software Solutions Limited
* SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0 OR LicenseRef-PolyForm-Internal-Use-1.0.0 OR LicenseRef-COSOSO-Commercial
*/

/** @file
* An OpenSSL credentials backend that names its material by file path, and
* hands those paths to OpenSSL to open and parse. This library performs no
* file handling of its own: it neither opens, reads, parses nor buffers the
* PEM, so key bytes never pass through it.
*
* Paths are re-read on every connection, so a device issued new credentials
* while it is running uses them on its next connect without a restart. */
#ifndef SOLIDSYSLOGOPENSSLPEMFILECREDENTIALS_H
#define SOLIDSYSLOGOPENSSLPEMFILECREDENTIALS_H

#include "SolidSyslogExternC.h"

SOLIDSYSLOG_EXTERN_C_BEGIN

struct SolidSyslogOpenSslCredentials;

/** Where this backend's material lives. Every member is a path the caller
* owns and must keep valid for the lifetime of the credentials. */
struct SolidSyslogOpenSslPemFileCredentialsConfig
{
/** PEM file of trust anchors the peer certificate must chain to; NULL
* installs none, which leaves the peer authorised only if the stream
* has another means to do it. */
const char* CaBundlePath;
/** PEM leaf certificate (plus intermediates) for mutual TLS; NULL means
* no client credential. Certificate and key are all-or-nothing -
* supplying one without the other is reported. */
const char* ClientCertChainPath;
/** PEM private key matching ClientCertChainPath; NULL means no client
* credential. */
const char* ClientKeyPath;
};

/** Draw a credentials instance from the pool. A NULL config is reported and
* falls back to the shared Null credentials, as does an exhausted pool. */
Comment thread
coderabbitai[bot] marked this conversation as resolved.
struct SolidSyslogOpenSslCredentials* SolidSyslogOpenSslPemFileCredentials_Create(
const struct SolidSyslogOpenSslPemFileCredentialsConfig* config
);
/** Release the pool slot. */
void SolidSyslogOpenSslPemFileCredentials_Destroy(struct SolidSyslogOpenSslCredentials * base);

SOLIDSYSLOG_EXTERN_C_END

#endif /* SOLIDSYSLOGOPENSSLPEMFILECREDENTIALS_H */
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/* SPDX-FileCopyrightText: Copyright 2026 Cozens Software Solutions Limited
* SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0 OR LicenseRef-PolyForm-Internal-Use-1.0.0 OR LicenseRef-COSOSO-Commercial
*/

/** @file
* Error codes and Source identity for the OpenSslPemFileCredentials backend. */
#ifndef SOLIDSYSLOGOPENSSLPEMFILECREDENTIALSERRORS_H
#define SOLIDSYSLOGOPENSSLPEMFILECREDENTIALSERRORS_H

#include "SolidSyslogExternC.h"

SOLIDSYSLOG_EXTERN_C_BEGIN

struct SolidSyslogErrorSource;

/** Detail codes for events whose Source is OpenSslPemFileCredentialsErrorSource.
* A handler reads these off event->Detail after matching event->Source; the
* members name their own fault. */
enum SolidSyslogOpenSslPemFileCredentialsErrors
{
SOLIDSYSLOG_OPENSSL_PEM_FILE_CREDENTIALS_ERROR_POOL_EXHAUSTED,
SOLIDSYSLOG_OPENSSL_PEM_FILE_CREDENTIALS_ERROR_UNKNOWN_DESTROY,
SOLIDSYSLOG_OPENSSL_PEM_FILE_CREDENTIALS_ERROR_NULL_CONFIG,
SOLIDSYSLOG_OPENSSL_PEM_FILE_CREDENTIALS_ERROR_TRUST_ANCHORS_NOT_LOADED,
SOLIDSYSLOG_OPENSSL_PEM_FILE_CREDENTIALS_ERROR_CLIENT_CREDENTIAL_INCOMPLETE,
SOLIDSYSLOG_OPENSSL_PEM_FILE_CREDENTIALS_ERROR_CLIENT_CREDENTIAL_MISMATCHED,
SOLIDSYSLOG_OPENSSL_PEM_FILE_CREDENTIALS_ERROR_CLIENT_CREDENTIAL_NOT_INSTALLED,
SOLIDSYSLOG_OPENSSL_PEM_FILE_CREDENTIALS_ERROR_MAX /**< One past the last code; never emitted. Bounds the range for iteration. */
};

/** Identity for events raised by an OpenSslPemFileCredentials. A handler
* matches by address (event->Source == &OpenSslPemFileCredentialsErrorSource),
* then reads event->Detail as an enum
* SolidSyslogOpenSslPemFileCredentialsErrors. */
extern const struct SolidSyslogErrorSource OpenSslPemFileCredentialsErrorSource;

SOLIDSYSLOG_EXTERN_C_END

#endif /* SOLIDSYSLOGOPENSSLPEMFILECREDENTIALSERRORS_H */
21 changes: 12 additions & 9 deletions Platform/OpenSsl/Interface/SolidSyslogOpenSslStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "SolidSyslogTlsHandshakeTimeoutFunction.h"

struct SolidSyslogStream;
struct SolidSyslogOpenSslCredentials;

SOLIDSYSLOG_EXTERN_C_BEGIN

Expand All @@ -46,6 +47,13 @@ SOLIDSYSLOG_EXTERN_C_BEGIN
* destroys it; the caller owns it and must keep it valid until
* SolidSyslogOpenSslStream_Destroy. */
struct SolidSyslogStream* Transport;
/** Where the trust anchors, any pinned peer fingerprints and the mutual-TLS
* client credential come from; required - a NULL is reported at
* SolidSyslogOpenSslStream_Create. Asked once per connection, so material
* is fetched only for a connection actually being made, and told when the
* connection ends. Borrowed - the caller owns it and must keep it valid
* until SolidSyslogOpenSslStream_Destroy. */
struct SolidSyslogOpenSslCredentials* Credentials;
SolidSyslogSleepFunction Sleep; /**< Drives the bounded handshake retry between WANT_READ/WANT_WRITE
* polls; required - a NULL is reported at
* SolidSyslogOpenSslStream_Create. */
Expand All @@ -54,24 +62,19 @@ SOLIDSYSLOG_EXTERN_C_BEGIN
* SOLIDSYSLOG_TLS_HANDSHAKE_TIMEOUT_MS
* tunable. */
void* HandshakeTimeoutContext; /**< Passed back to GetHandshakeTimeoutMs unchanged; NULL is fine. */
const char* CaBundlePath; /**< PEM file of trust anchors the peer cert must chain to. */
/** SNI plus the expected peer identity. A non-empty name is verified against
* the cert (SAN/CN). NULL connects chain-only but emits a WARNING - the peer
* is unverified (MITM-class). "" is the no-name-check opt-out (closed network
* / private CA): still chain-verified against CaBundlePath, endpoint identity
* unchecked; no diagnostic. */
* / private CA): still verified against whatever the credentials installed,
* endpoint identity unchecked; no diagnostic. */
const char* ServerName;
const char* CipherList; /**< TLS 1.2 cipher list; NULL uses the OpenSSL default. */
const char* ClientCertChainPath; /**< PEM leaf cert (+ intermediates) for mTLS; NULL = no mTLS. Cert and
* key are all-or-nothing - supplying one without the other is a setup
* error. */
const char* ClientKeyPath; /**< PEM private key matching ClientCertChainPath; NULL = no mTLS. */
};

/** Draw a TLS stream from the pool over the injected transport (see the file
* overview for the handshake and I/O behaviour). A NULL config, a NULL
* Transport or a NULL Sleep is reported and falls back to the shared
* NullStream, as does an exhausted pool (default size 1). */
* Transport, a NULL Sleep or a NULL Credentials is reported and falls back to
* the shared NullStream, as does an exhausted pool (default size 1). */
struct SolidSyslogStream* SolidSyslogOpenSslStream_Create(const struct SolidSyslogOpenSslStreamConfig* config);
/** Release the pool slot; closes the TLS session and the underlying transport
* first if the stream is still Open. */
Expand Down
5 changes: 2 additions & 3 deletions Platform/OpenSsl/Interface/SolidSyslogOpenSslStreamErrors.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,11 @@ SOLIDSYSLOG_EXTERN_C_BEGIN
SOLIDSYSLOG_OPENSSL_STREAM_ERROR_SERVER_NAME_NOT_SET,
SOLIDSYSLOG_OPENSSL_STREAM_ERROR_HANDSHAKE_REJECTED,
SOLIDSYSLOG_OPENSSL_STREAM_ERROR_HANDSHAKE_TIMEOUT,
SOLIDSYSLOG_OPENSSL_STREAM_ERROR_CLIENT_CREDENTIAL_INCOMPLETE,
SOLIDSYSLOG_OPENSSL_STREAM_ERROR_CLIENT_CREDENTIAL_MISMATCHED,
SOLIDSYSLOG_OPENSSL_STREAM_ERROR_CLIENT_CREDENTIAL_NOT_INSTALLED,
SOLIDSYSLOG_OPENSSL_STREAM_ERROR_NULL_CONFIG,
SOLIDSYSLOG_OPENSSL_STREAM_ERROR_NULL_TRANSPORT,
SOLIDSYSLOG_OPENSSL_STREAM_ERROR_NULL_SLEEP,
SOLIDSYSLOG_OPENSSL_STREAM_ERROR_NULL_CREDENTIALS,
SOLIDSYSLOG_OPENSSL_STREAM_ERROR_NO_PEER_AUTHORISATION,
SOLIDSYSLOG_OPENSSL_STREAM_ERROR_PEER_CERTIFICATE_UNTRUSTED,
SOLIDSYSLOG_OPENSSL_STREAM_ERROR_PEER_NAME_MISMATCHED,
SOLIDSYSLOG_OPENSSL_STREAM_ERROR_PEER_CERTIFICATE_EXPIRED,
Expand Down
Loading
Loading