Coverage Report

Created: 2026-08-13 06:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/S2OPC/src/Common/sks/sopc_sk_provider.c
Line
Count
Source
1
/*
2
 * Licensed to Systerel under one or more contributor license
3
 * agreements. See the NOTICE file distributed with this work
4
 * for additional information regarding copyright ownership.
5
 * Systerel licenses this file to you under the Apache
6
 * License, Version 2.0 (the "License"); you may not use this
7
 * file except in compliance with the License. You may obtain
8
 * a copy of the License at
9
 *
10
 *   http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing,
13
 * software distributed under the License is distributed on an
14
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
 * KIND, either express or implied.  See the License for the
16
 * specific language governing permissions and limitations
17
 * under the License.
18
 */
19
20
#include <inttypes.h>
21
#include <stdio.h>
22
#include <string.h>
23
24
#include "sopc_assert.h"
25
#include "sopc_crypto_profiles.h"
26
#include "sopc_crypto_provider.h"
27
#include "sopc_logger.h"
28
#include "sopc_macros.h"
29
#include "sopc_mem_alloc.h"
30
#include "sopc_sk_provider.h"
31
32
/* Internal constantes */
33
0
#define SOPC_SK_PROVIDER_INTERNAL_PUBSUB_KEYS_SIZE (32 + 32 + 4)
34
0
#define SOPC_SK_PROVIDER_INTERNAL_PUBSUB_SECURITY_POLICY SOPC_SecurityPolicy_PubSub_Aes256_URI
35
36
typedef struct SOPC_SKProvider_RandomPubSub
37
{
38
    SOPC_CryptoProvider* cryptoProvider;
39
    uint32_t nbMaxKeys;
40
} SOPC_SKProvider_RandomPubSub;
41
42
static void SOPC_SKProvider_Clear_RandomPubSub_Aes256(void* data);
43
44
/*** DEFAULT IMPLEMENTATION FUNCTIONS ***/
45
46
typedef struct SOPC_SKProvider_TryList
47
{
48
    SOPC_SKProvider** providers;
49
    uint32_t nbProviders;
50
} SOPC_SKProvider_TryList;
51
52
/* TryList internal functions */
53
54
/**
55
 * \brief GetKeys function for SK Provider default implementation
56
 * Data is SOPC_SKProvider_TryList
57
 */
58
static SOPC_ReturnStatus SOPC_SKProvider_GetKeys_TryList(SOPC_SKProvider* skp,
59
                                                         const char* securityGroupId,
60
                                                         uint32_t StartingTokenId,
61
                                                         uint32_t NbRequestedToken,
62
                                                         SOPC_String** SecurityPolicyUri,
63
                                                         uint32_t* FirstTokenId,
64
                                                         SOPC_ByteString** Keys,
65
                                                         uint32_t* NbToken,
66
                                                         uint64_t* TimeToNextKey,
67
                                                         uint64_t* KeyLifetime)
68
0
{
69
0
    if (NULL == skp || 0 == skp->data || NULL == Keys || NULL == NbToken || 0 == NbRequestedToken)
70
0
    {
71
0
        return SOPC_STATUS_INVALID_PARAMETERS;
72
0
    }
73
74
0
    SOPC_ReturnStatus status = SOPC_STATUS_NOK;
75
0
    SOPC_SKProvider_TryList* data = (SOPC_SKProvider_TryList*) skp->data;
76
0
    SOPC_ASSERT(NULL != data);
77
0
    SOPC_ASSERT(NULL != data->providers);
78
0
    bool keysFound = false;
79
0
    for (uint32_t i = 0; i < data->nbProviders && !keysFound; i++)
80
0
    {
81
0
        SOPC_Logger_TraceInfo(SOPC_LOG_MODULE_COMMON, "Try GetKeys with provider %" PRIu32, i + 1);
82
0
        status = SOPC_SKProvider_GetKeys(data->providers[i], securityGroupId, StartingTokenId, NbRequestedToken,
83
0
                                         SecurityPolicyUri, FirstTokenId, Keys, NbToken, TimeToNextKey, KeyLifetime);
84
0
        if (SOPC_STATUS_OK == status && 0 < *NbToken)
85
0
        {
86
0
            keysFound = true;
87
0
        }
88
0
    }
89
90
0
    return status;
91
0
}
92
93
static void SOPC_SKProvider_Clear_TryList(void* pdata)
94
0
{
95
0
    if (NULL == pdata)
96
0
    {
97
0
        return;
98
0
    }
99
100
0
    SOPC_SKProvider_TryList* data = (SOPC_SKProvider_TryList*) pdata;
101
0
    SOPC_ASSERT(NULL != data->providers);
102
0
    for (uint32_t i = 0; i < data->nbProviders; i++)
103
0
    {
104
0
        SOPC_SKProvider_Clear(data->providers[i]);
105
0
        SOPC_Free(data->providers[i]);
106
0
    }
107
0
    SOPC_Free(data->providers);
108
0
    data->providers = NULL;
109
0
    SOPC_Free(data);
110
0
}
111
112
/* RandomPubSub internal functions */
113
114
/**
115
 * \brief GetKeys function for SK Provider default implementation
116
 * Data is SOPC_CryptoProvider
117
 */
