Branch data Line data Source code
1 : : /* SPDX-FileCopyrightText: Copyright 2026 Cozens Software Solutions Limited
2 : : * SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0 OR LicenseRef-PolyForm-Internal-Use-1.0.0 OR LicenseRef-COSOSO-Commercial
3 : : */
4 : :
5 : : #include "SolidSyslogMbedTlsPemBufferCredentials.h"
6 : :
7 : : #include <stdbool.h>
8 : : #include <stddef.h>
9 : :
10 : : #include "SolidSyslogError.h"
11 : : #include "SolidSyslogErrorCategory.h"
12 : : #include "SolidSyslogMbedTlsCredentialsDefinition.h"
13 : : #include "SolidSyslogMbedTlsPemBufferCredentialsPrivate.h"
14 : : #include "SolidSyslogMbedTlsNullCredentials.h"
15 : : #include "SolidSyslogPoolAllocator.h"
16 : : #include "SolidSyslogTlsFingerprint.h"
17 : : #include "SolidSyslogPrival.h"
18 : : #include "SolidSyslogTunables.h"
19 : :
20 : : static inline bool MbedTlsPemBufferCredentials_IsValidConfig(
21 : : const struct SolidSyslogMbedTlsPemBufferCredentialsConfig* config
22 : : );
23 : : static inline size_t MbedTlsPemBufferCredentials_IndexFromHandle(const struct SolidSyslogMbedTlsCredentials* base);
24 : : static inline void MbedTlsPemBufferCredentials_CleanupAtIndex(size_t index, void* context);
25 : :
26 : : static bool MbedTlsPemBufferCredentials_InUse[SOLIDSYSLOG_TLS_CREDENTIALS_POOL_SIZE];
27 : : static struct SolidSyslogMbedTlsPemBufferCredentials
28 : : MbedTlsPemBufferCredentials_Pool[SOLIDSYSLOG_TLS_CREDENTIALS_POOL_SIZE];
29 : : static struct SolidSyslogPoolAllocator MbedTlsPemBufferCredentials_Allocator = {
30 : : MbedTlsPemBufferCredentials_InUse,
31 : : SOLIDSYSLOG_TLS_CREDENTIALS_POOL_SIZE
32 : : };
33 : :
34 : 38 : struct SolidSyslogMbedTlsCredentials* SolidSyslogMbedTlsPemBufferCredentials_Create(
35 : : const struct SolidSyslogMbedTlsPemBufferCredentialsConfig* config
36 : : )
37 : : {
38 : 38 : struct SolidSyslogMbedTlsCredentials* handle = SolidSyslogMbedTlsNullCredentials_Get();
39 [ + + ]: 38 : if (MbedTlsPemBufferCredentials_IsValidConfig(config))
40 : : {
41 : 34 : size_t index = SolidSyslogPoolAllocator_AcquireFirstFree(&MbedTlsPemBufferCredentials_Allocator);
42 [ + + ]: 34 : if (SolidSyslogPoolAllocator_IndexIsValid(&MbedTlsPemBufferCredentials_Allocator, index) == true)
43 : : {
44 : 33 : SolidSyslogMbedTlsPemBufferCredentials_Initialise(&MbedTlsPemBufferCredentials_Pool[index].Base, config);
45 : 33 : handle = &MbedTlsPemBufferCredentials_Pool[index].Base;
46 : : }
47 : : else
48 : : {
49 : 1 : MbedTlsPemBufferCredentials_Report(
50 : : SOLIDSYSLOG_POOL_EXHAUSTED_SEVERITY,
51 : : SOLIDSYSLOG_CAT_POOL_EXHAUSTED,
52 : : SOLIDSYSLOG_TLS_CREDENTIALS_ERROR_POOL_EXHAUSTED
53 : : );
54 : : }
55 : : }
56 : 38 : return handle;
57 : : }
58 : :
59 : : /* The RNG is checked here rather than where it is used, so a wiring fault is
60 : : * one Create-time report instead of a surprise on the first connection - Mbed
61 : : * TLS needs one to parse a private key at all. */
62 : 38 : static inline bool MbedTlsPemBufferCredentials_IsValidConfig(
63 : : const struct SolidSyslogMbedTlsPemBufferCredentialsConfig* config
64 : : )
65 : : {
66 : 38 : bool valid = false;
67 [ + + ]: 38 : if (config == NULL)
68 : : {
69 : 1 : MbedTlsPemBufferCredentials_Report(
70 : : SOLIDSYSLOG_BAD_CONFIG_FATAL_SEVERITY,
71 : : SOLIDSYSLOG_CAT_BAD_CONFIG,
72 : : SOLIDSYSLOG_TLS_CREDENTIALS_ERROR_NULL_CONFIG
73 : : );
74 : : }
75 [ + + ]: 37 : else if (config->Rng == NULL)
76 : : {
77 : 1 : MbedTlsPemBufferCredentials_Report(
78 : : SOLIDSYSLOG_BAD_CONFIG_FATAL_SEVERITY,
79 : : SOLIDSYSLOG_CAT_BAD_CONFIG,
80 : : SOLIDSYSLOG_TLS_CREDENTIALS_ERROR_NULL_RNG
81 : : );
82 : : }
83 [ + + ]: 36 : else if (!SolidSyslogTlsFingerprint_ListIsPresent(config->PeerFingerprints, config->PeerFingerprintCount))
84 : : {
85 : 2 : MbedTlsPemBufferCredentials_Report(
86 : : SOLIDSYSLOG_BAD_CONFIG_FATAL_SEVERITY,
87 : : SOLIDSYSLOG_CAT_BAD_CONFIG,
88 : : SOLIDSYSLOG_TLS_CREDENTIALS_ERROR_NULL_PEER_FINGERPRINT
89 : : );
90 : : }
91 : : else
92 : : {
93 : 34 : valid = true;
94 : : }
95 : 38 : return valid;
96 : : }
97 : :
98 : 35 : void SolidSyslogMbedTlsPemBufferCredentials_Destroy(struct SolidSyslogMbedTlsCredentials* base)
99 : : {
100 : 35 : size_t index = MbedTlsPemBufferCredentials_IndexFromHandle(base);
101 [ + + + + ]: 69 : bool released = SolidSyslogPoolAllocator_IndexIsValid(&MbedTlsPemBufferCredentials_Allocator, index) &&
102 : 34 : SolidSyslogPoolAllocator_FreeIfInUse(
103 : : &MbedTlsPemBufferCredentials_Allocator,
104 : : index,
105 : : MbedTlsPemBufferCredentials_CleanupAtIndex,
106 : : NULL
107 : : );
108 [ + + ]: 35 : if (!released)
109 : : {
110 : 2 : MbedTlsPemBufferCredentials_Report(
111 : : SOLIDSYSLOG_UNKNOWN_DESTROY_SEVERITY,
112 : : SOLIDSYSLOG_CAT_UNKNOWN_DESTROY,
113 : : SOLIDSYSLOG_TLS_CREDENTIALS_ERROR_UNKNOWN_DESTROY
114 : : );
115 : : }
116 : 35 : }
117 : :
118 : 35 : static inline size_t MbedTlsPemBufferCredentials_IndexFromHandle(const struct SolidSyslogMbedTlsCredentials* base)
119 : : {
120 : 35 : size_t result = SOLIDSYSLOG_TLS_CREDENTIALS_POOL_SIZE;
121 [ + + ]: 36 : for (size_t poolIndex = 0U; poolIndex < SOLIDSYSLOG_TLS_CREDENTIALS_POOL_SIZE; poolIndex++)
122 : : {
123 [ + + ]: 35 : if (base == &MbedTlsPemBufferCredentials_Pool[poolIndex].Base)
124 : : {
125 : 34 : result = poolIndex;
126 : 34 : break;
127 : : }
128 : : }
129 : 35 : return result;
130 : : }
131 : :
132 : : /* Destroying a source part way through a connection must not leave a parsed
133 : : * private key in a slot the pool is about to hand out again. */
134 : 33 : static inline void MbedTlsPemBufferCredentials_CleanupAtIndex(size_t index, void* context)
135 : : {
136 : : (void) context;
137 : 33 : SolidSyslogMbedTlsPemBufferCredentials_Cleanup(&MbedTlsPemBufferCredentials_Pool[index].Base);
138 : 33 : }
|