/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 | } |