118
static SOPC_ReturnStatus SOPC_SKProvider_GetKeys_RandomPubSub_Aes256(SOPC_SKProvider* skp,
119
                                                                     const char* securityGroupId,
120
                                                                     uint32_t StartingTokenId,
121
                                                                     uint32_t NbRequestedToken,
122
                                                                     SOPC_String** SecurityPolicyUri,
123
                                                                     uint32_t* FirstTokenId,
124
                                                                     SOPC_ByteString** Keys,
125
                                                                     uint32_t* NbToken,
126
                                                                     uint64_t* TimeToNextKey,
127
                                                                     uint64_t* KeyLifetime)
128
0
{
129
    /* Not used*/
130
0
    SOPC_UNUSED_ARG(securityGroupId); // not necessary as we generate fresh keys anyway
131
0
    SOPC_UNUSED_ARG(StartingTokenId);
132
0
    SOPC_UNUSED_ARG(SecurityPolicyUri);
133
0
    SOPC_UNUSED_ARG(FirstTokenId);
134
0
    SOPC_UNUSED_ARG(TimeToNextKey);
135
0
    SOPC_UNUSED_ARG(KeyLifetime);
136
137
    /* Only skp */
138
0
    if (NULL == skp || 0 == skp->data || NULL == Keys || NULL == NbToken || 0 == NbRequestedToken)
139
0
    {
140
0
        return SOPC_STATUS_INVALID_PARAMETERS;
141
0
    }
142
143
0
    SOPC_ReturnStatus status = SOPC_STATUS_OK;
144
145
0
    SOPC_SKProvider_RandomPubSub* data = (SOPC_SKProvider_RandomPubSub*) skp->data;
146
147
0
    if (0 == data->nbMaxKeys)
148
0
    {
149
0
        return SOPC_STATUS_INVALID_PARAMETERS;
150
0
    }
151
152
0
    uint32_t nbKeys = (NbRequestedToken < data->nbMaxKeys) ? NbRequestedToken : data->nbMaxKeys;
153
154
0
    SOPC_ByteString* generatedKeys = SOPC_Calloc(nbKeys, sizeof(SOPC_ByteString));
155
0
    if (NULL == generatedKeys)
156
0
    {
157
0
        return SOPC_STATUS_OUT_OF_MEMORY;
158
0
    }
159
160
    /* Generate Random Keys and copy in out parameter */
161
0
    uint32_t keyIndex = 0;
162
0
    for (keyIndex = 0; keyIndex < nbKeys && SOPC_STATUS_OK == status; keyIndex++)
163
0
    {
164
0
        SOPC_ExposedBuffer* ppBuffer = NULL;
165
0
        SOPC_ByteString_Initialize(&generatedKeys[keyIndex]);
166
0
        status = SOPC_CryptoProvider_GenerateRandomBytes(data->cryptoProvider,
167
0
                                                         SOPC_SK_PROVIDER_INTERNAL_PUBSUB_KEYS_SIZE, &ppBuffer);
168
0
        if (SOPC_STATUS_OK == status)
169
0
        {
170
0
            status = SOPC_ByteString_CopyFromBytes((&generatedKeys[keyIndex]), ppBuffer,
171
0
                                                   SOPC_SK_PROVIDER_INTERNAL_PUBSUB_KEYS_SIZE);
172
0
        }
173
0
        SOPC_Free(ppBuffer);
174
0
    }
175
176
0
    if (SOPC_STATUS_OK != status)
177
0
    {
178
0
        *NbToken = 0;
179
        /* Clear only initialized Keys */
180
0
        for (uint32_t i = 0; i < keyIndex; i++)
181
0
        {
182
0
            SOPC_ByteString_Clear(&generatedKeys[i]);
183
0
        }
184
0
        SOPC_Free(generatedKeys);
185
0
    }
186
0
    else
187
0
    {
188
0
        *Keys = generatedKeys;
189
0
        *NbToken = nbKeys;
190
0
    }
191
0
    return status;
192
0
}
193
194
static void SOPC_SKProvider_Clear_RandomPubSub_Aes256(void* pdata)
195
0
{
196
0
    if (NULL == pdata)
197
0
    {
198
0
        return;
199
0
    }
200
201
0
    SOPC_SKProvider_RandomPubSub* data = (SOPC_SKProvider_RandomPubSub*) pdata;
202
0
    SOPC_CryptoProvider_Free(data->cryptoProvider);
203
0
    data->cryptoProvider = NULL;
204
0
    data->nbMaxKeys = 0;
205
0
    SOPC_Free(data);
206
0
}
207
208
/*** API FUNCTIONS ***/
209
210
SOPC_SKProvider* SOPC_SKProvider_TryList_Create(SOPC_SKProvider** providers, uint32_t nbProviders)
211
0
{
212
0
    if (NULL == providers || 0 == nbProviders)
213
0
    {
214
0
        return NULL;
215
0
    }
216
217
0
    SOPC_SKProvider* skp = SOPC_Malloc(sizeof(SOPC_SKProvider));
218
0
    if (NULL == skp)
219
0
    {
220
0
        return NULL;
221
0
    }
222
223
0
    SOPC_SKProvider_TryList* data = SOPC_Calloc(1, sizeof(SOPC_SKProvider_TryList));
224
0
    if (NULL == data)
225
0
    {
226
0
        SOPC_Free(skp);
227
0
        return NULL;
228
0
    }
229
230
0
    skp->data = (uintptr_t) data;
231
0
    data->providers = providers;
232
0
    data->nbProviders = nbProviders;
233
234
0
    skp->ptrGetKeys = SOPC_SKProvider_GetKeys_TryList;
235
0
    skp->ptrClear = SOPC_SKProvider_Clear_TryList;
236
0
    skp->referencesCounter = 0;
237
238
0
    return skp;
239
0
}
240
241
SOPC_SKProvider* SOPC_SKProvider_RandomPubSub_Create(uint32_t maxKeys)
242
0
{
243
0
    SOPC_SKProvider* skp = SOPC_Malloc(sizeof(SOPC_SKProvider));
244
0
    if (NULL == skp)
245
0
    {
246
0
        return NULL;
247
0
    }
248
249
0
    skp->data = (uintptr_t) SOPC_Calloc(1, sizeof(SOPC_SKProvider_RandomPubSub));
250
0
    if ((uintptr_t) NULL == skp->data)
251
0
    {
252
0
        SOPC_Free(skp);
253
0
        return NULL;
254
0
    }
255
256
0
    SOPC_SKProvider_RandomPubSub* data = (SOPC_SKProvider_RandomPubSub*) skp->data;
257
0
    data->cryptoProvider = SOPC_CryptoProvider_CreatePubSub(SOPC_SK_PROVIDER_INTERNAL_PUBSUB_SECURITY_POLICY);
258
0
    if (NULL == data->cryptoProvider)
259
0
    {
260
0
        SOPC_Free((void*) skp->data);
261
0
        SOPC_Free(skp);
262
0
        return NULL;
263
0
    }
264
0
    data->nbMaxKeys = maxKeys;
265
266
0
    skp->ptrGetKeys = SOPC_SKProvider_GetKeys_RandomPubSub_Aes256;
267
0
    skp->ptrClear = SOPC_SKProvider_Clear_RandomPubSub_Aes256;
268
0
    skp->referencesCounter = 0;
269
270
0
    return skp;
271
0
}
272
273
SOPC_ReturnStatus SOPC_SKProvider_GetKeys(SOPC_SKProvider* skp,
274
                                          const char* securityGroupId,
275
                                          uint32_t StartingTokenId,
276
                                          uint32_t NbRequestedToken,
277
                                          SOPC_String** SecurityPolicyUri,
278
                                          uint32_t* FirstTokenId,
279
                                          SOPC_ByteString** Keys,
280
                                          uint32_t* NbKeys,
281
                                          uint64_t* TimeToNextKey,
282
                                          uint64_t* KeyLifetime)
