/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 | for (uint32_t i = 0; i < data->nbProviders; i++) |
79 | 0 | { |
80 | 0 | SOPC_Logger_TraceInfo(SOPC_LOG_MODULE_COMMON, "Try GetKeys with provider %" PRIu32, i + 1); |
81 | 0 | status = SOPC_SKProvider_GetKeys(data->providers[i], securityGroupId, StartingTokenId, NbRequestedToken, |
82 | 0 | SecurityPolicyUri, FirstTokenId, Keys, NbToken, TimeToNextKey, KeyLifetime); |
83 | 0 | if (SOPC_STATUS_OK == status && 0 < *NbToken) |
84 | 0 | { |
85 | 0 | break; |
86 | 0 | } |
87 | 0 | } |
88 | |
|
89 | 0 | return status; |
90 | 0 | } |
91 | | |
92 | | static void SOPC_SKProvider_Clear_TryList(void* pdata) |
93 | 0 | { |
94 | 0 | if (NULL == pdata) |
95 | 0 | { |
96 | 0 | return; |
97 | 0 | } |
98 | | |
99 | 0 | SOPC_SKProvider_TryList* data = (SOPC_SKProvider_TryList*) pdata; |
100 | 0 | SOPC_ASSERT(NULL != data->providers); |
101 | 0 | for (uint32_t i = 0; i < data->nbProviders; i++) |
102 | 0 | { |
103 | 0 | SOPC_SKProvider_Clear(data->providers[i]); |
104 | 0 | SOPC_Free(data->providers[i]); |
105 | 0 | } |
106 | 0 | SOPC_Free(data->providers); |
107 | 0 | data->providers = NULL; |
108 | 0 | SOPC_Free(data); |
109 | 0 | } |
110 | | |
111 | | /* RandomPubSub internal functions */ |
112 | | |
113 | | /** |
114 | | * \brief GetKeys function for SK Provider default implementation |
115 | | * Data is SOPC_CryptoProvider |
116 | | */ |
117 | | static SOPC_ReturnStatus SOPC_SKProvider_GetKeys_RandomPubSub_Aes256(SOPC_SKProvider* skp, |
118 | | const char* securityGroupId, |
119 | | uint32_t StartingTokenId, |
120 | | uint32_t NbRequestedToken, |
121 | | SOPC_String** SecurityPolicyUri, |
122 | | uint32_t* FirstTokenId, |
123 | | SOPC_ByteString** Keys, |
124 | | uint32_t* NbToken, |
125 | | uint64_t* TimeToNextKey, |
126 | | uint64_t* KeyLifetime) |
127 | 0 | { |
128 | | /* Not used*/ |
129 | 0 | SOPC_UNUSED_ARG(securityGroupId); // not necessary as we generate fresh keys anyway |
130 | 0 | SOPC_UNUSED_ARG(StartingTokenId); |
131 | 0 | SOPC_UNUSED_ARG(SecurityPolicyUri); |
132 | 0 | SOPC_UNUSED_ARG(FirstTokenId); |
133 | 0 | SOPC_UNUSED_ARG(TimeToNextKey); |
134 | 0 | SOPC_UNUSED_ARG(KeyLifetime); |
135 | | |
136 | | /* Only skp */ |
137 | 0 | if (NULL == skp || 0 == skp->data || NULL == Keys || NULL == NbToken || 0 == NbRequestedToken) |
138 | 0 | { |
139 | 0 | return SOPC_STATUS_INVALID_PARAMETERS; |
140 | 0 | } |
141 | | |
142 | 0 | SOPC_ReturnStatus status = SOPC_STATUS_OK; |
143 | |
|
144 | 0 | SOPC_SKProvider_RandomPubSub* data = (SOPC_SKProvider_RandomPubSub*) skp->data; |
145 | |
|
146 | 0 | if (0 == data->nbMaxKeys) |
147 | 0 | { |
148 | 0 | return SOPC_STATUS_INVALID_PARAMETERS; |
149 | 0 | } |
150 | | |
151 | 0 | uint32_t nbKeys = (NbRequestedToken < data->nbMaxKeys) ? NbRequestedToken : data->nbMaxKeys; |
152 | |
|
153 | 0 | SOPC_ByteString* generatedKeys = SOPC_Calloc(nbKeys, sizeof(SOPC_ByteString)); |
154 | 0 | if (NULL == generatedKeys) |
155 | 0 | { |
156 | 0 | return SOPC_STATUS_OUT_OF_MEMORY; |
157 | 0 | } |
158 | | |
159 | | /* Generate Random Keys and copy in out parameter */ |
160 | 0 | uint32_t keyIndex = 0; |
161 | 0 | for (keyIndex = 0; keyIndex < nbKeys && SOPC_STATUS_OK == status; keyIndex++) |
162 | 0 | { |
163 | 0 | SOPC_ExposedBuffer* ppBuffer = NULL; |
164 | 0 | SOPC_ByteString_Initialize(&generatedKeys[keyIndex]); |
165 | 0 | status = SOPC_CryptoProvider_GenerateRandomBytes(data->cryptoProvider, |
166 | 0 | SOPC_SK_PROVIDER_INTERNAL_PUBSUB_KEYS_SIZE, &ppBuffer); |
167 | 0 | if (SOPC_STATUS_OK == status) |
168 | 0 | { |
169 | 0 | status = SOPC_ByteString_CopyFromBytes((&generatedKeys[keyIndex]), ppBuffer, |
170 | 0 | SOPC_SK_PROVIDER_INTERNAL_PUBSUB_KEYS_SIZE); |
171 | 0 | } |
172 | 0 | SOPC_Free(ppBuffer); |
173 | 0 | } |
174 | |
|
175 | 0 | if (SOPC_STATUS_OK != status) |
176 | 0 | { |
177 | 0 | *NbToken = 0; |
178 | | /* Clear only initialized Keys */ |
179 | 0 | for (uint32_t i = 0; i < keyIndex; i++) |
180 | 0 | { |
181 | 0 | SOPC_ByteString_Clear(&generatedKeys[i]); |
182 | 0 | } |
183 | 0 | SOPC_Free(generatedKeys); |
184 | 0 | } |
185 | 0 | else |
186 | 0 | { |
187 | 0 | *Keys = generatedKeys; |
188 | 0 | *NbToken = nbKeys; |
189 | 0 | } |
190 | 0 | return status; |
191 | 0 | } |
192 | | |
193 | | static void SOPC_SKProvider_Clear_RandomPubSub_Aes256(void* pdata) |
194 | 0 | { |
195 | 0 | if (NULL == pdata) |
196 | 0 | { |
197 | 0 | return; |
198 | 0 | } |
199 | | |
200 | 0 | SOPC_SKProvider_RandomPubSub* data = (SOPC_SKProvider_RandomPubSub*) pdata; |
201 | 0 | SOPC_CryptoProvider_Free(data->cryptoProvider); |
202 | 0 | data->cryptoProvider = NULL; |
203 | 0 | data->nbMaxKeys = 0; |
204 | 0 | SOPC_Free(data); |
205 | 0 | } |
206 | | |
207 | | /*** API FUNCTIONS ***/ |
208 | | |
209 | | SOPC_SKProvider* SOPC_SKProvider_TryList_Create(SOPC_SKProvider** providers, uint32_t nbProviders) |
210 | 0 | { |
211 | 0 | if (NULL == providers || 0 == nbProviders) |
212 | 0 | { |
213 | 0 | return NULL; |
214 | 0 | } |
215 | | |
216 | 0 | SOPC_SKProvider* skp = SOPC_Malloc(sizeof(SOPC_SKProvider)); |
217 | 0 | if (NULL == skp) |
218 | 0 | { |
219 | 0 | return NULL; |
220 | 0 | } |
221 | | |
222 | 0 | SOPC_SKProvider_TryList* data = SOPC_Calloc(1, sizeof(SOPC_SKProvider_TryList)); |
223 | 0 | if (NULL == data) |
224 | 0 | { |
225 | 0 | SOPC_Free(skp); |
226 | 0 | return NULL; |
227 | 0 | } |
228 | | |
229 | 0 | skp->data = (uintptr_t) data; |
230 | 0 | data->providers = providers; |
231 | 0 | data->nbProviders = nbProviders; |
232 | |
|
233 | 0 | skp->ptrGetKeys = SOPC_SKProvider_GetKeys_TryList; |
234 | 0 | skp->ptrClear = SOPC_SKProvider_Clear_TryList; |
235 | 0 | skp->referencesCounter = 0; |
236 | |
|
237 | 0 | return skp; |
238 | 0 | } |
239 | | |
240 | | SOPC_SKProvider* SOPC_SKProvider_RandomPubSub_Create(uint32_t maxKeys) |
241 | 0 | { |
242 | 0 | SOPC_SKProvider* skp = SOPC_Malloc(sizeof(SOPC_SKProvider)); |
243 | 0 | if (NULL == skp) |
244 | 0 | { |
245 | 0 | return NULL; |
246 | 0 | } |
247 | | |
248 | 0 | skp->data = (uintptr_t) SOPC_Calloc(1, sizeof(SOPC_SKProvider_RandomPubSub)); |
249 | 0 | if ((uintptr_t) NULL == skp->data) |
250 | 0 | { |
251 | 0 | SOPC_Free(skp); |
252 | 0 | return NULL; |
253 | 0 | } |
254 | | |
255 | 0 | SOPC_SKProvider_RandomPubSub* data = (SOPC_SKProvider_RandomPubSub*) skp->data; |
256 | 0 | data->cryptoProvider = SOPC_CryptoProvider_CreatePubSub(SOPC_SK_PROVIDER_INTERNAL_PUBSUB_SECURITY_POLICY); |
257 | 0 | if (NULL == data->cryptoProvider) |
258 | 0 | { |
259 | 0 | SOPC_Free((void*) skp->data); |
260 | 0 | SOPC_Free(skp); |
261 | 0 | return NULL; |
262 | 0 | } |
263 | 0 | data->nbMaxKeys = maxKeys; |
264 | |
|
265 | 0 | skp->ptrGetKeys = SOPC_SKProvider_GetKeys_RandomPubSub_Aes256; |
266 | 0 | skp->ptrClear = SOPC_SKProvider_Clear_RandomPubSub_Aes256; |
267 | 0 | skp->referencesCounter = 0; |
268 | |
|
269 | 0 | return skp; |
270 | 0 | } |
271 | | |
272 | | SOPC_ReturnStatus SOPC_SKProvider_GetKeys(SOPC_SKProvider* skp, |
273 | | const char* securityGroupId, |
274 | | uint32_t StartingTokenId, |
275 | | uint32_t NbRequestedToken, |
276 | | SOPC_String** SecurityPolicyUri, |
277 | | uint32_t* FirstTokenId, |
278 | | SOPC_ByteString** Keys, |
279 | | uint32_t* NbKeys, |
280 | | uint64_t* TimeToNextKey, |
281 | | uint64_t* KeyLifetime) |
282 | 0 | { |
283 | 0 | if (NULL == skp) |
284 | 0 | { |
285 | 0 | return SOPC_STATUS_INVALID_PARAMETERS; |
286 | 0 | } |
287 | 0 | return skp->ptrGetKeys(skp, securityGroupId, StartingTokenId, NbRequestedToken, SecurityPolicyUri, FirstTokenId, |
288 | 0 | Keys, NbKeys, TimeToNextKey, KeyLifetime); |
289 | 0 | } |
290 | | |
291 | | void SOPC_SKProvider_Clear(SOPC_SKProvider* skp) |
292 | 0 | { |
293 | 0 | if (NULL != skp) |
294 | 0 | { |
295 | 0 | if (NULL != skp->ptrClear) |
296 | 0 | { |
297 | 0 | skp->ptrClear((void*) skp->data); |
298 | 0 | } |
299 | 0 | skp->data = (uintptr_t) NULL; |
300 | 0 | } |
301 | 0 | } |
302 | | |
303 | | void SOPC_SKProvider_MayDelete(SOPC_SKProvider** skp) |
304 | 0 | { |
305 | 0 | if (NULL == skp || NULL == *skp) |
306 | 0 | { |
307 | 0 | return; |
308 | 0 | } |
309 | 0 | SOPC_SKProvider* provider = *skp; |
310 | | // Updates the counter if not already zero |
311 | 0 | provider->referencesCounter = provider->referencesCounter > 0 ? provider->referencesCounter - 1 : 0; |
312 | 0 | if (provider->referencesCounter == 0) |
313 | 0 | { |
314 | 0 | SOPC_SKProvider_Clear(provider); |
315 | 0 | SOPC_Free(provider); |
316 | | *skp = NULL; |
317 | 0 | } |
318 | 0 | } |