283
0
{
284
0
    if (NULL == skp)
285
0
    {
286
0
        return SOPC_STATUS_INVALID_PARAMETERS;
287
0
    }
288
0
    return skp->ptrGetKeys(skp, securityGroupId, StartingTokenId, NbRequestedToken, SecurityPolicyUri, FirstTokenId,
289
0
                           Keys, NbKeys, TimeToNextKey, KeyLifetime);
290
0
}
291
292
void SOPC_SKProvider_Clear(SOPC_SKProvider* skp)
293
0
{
294
0
    if (NULL != skp)
295
0
    {
296
0
        if (NULL != skp->ptrClear)
297
0
        {
298
0
            skp->ptrClear((void*) skp->data);
299
0
        }
300
0
        skp->data = (uintptr_t) NULL;
301
0
    }
302
0
}
303
304
void SOPC_SKProvider_MayDelete(SOPC_SKProvider** skp)
305
0
{
306
0
    if (NULL == skp || NULL == *skp)
307
0
    {
308
0
        return;
309
0
    }
310
0
    SOPC_SKProvider* provider = *skp;
311
    // Updates the counter if not already zero
312
0
    provider->referencesCounter = provider->referencesCounter > 0 ? provider->referencesCounter - 1 : 0;
313
0
    if (provider->referencesCounter == 0)
314
0
    {
315
0
        SOPC_SKProvider_Clear(provider);
316
0
        SOPC_Free(provider);
317
        *skp = NULL;
318
0
    }
319
0
}